10#include "clang/Basic/SourceManager.h"
16std::pair<Token, SourceLocation>
18 const LangOptions &LangOpts,
bool SkipComments) {
19 const std::optional<Token> Tok =
20 Lexer::findPreviousToken(
Location, SM, LangOpts, !SkipComments);
22 if (Tok.has_value()) {
23 return {*Tok, Lexer::GetBeginningOfToken(Tok->getLocation(), SM, LangOpts)};
27 Token.setKind(tok::unknown);
28 return {Token, SourceLocation()};
32 const LangOptions &LangOpts,
bool SkipComments) {
39 const SourceManager &SM,
40 const LangOptions &LangOpts) {
41 if (Start.isInvalid() || Start.isMacroID())
44 const SourceLocation BeforeStart = Start.getLocWithOffset(-1);
45 if (BeforeStart.isInvalid() || BeforeStart.isMacroID())
48 return Lexer::GetBeginningOfToken(BeforeStart, SM, LangOpts);
52 const SourceManager &SM,
53 const LangOptions &LangOpts,
55 if (Start.isInvalid() || Start.isMacroID())
60 if (L.isInvalid() || L.isMacroID())
64 if (Lexer::getRawToken(L, T, SM, LangOpts,
true))
68 return T.getLocation();
75 const LangOptions &LangOpts) {
81 const LangOptions &LangOpts) {
82 while (Start.isValid()) {
83 std::optional<Token> CurrentToken =
84 Lexer::findNextToken(Start, SM, LangOpts);
85 if (!CurrentToken || !CurrentToken->is(tok::comment))
88 Start = CurrentToken->getLocation();
95 const SourceManager &SM,
96 const LangOptions &LangOpts) {
97 assert(Range.isValid() &&
"Invalid Range for relexing provided");
98 SourceLocation Loc = Range.getBegin();
100 while (Loc <= Range.getEnd()) {
104 std::optional<Token> Tok = Lexer::findNextToken(Loc, SM, LangOpts);
109 if (Tok->is(tok::hash))
112 Loc = Tok->getLocation();
119 CharSourceRange Range,
120 const ASTContext &Context,
121 const SourceManager &SM) {
122 assert((TK == tok::kw_const || TK == tok::kw_volatile ||
123 TK == tok::kw_restrict) &&
124 "TK is not a qualifier keyword");
125 const std::pair<FileID, unsigned> LocInfo =
126 SM.getDecomposedLoc(Range.getBegin());
127 const StringRef File = SM.getBufferData(LocInfo.first);
128 Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
129 File.begin(), File.data() + LocInfo.second, File.end());
130 std::optional<Token> LastMatchBeforeTemplate;
131 std::optional<Token> LastMatchAfterTemplate;
132 bool SawTemplate =
false;
134 while (!RawLexer.LexFromRawLexer(Tok) &&
135 Range.getEnd() != Tok.getLocation() &&
136 !SM.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation())) {
137 if (Tok.is(tok::raw_identifier)) {
138 IdentifierInfo &Info = Context.Idents.get(
139 StringRef(SM.getCharacterData(Tok.getLocation()), Tok.getLength()));
140 Tok.setIdentifierInfo(&Info);
141 Tok.setKind(Info.getTokenID());
143 if (Tok.is(tok::less))
145 else if (Tok.isOneOf(tok::greater, tok::greatergreater))
146 LastMatchAfterTemplate = std::nullopt;
147 else if (Tok.is(TK)) {
149 LastMatchAfterTemplate = Tok;
151 LastMatchBeforeTemplate = Tok;
154 return LastMatchAfterTemplate != std::nullopt ? LastMatchAfterTemplate
155 : LastMatchBeforeTemplate;
159 return isa<CompoundStmt, DeclStmt, NullStmt>(S);
163 return isa<Expr, DoStmt, ReturnStmt, BreakStmt, ContinueStmt, GotoStmt,
170 const SourceManager &SM,
171 const LangOptions &LangOpts) {
172 if (EndLoc.isMacroID()) {
178 const SourceLocation SpellingLoc = SM.getSpellingLoc(EndLoc);
179 std::optional<Token> NextTok =
184 if (NextTok && NextTok->is(tok::TokenKind::semi)) {
187 return NextTok->getLocation();
195 std::optional<Token> NextTok =
199 if (NextTok && NextTok->is(tok::TokenKind::semi))
200 return NextTok->getLocation();
206 const LangOptions &LangOpts) {
207 const Stmt *LastChild = &S;
210 for (
const Stmt *Child : LastChild->children())
217 return S.getEndLoc();
221 const SourceManager &SM) {
225 const LangOptions &LangOpts =
FuncDecl->getLangOpts();
227 if (
FuncDecl->getNumParams() == 0) {
231 SourceLocation CurrentLocation =
FuncDecl->getBeginLoc();
232 while (!Lexer::getRawToken(CurrentLocation, CurrentToken, SM, LangOpts,
234 if (CurrentToken.is(tok::r_paren))
235 return CurrentLocation.getLocWithOffset(1);
237 CurrentLocation = CurrentToken.getEndLoc();
246 const SourceLocation NoexceptLoc =
248 if (NoexceptLoc.isValid())
249 return Lexer::findLocationAfterToken(
250 NoexceptLoc, tok::r_paren, SM, LangOpts,
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...
static constexpr const char FuncDecl[]