diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-04-16 00:07:09 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-04-16 00:07:09 +0000 |
| commit | 4d247e7012ae6355c9b63b6a6549adadd0a16fd1 (patch) | |
| tree | 7a9023b34b23836242445e0198efc694ec78c0ce /clang/lib | |
| parent | 60469e2ac0248f29afb4a9247913410ecef8ddd4 (diff) | |
| download | bcm5719-llvm-4d247e7012ae6355c9b63b6a6549adadd0a16fd1.tar.gz bcm5719-llvm-4d247e7012ae6355c9b63b6a6549adadd0a16fd1.zip | |
Improve diagnostic for the case when a non-defined function-like macro is used
in a preprocessor constant expression.
llvm-svn: 266495
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Lex/PPExpressions.cpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 058e2741d7a..94075ece35c 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -33,12 +33,18 @@ namespace { /// conditional and the source range covered by it. class PPValue { SourceRange Range; + IdentifierInfo *II; public: llvm::APSInt Val; // Default ctor - Construct an 'invalid' PPValue. PPValue(unsigned BitWidth) : Val(BitWidth) {} + // If this value was produced by directly evaluating an identifier, produce + // that identifier. + IdentifierInfo *getIdentifier() const { return II; } + void setIdentifier(IdentifierInfo *II) { this->II = II; } + unsigned getBitWidth() const { return Val.getBitWidth(); } bool isUnsigned() const { return Val.isUnsigned(); } @@ -209,6 +215,8 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP) { DT.State = DefinedTracker::Unknown; + Result.setIdentifier(nullptr); + if (PeekTok.is(tok::code_completion)) { if (PP.getCodeCompletionHandler()) PP.getCodeCompletionHandler()->CodeCompletePreprocessorExpression(); @@ -234,6 +242,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II; Result.Val = II->getTokenID() == tok::kw_true; Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0. + Result.setIdentifier(II); Result.setRange(PeekTok.getLocation()); PP.LexNonComment(PeekTok); return false; @@ -392,6 +401,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, DT.State = DefinedTracker::Unknown; } Result.setRange(Start, PeekTok.getLocation()); + Result.setIdentifier(nullptr); PP.LexNonComment(PeekTok); // Eat the ). return false; } @@ -401,6 +411,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, PP.LexNonComment(PeekTok); if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true; Result.setBegin(Start); + Result.setIdentifier(nullptr); return false; } case tok::minus: { @@ -408,6 +419,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, PP.LexNonComment(PeekTok); if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true; Result.setBegin(Loc); + Result.setIdentifier(nullptr); // C99 6.5.3.3p3: The sign of the result matches the sign of the operand. Result.Val = -Result.Val; @@ -428,6 +440,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, PP.LexNonComment(PeekTok); if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true; Result.setBegin(Start); + Result.setIdentifier(nullptr); // C99 6.5.3.3p4: The sign of the result matches the sign of the operand. Result.Val = ~Result.Val; @@ -443,6 +456,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, Result.Val = !Result.Val; // C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed. Result.Val.setIsUnsigned(false); + Result.setIdentifier(nullptr); if (DT.State == DefinedTracker::DefinedMacro) DT.State = DefinedTracker::NotDefinedMacro; @@ -491,6 +505,15 @@ static unsigned getPrecedence(tok::TokenKind Kind) { } } +static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS, + Token &Tok) { + if (Tok.is(tok::l_paren) && LHS.getIdentifier()) + PP.Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen) + << LHS.getIdentifier(); + else + PP.Diag(Tok.getLocation(), diag::err_pp_expr_bad_token_binop) + << LHS.getRange(); +} /// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is /// PeekTok, and whose precedence is PeekPrec. This returns the result in LHS. @@ -504,8 +527,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, unsigned PeekPrec = getPrecedence(PeekTok.getKind()); // If this token isn't valid, report the error. if (PeekPrec == ~0U) { - PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop) - << LHS.getRange(); + diagnoseUnexpectedOperator(PP, LHS, PeekTok); return true; } @@ -548,8 +570,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, // If this token isn't valid, report the error. if (PeekPrec == ~0U) { - PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop) - << RHS.getRange(); + diagnoseUnexpectedOperator(PP, RHS, PeekTok); return true; } @@ -769,6 +790,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, // Put the result back into 'LHS' for our next iteration. LHS.Val = Res; LHS.setEnd(RHS.getRange().getEnd()); + RHS.setIdentifier(nullptr); } } |

