10#include "clang/AST/AST.h"
11#include "clang/Basic/SourceManager.h"
17std::pair<Token, SourceLocation>
19 const LangOptions &LangOpts,
bool SkipComments) {
21 Token.setKind(tok::unknown);
27 const auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(
Location));
30 if (!Lexer::getRawToken(
Location, Token, SM, LangOpts) &&
31 (!SkipComments || !Token.is(tok::comment))) {
42 const LangOptions &LangOpts,
bool SkipComments) {
49 const SourceManager &SM,
50 const LangOptions &LangOpts) {
51 if (Start.isInvalid() || Start.isMacroID())
54 SourceLocation BeforeStart = Start.getLocWithOffset(-1);
55 if (BeforeStart.isInvalid() || BeforeStart.isMacroID())
58 return Lexer::GetBeginningOfToken(BeforeStart, SM, LangOpts);
62 const SourceManager &SM,
63 const LangOptions &LangOpts,
65 if (Start.isInvalid() || Start.isMacroID())
70 if (L.isInvalid() || L.isMacroID())
74 if (Lexer::getRawToken(L, T, SM, LangOpts,
true))
78 return T.getLocation();
85 const LangOptions &LangOpts) {
91 const LangOptions &LangOpts) {
93 if (Start.isMacroID())
95 Start = Lexer::getLocForEndOfToken(Start, 0, SM, LangOpts);
97 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Start);
98 bool InvalidTemp =
false;
99 StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
103 Lexer L(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
104 File.data() + LocInfo.second, File.end());
105 L.SetCommentRetentionState(
true);
108 L.LexFromRawLexer(Tok);
114 const LangOptions &LangOpts) {
115 while (Start.isValid()) {
116 std::optional<Token> CurrentToken =
117 Lexer::findNextToken(Start, SM, LangOpts);
118 if (!CurrentToken || !CurrentToken->is(tok::comment))
121 Start = CurrentToken->getLocation();
128 const SourceManager &SM,
129 const LangOptions &LangOpts) {
130 assert(
Range.isValid() &&
"Invalid Range for relexing provided");
131 SourceLocation
Loc =
Range.getBegin();
137 std::optional<Token> Tok = Lexer::findNextToken(
Loc, SM, LangOpts);
142 if (Tok->is(tok::hash))
145 Loc = Tok->getLocation();
152 CharSourceRange
Range,
153 const ASTContext &Context,
154 const SourceManager &SM) {
155 assert((TK == tok::kw_const || TK == tok::kw_volatile ||
156 TK == tok::kw_restrict) &&
157 "TK is not a qualifier keyword");
158 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(
Range.getBegin());
159 StringRef File = SM.getBufferData(LocInfo.first);
160 Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
161 File.begin(), File.data() + LocInfo.second, File.end());
162 std::optional<Token> LastMatchBeforeTemplate;
163 std::optional<Token> LastMatchAfterTemplate;
164 bool SawTemplate =
false;
166 while (!RawLexer.LexFromRawLexer(Tok) &&
167 Range.getEnd() != Tok.getLocation() &&
168 !SM.isBeforeInTranslationUnit(
Range.getEnd(), Tok.getLocation())) {
169 if (Tok.is(tok::raw_identifier)) {
170 IdentifierInfo &
Info = Context.Idents.get(
171 StringRef(SM.getCharacterData(Tok.getLocation()), Tok.getLength()));
172 Tok.setIdentifierInfo(&
Info);
173 Tok.setKind(
Info.getTokenID());
175 if (Tok.is(tok::less))
177 else if (Tok.isOneOf(tok::greater, tok::greatergreater))
178 LastMatchAfterTemplate = std::nullopt;
179 else if (Tok.is(TK)) {
181 LastMatchAfterTemplate = Tok;
183 LastMatchBeforeTemplate = Tok;
186 return LastMatchAfterTemplate != std::nullopt ? LastMatchAfterTemplate
187 : LastMatchBeforeTemplate;
191 return isa<CompoundStmt, DeclStmt, NullStmt>(S);
195 return isa<Expr, DoStmt, ReturnStmt, BreakStmt, ContinueStmt, GotoStmt,
202 const SourceManager &SM,
203 const LangOptions &LangOpts) {
205 if (EndLoc.isMacroID()) {
211 const SourceLocation SpellingLoc = SM.getSpellingLoc(EndLoc);
212 std::optional<Token> NextTok =
217 if (NextTok && NextTok->is(tok::TokenKind::semi)) {
220 return NextTok->getLocation();
228 std::optional<Token> NextTok =
232 if (NextTok && NextTok->is(tok::TokenKind::semi))
233 return NextTok->getLocation();
239 const LangOptions &LangOpts) {
241 const Stmt *LastChild = &S;
244 for (
const Stmt *Child : LastChild->children())
251 return S.getEndLoc();
255 const SourceManager &SM) {
259 const LangOptions &LangOpts =
FuncDecl->getLangOpts();
261 if (
FuncDecl->getNumParams() == 0) {
265 SourceLocation CurrentLocation =
FuncDecl->getBeginLoc();
266 while (!Lexer::getRawToken(CurrentLocation, CurrentToken, SM, LangOpts,
268 if (CurrentToken.is(tok::r_paren))
269 return CurrentLocation.getLocWithOffset(1);
271 CurrentLocation = CurrentToken.getEndLoc();
280 const SourceLocation NoexceptLoc =
282 if (NoexceptLoc.isValid())
283 return Lexer::findLocationAfterToken(
284 NoexceptLoc, tok::r_paren, SM, LangOpts,
CharSourceRange Range
SourceRange for the file name.
SourceLocation getLocationForNoexceptSpecifier(const FunctionDecl *FuncDecl, const SourceManager &SM)
For a given FunctionDecl returns the location where you would need to place the noexcept specifier.
std::pair< Token, SourceLocation > getPreviousTokenAndStart(SourceLocation Location, const SourceManager &SM, const LangOptions &LangOpts, bool SkipComments)
SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM, const LangOptions &LangOpts)
Stmt->getEndLoc does not always behave the same way depending on Token type.
bool rangeContainsExpansionsOrDirectives(SourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Re-lex the provide Range and return false if either a macro spans multiple tokens,...
SourceLocation findNextTerminator(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts)
SourceLocation findNextAnyTokenKind(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts, TokenKind TK, TokenKinds... TKs)
Token getPreviousToken(SourceLocation Location, const SourceManager &SM, const LangOptions &LangOpts, bool SkipComments)
Returns previous token or tok::unknown if not found.
std::optional< Token > findNextTokenSkippingComments(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts)
SourceLocation findPreviousTokenStart(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts)
static SourceLocation getSemicolonAfterStmtEndLoc(const SourceLocation &EndLoc, const SourceManager &SM, const LangOptions &LangOpts)
static bool breakAndReturnEndPlus1Token(const Stmt &S)
static bool breakAndReturnEnd(const Stmt &S)
SourceLocation findPreviousTokenKind(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts, tok::TokenKind TK)
std::optional< Token > getQualifyingToken(tok::TokenKind TK, CharSourceRange Range, const ASTContext &Context, const SourceManager &SM)
Assuming that Range spans a CVR-qualified type, returns the token in Range that is responsible for th...
std::optional< Token > findNextTokenIncludingComments(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts)
static constexpr const char FuncDecl[]