10 #include "clang/AST/AST.h"
11 #include "clang/Basic/SourceManager.h"
17 const LangOptions &
LangOpts,
bool SkipComments) {
19 Token.setKind(tok::unknown);
25 auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(
Location));
29 (!SkipComments || !Token.is(tok::comment))) {
38 const SourceManager &SM,
40 if (Start.isInvalid() || Start.isMacroID())
41 return SourceLocation();
43 SourceLocation BeforeStart = Start.getLocWithOffset(-1);
44 if (BeforeStart.isInvalid() || BeforeStart.isMacroID())
45 return SourceLocation();
47 return Lexer::GetBeginningOfToken(BeforeStart, SM,
LangOpts);
51 const SourceManager &SM,
54 if (Start.isInvalid() || Start.isMacroID())
55 return SourceLocation();
59 if (L.isInvalid() || L.isMacroID())
60 return SourceLocation();
63 if (Lexer::getRawToken(L, T, SM,
LangOpts,
true))
64 return SourceLocation();
67 return T.getLocation();
81 std::optional<Token> CurrentToken;
83 CurrentToken = Lexer::findNextToken(Start, SM,
LangOpts);
84 }
while (CurrentToken && CurrentToken->is(tok::comment));
89 const SourceManager &SM,
91 assert(
Range.isValid() &&
"Invalid Range for relexing provided");
92 SourceLocation
Loc =
Range.getBegin();
98 std::optional<Token> Tok = Lexer::findNextToken(
Loc, SM,
LangOpts);
103 if (Tok->is(tok::hash))
106 Loc = Lexer::getLocForEndOfToken(
Loc, 0, SM,
LangOpts).getLocWithOffset(1);
113 CharSourceRange
Range,
114 const ASTContext &Context,
115 const SourceManager &SM) {
116 assert((TK == tok::kw_const || TK == tok::kw_volatile ||
117 TK == tok::kw_restrict) &&
118 "TK is not a qualifier keyword");
119 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(
Range.getBegin());
120 StringRef File = SM.getBufferData(LocInfo.first);
121 Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
122 File.begin(), File.data() + LocInfo.second, File.end());
123 std::optional<Token> LastMatchBeforeTemplate;
124 std::optional<Token> LastMatchAfterTemplate;
125 bool SawTemplate =
false;
127 while (!RawLexer.LexFromRawLexer(Tok) &&
128 Range.getEnd() != Tok.getLocation() &&
129 !SM.isBeforeInTranslationUnit(
Range.getEnd(), Tok.getLocation())) {
130 if (Tok.is(tok::raw_identifier)) {
131 IdentifierInfo &
Info = Context.Idents.get(
132 StringRef(SM.getCharacterData(Tok.getLocation()), Tok.getLength()));
133 Tok.setIdentifierInfo(&
Info);
134 Tok.setKind(
Info.getTokenID());
136 if (Tok.is(tok::less))
138 else if (Tok.isOneOf(tok::greater, tok::greatergreater))
139 LastMatchAfterTemplate = std::nullopt;
140 else if (Tok.is(TK)) {
142 LastMatchAfterTemplate = Tok;
144 LastMatchBeforeTemplate = Tok;
147 return LastMatchAfterTemplate != std::nullopt ? LastMatchAfterTemplate
148 : LastMatchBeforeTemplate;
152 return isa<CompoundStmt, DeclStmt, NullStmt>(S);
156 return isa<Expr, DoStmt, ReturnStmt, BreakStmt, ContinueStmt, GotoStmt, SEHLeaveStmt>(S);
162 const SourceManager &SM,
165 if (EndLoc.isMacroID()) {
171 const SourceLocation SpellingLoc = SM.getSpellingLoc(EndLoc);
172 std::optional<Token> NextTok =
177 if (NextTok && NextTok->is(tok::TokenKind::semi)) {
180 return NextTok->getLocation();
188 std::optional<Token> NextTok =
192 if (NextTok && NextTok->is(tok::TokenKind::semi))
193 return NextTok->getLocation();
195 return SourceLocation();
201 const Stmt *LastChild = &S;
204 for (
const Stmt *Child : LastChild->children())
212 return S.getEndLoc();