void PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) { PP.LexUnexpandedToken(Tok); if (Tok.isNot(tok::identifier)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "OPENCL"; return; } IdentifierInfo *ename = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.isNot(tok::colon)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename; return; } PP.Lex(Tok); if (Tok.isNot(tok::identifier)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); return; } IdentifierInfo *op = Tok.getIdentifierInfo(); unsigned state; if (op->isStr("enable")) { state = 1; } else if (op->isStr("disable")) { state = 0; } else { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); return; } SourceLocation StateLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.isNot(tok::eod)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "OPENCL EXTENSION"; return; } OpenCLExtData data(ename, state); Token *Toks = (Token*) PP.getPreprocessorAllocator().Allocate( sizeof(Token) * 1, llvm::alignOf<Token>()); new (Toks) Token(); Toks[0].startToken(); Toks[0].setKind(tok::annot_pragma_opencl_extension); Toks[0].setLocation(NameLoc); Toks[0].setAnnotationValue(data.getOpaqueValue()); PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { Callbacks->PragmaOpenCLExtension(NameLoc, ename, StateLoc, state); } }
/// EvaluateDefined - Process a 'defined(sym)' expression. static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP) { IdentifierInfo *II; Result.setBegin(PeekTok.getLocation()); // Get the next token, don't expand it. PP.LexUnexpandedNonComment(PeekTok); // Two options, it can either be a pp-identifier or a (. SourceLocation LParenLoc; if (PeekTok.is(tok::l_paren)) { // Found a paren, remember we saw it and skip it. LParenLoc = PeekTok.getLocation(); PP.LexUnexpandedNonComment(PeekTok); } if (PeekTok.is(tok::code_completion)) { if (PP.getCodeCompletionHandler()) PP.getCodeCompletionHandler()->CodeCompleteMacroName(false); PP.setCodeCompletionReached(); PP.LexUnexpandedNonComment(PeekTok); } // If we don't have a pp-identifier now, this is an error. if ((II = PeekTok.getIdentifierInfo()) == 0) { PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier); return true; } // Otherwise, we got an identifier, is it defined to something? Result.Val = II->hasMacroDefinition(); Result.Val.setIsUnsigned(false); // Result is signed intmax_t. MacroInfo *Macro = 0; // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) { Macro = PP.getMacroInfo(II); PP.markMacroAsUsed(Macro); } // Invoke the 'defined' callback. if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { MacroInfo *MI = Macro; // Pass the MacroInfo for the macro name even if the value is dead. if (!MI && Result.Val != 0) MI = PP.getMacroInfo(II); Callbacks->Defined(PeekTok, MI); } // If we are in parens, ensure we have a trailing ). if (LParenLoc.isValid()) { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexUnexpandedNonComment(PeekTok); if (PeekTok.isNot(tok::r_paren)) { PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined"; PP.Diag(LParenLoc, diag::note_matching) << "("; return true; } // Consume the ). Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } else { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } // Success, remember that we saw defined(X). DT.State = DefinedTracker::DefinedMacro; DT.TheMacro = II; return false; }
/// EvaluateDefined - Process a 'defined(sym)' expression. static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP) { SourceLocation beginLoc(PeekTok.getLocation()); Result.setBegin(beginLoc); // Get the next token, don't expand it. PP.LexUnexpandedNonComment(PeekTok); // Two options, it can either be a pp-identifier or a (. SourceLocation LParenLoc; if (PeekTok.is(tok::l_paren)) { // Found a paren, remember we saw it and skip it. LParenLoc = PeekTok.getLocation(); PP.LexUnexpandedNonComment(PeekTok); } if (PeekTok.is(tok::code_completion)) { if (PP.getCodeCompletionHandler()) PP.getCodeCompletionHandler()->CodeCompleteMacroName(false); PP.setCodeCompletionReached(); PP.LexUnexpandedNonComment(PeekTok); } // If we don't have a pp-identifier now, this is an error. if (PP.CheckMacroName(PeekTok, MU_Other)) return true; // Otherwise, we got an identifier, is it defined to something? IdentifierInfo *II = PeekTok.getIdentifierInfo(); MacroDefinition Macro = PP.getMacroDefinition(II); Result.Val = !!Macro; Result.Val.setIsUnsigned(false); // Result is signed intmax_t. // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) PP.markMacroAsUsed(Macro.getMacroInfo()); // Save macro token for callback. Token macroToken(PeekTok); // If we are in parens, ensure we have a trailing ). if (LParenLoc.isValid()) { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexUnexpandedNonComment(PeekTok); if (PeekTok.isNot(tok::r_paren)) { PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after) << "'defined'" << tok::r_paren; PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren; return true; } // Consume the ). Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } else { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } // [cpp.cond]p4: // Prior to evaluation, macro invocations in the list of preprocessing // tokens that will become the controlling constant expression are replaced // (except for those macro names modified by the 'defined' unary operator), // just as in normal text. If the token 'defined' is generated as a result // of this replacement process or use of the 'defined' unary operator does // not match one of the two specified forms prior to macro replacement, the // behavior is undefined. // This isn't an idle threat, consider this program: // #define FOO // #define BAR defined(FOO) // #if BAR // ... // #else // ... // #endif // clang and gcc will pick the #if branch while Visual Studio will take the // #else branch. Emit a warning about this undefined behavior. if (beginLoc.isMacroID()) { bool IsFunctionTypeMacro = PP.getSourceManager() .getSLocEntry(PP.getSourceManager().getFileID(beginLoc)) .getExpansion() .isFunctionMacroExpansion(); // For object-type macros, it's easy to replace // #define FOO defined(BAR) // with // #if defined(BAR) // #define FOO 1 // #else // #define FOO 0 // #endif // and doing so makes sense since compilers handle this differently in // practice (see example further up). But for function-type macros, // there is no good way to write // # define FOO(x) (defined(M_ ## x) && M_ ## x) // in a different way, and compilers seem to agree on how to behave here. // So warn by default on object-type macros, but only warn in -pedantic // mode on function-type macros. if (IsFunctionTypeMacro) PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro); else PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro); } // Invoke the 'defined' callback. if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { Callbacks->Defined(macroToken, Macro, SourceRange(beginLoc, PeekTok.getLocation())); } // Success, remember that we saw defined(X). DT.State = DefinedTracker::DefinedMacro; DT.TheMacro = II; return false; }
/// EvaluateDefined - Process a 'defined(sym)' expression. static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP) { SourceLocation beginLoc(PeekTok.getLocation()); Result.setBegin(beginLoc); // Get the next token, don't expand it. PP.LexUnexpandedNonComment(PeekTok); // Two options, it can either be a pp-identifier or a (. SourceLocation LParenLoc; if (PeekTok.is(tok::l_paren)) { // Found a paren, remember we saw it and skip it. LParenLoc = PeekTok.getLocation(); PP.LexUnexpandedNonComment(PeekTok); } if (PeekTok.is(tok::code_completion)) { if (PP.getCodeCompletionHandler()) PP.getCodeCompletionHandler()->CodeCompleteMacroName(false); PP.setCodeCompletionReached(); PP.LexUnexpandedNonComment(PeekTok); } // If we don't have a pp-identifier now, this is an error. if (PP.CheckMacroName(PeekTok, MU_Other)) return true; // Otherwise, we got an identifier, is it defined to something? IdentifierInfo *II = PeekTok.getIdentifierInfo(); MacroDefinition Macro = PP.getMacroDefinition(II); Result.Val = !!Macro; Result.Val.setIsUnsigned(false); // Result is signed intmax_t. // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) PP.markMacroAsUsed(Macro.getMacroInfo()); // Save macro token for callback. Token macroToken(PeekTok); // If we are in parens, ensure we have a trailing ). if (LParenLoc.isValid()) { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexUnexpandedNonComment(PeekTok); if (PeekTok.isNot(tok::r_paren)) { PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after) << "'defined'" << tok::r_paren; PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren; return true; } // Consume the ). Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } else { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } // Invoke the 'defined' callback. if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { Callbacks->Defined(macroToken, Macro, SourceRange(beginLoc, PeekTok.getLocation())); } // Success, remember that we saw defined(X). DT.State = DefinedTracker::DefinedMacro; DT.TheMacro = II; return false; }
/// \brief Handle the microsoft \#pragma comment extension. /// /// The syntax is: /// \code /// #pragma comment(linker, "foo") /// \endcode /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user. /// "foo" is a string, which is fully macro expanded, and permits string /// concatenation, embedded escape characters etc. See MSDN for more details. void PragmaCommentHandler::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_pragma_comment_malformed); return; } // Read the identifier. PP.Lex(Tok); if (Tok.isNot(tok::identifier)) { PP.Diag(CommentLoc, diag::err_pragma_comment_malformed); return; } // Verify that this is one of the 5 whitelisted options. IdentifierInfo *II = Tok.getIdentifierInfo(); Sema::PragmaMSCommentKind Kind = llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName()) .Case("linker", Sema::PCK_Linker) .Case("lib", Sema::PCK_Lib) .Case("compiler", Sema::PCK_Compiler) .Case("exestr", Sema::PCK_ExeStr) .Case("user", Sema::PCK_User) .Default(Sema::PCK_Unknown); if (Kind == Sema::PCK_Unknown) { PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind); return; } // Read the optional string if present. PP.Lex(Tok); std::string ArgumentString; if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString, "pragma comment", /*MacroExpansion=*/true)) return; // FIXME: warn that 'exestr' is deprecated. // FIXME: If the kind is "compiler" warn if the string is present (it is // ignored). // The MSDN docs say that "lib" and "linker" require a string and have a short // whitelist of linker options they support, but in practice MSVC doesn't // issue a diagnostic. Therefore neither does clang. if (Tok.isNot(tok::r_paren)) { PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); return; } PP.Lex(Tok); // eat the r_paren. if (Tok.isNot(tok::eod)) { PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); return; } // If the pragma is lexically sound, notify any interested PPCallbacks. if (PP.getPPCallbacks()) PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString); Actions.ActOnPragmaMSComment(Kind, ArgumentString); }