10 #include "clang/AST/AST.h"
11 #include "clang/Basic/SourceManager.h"
19 const LangOptions &
LangOpts,
bool SkipComments) {
21 Token.setKind(tok::unknown);
27 auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(
Location));
31 (!SkipComments || !Token.is(tok::comment))) {
40 const SourceManager &SM,
42 if (Start.isInvalid() || Start.isMacroID())
43 return SourceLocation();
45 SourceLocation BeforeStart = Start.getLocWithOffset(-1);
46 if (BeforeStart.isInvalid() || BeforeStart.isMacroID())
47 return SourceLocation();
49 return Lexer::GetBeginningOfToken(BeforeStart, SM,
LangOpts);
53 const SourceManager &SM,
56 if (Start.isInvalid() || Start.isMacroID())
57 return SourceLocation();
61 if (L.isInvalid() || L.isMacroID())
62 return SourceLocation();
65 if (Lexer::getRawToken(L, T, SM,
LangOpts,
true))
66 return SourceLocation();
69 return T.getLocation();
81 const SourceManager &SM,
83 Optional<Token> CurrentToken;
85 CurrentToken = Lexer::findNextToken(Start, SM,
LangOpts);
86 }
while (CurrentToken && CurrentToken->is(tok::comment));
91 const SourceManager &SM,
93 assert(
Range.isValid() &&
"Invalid Range for relexing provided");
94 SourceLocation
Loc =
Range.getBegin();
100 llvm::Optional<Token> Tok = Lexer::findNextToken(
Loc, SM,
LangOpts);
105 if (Tok->is(tok::hash))
108 Loc = Lexer::getLocForEndOfToken(
Loc, 0, SM,
LangOpts).getLocWithOffset(1);
115 CharSourceRange
Range,
116 const ASTContext &Context,
117 const SourceManager &SM) {
118 assert((TK == tok::kw_const || TK == tok::kw_volatile ||
119 TK == tok::kw_restrict) &&
120 "TK is not a qualifier keyword");
121 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(
Range.getBegin());
122 StringRef File = SM.getBufferData(LocInfo.first);
123 Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
124 File.begin(), File.data() + LocInfo.second, File.end());
125 llvm::Optional<Token> LastMatchBeforeTemplate;
126 llvm::Optional<Token> LastMatchAfterTemplate;
127 bool SawTemplate =
false;
129 while (!RawLexer.LexFromRawLexer(Tok) &&
130 Range.getEnd() != Tok.getLocation() &&
131 !SM.isBeforeInTranslationUnit(
Range.getEnd(), Tok.getLocation())) {
132 if (Tok.is(tok::raw_identifier)) {
133 IdentifierInfo &
Info = Context.Idents.get(
134 StringRef(SM.getCharacterData(Tok.getLocation()), Tok.getLength()));
135 Tok.setIdentifierInfo(&
Info);
136 Tok.setKind(
Info.getTokenID());
138 if (Tok.is(tok::less))
140 else if (Tok.isOneOf(tok::greater, tok::greatergreater))
141 LastMatchAfterTemplate = None;
142 else if (Tok.is(TK)) {
144 LastMatchAfterTemplate = Tok;
146 LastMatchBeforeTemplate = Tok;
149 return LastMatchAfterTemplate != None ? LastMatchAfterTemplate
150 : LastMatchBeforeTemplate;
154 return isa<CompoundStmt, DeclStmt, NullStmt>(S);
158 return isa<Expr, DoStmt, ReturnStmt, BreakStmt, ContinueStmt, GotoStmt, SEHLeaveStmt>(S);
164 const SourceManager &SM,
167 if (EndLoc.isMacroID()) {
173 const SourceLocation SpellingLoc = SM.getSpellingLoc(EndLoc);
174 Optional<Token> NextTok =
179 if (NextTok && NextTok->is(tok::TokenKind::semi)) {
182 return NextTok->getLocation();
193 if (NextTok && NextTok->is(tok::TokenKind::semi))
194 return NextTok->getLocation();
196 return SourceLocation();
202 const Stmt *LastChild = &S;
205 for (
const Stmt *Child : LastChild->children())
213 return S.getEndLoc();