;
52PPValue(
unsignedBitWidth) : Val(BitWidth) {}
59 unsignedgetBitWidth()
const{
returnVal.getBitWidth(); }
60 bool isUnsigned()
const{
returnVal.isUnsigned(); }
75 Token&PeekTok,
boolValueLive,
76 bool&IncludedUndefinedIds,
104Result.setBegin(beginLoc);
111 if(PeekTok.
is(tok::l_paren)) {
117 if(PeekTok.
is(tok::code_completion)) {
131Result.Val = !!Macro;
132Result.Val.setIsUnsigned(
false);
137(II->
getName() ==
"INFINITY"|| II->
getName() ==
"NAN") ?
true:
false);
140 if(Result.Val != 0 && ValueLive)
144 TokenmacroToken(PeekTok);
152 if(PeekTok.
isNot(tok::r_paren)) {
154<<
"'defined'"<< tok::r_paren;
155PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
186 boolIsFunctionTypeMacro =
206 if(IsFunctionTypeMacro)
207PP.
Diag(beginLoc, diag::warn_defined_in_function_type_macro);
209PP.
Diag(beginLoc, diag::warn_defined_in_object_type_macro);
214Callbacks->Defined(macroToken, Macro,
236Result.setIdentifier(
nullptr);
238 if(PeekTok.
is(tok::code_completion)) {
252 if(II->
isStr(
"defined"))
260PP.
Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
264 if(DiagEngine.
isIgnored(diag::warn_pp_undef_identifier,
266 conststd::vector<std::string> UndefPrefixes =
268 constStringRef IdentifierName = II->
getName();
269 if(llvm::any_of(UndefPrefixes,
270[&IdentifierName](
conststd::string &Prefix) {
271 returnIdentifierName.starts_with(Prefix);
273PP.
Diag(PeekTok, diag::warn_pp_undef_prefix)
274<<
AddFlagValue{llvm::join(UndefPrefixes,
",")} << II;
278Result.Val.setIsUnsigned(
false);
279Result.setIdentifier(II);
286PP.
Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
291PP.
Diag(PeekTok, diag::err_pp_expected_value_in_expr);
293 casetok::numeric_constant: {
295 boolNumberInvalid =
false;
296StringRef Spelling = PP.
getSpelling(PeekTok, IntegerBuffer,
304 if(Literal.hadError)
307 if(Literal.isFloatingLiteral() || Literal.isImaginary) {
308PP.
Diag(PeekTok, diag::err_pp_illegal_floating_literal);
311assert(Literal.isIntegerLiteral() &&
"Unknown ppnumber");
314 if(Literal.hasUDSuffix())
315PP.
Diag(PeekTok, diag::err_pp_invalid_udl) <<
1;
318 if(!PP.
getLangOpts().C99 && Literal.isLongLong) {
322diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
324PP.
Diag(PeekTok, diag::ext_c99_longlong);
331? diag::warn_cxx20_compat_size_t_suffix
332: diag::ext_cxx23_size_t_suffix
333: diag::err_cxx23_size_t_suffix);
337 if(Literal.isBitInt)
338PP.
Diag(PeekTok, PP.
getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
340? diag::warn_c23_compat_bitint_suffix
341: diag::ext_c23_bitint_suffix);
344 if(Literal.GetIntegerValue(Result.Val)) {
347PP.
Diag(PeekTok, diag::err_integer_literal_too_large)
349Result.Val.setIsUnsigned(
true);
353Result.Val.setIsUnsigned(Literal.isUnsigned);
359 if(!Literal.isUnsigned && Result.Val.isNegative()) {
362 if(ValueLive && Literal.getRadix() == 10)
363PP.
Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
364Result.Val.setIsUnsigned(
true);
373 casetok::char_constant:
374 casetok::wide_char_constant:
375 casetok::utf8_char_constant:
376 casetok::utf16_char_constant:
377 casetok::utf32_char_constant: {
380PP.
Diag(PeekTok, diag::err_pp_invalid_udl) <<
0;
383 boolCharInvalid =
false;
384StringRef ThisTok = PP.
getSpelling(PeekTok, CharBuffer, &CharInvalid);
390 if(Literal.hadError())
396 if(Literal.isMultiChar())
398 else if(Literal.isWide())
400 else if(Literal.isUTF16())
402 else if(Literal.isUTF32())
408llvm::APSInt Val(NumBits);
410Val = Literal.getValue();
413 if(Literal.isWide())
415 else if(Literal.isUTF16() || Literal.isUTF32())
416Val.setIsUnsigned(
true);
417 else if(Literal.isUTF8()) {
422Val.setIsUnsigned(
true);
424Val.setIsUnsigned(!PP.
getLangOpts().CharIsSigned);
426 if(Result.Val.getBitWidth() > Val.getBitWidth()) {
427Result.Val = Val.extend(Result.Val.getBitWidth());
429assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
430 "intmax_t smaller than char/wchar_t?");
444 if(
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
448 if(PeekTok.
is(tok::r_paren)) {
456 if(PeekTok.
isNot(tok::r_paren)) {
458<< Result.getRange();
459PP.
Diag(Start, diag::note_matching) << tok::l_paren;
465Result.setIdentifier(
nullptr);
473 if(
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
474Result.setBegin(Start);
475Result.setIdentifier(
nullptr);
481 if(
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
482Result.setBegin(
Loc);
483Result.setIdentifier(
nullptr);
486Result.Val = -Result.Val;
489 boolOverflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
492 if(Overflow && ValueLive)
493PP.
Diag(
Loc, diag::warn_pp_expr_overflow) << Result.getRange();
502 if(
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
503Result.setBegin(Start);
504Result.setIdentifier(
nullptr);
507Result.Val = ~Result.Val;
515 if(
EvaluateValue(Result, PeekTok, DT, ValueLive, PP))
return true;
516Result.setBegin(Start);
517Result.Val = !Result.Val;
519Result.Val.setIsUnsigned(
false);
520Result.setIdentifier(
nullptr);
530Result.Val = PeekTok.
getKind() == tok::kw_true;
531Result.Val.setIsUnsigned(
false);
548 default:
return~0
U;
551 casetok::star:
return14;
553 casetok::minus:
return13;
555 casetok::greatergreater:
return12;
558 casetok::greaterequal:
559 casetok::greater:
return11;
560 casetok::exclaimequal:
561 casetok::equalequal:
return10;
562 casetok::amp:
return9;
563 casetok::caret:
return8;
564 casetok::pipe:
return7;
565 casetok::ampamp:
return6;
566 casetok::pipepipe:
return5;
567 casetok::question:
return4;
568 casetok::comma:
return3;
569 casetok::colon:
return2;
570 casetok::r_paren:
return0;
571 casetok::eod:
return0;
577 if(Tok.
is(tok::l_paren) && LHS.getIdentifier())
578PP.
Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
579<< LHS.getIdentifier();
592 Token&PeekTok,
boolValueLive,
593 bool&IncludedUndefinedIds,
597 if(PeekPrec == ~0
U) {
605 if(PeekPrec < MinPrec)
616 if(Operator == tok::ampamp && LHS.Val == 0)
618 else if(Operator == tok::pipepipe && LHS.Val != 0)
620 else if(Operator == tok::question && LHS.Val == 0)
623RHSIsLive = ValueLive;
629PPValue RHS(LHS.getBitWidth());
632 if(
EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP))
return true;
637 unsignedThisPrec = PeekPrec;
641 if(PeekPrec == ~0
U) {
657 if(Operator == tok::question)
661RHSPrec = ThisPrec+1;
663 if(PeekPrec >= RHSPrec) {
665IncludedUndefinedIds, PP))
669assert(PeekPrec <= ThisPrec &&
"Recursion didn't work!");
673llvm::APSInt Res(LHS.getBitWidth());
677 casetok::greatergreater:
683Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());
686 if(ValueLive && Res.isUnsigned()) {
687 if(!LHS.isUnsigned() && LHS.Val.isNegative())
688PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
689<<
toString(LHS.Val, 10,
true) +
" to "+
691<< LHS.getRange() << RHS.getRange();
692 if(!RHS.isUnsigned() && RHS.Val.isNegative())
693PP.
Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
694<<
toString(RHS.Val, 10,
true) +
" to "+
696<< LHS.getRange() << RHS.getRange();
698LHS.Val.setIsUnsigned(Res.isUnsigned());
699RHS.Val.setIsUnsigned(Res.isUnsigned());
702 boolOverflow =
false;
704 default: llvm_unreachable(
"Unknown operator token!");
707Res = LHS.Val % RHS.Val;
708 else if(ValueLive) {
709PP.
Diag(OpLoc, diag::err_pp_remainder_by_zero)
710<< LHS.getRange() << RHS.getRange();
716 if(LHS.Val.isSigned())
717Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow),
false);
719Res = LHS.Val / RHS.Val;
720}
else if(ValueLive) {
721PP.
Diag(OpLoc, diag::err_pp_division_by_zero)
722<< LHS.getRange() << RHS.getRange();
729Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow),
false);
731Res = LHS.Val * RHS.Val;
733 casetok::lessless: {
735 if(LHS.isUnsigned())
736Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
738Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow),
false);
741 casetok::greatergreater: {
743 unsignedShAmt =
static_cast<unsigned>(RHS.Val.getLimitedValue());
744 if(ShAmt >= LHS.getBitWidth()) {
746ShAmt = LHS.getBitWidth()-1;
748Res = LHS.Val >> ShAmt;
752 if(LHS.isUnsigned())
753Res = LHS.Val + RHS.Val;
755Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow),
false);
758 if(LHS.isUnsigned())
759Res = LHS.Val - RHS.Val;
761Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow),
false);
764Res = LHS.Val <= RHS.Val;
765Res.setIsUnsigned(
false);
768Res = LHS.Val < RHS.Val;
769Res.setIsUnsigned(
false);
771 casetok::greaterequal:
772Res = LHS.Val >= RHS.Val;
773Res.setIsUnsigned(
false);
776Res = LHS.Val > RHS.Val;
777Res.setIsUnsigned(
false);
779 casetok::exclaimequal:
780Res = LHS.Val != RHS.Val;
781Res.setIsUnsigned(
false);
783 casetok::equalequal:
784Res = LHS.Val == RHS.Val;
785Res.setIsUnsigned(
false);
788Res = LHS.Val & RHS.Val;
791Res = LHS.Val ^ RHS.Val;
794Res = LHS.Val | RHS.Val;
797Res = (LHS.Val != 0 && RHS.Val != 0);
798Res.setIsUnsigned(
false);
801Res = (LHS.Val != 0 || RHS.Val != 0);
802Res.setIsUnsigned(
false);
808PP.
Diag(OpLoc, diag::ext_pp_comma_expr)
809<< LHS.getRange() << RHS.getRange();
812 casetok::question: {
814 if(PeekTok.
isNot(tok::colon)) {
816<< tok::colon << LHS.getRange() << RHS.getRange();
817PP.
Diag(OpLoc, diag::note_matching) << tok::question;
824 boolAfterColonLive = ValueLive && LHS.Val == 0;
825PPValue AfterColonVal(LHS.getBitWidth());
827 if(
EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
833PeekTok, AfterColonLive,
834IncludedUndefinedIds, PP))
838Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
839RHS.setEnd(AfterColonVal.getRange().getEnd());
843Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());
851PP.
Diag(OpLoc, diag::err_pp_colon_without_question)
852<< LHS.getRange() << RHS.getRange();
857 if(Overflow && ValueLive)
858PP.
Diag(OpLoc, diag::warn_pp_expr_overflow)
859<< LHS.getRange() << RHS.getRange();
863LHS.setEnd(RHS.getRange().getEnd());
864RHS.setIdentifier(
nullptr);
871Preprocessor::DirectiveEvalResult
872Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo*&IfNDefMacro,
873 Token&Tok,
bool&EvaluatedDefined,
882 boolDisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
883DisableMacroExpansion =
false;
891PPValue ResVal(BitWidth);
897 if(Tok.
isNot(tok::eod))
901DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
906 return{std::nullopt,
909{ExprStartLoc, ConditionRange.
getEnd()}};
917 if(Tok.
is(tok::eod)) {
924DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
925 boolIsNonZero = ResVal.Val != 0;
936 if(Tok.
isNot(tok::eod))
940DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
948 if(Tok.
isNot(tok::eod)) {
949 Diag(Tok, diag::err_pp_expected_eol);
957DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
958 boolIsNonZero = ResVal.Val != 0;
963Preprocessor::DirectiveEvalResult
964Preprocessor::EvaluateDirectiveExpression(
IdentifierInfo*&IfNDefMacro,
967 boolEvaluatedDefined;
968 returnEvaluateDirectiveExpression(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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4