Skip to content

Commit c71f0bd

Browse files
committed
Relex the token past the end location of the last token in the source range. If it's a semicolon, advance the location by one token.
1 parent 14bd903 commit c71f0bd

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

clang/lib/Frontend/FrontendAction.cpp

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/Basic/SourceLocation.h"
1919
#include "clang/Basic/SourceManager.h"
2020
#include "clang/Basic/Stack.h"
21+
#include "clang/Basic/TokenKinds.h"
2122
#include "clang/Frontend/ASTUnit.h"
2223
#include "clang/Frontend/CompilerInstance.h"
2324
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -105,9 +106,34 @@ class DeserializedDeclsLineRangePrinter : public ASTConsumer,
105106
return Column < other.Column;
106107
}
107108

108-
static Position GetSpelling(const SourceManager &SM,
109-
const SourceLocation &SL) {
110-
return {SM.getSpellingLineNumber(SL), SM.getSpellingColumnNumber(SL)};
109+
static Position GetBeginSpelling(const SourceManager &SM,
110+
const CharSourceRange &R) {
111+
SourceLocation Begin = R.getBegin();
112+
return {SM.getSpellingLineNumber(Begin),
113+
SM.getSpellingColumnNumber(Begin)};
114+
}
115+
116+
static Position GetEndSpelling(const SourceManager &SM,
117+
const CharSourceRange &R,
118+
const LangOptions &LangOpts) {
119+
SourceLocation End = R.getEnd();
120+
if (R.isTokenRange()) {
121+
// Compute end location for end character of the range.
122+
// The returned location is exclusive.
123+
End = Lexer::getLocForEndOfToken(End, 0, SM, LangOpts);
124+
} else {
125+
// If end already points at the last character in the range, advance one
126+
// location, so that end location is exclusive.
127+
End = End.getLocWithOffset(1);
128+
}
129+
// Relex the token past the end location of the last token in the source
130+
// range. If it's a semicolon, advance the location by one token.
131+
Token PossiblySemi;
132+
Lexer::getRawToken(End, PossiblySemi, SM, LangOpts, true);
133+
if (PossiblySemi.is(tok::semi))
134+
End = Lexer::getLocForEndOfToken(PossiblySemi.getLocation(), 0, SM,
135+
LangOpts);
136+
return {SM.getSpellingLineNumber(End), SM.getSpellingColumnNumber(End)};
111137
}
112138
};
113139

@@ -130,21 +156,18 @@ class DeserializedDeclsLineRangePrinter : public ASTConsumer,
130156
if (!R.isValid())
131157
continue;
132158

133-
SourceLocation End = R.getEnd();
134-
if (R.isTokenRange())
135-
End = Lexer::getLocForEndOfToken(End, 0, SM, D->getLangOpts());
136-
137159
auto *F = SM.getFileEntryForID(SM.getFileID(R.getBegin()));
138-
if (F != SM.getFileEntryForID(SM.getFileID(End))) {
160+
if (F != SM.getFileEntryForID(SM.getFileID(R.getEnd()))) {
139161
// Such cases are rare and difficult to handle.
140162
continue;
141163
}
142164

143165
auto &Data = FileToLines[F];
144166
if (!Data.Ref)
145167
Data.Ref = SM.getFileEntryRefForID(SM.getFileID(R.getBegin()));
146-
Data.FromTo.push_back({Position::GetSpelling(SM, R.getBegin()),
147-
Position::GetSpelling(SM, End)});
168+
Data.FromTo.push_back(
169+
{Position::GetBeginSpelling(SM, R),
170+
Position::GetEndSpelling(SM, R, D->getLangOpts())});
148171
}
149172

150173
// To simplify output, merge consecutive and intersecting ranges.

clang/test/Frontend/dump-deserialized-declaration-ranges.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// RANGE-NEXT: },
1818
// RANGE-NEXT: "to": {
1919
// RANGE-NEXT: "line": 9,
20-
// RANGE-NEXT: "column": 2
20+
// RANGE-NEXT: "column": 3
2121
// RANGE-NEXT: }
2222
// RANGE-NEXT: },
2323
// RANGE-NEXT: {
@@ -27,7 +27,7 @@
2727
// RANGE-NEXT: },
2828
// RANGE-NEXT: "to": {
2929
// RANGE-NEXT: "line": 11,
30-
// RANGE-NEXT: "column": 24
30+
// RANGE-NEXT: "column": 25
3131
// RANGE-NEXT: }
3232
// RANGE-NEXT: },
3333
// RANGE-NEXT: {

0 commit comments

Comments
 (0)