xref: /freebsd/contrib/llvm-project/clang/lib/Lex/PPExpressions.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- PPExpressions.cpp - Preprocessor Expression Evaluation -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the Preprocessor::EvaluateDirectiveExpression method,
100b57cec5SDimitry Andric // which parses and evaluates integer constant expressions for #if directives.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric // FIXME: implement testing for #assert's.
150b57cec5SDimitry Andric //
160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
190b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
200b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
210b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
220b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.h"
230b57cec5SDimitry Andric #include "clang/Lex/CodeCompletionHandler.h"
240b57cec5SDimitry Andric #include "clang/Lex/LexDiagnostic.h"
250b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h"
260b57cec5SDimitry Andric #include "clang/Lex/MacroInfo.h"
270b57cec5SDimitry Andric #include "clang/Lex/PPCallbacks.h"
285ffd83dbSDimitry Andric #include "clang/Lex/Preprocessor.h"
290b57cec5SDimitry Andric #include "clang/Lex/Token.h"
300b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
315ffd83dbSDimitry Andric #include "llvm/ADT/STLExtras.h"
320b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
335ffd83dbSDimitry Andric #include "llvm/ADT/StringExtras.h"
340b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
350b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
360b57cec5SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
370b57cec5SDimitry Andric #include <cassert>
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric using namespace clang;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric namespace {
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric /// PPValue - Represents the value of a subexpression of a preprocessor
440b57cec5SDimitry Andric /// conditional and the source range covered by it.
450b57cec5SDimitry Andric class PPValue {
460b57cec5SDimitry Andric   SourceRange Range;
4706c3fb27SDimitry Andric   IdentifierInfo *II = nullptr;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric public:
500b57cec5SDimitry Andric   llvm::APSInt Val;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   // Default ctor - Construct an 'invalid' PPValue.
PPValue(unsigned BitWidth)530b57cec5SDimitry Andric   PPValue(unsigned BitWidth) : Val(BitWidth) {}
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   // If this value was produced by directly evaluating an identifier, produce
560b57cec5SDimitry Andric   // that identifier.
getIdentifier() const570b57cec5SDimitry Andric   IdentifierInfo *getIdentifier() const { return II; }
setIdentifier(IdentifierInfo * II)580b57cec5SDimitry Andric   void setIdentifier(IdentifierInfo *II) { this->II = II; }
590b57cec5SDimitry Andric 
getBitWidth() const600b57cec5SDimitry Andric   unsigned getBitWidth() const { return Val.getBitWidth(); }
isUnsigned() const610b57cec5SDimitry Andric   bool isUnsigned() const { return Val.isUnsigned(); }
620b57cec5SDimitry Andric 
getRange() const630b57cec5SDimitry Andric   SourceRange getRange() const { return Range; }
640b57cec5SDimitry Andric 
setRange(SourceLocation L)650b57cec5SDimitry Andric   void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }
setRange(SourceLocation B,SourceLocation E)660b57cec5SDimitry Andric   void setRange(SourceLocation B, SourceLocation E) {
670b57cec5SDimitry Andric     Range.setBegin(B); Range.setEnd(E);
680b57cec5SDimitry Andric   }
setBegin(SourceLocation L)690b57cec5SDimitry Andric   void setBegin(SourceLocation L) { Range.setBegin(L); }
setEnd(SourceLocation L)700b57cec5SDimitry Andric   void setEnd(SourceLocation L) { Range.setEnd(L); }
710b57cec5SDimitry Andric };
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric } // end anonymous namespace
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
760b57cec5SDimitry Andric                                      Token &PeekTok, bool ValueLive,
770b57cec5SDimitry Andric                                      bool &IncludedUndefinedIds,
780b57cec5SDimitry Andric                                      Preprocessor &PP);
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric /// DefinedTracker - This struct is used while parsing expressions to keep track
810b57cec5SDimitry Andric /// of whether !defined(X) has been seen.
820b57cec5SDimitry Andric ///
830b57cec5SDimitry Andric /// With this simple scheme, we handle the basic forms:
840b57cec5SDimitry Andric ///    !defined(X)   and !defined X
850b57cec5SDimitry Andric /// but we also trivially handle (silly) stuff like:
860b57cec5SDimitry Andric ///    !!!defined(X) and +!defined(X) and !+!+!defined(X) and !(defined(X)).
870b57cec5SDimitry Andric struct DefinedTracker {
880b57cec5SDimitry Andric   /// Each time a Value is evaluated, it returns information about whether the
890b57cec5SDimitry Andric   /// parsed value is of the form defined(X), !defined(X) or is something else.
900b57cec5SDimitry Andric   enum TrackerState {
910b57cec5SDimitry Andric     DefinedMacro,        // defined(X)
920b57cec5SDimitry Andric     NotDefinedMacro,     // !defined(X)
930b57cec5SDimitry Andric     Unknown              // Something else.
940b57cec5SDimitry Andric   } State;
950b57cec5SDimitry Andric   /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this
960b57cec5SDimitry Andric   /// indicates the macro that was checked.
970b57cec5SDimitry Andric   IdentifierInfo *TheMacro;
980b57cec5SDimitry Andric   bool IncludedUndefinedIds = false;
990b57cec5SDimitry Andric };
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric /// EvaluateDefined - Process a 'defined(sym)' expression.
EvaluateDefined(PPValue & Result,Token & PeekTok,DefinedTracker & DT,bool ValueLive,Preprocessor & PP)1020b57cec5SDimitry Andric static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
1030b57cec5SDimitry Andric                             bool ValueLive, Preprocessor &PP) {
1040b57cec5SDimitry Andric   SourceLocation beginLoc(PeekTok.getLocation());
1050b57cec5SDimitry Andric   Result.setBegin(beginLoc);
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   // Get the next token, don't expand it.
1080b57cec5SDimitry Andric   PP.LexUnexpandedNonComment(PeekTok);
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   // Two options, it can either be a pp-identifier or a (.
1110b57cec5SDimitry Andric   SourceLocation LParenLoc;
1120b57cec5SDimitry Andric   if (PeekTok.is(tok::l_paren)) {
1130b57cec5SDimitry Andric     // Found a paren, remember we saw it and skip it.
1140b57cec5SDimitry Andric     LParenLoc = PeekTok.getLocation();
1150b57cec5SDimitry Andric     PP.LexUnexpandedNonComment(PeekTok);
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   if (PeekTok.is(tok::code_completion)) {
1190b57cec5SDimitry Andric     if (PP.getCodeCompletionHandler())
1200b57cec5SDimitry Andric       PP.getCodeCompletionHandler()->CodeCompleteMacroName(false);
1210b57cec5SDimitry Andric     PP.setCodeCompletionReached();
1220b57cec5SDimitry Andric     PP.LexUnexpandedNonComment(PeekTok);
1230b57cec5SDimitry Andric   }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   // If we don't have a pp-identifier now, this is an error.
1260b57cec5SDimitry Andric   if (PP.CheckMacroName(PeekTok, MU_Other))
1270b57cec5SDimitry Andric     return true;
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   // Otherwise, we got an identifier, is it defined to something?
1300b57cec5SDimitry Andric   IdentifierInfo *II = PeekTok.getIdentifierInfo();
1310b57cec5SDimitry Andric   MacroDefinition Macro = PP.getMacroDefinition(II);
1320b57cec5SDimitry Andric   Result.Val = !!Macro;
1330b57cec5SDimitry Andric   Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
1340b57cec5SDimitry Andric   DT.IncludedUndefinedIds = !Macro;
1350b57cec5SDimitry Andric 
136b3edf446SDimitry Andric   PP.emitMacroExpansionWarnings(
137b3edf446SDimitry Andric       PeekTok,
138b3edf446SDimitry Andric       (II->getName() == "INFINITY" || II->getName() == "NAN") ? true : false);
139349cc55cSDimitry Andric 
1400b57cec5SDimitry Andric   // If there is a macro, mark it used.
1410b57cec5SDimitry Andric   if (Result.Val != 0 && ValueLive)
1420b57cec5SDimitry Andric     PP.markMacroAsUsed(Macro.getMacroInfo());
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   // Save macro token for callback.
1450b57cec5SDimitry Andric   Token macroToken(PeekTok);
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   // If we are in parens, ensure we have a trailing ).
1480b57cec5SDimitry Andric   if (LParenLoc.isValid()) {
1490b57cec5SDimitry Andric     // Consume identifier.
1500b57cec5SDimitry Andric     Result.setEnd(PeekTok.getLocation());
1510b57cec5SDimitry Andric     PP.LexUnexpandedNonComment(PeekTok);
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric     if (PeekTok.isNot(tok::r_paren)) {
1540b57cec5SDimitry Andric       PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after)
1550b57cec5SDimitry Andric           << "'defined'" << tok::r_paren;
1560b57cec5SDimitry Andric       PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1570b57cec5SDimitry Andric       return true;
1580b57cec5SDimitry Andric     }
1590b57cec5SDimitry Andric     // Consume the ).
1600b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
1610b57cec5SDimitry Andric     Result.setEnd(PeekTok.getLocation());
1620b57cec5SDimitry Andric   } else {
1630b57cec5SDimitry Andric     // Consume identifier.
1640b57cec5SDimitry Andric     Result.setEnd(PeekTok.getLocation());
1650b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
1660b57cec5SDimitry Andric   }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   // [cpp.cond]p4:
1690b57cec5SDimitry Andric   //   Prior to evaluation, macro invocations in the list of preprocessing
1700b57cec5SDimitry Andric   //   tokens that will become the controlling constant expression are replaced
1710b57cec5SDimitry Andric   //   (except for those macro names modified by the 'defined' unary operator),
1720b57cec5SDimitry Andric   //   just as in normal text. If the token 'defined' is generated as a result
1730b57cec5SDimitry Andric   //   of this replacement process or use of the 'defined' unary operator does
1740b57cec5SDimitry Andric   //   not match one of the two specified forms prior to macro replacement, the
1750b57cec5SDimitry Andric   //   behavior is undefined.
1760b57cec5SDimitry Andric   // This isn't an idle threat, consider this program:
1770b57cec5SDimitry Andric   //   #define FOO
1780b57cec5SDimitry Andric   //   #define BAR defined(FOO)
1790b57cec5SDimitry Andric   //   #if BAR
1800b57cec5SDimitry Andric   //   ...
1810b57cec5SDimitry Andric   //   #else
1820b57cec5SDimitry Andric   //   ...
1830b57cec5SDimitry Andric   //   #endif
1840b57cec5SDimitry Andric   // clang and gcc will pick the #if branch while Visual Studio will take the
1850b57cec5SDimitry Andric   // #else branch.  Emit a warning about this undefined behavior.
1860b57cec5SDimitry Andric   if (beginLoc.isMacroID()) {
1870b57cec5SDimitry Andric     bool IsFunctionTypeMacro =
1880b57cec5SDimitry Andric         PP.getSourceManager()
1890b57cec5SDimitry Andric             .getSLocEntry(PP.getSourceManager().getFileID(beginLoc))
1900b57cec5SDimitry Andric             .getExpansion()
1910b57cec5SDimitry Andric             .isFunctionMacroExpansion();
1920b57cec5SDimitry Andric     // For object-type macros, it's easy to replace
1930b57cec5SDimitry Andric     //   #define FOO defined(BAR)
1940b57cec5SDimitry Andric     // with
1950b57cec5SDimitry Andric     //   #if defined(BAR)
1960b57cec5SDimitry Andric     //   #define FOO 1
1970b57cec5SDimitry Andric     //   #else
1980b57cec5SDimitry Andric     //   #define FOO 0
1990b57cec5SDimitry Andric     //   #endif
2000b57cec5SDimitry Andric     // and doing so makes sense since compilers handle this differently in
2010b57cec5SDimitry Andric     // practice (see example further up).  But for function-type macros,
2020b57cec5SDimitry Andric     // there is no good way to write
2030b57cec5SDimitry Andric     //   # define FOO(x) (defined(M_ ## x) && M_ ## x)
2040b57cec5SDimitry Andric     // in a different way, and compilers seem to agree on how to behave here.
2050b57cec5SDimitry Andric     // So warn by default on object-type macros, but only warn in -pedantic
2060b57cec5SDimitry Andric     // mode on function-type macros.
2070b57cec5SDimitry Andric     if (IsFunctionTypeMacro)
2080b57cec5SDimitry Andric       PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);
2090b57cec5SDimitry Andric     else
2100b57cec5SDimitry Andric       PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   // Invoke the 'defined' callback.
2140b57cec5SDimitry Andric   if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
2150b57cec5SDimitry Andric     Callbacks->Defined(macroToken, Macro,
2160b57cec5SDimitry Andric                        SourceRange(beginLoc, PeekTok.getLocation()));
2170b57cec5SDimitry Andric   }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   // Success, remember that we saw defined(X).
2200b57cec5SDimitry Andric   DT.State = DefinedTracker::DefinedMacro;
2210b57cec5SDimitry Andric   DT.TheMacro = II;
2220b57cec5SDimitry Andric   return false;
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric /// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
2260b57cec5SDimitry Andric /// return the computed value in Result.  Return true if there was an error
2270b57cec5SDimitry Andric /// parsing.  This function also returns information about the form of the
2280b57cec5SDimitry Andric /// expression in DT.  See above for information on what DT means.
2290b57cec5SDimitry Andric ///
2300b57cec5SDimitry Andric /// If ValueLive is false, then this value is being evaluated in a context where
2310b57cec5SDimitry Andric /// the result is not used.  As such, avoid diagnostics that relate to
2320b57cec5SDimitry Andric /// evaluation.
EvaluateValue(PPValue & Result,Token & PeekTok,DefinedTracker & DT,bool ValueLive,Preprocessor & PP)2330b57cec5SDimitry Andric static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
2340b57cec5SDimitry Andric                           bool ValueLive, Preprocessor &PP) {
2350b57cec5SDimitry Andric   DT.State = DefinedTracker::Unknown;
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   Result.setIdentifier(nullptr);
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   if (PeekTok.is(tok::code_completion)) {
2400b57cec5SDimitry Andric     if (PP.getCodeCompletionHandler())
2410b57cec5SDimitry Andric       PP.getCodeCompletionHandler()->CodeCompletePreprocessorExpression();
2420b57cec5SDimitry Andric     PP.setCodeCompletionReached();
2430b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
2440b57cec5SDimitry Andric   }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric   switch (PeekTok.getKind()) {
2470b57cec5SDimitry Andric   default:
2480b57cec5SDimitry Andric     // If this token's spelling is a pp-identifier, check to see if it is
2490b57cec5SDimitry Andric     // 'defined' or if it is a macro.  Note that we check here because many
2500b57cec5SDimitry Andric     // keywords are pp-identifiers, so we can't check the kind.
2510b57cec5SDimitry Andric     if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
2520b57cec5SDimitry Andric       // Handle "defined X" and "defined(X)".
2530b57cec5SDimitry Andric       if (II->isStr("defined"))
2540b57cec5SDimitry Andric         return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric       if (!II->isCPlusPlusOperatorKeyword()) {
2570b57cec5SDimitry Andric         // If this identifier isn't 'defined' or one of the special
2580b57cec5SDimitry Andric         // preprocessor keywords and it wasn't macro expanded, it turns
2590b57cec5SDimitry Andric         // into a simple 0
2605ffd83dbSDimitry Andric         if (ValueLive) {
2610b57cec5SDimitry Andric           PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
2625ffd83dbSDimitry Andric 
2635ffd83dbSDimitry Andric           const DiagnosticsEngine &DiagEngine = PP.getDiagnostics();
2645ffd83dbSDimitry Andric           // If 'Wundef' is enabled, do not emit 'undef-prefix' diagnostics.
2655ffd83dbSDimitry Andric           if (DiagEngine.isIgnored(diag::warn_pp_undef_identifier,
2665ffd83dbSDimitry Andric                                    PeekTok.getLocation())) {
2675ffd83dbSDimitry Andric             const std::vector<std::string> UndefPrefixes =
2685ffd83dbSDimitry Andric                 DiagEngine.getDiagnosticOptions().UndefPrefixes;
2695ffd83dbSDimitry Andric             const StringRef IdentifierName = II->getName();
2705ffd83dbSDimitry Andric             if (llvm::any_of(UndefPrefixes,
2715ffd83dbSDimitry Andric                              [&IdentifierName](const std::string &Prefix) {
2725f757f3fSDimitry Andric                                return IdentifierName.starts_with(Prefix);
2735ffd83dbSDimitry Andric                              }))
2745ffd83dbSDimitry Andric               PP.Diag(PeekTok, diag::warn_pp_undef_prefix)
2755ffd83dbSDimitry Andric                   << AddFlagValue{llvm::join(UndefPrefixes, ",")} << II;
2765ffd83dbSDimitry Andric           }
2775ffd83dbSDimitry Andric         }
2780b57cec5SDimitry Andric         Result.Val = 0;
2790b57cec5SDimitry Andric         Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
2800b57cec5SDimitry Andric         Result.setIdentifier(II);
2810b57cec5SDimitry Andric         Result.setRange(PeekTok.getLocation());
2820b57cec5SDimitry Andric         DT.IncludedUndefinedIds = true;
2830b57cec5SDimitry Andric         PP.LexNonComment(PeekTok);
2840b57cec5SDimitry Andric         return false;
2850b57cec5SDimitry Andric       }
2860b57cec5SDimitry Andric     }
2870b57cec5SDimitry Andric     PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
2880b57cec5SDimitry Andric     return true;
2890b57cec5SDimitry Andric   case tok::eod:
2900b57cec5SDimitry Andric   case tok::r_paren:
2910b57cec5SDimitry Andric     // If there is no expression, report and exit.
2920b57cec5SDimitry Andric     PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
2930b57cec5SDimitry Andric     return true;
2940b57cec5SDimitry Andric   case tok::numeric_constant: {
2950b57cec5SDimitry Andric     SmallString<64> IntegerBuffer;
2960b57cec5SDimitry Andric     bool NumberInvalid = false;
2970b57cec5SDimitry Andric     StringRef Spelling = PP.getSpelling(PeekTok, IntegerBuffer,
2980b57cec5SDimitry Andric                                               &NumberInvalid);
2990b57cec5SDimitry Andric     if (NumberInvalid)
3000b57cec5SDimitry Andric       return true; // a diagnostic was already reported
3010b57cec5SDimitry Andric 
3025ffd83dbSDimitry Andric     NumericLiteralParser Literal(Spelling, PeekTok.getLocation(),
3035ffd83dbSDimitry Andric                                  PP.getSourceManager(), PP.getLangOpts(),
3045ffd83dbSDimitry Andric                                  PP.getTargetInfo(), PP.getDiagnostics());
3050b57cec5SDimitry Andric     if (Literal.hadError)
3060b57cec5SDimitry Andric       return true; // a diagnostic was already reported.
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric     if (Literal.isFloatingLiteral() || Literal.isImaginary) {
3090b57cec5SDimitry Andric       PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
3100b57cec5SDimitry Andric       return true;
3110b57cec5SDimitry Andric     }
3120b57cec5SDimitry Andric     assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric     // Complain about, and drop, any ud-suffix.
3150b57cec5SDimitry Andric     if (Literal.hasUDSuffix())
3160b57cec5SDimitry Andric       PP.Diag(PeekTok, diag::err_pp_invalid_udl) << /*integer*/1;
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric     // 'long long' is a C99 or C++11 feature.
3190b57cec5SDimitry Andric     if (!PP.getLangOpts().C99 && Literal.isLongLong) {
3200b57cec5SDimitry Andric       if (PP.getLangOpts().CPlusPlus)
3210b57cec5SDimitry Andric         PP.Diag(PeekTok,
3220b57cec5SDimitry Andric              PP.getLangOpts().CPlusPlus11 ?
3230b57cec5SDimitry Andric              diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
3240b57cec5SDimitry Andric       else
3250b57cec5SDimitry Andric         PP.Diag(PeekTok, diag::ext_c99_longlong);
3260b57cec5SDimitry Andric     }
3270b57cec5SDimitry Andric 
32806c3fb27SDimitry Andric     // 'z/uz' literals are a C++23 feature.
329fe6060f1SDimitry Andric     if (Literal.isSizeT)
330fe6060f1SDimitry Andric       PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus
33106c3fb27SDimitry Andric                            ? PP.getLangOpts().CPlusPlus23
332fe6060f1SDimitry Andric                                  ? diag::warn_cxx20_compat_size_t_suffix
33306c3fb27SDimitry Andric                                  : diag::ext_cxx23_size_t_suffix
33406c3fb27SDimitry Andric                            : diag::err_cxx23_size_t_suffix);
335fe6060f1SDimitry Andric 
336*0fca6ea1SDimitry Andric     // 'wb/uwb' literals are a C23 feature.
337*0fca6ea1SDimitry Andric     // '__wb/__uwb' are a C++ extension.
33881ad6265SDimitry Andric     if (Literal.isBitInt)
339*0fca6ea1SDimitry Andric       PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
340*0fca6ea1SDimitry Andric                        : PP.getLangOpts().C23
3415f757f3fSDimitry Andric                            ? diag::warn_c23_compat_bitint_suffix
3425f757f3fSDimitry Andric                            : diag::ext_c23_bitint_suffix);
34381ad6265SDimitry Andric 
3440b57cec5SDimitry Andric     // Parse the integer literal into Result.
3450b57cec5SDimitry Andric     if (Literal.GetIntegerValue(Result.Val)) {
3460b57cec5SDimitry Andric       // Overflow parsing integer literal.
3470b57cec5SDimitry Andric       if (ValueLive)
3480b57cec5SDimitry Andric         PP.Diag(PeekTok, diag::err_integer_literal_too_large)
3490b57cec5SDimitry Andric             << /* Unsigned */ 1;
3500b57cec5SDimitry Andric       Result.Val.setIsUnsigned(true);
3510b57cec5SDimitry Andric     } else {
3520b57cec5SDimitry Andric       // Set the signedness of the result to match whether there was a U suffix
3530b57cec5SDimitry Andric       // or not.
3540b57cec5SDimitry Andric       Result.Val.setIsUnsigned(Literal.isUnsigned);
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric       // Detect overflow based on whether the value is signed.  If signed
3570b57cec5SDimitry Andric       // and if the value is too large, emit a warning "integer constant is so
3580b57cec5SDimitry Andric       // large that it is unsigned" e.g. on 12345678901234567890 where intmax_t
3590b57cec5SDimitry Andric       // is 64-bits.
3600b57cec5SDimitry Andric       if (!Literal.isUnsigned && Result.Val.isNegative()) {
3610b57cec5SDimitry Andric         // Octal, hexadecimal, and binary literals are implicitly unsigned if
3620b57cec5SDimitry Andric         // the value does not fit into a signed integer type.
3630b57cec5SDimitry Andric         if (ValueLive && Literal.getRadix() == 10)
3640b57cec5SDimitry Andric           PP.Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
3650b57cec5SDimitry Andric         Result.Val.setIsUnsigned(true);
3660b57cec5SDimitry Andric       }
3670b57cec5SDimitry Andric     }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric     // Consume the token.
3700b57cec5SDimitry Andric     Result.setRange(PeekTok.getLocation());
3710b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
3720b57cec5SDimitry Andric     return false;
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric   case tok::char_constant:          // 'x'
3750b57cec5SDimitry Andric   case tok::wide_char_constant:     // L'x'
3760b57cec5SDimitry Andric   case tok::utf8_char_constant:     // u8'x'
3770b57cec5SDimitry Andric   case tok::utf16_char_constant:    // u'x'
3780b57cec5SDimitry Andric   case tok::utf32_char_constant: {  // U'x'
3790b57cec5SDimitry Andric     // Complain about, and drop, any ud-suffix.
3800b57cec5SDimitry Andric     if (PeekTok.hasUDSuffix())
3810b57cec5SDimitry Andric       PP.Diag(PeekTok, diag::err_pp_invalid_udl) << /*character*/0;
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric     SmallString<32> CharBuffer;
3840b57cec5SDimitry Andric     bool CharInvalid = false;
3850b57cec5SDimitry Andric     StringRef ThisTok = PP.getSpelling(PeekTok, CharBuffer, &CharInvalid);
3860b57cec5SDimitry Andric     if (CharInvalid)
3870b57cec5SDimitry Andric       return true;
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric     CharLiteralParser Literal(ThisTok.begin(), ThisTok.end(),
3900b57cec5SDimitry Andric                               PeekTok.getLocation(), PP, PeekTok.getKind());
3910b57cec5SDimitry Andric     if (Literal.hadError())
3920b57cec5SDimitry Andric       return true;  // A diagnostic was already emitted.
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric     // Character literals are always int or wchar_t, expand to intmax_t.
3950b57cec5SDimitry Andric     const TargetInfo &TI = PP.getTargetInfo();
3960b57cec5SDimitry Andric     unsigned NumBits;
3970b57cec5SDimitry Andric     if (Literal.isMultiChar())
3980b57cec5SDimitry Andric       NumBits = TI.getIntWidth();
3990b57cec5SDimitry Andric     else if (Literal.isWide())
4000b57cec5SDimitry Andric       NumBits = TI.getWCharWidth();
4010b57cec5SDimitry Andric     else if (Literal.isUTF16())
4020b57cec5SDimitry Andric       NumBits = TI.getChar16Width();
4030b57cec5SDimitry Andric     else if (Literal.isUTF32())
4040b57cec5SDimitry Andric       NumBits = TI.getChar32Width();
4050b57cec5SDimitry Andric     else // char or char8_t
4060b57cec5SDimitry Andric       NumBits = TI.getCharWidth();
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric     // Set the width.
4090b57cec5SDimitry Andric     llvm::APSInt Val(NumBits);
4100b57cec5SDimitry Andric     // Set the value.
4110b57cec5SDimitry Andric     Val = Literal.getValue();
4120b57cec5SDimitry Andric     // Set the signedness. UTF-16 and UTF-32 are always unsigned
41381ad6265SDimitry Andric     // UTF-8 is unsigned if -fchar8_t is specified.
4140b57cec5SDimitry Andric     if (Literal.isWide())
4150b57cec5SDimitry Andric       Val.setIsUnsigned(!TargetInfo::isTypeSigned(TI.getWCharType()));
41681ad6265SDimitry Andric     else if (Literal.isUTF16() || Literal.isUTF32())
41781ad6265SDimitry Andric       Val.setIsUnsigned(true);
41881ad6265SDimitry Andric     else if (Literal.isUTF8()) {
41981ad6265SDimitry Andric       if (PP.getLangOpts().CPlusPlus)
42081ad6265SDimitry Andric         Val.setIsUnsigned(
42181ad6265SDimitry Andric             PP.getLangOpts().Char8 ? true : !PP.getLangOpts().CharIsSigned);
42281ad6265SDimitry Andric       else
42381ad6265SDimitry Andric         Val.setIsUnsigned(true);
42481ad6265SDimitry Andric     } else
4250b57cec5SDimitry Andric       Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned);
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric     if (Result.Val.getBitWidth() > Val.getBitWidth()) {
4280b57cec5SDimitry Andric       Result.Val = Val.extend(Result.Val.getBitWidth());
4290b57cec5SDimitry Andric     } else {
4300b57cec5SDimitry Andric       assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
4310b57cec5SDimitry Andric              "intmax_t smaller than char/wchar_t?");
4320b57cec5SDimitry Andric       Result.Val = Val;
4330b57cec5SDimitry Andric     }
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric     // Consume the token.
4360b57cec5SDimitry Andric     Result.setRange(PeekTok.getLocation());
4370b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
4380b57cec5SDimitry Andric     return false;
4390b57cec5SDimitry Andric   }
4400b57cec5SDimitry Andric   case tok::l_paren: {
4410b57cec5SDimitry Andric     SourceLocation Start = PeekTok.getLocation();
4420b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);  // Eat the (.
4430b57cec5SDimitry Andric     // Parse the value and if there are any binary operators involved, parse
4440b57cec5SDimitry Andric     // them.
4450b57cec5SDimitry Andric     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric     // If this is a silly value like (X), which doesn't need parens, check for
4480b57cec5SDimitry Andric     // !(defined X).
4490b57cec5SDimitry Andric     if (PeekTok.is(tok::r_paren)) {
4500b57cec5SDimitry Andric       // Just use DT unmodified as our result.
4510b57cec5SDimitry Andric     } else {
4520b57cec5SDimitry Andric       // Otherwise, we have something like (x+y), and we consumed '(x'.
4530b57cec5SDimitry Andric       if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive,
4540b57cec5SDimitry Andric                                    DT.IncludedUndefinedIds, PP))
4550b57cec5SDimitry Andric         return true;
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric       if (PeekTok.isNot(tok::r_paren)) {
4580b57cec5SDimitry Andric         PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
4590b57cec5SDimitry Andric           << Result.getRange();
4600b57cec5SDimitry Andric         PP.Diag(Start, diag::note_matching) << tok::l_paren;
4610b57cec5SDimitry Andric         return true;
4620b57cec5SDimitry Andric       }
4630b57cec5SDimitry Andric       DT.State = DefinedTracker::Unknown;
4640b57cec5SDimitry Andric     }
4650b57cec5SDimitry Andric     Result.setRange(Start, PeekTok.getLocation());
4660b57cec5SDimitry Andric     Result.setIdentifier(nullptr);
4670b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);  // Eat the ).
4680b57cec5SDimitry Andric     return false;
4690b57cec5SDimitry Andric   }
4700b57cec5SDimitry Andric   case tok::plus: {
4710b57cec5SDimitry Andric     SourceLocation Start = PeekTok.getLocation();
4720b57cec5SDimitry Andric     // Unary plus doesn't modify the value.
4730b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
4740b57cec5SDimitry Andric     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
4750b57cec5SDimitry Andric     Result.setBegin(Start);
4760b57cec5SDimitry Andric     Result.setIdentifier(nullptr);
4770b57cec5SDimitry Andric     return false;
4780b57cec5SDimitry Andric   }
4790b57cec5SDimitry Andric   case tok::minus: {
4800b57cec5SDimitry Andric     SourceLocation Loc = PeekTok.getLocation();
4810b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
4820b57cec5SDimitry Andric     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
4830b57cec5SDimitry Andric     Result.setBegin(Loc);
4840b57cec5SDimitry Andric     Result.setIdentifier(nullptr);
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric     // C99 6.5.3.3p3: The sign of the result matches the sign of the operand.
4870b57cec5SDimitry Andric     Result.Val = -Result.Val;
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric     // -MININT is the only thing that overflows.  Unsigned never overflows.
4900b57cec5SDimitry Andric     bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric     // If this operator is live and overflowed, report the issue.
4930b57cec5SDimitry Andric     if (Overflow && ValueLive)
4940b57cec5SDimitry Andric       PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric     DT.State = DefinedTracker::Unknown;
4970b57cec5SDimitry Andric     return false;
4980b57cec5SDimitry Andric   }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric   case tok::tilde: {
5010b57cec5SDimitry Andric     SourceLocation Start = PeekTok.getLocation();
5020b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
5030b57cec5SDimitry Andric     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
5040b57cec5SDimitry Andric     Result.setBegin(Start);
5050b57cec5SDimitry Andric     Result.setIdentifier(nullptr);
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric     // C99 6.5.3.3p4: The sign of the result matches the sign of the operand.
5080b57cec5SDimitry Andric     Result.Val = ~Result.Val;
5090b57cec5SDimitry Andric     DT.State = DefinedTracker::Unknown;
5100b57cec5SDimitry Andric     return false;
5110b57cec5SDimitry Andric   }
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   case tok::exclaim: {
5140b57cec5SDimitry Andric     SourceLocation Start = PeekTok.getLocation();
5150b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
5160b57cec5SDimitry Andric     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
5170b57cec5SDimitry Andric     Result.setBegin(Start);
5180b57cec5SDimitry Andric     Result.Val = !Result.Val;
5190b57cec5SDimitry Andric     // C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed.
5200b57cec5SDimitry Andric     Result.Val.setIsUnsigned(false);
5210b57cec5SDimitry Andric     Result.setIdentifier(nullptr);
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric     if (DT.State == DefinedTracker::DefinedMacro)
5240b57cec5SDimitry Andric       DT.State = DefinedTracker::NotDefinedMacro;
5250b57cec5SDimitry Andric     else if (DT.State == DefinedTracker::NotDefinedMacro)
5260b57cec5SDimitry Andric       DT.State = DefinedTracker::DefinedMacro;
5270b57cec5SDimitry Andric     return false;
5280b57cec5SDimitry Andric   }
5290b57cec5SDimitry Andric   case tok::kw_true:
5300b57cec5SDimitry Andric   case tok::kw_false:
5310b57cec5SDimitry Andric     Result.Val = PeekTok.getKind() == tok::kw_true;
5320b57cec5SDimitry Andric     Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
5330b57cec5SDimitry Andric     Result.setIdentifier(PeekTok.getIdentifierInfo());
5340b57cec5SDimitry Andric     Result.setRange(PeekTok.getLocation());
5350b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
5360b57cec5SDimitry Andric     return false;
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   // FIXME: Handle #assert
5390b57cec5SDimitry Andric   }
5400b57cec5SDimitry Andric }
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric /// getPrecedence - Return the precedence of the specified binary operator
5430b57cec5SDimitry Andric /// token.  This returns:
5440b57cec5SDimitry Andric ///   ~0 - Invalid token.
5450b57cec5SDimitry Andric ///   14 -> 3 - various operators.
5460b57cec5SDimitry Andric ///    0 - 'eod' or ')'
getPrecedence(tok::TokenKind Kind)5470b57cec5SDimitry Andric static unsigned getPrecedence(tok::TokenKind Kind) {
5480b57cec5SDimitry Andric   switch (Kind) {
5490b57cec5SDimitry Andric   default: return ~0U;
5500b57cec5SDimitry Andric   case tok::percent:
5510b57cec5SDimitry Andric   case tok::slash:
5520b57cec5SDimitry Andric   case tok::star:                 return 14;
5530b57cec5SDimitry Andric   case tok::plus:
5540b57cec5SDimitry Andric   case tok::minus:                return 13;
5550b57cec5SDimitry Andric   case tok::lessless:
5560b57cec5SDimitry Andric   case tok::greatergreater:       return 12;
5570b57cec5SDimitry Andric   case tok::lessequal:
5580b57cec5SDimitry Andric   case tok::less:
5590b57cec5SDimitry Andric   case tok::greaterequal:
5600b57cec5SDimitry Andric   case tok::greater:              return 11;
5610b57cec5SDimitry Andric   case tok::exclaimequal:
5620b57cec5SDimitry Andric   case tok::equalequal:           return 10;
5630b57cec5SDimitry Andric   case tok::amp:                  return 9;
5640b57cec5SDimitry Andric   case tok::caret:                return 8;
5650b57cec5SDimitry Andric   case tok::pipe:                 return 7;
5660b57cec5SDimitry Andric   case tok::ampamp:               return 6;
5670b57cec5SDimitry Andric   case tok::pipepipe:             return 5;
5680b57cec5SDimitry Andric   case tok::question:             return 4;
5690b57cec5SDimitry Andric   case tok::comma:                return 3;
5700b57cec5SDimitry Andric   case tok::colon:                return 2;
5710b57cec5SDimitry Andric   case tok::r_paren:              return 0;// Lowest priority, end of expr.
5720b57cec5SDimitry Andric   case tok::eod:                  return 0;// Lowest priority, end of directive.
5730b57cec5SDimitry Andric   }
5740b57cec5SDimitry Andric }
5750b57cec5SDimitry Andric 
diagnoseUnexpectedOperator(Preprocessor & PP,PPValue & LHS,Token & Tok)5760b57cec5SDimitry Andric static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS,
5770b57cec5SDimitry Andric                                        Token &Tok) {
5780b57cec5SDimitry Andric   if (Tok.is(tok::l_paren) && LHS.getIdentifier())
5790b57cec5SDimitry Andric     PP.Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
5800b57cec5SDimitry Andric         << LHS.getIdentifier();
5810b57cec5SDimitry Andric   else
5820b57cec5SDimitry Andric     PP.Diag(Tok.getLocation(), diag::err_pp_expr_bad_token_binop)
5830b57cec5SDimitry Andric         << LHS.getRange();
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric /// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
5870b57cec5SDimitry Andric /// PeekTok, and whose precedence is PeekPrec.  This returns the result in LHS.
5880b57cec5SDimitry Andric ///
5890b57cec5SDimitry Andric /// If ValueLive is false, then this value is being evaluated in a context where
5900b57cec5SDimitry Andric /// the result is not used.  As such, avoid diagnostics that relate to
5910b57cec5SDimitry Andric /// evaluation, such as division by zero warnings.
EvaluateDirectiveSubExpr(PPValue & LHS,unsigned MinPrec,Token & PeekTok,bool ValueLive,bool & IncludedUndefinedIds,Preprocessor & PP)5920b57cec5SDimitry Andric static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
5930b57cec5SDimitry Andric                                      Token &PeekTok, bool ValueLive,
5940b57cec5SDimitry Andric                                      bool &IncludedUndefinedIds,
5950b57cec5SDimitry Andric                                      Preprocessor &PP) {
5960b57cec5SDimitry Andric   unsigned PeekPrec = getPrecedence(PeekTok.getKind());
5970b57cec5SDimitry Andric   // If this token isn't valid, report the error.
5980b57cec5SDimitry Andric   if (PeekPrec == ~0U) {
5990b57cec5SDimitry Andric     diagnoseUnexpectedOperator(PP, LHS, PeekTok);
6000b57cec5SDimitry Andric     return true;
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   while (true) {
6040b57cec5SDimitry Andric     // If this token has a lower precedence than we are allowed to parse, return
6050b57cec5SDimitry Andric     // it so that higher levels of the recursion can parse it.
6060b57cec5SDimitry Andric     if (PeekPrec < MinPrec)
6070b57cec5SDimitry Andric       return false;
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric     tok::TokenKind Operator = PeekTok.getKind();
6100b57cec5SDimitry Andric 
6110b57cec5SDimitry Andric     // If this is a short-circuiting operator, see if the RHS of the operator is
6120b57cec5SDimitry Andric     // dead.  Note that this cannot just clobber ValueLive.  Consider
6130b57cec5SDimitry Andric     // "0 && 1 ? 4 : 1 / 0", which is parsed as "(0 && 1) ? 4 : (1 / 0)".  In
6140b57cec5SDimitry Andric     // this example, the RHS of the && being dead does not make the rest of the
6150b57cec5SDimitry Andric     // expr dead.
6160b57cec5SDimitry Andric     bool RHSIsLive;
6170b57cec5SDimitry Andric     if (Operator == tok::ampamp && LHS.Val == 0)
6180b57cec5SDimitry Andric       RHSIsLive = false;   // RHS of "0 && x" is dead.
6190b57cec5SDimitry Andric     else if (Operator == tok::pipepipe && LHS.Val != 0)
6200b57cec5SDimitry Andric       RHSIsLive = false;   // RHS of "1 || x" is dead.
6210b57cec5SDimitry Andric     else if (Operator == tok::question && LHS.Val == 0)
6220b57cec5SDimitry Andric       RHSIsLive = false;   // RHS (x) of "0 ? x : y" is dead.
6230b57cec5SDimitry Andric     else
6240b57cec5SDimitry Andric       RHSIsLive = ValueLive;
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric     // Consume the operator, remembering the operator's location for reporting.
6270b57cec5SDimitry Andric     SourceLocation OpLoc = PeekTok.getLocation();
6280b57cec5SDimitry Andric     PP.LexNonComment(PeekTok);
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric     PPValue RHS(LHS.getBitWidth());
6310b57cec5SDimitry Andric     // Parse the RHS of the operator.
6320b57cec5SDimitry Andric     DefinedTracker DT;
6330b57cec5SDimitry Andric     if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
6340b57cec5SDimitry Andric     IncludedUndefinedIds = DT.IncludedUndefinedIds;
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric     // Remember the precedence of this operator and get the precedence of the
6370b57cec5SDimitry Andric     // operator immediately to the right of the RHS.
6380b57cec5SDimitry Andric     unsigned ThisPrec = PeekPrec;
6390b57cec5SDimitry Andric     PeekPrec = getPrecedence(PeekTok.getKind());
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric     // If this token isn't valid, report the error.
6420b57cec5SDimitry Andric     if (PeekPrec == ~0U) {
6430b57cec5SDimitry Andric       diagnoseUnexpectedOperator(PP, RHS, PeekTok);
6440b57cec5SDimitry Andric       return true;
6450b57cec5SDimitry Andric     }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric     // Decide whether to include the next binop in this subexpression.  For
6480b57cec5SDimitry Andric     // example, when parsing x+y*z and looking at '*', we want to recursively
6490b57cec5SDimitry Andric     // handle y*z as a single subexpression.  We do this because the precedence
6500b57cec5SDimitry Andric     // of * is higher than that of +.  The only strange case we have to handle
6510b57cec5SDimitry Andric     // here is for the ?: operator, where the precedence is actually lower than
6520b57cec5SDimitry Andric     // the LHS of the '?'.  The grammar rule is:
6530b57cec5SDimitry Andric     //
6540b57cec5SDimitry Andric     // conditional-expression ::=
6550b57cec5SDimitry Andric     //    logical-OR-expression ? expression : conditional-expression
6560b57cec5SDimitry Andric     // where 'expression' is actually comma-expression.
6570b57cec5SDimitry Andric     unsigned RHSPrec;
6580b57cec5SDimitry Andric     if (Operator == tok::question)
6590b57cec5SDimitry Andric       // The RHS of "?" should be maximally consumed as an expression.
6600b57cec5SDimitry Andric       RHSPrec = getPrecedence(tok::comma);
6610b57cec5SDimitry Andric     else  // All others should munch while higher precedence.
6620b57cec5SDimitry Andric       RHSPrec = ThisPrec+1;
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric     if (PeekPrec >= RHSPrec) {
6650b57cec5SDimitry Andric       if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive,
6660b57cec5SDimitry Andric                                    IncludedUndefinedIds, PP))
6670b57cec5SDimitry Andric         return true;
6680b57cec5SDimitry Andric       PeekPrec = getPrecedence(PeekTok.getKind());
6690b57cec5SDimitry Andric     }
6700b57cec5SDimitry Andric     assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric     // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
6730b57cec5SDimitry Andric     // either operand is unsigned.
6740b57cec5SDimitry Andric     llvm::APSInt Res(LHS.getBitWidth());
6750b57cec5SDimitry Andric     switch (Operator) {
6760b57cec5SDimitry Andric     case tok::question:       // No UAC for x and y in "x ? y : z".
6770b57cec5SDimitry Andric     case tok::lessless:       // Shift amount doesn't UAC with shift value.
6780b57cec5SDimitry Andric     case tok::greatergreater: // Shift amount doesn't UAC with shift value.
6790b57cec5SDimitry Andric     case tok::comma:          // Comma operands are not subject to UACs.
6800b57cec5SDimitry Andric     case tok::pipepipe:       // Logical || does not do UACs.
6810b57cec5SDimitry Andric     case tok::ampamp:         // Logical && does not do UACs.
6820b57cec5SDimitry Andric       break;                  // No UAC
6830b57cec5SDimitry Andric     default:
684349cc55cSDimitry Andric       Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());
6850b57cec5SDimitry Andric       // If this just promoted something from signed to unsigned, and if the
6860b57cec5SDimitry Andric       // value was negative, warn about it.
6870b57cec5SDimitry Andric       if (ValueLive && Res.isUnsigned()) {
6880b57cec5SDimitry Andric         if (!LHS.isUnsigned() && LHS.Val.isNegative())
6890b57cec5SDimitry Andric           PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
690fe6060f1SDimitry Andric             << toString(LHS.Val, 10, true) + " to " +
691fe6060f1SDimitry Andric                toString(LHS.Val, 10, false)
6920b57cec5SDimitry Andric             << LHS.getRange() << RHS.getRange();
6930b57cec5SDimitry Andric         if (!RHS.isUnsigned() && RHS.Val.isNegative())
6940b57cec5SDimitry Andric           PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
695fe6060f1SDimitry Andric             << toString(RHS.Val, 10, true) + " to " +
696fe6060f1SDimitry Andric                toString(RHS.Val, 10, false)
6970b57cec5SDimitry Andric             << LHS.getRange() << RHS.getRange();
6980b57cec5SDimitry Andric       }
6990b57cec5SDimitry Andric       LHS.Val.setIsUnsigned(Res.isUnsigned());
7000b57cec5SDimitry Andric       RHS.Val.setIsUnsigned(Res.isUnsigned());
7010b57cec5SDimitry Andric     }
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric     bool Overflow = false;
7040b57cec5SDimitry Andric     switch (Operator) {
7050b57cec5SDimitry Andric     default: llvm_unreachable("Unknown operator token!");
7060b57cec5SDimitry Andric     case tok::percent:
7070b57cec5SDimitry Andric       if (RHS.Val != 0)
7080b57cec5SDimitry Andric         Res = LHS.Val % RHS.Val;
7090b57cec5SDimitry Andric       else if (ValueLive) {
7100b57cec5SDimitry Andric         PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)
7110b57cec5SDimitry Andric           << LHS.getRange() << RHS.getRange();
7120b57cec5SDimitry Andric         return true;
7130b57cec5SDimitry Andric       }
7140b57cec5SDimitry Andric       break;
7150b57cec5SDimitry Andric     case tok::slash:
7160b57cec5SDimitry Andric       if (RHS.Val != 0) {
7170b57cec5SDimitry Andric         if (LHS.Val.isSigned())
7180b57cec5SDimitry Andric           Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow), false);
7190b57cec5SDimitry Andric         else
7200b57cec5SDimitry Andric           Res = LHS.Val / RHS.Val;
7210b57cec5SDimitry Andric       } else if (ValueLive) {
7220b57cec5SDimitry Andric         PP.Diag(OpLoc, diag::err_pp_division_by_zero)
7230b57cec5SDimitry Andric           << LHS.getRange() << RHS.getRange();
7240b57cec5SDimitry Andric         return true;
7250b57cec5SDimitry Andric       }
7260b57cec5SDimitry Andric       break;
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric     case tok::star:
7290b57cec5SDimitry Andric       if (Res.isSigned())
7300b57cec5SDimitry Andric         Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow), false);
7310b57cec5SDimitry Andric       else
7320b57cec5SDimitry Andric         Res = LHS.Val * RHS.Val;
7330b57cec5SDimitry Andric       break;
7340b57cec5SDimitry Andric     case tok::lessless: {
7350b57cec5SDimitry Andric       // Determine whether overflow is about to happen.
7360b57cec5SDimitry Andric       if (LHS.isUnsigned())
7370b57cec5SDimitry Andric         Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
7380b57cec5SDimitry Andric       else
7390b57cec5SDimitry Andric         Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow), false);
7400b57cec5SDimitry Andric       break;
7410b57cec5SDimitry Andric     }
7420b57cec5SDimitry Andric     case tok::greatergreater: {
7430b57cec5SDimitry Andric       // Determine whether overflow is about to happen.
7440b57cec5SDimitry Andric       unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
7450b57cec5SDimitry Andric       if (ShAmt >= LHS.getBitWidth()) {
7460b57cec5SDimitry Andric         Overflow = true;
7470b57cec5SDimitry Andric         ShAmt = LHS.getBitWidth()-1;
7480b57cec5SDimitry Andric       }
7490b57cec5SDimitry Andric       Res = LHS.Val >> ShAmt;
7500b57cec5SDimitry Andric       break;
7510b57cec5SDimitry Andric     }
7520b57cec5SDimitry Andric     case tok::plus:
7530b57cec5SDimitry Andric       if (LHS.isUnsigned())
7540b57cec5SDimitry Andric         Res = LHS.Val + RHS.Val;
7550b57cec5SDimitry Andric       else
7560b57cec5SDimitry Andric         Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow), false);
7570b57cec5SDimitry Andric       break;
7580b57cec5SDimitry Andric     case tok::minus:
7590b57cec5SDimitry Andric       if (LHS.isUnsigned())
7600b57cec5SDimitry Andric         Res = LHS.Val - RHS.Val;
7610b57cec5SDimitry Andric       else
7620b57cec5SDimitry Andric         Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow), false);
7630b57cec5SDimitry Andric       break;
7640b57cec5SDimitry Andric     case tok::lessequal:
7650b57cec5SDimitry Andric       Res = LHS.Val <= RHS.Val;
7660b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
7670b57cec5SDimitry Andric       break;
7680b57cec5SDimitry Andric     case tok::less:
7690b57cec5SDimitry Andric       Res = LHS.Val < RHS.Val;
7700b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
7710b57cec5SDimitry Andric       break;
7720b57cec5SDimitry Andric     case tok::greaterequal:
7730b57cec5SDimitry Andric       Res = LHS.Val >= RHS.Val;
7740b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
7750b57cec5SDimitry Andric       break;
7760b57cec5SDimitry Andric     case tok::greater:
7770b57cec5SDimitry Andric       Res = LHS.Val > RHS.Val;
7780b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
7790b57cec5SDimitry Andric       break;
7800b57cec5SDimitry Andric     case tok::exclaimequal:
7810b57cec5SDimitry Andric       Res = LHS.Val != RHS.Val;
7820b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
7830b57cec5SDimitry Andric       break;
7840b57cec5SDimitry Andric     case tok::equalequal:
7850b57cec5SDimitry Andric       Res = LHS.Val == RHS.Val;
7860b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
7870b57cec5SDimitry Andric       break;
7880b57cec5SDimitry Andric     case tok::amp:
7890b57cec5SDimitry Andric       Res = LHS.Val & RHS.Val;
7900b57cec5SDimitry Andric       break;
7910b57cec5SDimitry Andric     case tok::caret:
7920b57cec5SDimitry Andric       Res = LHS.Val ^ RHS.Val;
7930b57cec5SDimitry Andric       break;
7940b57cec5SDimitry Andric     case tok::pipe:
7950b57cec5SDimitry Andric       Res = LHS.Val | RHS.Val;
7960b57cec5SDimitry Andric       break;
7970b57cec5SDimitry Andric     case tok::ampamp:
7980b57cec5SDimitry Andric       Res = (LHS.Val != 0 && RHS.Val != 0);
7990b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.13p3, result is always int (signed)
8000b57cec5SDimitry Andric       break;
8010b57cec5SDimitry Andric     case tok::pipepipe:
8020b57cec5SDimitry Andric       Res = (LHS.Val != 0 || RHS.Val != 0);
8030b57cec5SDimitry Andric       Res.setIsUnsigned(false);  // C99 6.5.14p3, result is always int (signed)
8040b57cec5SDimitry Andric       break;
8050b57cec5SDimitry Andric     case tok::comma:
8060b57cec5SDimitry Andric       // Comma is invalid in pp expressions in c89/c++ mode, but is valid in C99
8070b57cec5SDimitry Andric       // if not being evaluated.
8080b57cec5SDimitry Andric       if (!PP.getLangOpts().C99 || ValueLive)
8090b57cec5SDimitry Andric         PP.Diag(OpLoc, diag::ext_pp_comma_expr)
8100b57cec5SDimitry Andric           << LHS.getRange() << RHS.getRange();
8110b57cec5SDimitry Andric       Res = RHS.Val; // LHS = LHS,RHS -> RHS.
8120b57cec5SDimitry Andric       break;
8130b57cec5SDimitry Andric     case tok::question: {
8140b57cec5SDimitry Andric       // Parse the : part of the expression.
8150b57cec5SDimitry Andric       if (PeekTok.isNot(tok::colon)) {
8160b57cec5SDimitry Andric         PP.Diag(PeekTok.getLocation(), diag::err_expected)
8170b57cec5SDimitry Andric             << tok::colon << LHS.getRange() << RHS.getRange();
8180b57cec5SDimitry Andric         PP.Diag(OpLoc, diag::note_matching) << tok::question;
8190b57cec5SDimitry Andric         return true;
8200b57cec5SDimitry Andric       }
8210b57cec5SDimitry Andric       // Consume the :.
8220b57cec5SDimitry Andric       PP.LexNonComment(PeekTok);
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric       // Evaluate the value after the :.
8250b57cec5SDimitry Andric       bool AfterColonLive = ValueLive && LHS.Val == 0;
8260b57cec5SDimitry Andric       PPValue AfterColonVal(LHS.getBitWidth());
8270b57cec5SDimitry Andric       DefinedTracker DT;
8280b57cec5SDimitry Andric       if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
8290b57cec5SDimitry Andric         return true;
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric       // Parse anything after the : with the same precedence as ?.  We allow
8320b57cec5SDimitry Andric       // things of equal precedence because ?: is right associative.
8330b57cec5SDimitry Andric       if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec,
8340b57cec5SDimitry Andric                                    PeekTok, AfterColonLive,
8350b57cec5SDimitry Andric                                    IncludedUndefinedIds, PP))
8360b57cec5SDimitry Andric         return true;
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric       // Now that we have the condition, the LHS and the RHS of the :, evaluate.
8390b57cec5SDimitry Andric       Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
8400b57cec5SDimitry Andric       RHS.setEnd(AfterColonVal.getRange().getEnd());
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric       // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
8430b57cec5SDimitry Andric       // either operand is unsigned.
844349cc55cSDimitry Andric       Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric       // Figure out the precedence of the token after the : part.
8470b57cec5SDimitry Andric       PeekPrec = getPrecedence(PeekTok.getKind());
8480b57cec5SDimitry Andric       break;
8490b57cec5SDimitry Andric     }
8500b57cec5SDimitry Andric     case tok::colon:
8510b57cec5SDimitry Andric       // Don't allow :'s to float around without being part of ?: exprs.
8520b57cec5SDimitry Andric       PP.Diag(OpLoc, diag::err_pp_colon_without_question)
8530b57cec5SDimitry Andric         << LHS.getRange() << RHS.getRange();
8540b57cec5SDimitry Andric       return true;
8550b57cec5SDimitry Andric     }
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric     // If this operator is live and overflowed, report the issue.
8580b57cec5SDimitry Andric     if (Overflow && ValueLive)
8590b57cec5SDimitry Andric       PP.Diag(OpLoc, diag::warn_pp_expr_overflow)
8600b57cec5SDimitry Andric         << LHS.getRange() << RHS.getRange();
8610b57cec5SDimitry Andric 
8620b57cec5SDimitry Andric     // Put the result back into 'LHS' for our next iteration.
8630b57cec5SDimitry Andric     LHS.Val = Res;
8640b57cec5SDimitry Andric     LHS.setEnd(RHS.getRange().getEnd());
8650b57cec5SDimitry Andric     RHS.setIdentifier(nullptr);
8660b57cec5SDimitry Andric   }
8670b57cec5SDimitry Andric }
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
8700b57cec5SDimitry Andric /// may occur after a #if or #elif directive.  If the expression is equivalent
8710b57cec5SDimitry Andric /// to "!defined(X)" return X in IfNDefMacro.
8720b57cec5SDimitry Andric Preprocessor::DirectiveEvalResult
EvaluateDirectiveExpression(IdentifierInfo * & IfNDefMacro,Token & Tok,bool & EvaluatedDefined,bool CheckForEoD)873*0fca6ea1SDimitry Andric Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
874*0fca6ea1SDimitry Andric                                           Token &Tok, bool &EvaluatedDefined,
875*0fca6ea1SDimitry Andric                                           bool CheckForEoD) {
876bdd1243dSDimitry Andric   SaveAndRestore PPDir(ParsingIfOrElifDirective, true);
8770b57cec5SDimitry Andric   // Save the current state of 'DisableMacroExpansion' and reset it to false. If
8780b57cec5SDimitry Andric   // 'DisableMacroExpansion' is true, then we must be in a macro argument list
8790b57cec5SDimitry Andric   // in which case a directive is undefined behavior.  We want macros to be able
8800b57cec5SDimitry Andric   // to recursively expand in order to get more gcc-list behavior, so we force
8810b57cec5SDimitry Andric   // DisableMacroExpansion to false and restore it when we're done parsing the
8820b57cec5SDimitry Andric   // expression.
8830b57cec5SDimitry Andric   bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
8840b57cec5SDimitry Andric   DisableMacroExpansion = false;
8850b57cec5SDimitry Andric 
8860b57cec5SDimitry Andric   // Peek ahead one token.
8870b57cec5SDimitry Andric   LexNonComment(Tok);
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
8900b57cec5SDimitry Andric   unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric   PPValue ResVal(BitWidth);
8930b57cec5SDimitry Andric   DefinedTracker DT;
8940b57cec5SDimitry Andric   SourceLocation ExprStartLoc = SourceMgr.getExpansionLoc(Tok.getLocation());
8950b57cec5SDimitry Andric   if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
8960b57cec5SDimitry Andric     // Parse error, skip the rest of the macro line.
8970b57cec5SDimitry Andric     SourceRange ConditionRange = ExprStartLoc;
8980b57cec5SDimitry Andric     if (Tok.isNot(tok::eod))
899*0fca6ea1SDimitry Andric       ConditionRange = DiscardUntilEndOfDirective(Tok);
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric     // Restore 'DisableMacroExpansion'.
9020b57cec5SDimitry Andric     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric     // We cannot trust the source range from the value because there was a
9050b57cec5SDimitry Andric     // parse error. Track the range manually -- the end of the directive is the
9060b57cec5SDimitry Andric     // end of the condition range.
907*0fca6ea1SDimitry Andric     return {std::nullopt,
908*0fca6ea1SDimitry Andric             false,
9090b57cec5SDimitry Andric             DT.IncludedUndefinedIds,
9100b57cec5SDimitry Andric             {ExprStartLoc, ConditionRange.getEnd()}};
9110b57cec5SDimitry Andric   }
9120b57cec5SDimitry Andric 
913*0fca6ea1SDimitry Andric   EvaluatedDefined = DT.State != DefinedTracker::Unknown;
914*0fca6ea1SDimitry Andric 
9150b57cec5SDimitry Andric   // If we are at the end of the expression after just parsing a value, there
9160b57cec5SDimitry Andric   // must be no (unparenthesized) binary operators involved, so we can exit
9170b57cec5SDimitry Andric   // directly.
9180b57cec5SDimitry Andric   if (Tok.is(tok::eod)) {
9190b57cec5SDimitry Andric     // If the expression we parsed was of the form !defined(macro), return the
9200b57cec5SDimitry Andric     // macro in IfNDefMacro.
9210b57cec5SDimitry Andric     if (DT.State == DefinedTracker::NotDefinedMacro)
9220b57cec5SDimitry Andric       IfNDefMacro = DT.TheMacro;
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric     // Restore 'DisableMacroExpansion'.
9250b57cec5SDimitry Andric     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
926*0fca6ea1SDimitry Andric     bool IsNonZero = ResVal.Val != 0;
927*0fca6ea1SDimitry Andric     SourceRange ValRange = ResVal.getRange();
928*0fca6ea1SDimitry Andric     return {std::move(ResVal.Val), IsNonZero, DT.IncludedUndefinedIds,
929*0fca6ea1SDimitry Andric             ValRange};
9300b57cec5SDimitry Andric   }
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric   // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
9330b57cec5SDimitry Andric   // operator and the stuff after it.
9340b57cec5SDimitry Andric   if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question),
9350b57cec5SDimitry Andric                                Tok, true, DT.IncludedUndefinedIds, *this)) {
9360b57cec5SDimitry Andric     // Parse error, skip the rest of the macro line.
9370b57cec5SDimitry Andric     if (Tok.isNot(tok::eod))
938*0fca6ea1SDimitry Andric       DiscardUntilEndOfDirective(Tok);
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric     // Restore 'DisableMacroExpansion'.
9410b57cec5SDimitry Andric     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
942*0fca6ea1SDimitry Andric     SourceRange ValRange = ResVal.getRange();
943*0fca6ea1SDimitry Andric     return {std::nullopt, false, DT.IncludedUndefinedIds, ValRange};
9440b57cec5SDimitry Andric   }
9450b57cec5SDimitry Andric 
946*0fca6ea1SDimitry Andric   if (CheckForEoD) {
9470b57cec5SDimitry Andric     // If we aren't at the tok::eod token, something bad happened, like an extra
9480b57cec5SDimitry Andric     // ')' token.
9490b57cec5SDimitry Andric     if (Tok.isNot(tok::eod)) {
9500b57cec5SDimitry Andric       Diag(Tok, diag::err_pp_expected_eol);
951*0fca6ea1SDimitry Andric       DiscardUntilEndOfDirective(Tok);
9520b57cec5SDimitry Andric     }
953*0fca6ea1SDimitry Andric   }
954*0fca6ea1SDimitry Andric 
955*0fca6ea1SDimitry Andric   EvaluatedDefined = EvaluatedDefined || DT.State != DefinedTracker::Unknown;
9560b57cec5SDimitry Andric 
9570b57cec5SDimitry Andric   // Restore 'DisableMacroExpansion'.
9580b57cec5SDimitry Andric   DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
959*0fca6ea1SDimitry Andric   bool IsNonZero = ResVal.Val != 0;
960*0fca6ea1SDimitry Andric   SourceRange ValRange = ResVal.getRange();
961*0fca6ea1SDimitry Andric   return {std::move(ResVal.Val), IsNonZero, DT.IncludedUndefinedIds, ValRange};
962*0fca6ea1SDimitry Andric }
963*0fca6ea1SDimitry Andric 
964*0fca6ea1SDimitry Andric Preprocessor::DirectiveEvalResult
EvaluateDirectiveExpression(IdentifierInfo * & IfNDefMacro,bool CheckForEoD)965*0fca6ea1SDimitry Andric Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
966*0fca6ea1SDimitry Andric                                           bool CheckForEoD) {
967*0fca6ea1SDimitry Andric   Token Tok;
968*0fca6ea1SDimitry Andric   bool EvaluatedDefined;
969*0fca6ea1SDimitry Andric   return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined,
970*0fca6ea1SDimitry Andric                                      CheckForEoD);
9710b57cec5SDimitry Andric }
972