Skip to content

Commit 1819646

Browse files
[clang][refactor] Refactor findNextTokenIncludingComments (#123060)
We have two copies of the same code in clang-tidy and clang-reorder-fields, and those are extremenly similar to `Lexer::findNextToken`, so just add an extra agument to the latter. --------- Co-authored-by: cor3ntin <[email protected]>
1 parent f6b0555 commit 1819646

File tree

6 files changed

+33
-58
lines changed

6 files changed

+33
-58
lines changed

clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -118,47 +118,19 @@ findMembersUsedInInitExpr(const CXXCtorInitializer *Initializer,
118118
return Results;
119119
}
120120

121-
/// Returns the next token after `Loc` (including comment tokens).
122-
static std::optional<Token> getTokenAfter(SourceLocation Loc,
123-
const SourceManager &SM,
124-
const LangOptions &LangOpts) {
125-
if (Loc.isMacroID()) {
126-
return std::nullopt;
127-
}
128-
Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
129-
130-
// Break down the source location.
131-
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
132-
133-
// Try to load the file buffer.
134-
bool InvalidTemp = false;
135-
StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
136-
if (InvalidTemp)
137-
return std::nullopt;
138-
139-
const char *TokenBegin = File.data() + LocInfo.second;
140-
141-
Lexer lexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
142-
TokenBegin, File.end());
143-
lexer.SetCommentRetentionState(true);
144-
// Find the token.
145-
Token Tok;
146-
lexer.LexFromRawLexer(Tok);
147-
return Tok;
148-
}
149-
150121
/// Returns the end of the trailing comments after `Loc`.
151122
static SourceLocation getEndOfTrailingComment(SourceLocation Loc,
152123
const SourceManager &SM,
153124
const LangOptions &LangOpts) {
154125
// We consider any following comment token that is indented more than the
155126
// first comment to be part of the trailing comment.
156127
const unsigned Column = SM.getPresumedColumnNumber(Loc);
157-
std::optional<Token> Tok = getTokenAfter(Loc, SM, LangOpts);
128+
std::optional<Token> Tok =
129+
Lexer::findNextToken(Loc, SM, LangOpts, /*IncludeComments=*/true);
158130
while (Tok && Tok->is(tok::comment) &&
159131
SM.getPresumedColumnNumber(Tok->getLocation()) > Column) {
160132
Loc = Tok->getEndLoc();
161-
Tok = getTokenAfter(Loc, SM, LangOpts);
133+
Tok = Lexer::findNextToken(Loc, SM, LangOpts, /*IncludeComments=*/true);
162134
}
163135
return Loc;
164136
}

clang-tools-extra/clang-tidy/utils/LexerUtils.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -86,29 +86,6 @@ SourceLocation findNextTerminator(SourceLocation Start, const SourceManager &SM,
8686
return findNextAnyTokenKind(Start, SM, LangOpts, tok::comma, tok::semi);
8787
}
8888

89-
std::optional<Token>
90-
findNextTokenIncludingComments(SourceLocation Start, const SourceManager &SM,
91-
const LangOptions &LangOpts) {
92-
// `Lexer::findNextToken` will ignore comment
93-
if (Start.isMacroID())
94-
return std::nullopt;
95-
Start = Lexer::getLocForEndOfToken(Start, 0, SM, LangOpts);
96-
// Break down the source location.
97-
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Start);
98-
bool InvalidTemp = false;
99-
StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
100-
if (InvalidTemp)
101-
return std::nullopt;
102-
// Lex from the start of the given location.
103-
Lexer L(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
104-
File.data() + LocInfo.second, File.end());
105-
L.SetCommentRetentionState(true);
106-
// Find the token.
107-
Token Tok;
108-
L.LexFromRawLexer(Tok);
109-
return Tok;
110-
}
111-
11289
std::optional<Token>
11390
findNextTokenSkippingComments(SourceLocation Start, const SourceManager &SM,
11491
const LangOptions &LangOpts) {

clang-tools-extra/clang-tidy/utils/LexerUtils.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,11 @@ SourceLocation findNextAnyTokenKind(SourceLocation Start,
8989
}
9090
}
9191

92-
std::optional<Token>
92+
inline std::optional<Token>
9393
findNextTokenIncludingComments(SourceLocation Start, const SourceManager &SM,
94-
const LangOptions &LangOpts);
94+
const LangOptions &LangOpts) {
95+
return Lexer::findNextToken(Start, SM, LangOpts, true);
96+
}
9597

9698
// Finds next token that's not a comment.
9799
std::optional<Token> findNextTokenSkippingComments(SourceLocation Start,

clang/include/clang/Lex/Lexer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,8 @@ class Lexer : public PreprocessorLexer {
554554
/// Returns the next token, or std::nullopt if the location is inside a macro.
555555
static std::optional<Token> findNextToken(SourceLocation Loc,
556556
const SourceManager &SM,
557-
const LangOptions &LangOpts);
557+
const LangOptions &LangOpts,
558+
bool IncludeComments = false);
558559

559560
/// Checks that the given token is the first token that occurs after
560561
/// the given location (this excludes comments and whitespace). Returns the

clang/lib/Lex/Lexer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,8 @@ const char *Lexer::SkipEscapedNewLines(const char *P) {
13231323

13241324
std::optional<Token> Lexer::findNextToken(SourceLocation Loc,
13251325
const SourceManager &SM,
1326-
const LangOptions &LangOpts) {
1326+
const LangOptions &LangOpts,
1327+
bool IncludeComments) {
13271328
if (Loc.isMacroID()) {
13281329
if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
13291330
return std::nullopt;
@@ -1344,6 +1345,7 @@ std::optional<Token> Lexer::findNextToken(SourceLocation Loc,
13441345
// Lex from the start of the given location.
13451346
Lexer lexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
13461347
TokenBegin, File.end());
1348+
lexer.SetCommentRetentionState(IncludeComments);
13471349
// Find the token.
13481350
Token Tok;
13491351
lexer.LexFromRawLexer(Tok);

clang/unittests/Lex/LexerTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ TEST_F(LexerTest, CharRangeOffByOne) {
603603

604604
TEST_F(LexerTest, FindNextToken) {
605605
Lex("int abcd = 0;\n"
606+
"// A comment.\n"
606607
"int xyz = abcd;\n");
607608
std::vector<std::string> GeneratedByNextToken;
608609
SourceLocation Loc =
@@ -619,6 +620,26 @@ TEST_F(LexerTest, FindNextToken) {
619620
"xyz", "=", "abcd", ";"));
620621
}
621622

623+
TEST_F(LexerTest, FindNextTokenIncludingComments) {
624+
Lex("int abcd = 0;\n"
625+
"// A comment.\n"
626+
"int xyz = abcd;\n");
627+
std::vector<std::string> GeneratedByNextToken;
628+
SourceLocation Loc =
629+
SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
630+
while (true) {
631+
auto T = Lexer::findNextToken(Loc, SourceMgr, LangOpts, true);
632+
ASSERT_TRUE(T);
633+
if (T->is(tok::eof))
634+
break;
635+
GeneratedByNextToken.push_back(getSourceText(*T, *T));
636+
Loc = T->getLocation();
637+
}
638+
EXPECT_THAT(GeneratedByNextToken,
639+
ElementsAre("abcd", "=", "0", ";", "// A comment.", "int", "xyz",
640+
"=", "abcd", ";"));
641+
}
642+
622643
TEST_F(LexerTest, CreatedFIDCountForPredefinedBuffer) {
623644
TrivialModuleLoader ModLoader;
624645
auto PP = CreatePP("", ModLoader);

0 commit comments

Comments
 (0)