/// LookupBuiltin - Lookup for built-in functions static bool LookupBuiltin(Sema &S, LookupResult &R) { Sema::LookupNameKind NameKind = R.getLookupKind(); // If we didn't find a use of this identifier, and if the identifier // corresponds to a compiler builtin, create the defn object for the builtin // now, injecting it into system scope, and return it. if (NameKind == Sema::LookupOrdinaryName) { IdentifierInfo *II = R.getLookupName().getAsIdentifierInfo(); if (II) { // If this is a builtin on this (or all) targets, create the defn. if (unsigned BuiltinID = II->getBuiltinID()) { if (NamedDefn *D = S.LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, S.BaseWorkspace, /*R.isForRedeclaration()*/false, R.getNameLoc())) { R.addDefn(D); return true; } //FIXME yabin // should i deal with this situation in gmat? // if (R.isForRedeclaration()) { // // If we're redeclaring this function anyway, forget that // // this was a builtin at all. // S.Context.BuiltinInfo.ForgetBuiltin(BuiltinID, // S.Context.Idents); // } return false; } } } return false; }
unsigned MacroRepeatedPPCallbacks::countArgumentExpansions( const MacroInfo *MI, const IdentifierInfo *Arg) const { // Current argument count. When moving forward to a different control-flow // path this can decrease. unsigned Current = 0; // Max argument count. unsigned Max = 0; bool SkipParen = false; int SkipParenCount = 0; // Has a __builtin_constant_p been found? bool FoundBuiltin = false; // Count when "?" is reached. The "Current" will get this value when the ":" // is reached. std::stack<unsigned, SmallVector<unsigned, 8>> CountAtQuestion; for (const auto &T : MI->tokens()) { // The result of __builtin_constant_p(x) is 0 if x is a macro argument // with side effects. If we see a __builtin_constant_p(x) followed by a // "?" "&&" or "||", then we need to reason about control flow to report // warnings correctly. Until such reasoning is added, bail out when this // happens. if (FoundBuiltin && T.isOneOf(tok::question, tok::ampamp, tok::pipepipe)) return Max; // Handling of ? and :. if (T.is(tok::question)) { CountAtQuestion.push(Current); } else if (T.is(tok::colon)) { if (CountAtQuestion.empty()) return 0; Current = CountAtQuestion.top(); CountAtQuestion.pop(); } // If current token is a parenthesis, skip it. if (SkipParen) { if (T.is(tok::l_paren)) SkipParenCount++; else if (T.is(tok::r_paren)) SkipParenCount--; SkipParen = (SkipParenCount != 0); if (SkipParen) continue; } IdentifierInfo *TII = T.getIdentifierInfo(); // If not existent, skip it. if (TII == nullptr) continue; // If a __builtin_constant_p is found within the macro definition, don't // count arguments inside the parentheses and remember that it has been // seen in case there are "?", "&&" or "||" operators later. if (TII->getBuiltinID() == Builtin::BI__builtin_constant_p) { FoundBuiltin = true; SkipParen = true; continue; } // If another macro is found within the macro definition, skip the macro // and the eventual arguments. if (TII->hasMacroDefinition()) { const MacroInfo *M = PP.getMacroDefinition(TII).getMacroInfo(); if (M != nullptr && M->isFunctionLike()) SkipParen = true; continue; } // Count argument. if (TII == Arg) { Current++; if (Current > Max) Max = Current; } } return Max; }
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded /// as a builtin macro, handle it and return the next token as 'Tok'. void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // Figure out which token this is. IdentifierInfo *II = Tok.getIdentifierInfo(); assert(II && "Can't be a macro without id info!"); // If this is an _Pragma or Microsoft __pragma directive, expand it, // invoke the pragma handler, then lex the token after it. if (II == Ident_Pragma) return Handle_Pragma(Tok); else if (II == Ident__pragma) // in non-MS mode this is null return HandleMicrosoft__pragma(Tok); ++NumBuiltinMacroExpanded; llvm::SmallString<128> TmpBuffer; llvm::raw_svector_ostream OS(TmpBuffer); // Set up the return result. Tok.setIdentifierInfo(0); Tok.clearFlag(Token::NeedsCleaning); if (II == Ident__LINE__) { // C99 6.10.8: "__LINE__: The presumed line number (within the current // source file) of the current source line (an integer constant)". This can // be affected by #line. SourceLocation Loc = Tok.getLocation(); // Advance to the location of the first _, this might not be the first byte // of the token if it starts with an escaped newline. Loc = AdvanceToTokenCharacter(Loc, 0); // One wrinkle here is that GCC expands __LINE__ to location of the *end* of // a macro expansion. This doesn't matter for object-like macros, but // can matter for a function-like macro that expands to contain __LINE__. // Skip down through expansion points until we find a file loc for the // end of the expansion history. Loc = SourceMgr.getExpansionRange(Loc).second; PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc); // __LINE__ expands to a simple numeric value. OS << (PLoc.isValid()? PLoc.getLine() : 1); Tok.setKind(tok::numeric_constant); } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) { // C99 6.10.8: "__FILE__: The presumed name of the current source file (a // character string literal)". This can be affected by #line. PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); // __BASE_FILE__ is a GNU extension that returns the top of the presumed // #include stack instead of the current file. if (II == Ident__BASE_FILE__ && PLoc.isValid()) { SourceLocation NextLoc = PLoc.getIncludeLoc(); while (NextLoc.isValid()) { PLoc = SourceMgr.getPresumedLoc(NextLoc); if (PLoc.isInvalid()) break; NextLoc = PLoc.getIncludeLoc(); } } // Escape this filename. Turn '\' -> '\\' '"' -> '\"' llvm::SmallString<128> FN; if (PLoc.isValid()) { FN += PLoc.getFilename(); Lexer::Stringify(FN); OS << '"' << FN.str() << '"'; } Tok.setKind(tok::string_literal); } else if (II == Ident__DATE__) { if (!DATELoc.isValid()) ComputeDATE_TIME(DATELoc, TIMELoc, *this); Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"Mmm dd yyyy\"")); Tok.setLocation(SourceMgr.createExpansionLoc(DATELoc, Tok.getLocation(), Tok.getLocation(), Tok.getLength())); return; } else if (II == Ident__TIME__) { if (!TIMELoc.isValid()) ComputeDATE_TIME(DATELoc, TIMELoc, *this); Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"hh:mm:ss\"")); Tok.setLocation(SourceMgr.createExpansionLoc(TIMELoc, Tok.getLocation(), Tok.getLocation(), Tok.getLength())); return; } else if (II == Ident__INCLUDE_LEVEL__) { // Compute the presumed include depth of this token. This can be affected // by GNU line markers. unsigned Depth = 0; PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); if (PLoc.isValid()) { PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc()); for (; PLoc.isValid(); ++Depth) PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc()); } // __INCLUDE_LEVEL__ expands to a simple numeric value. OS << Depth; Tok.setKind(tok::numeric_constant); } else if (II == Ident__TIMESTAMP__) { // MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime. // Get the file that we are lexing out of. If we're currently lexing from // a macro, dig into the include stack. const FileEntry *CurFile = 0; PreprocessorLexer *TheLexer = getCurrentFileLexer(); if (TheLexer) CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID()); const char *Result; if (CurFile) { time_t TT = CurFile->getModificationTime(); struct tm *TM = localtime(&TT); Result = asctime(TM); } else { Result = "??? ??? ?? ??:??:?? ????\n"; } // Surround the string with " and strip the trailing newline. OS << '"' << StringRef(Result, strlen(Result)-1) << '"'; Tok.setKind(tok::string_literal); } else if (II == Ident__COUNTER__) { // __COUNTER__ expands to a simple numeric value. OS << CounterValue++; Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_feature || II == Ident__has_extension || II == Ident__has_builtin || II == Ident__has_attribute) { // The argument to these builtins should be a parenthesized identifier. SourceLocation StartLoc = Tok.getLocation(); bool IsValid = false; IdentifierInfo *FeatureII = 0; // Read the '('. Lex(Tok); if (Tok.is(tok::l_paren)) { // Read the identifier Lex(Tok); if (Tok.is(tok::identifier)) { FeatureII = Tok.getIdentifierInfo(); // Read the ')'. Lex(Tok); if (Tok.is(tok::r_paren)) IsValid = true; } } bool Value = false; if (!IsValid) Diag(StartLoc, diag::err_feature_check_malformed); else if (II == Ident__has_builtin) { // Check for a builtin is trivial. Value = FeatureII->getBuiltinID() != 0; } else if (II == Ident__has_attribute) Value = HasAttribute(FeatureII); else if (II == Ident__has_extension) Value = HasExtension(*this, FeatureII); else { assert(II == Ident__has_feature && "Must be feature check"); Value = HasFeature(*this, FeatureII); } OS << (int)Value; Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_include || II == Ident__has_include_next) { // The argument to these two builtins should be a parenthesized // file name string literal using angle brackets (<>) or // double-quotes (""). bool Value; if (II == Ident__has_include) Value = EvaluateHasInclude(Tok, II, *this); else Value = EvaluateHasIncludeNext(Tok, II, *this); OS << (int)Value; Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_warning) { // The argument should be a parenthesized string literal. // The argument to these builtins should be a parenthesized identifier. SourceLocation StartLoc = Tok.getLocation(); bool IsValid = false; bool Value = false; // Read the '('. Lex(Tok); do { if (Tok.is(tok::l_paren)) { // Read the string. Lex(Tok); // We need at least one string literal. if (!Tok.is(tok::string_literal)) { StartLoc = Tok.getLocation(); IsValid = false; // Eat tokens until ')'. do Lex(Tok); while (!(Tok.is(tok::r_paren) || Tok.is(tok::eod))); break; } // String concatenation allows multiple strings, which can even come // from macro expansion. SmallVector<Token, 4> StrToks; while (Tok.is(tok::string_literal)) { StrToks.push_back(Tok); LexUnexpandedToken(Tok); } // Is the end a ')'? if (!(IsValid = Tok.is(tok::r_paren))) break; // Concatenate and parse the strings. StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this); assert(Literal.isAscii() && "Didn't allow wide strings in"); if (Literal.hadError) break; if (Literal.Pascal) { Diag(Tok, diag::warn_pragma_diagnostic_invalid); break; } StringRef WarningName(Literal.GetString()); if (WarningName.size() < 3 || WarningName[0] != '-' || WarningName[1] != 'W') { Diag(StrToks[0].getLocation(), diag::warn_has_warning_invalid_option); break; } // Finally, check if the warning flags maps to a diagnostic group. // We construct a SmallVector here to talk to getDiagnosticIDs(). // Although we don't use the result, this isn't a hot path, and not // worth special casing. llvm::SmallVector<diag::kind, 10> Diags; Value = !getDiagnostics().getDiagnosticIDs()-> getDiagnosticsInGroup(WarningName.substr(2), Diags); } } while (false); if (!IsValid) Diag(StartLoc, diag::err_warning_check_malformed); OS << (int)Value; Tok.setKind(tok::numeric_constant); } else { llvm_unreachable("Unknown identifier!"); } CreateString(OS.str().data(), OS.str().size(), Tok, Tok.getLocation(), Tok.getLocation()); }
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded /// as a builtin macro, handle it and return the next token as 'Tok'. void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // Figure out which token this is. IdentifierInfo *II = Tok.getIdentifierInfo(); assert(II && "Can't be a macro without id info!"); // If this is an _Pragma or Microsoft __pragma directive, expand it, // invoke the pragma handler, then lex the token after it. if (II == Ident_Pragma) return Handle_Pragma(Tok); else if (II == Ident__pragma) // in non-MS mode this is null return HandleMicrosoft__pragma(Tok); ++NumBuiltinMacroExpanded; llvm::SmallString<128> TmpBuffer; llvm::raw_svector_ostream OS(TmpBuffer); // Set up the return result. Tok.setIdentifierInfo(0); Tok.clearFlag(Token::NeedsCleaning); if (II == Ident__LINE__) { // C99 6.10.8: "__LINE__: The presumed line number (within the current // source file) of the current source line (an integer constant)". This can // be affected by #line. SourceLocation Loc = Tok.getLocation(); // Advance to the location of the first _, this might not be the first byte // of the token if it starts with an escaped newline. Loc = AdvanceToTokenCharacter(Loc, 0); // One wrinkle here is that GCC expands __LINE__ to location of the *end* of // a macro instantiation. This doesn't matter for object-like macros, but // can matter for a function-like macro that expands to contain __LINE__. // Skip down through instantiation points until we find a file loc for the // end of the instantiation history. Loc = SourceMgr.getInstantiationRange(Loc).second; PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc); // __LINE__ expands to a simple numeric value. OS << PLoc.getLine(); Tok.setKind(tok::numeric_constant); } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) { // C99 6.10.8: "__FILE__: The presumed name of the current source file (a // character string literal)". This can be affected by #line. PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); // __BASE_FILE__ is a GNU extension that returns the top of the presumed // #include stack instead of the current file. if (II == Ident__BASE_FILE__) { SourceLocation NextLoc = PLoc.getIncludeLoc(); while (NextLoc.isValid()) { PLoc = SourceMgr.getPresumedLoc(NextLoc); NextLoc = PLoc.getIncludeLoc(); } } // Escape this filename. Turn '\' -> '\\' '"' -> '\"' llvm::SmallString<128> FN; FN += PLoc.getFilename(); Lexer::Stringify(FN); OS << '"' << FN.str() << '"'; Tok.setKind(tok::string_literal); } else if (II == Ident__DATE__) { if (!DATELoc.isValid()) ComputeDATE_TIME(DATELoc, TIMELoc, *this); Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"Mmm dd yyyy\"")); Tok.setLocation(SourceMgr.createInstantiationLoc(DATELoc, Tok.getLocation(), Tok.getLocation(), Tok.getLength())); return; } else if (II == Ident__TIME__) { if (!TIMELoc.isValid()) ComputeDATE_TIME(DATELoc, TIMELoc, *this); Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"hh:mm:ss\"")); Tok.setLocation(SourceMgr.createInstantiationLoc(TIMELoc, Tok.getLocation(), Tok.getLocation(), Tok.getLength())); return; } else if (II == Ident__INCLUDE_LEVEL__) { // Compute the presumed include depth of this token. This can be affected // by GNU line markers. unsigned Depth = 0; PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc()); for (; PLoc.isValid(); ++Depth) PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc()); // __INCLUDE_LEVEL__ expands to a simple numeric value. OS << Depth; Tok.setKind(tok::numeric_constant); } else if (II == Ident__TIMESTAMP__) { // MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime. // Get the file that we are lexing out of. If we're currently lexing from // a macro, dig into the include stack. const FileEntry *CurFile = 0; PreprocessorLexer *TheLexer = getCurrentFileLexer(); if (TheLexer) CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID()); const char *Result; if (CurFile) { time_t TT = CurFile->getModificationTime(); struct tm *TM = localtime(&TT); Result = asctime(TM); } else { Result = "??? ??? ?? ??:??:?? ????\n"; } // Surround the string with " and strip the trailing newline. OS << '"' << llvm::StringRef(Result, strlen(Result)-1) << '"'; Tok.setKind(tok::string_literal); } else if (II == Ident__COUNTER__) { // __COUNTER__ expands to a simple numeric value. OS << CounterValue++; Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_feature || II == Ident__has_builtin) { // The argument to these two builtins should be a parenthesized identifier. SourceLocation StartLoc = Tok.getLocation(); bool IsValid = false; IdentifierInfo *FeatureII = 0; // Read the '('. Lex(Tok); if (Tok.is(tok::l_paren)) { // Read the identifier Lex(Tok); if (Tok.is(tok::identifier)) { FeatureII = Tok.getIdentifierInfo(); // Read the ')'. Lex(Tok); if (Tok.is(tok::r_paren)) IsValid = true; } } bool Value = false; if (!IsValid) Diag(StartLoc, diag::err_feature_check_malformed); else if (II == Ident__has_builtin) { // Check for a builtin is trivial. Value = FeatureII->getBuiltinID() != 0; } else { assert(II == Ident__has_feature && "Must be feature check"); Value = HasFeature(*this, FeatureII); } OS << (int)Value; Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_include || II == Ident__has_include_next) { // The argument to these two builtins should be a parenthesized // file name string literal using angle brackets (<>) or // double-quotes (""). bool Value = false; bool IsValid; if (II == Ident__has_include) IsValid = EvaluateHasInclude(Value, Tok, II, *this); else IsValid = EvaluateHasIncludeNext(Value, Tok, II, *this); OS << (int)Value; Tok.setKind(tok::numeric_constant); } else { assert(0 && "Unknown identifier!"); } CreateString(OS.str().data(), OS.str().size(), Tok, Tok.getLocation()); }