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);
139 if (Result.Val != 0 && ValueLive)
143 Token macroToken(PeekTok);
151 if (PeekTok.
isNot(tok::r_paren)) {
153 <<
"'defined'" << tok::r_paren;
154 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
185 bool IsFunctionTypeMacro =
205 if (IsFunctionTypeMacro)
206 PP.
Diag(beginLoc, diag::warn_defined_in_function_type_macro);
208 PP.
Diag(beginLoc, diag::warn_defined_in_object_type_macro);
213 Callbacks->Defined(macroToken, Macro,
235 Result.setIdentifier(
nullptr);
237 if (PeekTok.
is(tok::code_completion)) {
251 if (II->
isStr(
"defined"))
259 PP.
Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
263 if (DiagEngine.
isIgnored(diag::warn_pp_undef_identifier,
265 const std::vector<std::string> UndefPrefixes =
267 const StringRef IdentifierName = II->
getName();
268 if (llvm::any_of(UndefPrefixes,
269 [&IdentifierName](
const std::string &Prefix) {
270 return IdentifierName.startswith(Prefix);
272 PP.
Diag(PeekTok, diag::warn_pp_undef_prefix)
277 Result.Val.setIsUnsigned(
false);
278 Result.setIdentifier(II);
285 PP.
Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
290 PP.
Diag(PeekTok, diag::err_pp_expected_value_in_expr);
292 case tok::numeric_constant: {
294 bool NumberInvalid =
false;
295 StringRef Spelling = PP.
getSpelling(PeekTok, IntegerBuffer,
303 if (Literal.hadError)
306 if (Literal.isFloatingLiteral() || Literal.isImaginary) {
307 PP.
Diag(PeekTok, diag::err_pp_illegal_floating_literal);
310 assert(Literal.isIntegerLiteral() &&
"Unknown ppnumber");
313 if (Literal.hasUDSuffix())
314 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 1;
321 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
323 PP.
Diag(PeekTok, diag::ext_c99_longlong);
330 ? diag::warn_cxx20_compat_size_t_suffix
331 : diag::ext_cxx23_size_t_suffix
332 : diag::err_cxx23_size_t_suffix);
337 if (Literal.isBitInt)
339 ? diag::warn_c2x_compat_bitint_suffix
340 : diag::ext_c2x_bitint_suffix);
343 if (Literal.GetIntegerValue(Result.Val)) {
346 PP.
Diag(PeekTok, diag::err_integer_literal_too_large)
348 Result.Val.setIsUnsigned(
true);
352 Result.Val.setIsUnsigned(Literal.isUnsigned);
358 if (!Literal.isUnsigned && Result.Val.isNegative()) {
361 if (ValueLive && Literal.getRadix() == 10)
362 PP.
Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
363 Result.Val.setIsUnsigned(
true);
372 case tok::char_constant:
373 case tok::wide_char_constant:
374 case tok::utf8_char_constant:
375 case tok::utf16_char_constant:
376 case tok::utf32_char_constant: {
379 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 0;
382 bool CharInvalid =
false;
383 StringRef ThisTok = PP.
getSpelling(PeekTok, CharBuffer, &CharInvalid);
389 if (Literal.hadError())
395 if (Literal.isMultiChar())
397 else if (Literal.isWide())
399 else if (Literal.isUTF16())
401 else if (Literal.isUTF32())
407 llvm::APSInt Val(NumBits);
409 Val = Literal.getValue();
412 if (Literal.isWide())
414 else if (Literal.isUTF16() || Literal.isUTF32())
415 Val.setIsUnsigned(
true);
416 else if (Literal.isUTF8()) {
421 Val.setIsUnsigned(
true);
425 if (Result.Val.getBitWidth() > Val.getBitWidth()) {
426 Result.Val = Val.extend(Result.Val.getBitWidth());
428 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
429 "intmax_t smaller than char/wchar_t?");
443 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
447 if (PeekTok.
is(tok::r_paren)) {
455 if (PeekTok.
isNot(tok::r_paren)) {
457 << Result.getRange();
458 PP.
Diag(Start, diag::note_matching) << tok::l_paren;
464 Result.setIdentifier(
nullptr);
472 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
473 Result.setBegin(Start);
474 Result.setIdentifier(
nullptr);
480 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
481 Result.setBegin(Loc);
482 Result.setIdentifier(
nullptr);
485 Result.Val = -Result.Val;
488 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
491 if (Overflow && ValueLive)
492 PP.
Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
501 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
502 Result.setBegin(Start);
503 Result.setIdentifier(
nullptr);
506 Result.Val = ~Result.Val;
514 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
515 Result.setBegin(Start);
516 Result.Val = !Result.Val;
518 Result.Val.setIsUnsigned(
false);
519 Result.setIdentifier(
nullptr);
529 Result.Val = PeekTok.
getKind() == tok::kw_true;
530 Result.Val.setIsUnsigned(
false);
550 case tok::star:
return 14;
552 case tok::minus:
return 13;
554 case tok::greatergreater:
return 12;
557 case tok::greaterequal:
558 case tok::greater:
return 11;
559 case tok::exclaimequal:
560 case tok::equalequal:
return 10;
561 case tok::amp:
return 9;
562 case tok::caret:
return 8;
563 case tok::pipe:
return 7;
564 case tok::ampamp:
return 6;
565 case tok::pipepipe:
return 5;
566 case tok::question:
return 4;
567 case tok::comma:
return 3;
568 case tok::colon:
return 2;
569 case tok::r_paren:
return 0;
570 case tok::eod:
return 0;
576 if (Tok.
is(tok::l_paren) && LHS.getIdentifier())
577 PP.
Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
578 << LHS.getIdentifier();
591 Token &PeekTok,
bool ValueLive,
592 bool &IncludedUndefinedIds,
596 if (PeekPrec == ~0
U) {
604 if (PeekPrec < MinPrec)
615 if (Operator == tok::ampamp && LHS.Val == 0)
617 else if (Operator == tok::pipepipe && LHS.Val != 0)
619 else if (Operator == tok::question && LHS.Val == 0)
622 RHSIsLive = ValueLive;
628 PPValue RHS(LHS.getBitWidth());
631 if (
EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP))
return true;
636 unsigned ThisPrec = PeekPrec;
640 if (PeekPrec == ~0
U) {
656 if (Operator == tok::question)
660 RHSPrec = ThisPrec+1;
662 if (PeekPrec >= RHSPrec) {
664 IncludedUndefinedIds, PP))
668 assert(PeekPrec <= ThisPrec &&
"Recursion didn't work!");
672 llvm::APSInt Res(LHS.getBitWidth());
676 case tok::greatergreater:
682 Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());
685 if (ValueLive && Res.isUnsigned()) {
686 if (!LHS.isUnsigned() && LHS.Val.isNegative())
687 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
688 <<
toString(LHS.Val, 10,
true) +
" to " +
690 << LHS.getRange() << RHS.getRange();
691 if (!RHS.isUnsigned() && RHS.Val.isNegative())
692 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
693 <<
toString(RHS.Val, 10,
true) +
" to " +
695 << LHS.getRange() << RHS.getRange();
697 LHS.Val.setIsUnsigned(Res.isUnsigned());
698 RHS.Val.setIsUnsigned(Res.isUnsigned());
701 bool Overflow =
false;
703 default: llvm_unreachable(
"Unknown operator token!");
706 Res = LHS.Val % RHS.Val;
707 else if (ValueLive) {
708 PP.
Diag(OpLoc, diag::err_pp_remainder_by_zero)
709 << LHS.getRange() << RHS.getRange();
715 if (LHS.Val.isSigned())
716 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow),
false);
718 Res = LHS.Val / RHS.Val;
719 }
else if (ValueLive) {
720 PP.
Diag(OpLoc, diag::err_pp_division_by_zero)
721 << LHS.getRange() << RHS.getRange();
728 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow),
false);
730 Res = LHS.Val * RHS.Val;
732 case tok::lessless: {
734 if (LHS.isUnsigned())
735 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
737 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow),
false);
740 case tok::greatergreater: {
742 unsigned ShAmt =
static_cast<unsigned>(RHS.Val.getLimitedValue());
743 if (ShAmt >= LHS.getBitWidth()) {
745 ShAmt = LHS.getBitWidth()-1;
747 Res = LHS.Val >> ShAmt;
751 if (LHS.isUnsigned())
752 Res = LHS.Val + RHS.Val;
754 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow),
false);
757 if (LHS.isUnsigned())
758 Res = LHS.Val - RHS.Val;
760 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow),
false);
763 Res = LHS.Val <= RHS.Val;
764 Res.setIsUnsigned(
false);
767 Res = LHS.Val < RHS.Val;
768 Res.setIsUnsigned(
false);
770 case tok::greaterequal:
771 Res = LHS.Val >= RHS.Val;
772 Res.setIsUnsigned(
false);
775 Res = LHS.Val > RHS.Val;
776 Res.setIsUnsigned(
false);
778 case tok::exclaimequal:
779 Res = LHS.Val != RHS.Val;
780 Res.setIsUnsigned(
false);
782 case tok::equalequal:
783 Res = LHS.Val == RHS.Val;
784 Res.setIsUnsigned(
false);
787 Res = LHS.Val & RHS.Val;
790 Res = LHS.Val ^ RHS.Val;
793 Res = LHS.Val | RHS.Val;
796 Res = (LHS.Val != 0 && RHS.Val != 0);
797 Res.setIsUnsigned(
false);
800 Res = (LHS.Val != 0 || RHS.Val != 0);
801 Res.setIsUnsigned(
false);
807 PP.
Diag(OpLoc, diag::ext_pp_comma_expr)
808 << LHS.getRange() << RHS.getRange();
811 case tok::question: {
813 if (PeekTok.
isNot(tok::colon)) {
815 << tok::colon << LHS.getRange() << RHS.getRange();
816 PP.
Diag(OpLoc, diag::note_matching) << tok::question;
823 bool AfterColonLive = ValueLive && LHS.Val == 0;
824 PPValue AfterColonVal(LHS.getBitWidth());
826 if (
EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
832 PeekTok, AfterColonLive,
833 IncludedUndefinedIds, PP))
837 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
838 RHS.setEnd(AfterColonVal.getRange().getEnd());
842 Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());
850 PP.
Diag(OpLoc, diag::err_pp_colon_without_question)
851 << LHS.getRange() << RHS.getRange();
856 if (Overflow && ValueLive)
857 PP.
Diag(OpLoc, diag::warn_pp_expr_overflow)
858 << LHS.getRange() << RHS.getRange();
862 LHS.setEnd(RHS.getRange().getEnd());
863 RHS.setIdentifier(
nullptr);
870Preprocessor::DirectiveEvalResult
871Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo *&IfNDefMacro) {
879 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
880 DisableMacroExpansion =
false;
889 PPValue ResVal(BitWidth);
895 if (Tok.
isNot(tok::eod))
899 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
906 {ExprStartLoc, ConditionRange.
getEnd()}};
912 if (Tok.
is(tok::eod)) {
919 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
928 if (Tok.
isNot(tok::eod))
932 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
938 if (Tok.
isNot(tok::eod)) {
939 Diag(Tok, diag::err_pp_expected_eol);
944 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
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.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
void emitMacroExpansionWarnings(const Token &Identifier) const
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 ...
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
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.
SourceLocation getEnd() const
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.
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