clang: lib/Lex/PPExpressions.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
30#include "llvm/ADT/APSInt.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/SaveAndRestore.h"
36#include
37
38using namespace clang;
39
40namespace {
41
42
43
44class PPValue {
47
48public:
49 llvm::APSInt Val;
50
51
52 PPValue(unsigned BitWidth) : Val(BitWidth) {}
53
54
55
57 void setIdentifier(IdentifierInfo *II) { this->II = II; }
58
59 unsigned getBitWidth() const { return Val.getBitWidth(); }
60 bool isUnsigned() const { return Val.isUnsigned(); }
61
63
67 }
70};
71
72}
73
75 Token &PeekTok, bool ValueLive,
76 bool &IncludedUndefinedIds,
78
79
80
81
82
83
84
85
87
88
92 Unknown
94
95
98};
99
100
104 Result.setBegin(beginLoc);
105
106
108
109
111 if (PeekTok.is(tok::l_paren)) {
112
115 }
116
117 if (PeekTok.is(tok::code_completion)) {
122 }
123
124
126 return true;
127
128
131 Result.Val = !!Macro;
132 Result.Val.setIsUnsigned(false);
134
136 PeekTok,
137 (II->getName() == "INFINITY" || II->getName() == "NAN") ? true : false);
138
139
140 if (Result.Val != 0 && ValueLive)
142
143
144 Token macroToken(PeekTok);
145
146
147 if (LParenLoc.isValid()) {
148
151
152 if (PeekTok.isNot(tok::r_paren)) {
153 PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after)
154 << "'defined'" << tok::r_paren;
155 PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
156 return true;
157 }
158
161 } else {
162
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
186 bool IsFunctionTypeMacro =
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 if (IsFunctionTypeMacro)
207 PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);
208 else
209 PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);
210 }
211
212
214 Callbacks->Defined(macroToken, Macro,
216 }
217
218
221 return false;
222}
223
224
225
226
227
228
229
230
231
235
236 Result.setIdentifier(nullptr);
237
238 if (PeekTok.is(tok::code_completion)) {
243 }
244
245 switch (PeekTok.getKind()) {
246 default:
247
248
249
251
252 if (II->isStr("defined"))
253 return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);
254
256
257
258
259 if (ValueLive) {
260 PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
261
263
264 if (DiagEngine.isIgnored(diag::warn_pp_undef_identifier,
266 const std::vectorstd::string UndefPrefixes =
268 const StringRef IdentifierName = II->getName();
269 if (llvm::any_of(UndefPrefixes,
270 [&IdentifierName](const std::string &Prefix) {
271 return IdentifierName.starts_with(Prefix);
272 }))
273 PP.Diag(PeekTok, diag::warn_pp_undef_prefix)
274 << AddFlagValue{llvm::join(UndefPrefixes, ",")} << II;
275 }
276 }
277 Result.Val = 0;
278 Result.Val.setIsUnsigned(false);
279 Result.setIdentifier(II);
283 return false;
284 }
285 }
286 PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
287 return true;
288 case tok::eod:
289 case tok::r_paren:
290
291 PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
292 return true;
293 case tok::numeric_constant: {
295 bool NumberInvalid = false;
296 StringRef Spelling = PP.getSpelling(PeekTok, IntegerBuffer,
297 &NumberInvalid);
298 if (NumberInvalid)
299 return true;
300
304 if (Literal.hadError)
305 return true;
306
307 if (Literal.isFloatingLiteral() || Literal.isImaginary) {
308 PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
309 return true;
310 }
311 assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
312
313
314 if (Literal.hasUDSuffix())
315 PP.Diag(PeekTok, diag::err_pp_invalid_udl) << 1;
316
317
318 if (!PP.getLangOpts().C99 && Literal.isLongLong) {
320 PP.Diag(PeekTok,
322 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
323 else
324 PP.Diag(PeekTok, diag::ext_c99_longlong);
325 }
326
327
328 if (Literal.isSizeT)
331 ? diag::warn_cxx20_compat_size_t_suffix
332 : diag::ext_cxx23_size_t_suffix
333 : diag::err_cxx23_size_t_suffix);
334
335
336
337 if (Literal.isBitInt)
338 PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
340 ? diag::warn_c23_compat_bitint_suffix
341 : diag::ext_c23_bitint_suffix);
342
343
344 if (Literal.GetIntegerValue(Result.Val)) {
345
346 if (ValueLive)
347 PP.Diag(PeekTok, diag::err_integer_literal_too_large)
348 << 1;
349 Result.Val.setIsUnsigned(true);
350 } else {
351
352
353 Result.Val.setIsUnsigned(Literal.isUnsigned);
354
355
356
357
358
359 if (!Literal.isUnsigned && Result.Val.isNegative()) {
360
361
362 if (ValueLive && Literal.getRadix() == 10)
363 PP.Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
364 Result.Val.setIsUnsigned(true);
365 }
366 }
367
368
371 return false;
372 }
373 case tok::char_constant:
374 case tok::wide_char_constant:
375 case tok::utf8_char_constant:
376 case tok::utf16_char_constant:
377 case tok::utf32_char_constant: {
378
380 PP.Diag(PeekTok, diag::err_pp_invalid_udl) << 0;
381
383 bool CharInvalid = false;
384 StringRef ThisTok = PP.getSpelling(PeekTok, CharBuffer, &CharInvalid);
385 if (CharInvalid)
386 return true;
387
390 if (Literal.hadError())
391 return true;
392
393
395 unsigned NumBits;
396 if (Literal.isMultiChar())
398 else if (Literal.isWide())
400 else if (Literal.isUTF16())
402 else if (Literal.isUTF32())
404 else
406
407
408 llvm::APSInt Val(NumBits);
409
410 Val = Literal.getValue();
411
412
413 if (Literal.isWide())
415 else if (Literal.isUTF16() || Literal.isUTF32())
416 Val.setIsUnsigned(true);
417 else if (Literal.isUTF8()) {
419 Val.setIsUnsigned(
421 else
422 Val.setIsUnsigned(true);
423 } else
424 Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned);
425
426 if (Result.Val.getBitWidth() > Val.getBitWidth()) {
427 Result.Val = Val.extend(Result.Val.getBitWidth());
428 } else {
429 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
430 "intmax_t smaller than char/wchar_t?");
431 Result.Val = Val;
432 }
433
434
437 return false;
438 }
439 case tok::l_paren: {
442
443
444 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
445
446
447
448 if (PeekTok.is(tok::r_paren)) {
449
450 } else {
451
454 return true;
455
456 if (PeekTok.isNot(tok::r_paren)) {
457 PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
458 << Result.getRange();
459 PP.Diag(Start, diag::note_matching) << tok::l_paren;
460 return true;
461 }
463 }
464 Result.setRange(Start, PeekTok.getLocation());
465 Result.setIdentifier(nullptr);
467 return false;
468 }
469 case tok:➕ {
471
473 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
474 Result.setBegin(Start);
475 Result.setIdentifier(nullptr);
476 return false;
477 }
478 case tok:➖ {
481 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
482 Result.setBegin(Loc);
483 Result.setIdentifier(nullptr);
484
485
486 Result.Val = -Result.Val;
487
488
489 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
490
491
492 if (Overflow && ValueLive)
493 PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
494
496 return false;
497 }
498
499 case tok::tilde: {
502 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
503 Result.setBegin(Start);
504 Result.setIdentifier(nullptr);
505
506
507 Result.Val = ~Result.Val;
509 return false;
510 }
511
512 case tok::exclaim: {
515 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
516 Result.setBegin(Start);
517 Result.Val = !Result.Val;
518
519 Result.Val.setIsUnsigned(false);
520 Result.setIdentifier(nullptr);
521
526 return false;
527 }
528 case tok::kw_true:
529 case tok::kw_false:
530 Result.Val = PeekTok.getKind() == tok::kw_true;
531 Result.Val.setIsUnsigned(false);
535 return false;
536
537
538 }
539}
540
541
542
543
544
545
547 switch (Kind) {
548 default: return ~0U;
549 case tok::percent:
550 case tok::slash:
551 case tok:⭐ return 14;
552 case tok:➕
553 case tok:➖ return 13;
554 case tok::lessless:
555 case tok::greatergreater: return 12;
556 case tok::lessequal:
557 case tok::less:
558 case tok::greaterequal:
559 case tok::greater: return 11;
560 case tok::exclaimequal:
561 case tok::equalequal: return 10;
562 case tok::amp: return 9;
563 case tok::caret: return 8;
564 case tok::pipe: return 7;
565 case tok::ampamp: return 6;
566 case tok::pipepipe: return 5;
567 case tok::question: return 4;
568 case tok::comma: return 3;
569 case tok::colon: return 2;
570 case tok::r_paren: return 0;
571 case tok::eod: return 0;
572 }
573}
574
577 if (Tok.is(tok::l_paren) && LHS.getIdentifier())
578 PP.Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
579 << LHS.getIdentifier();
580 else
581 PP.Diag(Tok.getLocation(), diag::err_pp_expr_bad_token_binop)
582 << LHS.getRange();
583}
584
585
586
587
588
589
590
592 Token &PeekTok, bool ValueLive,
593 bool &IncludedUndefinedIds,
596
597 if (PeekPrec == ~0U) {
599 return true;
600 }
601
602 while (true) {
603
604
605 if (PeekPrec < MinPrec)
606 return false;
607
609
610
611
612
613
614
615 bool RHSIsLive;
616 if (Operator == tok::ampamp && LHS.Val == 0)
617 RHSIsLive = false;
618 else if (Operator == tok::pipepipe && LHS.Val != 0)
619 RHSIsLive = false;
620 else if (Operator == tok::question && LHS.Val == 0)
621 RHSIsLive = false;
622 else
623 RHSIsLive = ValueLive;
624
625
628
629 PPValue RHS(LHS.getBitWidth());
630
632 if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
634
635
636
637 unsigned ThisPrec = PeekPrec;
639
640
641 if (PeekPrec == ~0U) {
643 return true;
644 }
645
646
647
648
649
650
651
652
653
654
655
656 unsigned RHSPrec;
657 if (Operator == tok::question)
658
660 else
661 RHSPrec = ThisPrec+1;
662
663 if (PeekPrec >= RHSPrec) {
665 IncludedUndefinedIds, PP))
666 return true;
668 }
669 assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
670
671
672
673 llvm::APSInt Res(LHS.getBitWidth());
674 switch (Operator) {
675 case tok::question:
676 case tok::lessless:
677 case tok::greatergreater:
678 case tok::comma:
679 case tok::pipepipe:
680 case tok::ampamp:
681 break;
682 default:
683 Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());
684
685
686 if (ValueLive && Res.isUnsigned()) {
687 if (!LHS.isUnsigned() && LHS.Val.isNegative())
688 PP.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())
693 PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
694 << toString(RHS.Val, 10, true) + " to " +
696 << LHS.getRange() << RHS.getRange();
697 }
698 LHS.Val.setIsUnsigned(Res.isUnsigned());
699 RHS.Val.setIsUnsigned(Res.isUnsigned());
700 }
701
702 bool Overflow = false;
703 switch (Operator) {
704 default: llvm_unreachable("Unknown operator token!");
705 case tok::percent:
706 if (RHS.Val != 0)
707 Res = LHS.Val % RHS.Val;
708 else if (ValueLive) {
709 PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)
710 << LHS.getRange() << RHS.getRange();
711 return true;
712 }
713 break;
714 case tok::slash:
715 if (RHS.Val != 0) {
716 if (LHS.Val.isSigned())
717 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow), false);
718 else
719 Res = LHS.Val / RHS.Val;
720 } else if (ValueLive) {
721 PP.Diag(OpLoc, diag::err_pp_division_by_zero)
722 << LHS.getRange() << RHS.getRange();
723 return true;
724 }
725 break;
726
727 case tok:⭐
728 if (Res.isSigned())
729 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow), false);
730 else
731 Res = LHS.Val * RHS.Val;
732 break;
733 case tok::lessless: {
734
735 if (LHS.isUnsigned())
736 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
737 else
738 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow), false);
739 break;
740 }
741 case tok::greatergreater: {
742
743 unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
744 if (ShAmt >= LHS.getBitWidth()) {
745 Overflow = true;
746 ShAmt = LHS.getBitWidth()-1;
747 }
748 Res = LHS.Val >> ShAmt;
749 break;
750 }
751 case tok:➕
752 if (LHS.isUnsigned())
753 Res = LHS.Val + RHS.Val;
754 else
755 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow), false);
756 break;
757 case tok:➖
758 if (LHS.isUnsigned())
759 Res = LHS.Val - RHS.Val;
760 else
761 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow), false);
762 break;
763 case tok::lessequal:
764 Res = LHS.Val <= RHS.Val;
765 Res.setIsUnsigned(false);
766 break;
767 case tok::less:
768 Res = LHS.Val < RHS.Val;
769 Res.setIsUnsigned(false);
770 break;
771 case tok::greaterequal:
772 Res = LHS.Val >= RHS.Val;
773 Res.setIsUnsigned(false);
774 break;
775 case tok::greater:
776 Res = LHS.Val > RHS.Val;
777 Res.setIsUnsigned(false);
778 break;
779 case tok::exclaimequal:
780 Res = LHS.Val != RHS.Val;
781 Res.setIsUnsigned(false);
782 break;
783 case tok::equalequal:
784 Res = LHS.Val == RHS.Val;
785 Res.setIsUnsigned(false);
786 break;
787 case tok::amp:
788 Res = LHS.Val & RHS.Val;
789 break;
790 case tok::caret:
791 Res = LHS.Val ^ RHS.Val;
792 break;
793 case tok::pipe:
794 Res = LHS.Val | RHS.Val;
795 break;
796 case tok::ampamp:
797 Res = (LHS.Val != 0 && RHS.Val != 0);
798 Res.setIsUnsigned(false);
799 break;
800 case tok::pipepipe:
801 Res = (LHS.Val != 0 || RHS.Val != 0);
802 Res.setIsUnsigned(false);
803 break;
804 case tok::comma:
805
806
808 PP.Diag(OpLoc, diag::ext_pp_comma_expr)
809 << LHS.getRange() << RHS.getRange();
810 Res = RHS.Val;
811 break;
812 case tok::question: {
813
814 if (PeekTok.isNot(tok::colon)) {
816 << tok::colon << LHS.getRange() << RHS.getRange();
817 PP.Diag(OpLoc, diag::note_matching) << tok::question;
818 return true;
819 }
820
822
823
824 bool AfterColonLive = ValueLive && LHS.Val == 0;
825 PPValue AfterColonVal(LHS.getBitWidth());
827 if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
828 return true;
829
830
831
833 PeekTok, AfterColonLive,
834 IncludedUndefinedIds, PP))
835 return true;
836
837
838 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
839 RHS.setEnd(AfterColonVal.getRange().getEnd());
840
841
842
843 Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());
844
845
847 break;
848 }
849 case tok::colon:
850
851 PP.Diag(OpLoc, diag::err_pp_colon_without_question)
852 << LHS.getRange() << RHS.getRange();
853 return true;
854 }
855
856
857 if (Overflow && ValueLive)
858 PP.Diag(OpLoc, diag::warn_pp_expr_overflow)
859 << LHS.getRange() << RHS.getRange();
860
861
862 LHS.Val = Res;
863 LHS.setEnd(RHS.getRange().getEnd());
864 RHS.setIdentifier(nullptr);
865 }
866}
867
868
869
870
871Preprocessor::DirectiveEvalResult
872Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
873 Token &Tok, bool &EvaluatedDefined,
874 bool CheckForEoD) {
875 SaveAndRestore PPDir(ParsingIfOrElifDirective, true);
876
877
878
879
880
881
882 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
883 DisableMacroExpansion = false;
884
885
887
888
890
891 PPValue ResVal(BitWidth);
894 if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
895
896 SourceRange ConditionRange = ExprStartLoc;
897 if (Tok.isNot(tok::eod))
899
900
901 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
902
903
904
905
906 return {std::nullopt,
907 false,
909 {ExprStartLoc, ConditionRange.getEnd()}};
910 }
911
913
914
915
916
917 if (Tok.is(tok::eod)) {
918
919
922
923
924 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
925 bool IsNonZero = ResVal.Val != 0;
926 SourceRange ValRange = ResVal.getRange();
928 ValRange};
929 }
930
931
932
935
936 if (Tok.isNot(tok::eod))
938
939
940 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
941 SourceRange ValRange = ResVal.getRange();
943 }
944
945 if (CheckForEoD) {
946
947
948 if (Tok.isNot(tok::eod)) {
949 Diag(Tok, diag::err_pp_expected_eol);
951 }
952 }
953
955
956
957 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
958 bool IsNonZero = ResVal.Val != 0;
959 SourceRange ValRange = ResVal.getRange();
960 return {std::move(ResVal.Val), IsNonZero, DT.IncludedUndefinedIds, ValRange};
961}
962
963Preprocessor::DirectiveEvalResult
964Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
965 bool CheckForEoD) {
967 bool EvaluatedDefined;
968 return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined,
969 CheckForEoD);
970}
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