30#include "llvm/ADT/APSInt.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/SmallString.h"
33#include "llvm/ADT/StringExtras.h"
34#include "llvm/ADT/StringRef.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/SaveAndRestore.h"
53 PPValue(
unsigned BitWidth) : Val(BitWidth) {}
60 unsigned getBitWidth()
const {
return Val.getBitWidth(); }
61 bool isUnsigned()
const {
return Val.isUnsigned(); }
76 Token &PeekTok,
bool ValueLive,
77 bool &IncludedUndefinedIds,
105 Result.setBegin(beginLoc);
112 if (PeekTok.
is(tok::l_paren)) {
118 if (PeekTok.
is(tok::code_completion)) {
132 Result.Val = !!Macro;
133 Result.Val.setIsUnsigned(
false);
138 (II->
getName() ==
"INFINITY" || II->
getName() ==
"NAN") ?
true :
false);
141 if (Result.Val != 0 && ValueLive)
145 Token macroToken(PeekTok);
153 if (PeekTok.
isNot(tok::r_paren)) {
155 <<
"'defined'" << tok::r_paren;
156 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
187 bool IsFunctionTypeMacro =
207 if (IsFunctionTypeMacro)
208 PP.
Diag(beginLoc, diag::warn_defined_in_function_type_macro);
210 PP.
Diag(beginLoc, diag::warn_defined_in_object_type_macro);
215 Callbacks->Defined(macroToken, Macro,
237 Result.setIdentifier(
nullptr);
239 if (PeekTok.
is(tok::code_completion)) {
253 if (II->
isStr(
"defined"))
261 PP.
Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
265 if (DiagEngine.
isIgnored(diag::warn_pp_undef_identifier,
267 const std::vector<std::string> UndefPrefixes =
269 const StringRef IdentifierName = II->
getName();
270 if (llvm::any_of(UndefPrefixes,
271 [&IdentifierName](
const std::string &Prefix) {
272 return IdentifierName.starts_with(Prefix);
274 PP.
Diag(PeekTok, diag::warn_pp_undef_prefix)
279 Result.Val.setIsUnsigned(
false);
280 Result.setIdentifier(II);
287 PP.
Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
292 PP.
Diag(PeekTok, diag::err_pp_expected_value_in_expr);
294 case tok::numeric_constant: {
296 bool NumberInvalid =
false;
297 StringRef Spelling = PP.
getSpelling(PeekTok, IntegerBuffer,
305 if (Literal.hadError)
308 if (Literal.isFloatingLiteral() || Literal.isImaginary) {
309 PP.
Diag(PeekTok, diag::err_pp_illegal_floating_literal);
312 assert(Literal.isIntegerLiteral() &&
"Unknown ppnumber");
315 if (Literal.hasUDSuffix())
316 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 1;
323 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
325 PP.
Diag(PeekTok, diag::ext_c99_longlong);
332 ? diag::warn_cxx20_compat_size_t_suffix
333 : diag::ext_cxx23_size_t_suffix
334 : diag::err_cxx23_size_t_suffix);
338 if (Literal.isBitInt)
339 PP.
Diag(PeekTok, PP.
getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
341 ? diag::warn_c23_compat_bitint_suffix
342 : diag::ext_c23_bitint_suffix);
345 if (Literal.GetIntegerValue(Result.Val)) {
348 PP.
Diag(PeekTok, diag::err_integer_literal_too_large)
350 Result.Val.setIsUnsigned(
true);
354 Result.Val.setIsUnsigned(Literal.isUnsigned);
360 if (!Literal.isUnsigned && Result.Val.isNegative()) {
363 if (ValueLive && Literal.getRadix() == 10)
364 PP.
Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
365 Result.Val.setIsUnsigned(
true);
374 case tok::char_constant:
375 case tok::wide_char_constant:
376 case tok::utf8_char_constant:
377 case tok::utf16_char_constant:
378 case tok::utf32_char_constant: {
381 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 0;
384 bool CharInvalid =
false;
385 StringRef ThisTok = PP.
getSpelling(PeekTok, CharBuffer, &CharInvalid);
391 if (Literal.hadError())
397 if (Literal.isMultiChar())
399 else if (Literal.isWide())
401 else if (Literal.isUTF16())
403 else if (Literal.isUTF32())
409 llvm::APSInt Val(NumBits);
411 Val = Literal.getValue();
414 if (Literal.isWide())
416 else if (Literal.isUTF16() || Literal.isUTF32())
417 Val.setIsUnsigned(
true);
418 else if (Literal.isUTF8()) {
423 Val.setIsUnsigned(
true);
427 if (Result.Val.getBitWidth() > Val.getBitWidth()) {
428 Result.Val = Val.extend(Result.Val.getBitWidth());
430 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
431 "intmax_t smaller than char/wchar_t?");
445 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
449 if (PeekTok.
is(tok::r_paren)) {
457 if (PeekTok.
isNot(tok::r_paren)) {
459 << Result.getRange();
460 PP.
Diag(Start, diag::note_matching) << tok::l_paren;
466 Result.setIdentifier(
nullptr);
474 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
475 Result.setBegin(Start);
476 Result.setIdentifier(
nullptr);
482 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
483 Result.setBegin(
Loc);
484 Result.setIdentifier(
nullptr);
487 Result.Val = -Result.Val;
490 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
493 if (Overflow && ValueLive)
494 PP.
Diag(
Loc, diag::warn_pp_expr_overflow) << Result.getRange();
503 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
504 Result.setBegin(Start);
505 Result.setIdentifier(
nullptr);
508 Result.Val = ~Result.Val;
516 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
517 Result.setBegin(Start);
518 Result.Val = !Result.Val;
520 Result.Val.setIsUnsigned(
false);
521 Result.setIdentifier(
nullptr);
531 Result.Val = PeekTok.
getKind() == tok::kw_true;
532 Result.Val.setIsUnsigned(
false);
552 case tok::star:
return 14;
554 case tok::minus:
return 13;
556 case tok::greatergreater:
return 12;
559 case tok::greaterequal:
560 case tok::greater:
return 11;
561 case tok::exclaimequal:
562 case tok::equalequal:
return 10;
563 case tok::amp:
return 9;
564 case tok::caret:
return 8;
565 case tok::pipe:
return 7;
566 case tok::ampamp:
return 6;
567 case tok::pipepipe:
return 5;
568 case tok::question:
return 4;
569 case tok::comma:
return 3;
570 case tok::colon:
return 2;
571 case tok::r_paren:
return 0;
572 case tok::eod:
return 0;
578 if (Tok.
is(tok::l_paren) && LHS.getIdentifier())
579 PP.
Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
580 << LHS.getIdentifier();
593 Token &PeekTok,
bool ValueLive,
594 bool &IncludedUndefinedIds,
598 if (PeekPrec == ~0
U) {
606 if (PeekPrec < MinPrec)
617 if (Operator == tok::ampamp && LHS.Val == 0)
619 else if (Operator == tok::pipepipe && LHS.Val != 0)
621 else if (Operator == tok::question && LHS.Val == 0)
624 RHSIsLive = ValueLive;
630 PPValue RHS(LHS.getBitWidth());
633 if (
EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP))
return true;
638 unsigned ThisPrec = PeekPrec;
642 if (PeekPrec == ~0
U) {
658 if (Operator == tok::question)
662 RHSPrec = ThisPrec+1;
664 if (PeekPrec >= RHSPrec) {
666 IncludedUndefinedIds, PP))
670 assert(PeekPrec <= ThisPrec &&
"Recursion didn't work!");
674 llvm::APSInt Res(LHS.getBitWidth());
678 case tok::greatergreater:
684 Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());
687 if (ValueLive && Res.isUnsigned()) {
688 if (!LHS.isUnsigned() && LHS.Val.isNegative())
689 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
690 <<
toString(LHS.Val, 10,
true) +
" to " +
692 << LHS.getRange() << RHS.getRange();
693 if (!RHS.isUnsigned() && RHS.Val.isNegative())
694 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
695 <<
toString(RHS.Val, 10,
true) +
" to " +
697 << LHS.getRange() << RHS.getRange();
699 LHS.Val.setIsUnsigned(Res.isUnsigned());
700 RHS.Val.setIsUnsigned(Res.isUnsigned());
703 bool Overflow =
false;
705 default: llvm_unreachable(
"Unknown operator token!");
708 Res = LHS.Val % RHS.Val;
709 else if (ValueLive) {
710 PP.
Diag(OpLoc, diag::err_pp_remainder_by_zero)
711 << LHS.getRange() << RHS.getRange();
717 if (LHS.Val.isSigned())
718 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow),
false);
720 Res = LHS.Val / RHS.Val;
721 }
else if (ValueLive) {
722 PP.
Diag(OpLoc, diag::err_pp_division_by_zero)
723 << LHS.getRange() << RHS.getRange();
730 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow),
false);
732 Res = LHS.Val * RHS.Val;
734 case tok::lessless: {
736 if (LHS.isUnsigned())
737 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
739 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow),
false);
742 case tok::greatergreater: {
744 unsigned ShAmt =
static_cast<unsigned>(RHS.Val.getLimitedValue());
745 if (ShAmt >= LHS.getBitWidth()) {
747 ShAmt = LHS.getBitWidth()-1;
749 Res = LHS.Val >> ShAmt;
753 if (LHS.isUnsigned())
754 Res = LHS.Val + RHS.Val;
756 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow),
false);
759 if (LHS.isUnsigned())
760 Res = LHS.Val - RHS.Val;
762 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow),
false);
765 Res = LHS.Val <= RHS.Val;
766 Res.setIsUnsigned(
false);
769 Res = LHS.Val < RHS.Val;
770 Res.setIsUnsigned(
false);
772 case tok::greaterequal:
773 Res = LHS.Val >= RHS.Val;
774 Res.setIsUnsigned(
false);
777 Res = LHS.Val > RHS.Val;
778 Res.setIsUnsigned(
false);
780 case tok::exclaimequal:
781 Res = LHS.Val != RHS.Val;
782 Res.setIsUnsigned(
false);
784 case tok::equalequal:
785 Res = LHS.Val == RHS.Val;
786 Res.setIsUnsigned(
false);
789 Res = LHS.Val & RHS.Val;
792 Res = LHS.Val ^ RHS.Val;
795 Res = LHS.Val | RHS.Val;
798 Res = (LHS.Val != 0 && RHS.Val != 0);
799 Res.setIsUnsigned(
false);
802 Res = (LHS.Val != 0 || RHS.Val != 0);
803 Res.setIsUnsigned(
false);
809 PP.
Diag(OpLoc, diag::ext_pp_comma_expr)
810 << LHS.getRange() << RHS.getRange();
813 case tok::question: {
815 if (PeekTok.
isNot(tok::colon)) {
817 << tok::colon << LHS.getRange() << RHS.getRange();
818 PP.
Diag(OpLoc, diag::note_matching) << tok::question;
825 bool AfterColonLive = ValueLive && LHS.Val == 0;
826 PPValue AfterColonVal(LHS.getBitWidth());
828 if (
EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
834 PeekTok, AfterColonLive,
835 IncludedUndefinedIds, PP))
839 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
840 RHS.setEnd(AfterColonVal.getRange().getEnd());
844 Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());
852 PP.
Diag(OpLoc, diag::err_pp_colon_without_question)
853 << LHS.getRange() << RHS.getRange();
858 if (Overflow && ValueLive)
859 PP.
Diag(OpLoc, diag::warn_pp_expr_overflow)
860 << LHS.getRange() << RHS.getRange();
864 LHS.setEnd(RHS.getRange().getEnd());
865 RHS.setIdentifier(
nullptr);
872Preprocessor::DirectiveEvalResult
873Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo *&IfNDefMacro,
874 Token &Tok,
bool &EvaluatedDefined,
883 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
884 DisableMacroExpansion =
false;
892 PPValue ResVal(BitWidth);
898 if (Tok.
isNot(tok::eod))
902 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
907 return {std::nullopt,
910 {ExprStartLoc, ConditionRange.
getEnd()}};
918 if (Tok.
is(tok::eod)) {
925 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
926 bool IsNonZero = ResVal.Val != 0;
937 if (Tok.
isNot(tok::eod))
941 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
949 if (Tok.
isNot(tok::eod)) {
950 Diag(Tok, diag::err_pp_expected_eol);
958 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
959 bool IsNonZero = ResVal.Val != 0;
964Preprocessor::DirectiveEvalResult
965Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo *&IfNDefMacro,
968 bool EvaluatedDefined;
969 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