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(); }
66 Range.setBegin(B); Range.setEnd(E);
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"))
251 if (!II->isCPlusPlusOperatorKeyword()) {
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;
843 PPValue ResVal(BitWidth);
847 if (Tok.
isNot(tok::eod))
851 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
858 if (Tok.
is(tok::eod)) {
865 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
874 if (Tok.
isNot(tok::eod))
878 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
884 if (Tok.
isNot(tok::eod)) {
885 Diag(Tok, diag::err_pp_expected_eol);
890 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
SourceManager & getSourceManager() const
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
unsigned getChar16Width() const
getChar16Width/Align - Return the size of 'char16_t' for this target, in bits.
Defines the SourceManager interface.
static unsigned getPrecedence(tok::TokenKind Kind)
getPrecedence - Return the precedence of the specified binary operator token.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
Defines the clang::MacroInfo and clang::MacroDirective classes.
A description of the current definition of a macro.
void setCodeCompletionReached()
Note that we hit the code-completion point.
unsigned getChar32Width() const
getChar32Width/Align - Return the size of 'char32_t' for this target, in bits.
CodeCompletionHandler * getCodeCompletionHandler() const
Retrieve the current code-completion handler.
void setBegin(SourceLocation b)
This interface provides a way to observe the actions of the preprocessor as it does its thing...
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 ...
One of these records is kept for each identifier that is lexed.
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
const LangOptions & getLangOpts() const
Token - This structure provides full information about a lexed token.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
static bool isTypeSigned(IntType T)
Returns true if the type is signed; false otherwise.
void LexNonComment(Token &Result)
Lex a token.
tok::TokenKind getKind() const
const TargetInfo & getTargetInfo() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
unsigned getWCharWidth() const
getWCharWidth/Align - Return the size of 'wchar_t' for this target, in bits.
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.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
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 ...
bool IncludedUndefinedIds
Defines the clang::Preprocessor interface.
CharLiteralParser - Perform interpretation and semantic analysis of a character literal.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
unsigned getIntMaxTWidth() const
Return the size of intmax_t and uintmax_t for this target, in bits.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
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...
bool isNot(tok::TokenKind K) const
static StringRef getIdentifier(const Token &Tok)
IdentifierInfo * TheMacro
TheMacro - When the state is DefinedMacro or NotDefinedMacro, this indicates the macro that was check...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
enum DefinedTracker::TrackerState State
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPCallbacks * getPPCallbacks() const
Accessors for preprocessor callbacks.
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)) {...
IntType getWCharType() const
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 ...
DefinedTracker - This struct is used while parsing expressions to keep track of whether !defined(X) h...
unsigned getCharWidth() const
detail::InMemoryDirectory::const_iterator E
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target, in bits.
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.
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.
Defines the clang::TargetInfo interface.
NumericLiteralParser - This performs strict semantic analysis of the content of a ppnumber...
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
A trivial tuple used to represent a source range.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo() const