/// isTrivialSingleTokenExpansion - Return true if MI, which has a single token /// in its expansion, currently expands to that token literally. static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, const IdentifierInfo *MacroIdent, Preprocessor &PP) { IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo(); // If the token isn't an identifier, it's always literally expanded. if (II == 0) return true; // If the information about this identifier is out of date, update it from // the external source. if (II->isOutOfDate()) PP.getExternalSource()->updateOutOfDateIdentifier(*II); // If the identifier is a macro, and if that macro is enabled, it may be // expanded so it's not a trivial expansion. if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() && // Fast expanding "#define X X" is ok, because X would be disabled. II != MacroIdent) return false; // If this is an object-like macro invocation, it is safe to trivially expand // it. if (MI->isObjectLike()) return true; // If this is a function-like macro invocation, it's safe to trivially expand // as long as the identifier is not a macro argument. for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end(); I != E; ++I) if (*I == II) return false; // Identifier is a macro argument. return true; }
/// 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.LexUnexpandedToken(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.LexUnexpandedToken(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. // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) { MacroInfo *Macro = PP.getMacroInfo(II); Macro->setIsUsed(true); } // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); // If we are in parens, ensure we have a trailing ). if (LParenLoc.isValid()) { 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); } // Success, remember that we saw defined(X). DT.State = DefinedTracker::DefinedMacro; DT.TheMacro = II; return false; }
void PHPZPPCheckerImpl::initIdentifierInfo(ASTContext &Ctx) const { if (IIzpp) return; IIzpp = &Ctx.Idents.get("zend_parse_parameters"); IIzpp_ex = &Ctx.Idents.get("zend_parse_parameters_ex"); IIzpmp = &Ctx.Idents.get("zend_parse_method_parameters"); IIzpmp_ex = &Ctx.Idents.get("zend_parse_method_parameters_ex"); IdentifierInfo *tsrm = &Ctx.Idents.get("ZTS"); TSRMBuild = tsrm->hasMacroDefinition(); }
virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDirective *MD) override { Guard->Count++; // If this #ifndef is the top-most directive and the symbol isn't defined // store those information in the guard detection, the next step will be to // check for the define. if (Guard->Count == 1 && MD == nullptr) { IdentifierInfo *MII = MacroNameTok.getIdentifierInfo(); if (MII->hasMacroDefinition()) return; Guard->IfndefLoc = Loc; Guard->TheMacro = MII; } }
/// HandlePragmaPoison - Handle \#pragma GCC poison. PoisonTok is the 'poison'. /// void Preprocessor::HandlePragmaPoison(Token &PoisonTok) { Token Tok; while (1) { // Read the next token to poison. While doing this, pretend that we are // skipping while reading the identifier to poison. // This avoids errors on code like: // #pragma GCC poison X // #pragma GCC poison X if (CurPPLexer) CurPPLexer->LexingRawMode = true; LexUnexpandedToken(Tok); if (CurPPLexer) CurPPLexer->LexingRawMode = false; // If we reached the end of line, we're done. if (Tok.is(tok::eod)) return; // Can only poison identifiers. if (Tok.isNot(tok::raw_identifier)) { Diag(Tok, diag::err_pp_invalid_poison); return; } // Look up the identifier info for the token. We disabled identifier lookup // by saying we're skipping contents, so we need to do this manually. IdentifierInfo *II = LookUpIdentifierInfo(Tok); // Already poisoned. if (II->isPoisoned()) continue; // If this is a macro identifier, emit a warning. if (II->hasMacroDefinition()) Diag(Tok, diag::pp_poisoning_existing_macro); // Finally, poison it! II->setIsPoisoned(); if (II->isFromAST()) II->setChangedSinceDeserialization(); } }
/// \brief Handle \#pragma pop_macro. /// /// The syntax is: /// \code /// #pragma pop_macro("macro") /// \endcode void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { SourceLocation MessageLoc = PopMacroTok.getLocation(); // Parse the pragma directive and get the macro IdentifierInfo*. IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok); if (!IdentInfo) return; // Find the vector<MacroInfo*> associated with the macro. llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter = PragmaPushMacroInfo.find(IdentInfo); if (iter != PragmaPushMacroInfo.end()) { // Forget the MacroInfo currently associated with IdentInfo. if (MacroInfo *CurrentMI = getMacroInfo(IdentInfo)) { if (CurrentMI->isWarnIfUnused()) WarnUnusedMacroLocs.erase(CurrentMI->getDefinitionLoc()); UndefineMacro(IdentInfo, CurrentMI, MessageLoc); } // Get the MacroInfo we want to reinstall. MacroInfo *MacroToReInstall = iter->second.back(); if (MacroToReInstall) { // Reinstall the previously pushed macro. setMacroInfo(IdentInfo, MacroToReInstall); } else if (IdentInfo->hasMacroDefinition()) { clearMacroInfo(IdentInfo); } // Pop PragmaPushMacroInfo stack. iter->second.pop_back(); if (iter->second.size() == 0) PragmaPushMacroInfo.erase(iter); } else { Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push) << IdentInfo->getName(); } }
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; }
/// 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; }