clang: lib/Lex/TokenLexer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
27#include "llvm/ADT/ArrayRef.h"
28#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/SmallVector.h"
30#include "llvm/ADT/iterator_range.h"
31#include
32#include
33#include
34
35using namespace clang;
36
37
38
41
42
43 destroy();
44
45 Macro = MI;
46 ActualArgs = Actuals;
47 CurTokenIdx = 0;
48
50 ExpandLocEnd = ELEnd;
53 NextTokGetsSpace = false;
55 OwnsTokens = false;
56 DisableMacroExpansion = false;
57 IsReinject = false;
60
62 MacroStartSLocOffset = SM.getNextLocalOffset();
63
64 if (NumTokens > 0) {
65 assert(Tokens[0].getLocation().isValid());
66 assert((Tokens[0].getLocation().isFileID() || Tokens[0].is(tok::comment)) &&
67 "Macro defined in macro?");
68 assert(ExpandLocStart.isValid());
69
70
71
72
73
74 MacroDefStart = SM.getExpansionLoc(Tokens[0].getLocation());
76 MacroExpansionStart = SM.createExpansionLoc(MacroDefStart,
77 ExpandLocStart,
78 ExpandLocEnd,
79 MacroDefLength);
80 }
81
82
83
85 ExpandFunctionArguments();
86
87
88
89
91}
92
93
94
96 bool disableMacroExpansion, bool ownsTokens,
97 bool isReinject) {
98 assert(!isReinject || disableMacroExpansion);
99
100
101 destroy();
102
103 Macro = nullptr;
104 ActualArgs = nullptr;
105 Tokens = TokArray;
106 OwnsTokens = ownsTokens;
107 DisableMacroExpansion = disableMacroExpansion;
108 IsReinject = isReinject;
109 NumTokens = NumToks;
110 CurTokenIdx = 0;
112 AtStartOfLine = false;
113 HasLeadingSpace = false;
114 NextTokGetsSpace = false;
116
117
118
119 if (NumToks != 0) {
122 }
123}
124
125void TokenLexer::destroy() {
126
127
128 if (OwnsTokens) {
129 delete [] Tokens;
130 Tokens = nullptr;
131 OwnsTokens = false;
132 }
133
134
135 if (ActualArgs) ActualArgs->destroy(PP);
136}
137
138bool TokenLexer::MaybeRemoveCommaBeforeVaArgs(
141
142 if (->isVariadic() || MacroArgNo != Macro->getNumParams()-1)
143 return false;
144
145
146
147
148 if (!HasPasteOperator && !PP.getLangOpts().MSVCCompat)
149 return false;
150
151
152
153
154
155
157 && Macro->getNumParams() < 2)
158 return false;
159
160
161 if (ResultToks.empty() || !ResultToks.back().is(tok::comma))
162 return false;
163
164
165 if (HasPasteOperator)
166 PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
167
168
169 ResultToks.pop_back();
170
171 if (!ResultToks.empty()) {
172
173
174
175
176 if (ResultToks.back().is(tok::hashhash))
177 ResultToks.pop_back();
178
179
181 }
182
183
184 NextTokGetsSpace = false;
185 return true;
186}
187
188void TokenLexer::stringifyVAOPTContents(
192 const unsigned int NumVAOptTokens = ResultToks.size() - NumToksPriorToVAOpt;
193 Token *const VAOPTTokens =
194 NumVAOptTokens ? &ResultToks[NumToksPriorToVAOpt] : nullptr;
195
197
198
199
200
201 for (unsigned int CurTokenIdx = 0; CurTokenIdx != NumVAOptTokens;
202 ++CurTokenIdx) {
203 if (VAOPTTokens[CurTokenIdx].is(tok::hashhash)) {
204 assert(CurTokenIdx != 0 &&
205 "Can not have __VAOPT__ contents begin with a ##");
206 Token &LHS = VAOPTTokens[CurTokenIdx - 1];
207 pasteTokens(LHS, llvm::ArrayRef(VAOPTTokens, NumVAOptTokens),
208 CurTokenIdx);
209
210 ConcatenatedVAOPTResultToks.back() = LHS;
211 if (CurTokenIdx == NumVAOptTokens)
212 break;
213 }
214 ConcatenatedVAOPTResultToks.push_back(VAOPTTokens[CurTokenIdx]);
215 }
216
217 ConcatenatedVAOPTResultToks.push_back(VCtx.getEOFTok());
218
219
220
221
222
224 getExpansionLocForMacroDefLoc(VCtx.getVAOptLoc());
226 getExpansionLocForMacroDefLoc(VAOPTClosingParenLoc);
227
229 &ConcatenatedVAOPTResultToks[0], PP, VCtx.hasCharifyBefore() ,
230 ExpansionLocStartWithinMacro, ExpansionLocEndWithinMacro);
231
234
236
237 ResultToks.resize(NumToksPriorToVAOpt + 1);
238 ResultToks.back() = StringifiedVAOPT;
239}
240
241
242
243void TokenLexer::ExpandFunctionArguments() {
245
246
247
248
249 bool MadeChange = false;
250
251 std::optional CalledWithVariadicArguments;
252
254
255 for (unsigned I = 0, E = NumTokens; I != E; ++I) {
256 const Token &CurTok = Tokens[I];
257
258
259
260
261
262
263 if (I != 0 && !Tokens[I-1].is(tok::hashhash) && CurTok.hasLeadingSpace())
264 NextTokGetsSpace = true;
265
267 MadeChange = true;
268 assert(Tokens[I + 1].is(tok::l_paren) &&
269 "__VA_OPT__ must be followed by '('");
270
271 ++I;
273 ResultToks.size());
274
275 continue;
276 }
277
278
279
281
282
283
284
285
286
287
288
289
290
291 if (Tokens[I].is(tok::l_paren))
293
294
295
296
297 if (!Tokens[I].is(tok::r_paren) || !VCtx.sawClosingParen()) {
298
299 if (!CalledWithVariadicArguments) {
300 CalledWithVariadicArguments =
302 }
303 if (!*CalledWithVariadicArguments) {
304
305 continue;
306 }
307
308
309 } else {
310
311
312
313
314
315
316
318
319
320
321
322
323 stringifyVAOPTContents(ResultToks, VCtx,
324 Tokens[I].getLocation());
325
326 } else if (
328
329
330
331
332
333 if (ResultToks.size() && ResultToks.back().is(tok::hashhash)) {
334 ResultToks.pop_back();
335 } else if ((I + 1 != E) && Tokens[I + 1].is(tok::hashhash)) {
336 ++I;
337 }
338 } else {
339
340
341
342
347 tok::hashhash) &&
348 "no token paste before __VA_OPT__");
349 ResultToks.erase(ResultToks.begin() +
351 }
352
353
355 Tokens[I + 1].is(tok::hashhash)) {
356 ++I;
357 }
358 }
360
361
362 continue;
363 }
364 }
365
366
367
368
369
370 if (CurTok.isOneOf(tok::hash, tok::hashat)) {
371 int ArgNo = Macro->getParameterNum(Tokens[I+1].getIdentifierInfo());
372 assert((ArgNo != -1 || VCtx.isVAOptToken(Tokens[I + 1])) &&
373 "Token following # is not an argument or __VA_OPT__!");
374
375 if (ArgNo == -1) {
376
378 CurTok.is(tok::hashat));
379 continue;
380 }
381
383 getExpansionLocForMacroDefLoc(CurTok.getLocation());
385 getExpansionLocForMacroDefLoc(Tokens[I+1].getLocation());
386
387 bool Charify = CurTok.is(tok::hashat);
390 UnexpArg, PP, Charify, ExpansionLocStart, ExpansionLocEnd);
392
393
394
395 if (NextTokGetsSpace)
397
398 ResultToks.push_back(Res);
399 MadeChange = true;
400 ++I;
401 NextTokGetsSpace = false;
402 continue;
403 }
404
405
406 bool NonEmptyPasteBefore =
407 !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
408 bool PasteBefore = I != 0 && Tokens[I-1].is(tok::hashhash);
409 bool PasteAfter = I+1 != E && Tokens[I+1].is(tok::hashhash);
410 bool RParenAfter = I+1 != E && Tokens[I+1].is(tok::r_paren);
411
412 assert((!NonEmptyPasteBefore || PasteBefore || VCtx.isInVAOpt()) &&
413 "unexpected ## in ResultToks");
414
415
416
418 int ArgNo = II ? Macro->getParameterNum(II) : -1;
419 if (ArgNo == -1) {
420
421 ResultToks.push_back(CurTok);
422
423 if (NextTokGetsSpace) {
425 NextTokGetsSpace = false;
426 } else if (PasteBefore && !NonEmptyPasteBefore)
428
429 continue;
430 }
431
432
433
434 MadeChange = true;
435
436
437
438
439
441 MaybeRemoveCommaBeforeVaArgs(ResultToks,
442 false,
443 Macro, ArgNo, PP))
444 continue;
445
446
447
448
449 if (!PasteBefore && !PasteAfter) {
450 const Token *ResultArgToks;
451
452
453
457 else
458 ResultArgToks = ArgTok;
459
460
461 if (ResultArgToks->isNot(tok::eof)) {
462 size_t FirstResult = ResultToks.size();
464 ResultToks.append(ResultArgToks, ResultArgToks+NumToks);
465
466
467
468
469
470 if (PP.getLangOpts().MSVCCompat && NumToks == 1 &&
471 ResultToks.back().is(tok::comma))
473
474
475
476 for (Token &Tok : llvm::drop_begin(ResultToks, FirstResult))
477 if (Tok.is(tok::hashhash))
478 Tok.setKind(tok::unknown);
479
480 if(ExpandLocStart.isValid()) {
481 updateLocForMacroArgTokens(CurTok.getLocation(),
482 ResultToks.begin()+FirstResult,
483 ResultToks.end());
484 }
485
486
487
488
490 NextTokGetsSpace);
492 NextTokGetsSpace = false;
493 } else {
494
495
496
497 if (NonEmptyPasteBefore) {
498
499
500 assert(VCtx.isInVAOpt() && "should only happen inside a __VA_OPT__");
502 } else if (RParenAfter)
504 }
505 continue;
506 }
507
508
509
512 if (NumToks) {
513 bool VaArgsPseudoPaste = false;
514
515
516
517
518 if (NonEmptyPasteBefore && ResultToks.size() >= 2 &&
519 ResultToks[ResultToks.size()-2].is(tok::comma) &&
520 (unsigned)ArgNo == Macro->getNumParams()-1 &&
521 Macro->isVariadic()) {
522 VaArgsPseudoPaste = true;
523
524 PP.Diag(ResultToks.pop_back_val().getLocation(), diag::ext_paste_comma);
525 }
526
527 ResultToks.append(ArgToks, ArgToks+NumToks);
528
529
530
531 for (Token &Tok : llvm::make_range(ResultToks.end() - NumToks,
532 ResultToks.end())) {
533 if (Tok.is(tok::hashhash))
534 Tok.setKind(tok::unknown);
535 }
536
537 if (ExpandLocStart.isValid()) {
538 updateLocForMacroArgTokens(CurTok.getLocation(),
539 ResultToks.end()-NumToks, ResultToks.end());
540 }
541
542
543
544
545
546 if (!VaArgsPseudoPaste) {
547 ResultToks[ResultToks.size() - NumToks].setFlagValue(Token::StartOfLine,
548 false);
549 ResultToks[ResultToks.size() - NumToks].setFlagValue(
551 }
552
553 NextTokGetsSpace = false;
554 continue;
555 }
556
557
558
559
560
561 if (PasteAfter) {
562
563
564 ++I;
565 continue;
566 }
567
568 if (RParenAfter && !NonEmptyPasteBefore)
570
571
572
573
574 assert(PasteBefore);
575 if (NonEmptyPasteBefore) {
576 assert(ResultToks.back().is(tok::hashhash));
577
578
579
580
583 ResultToks.pop_back();
584 else
586 }
587
588
589
590
591
593 MaybeRemoveCommaBeforeVaArgs(ResultToks,
594 true,
595 Macro, ArgNo, PP);
596 }
597
598
599 if (MadeChange) {
600 assert(!OwnsTokens && "This would leak if we already own the token list");
601
602 NumTokens = ResultToks.size();
603
604
605 Tokens = PP.cacheMacroExpandedTokens(this, ResultToks);
606
607
608 OwnsTokens = false;
609 }
610}
611
612
614 const Token &SecondTok) {
615 return FirstTok.is(tok::identifier) &&
618}
619
620
622
623 if (isAtEnd()) {
624
625
626 if (Macro) Macro->EnableMacro();
627
631 if (CurTokenIdx == 0)
634 }
635
637
638
639
640 bool isFirstToken = CurTokenIdx == 0;
641
642
643 Tok = Tokens[CurTokenIdx++];
644 if (IsReinject)
646
647 bool TokenIsFromPaste = false;
648
649
650
651 if (!isAtEnd() && Macro &&
652 (Tokens[CurTokenIdx].is(tok::hashhash) ||
653
654
655
658
659
660 if (pasteTokens(Tok))
661 return true;
662
663 TokenIsFromPaste = true;
664 }
665
666
667
668
669
670
671 if (ExpandLocStart.isValid() &&
672
673 SM.isBeforeInSLocAddrSpace(Tok.getLocation(), MacroStartSLocOffset)) {
675 if (Tok.is(tok::comment)) {
676 instLoc = SM.createExpansionLoc(Tok.getLocation(),
677 ExpandLocStart,
678 ExpandLocEnd,
680 } else {
681 instLoc = getExpansionLocForMacroDefLoc(Tok.getLocation());
682 }
683
685 }
686
687
688
689 if (isFirstToken) {
692 } else {
693
694
697 }
698 AtStartOfLine = false;
699 HasLeadingSpace = false;
700
701
703
704
707
708
709
710
711 if (II->isPoisoned() && TokenIsFromPaste) {
713 }
714
717 }
718
719
720 return true;
721}
722
723bool TokenLexer::pasteTokens(Token &Tok) {
724 return pasteTokens(Tok, llvm::ArrayRef(Tokens, NumTokens), CurTokenIdx);
725}
726
727
728
729
730
732 unsigned int &CurIdx) {
733 assert(CurIdx > 0 && "## can not be the first token within tokens");
734 assert((TokenStream[CurIdx].is(tok::hashhash) ||
737 "Token at this Index must be ## or part of the MSVC 'L "
738 "#macro-arg' pasting pair");
739
740
741
742
743 if (PP.getLangOpts().MicrosoftExt && (CurIdx >= 2) &&
744 TokenStream[CurIdx - 2].is(tok::hashhash))
746
748 const char *ResultTokStrPtr = nullptr;
751
752 auto IsAtEnd = [&TokenStream, &CurIdx] {
753 return TokenStream.size() == CurIdx;
754 };
755
756 do {
757
758 PasteOpLoc = TokenStream[CurIdx].getLocation();
759 if (TokenStream[CurIdx].is(tok::hashhash))
760 ++CurIdx;
761 assert(!IsAtEnd() && "No token on the RHS of a paste operator!");
762
763
764 const Token &RHS = TokenStream[CurIdx];
765
766
767
769
770
771 const char *BufPtr = &Buffer[0];
774 if (BufPtr != &Buffer[0])
775 memcpy(&Buffer[0], BufPtr, LHSLen);
777 return true;
778
779 BufPtr = Buffer.data() + LHSLen;
782 return true;
783 if (RHSLen && BufPtr != &Buffer[LHSLen])
784
785 memcpy(&Buffer[LHSLen], BufPtr, RHSLen);
786
787
788 Buffer.resize(LHSLen+RHSLen);
789
790
791
792 Token ResultTokTmp;
794
795
796
797 ResultTokTmp.setKind(tok::string_literal);
801
802
804
806
807
810 Result.setKind(tok::raw_identifier);
811 Result.setRawIdentifierData(ResultTokStrPtr);
812 Result.setLocation(ResultTokLoc);
813 Result.setLength(LHSLen+RHSLen);
814 } else {
816
817 assert(ResultTokLoc.isFileID() &&
818 "Should be a raw location into scratch buffer");
821
823 const char *ScratchBufStart
826 return false;
827
828
829
832 ResultTokStrPtr, ResultTokStrPtr+LHSLen+RHSLen);
833
834
835
836
837
839
840
841
843
844
845
846
848
849
852 SM.createExpansionLoc(PasteOpLoc, ExpandLocStart, ExpandLocEnd, 2);
853
854
855
856 if (PP.getLangOpts().MicrosoftExt && LHSTok.is(tok::slash) &&
857 RHS.is(tok::slash)) {
858 HandleMicrosoftCommentPaste(LHSTok, Loc);
859 return true;
860 }
861
862
864
865
866
867 PP.Diag(Loc, PP.getLangOpts().MicrosoftExt ? diag::ext_pp_bad_paste_ms
868 : diag::err_pp_bad_paste)
869 << Buffer;
870 }
871
872
873 break;
874 }
875
876
877
878 if (Result.is(tok::hashhash))
879 Result.setKind(tok::unknown);
880 }
881
882
885
886
887 ++CurIdx;
889 } while (!IsAtEnd() && TokenStream[CurIdx].is(tok::hashhash));
890
891 SourceLocation EndLoc = TokenStream[CurIdx - 1].getLocation();
892
893
894
895
896
897
900 StartLoc = getExpansionLocForMacroDefLoc(StartLoc);
902 EndLoc = getExpansionLocForMacroDefLoc(EndLoc);
903 FileID MacroFID = SM.getFileID(MacroExpansionStart);
904 while (SM.getFileID(StartLoc) != MacroFID)
905 StartLoc = SM.getImmediateExpansionRange(StartLoc).getBegin();
906 while (SM.getFileID(EndLoc) != MacroFID)
907 EndLoc = SM.getImmediateExpansionRange(EndLoc).getEnd();
908
911
912
913
914
915 if (LHSTok.is(tok::raw_identifier)) {
916
917
919 }
920 return false;
921}
922
923
924
925
927
928 if (isAtEnd())
929 return 2;
930 return Tokens[CurTokenIdx].is(tok::l_paren);
931}
932
933
934
936 return Tokens[NumTokens-1].is(tok::eod) && !isAtEnd();
937}
938
939
940
941
942
943
944void TokenLexer::HandleMicrosoftCommentPaste(Token &Tok, SourceLocation OpLoc) {
945 PP.Diag(OpLoc, diag::ext_comment_paste_microsoft);
946
947
948
949
950
951
952 assert(Macro && "Token streams can't paste comments");
953 Macro->EnableMacro();
954
956}
957
958
959
960
961
963TokenLexer::getExpansionLocForMacroDefLoc(SourceLocation loc) const {
964 assert(ExpandLocStart.isValid() && MacroExpansionStart.isValid() &&
965 "Not appropriate for token streams");
967
969 assert(SM.isInSLocAddrSpace(loc, MacroDefStart, MacroDefLength) &&
970 "Expected loc to come from the macro definition");
971
973 SM.isInSLocAddrSpace(loc, MacroDefStart, MacroDefLength, &relativeOffset);
975}
976
977
978
979
980
981
982
983
984
985
988 Token *&begin_tokens,
989 Token * end_tokens) {
990 assert(begin_tokens + 1 < end_tokens);
994
996
997
998
1002 return Distance <= MaxDistance;
1003 };
1004
1005
1006
1007
1009
1010
1011 Partition = All.take_while([&](const Token &T) {
1012 return T.getLocation().isFileID() && NearLast(T.getLocation());
1013 });
1014 } else {
1015
1016
1017 FileID BeginFID = SM.getFileID(BeginLoc);
1019 SM.getComposedLoc(BeginFID, SM.getFileIDSize(BeginFID));
1020 Partition = All.take_while([&](const Token &T) {
1021
1022
1023
1024
1025
1026
1027
1028
1029 return T.getLocation() >= BeginLoc && T.getLocation() <= Limit
1030 && NearLast(T.getLocation());
1031 });
1032 }
1033 assert(!Partition.empty());
1034
1035
1036
1038 Partition.back().getEndLoc().getRawEncoding() -
1039 Partition.front().getLocation().getRawEncoding();
1040
1042 SM.createMacroArgExpansionLoc(BeginLoc, ExpandLoc, FullLength);
1043
1044#ifdef EXPENSIVE_CHECKS
1045 assert(llvm::all_of(Partition.drop_front(),
1046 [&SM, ID = SM.getFileID(Partition.front().getLocation())](
1048 return ID == SM.getFileID(T.getLocation());
1049 }) &&
1050 "Must have the same FIleID!");
1051#endif
1052
1053
1054 for (Token& T : Partition) {
1056 T.getLocation().getRawEncoding() - BeginLoc.getRawEncoding();
1058 }
1059 begin_tokens = &Partition.back() + 1;
1060}
1061
1062
1063
1064
1065
1066
1067void TokenLexer::updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc,
1068 Token *begin_tokens,
1069 Token *end_tokens) {
1071
1073 getExpansionLocForMacroDefLoc(ArgIdSpellLoc);
1074
1075 while (begin_tokens < end_tokens) {
1076
1077 if (end_tokens - begin_tokens == 1) {
1078 Token &Tok = *begin_tokens;
1080 ExpandLoc,
1082 return;
1083 }
1084
1086 }
1087}
1088
1089void TokenLexer::PropagateLineStartLeadingSpaceInfo(Token &Result) {
1090 AtStartOfLine = Result.isAtStartOfLine();
1091 HasLeadingSpace = Result.hasLeadingSpace();
1092}
Defines the Diagnostic-related interfaces.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
static bool isWideStringLiteralFromMacro(const Token &FirstTok, const Token &SecondTok)
Checks if two tokens form wide string literal.
static void updateConsecutiveMacroArgTokens(SourceManager &SM, SourceLocation ExpandLoc, Token *&begin_tokens, Token *end_tokens)
Finds the tokens that are consecutive (from the same FileID) creates a single SLocEntry,...
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
One of these records is kept for each identifier that is lexed.
bool isHandleIdentifierCase() const
Return true if the Preprocessor::HandleIdentifier must be called on a token of this identifier.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool isPoisoned() const
Return true if this token has been poisoned.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
const Token * getUnexpArgument(unsigned Arg) const
getUnexpArgument - Return a pointer to the first token of the unexpanded token list for the specified...
const std::vector< Token > & getPreExpArgument(unsigned Arg, Preprocessor &PP)
getPreExpArgument - Return the pre-expanded form of the specified argument.
static unsigned getArgLength(const Token *ArgPtr)
getArgLength - Given a pointer to an expanded or unexpanded argument, return the number of tokens,...
bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const
ArgNeedsPreexpansion - If we can prove that the argument won't be affected by pre-expansion,...
bool invokedWithVariadicArgument(const MacroInfo *const MI, Preprocessor &PP)
Returns true if the macro was defined with a variadic (ellipsis) parameter AND was invoked with at le...
bool isVarargsElidedUse() const
isVarargsElidedUse - Return true if this is a C99 style varargs macro invocation and there was no arg...
static Token StringifyArgument(const Token *ArgToks, Preprocessor &PP, bool Charify, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd)
StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of tokens into the literal string...
void destroy(Preprocessor &PP)
destroy - Destroy and deallocate the memory for this object.
Encapsulates the data about a macro definition (e.g.
bool isFunctionLike() const
const_tokens_iterator tokens_begin() const
const_tokens_iterator tokens_end() const
unsigned getNumParams() const
unsigned getDefinitionLength(const SourceManager &SM) const
Get length in characters of the macro definition.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())
Plop the specified string into a scratch buffer and set the specified token's location and length to ...
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
bool HandleEndOfTokenLexer(Token &Result)
Callback invoked when the current TokenLexer hits the end of its token stream.
void HandlePoisonedIdentifier(Token &Identifier)
Display reason for poisoned identifier.
bool HandleIdentifier(Token &Identifier)
Callback invoked when the lexer reads an identifier and has filled in the tokens IdentifierInfo membe...
void IncrementPasteCounter(bool isFast)
Increment the counters for the number of token paste operations performed.
SourceManager & getSourceManager() const
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 ...
const LangOptions & getLangOpts() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void HandleMicrosoftCommentPaste(Token &Tok)
When the macro expander pastes together a comment (/##/) in Microsoft mode, this method handles updat...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
bool isParsingPreprocessorDirective() const
isParsingPreprocessorDirective - Return true if we are in the middle of a preprocessor directive.
unsigned isNextTokenLParen() const
If the next token lexed will pop this macro off the expansion stack, return 2.
bool Lex(Token &Tok)
Lex and return a token from this macro stream.
void Init(Token &Tok, SourceLocation ELEnd, MacroInfo *MI, MacroArgs *Actuals)
Initialize this TokenLexer to expand from the specified macro with the specified argument information...
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
void clearFlag(TokenFlags Flag)
Unset the specified flag.
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
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)) {....
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
bool stringifiedInMacro() const
Returns true if this token is formed by macro by stringizing or charizing operator.
void startToken()
Reset all flags to cleared.
void setFlagValue(TokenFlags Flag, bool Val)
Set a flag to either true or false.
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
void setFlag(TokenFlags Flag)
Set the specified flag.
A class for tracking whether we're inside a VA_OPT during a traversal of the tokens of a macro during...
void hasPlaceholderAfterHashhashAtStart()
bool isInVAOpt() const
Returns true if we have seen the VA_OPT and '(' but before having seen the matching ')'.
bool isVAOptToken(const Token &T) const
void sawHashOrHashAtBefore(const bool HasLeadingSpace, const bool IsHashAt)
SourceLocation getVAOptLoc() const
unsigned int getNumberOfTokensPriorToVAOpt() const
bool getLeadingSpaceForStringifiedToken() const
bool hasStringifyOrCharifyBefore() const
bool hasCharifyBefore() const
void sawOpeningParen(SourceLocation LParenLoc)
Call this function each time an lparen is seen.
void hasPlaceholderBeforeRParen()
const Token & getEOFTok() const
bool sawClosingParen()
Call this function each time an rparen is seen.
bool beginsWithPlaceholder() const
bool endsWithPlaceholder() const
void sawVAOptFollowedByOpeningParens(const SourceLocation VAOptLoc, const unsigned int NumPriorTokens)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T