diff options
author | Javed Absar <javed.absar@arm.com> | 2017-06-05 10:11:57 +0000 |
---|---|---|
committer | Javed Absar <javed.absar@arm.com> | 2017-06-05 10:11:57 +0000 |
commit | 2a67c9ee39c3a2dd298a9a0aec96a1eff6349344 (patch) | |
tree | 4ad76a7874c3308ece86e0e2b76b35f0ff1102df /clang/lib/Parse/ParsePragma.cpp | |
parent | b16d146838b8f4b34e072f34a5f194d9a4df4cc5 (diff) | |
download | bcm5719-llvm-2a67c9ee39c3a2dd298a9a0aec96a1eff6349344.tar.gz bcm5719-llvm-2a67c9ee39c3a2dd298a9a0aec96a1eff6349344.zip |
Add support for #pragma clang section
This patch provides a means to specify section-names for global variables,
functions and static variables, using #pragma directives.
This feature is only defined to work sensibly for ELF targets.
One can specify section names as:
#pragma clang section bss="myBSS" data="myData" rodata="myRodata" text="myText"
One can "unspecify" a section name with empty string e.g.
#pragma clang section bss="" data="" text="" rodata=""
Reviewers: Roger Ferrer, Jonathan Roelofs, Reid Kleckner
Differential Revision: https://reviews.llvm.org/D33412
llvm-svn: 304705
Diffstat (limited to 'clang/lib/Parse/ParsePragma.cpp')
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 18aebe65807..262743756a6 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/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, |