30#include "llvm/ADT/APSInt.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/SaveAndRestore.h"
52 PPValue(
unsigned BitWidth) : Val(BitWidth) {}
59 unsigned getBitWidth()
const {
return Val.getBitWidth(); }
60 bool isUnsigned()
const {
return Val.isUnsigned(); }
75 Token &PeekTok,
bool ValueLive,
76 bool &IncludedUndefinedIds,
104 Result.setBegin(beginLoc);
111 if (PeekTok.
is(tok::l_paren)) {
117 if (PeekTok.
is(tok::code_completion)) {
131 Result.Val = !!Macro;
132 Result.Val.setIsUnsigned(
false);
137 (II->
getName() ==
"INFINITY" || II->
getName() ==
"NAN") ?
true :
false);
140 if (Result.Val != 0 && ValueLive)
144 Token macroToken(PeekTok);
152 if (PeekTok.
isNot(tok::r_paren)) {
154 <<
"'defined'" << tok::r_paren;
155 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
186 bool IsFunctionTypeMacro =
206 if (IsFunctionTypeMacro)
207 PP.
Diag(beginLoc, diag::warn_defined_in_function_type_macro);
209 PP.
Diag(beginLoc, diag::warn_defined_in_object_type_macro);
214 Callbacks->Defined(macroToken, Macro,
236 Result.setIdentifier(
nullptr);
238 if (PeekTok.
is(tok::code_completion)) {
252 if (II->
isStr(
"defined"))
260 PP.
Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
264 if (DiagEngine.
isIgnored(diag::warn_pp_undef_identifier,
266 const std::vector<std::string> UndefPrefixes =
268 const StringRef IdentifierName = II->
getName();
269 if (llvm::any_of(UndefPrefixes,
270 [&IdentifierName](
const std::string &Prefix) {
271 return IdentifierName.starts_with(Prefix);
273 PP.
Diag(PeekTok, diag::warn_pp_undef_prefix)
278 Result.Val.setIsUnsigned(
false);
279 Result.setIdentifier(II);
286 PP.
Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
291 PP.
Diag(PeekTok, diag::err_pp_expected_value_in_expr);
293 case tok::numeric_constant: {
295 bool NumberInvalid =
false;
296 StringRef Spelling = PP.
getSpelling(PeekTok, IntegerBuffer,
304 if (Literal.hadError)
307 if (Literal.isFloatingLiteral() || Literal.isImaginary) {
308 PP.
Diag(PeekTok, diag::err_pp_illegal_floating_literal);
311 assert(Literal.isIntegerLiteral() &&
"Unknown ppnumber");
314 if (Literal.hasUDSuffix())
315 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 1;
322 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
324 PP.
Diag(PeekTok, diag::ext_c99_longlong);
331 ? diag::warn_cxx20_compat_size_t_suffix
332 : diag::ext_cxx23_size_t_suffix
333 : diag::err_cxx23_size_t_suffix);
337 if (Literal.isBitInt)
338 PP.
Diag(PeekTok, PP.
getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
340 ? diag::warn_c23_compat_bitint_suffix
341 : diag::ext_c23_bitint_suffix);
344 if (Literal.GetIntegerValue(Result.Val)) {
347 PP.
Diag(PeekTok, diag::err_integer_literal_too_large)
349 Result.Val.setIsUnsigned(
true);
353 Result.Val.setIsUnsigned(Literal.isUnsigned);
359 if (!Literal.isUnsigned && Result.Val.isNegative()) {
362 if (ValueLive && Literal.getRadix() == 10)
363 PP.
Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
364 Result.Val.setIsUnsigned(
true);
373 case tok::char_constant:
374 case tok::wide_char_constant:
375 case tok::utf8_char_constant:
376 case tok::utf16_char_constant:
377 case tok::utf32_char_constant: {
380 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 0;
383 bool CharInvalid =
false;
384 StringRef ThisTok = PP.
getSpelling(PeekTok, CharBuffer, &CharInvalid);
390 if (Literal.hadError())
396 if (Literal.isMultiChar())
398 else if (Literal.isWide())
400 else if (Literal.isUTF16())
402 else if (Literal.isUTF32())
408 llvm::APSInt Val(NumBits);
410 Val = Literal.getValue();
413 if (Literal.isWide())
415 else if (Literal.isUTF16() || Literal.isUTF32())
416 Val.setIsUnsigned(
true);
417 else if (Literal.isUTF8()) {
422 Val.setIsUnsigned(
true);
426 if (Result.Val.getBitWidth() > Val.getBitWidth()) {
427 Result.Val = Val.extend(Result.Val.getBitWidth());
429 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
430 "intmax_t smaller than char/wchar_t?");
444 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
448 if (PeekTok.
is(tok::r_paren)) {
456 if (PeekTok.
isNot(tok::r_paren)) {
458 << Result.getRange();
459 PP.
Diag(Start, diag::note_matching) << tok::l_paren;
465 Result.setIdentifier(
nullptr);
473 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
474 Result.setBegin(Start);
475 Result.setIdentifier(
nullptr);
481 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
482 Result.setBegin(
Loc);
483 Result.setIdentifier(
nullptr);
486 Result.Val = -Result.Val;
489 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
492 if (Overflow && ValueLive)
493 PP.
Diag(
Loc, diag::warn_pp_expr_overflow) << Result.getRange();
502 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
503 Result.setBegin(Start);
504 Result.setIdentifier(
nullptr);
507 Result.Val = ~Result.Val;
515 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
516 Result.setBegin(Start);
517 Result.Val = !Result.Val;
519 Result.Val.setIsUnsigned(
false);
520 Result.setIdentifier(
nullptr);
530 Result.Val = PeekTok.
getKind() == tok::kw_true;
531 Result.Val.setIsUnsigned(
false);
551 case tok::star:
return 14;
553 case tok::minus:
return 13;
555 case tok::greatergreater:
return 12;
558 case tok::greaterequal:
559 case tok::greater:
return 11;
560 case tok::exclaimequal:
561 case tok::equalequal:
return 10;
562 case tok::amp:
return 9;
563 case tok::caret:
return 8;
564 case tok::pipe:
return 7;
565 case tok::ampamp:
return 6;
566 case tok::pipepipe:
return 5;
567 case tok::question:
return 4;
568 case tok::comma:
return 3;
569 case tok::colon:
return 2;
570 case tok::r_paren:
return 0;
571 case tok::eod:
return 0;
577 if (Tok.
is(tok::l_paren) && LHS.getIdentifier())
578 PP.
Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
579 << LHS.getIdentifier();
592 Token &PeekTok,
bool ValueLive,
593 bool &IncludedUndefinedIds,
597 if (PeekPrec == ~0
U) {
605 if (PeekPrec < MinPrec)
616 if (Operator == tok::ampamp && LHS.Val == 0)
618 else if (Operator == tok::pipepipe && LHS.Val != 0)
620 else if (Operator == tok::question && LHS.Val == 0)
623 RHSIsLive = ValueLive;
629 PPValue RHS(LHS.getBitWidth());
632 if (
EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP))
return true;
637 unsigned ThisPrec = PeekPrec;
641 if (PeekPrec == ~0
U) {
657 if (Operator == tok::question)
661 RHSPrec = ThisPrec+1;
663 if (PeekPrec >= RHSPrec) {
665 IncludedUndefinedIds, PP))
669 assert(PeekPrec <= ThisPrec &&
"Recursion didn't work!");
673 llvm::APSInt Res(LHS.getBitWidth());
677 case tok::greatergreater:
683 Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());
686 if (ValueLive && Res.isUnsigned()) {
687 if (!LHS.isUnsigned() && LHS.Val.isNegative())
688 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
689 <<
toString(LHS.Val, 10,
true) +
" to " +
691 << LHS.getRange() << RHS.getRange();
692 if (!RHS.isUnsigned() && RHS.Val.isNegative())
693 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
694 <<
toString(RHS.Val, 10,
true) +
" to " +
696 << LHS.getRange() << RHS.getRange();
698 LHS.Val.setIsUnsigned(Res.isUnsigned());
699 RHS.Val.setIsUnsigned(Res.isUnsigned());
702 bool Overflow =
false;
704 default: llvm_unreachable(
"Unknown operator token!");
707 Res = LHS.Val % RHS.Val;
708 else if (ValueLive) {
709 PP.
Diag(OpLoc, diag::err_pp_remainder_by_zero)
710 << LHS.getRange() << RHS.getRange();
716 if (LHS.Val.isSigned())
717 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow),
false);
719 Res = LHS.Val / RHS.Val;
720 }
else if (ValueLive) {
721 PP.
Diag(OpLoc, diag::err_pp_division_by_zero)
722 << LHS.getRange() << RHS.getRange();
729 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow),
false);
731 Res = LHS.Val * RHS.Val;
733 case tok::lessless: {
735 if (LHS.isUnsigned())
736 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
738 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow),
false);
741 case tok::greatergreater: {
743 unsigned ShAmt =
static_cast<unsigned>(RHS.Val.getLimitedValue());
744 if (ShAmt >= LHS.getBitWidth()) {
746 ShAmt = LHS.getBitWidth()-1;
748 Res = LHS.Val >> ShAmt;
752 if (LHS.isUnsigned())
753 Res = LHS.Val + RHS.Val;
755 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow),
false);
758 if (LHS.isUnsigned())
759 Res = LHS.Val - RHS.Val;
761 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow),
false);
764 Res = LHS.Val <= RHS.Val;
765 Res.setIsUnsigned(
false);
768 Res = LHS.Val < RHS.Val;
769 Res.setIsUnsigned(
false);
771 case tok::greaterequal:
772 Res = LHS.Val >= RHS.Val;
773 Res.setIsUnsigned(
false);
776 Res = LHS.Val > RHS.Val;
777 Res.setIsUnsigned(
false);
779 case tok::exclaimequal:
780 Res = LHS.Val != RHS.Val;
781 Res.setIsUnsigned(
false);
783 case tok::equalequal:
784 Res = LHS.Val == RHS.Val;
785 Res.setIsUnsigned(
false);
788 Res = LHS.Val & RHS.Val;
791 Res = LHS.Val ^ RHS.Val;
794 Res = LHS.Val | RHS.Val;
797 Res = (LHS.Val != 0 && RHS.Val != 0);
798 Res.setIsUnsigned(
false);
801 Res = (LHS.Val != 0 || RHS.Val != 0);
802 Res.setIsUnsigned(
false);
808 PP.
Diag(OpLoc, diag::ext_pp_comma_expr)
809 << LHS.getRange() << RHS.getRange();
812 case tok::question: {
814 if (PeekTok.
isNot(tok::colon)) {
816 << tok::colon << LHS.getRange() << RHS.getRange();
817 PP.
Diag(OpLoc, diag::note_matching) << tok::question;
824 bool AfterColonLive = ValueLive && LHS.Val == 0;
825 PPValue AfterColonVal(LHS.getBitWidth());
827 if (
EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
833 PeekTok, AfterColonLive,
834 IncludedUndefinedIds, PP))
838 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
839 RHS.setEnd(AfterColonVal.getRange().getEnd());
843 Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());
851 PP.
Diag(OpLoc, diag::err_pp_colon_without_question)
852 << LHS.getRange() << RHS.getRange();
857 if (Overflow && ValueLive)
858 PP.
Diag(OpLoc, diag::warn_pp_expr_overflow)
859 << LHS.getRange() << RHS.getRange();
863 LHS.setEnd(RHS.getRange().getEnd());
864 RHS.setIdentifier(
nullptr);
871Preprocessor::DirectiveEvalResult
872Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo *&IfNDefMacro,
873 Token &Tok,
bool &EvaluatedDefined,
882 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
883 DisableMacroExpansion =
false;
891 PPValue ResVal(BitWidth);
897 if (Tok.
isNot(tok::eod))
901 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
906 return {std::nullopt,
909 {ExprStartLoc, ConditionRange.
getEnd()}};
917 if (Tok.
is(tok::eod)) {
924 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
925 bool IsNonZero = ResVal.Val != 0;
936 if (Tok.
isNot(tok::eod))
940 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
948 if (Tok.
isNot(tok::eod)) {
949 Diag(Tok, diag::err_pp_expected_eol);
957 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
958 bool IsNonZero = ResVal.Val != 0;
963Preprocessor::DirectiveEvalResult
964Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo *&IfNDefMacro,
967 bool EvaluatedDefined;
968 return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined,
static bool isUnsigned(SValBuilder &SVB, NonLoc Value)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the PPCallbacks interface.
static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP)
EvaluateValue - Evaluate the token PeekTok (and any others needed) and return the computed value in R...
static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS, Token &Tok)
static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, bool &IncludedUndefinedIds, Preprocessor &PP)
EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is PeekTok,...
static unsigned getPrecedence(tok::TokenKind Kind)
getPrecedence - Return the precedence of the specified binary operator token.
static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP)
EvaluateDefined - Process a 'defined(sym)' expression.
static StringRef getIdentifier(const Token &Tok)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
CharLiteralParser - Perform interpretation and semantic analysis of a character literal.
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
virtual void CodeCompletePreprocessorExpression()
Callback invoked when performing code completion in a preprocessor expression, such as the condition ...
std::vector< std::string > UndefPrefixes
The list of prefixes from -Wundef-prefix=... used to generate warnings for undefined macros.
Concrete class used by the front-end to report problems and issues.
DiagnosticOptions & getDiagnosticOptions() const
Retrieve the diagnostic options.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
One of these records is kept for each identifier that is lexed.
bool isCPlusPlusOperatorKeyword() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A description of the current definition of a macro.
NumericLiteralParser - This performs strict semantic analysis of the content of a ppnumber,...
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
PPCallbacks * getPPCallbacks() const
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void setCodeCompletionReached()
Note that we hit the code-completion point.
void LexNonComment(Token &Result)
Lex a token.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
const TargetInfo & getTargetInfo() const
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
CodeCompletionHandler * getCodeCompletionHandler() const
Retrieve the current code-completion handler.
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
void setEnd(SourceLocation e)
bool isFunctionMacroExpansion() const
const ExpansionInfo & getExpansion() const
Exposes information about the current target.
unsigned getChar32Width() const
getChar32Width/Align - Return the size of 'char32_t' for this target, in bits.
static bool isTypeSigned(IntType T)
Returns true if the type is signed; false otherwise.
unsigned getChar16Width() const
getChar16Width/Align - Return the size of 'char16_t' for this target, in bits.
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...
IntType getWCharType() const
unsigned getWCharWidth() const
getWCharWidth/Align - Return the size of 'wchar_t' for this target, in bits.
unsigned getIntMaxTWidth() const
Return the size of intmax_t and uintmax_t for this target, in bits.
unsigned getCharWidth() const
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
Defines the clang::TargetInfo interface.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
DefinedTracker - This struct is used while parsing expressions to keep track of whether !...
TrackerState
Each time a Value is evaluated, it returns information about whether the parsed value is of the form ...
bool IncludedUndefinedIds
IdentifierInfo * TheMacro
TheMacro - When the state is DefinedMacro or NotDefinedMacro, this indicates the macro that was check...
enum DefinedTracker::TrackerState State