Skip to content

Commit 3302af8

Browse files
committed
[clangd] Make use of token buffers in semantic highlighting
Reviewers: hokein, sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75447
1 parent cd9b2e1 commit 3302af8

File tree

1 file changed

+26
-25
lines changed

1 file changed

+26
-25
lines changed

clang-tools-extra/clangd/SemanticHighlighting.cpp

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "clang/Basic/LangOptions.h"
2424
#include "clang/Basic/SourceLocation.h"
2525
#include "clang/Basic/SourceManager.h"
26+
#include "clang/Tooling/Syntax/Tokens.h"
2627
#include "llvm/ADT/None.h"
2728
#include "llvm/ADT/Optional.h"
2829
#include "llvm/ADT/STLExtras.h"
@@ -128,40 +129,39 @@ llvm::Optional<HighlightingKind> kindForReference(const ReferenceLoc &R) {
128129
return Result;
129130
}
130131

132+
// For a macro usage `DUMP(foo)`, we want:
133+
// - DUMP --> "macro"
134+
// - foo --> "variable".
135+
SourceLocation getHighlightableSpellingToken(SourceLocation L,
136+
const SourceManager &SM) {
137+
if (L.isFileID())
138+
return SM.isWrittenInMainFile(L) ? L : SourceLocation{};
139+
// Tokens expanded from the macro body contribute no highlightings.
140+
if (!SM.isMacroArgExpansion(L))
141+
return {};
142+
// Tokens expanded from macro args are potentially highlightable.
143+
return getHighlightableSpellingToken(SM.getImmediateSpellingLoc(L), SM);
144+
}
145+
131146
/// Consumes source locations and maps them to text ranges for highlightings.
132147
class HighlightingsBuilder {
133148
public:
134-
HighlightingsBuilder(const SourceManager &SourceMgr,
135-
const LangOptions &LangOpts)
136-
: SourceMgr(SourceMgr), LangOpts(LangOpts) {}
149+
HighlightingsBuilder(const ParsedAST &AST)
150+
: TB(AST.getTokens()), SourceMgr(AST.getSourceManager()),
151+
LangOpts(AST.getLangOpts()) {}
137152

138153
void addToken(HighlightingToken T) { Tokens.push_back(T); }
139154

140155
void addToken(SourceLocation Loc, HighlightingKind Kind) {
156+
Loc = getHighlightableSpellingToken(Loc, SourceMgr);
141157
if (Loc.isInvalid())
142158
return;
143-
if (Loc.isMacroID()) {
144-
// Only intereseted in highlighting arguments in macros (DEF_X(arg)).
145-
if (!SourceMgr.isMacroArgExpansion(Loc))
146-
return;
147-
Loc = SourceMgr.getSpellingLoc(Loc);
148-
}
149-
150-
// Non top level decls that are included from a header are not filtered by
151-
// topLevelDecls. (example: method declarations being included from
152-
// another file for a class from another file).
153-
// There are also cases with macros where the spelling loc will not be in
154-
// the main file and the highlighting would be incorrect.
155-
if (!isInsideMainFile(Loc, SourceMgr))
156-
return;
159+
const auto *Tok = TB.spelledTokenAt(Loc);
160+
assert(Tok);
157161

158-
auto Range = getTokenRange(SourceMgr, LangOpts, Loc);
159-
if (!Range) {
160-
// R should always have a value, if it doesn't something is very wrong.
161-
elog("Tried to add semantic token with an invalid range");
162-
return;
163-
}
164-
Tokens.push_back(HighlightingToken{Kind, *Range});
162+
auto Range = halfOpenToRange(SourceMgr,
163+
Tok->range(SourceMgr).toCharRange(SourceMgr));
164+
Tokens.push_back(HighlightingToken{Kind, std::move(Range)});
165165
}
166166

167167
std::vector<HighlightingToken> collect(ParsedAST &AST) && {
@@ -211,6 +211,7 @@ class HighlightingsBuilder {
211211
}
212212

213213
private:
214+
const syntax::TokenBuffer &TB;
214215
const SourceManager &SourceMgr;
215216
const LangOptions &LangOpts;
216217
std::vector<HighlightingToken> Tokens;
@@ -311,7 +312,7 @@ takeLine(ArrayRef<HighlightingToken> AllTokens,
311312
std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST) {
312313
auto &C = AST.getASTContext();
313314
// Add highlightings for AST nodes.
314-
HighlightingsBuilder Builder(AST.getSourceManager(), C.getLangOpts());
315+
HighlightingsBuilder Builder(AST);
315316
// Highlight 'decltype' and 'auto' as their underlying types.
316317
CollectExtraHighlightings(Builder).TraverseAST(C);
317318
// Highlight all decls and references coming from the AST.

0 commit comments

Comments
 (0)