30 #include "llvm/ADT/APSInt.h" 31 #include "llvm/ADT/SmallString.h" 32 #include "llvm/ADT/StringRef.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/SaveAndRestore.h" 37 using namespace clang;
51 PPValue(
unsigned BitWidth) : Val(BitWidth) {}
58 unsigned getBitWidth()
const {
return Val.getBitWidth(); }
59 bool isUnsigned()
const {
return Val.isUnsigned(); }
74 Token &PeekTok,
bool ValueLive,
75 bool &IncludedUndefinedIds,
96 bool IncludedUndefinedIds =
false;
103 Result.setBegin(beginLoc);
110 if (PeekTok.
is(tok::l_paren)) {
116 if (PeekTok.
is(tok::code_completion)) {
130 Result.Val = !!Macro;
131 Result.Val.setIsUnsigned(
false);
135 if (Result.Val != 0 && ValueLive)
139 Token macroToken(PeekTok);
147 if (PeekTok.
isNot(tok::r_paren)) {
149 <<
"'defined'" << tok::r_paren;
150 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
180 if (beginLoc.isMacroID()) {
181 bool IsFunctionTypeMacro =
185 .isFunctionMacroExpansion();
201 if (IsFunctionTypeMacro)
202 PP.
Diag(beginLoc, diag::warn_defined_in_function_type_macro);
204 PP.
Diag(beginLoc, diag::warn_defined_in_object_type_macro);
209 Callbacks->Defined(macroToken, Macro,
231 Result.setIdentifier(
nullptr);
233 if (PeekTok.
is(tok::code_completion)) {
247 if (II->
isStr(
"defined"))
255 PP.
Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
257 Result.Val.setIsUnsigned(
false);
258 Result.setIdentifier(II);
265 PP.
Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
270 PP.
Diag(PeekTok, diag::err_pp_expected_value_in_expr);
272 case tok::numeric_constant: {
274 bool NumberInvalid =
false;
275 StringRef Spelling = PP.
getSpelling(PeekTok, IntegerBuffer,
281 if (Literal.hadError)
284 if (Literal.isFloatingLiteral() || Literal.isImaginary) {
285 PP.
Diag(PeekTok, diag::err_pp_illegal_floating_literal);
288 assert(Literal.isIntegerLiteral() &&
"Unknown ppnumber");
291 if (Literal.hasUDSuffix())
292 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 1;
299 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
301 PP.
Diag(PeekTok, diag::ext_c99_longlong);
305 if (Literal.GetIntegerValue(Result.Val)) {
308 PP.
Diag(PeekTok, diag::err_integer_literal_too_large)
310 Result.Val.setIsUnsigned(
true);
314 Result.Val.setIsUnsigned(Literal.isUnsigned);
320 if (!Literal.isUnsigned && Result.Val.isNegative()) {
323 if (ValueLive && Literal.getRadix() == 10)
324 PP.
Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
325 Result.Val.setIsUnsigned(
true);
334 case tok::char_constant:
335 case tok::wide_char_constant:
336 case tok::utf8_char_constant:
337 case tok::utf16_char_constant:
338 case tok::utf32_char_constant: {
341 PP.
Diag(PeekTok, diag::err_pp_invalid_udl) << 0;
344 bool CharInvalid =
false;
345 StringRef ThisTok = PP.
getSpelling(PeekTok, CharBuffer, &CharInvalid);
351 if (Literal.hadError())
357 if (Literal.isMultiChar())
359 else if (Literal.isWide())
361 else if (Literal.isUTF16())
363 else if (Literal.isUTF32())
369 llvm::APSInt Val(NumBits);
371 Val = Literal.getValue();
373 if (Literal.isWide())
375 else if (!Literal.isUTF16() && !Literal.isUTF32())
378 if (Result.Val.getBitWidth() > Val.getBitWidth()) {
379 Result.Val = Val.extend(Result.Val.getBitWidth());
381 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
382 "intmax_t smaller than char/wchar_t?");
396 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
400 if (PeekTok.
is(tok::r_paren)) {
408 if (PeekTok.
isNot(tok::r_paren)) {
410 << Result.getRange();
411 PP.
Diag(Start, diag::note_matching) << tok::l_paren;
417 Result.setIdentifier(
nullptr);
425 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
426 Result.setBegin(Start);
427 Result.setIdentifier(
nullptr);
433 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
434 Result.setBegin(Loc);
435 Result.setIdentifier(
nullptr);
438 Result.Val = -Result.Val;
441 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
444 if (Overflow && ValueLive)
445 PP.
Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
454 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
455 Result.setBegin(Start);
456 Result.setIdentifier(
nullptr);
459 Result.Val = ~Result.Val;
467 if (
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
468 Result.setBegin(Start);
469 Result.Val = !Result.Val;
471 Result.Val.setIsUnsigned(
false);
472 Result.setIdentifier(
nullptr);
482 Result.Val = PeekTok.
getKind() == tok::kw_true;
483 Result.Val.setIsUnsigned(
false);
503 case tok::star:
return 14;
505 case tok::minus:
return 13;
507 case tok::greatergreater:
return 12;
510 case tok::greaterequal:
511 case tok::greater:
return 11;
512 case tok::exclaimequal:
513 case tok::equalequal:
return 10;
514 case tok::amp:
return 9;
515 case tok::caret:
return 8;
516 case tok::pipe:
return 7;
517 case tok::ampamp:
return 6;
518 case tok::pipepipe:
return 5;
519 case tok::question:
return 4;
520 case tok::comma:
return 3;
521 case tok::colon:
return 2;
522 case tok::r_paren:
return 0;
523 case tok::eod:
return 0;
529 if (Tok.
is(tok::l_paren) && LHS.getIdentifier())
530 PP.
Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
531 << LHS.getIdentifier();
544 Token &PeekTok,
bool ValueLive,
545 bool &IncludedUndefinedIds,
549 if (PeekPrec == ~0U) {
557 if (PeekPrec < MinPrec)
568 if (Operator == tok::ampamp && LHS.Val == 0)
570 else if (Operator == tok::pipepipe && LHS.Val != 0)
572 else if (Operator == tok::question && LHS.Val == 0)
575 RHSIsLive = ValueLive;
581 PPValue RHS(LHS.getBitWidth());
584 if (
EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP))
return true;
589 unsigned ThisPrec = PeekPrec;
593 if (PeekPrec == ~0U) {
609 if (Operator == tok::question)
613 RHSPrec = ThisPrec+1;
615 if (PeekPrec >= RHSPrec) {
617 IncludedUndefinedIds, PP))
621 assert(PeekPrec <= ThisPrec &&
"Recursion didn't work!");
625 llvm::APSInt Res(LHS.getBitWidth());
629 case tok::greatergreater:
635 Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
638 if (ValueLive && Res.isUnsigned()) {
639 if (!LHS.isUnsigned() && LHS.Val.isNegative())
640 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
641 << LHS.Val.toString(10,
true) +
" to " +
642 LHS.Val.toString(10,
false)
643 << LHS.getRange() << RHS.getRange();
644 if (!RHS.isUnsigned() && RHS.Val.isNegative())
645 PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
646 << RHS.Val.toString(10,
true) +
" to " +
647 RHS.Val.toString(10,
false)
648 << LHS.getRange() << RHS.getRange();
650 LHS.Val.setIsUnsigned(Res.isUnsigned());
651 RHS.Val.setIsUnsigned(Res.isUnsigned());
654 bool Overflow =
false;
656 default: llvm_unreachable(
"Unknown operator token!");
659 Res = LHS.Val % RHS.Val;
660 else if (ValueLive) {
661 PP.
Diag(OpLoc, diag::err_pp_remainder_by_zero)
662 << LHS.getRange() << RHS.getRange();
668 if (LHS.Val.isSigned())
669 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow),
false);
671 Res = LHS.Val / RHS.Val;
672 }
else if (ValueLive) {
673 PP.
Diag(OpLoc, diag::err_pp_division_by_zero)
674 << LHS.getRange() << RHS.getRange();
681 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow),
false);
683 Res = LHS.Val * RHS.Val;
685 case tok::lessless: {
687 if (LHS.isUnsigned())
688 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
690 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow),
false);
693 case tok::greatergreater: {
695 unsigned ShAmt =
static_cast<unsigned>(RHS.Val.getLimitedValue());
696 if (ShAmt >= LHS.getBitWidth()) {
698 ShAmt = LHS.getBitWidth()-1;
700 Res = LHS.Val >> ShAmt;
704 if (LHS.isUnsigned())
705 Res = LHS.Val + RHS.Val;
707 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow),
false);
710 if (LHS.isUnsigned())
711 Res = LHS.Val - RHS.Val;
713 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow),
false);
716 Res = LHS.Val <= RHS.Val;
717 Res.setIsUnsigned(
false);
720 Res = LHS.Val < RHS.Val;
721 Res.setIsUnsigned(
false);
723 case tok::greaterequal:
724 Res = LHS.Val >= RHS.Val;
725 Res.setIsUnsigned(
false);
728 Res = LHS.Val > RHS.Val;
729 Res.setIsUnsigned(
false);
731 case tok::exclaimequal:
732 Res = LHS.Val != RHS.Val;
733 Res.setIsUnsigned(
false);
735 case tok::equalequal:
736 Res = LHS.Val == RHS.Val;
737 Res.setIsUnsigned(
false);
740 Res = LHS.Val & RHS.Val;
743 Res = LHS.Val ^ RHS.Val;
746 Res = LHS.Val | RHS.Val;
749 Res = (LHS.Val != 0 && RHS.Val != 0);
750 Res.setIsUnsigned(
false);
753 Res = (LHS.Val != 0 || RHS.Val != 0);
754 Res.setIsUnsigned(
false);
760 PP.
Diag(OpLoc, diag::ext_pp_comma_expr)
761 << LHS.getRange() << RHS.getRange();
764 case tok::question: {
766 if (PeekTok.
isNot(tok::colon)) {
768 << tok::colon << LHS.getRange() << RHS.getRange();
769 PP.
Diag(OpLoc, diag::note_matching) << tok::question;
776 bool AfterColonLive = ValueLive && LHS.Val == 0;
777 PPValue AfterColonVal(LHS.getBitWidth());
779 if (
EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
785 PeekTok, AfterColonLive,
786 IncludedUndefinedIds, PP))
790 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
791 RHS.setEnd(AfterColonVal.getRange().getEnd());
795 Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
803 PP.
Diag(OpLoc, diag::err_pp_colon_without_question)
804 << LHS.getRange() << RHS.getRange();
809 if (Overflow && ValueLive)
810 PP.
Diag(OpLoc, diag::warn_pp_expr_overflow)
811 << LHS.getRange() << RHS.getRange();
815 LHS.setEnd(RHS.getRange().getEnd());
816 RHS.setIdentifier(
nullptr);
823 Preprocessor::DirectiveEvalResult
824 Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo *&IfNDefMacro) {
832 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
833 DisableMacroExpansion =
false;
840 unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
842 PPValue ResVal(BitWidth);
848 if (Tok.
isNot(tok::eod))
849 ConditionRange = DiscardUntilEndOfDirective();
852 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
859 {ExprStartLoc, ConditionRange.
getEnd()}};
865 if (Tok.
is(tok::eod)) {
872 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
881 if (Tok.
isNot(tok::eod))
882 DiscardUntilEndOfDirective();
885 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
891 if (Tok.
isNot(tok::eod)) {
892 Diag(Tok, diag::err_pp_expected_eol);
893 DiscardUntilEndOfDirective();
897 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...
SourceLocation getEnd() const
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.