diff options
Diffstat (limited to 'lib/Parse/ParsePragma.cpp')
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 18aebe658073..262743756a6b 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -49,6 +49,15 @@ struct PragmaPackHandler : public PragmaHandler { Token &FirstToken) override; }; +struct PragmaClangSectionHandler : public PragmaHandler { + explicit PragmaClangSectionHandler(Sema &S) + : PragmaHandler("section"), Actions(S) {} + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken) override; +private: + Sema &Actions; +}; + struct PragmaMSStructHandler : public PragmaHandler { explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {} void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, @@ -224,6 +233,9 @@ void Parser::initializePragmaHandlers() { FPContractHandler.reset(new PragmaFPContractHandler()); PP.AddPragmaHandler("STDC", FPContractHandler.get()); + PCSectionHandler.reset(new PragmaClangSectionHandler(Actions)); + PP.AddPragmaHandler("clang", PCSectionHandler.get()); + if (getLangOpts().OpenCL) { OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler()); PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get()); @@ -323,6 +335,9 @@ void Parser::resetPragmaHandlers() { MSCommentHandler.reset(); } + PP.RemovePragmaHandler("clang", PCSectionHandler.get()); + PCSectionHandler.reset(); + if (getLangOpts().MicrosoftExt) { PP.RemovePragmaHandler(MSDetectMismatchHandler.get()); MSDetectMismatchHandler.reset(); @@ -1614,6 +1629,51 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); } +// #pragma clang section bss="abc" data="" rodata="def" text="" +void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, Token &FirstToken) { + + Token Tok; + auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid; + + PP.Lex(Tok); // eat 'section' + while (Tok.isNot(tok::eod)) { + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section"; + return; + } + + const IdentifierInfo *SecType = Tok.getIdentifierInfo(); + if (SecType->isStr("bss")) + SecKind = Sema::PragmaClangSectionKind::PCSK_BSS; + else if (SecType->isStr("data")) + SecKind = Sema::PragmaClangSectionKind::PCSK_Data; + else if (SecType->isStr("rodata")) + SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata; + else if (SecType->isStr("text")) + SecKind = Sema::PragmaClangSectionKind::PCSK_Text; + else { + PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section"; + return; + } + + PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text'] + if (Tok.isNot(tok::equal)) { + PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind; + return; + } + + std::string SecName; + if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false)) + return; + + Actions.ActOnPragmaClangSection(Tok.getLocation(), + (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set : + Sema::PragmaClangSectionAction::PCSA_Clear), + SecKind, SecName); + } +} + // #pragma 'align' '=' {'native','natural','mac68k','power','reset'} // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, |