summaryrefslogtreecommitdiff
path: root/lib/Parse/ParsePragma.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParsePragma.cpp')
-rw-r--r--lib/Parse/ParsePragma.cpp60
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,