diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2017-06-20 14:36:58 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2017-06-20 14:36:58 +0000 |
commit | ad870f82858671c5089809bda1286780506f4c81 (patch) | |
tree | 15ffc0592c6b35772da33cf078055947e9ae693d /clang/lib/Lex/PPExpressions.cpp | |
parent | 364a11651ed58d8ed8a30169ac179bb416d67c6b (diff) | |
download | bcm5719-llvm-ad870f82858671c5089809bda1286780506f4c81.tar.gz bcm5719-llvm-ad870f82858671c5089809bda1286780506f4c81.zip |
[preprocessor] When preprocessor option 'SingleFileParseMode' is enabled, parse all directive blocks if the condition uses undefined macros
This is useful for being able to parse the preprocessor directive blocks even if the header, that defined the macro that is checked, hasn't been included.
Differential Revision: https://reviews.llvm.org/D34263
llvm-svn: 305797
Diffstat (limited to 'clang/lib/Lex/PPExpressions.cpp')
-rw-r--r-- | clang/lib/Lex/PPExpressions.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 862a4713e4b..12f5084298d 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -73,6 +73,7 @@ public: static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, + bool &IncludedUndefinedIds, Preprocessor &PP); /// DefinedTracker - This struct is used while parsing expressions to keep track @@ -93,6 +94,7 @@ struct DefinedTracker { /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this /// indicates the macro that was checked. IdentifierInfo *TheMacro; + bool IncludedUndefinedIds = false; }; /// EvaluateDefined - Process a 'defined(sym)' expression. @@ -128,6 +130,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, MacroDefinition Macro = PP.getMacroDefinition(II); Result.Val = !!Macro; Result.Val.setIsUnsigned(false); // Result is signed intmax_t. + DT.IncludedUndefinedIds = !Macro; // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) @@ -255,6 +258,8 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0. Result.setIdentifier(II); Result.setRange(PeekTok.getLocation()); + DT.IncludedUndefinedIds = (II->getTokenID() != tok::kw_true && + II->getTokenID() != tok::kw_false); PP.LexNonComment(PeekTok); return false; } @@ -400,7 +405,8 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Just use DT unmodified as our result. } else { // Otherwise, we have something like (x+y), and we consumed '(x'. - if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, PP)) + if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, + DT.IncludedUndefinedIds, PP)) return true; if (PeekTok.isNot(tok::r_paren)) { @@ -532,6 +538,7 @@ static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS, /// evaluation, such as division by zero warnings. static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, + bool &IncludedUndefinedIds, Preprocessor &PP) { unsigned PeekPrec = getPrecedence(PeekTok.getKind()); // If this token isn't valid, report the error. @@ -571,6 +578,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, // Parse the RHS of the operator. DefinedTracker DT; if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true; + IncludedUndefinedIds = DT.IncludedUndefinedIds; // Remember the precedence of this operator and get the precedence of the // operator immediately to the right of the RHS. @@ -601,7 +609,8 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, RHSPrec = ThisPrec+1; if (PeekPrec >= RHSPrec) { - if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP)) + if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, + IncludedUndefinedIds, PP)) return true; PeekPrec = getPrecedence(PeekTok.getKind()); } @@ -769,7 +778,8 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, // Parse anything after the : with the same precedence as ?. We allow // things of equal precedence because ?: is right associative. if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec, - PeekTok, AfterColonLive, PP)) + PeekTok, AfterColonLive, + IncludedUndefinedIds, PP)) return true; // Now that we have the condition, the LHS and the RHS of the :, evaluate. @@ -806,7 +816,8 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, /// EvaluateDirectiveExpression - Evaluate an integer constant expression that /// may occur after a #if or #elif directive. If the expression is equivalent /// to "!defined(X)" return X in IfNDefMacro. -bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { +Preprocessor::DirectiveEvalResult +Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { SaveAndRestore<bool> PPDir(ParsingIfOrElifDirective, true); // Save the current state of 'DisableMacroExpansion' and reset it to false. If // 'DisableMacroExpansion' is true, then we must be in a macro argument list @@ -833,7 +844,7 @@ bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return false; + return {false, DT.IncludedUndefinedIds}; } // If we are at the end of the expression after just parsing a value, there @@ -847,20 +858,20 @@ bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return ResVal.Val != 0; + return {ResVal.Val != 0, DT.IncludedUndefinedIds}; } // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the // operator and the stuff after it. if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question), - Tok, true, *this)) { + Tok, true, DT.IncludedUndefinedIds, *this)) { // Parse error, skip the rest of the macro line. if (Tok.isNot(tok::eod)) DiscardUntilEndOfDirective(); // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return false; + return {false, DT.IncludedUndefinedIds}; } // If we aren't at the tok::eod token, something bad happened, like an extra @@ -872,5 +883,5 @@ bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return ResVal.Val != 0; + return {ResVal.Val != 0, DT.IncludedUndefinedIds}; } |