/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message /// extension. The syntax is: /// \code /// #pragma message(string) /// \endcode /// OR, in GCC mode: /// \code /// #pragma message string /// \endcode /// string is a string, which is fully macro expanded, and permits string /// concatenation, embedded escape characters, etc... See MSDN for more details. /// Also handles \#pragma GCC warning and \#pragma GCC error which take the same /// form as \#pragma message. structPragmaMessageHandler : public PragmaHandler { private: const PPCallbacks::PragmaMessageKind Kind; const StringRef Namespace;
voidHandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok)override{ SourceLocation MessageLoc = Tok.getLocation(); PP.Lex(Tok); bool ExpectClosingParen = false; switch (Tok.getKind()) { case tok::l_paren: // We have a MSVC style pragma message. ExpectClosingParen = true; // Read the string. PP.Lex(Tok); break; case tok::string_literal: // We have a GCC style pragma message, and we just read the string. break; default: PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind; return; }
std::string MessageString; if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind), /*AllowMacroExpansion=*/true)) return;
if (ExpectClosingParen) { if (Tok.isNot(tok::r_paren)) { PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind; return; } PP.Lex(Tok); // eat the r_paren. }
if (Tok.isNot(tok::eod)) { PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind; return; }
// If the pragma is lexically sound, notify any interested PPCallbacks. if (PPCallbacks *Callbacks = PP.getPPCallbacks()) Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString); } };