@@ -171,18 +171,13 @@ namespace {
171
171
llvm::Optional<DocumentSymbol> declToSym (ASTContext &Ctx, const NamedDecl &ND) {
172
172
auto &SM = Ctx.getSourceManager ();
173
173
174
- SourceLocation NameLoc = nameLocation (ND, SM);
175
174
SourceLocation BeginLoc = SM.getSpellingLoc (SM.getFileLoc (ND.getBeginLoc ()));
176
175
SourceLocation EndLoc = SM.getSpellingLoc (SM.getFileLoc (ND.getEndLoc ()));
177
176
const auto SymbolRange =
178
177
toHalfOpenFileRange (SM, Ctx.getLangOpts (), {BeginLoc, EndLoc});
179
178
if (!SymbolRange)
180
179
return llvm::None;
181
180
182
- Position NameBegin = sourceLocToPosition (SM, NameLoc);
183
- Position NameEnd = sourceLocToPosition (
184
- SM, Lexer::getLocForEndOfToken (NameLoc, 0 , SM, Ctx.getLangOpts ()));
185
-
186
181
index::SymbolInfo SymInfo = index::getSymbolInfo (&ND);
187
182
// FIXME: this is not classifying constructors, destructors and operators
188
183
// correctly (they're all "methods").
@@ -194,10 +189,35 @@ llvm::Optional<DocumentSymbol> declToSym(ASTContext &Ctx, const NamedDecl &ND) {
194
189
SI.deprecated = ND.isDeprecated ();
195
190
SI.range = Range{sourceLocToPosition (SM, SymbolRange->getBegin ()),
196
191
sourceLocToPosition (SM, SymbolRange->getEnd ())};
197
- SI.selectionRange = Range{NameBegin, NameEnd};
192
+
193
+ SourceLocation NameLoc = ND.getLocation ();
194
+ SourceLocation FallbackNameLoc;
195
+ if (NameLoc.isMacroID ()) {
196
+ if (isSpelledInSource (NameLoc, SM)) {
197
+ // Prefer the spelling loc, but save the expansion loc as a fallback.
198
+ FallbackNameLoc = SM.getExpansionLoc (NameLoc);
199
+ NameLoc = SM.getSpellingLoc (NameLoc);
200
+ } else {
201
+ NameLoc = SM.getExpansionLoc (NameLoc);
202
+ }
203
+ }
204
+ auto ComputeSelectionRange = [&](SourceLocation L) -> Range {
205
+ Position NameBegin = sourceLocToPosition (SM, L);
206
+ Position NameEnd = sourceLocToPosition (
207
+ SM, Lexer::getLocForEndOfToken (L, 0 , SM, Ctx.getLangOpts ()));
208
+ return Range{NameBegin, NameEnd};
209
+ };
210
+
211
+ SI.selectionRange = ComputeSelectionRange (NameLoc);
212
+ if (!SI.range .contains (SI.selectionRange ) && FallbackNameLoc.isValid ()) {
213
+ // 'selectionRange' must be contained in 'range'. In cases where clang
214
+ // reports unrelated ranges, we first try falling back to the expansion
215
+ // loc for the selection range.
216
+ SI.selectionRange = ComputeSelectionRange (FallbackNameLoc);
217
+ }
198
218
if (!SI.range .contains (SI.selectionRange )) {
199
- // 'selectionRange' must be contained in 'range', so in cases where clang
200
- // reports unrelated ranges we need to reconcile somehow .
219
+ // If the containment relationship still doesn't hold, throw away
220
+ // 'range' and use 'selectionRange' for both .
201
221
SI.range = SI.selectionRange ;
202
222
}
203
223
return SI;
0 commit comments