|
23 | 23 | #include "clang/Basic/LangOptions.h"
|
24 | 24 | #include "clang/Basic/SourceLocation.h"
|
25 | 25 | #include "clang/Basic/SourceManager.h"
|
| 26 | +#include "clang/Tooling/Syntax/Tokens.h" |
26 | 27 | #include "llvm/ADT/None.h"
|
27 | 28 | #include "llvm/ADT/Optional.h"
|
28 | 29 | #include "llvm/ADT/STLExtras.h"
|
@@ -128,40 +129,39 @@ llvm::Optional<HighlightingKind> kindForReference(const ReferenceLoc &R) {
|
128 | 129 | return Result;
|
129 | 130 | }
|
130 | 131 |
|
| 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 | + |
131 | 146 | /// Consumes source locations and maps them to text ranges for highlightings.
|
132 | 147 | class HighlightingsBuilder {
|
133 | 148 | 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()) {} |
137 | 152 |
|
138 | 153 | void addToken(HighlightingToken T) { Tokens.push_back(T); }
|
139 | 154 |
|
140 | 155 | void addToken(SourceLocation Loc, HighlightingKind Kind) {
|
| 156 | + Loc = getHighlightableSpellingToken(Loc, SourceMgr); |
141 | 157 | if (Loc.isInvalid())
|
142 | 158 | 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); |
157 | 161 |
|
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)}); |
165 | 165 | }
|
166 | 166 |
|
167 | 167 | std::vector<HighlightingToken> collect(ParsedAST &AST) && {
|
@@ -211,6 +211,7 @@ class HighlightingsBuilder {
|
211 | 211 | }
|
212 | 212 |
|
213 | 213 | private:
|
| 214 | + const syntax::TokenBuffer &TB; |
214 | 215 | const SourceManager &SourceMgr;
|
215 | 216 | const LangOptions &LangOpts;
|
216 | 217 | std::vector<HighlightingToken> Tokens;
|
@@ -311,7 +312,7 @@ takeLine(ArrayRef<HighlightingToken> AllTokens,
|
311 | 312 | std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST) {
|
312 | 313 | auto &C = AST.getASTContext();
|
313 | 314 | // Add highlightings for AST nodes.
|
314 |
| - HighlightingsBuilder Builder(AST.getSourceManager(), C.getLangOpts()); |
| 315 | + HighlightingsBuilder Builder(AST); |
315 | 316 | // Highlight 'decltype' and 'auto' as their underlying types.
|
316 | 317 | CollectExtraHighlightings(Builder).TraverseAST(C);
|
317 | 318 | // Highlight all decls and references coming from the AST.
|
|
0 commit comments