31 #include "llvm/ADT/APSInt.h" 32 #include "llvm/ADT/SmallString.h" 33 #include "llvm/ADT/StringRef.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/SaveAndRestore.h" 38 using namespace clang;
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,
97 bool IncludedUndefinedIds =
false;
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);
136 if (Result.Val != 0 && ValueLive)
140 Token macroToken(PeekTok);
148 if (PeekTok.
isNot(tok::r_paren)) {
150 <<
"'defined'" << tok::r_paren;
151 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
181 if (beginLoc.isMacroID()) {
182 bool IsFunctionTypeMacro =
186 .isFunctionMacroExpansion();
202 if (IsFunctionTypeMacro)
203 PP.
Diag(beginLoc, diag::warn_defined_in_function_type_macro);
205 PP.
Diag(beginLoc, diag::warn_defined_in_object_type_macro);
210 Callbacks->Defined(macroToken, Macro,
232 Result.setIdentifier(
nullptr);
234 if (PeekTok.
is(tok::code_completion)) {
248 if (II->
isStr(
"defined"))
256 PP.
Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
258 Result.Val.setIsUnsigned(
false);
259 Result.setIdentifier(II);
266 PP.
Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
271 PP.
Diag(PeekTok, diag::err_pp_expected_value_in_expr);
273 case tok::numeric_constant: {
275 bool NumberInvalid =
false;
276 StringRef Spelling = PP.
getSpelling(PeekTok, IntegerBuffer,
282 if (Literal.hadError)
285 if (Literal.isFloatingLiteral() || Literal.isImaginary) {
286 PP.
Diag(PeekTok, diag::err_pp_illegal_floating_literal);
289 assert(Literal.isIntegerLiteral() &&
"Unknown ppnumber");
292 if (Literal.hasUDSuffix())
293 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 1;
300 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
302 PP.
Diag(PeekTok, diag::ext_c99_longlong);
306 if (Literal.GetIntegerValue(Result.Val)) {
309 PP.
Diag(PeekTok, diag::err_integer_literal_too_large)
311 Result.Val.setIsUnsigned(
true);
315 Result.Val.setIsUnsigned(Literal.isUnsigned);
321 if (!Literal.isUnsigned && Result.Val.isNegative()) {
324 if (ValueLive && Literal.getRadix() == 10)
325 PP.
Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
326 Result.Val.setIsUnsigned(
true);
335 case tok::char_constant:
336 case tok::wide_char_constant:
337 case tok::utf8_char_constant:
338 case tok::utf16_char_constant:
339 case tok::utf32_char_constant: {
342 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 0;
345 bool CharInvalid =
false;
346 StringRef ThisTok = PP.
getSpelling(PeekTok, CharBuffer, &CharInvalid);
352 if (Literal.hadError())
358 if (Literal.isMultiChar())
360 else if (Literal.isWide())
362 else if (Literal.isUTF16())
364 else if (Literal.isUTF32())
370 llvm::APSInt Val(NumBits);
372 Val = Literal.getValue();
374 if (Literal.isWide())
376 else if (!Literal.isUTF16() && !Literal.isUTF32())
379 if (Result.Val.getBitWidth() > Val.getBitWidth()) {
380 Result.Val = Val.extend(Result.Val.getBitWidth());
382 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
383 "intmax_t smaller than char/wchar_t?");
397 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
401 if (PeekTok.
is(tok::r_paren)) {
409 if (PeekTok.
isNot(tok::r_paren)) {
411 << Result.getRange();
412 PP.
Diag(Start, diag::note_matching) << tok::l_paren;
418 Result.setIdentifier(
nullptr);
426 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
427 Result.setBegin(Start);
428 Result.setIdentifier(
nullptr);
434 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
435 Result.setBegin(Loc);
436 Result.setIdentifier(
nullptr);
439 Result.Val = -Result.Val;
442 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
445 if (Overflow && ValueLive)
446 PP.
Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
455 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
456 Result.setBegin(Start);
457 Result.setIdentifier(
nullptr);
460 Result.Val = ~Result.Val;
468 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
469 Result.setBegin(Start);
470 Result.Val = !Result.Val;
472 Result.Val.setIsUnsigned(
false);
473 Result.setIdentifier(
nullptr);
483 Result.Val = PeekTok.
getKind() == tok::kw_true;
484 Result.Val.setIsUnsigned(
false);
504 case tok::star:
return 14;
506 case tok::minus:
return 13;
508 case tok::greatergreater:
return 12;
511 case tok::greaterequal:
512 case tok::greater:
return 11;
513 case tok::exclaimequal:
514 case tok::equalequal:
return 10;
515 case tok::amp:
return 9;
516 case tok::caret:
return 8;
517 case tok::pipe:
return 7;
518 case tok::ampamp:
return 6;
519 case tok::pipepipe:
return 5;
520 case tok::question:
return 4;
521 case tok::comma:
return 3;
522 case tok::colon:
return 2;
523 case tok::r_paren:
return 0;
524 case tok::eod:
return 0;
530 if (Tok.
is(tok::l_paren) && LHS.getIdentifier())
531 PP.
Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
532 << LHS.getIdentifier();
545 Token &PeekTok,
bool ValueLive,
546 bool &IncludedUndefinedIds,
550 if (PeekPrec == ~0U) {
558 if (PeekPrec < MinPrec)
569 if (Operator == tok::ampamp && LHS.Val == 0)
571 else if (Operator == tok::pipepipe && LHS.Val != 0)
573 else if (Operator == tok::question && LHS.Val == 0)
576 RHSIsLive = ValueLive;
582 PPValue RHS(LHS.getBitWidth());
585 if (
EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP))
return true;
590 unsigned ThisPrec = PeekPrec;
594 if (PeekPrec == ~0U) {
610 if (Operator == tok::question)
614 RHSPrec = ThisPrec+1;
616 if (PeekPrec >= RHSPrec) {
618 IncludedUndefinedIds, PP))
622 assert(PeekPrec <= ThisPrec &&
"Recursion didn't work!");
626 llvm::APSInt Res(LHS.getBitWidth());
630 case tok::greatergreater:
636 Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
639 if (ValueLive && Res.isUnsigned()) {
640 if (!LHS.isUnsigned() && LHS.Val.isNegative())
641 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
642 << LHS.Val.toString(10,
true) +
" to " +
643 LHS.Val.toString(10,
false)
644 << LHS.getRange() << RHS.getRange();
645 if (!RHS.isUnsigned() && RHS.Val.isNegative())
646 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
647 << RHS.Val.toString(10,
true) +
" to " +
648 RHS.Val.toString(10,
false)
649 << LHS.getRange() << RHS.getRange();
651 LHS.Val.setIsUnsigned(Res.isUnsigned());
652 RHS.Val.setIsUnsigned(Res.isUnsigned());
655 bool Overflow =
false;
657 default: llvm_unreachable(
"Unknown operator token!");
660 Res = LHS.Val % RHS.Val;
661 else if (ValueLive) {
662 PP.
Diag(OpLoc, diag::err_pp_remainder_by_zero)
663 << LHS.getRange() << RHS.getRange();
669 if (LHS.Val.isSigned())
670 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow),
false);
672 Res = LHS.Val / RHS.Val;
673 }
else if (ValueLive) {
674 PP.
Diag(OpLoc, diag::err_pp_division_by_zero)
675 << LHS.getRange() << RHS.getRange();
682 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow),
false);
684 Res = LHS.Val * RHS.Val;
686 case tok::lessless: {
688 if (LHS.isUnsigned())
689 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
691 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow),
false);
694 case tok::greatergreater: {
696 unsigned ShAmt =
static_cast<unsigned>(RHS.Val.getLimitedValue());
697 if (ShAmt >= LHS.getBitWidth()) {
699 ShAmt = LHS.getBitWidth()-1;
701 Res = LHS.Val >> ShAmt;
705 if (LHS.isUnsigned())
706 Res = LHS.Val + RHS.Val;
708 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow),
false);
711 if (LHS.isUnsigned())
712 Res = LHS.Val - RHS.Val;
714 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow),
false);
717 Res = LHS.Val <= RHS.Val;
718 Res.setIsUnsigned(
false);
721 Res = LHS.Val < RHS.Val;
722 Res.setIsUnsigned(
false);
724 case tok::greaterequal:
725 Res = LHS.Val >= RHS.Val;
726 Res.setIsUnsigned(
false);
729 Res = LHS.Val > RHS.Val;
730 Res.setIsUnsigned(
false);
732 case tok::exclaimequal:
733 Res = LHS.Val != RHS.Val;
734 Res.setIsUnsigned(
false);
736 case tok::equalequal:
737 Res = LHS.Val == RHS.Val;
738 Res.setIsUnsigned(
false);
741 Res = LHS.Val & RHS.Val;
744 Res = LHS.Val ^ RHS.Val;
747 Res = LHS.Val | RHS.Val;
750 Res = (LHS.Val != 0 && RHS.Val != 0);
751 Res.setIsUnsigned(
false);
754 Res = (LHS.Val != 0 || RHS.Val != 0);
755 Res.setIsUnsigned(
false);
761 PP.
Diag(OpLoc, diag::ext_pp_comma_expr)
762 << LHS.getRange() << RHS.getRange();
765 case tok::question: {
767 if (PeekTok.
isNot(tok::colon)) {
769 << tok::colon << LHS.getRange() << RHS.getRange();
770 PP.
Diag(OpLoc, diag::note_matching) << tok::question;
777 bool AfterColonLive = ValueLive && LHS.Val == 0;
778 PPValue AfterColonVal(LHS.getBitWidth());
780 if (
EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
786 PeekTok, AfterColonLive,
787 IncludedUndefinedIds, PP))
791 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
792 RHS.setEnd(AfterColonVal.getRange().getEnd());
796 Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
804 PP.
Diag(OpLoc, diag::err_pp_colon_without_question)
805 << LHS.getRange() << RHS.getRange();
810 if (Overflow && ValueLive)
811 PP.
Diag(OpLoc, diag::warn_pp_expr_overflow)
812 << LHS.getRange() << RHS.getRange();
816 LHS.setEnd(RHS.getRange().getEnd());
817 RHS.setIdentifier(
nullptr);
824 Preprocessor::DirectiveEvalResult
825 Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo *&IfNDefMacro) {
833 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
834 DisableMacroExpansion =
false;
841 unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
843 PPValue ResVal(BitWidth);
847 if (Tok.
isNot(tok::eod))
848 DiscardUntilEndOfDirective();
851 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
858 if (Tok.
is(tok::eod)) {
865 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
874 if (Tok.
isNot(tok::eod))
875 DiscardUntilEndOfDirective();
878 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
884 if (Tok.
isNot(tok::eod)) {
885 Diag(Tok, diag::err_pp_expected_eol);
886 DiscardUntilEndOfDirective();
890 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
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)) {...
Defines the SourceManager interface.
static unsigned getPrecedence(tok::TokenKind Kind)
getPrecedence - Return the precedence of the specified binary operator token.
Defines the clang::MacroInfo and clang::MacroDirective classes.
A description of the current definition of a macro.
unsigned getCharWidth() const
void setCodeCompletionReached()
Note that we hit the code-completion point.
void setBegin(SourceLocation b)
This interface provides a way to observe the actions of the preprocessor as it does its thing...
tok::TokenKind getKind() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
unsigned getChar32Width() const
getChar32Width/Align - Return the size of 'char32_t' for this target, in bits.
bool isCPlusPlusOperatorKeyword() const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
const LangOptions & getLangOpts() const
static bool isTypeSigned(IntType T)
Returns true if the type is signed; false otherwise.
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 ...
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
void LexNonComment(Token &Result)
Lex a token.
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, and whose precedence is PeekPrec.
Exposes information about the current target.
TrackerState
Each time a Value is evaluated, it returns information about whether the parsed value is of the form ...
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target, in bits.
bool IncludedUndefinedIds
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
CharLiteralParser - Perform interpretation and semantic analysis of a character literal.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
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...
PPCallbacks * getPPCallbacks() const
The result type of a method or function.
static StringRef getIdentifier(const Token &Tok)
SourceManager & getSourceManager() const
unsigned getWCharWidth() const
getWCharWidth/Align - Return the size of 'wchar_t' for this target, in bits.
IdentifierInfo * TheMacro
TheMacro - When the state is DefinedMacro or NotDefinedMacro, this indicates the macro that was check...
Encodes a location in the source.
unsigned getChar16Width() const
getChar16Width/Align - Return the size of 'char16_t' for this target, in bits.
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
enum DefinedTracker::TrackerState State
IdentifierInfo * getIdentifierInfo() const
CodeCompletionHandler * getCodeCompletionHandler() const
Retrieve the current code-completion handler.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP)
EvaluateDefined - Process a 'defined(sym)' expression.
virtual void CodeCompletePreprocessorExpression()
Callback invoked when performing code completion in a preprocessor expression, such as the condition ...
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
DefinedTracker - This struct is used while parsing expressions to keep track of whether !defined(X) h...
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
Defines the PPCallbacks interface.
Defines the clang::TokenKind enum and support functions.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected...
Defines the clang::SourceLocation class and associated facilities.
void setEnd(SourceLocation e)
IntType getWCharType() const
Defines the clang::TargetInfo interface.
NumericLiteralParser - This performs strict semantic analysis of the content of a ppnumber...
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
A trivial tuple used to represent a source range.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.