diff options
Diffstat (limited to 'clang/lib/Lex/PPExpressions.cpp')
-rw-r--r-- | clang/lib/Lex/PPExpressions.cpp | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index f267efabd..8bb82bd 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -870,7 +870,9 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, /// may occur after a #if or #elif directive. If the expression is equivalent /// to "!defined(X)" return X in IfNDefMacro. Preprocessor::DirectiveEvalResult -Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { +Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro, + Token &Tok, bool &EvaluatedDefined, + bool CheckForEoD) { SaveAndRestore 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 @@ -882,7 +884,6 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { DisableMacroExpansion = false; // Peek ahead one token. - Token Tok; LexNonComment(Tok); // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t. @@ -895,7 +896,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Parse error, skip the rest of the macro line. SourceRange ConditionRange = ExprStartLoc; if (Tok.isNot(tok::eod)) - ConditionRange = DiscardUntilEndOfDirective(); + ConditionRange = DiscardUntilEndOfDirective(Tok); // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; @@ -903,11 +904,14 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // We cannot trust the source range from the value because there was a // parse error. Track the range manually -- the end of the directive is the // end of the condition range. - return {false, + return {std::nullopt, + false, DT.IncludedUndefinedIds, {ExprStartLoc, ConditionRange.getEnd()}}; } + EvaluatedDefined = DT.State != DefinedTracker::Unknown; + // If we are at the end of the expression after just parsing a value, there // must be no (unparenthesized) binary operators involved, so we can exit // directly. @@ -919,7 +923,10 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return {ResVal.Val != 0, DT.IncludedUndefinedIds, ResVal.getRange()}; + bool IsNonZero = ResVal.Val != 0; + SourceRange ValRange = ResVal.getRange(); + return {std::move(ResVal.Val), IsNonZero, DT.IncludedUndefinedIds, + ValRange}; } // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the @@ -928,21 +935,37 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { Tok, true, DT.IncludedUndefinedIds, *this)) { // Parse error, skip the rest of the macro line. if (Tok.isNot(tok::eod)) - DiscardUntilEndOfDirective(); + DiscardUntilEndOfDirective(Tok); // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return {false, DT.IncludedUndefinedIds, ResVal.getRange()}; + SourceRange ValRange = ResVal.getRange(); + return {std::nullopt, false, DT.IncludedUndefinedIds, ValRange}; } - // If we aren't at the tok::eod token, something bad happened, like an extra - // ')' token. - if (Tok.isNot(tok::eod)) { - Diag(Tok, diag::err_pp_expected_eol); - DiscardUntilEndOfDirective(); + if (CheckForEoD) { + // If we aren't at the tok::eod token, something bad happened, like an extra + // ')' token. + if (Tok.isNot(tok::eod)) { + Diag(Tok, diag::err_pp_expected_eol); + DiscardUntilEndOfDirective(Tok); + } } + EvaluatedDefined = EvaluatedDefined || DT.State != DefinedTracker::Unknown; + // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return {ResVal.Val != 0, DT.IncludedUndefinedIds, ResVal.getRange()}; + bool IsNonZero = ResVal.Val != 0; + SourceRange ValRange = ResVal.getRange(); + return {std::move(ResVal.Val), IsNonZero, DT.IncludedUndefinedIds, ValRange}; +} + +Preprocessor::DirectiveEvalResult +Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro, + bool CheckForEoD) { + Token Tok; + bool EvaluatedDefined; + return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined, + CheckForEoD); } |