diff options
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 57 | ||||
-rw-r--r-- | clang/lib/Parse/ParsePragma.h | 10 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 4 |
3 files changed, 71 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 3c6f96ac2be..10ad5df629e 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -794,6 +794,63 @@ PragmaOpenMPHandler::HandlePragma(Preprocessor &PP, /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true); } +/// \brief Handle the Microsoft \#pragma detect_mismatch extension. +/// +/// The syntax is: +/// \code +/// #pragma detect_mismatch("name", "value") +/// \endcode +/// Where 'name' and 'value' are quoted strings. The values are embedded in +/// the object file and passed along to the linker. If the linker detects a +/// mismatch in the object file's values for the given name, a LNK2038 error +/// is emitted. See MSDN for more details. +void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &Tok) { + SourceLocation CommentLoc = Tok.getLocation(); + PP.Lex(Tok); + if (Tok.isNot(tok::l_paren)) { + PP.Diag(CommentLoc, diag::err_expected_lparen); + return; + } + + // Read the name to embed, which must be a string literal. + std::string NameString; + if (!PP.LexStringLiteral(Tok, NameString, + "pragma detect_mismatch", + /*MacroExpansion=*/true)) + return; + + // Read the comma followed by a second string literal. + std::string ValueString; + if (Tok.isNot(tok::comma)) { + PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); + return; + } + + if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch", + /*MacroExpansion=*/true)) + return; + + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::err_expected_rparen); + return; + } + PP.Lex(Tok); // Eat the r_paren. + + if (Tok.isNot(tok::eod)) { + PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); + return; + } + + // If the pragma is lexically sound, notify any interested PPCallbacks. + if (PP.getPPCallbacks()) + PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString, + ValueString); + + Actions.ActOnPragmaDetectMismatch(NameString, ValueString); +} + /// \brief Handle the microsoft \#pragma comment extension. /// /// The syntax is: diff --git a/clang/lib/Parse/ParsePragma.h b/clang/lib/Parse/ParsePragma.h index 3c6f3434ad0..b41450f4ead 100644 --- a/clang/lib/Parse/ParsePragma.h +++ b/clang/lib/Parse/ParsePragma.h @@ -124,6 +124,16 @@ private: Sema &Actions; }; +class PragmaDetectMismatchHandler : public PragmaHandler { +public: + PragmaDetectMismatchHandler(Sema &Actions) + : PragmaHandler("detect_mismatch"), Actions(Actions) {} + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); +private: + Sema &Actions; +}; + } // end namespace clang #endif diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 3124b96455e..f19d24299aa 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -105,6 +105,8 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) if (getLangOpts().MicrosoftExt) { MSCommentHandler.reset(new PragmaCommentHandler(actions)); PP.AddPragmaHandler(MSCommentHandler.get()); + MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(actions)); + PP.AddPragmaHandler(MSDetectMismatchHandler.get()); } CommentSemaHandler.reset(new ActionCommentHandler(actions)); @@ -444,6 +446,8 @@ Parser::~Parser() { if (getLangOpts().MicrosoftExt) { PP.RemovePragmaHandler(MSCommentHandler.get()); MSCommentHandler.reset(); + PP.RemovePragmaHandler(MSDetectMismatchHandler.get()); + MSDetectMismatchHandler.reset(); } PP.RemovePragmaHandler("STDC", FPContractHandler.get()); |