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
31#include "llvm/ADT/APSInt.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/ADT/StringExtras.h"
34#include "llvm/ADT/StringRef.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/SaveAndRestore.h"
37#include
38
39using namespace clang;
40
41namespace {
42
43
44
45class PPValue {
46 SourceRange Range;
47 IdentifierInfo *II = nullptr;
48
49public:
50 llvm::APSInt Val;
51
52
53 PPValue(unsigned BitWidth) : Val(BitWidth) {}
54
55
56
57 IdentifierInfo *getIdentifier() const { return II; }
58 void setIdentifier(IdentifierInfo *II) { this->II = II; }
59
60 unsigned getBitWidth() const { return Val.getBitWidth(); }
61 bool isUnsigned() const { return Val.isUnsigned(); }
62
63 SourceRange getRange() const { return Range; }
64
65 void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }
66 void setRange(SourceLocation B, SourceLocation E) {
67 Range.setBegin(B); Range.setEnd(E);
68 }
69 void setBegin(SourceLocation L) { Range.setBegin(L); }
70 void setEnd(SourceLocation L) { Range.setEnd(L); }
71};
72
73}
74
76 Token &PeekTok, bool ValueLive,
77 bool &IncludedUndefinedIds,
79
80
81
82
83
84
85
86
100
101
105 Result.setBegin(beginLoc);
106
107
109
110
112 if (PeekTok.is(tok::l_paren)) {
113
116 }
117
118 if (PeekTok.is(tok::code_completion)) {
123 }
124
125
127 return true;
128
129
132 Result.Val = !;
133 Result.Val.setIsUnsigned(false);
135
137 PeekTok,
138 (II->getName() == "INFINITY" || II->getName() == "NAN") ? true : false);
139
140
141 if (Result.Val != 0 && ValueLive)
143
144
145 Token macroToken(PeekTok);
146
147
148 if (LParenLoc.isValid()) {
149
152
153 if (PeekTok.isNot(tok::r_paren)) {
154 PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after)
155 << "'defined'" << tok::r_paren;
156 PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
157 return true;
158 }
159
162 } else {
163
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
187 bool IsFunctionTypeMacro =
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 if (IsFunctionTypeMacro)
208 PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);
209 else
210 PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);
211 }
212
213
215 Callbacks->Defined(macroToken, Macro,
217 }
218
219
222 return false;
223}
224
225
226
227
228
229
230
231
232
236
237 Result.setIdentifier(nullptr);
238
239 if (PeekTok.is(tok::code_completion)) {
244 }
245
246 switch (PeekTok.getKind()) {
247 default:
248
249
250
252
253 if (II->isStr("defined"))
254 return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);
255
257
258
259
260 if (ValueLive) {
261 unsigned DiagID = II->getName() == "true"
262 ? diag::warn_pp_undef_true_identifier
263 : diag::warn_pp_undef_identifier;
264 PP.Diag(PeekTok, DiagID) << II;
265
267
269 const std::vectorstd::string UndefPrefixes =
271 const StringRef IdentifierName = II->getName();
272 if (llvm::any_of(UndefPrefixes,
273 [&IdentifierName](const std::string &Prefix) {
274 return IdentifierName.starts_with(Prefix);
275 }))
276 PP.Diag(PeekTok, diag::warn_pp_undef_prefix)
277 << AddFlagValue{llvm::join(UndefPrefixes, ",")} << II;
278 }
279 }
280 Result.Val = 0;
281 Result.Val.setIsUnsigned(false);
282 Result.setIdentifier(II);
286 return false;
287 }
288 }
289 PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
290 return true;
291 case tok::eod:
292 case tok::r_paren:
293
294 PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
295 return true;
296 case tok::numeric_constant: {
298 bool NumberInvalid = false;
299 StringRef Spelling = PP.getSpelling(PeekTok, IntegerBuffer,
300 &NumberInvalid);
301 if (NumberInvalid)
302 return true;
303
307 if (Literal.hadError)
308 return true;
309
310 if (Literal.isFloatingLiteral() || Literal.isImaginary) {
311 PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
312 return true;
313 }
314 assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
315
316
317 if (Literal.hasUDSuffix())
318 PP.Diag(PeekTok, diag::err_pp_invalid_udl) << 1;
319
320
321 if (!PP.getLangOpts().C99 && Literal.isLongLong) {
323 PP.Diag(PeekTok,
325 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
326 else
327 PP.Diag(PeekTok, diag::ext_c99_longlong);
328 }
329
330
331 if (Literal.isSizeT)
334 ? diag::warn_cxx20_compat_size_t_suffix
335 : diag::ext_cxx23_size_t_suffix
336 : diag::err_cxx23_size_t_suffix);
337
338
339
340 if (Literal.isBitInt)
341 PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
343 ? diag::warn_c23_compat_bitint_suffix
344 : diag::ext_c23_bitint_suffix);
345
346
347 if (Literal.GetIntegerValue(Result.Val)) {
348
349 PP.Diag(PeekTok, diag::err_integer_literal_too_large) << 1;
350 Result.Val.setIsUnsigned(true);
351 } else {
352
353
354 Result.Val.setIsUnsigned(Literal.isUnsigned);
355
356
357
358
359
360 if (!Literal.isUnsigned && Result.Val.isNegative()) {
361
362
363 if (ValueLive && Literal.getRadix() == 10)
364 PP.Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);
365 Result.Val.setIsUnsigned(true);
366 }
367 }
368
369
372 return false;
373 }
374 case tok::char_constant:
375 case tok::wide_char_constant:
376 case tok::utf8_char_constant:
377 case tok::utf16_char_constant:
378 case tok::utf32_char_constant: {
379
381 PP.Diag(PeekTok, diag::err_pp_invalid_udl) << 0;
382
384 bool CharInvalid = false;
385 StringRef ThisTok = PP.getSpelling(PeekTok, CharBuffer, &CharInvalid);
386 if (CharInvalid)
387 return true;
388
391 if (Literal.hadError())
392 return true;
393
394
396 unsigned NumBits;
397 if (Literal.isMultiChar())
399 else if (Literal.isWide())
401 else if (Literal.isUTF16())
403 else if (Literal.isUTF32())
405 else
407
408
409 llvm::APSInt Val(NumBits);
410
411 Val = Literal.getValue();
412
413
414 if (Literal.isWide())
416 else if (Literal.isUTF16() || Literal.isUTF32())
417 Val.setIsUnsigned(true);
418 else if (Literal.isUTF8()) {
420 Val.setIsUnsigned(
422 else
423 Val.setIsUnsigned(true);
424 } else
425 Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned);
426
427 if (Result.Val.getBitWidth() > Val.getBitWidth()) {
428 Result.Val = Val.extend(Result.Val.getBitWidth());
429 } else {
430 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
431 "intmax_t smaller than char/wchar_t?");
432 Result.Val = Val;
433 }
434
435
438 return false;
439 }
440 case tok::l_paren: {
443
444
445 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
446
447
448
449 if (PeekTok.is(tok::r_paren)) {
450
451 } else {
452
455 return true;
456
457 if (PeekTok.isNot(tok::r_paren)) {
458 PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
459 << Result.getRange();
460 PP.Diag(Start, diag::note_matching) << tok::l_paren;
461 return true;
462 }
464 }
465 Result.setRange(Start, PeekTok.getLocation());
466 Result.setIdentifier(nullptr);
468 return false;
469 }
470 case tok:➕ {
472
474 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
475 Result.setBegin(Start);
476 Result.setIdentifier(nullptr);
477 return false;
478 }
479 case tok:➖ {
482 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
483 Result.setBegin(Loc);
484 Result.setIdentifier(nullptr);
485
486
487 Result.Val = -Result.Val;
488
489
490 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
491
492
493 if (Overflow && ValueLive)
494 PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
495
497 return false;
498 }
499
500 case tok::tilde: {
503 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
504 Result.setBegin(Start);
505 Result.setIdentifier(nullptr);
506
507
508 Result.Val = ~Result.Val;
510 return false;
511 }
512
513 case tok::exclaim: {
516 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
517 Result.setBegin(Start);
518 Result.Val = !Result.Val;
519
520 Result.Val.setIsUnsigned(false);
521 Result.setIdentifier(nullptr);
522
527 return false;
528 }
529 case tok::kw_true:
530 case tok::kw_false:
531 Result.Val = PeekTok.getKind() == tok::kw_true;
532 Result.Val.setIsUnsigned(false);
536 return false;
537
538
539 }
540}
541
542
543
544
545
546
548 switch (Kind) {
549 default: return ~0U;
550 case tok::percent:
551 case tok::slash:
552 case tok:⭐ return 14;
553 case tok:➕
554 case tok:➖ return 13;
555 case tok::lessless:
556 case tok::greatergreater: return 12;
557 case tok::lessequal:
558 case tok::less:
559 case tok::greaterequal:
560 case tok::greater: return 11;
561 case tok::exclaimequal:
562 case tok::equalequal: return 10;
563 case tok::amp: return 9;
564 case tok::caret: return 8;
565 case tok::pipe: return 7;
566 case tok::ampamp: return 6;
567 case tok::pipepipe: return 5;
568 case tok::question: return 4;
569 case tok::comma: return 3;
570 case tok::colon: return 2;
571 case tok::r_paren: return 0;
572 case tok::eod: return 0;
573 }
574}
575
578 if (Tok.is(tok::l_paren) && LHS.getIdentifier())
579 PP.Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
580 << LHS.getIdentifier();
581 else
582 PP.Diag(Tok.getLocation(), diag::err_pp_expr_bad_token_binop)
583 << LHS.getRange();
584}
585
586
587
588
589
590
591
593 Token &PeekTok, bool ValueLive,
594 bool &IncludedUndefinedIds,
598 IncludedUndefinedIds) {
599
600
601
602
604 return true;
605 }
606
608
609 if (PeekPrec == ~0U) {
611 return true;
612 }
613
614 while (true) {
615
616
617 if (PeekPrec < MinPrec)
618 return false;
619
621
622
623
624
625
626
627 bool RHSIsLive;
628 if (Operator == tok::ampamp && LHS.Val == 0)
629 RHSIsLive = false;
630 else if (Operator == tok::pipepipe && LHS.Val != 0)
631 RHSIsLive = false;
632 else if (Operator == tok::question && LHS.Val == 0)
633 RHSIsLive = false;
634 else
635 RHSIsLive = ValueLive;
636
637
640
641 PPValue RHS(LHS.getBitWidth());
642
644 if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
646
647
648
649 unsigned ThisPrec = PeekPrec;
651
652
653 if (PeekPrec == ~0U) {
655 return true;
656 }
657
658
659
660
661
662
663
664
665
666
667
668 unsigned RHSPrec;
669 if (Operator == tok::question)
670
672 else
673 RHSPrec = ThisPrec+1;
674
675 if (PeekPrec >= RHSPrec) {
677 IncludedUndefinedIds, PP))
678 return true;
680 }
681 assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
682
683
684
685 llvm::APSInt Res(LHS.getBitWidth());
686 switch (Operator) {
687 case tok::question:
688 case tok::lessless:
689 case tok::greatergreater:
690 case tok::comma:
691 case tok::pipepipe:
692 case tok::ampamp:
693 break;
694 default:
695 Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());
696
697
698 if (ValueLive && Res.isUnsigned()) {
699 if (!LHS.isUnsigned() && LHS.Val.isNegative())
700 PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
701 << toString(LHS.Val, 10, true) + " to " +
703 << LHS.getRange() << RHS.getRange();
704 if (!RHS.isUnsigned() && RHS.Val.isNegative())
705 PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
706 << toString(RHS.Val, 10, true) + " to " +
708 << LHS.getRange() << RHS.getRange();
709 }
710 LHS.Val.setIsUnsigned(Res.isUnsigned());
711 RHS.Val.setIsUnsigned(Res.isUnsigned());
712 }
713
714 bool Overflow = false;
715 switch (Operator) {
716 default: llvm_unreachable("Unknown operator token!");
717 case tok::percent:
718 if (RHS.Val != 0)
719 Res = LHS.Val % RHS.Val;
720 else if (ValueLive) {
721 PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)
722 << LHS.getRange() << RHS.getRange();
723 return true;
724 }
725 break;
726 case tok::slash:
727 if (RHS.Val != 0) {
728 if (LHS.Val.isSigned())
729 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow), false);
730 else
731 Res = LHS.Val / RHS.Val;
732 } else if (ValueLive) {
733 PP.Diag(OpLoc, diag::err_pp_division_by_zero)
734 << LHS.getRange() << RHS.getRange();
735 return true;
736 }
737 break;
738
739 case tok:⭐
740 if (Res.isSigned())
741 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow), false);
742 else
743 Res = LHS.Val * RHS.Val;
744 break;
745 case tok::lessless: {
746
747 if (LHS.isUnsigned())
748 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);
749 else
750 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow), false);
751 break;
752 }
753 case tok::greatergreater: {
754
755 unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
756 if (ShAmt >= LHS.getBitWidth()) {
757 Overflow = true;
758 ShAmt = LHS.getBitWidth()-1;
759 }
760 Res = LHS.Val >> ShAmt;
761 break;
762 }
763 case tok:➕
764 if (LHS.isUnsigned())
765 Res = LHS.Val + RHS.Val;
766 else
767 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow), false);
768 break;
769 case tok:➖
770 if (LHS.isUnsigned())
771 Res = LHS.Val - RHS.Val;
772 else
773 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow), false);
774 break;
775 case tok::lessequal:
776 Res = LHS.Val <= RHS.Val;
777 Res.setIsUnsigned(false);
778 break;
779 case tok::less:
780 Res = LHS.Val < RHS.Val;
781 Res.setIsUnsigned(false);
782 break;
783 case tok::greaterequal:
784 Res = LHS.Val >= RHS.Val;
785 Res.setIsUnsigned(false);
786 break;
787 case tok::greater:
788 Res = LHS.Val > RHS.Val;
789 Res.setIsUnsigned(false);
790 break;
791 case tok::exclaimequal:
792 Res = LHS.Val != RHS.Val;
793 Res.setIsUnsigned(false);
794 break;
795 case tok::equalequal:
796 Res = LHS.Val == RHS.Val;
797 Res.setIsUnsigned(false);
798 break;
799 case tok::amp:
800 Res = LHS.Val & RHS.Val;
801 break;
802 case tok::caret:
803 Res = LHS.Val ^ RHS.Val;
804 break;
805 case tok::pipe:
806 Res = LHS.Val | RHS.Val;
807 break;
808 case tok::ampamp:
809 Res = (LHS.Val != 0 && RHS.Val != 0);
810 Res.setIsUnsigned(false);
811 break;
812 case tok::pipepipe:
813 Res = (LHS.Val != 0 || RHS.Val != 0);
814 Res.setIsUnsigned(false);
815 break;
816 case tok::comma:
817
818
820 PP.Diag(OpLoc, diag::ext_pp_comma_expr)
821 << LHS.getRange() << RHS.getRange();
822 Res = RHS.Val;
823 break;
824 case tok::question: {
825
826 if (PeekTok.isNot(tok::colon)) {
828 << tok::colon << LHS.getRange() << RHS.getRange();
829 PP.Diag(OpLoc, diag::note_matching) << tok::question;
830 return true;
831 }
832
834
835
836 bool AfterColonLive = ValueLive && LHS.Val == 0;
837 PPValue AfterColonVal(LHS.getBitWidth());
839 if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
840 return true;
841
842
843
845 PeekTok, AfterColonLive,
846 IncludedUndefinedIds, PP))
847 return true;
848
849
850 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
851 RHS.setEnd(AfterColonVal.getRange().getEnd());
852
853
854
855 Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());
856
857
859 break;
860 }
861 case tok::colon:
862
863 PP.Diag(OpLoc, diag::err_pp_colon_without_question)
864 << LHS.getRange() << RHS.getRange();
865 return true;
866 }
867
868
869 if (Overflow && ValueLive)
870 PP.Diag(OpLoc, diag::warn_pp_expr_overflow)
871 << LHS.getRange() << RHS.getRange();
872
873
874 LHS.Val = Res;
875 LHS.setEnd(RHS.getRange().getEnd());
876 RHS.setIdentifier(nullptr);
877 }
878}
879
880
881
882
883Preprocessor::DirectiveEvalResult
884Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
885 Token &Tok, bool &EvaluatedDefined,
886 bool CheckForEoD) {
887 SaveAndRestore PPDir(ParsingIfOrElifDirective, true);
888
889
890
891
892
893
894 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
895 DisableMacroExpansion = false;
896
897
899
900
902
903 PPValue ResVal(BitWidth);
904 DefinedTracker DT;
905 SourceLocation ExprStartLoc = SourceMgr.getExpansionLoc(Tok.getLocation());
907
910
911
912 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
913
914
915
916
917 return {std::nullopt,
918 false,
921 }
922
924
925
926
927
929
930
933
934
935 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
936 bool IsNonZero = ResVal.Val != 0;
937 SourceRange ValRange = ResVal.getRange();
939 ValRange};
940 }
941
942
943
946
949
950
951 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
952 return {std::nullopt,
953 false,
956 }
957
958 if (CheckForEoD) {
959
960
962 Diag(Tok, diag::err_pp_expected_eol);
964 }
965 }
966
968
969
970 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
971 bool IsNonZero = ResVal.Val != 0;
972 SourceRange ValRange = ResVal.getRange();
973 return {std::move(ResVal.Val), IsNonZero, DT.IncludedUndefinedIds, ValRange};
974}
975
976Preprocessor::DirectiveEvalResult
977Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
978 bool CheckForEoD) {
979 Token Tok;
980 bool EvaluatedDefined;
981 return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined,
982 CheckForEoD);
983}
984
985static std::optional
989 if ( || Macro->getNumTokens() != 1 ||
->isObjectLike())
990 return std::nullopt;
991
992 const Token &RevisionDateTok = Macro->getReplacementToken(0);
993
996 llvm::StringRef RevisionDate =
999 std::uint64_t Value;
1000
1001 if (!RevisionDate.consumeInteger(10, Value))
1003 }
1005 0};
1006}
1007
1009 if (!CXXStandardLibraryVersion)
1012 if (!CXXStandardLibraryVersion)
1013 return std::nullopt;
1014
1015 if (CXXStandardLibraryVersion->Lib ==
1017 return CXXStandardLibraryVersion->Version;
1018 return std::nullopt;
1019}
1020
1022 assert(FixedVersion >= 2000'00'00 && FixedVersion <= 2100'00'00 &&
1023 "invalid value for __GLIBCXX__");
1025 if (!Ver)
1026 return false;
1027 return *Ver < FixedVersion;
1028}
static bool isUnsigned(SValBuilder &SVB, NonLoc Value)
static uint32_t getBitWidth(const Expr *E)
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...
Definition PPExpressions.cpp:233
static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS, Token &Tok)
Definition PPExpressions.cpp:576
static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, bool &IncludedUndefinedIds, Preprocessor &PP)
EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is PeekTok,...
Definition PPExpressions.cpp:592
static std::optional< CXXStandardLibraryVersionInfo > getCXXStandardLibraryVersion(Preprocessor &PP, StringRef MacroName, CXXStandardLibraryVersionInfo::Library Lib)
Definition PPExpressions.cpp:986
static unsigned getPrecedence(tok::TokenKind Kind)
getPrecedence - Return the precedence of the specified binary operator token.
Definition PPExpressions.cpp:547
static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP)
EvaluateDefined - Process a 'defined(sym)' expression.
Definition PPExpressions.cpp:102
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.
void setBegin(SourceLocation b)
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.
Encapsulates the data about a macro definition (e.g.
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.
bool SingleFileParseMode
When enabled, preprocessor is in a mode for parsing a single file only.
bool SingleModuleParseMode
When enabled, preprocessor is in a mode for parsing a single module only.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
PPCallbacks * getPPCallbacks() const
const MacroInfo * getMacroInfo(const IdentifierInfo *II) 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.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
std::optional< std::uint64_t > getStdLibCxxVersion()
Definition PPExpressions.cpp:1008
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
bool NeedsStdLibCxxWorkaroundBefore(std::uint64_t FixedVersion)
Definition PPExpressions.cpp:1021
CodeCompletionHandler * getCodeCompletionHandler() const
Retrieve the current code-completion handler.
const PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
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.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
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 !...
Definition PPExpressions.cpp:87
TrackerState
Each time a Value is evaluated, it returns information about whether the parsed value is of the form ...
Definition PPExpressions.cpp:90
@ Unknown
Definition PPExpressions.cpp:93
@ NotDefinedMacro
Definition PPExpressions.cpp:92
@ DefinedMacro
Definition PPExpressions.cpp:91
bool IncludedUndefinedIds
Definition PPExpressions.cpp:98
IdentifierInfo * TheMacro
TheMacro - When the state is DefinedMacro or NotDefinedMacro, this indicates the macro that was check...
Definition PPExpressions.cpp:97
enum DefinedTracker::TrackerState State