20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/FormatVariadic.h"
25#include "llvm/Support/Path.h"
26#include "llvm/Support/raw_ostream.h"
87 while (
First.isMacroID() &&
Last.isMacroID()) {
93 if (!ExpFirst.isMacroArgExpansion() || !ExpLast.isMacroArgExpansion())
97 if (ExpFirst.getExpansionLocStart() != ExpLast.getExpansionLocStart())
105 auto ExpFileID = SM.
getFileID(ExpFirst.getExpansionLocStart());
106 if (ExpFileID == TargetFile)
110 First = ExpFirst.getSpellingLoc().getLocWithOffset(DecFirst.second);
111 Last = ExpLast.getSpellingLoc().getLocWithOffset(DecLast.second);
121 if (Candidate.
isInvalid() || DecFirst.first != TargetFile ||
122 DecLast.first != TargetFile)
127 if (
Dec.first != DecFirst.first ||
Dec.second >= DecFirst.second)
130 if (
Next.isValid()) {
132 if (
Dec.first != DecLast.first ||
Dec.second <= DecLast.second)
144 : Location(Location), Length(Length), Kind(Kind) {
145 assert(Location.isValid());
150 assert(!
T.isAnnotation());
157 return llvm::StringRef(Start,
length());
161 assert(
location().isFileID() &&
"must be a spelled token");
163 unsigned StartOffset;
171 auto F =
First.range(SM);
172 auto L =
Last.range(SM);
173 assert(F.file() == L.file() &&
"tokens from different files");
174 assert((F == L || F.endOffset() <= L.beginOffset()) &&
175 "wrong order of tokens");
176 return FileRange(F.file(), F.beginOffset(), L.endOffset());
180 return OS <<
T.str();
184 : File(File), Begin(BeginOffset), End(EndOffset) {
185 assert(File.isValid());
186 assert(BeginOffset <= EndOffset);
195 End = Begin + Length;
212 return OS << llvm::formatv(
"FileRange(file = {0}, offsets = {1}-{2})",
213 R.file().getHashValue(), R.beginOffset(),
222 assert(Begin <=
Text.size());
223 assert(End <=
Text.size());
229 if (!ExpandedTokIndex.empty())
231 ExpandedTokIndex.reserve(ExpandedTokens.size());
233 for (
size_t I = 0, E = ExpandedTokens.size(); I != E; ++I) {
236 ExpandedTokIndex[Loc] = I;
243 if (!ExpandedTokIndex.empty()) {
247 const auto B = ExpandedTokIndex.find(R.getBegin());
248 const auto E = ExpandedTokIndex.find(R.getEnd());
249 if (B != ExpandedTokIndex.end() && E != ExpandedTokIndex.end()) {
250 const Token *L = ExpandedTokens.data() + B->getSecond();
252 const Token *R = ExpandedTokens.data() + E->getSecond() + 1;
269std::pair<const syntax::Token *, const TokenBuffer::Mapping *>
270TokenBuffer::spelledForExpandedToken(
const syntax::Token *Expanded)
const {
272 assert(ExpandedTokens.data() <= Expanded &&
273 Expanded < ExpandedTokens.data() + ExpandedTokens.size());
275 auto FileIt = Files.find(
276 SourceMgr->getFileID(SourceMgr->getExpansionLoc(Expanded->
location())));
277 assert(FileIt != Files.end() &&
"no file for an expanded token");
279 const MarkedFile &
File = FileIt->second;
281 unsigned ExpandedIndex = Expanded - ExpandedTokens.data();
283 auto It = llvm::partition_point(
File.Mappings, [&](
const Mapping &M) {
284 return M.BeginExpanded <= ExpandedIndex;
287 if (It ==
File.Mappings.begin()) {
289 return {&
File.SpelledTokens[ExpandedIndex -
File.BeginExpanded],
295 if (ExpandedIndex < It->EndExpanded)
296 return {&
File.SpelledTokens[It->BeginSpelled], &*It};
301 &
File.SpelledTokens[It->EndSpelled + (ExpandedIndex - It->EndExpanded)],
305const TokenBuffer::Mapping *
306TokenBuffer::mappingStartingBeforeSpelled(
const MarkedFile &F,
307 const syntax::Token *Spelled) {
308 assert(F.SpelledTokens.data() <= Spelled);
309 unsigned SpelledI = Spelled - F.SpelledTokens.data();
310 assert(SpelledI < F.SpelledTokens.size());
312 auto It = llvm::partition_point(F.Mappings, [SpelledI](
const Mapping &M) {
313 return M.BeginSpelled <= SpelledI;
315 if (It == F.Mappings.begin())
321llvm::SmallVector<llvm::ArrayRef<syntax::Token>, 1>
325 const auto &
File = fileForSpelled(Spelled);
327 auto *FrontMapping = mappingStartingBeforeSpelled(
File, &Spelled.front());
328 unsigned SpelledFrontI = &Spelled.front() -
File.SpelledTokens.data();
329 assert(SpelledFrontI <
File.SpelledTokens.size());
330 unsigned ExpandedBegin;
334 ExpandedBegin =
File.BeginExpanded + SpelledFrontI;
335 }
else if (SpelledFrontI < FrontMapping->EndSpelled) {
337 if (SpelledFrontI != FrontMapping->BeginSpelled) {
342 ExpandedBegin = FrontMapping->BeginExpanded;
347 FrontMapping->EndExpanded + (SpelledFrontI - FrontMapping->EndSpelled);
350 auto *BackMapping = mappingStartingBeforeSpelled(
File, &Spelled.back());
351 unsigned SpelledBackI = &Spelled.back() -
File.SpelledTokens.data();
352 unsigned ExpandedEnd;
356 ExpandedEnd =
File.BeginExpanded + SpelledBackI + 1;
357 }
else if (SpelledBackI < BackMapping->EndSpelled) {
359 if (SpelledBackI + 1 != BackMapping->EndSpelled) {
363 ExpandedEnd = BackMapping->EndExpanded;
367 BackMapping->EndExpanded + (SpelledBackI - BackMapping->EndSpelled) + 1;
370 assert(ExpandedBegin < ExpandedTokens.size());
371 assert(ExpandedEnd < ExpandedTokens.size());
373 if (ExpandedBegin == ExpandedEnd)
376 ExpandedTokens.data() + ExpandedEnd)};
380 auto It = Files.find(FID);
381 assert(It != Files.end());
382 return It->second.SpelledTokens;
388 const auto *
Tok = llvm::partition_point(
391 if (!
Tok || Loc < Tok->location())
396std::string TokenBuffer::Mapping::str()
const {
398 llvm::formatv(
"spelled tokens: [{0},{1}), expanded tokens: [{2},{3})",
399 BeginSpelled, EndSpelled, BeginExpanded, EndExpanded));
402std::optional<llvm::ArrayRef<syntax::Token>>
407 if (!Expanded.empty() && Expanded.back().kind() == tok::eof) {
408 Expanded = Expanded.drop_back();
412 if (Expanded.empty())
416 auto [FirstSpelled, FirstMapping] = spelledForExpandedToken(
First);
417 auto [LastSpelled, LastMapping] = spelledForExpandedToken(
Last);
419 FileID FID = SourceMgr->getFileID(FirstSpelled->location());
421 if (FID != SourceMgr->getFileID(LastSpelled->location()))
424 const MarkedFile &
File = Files.find(FID)->second;
428 if (FirstMapping && FirstMapping == LastMapping &&
429 SourceMgr->isMacroArgExpansion(
First->location()) &&
430 SourceMgr->isMacroArgExpansion(
Last->location())) {
434 : (
First - 1)->location();
437 : (
Last + 1)->location();
439 First->location(),
Last->location(), Prev,
Next, FID, *SourceMgr);
440 if (Range.isInvalid())
442 return getTokensCovering(
File.SpelledTokens, Range, *SourceMgr);
447 unsigned FirstExpanded = Expanded.begin() - ExpandedTokens.data();
448 unsigned LastExpanded = Expanded.end() - ExpandedTokens.data();
449 if (FirstMapping && FirstExpanded != FirstMapping->BeginExpanded)
451 if (LastMapping && LastMapping->EndExpanded != LastExpanded)
454 FirstMapping ?
File.SpelledTokens.data() + FirstMapping->BeginSpelled
456 LastMapping ?
File.SpelledTokens.data() + LastMapping->EndSpelled
461 const Mapping &M)
const {
464 F.SpelledTokens.data() + M.EndSpelled);
465 E.Expanded =
llvm::ArrayRef(ExpandedTokens.data() + M.BeginExpanded,
466 ExpandedTokens.data() + M.EndExpanded);
470const TokenBuffer::MarkedFile &
472 assert(!Spelled.empty());
473 assert(Spelled.front().location().isFileID() &&
"not a spelled token");
474 auto FileIt = Files.find(SourceMgr->getFileID(Spelled.front().location()));
475 assert(FileIt != Files.end() &&
"file not tracked by token buffer");
476 const auto &
File = FileIt->second;
477 assert(
File.SpelledTokens.data() <= Spelled.data() &&
479 (
File.SpelledTokens.data() +
File.SpelledTokens.size()) &&
480 "Tokens not in spelled range");
482 auto T1 = Spelled.back().location();
483 auto T2 =
File.SpelledTokens.back().location();
484 assert(T1 == T2 ||
sourceManager().isBeforeInTranslationUnit(T1, T2));
489std::optional<TokenBuffer::Expansion>
492 const auto &
File = fileForSpelled(*Spelled);
494 unsigned SpelledIndex = Spelled -
File.SpelledTokens.data();
495 auto M = llvm::partition_point(
File.Mappings, [&](
const Mapping &M) {
496 return M.BeginSpelled < SpelledIndex;
498 if (M ==
File.Mappings.end() || M->BeginSpelled != SpelledIndex)
500 return makeExpansion(
File, *M);
507 const auto &
File = fileForSpelled(Spelled);
510 unsigned SpelledBeginIndex = Spelled.begin() -
File.SpelledTokens.data();
511 unsigned SpelledEndIndex = Spelled.end() -
File.SpelledTokens.data();
512 auto M = llvm::partition_point(
File.Mappings, [&](
const Mapping &M) {
513 return M.EndSpelled <= SpelledBeginIndex;
515 std::vector<TokenBuffer::Expansion> Expansions;
516 for (; M !=
File.Mappings.end() && M->BeginSpelled < SpelledEndIndex; ++M)
517 Expansions.push_back(makeExpansion(
File, *M));
526 auto *Right = llvm::partition_point(
528 bool AcceptRight = Right != Tokens.end() && Right->location() <= Loc;
530 Right != Tokens.begin() && (Right - 1)->endLocation() >= Loc;
532 Right + (AcceptRight ? 1 : 0));
546 if (
Tok.kind() == tok::identifier)
559std::vector<const syntax::Token *>
561 auto FileIt = Files.find(FID);
562 assert(FileIt != Files.end() &&
"file not tracked by token buffer");
563 auto &
File = FileIt->second;
564 std::vector<const syntax::Token *> Expansions;
565 auto &Spelled =
File.SpelledTokens;
566 for (
auto Mapping :
File.Mappings) {
568 if (
Token->
kind() == tok::TokenKind::identifier)
569 Expansions.push_back(
Token);
577 std::vector<syntax::Token> Tokens;
581 if (
T.getKind() == tok::raw_identifier && !
T.needsCleaning() &&
584 T.setIdentifierInfo(&II);
595 SrcBuffer.data() + SrcBuffer.size());
627 const auto &SM = Collector->PP.getSourceManager();
642 if (!Range.getEnd().isFileID())
646 if (LastExpansionEnd.isValid() &&
653 if (!Range.getBegin().isFileID()) {
655 assert(Collector->Expansions.count(Range.getBegin()) &&
656 "Overlapping macros should have same expansion location");
659 Collector->Expansions[Range.getBegin()] = Range.getEnd();
660 LastExpansionEnd = Range.getEnd();
664 TokenCollector *Collector;
685 if (
T.is(tok::annot_module_name)) {
689 this->PP.getLangOpts());
696 if (
T.isAnnotation() ||
T.is(tok::eod))
700 DEBUG_WITH_TYPE(
"collect-tokens", llvm::dbgs()
710 auto CB = std::make_unique<CollectPPExpansions>(*
this);
711 this->Collector = CB.get();
712 PP.addPPCallbacks(std::move(CB));
719 Builder(std::vector<syntax::Token> Expanded, PPExpansions CollectedExpansions,
721 : Result(SM), CollectedExpansions(
std::move(CollectedExpansions)), SM(SM),
723 Result.ExpandedTokens = std::move(Expanded);
727 assert(!Result.ExpandedTokens.empty());
733 if (Result.ExpandedTokens.back().kind() != tok::eof) {
735 Result.ExpandedTokens.emplace_back(Loc, 0, tok::eof);
739 buildSpelledTokens();
745 while (NextExpanded < Result.ExpandedTokens.size() - 1 ) {
751 unsigned OldPosition = NextExpanded;
753 if (NextExpanded == OldPosition)
754 diagnoseAdvanceFailure();
758 for (
const auto &
File : Result.Files)
762 for (
auto &pair : Result.Files) {
763 auto &mappings = pair.second.Mappings;
764 assert(llvm::is_sorted(mappings, [](
const TokenBuffer::Mapping &M1,
765 const TokenBuffer::Mapping &M2) {
766 return M1.BeginSpelled < M2.BeginSpelled &&
767 M1.EndSpelled < M2.EndSpelled &&
768 M1.BeginExpanded < M2.BeginExpanded &&
769 M1.EndExpanded < M2.EndExpanded;
774 return std::move(Result);
782 void discard(std::optional<FileID> Drain = std::nullopt) {
786 Result.ExpandedTokens[NextExpanded].location());
788 const auto &SpelledTokens =
Result.Files[
File].SpelledTokens;
789 auto &NextSpelled = this->NextSpelled[
File];
791 TokenBuffer::Mapping Mapping;
792 Mapping.BeginSpelled = NextSpelled;
795 Mapping.BeginExpanded = Mapping.EndExpanded =
796 Drain ?
Result.Files[*Drain].EndExpanded : NextExpanded;
799 auto FlushMapping = [&,
this] {
800 Mapping.EndSpelled = NextSpelled;
801 if (Mapping.BeginSpelled != Mapping.EndSpelled)
802 Result.Files[
File].Mappings.push_back(Mapping);
803 Mapping.BeginSpelled = NextSpelled;
806 while (NextSpelled < SpelledTokens.size() &&
807 SpelledTokens[NextSpelled].location() <
Target) {
812 CollectedExpansions.lookup(SpelledTokens[NextSpelled].location());
815 while (NextSpelled < SpelledTokens.size() &&
816 SpelledTokens[NextSpelled].location() <= KnownEnd)
831 const syntax::Token &
Tok =
Result.ExpandedTokens[NextExpanded];
834 const auto &SpelledTokens =
Result.Files[
File].SpelledTokens;
835 auto &NextSpelled = this->NextSpelled[
File];
837 if (
Tok.location().isFileID()) {
839 while (NextSpelled < SpelledTokens.size() &&
840 NextExpanded <
Result.ExpandedTokens.size() &&
841 SpelledTokens[NextSpelled].location() ==
842 Result.ExpandedTokens[NextExpanded].location()) {
849 auto End = CollectedExpansions.lookup(Expansion);
850 assert(End.isValid() &&
"Macro expansion wasn't captured?");
853 TokenBuffer::Mapping Mapping;
854 Mapping.BeginExpanded = NextExpanded;
855 Mapping.BeginSpelled = NextSpelled;
857 while (NextSpelled < SpelledTokens.size() &&
858 SpelledTokens[NextSpelled].location() <= End)
861 while (NextExpanded <
Result.ExpandedTokens.size() &&
863 Result.ExpandedTokens[NextExpanded].location()) == Expansion)
866 Mapping.EndExpanded = NextExpanded;
867 Mapping.EndSpelled = NextSpelled;
868 Result.Files[
File].Mappings.push_back(Mapping);
873 void diagnoseAdvanceFailure() {
876 for (
unsigned I = (NextExpanded < 10) ? 0 : NextExpanded - 10;
877 I < NextExpanded + 5 && I <
Result.ExpandedTokens.size(); ++I) {
879 (I == NextExpanded) ?
"!! " : (I < NextExpanded) ?
"ok " :
" ";
880 llvm::errs() << L <<
Result.ExpandedTokens[I].dumpForTests(SM) <<
"\n";
883 llvm_unreachable(
"Couldn't map expanded token to spelled tokens!");
888 void buildSpelledTokens() {
889 for (
unsigned I = 0; I <
Result.ExpandedTokens.size(); ++I) {
890 const auto &
Tok =
Result.ExpandedTokens[I];
892 auto It =
Result.Files.try_emplace(FID);
893 TokenBuffer::MarkedFile &
File = It.first->second;
896 File.EndExpanded =
Tok.kind() == tok::eof ? I : I + 1;
901 File.BeginExpanded = I;
907 unsigned NextExpanded = 0;
908 llvm::DenseMap<FileID, unsigned> NextSpelled;
909 PPExpansions CollectedExpansions;
910 const SourceManager &SM;
911 const LangOptions &LangOpts;
915 PP.setTokenWatcher(
nullptr);
916 Collector->disable();
917 return Builder(std::move(Expanded), std::move(Expansions),
918 PP.getSourceManager(), PP.getLangOpts())
923 return std::string(llvm::formatv(
"Token({0}, length = {1})",
928 return std::string(llvm::formatv(
"Token(`{0}`, {1}, length = {2})",
text(SM),
934 if (
T.kind() == tok::eof)
936 return std::string(
T.text(*SourceMgr));
939 auto DumpTokens = [
this, &PrintToken](llvm::raw_ostream &OS,
941 if (Tokens.empty()) {
945 OS << Tokens[0].text(*SourceMgr);
946 for (
unsigned I = 1; I < Tokens.size(); ++I) {
947 if (Tokens[I].
kind() == tok::eof)
949 OS <<
" " << PrintToken(Tokens[I]);
954 llvm::raw_string_ostream OS(Dump);
956 OS <<
"expanded tokens:\n"
962 std::vector<FileID> Keys;
963 for (
const auto &F : Files)
964 Keys.push_back(F.first);
968 const MarkedFile &
File = Files.find(ID)->second;
969 auto Entry = SourceMgr->getFileEntryRefForID(ID);
972 std::string Path = llvm::sys::path::convert_to_slash(Entry->getName());
973 OS << llvm::formatv(
"file '{0}'\n", Path) <<
" spelled tokens:\n"
975 DumpTokens(OS,
File.SpelledTokens);
978 if (
File.Mappings.empty()) {
979 OS <<
" no mappings.\n";
982 OS <<
" mappings:\n";
983 for (
auto &M :
File.Mappings) {
985 " ['{0}'_{1}, '{2}'_{3}) => ['{4}'_{5}, '{6}'_{7})\n",
986 PrintToken(
File.SpelledTokens[M.BeginSpelled]), M.BeginSpelled,
987 M.EndSpelled ==
File.SpelledTokens.size()
989 : PrintToken(
File.SpelledTokens[M.EndSpelled]),
990 M.EndSpelled, PrintToken(ExpandedTokens[M.BeginExpanded]),
991 M.BeginExpanded, PrintToken(ExpandedTokens[M.EndExpanded]),
Defines the Diagnostic-related interfaces.
static Decl::Kind getKind(const Decl *D)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the PPCallbacks interface.
static ParseState advance(ParseState S, size_t N)
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
Builds mappings and spelled tokens in the TokenBuffer based on the expanded token stream.
Builder(std::vector< syntax::Token > Expanded, PPExpansions CollectedExpansions, const SourceManager &SM, const LangOptions &LangOpts)
Records information reqired to construct mappings for the token buffer that we are collecting.
CollectPPExpansions(TokenCollector &C)
void disable()
Disabled instance will stop reporting anything to TokenCollector.
void MacroExpands(const clang::Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override
Called by Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is found.
Represents a byte-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getEnd() const
SourceLocation getBegin() const
SourceRange getAsRange() const
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.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
Implements an efficient mapping from strings to IdentifierInfo nodes.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
unsigned getCurrentBufferOffset()
Returns the current lexing offset.
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
A description of the current definition of a macro.
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.
SourceManager & getSourceManager() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
FileIDAndOffset getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
FileIDAndOffset getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
unsigned getFileOffset(SourceLocation SpellingLoc) const
Returns the offset from the start of the file that the specified SourceLocation represents.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
SourceLocation getComposedLoc(FileID FID, unsigned Offset) const
Form a SourceLocation from a FileID and Offset pair.
SourceLocation getLocForEndOfFile(FileID FID) const
Return the source location corresponding to the last byte of the specified file.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
const ExpansionInfo & getExpansion() const
Token - This structure provides full information about a lexed token.
A list of tokens obtained by preprocessing a text buffer and operations to map between the expanded a...
const syntax::Token * spelledTokenContaining(SourceLocation Loc) const
Returns the spelled Token containing the Loc, if there are no such tokens returns nullptr.
const SourceManager & sourceManager() const
void indexExpandedTokens()
Builds a cache to make future calls to expandedToken(SourceRange) faster.
llvm::SmallVector< llvm::ArrayRef< syntax::Token >, 1 > expandedForSpelled(llvm::ArrayRef< syntax::Token > Spelled) const
Find the subranges of expanded tokens, corresponding to Spelled.
llvm::ArrayRef< syntax::Token > expandedTokens() const
All tokens produced by the preprocessor after all macro replacements, directives, etc.
std::string dumpForTests() const
std::optional< llvm::ArrayRef< syntax::Token > > spelledForExpanded(llvm::ArrayRef< syntax::Token > Expanded) const
Returns the subrange of spelled tokens corresponding to AST node spanning Expanded.
std::vector< Expansion > expansionsOverlapping(llvm::ArrayRef< syntax::Token > Spelled) const
Returns all expansions (partially) expanded from the specified tokens.
std::optional< Expansion > expansionStartingAt(const syntax::Token *Spelled) const
If Spelled starts a mapping (e.g.
llvm::ArrayRef< syntax::Token > spelledTokens(FileID FID) const
Lexed tokens of a file before preprocessing.
std::vector< const syntax::Token * > macroExpansions(FileID FID) const
Get all tokens that expand a macro in FID.
TokenBuffer consume() &&
Finalizes token collection.
TokenCollector(Preprocessor &P)
Adds the hooks to collect the tokens.
A token coming directly from a file or from a macro invocation.
std::string str() const
For debugging purposes.
llvm::StringRef text(const SourceManager &SM) const
Get the substring covered by the token.
tok::TokenKind kind() const
FileRange range(const SourceManager &SM) const
Gets a range of this token.
Token(SourceLocation Location, unsigned Length, tok::TokenKind Kind)
std::string dumpForTests(const SourceManager &SM) const
SourceLocation location() const
Location of the first character of a token.
bool Dec(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value decreased by ...
const syntax::Token * spelledIdentifierTouching(SourceLocation Loc, llvm::ArrayRef< syntax::Token > Tokens)
The identifier token that overlaps or touches a spelling location Loc.
std::vector< syntax::Token > tokenize(FileID FID, const SourceManager &SM, const LangOptions &LO)
Lex the text buffer, corresponding to FID, in raw mode and record the resulting spelled tokens.
raw_ostream & operator<<(raw_ostream &OS, NodeKind K)
For debugging purposes.
llvm::ArrayRef< syntax::Token > spelledTokensTouching(SourceLocation Loc, const syntax::TokenBuffer &Tokens)
The spelled tokens that overlap or touch a spelling location Loc.
const char * getTokenName(TokenKind Kind) LLVM_READNONE
Determines the name of a token as used within the front end.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Top level wrappers for InstallAPI frontend operations.
@ Result
The result type of a method or function.
const FunctionProtoType * T
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
A half-open character range inside a particular file, the start offset is included and the end offset...
CharSourceRange toCharRange(const SourceManager &SM) const
Convert to the clang range.
FileRange(FileID File, unsigned BeginOffset, unsigned EndOffset)
EXPECTS: File.isValid() && Begin <= End.
unsigned beginOffset() const
Start is a start offset (inclusive) in the corresponding file.
llvm::StringRef text(const SourceManager &SM) const
Gets the substring that this FileRange refers to.
unsigned endOffset() const
End offset (exclusive) in the corresponding file.
An expansion produced by the preprocessor, includes macro expansions and preprocessor directives.
llvm::ArrayRef< syntax::Token > Spelled