xref: /llvm-project/clang-tools-extra/clangd/XRefs.cpp (revision 4740e097031d231cd39680c16a31771d22fe84c9)
1 //===--- XRefs.cpp -----------------------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "XRefs.h"
9 #include "AST.h"
10 #include "FindSymbols.h"
11 #include "FindTarget.h"
12 #include "Headers.h"
13 #include "IncludeCleaner.h"
14 #include "ParsedAST.h"
15 #include "Protocol.h"
16 #include "Quality.h"
17 #include "Selection.h"
18 #include "SourceCode.h"
19 #include "URI.h"
20 #include "clang-include-cleaner/Analysis.h"
21 #include "clang-include-cleaner/Types.h"
22 #include "index/Index.h"
23 #include "index/Merge.h"
24 #include "index/Relation.h"
25 #include "index/SymbolCollector.h"
26 #include "index/SymbolID.h"
27 #include "index/SymbolLocation.h"
28 #include "support/Logger.h"
29 #include "clang/AST/ASTContext.h"
30 #include "clang/AST/ASTTypeTraits.h"
31 #include "clang/AST/Attr.h"
32 #include "clang/AST/Attrs.inc"
33 #include "clang/AST/Decl.h"
34 #include "clang/AST/DeclCXX.h"
35 #include "clang/AST/DeclObjC.h"
36 #include "clang/AST/DeclTemplate.h"
37 #include "clang/AST/DeclVisitor.h"
38 #include "clang/AST/ExprCXX.h"
39 #include "clang/AST/RecursiveASTVisitor.h"
40 #include "clang/AST/Stmt.h"
41 #include "clang/AST/StmtCXX.h"
42 #include "clang/AST/StmtVisitor.h"
43 #include "clang/AST/Type.h"
44 #include "clang/Basic/LLVM.h"
45 #include "clang/Basic/LangOptions.h"
46 #include "clang/Basic/SourceLocation.h"
47 #include "clang/Basic/SourceManager.h"
48 #include "clang/Basic/TokenKinds.h"
49 #include "clang/Index/IndexDataConsumer.h"
50 #include "clang/Index/IndexSymbol.h"
51 #include "clang/Index/IndexingAction.h"
52 #include "clang/Index/IndexingOptions.h"
53 #include "clang/Index/USRGeneration.h"
54 #include "clang/Lex/Lexer.h"
55 #include "clang/Sema/HeuristicResolver.h"
56 #include "clang/Tooling/Syntax/Tokens.h"
57 #include "llvm/ADT/ArrayRef.h"
58 #include "llvm/ADT/DenseMap.h"
59 #include "llvm/ADT/STLExtras.h"
60 #include "llvm/ADT/ScopeExit.h"
61 #include "llvm/ADT/SmallSet.h"
62 #include "llvm/ADT/SmallVector.h"
63 #include "llvm/ADT/StringRef.h"
64 #include "llvm/Support/Casting.h"
65 #include "llvm/Support/Error.h"
66 #include "llvm/Support/ErrorHandling.h"
67 #include "llvm/Support/Path.h"
68 #include "llvm/Support/raw_ostream.h"
69 #include <optional>
70 #include <string>
71 #include <vector>
72 
73 namespace clang {
74 namespace clangd {
75 namespace {
76 
77 // Returns the single definition of the entity declared by D, if visible.
78 // In particular:
79 // - for non-redeclarable kinds (e.g. local vars), return D
80 // - for kinds that allow multiple definitions (e.g. namespaces), return nullptr
81 // Kinds of nodes that always return nullptr here will not have definitions
82 // reported by locateSymbolAt().
83 const NamedDecl *getDefinition(const NamedDecl *D) {
84   assert(D);
85   // Decl has one definition that we can find.
86   if (const auto *TD = dyn_cast<TagDecl>(D))
87     return TD->getDefinition();
88   if (const auto *VD = dyn_cast<VarDecl>(D))
89     return VD->getDefinition();
90   if (const auto *FD = dyn_cast<FunctionDecl>(D))
91     return FD->getDefinition();
92   if (const auto *CTD = dyn_cast<ClassTemplateDecl>(D))
93     if (const auto *RD = CTD->getTemplatedDecl())
94       return RD->getDefinition();
95   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
96     if (MD->isThisDeclarationADefinition())
97       return MD;
98     // Look for the method definition inside the implementation decl.
99     auto *DeclCtx = cast<Decl>(MD->getDeclContext());
100     if (DeclCtx->isInvalidDecl())
101       return nullptr;
102 
103     if (const auto *CD = dyn_cast<ObjCContainerDecl>(DeclCtx))
104       if (const auto *Impl = getCorrespondingObjCImpl(CD))
105         return Impl->getMethod(MD->getSelector(), MD->isInstanceMethod());
106   }
107   if (const auto *CD = dyn_cast<ObjCContainerDecl>(D))
108     return getCorrespondingObjCImpl(CD);
109   // Only a single declaration is allowed.
110   if (isa<ValueDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
111       isa<TemplateTemplateParmDecl>(D)) // except cases above
112     return D;
113   // Multiple definitions are allowed.
114   return nullptr; // except cases above
115 }
116 
117 void logIfOverflow(const SymbolLocation &Loc) {
118   if (Loc.Start.hasOverflow() || Loc.End.hasOverflow())
119     log("Possible overflow in symbol location: {0}", Loc);
120 }
121 
122 // Convert a SymbolLocation to LSP's Location.
123 // TUPath is used to resolve the path of URI.
124 std::optional<Location> toLSPLocation(const SymbolLocation &Loc,
125                                       llvm::StringRef TUPath) {
126   if (!Loc)
127     return std::nullopt;
128   auto LSPLoc = indexToLSPLocation(Loc, TUPath);
129   if (!LSPLoc) {
130     elog("{0}", LSPLoc.takeError());
131     return std::nullopt;
132   }
133   logIfOverflow(Loc);
134   return *LSPLoc;
135 }
136 
137 SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) {
138   SymbolLocation SymLoc;
139   URIStorage = Loc.uri.uri();
140   SymLoc.FileURI = URIStorage.c_str();
141   SymLoc.Start.setLine(Loc.range.start.line);
142   SymLoc.Start.setColumn(Loc.range.start.character);
143   SymLoc.End.setLine(Loc.range.end.line);
144   SymLoc.End.setColumn(Loc.range.end.character);
145   return SymLoc;
146 }
147 
148 // Returns the preferred location between an AST location and an index location.
149 SymbolLocation getPreferredLocation(const Location &ASTLoc,
150                                     const SymbolLocation &IdxLoc,
151                                     std::string &Scratch) {
152   // Also use a mock symbol for the index location so that other fields (e.g.
153   // definition) are not factored into the preference.
154   Symbol ASTSym, IdxSym;
155   ASTSym.ID = IdxSym.ID = SymbolID("mock_symbol_id");
156   ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, Scratch);
157   IdxSym.CanonicalDeclaration = IdxLoc;
158   auto Merged = mergeSymbol(ASTSym, IdxSym);
159   return Merged.CanonicalDeclaration;
160 }
161 
162 std::vector<std::pair<const NamedDecl *, DeclRelationSet>>
163 getDeclAtPositionWithRelations(ParsedAST &AST, SourceLocation Pos,
164                                DeclRelationSet Relations,
165                                ASTNodeKind *NodeKind = nullptr) {
166   unsigned Offset = AST.getSourceManager().getDecomposedSpellingLoc(Pos).second;
167   std::vector<std::pair<const NamedDecl *, DeclRelationSet>> Result;
168   auto ResultFromTree = [&](SelectionTree ST) {
169     if (const SelectionTree::Node *N = ST.commonAncestor()) {
170       if (NodeKind)
171         *NodeKind = N->ASTNode.getNodeKind();
172       // Attributes don't target decls, look at the
173       // thing it's attached to.
174       // We still report the original NodeKind!
175       // This makes the `override` hack work.
176       if (N->ASTNode.get<Attr>() && N->Parent)
177         N = N->Parent;
178       llvm::copy_if(allTargetDecls(N->ASTNode, AST.getHeuristicResolver()),
179                     std::back_inserter(Result),
180                     [&](auto &Entry) { return !(Entry.second & ~Relations); });
181     }
182     return !Result.empty();
183   };
184   SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Offset,
185                             Offset, ResultFromTree);
186   return Result;
187 }
188 
189 std::vector<const NamedDecl *>
190 getDeclAtPosition(ParsedAST &AST, SourceLocation Pos, DeclRelationSet Relations,
191                   ASTNodeKind *NodeKind = nullptr) {
192   std::vector<const NamedDecl *> Result;
193   for (auto &Entry :
194        getDeclAtPositionWithRelations(AST, Pos, Relations, NodeKind))
195     Result.push_back(Entry.first);
196   return Result;
197 }
198 
199 // Expects Loc to be a SpellingLocation, will bail out otherwise as it can't
200 // figure out a filename.
201 std::optional<Location> makeLocation(const ASTContext &AST, SourceLocation Loc,
202                                      llvm::StringRef TUPath) {
203   const auto &SM = AST.getSourceManager();
204   const auto F = SM.getFileEntryRefForID(SM.getFileID(Loc));
205   if (!F)
206     return std::nullopt;
207   auto FilePath = getCanonicalPath(*F, SM.getFileManager());
208   if (!FilePath) {
209     log("failed to get path!");
210     return std::nullopt;
211   }
212   Location L;
213   L.uri = URIForFile::canonicalize(*FilePath, TUPath);
214   // We call MeasureTokenLength here as TokenBuffer doesn't store spelled tokens
215   // outside the main file.
216   auto TokLen = Lexer::MeasureTokenLength(Loc, SM, AST.getLangOpts());
217   L.range = halfOpenToRange(
218       SM, CharSourceRange::getCharRange(Loc, Loc.getLocWithOffset(TokLen)));
219   return L;
220 }
221 
222 // Treat #included files as symbols, to enable go-to-definition on them.
223 std::optional<LocatedSymbol> locateFileReferent(const Position &Pos,
224                                                 ParsedAST &AST,
225                                                 llvm::StringRef MainFilePath) {
226   for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) {
227     if (!Inc.Resolved.empty() && Inc.HashLine == Pos.line) {
228       LocatedSymbol File;
229       File.Name = std::string(llvm::sys::path::filename(Inc.Resolved));
230       File.PreferredDeclaration = {
231           URIForFile::canonicalize(Inc.Resolved, MainFilePath), Range{}};
232       File.Definition = File.PreferredDeclaration;
233       // We're not going to find any further symbols on #include lines.
234       return File;
235     }
236   }
237   return std::nullopt;
238 }
239 
240 // Macros are simple: there's no declaration/definition distinction.
241 // As a consequence, there's no need to look them up in the index either.
242 std::optional<LocatedSymbol>
243 locateMacroReferent(const syntax::Token &TouchedIdentifier, ParsedAST &AST,
244                     llvm::StringRef MainFilePath) {
245   if (auto M = locateMacroAt(TouchedIdentifier, AST.getPreprocessor())) {
246     if (auto Loc =
247             makeLocation(AST.getASTContext(), M->NameLoc, MainFilePath)) {
248       LocatedSymbol Macro;
249       Macro.Name = std::string(M->Name);
250       Macro.PreferredDeclaration = *Loc;
251       Macro.Definition = Loc;
252       Macro.ID = getSymbolID(M->Name, M->Info, AST.getSourceManager());
253       return Macro;
254     }
255   }
256   return std::nullopt;
257 }
258 
259 // A wrapper around `Decl::getCanonicalDecl` to support cases where Clang's
260 // definition of a canonical declaration doesn't match up to what a programmer
261 // would expect. For example, Objective-C classes can have three types of
262 // declarations:
263 //
264 // - forward declaration(s): @class MyClass;
265 // - true declaration (interface definition): @interface MyClass ... @end
266 // - true definition (implementation): @implementation MyClass ... @end
267 //
268 // Clang will consider the forward declaration to be the canonical declaration
269 // because it is first. We actually want the class definition if it is
270 // available since that is what a programmer would consider the primary
271 // declaration to be.
272 const NamedDecl *getPreferredDecl(const NamedDecl *D) {
273   // FIXME: Canonical declarations of some symbols might refer to built-in
274   // decls with possibly-invalid source locations (e.g. global new operator).
275   // In such cases we should pick up a redecl with valid source location
276   // instead of failing.
277   D = llvm::cast<NamedDecl>(D->getCanonicalDecl());
278 
279   // Prefer Objective-C class/protocol definitions over the forward declaration.
280   if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(D))
281     if (const auto *DefinitionID = ID->getDefinition())
282       return DefinitionID;
283   if (const auto *PD = dyn_cast<ObjCProtocolDecl>(D))
284     if (const auto *DefinitionID = PD->getDefinition())
285       return DefinitionID;
286 
287   return D;
288 }
289 
290 std::vector<LocatedSymbol> findImplementors(llvm::DenseSet<SymbolID> IDs,
291                                             RelationKind Predicate,
292                                             const SymbolIndex *Index,
293                                             llvm::StringRef MainFilePath) {
294   if (IDs.empty() || !Index)
295     return {};
296   static constexpr trace::Metric FindImplementorsMetric(
297       "find_implementors", trace::Metric::Counter, "case");
298   switch (Predicate) {
299   case RelationKind::BaseOf:
300     FindImplementorsMetric.record(1, "find-base");
301     break;
302   case RelationKind::OverriddenBy:
303     FindImplementorsMetric.record(1, "find-override");
304     break;
305   }
306 
307   RelationsRequest Req;
308   Req.Predicate = Predicate;
309   Req.Subjects = std::move(IDs);
310   std::vector<LocatedSymbol> Results;
311   Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) {
312     auto DeclLoc =
313         indexToLSPLocation(Object.CanonicalDeclaration, MainFilePath);
314     if (!DeclLoc) {
315       elog("Find overrides: {0}", DeclLoc.takeError());
316       return;
317     }
318     Results.emplace_back();
319     Results.back().Name = Object.Name.str();
320     Results.back().PreferredDeclaration = *DeclLoc;
321     auto DefLoc = indexToLSPLocation(Object.Definition, MainFilePath);
322     if (!DefLoc) {
323       elog("Failed to convert location: {0}", DefLoc.takeError());
324       return;
325     }
326     Results.back().Definition = *DefLoc;
327   });
328   return Results;
329 }
330 
331 // Given LocatedSymbol results derived from the AST, query the index to obtain
332 // definitions and preferred declarations.
333 void enhanceLocatedSymbolsFromIndex(llvm::MutableArrayRef<LocatedSymbol> Result,
334                                     const SymbolIndex *Index,
335                                     llvm::StringRef MainFilePath) {
336   LookupRequest QueryRequest;
337   llvm::DenseMap<SymbolID, unsigned> ResultIndex;
338   for (unsigned I = 0; I < Result.size(); ++I) {
339     if (auto ID = Result[I].ID) {
340       ResultIndex.try_emplace(ID, I);
341       QueryRequest.IDs.insert(ID);
342     }
343   }
344   if (!Index || QueryRequest.IDs.empty())
345     return;
346   std::string Scratch;
347   Index->lookup(QueryRequest, [&](const Symbol &Sym) {
348     auto &R = Result[ResultIndex.lookup(Sym.ID)];
349 
350     if (R.Definition) { // from AST
351       // Special case: if the AST yielded a definition, then it may not be
352       // the right *declaration*. Prefer the one from the index.
353       if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration, MainFilePath))
354         R.PreferredDeclaration = *Loc;
355 
356       // We might still prefer the definition from the index, e.g. for
357       // generated symbols.
358       if (auto Loc = toLSPLocation(
359               getPreferredLocation(*R.Definition, Sym.Definition, Scratch),
360               MainFilePath))
361         R.Definition = *Loc;
362     } else {
363       R.Definition = toLSPLocation(Sym.Definition, MainFilePath);
364 
365       // Use merge logic to choose AST or index declaration.
366       if (auto Loc = toLSPLocation(
367               getPreferredLocation(R.PreferredDeclaration,
368                                    Sym.CanonicalDeclaration, Scratch),
369               MainFilePath))
370         R.PreferredDeclaration = *Loc;
371     }
372   });
373 }
374 
375 // Decls are more complicated.
376 // The AST contains at least a declaration, maybe a definition.
377 // These are up-to-date, and so generally preferred over index results.
378 // We perform a single batch index lookup to find additional definitions.
379 std::vector<LocatedSymbol>
380 locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
381                   ParsedAST &AST, llvm::StringRef MainFilePath,
382                   const SymbolIndex *Index, ASTNodeKind &NodeKind) {
383   const SourceManager &SM = AST.getSourceManager();
384   // Results follow the order of Symbols.Decls.
385   std::vector<LocatedSymbol> Result;
386 
387   static constexpr trace::Metric LocateASTReferentMetric(
388       "locate_ast_referent", trace::Metric::Counter, "case");
389   auto AddResultDecl = [&](const NamedDecl *D) {
390     D = getPreferredDecl(D);
391     auto Loc =
392         makeLocation(AST.getASTContext(), nameLocation(*D, SM), MainFilePath);
393     if (!Loc)
394       return;
395 
396     Result.emplace_back();
397     Result.back().Name = printName(AST.getASTContext(), *D);
398     Result.back().PreferredDeclaration = *Loc;
399     Result.back().ID = getSymbolID(D);
400     if (const NamedDecl *Def = getDefinition(D))
401       Result.back().Definition = makeLocation(
402           AST.getASTContext(), nameLocation(*Def, SM), MainFilePath);
403   };
404 
405   // Emit all symbol locations (declaration or definition) from AST.
406   DeclRelationSet Relations =
407       DeclRelation::TemplatePattern | DeclRelation::Alias;
408   auto Candidates =
409       getDeclAtPositionWithRelations(AST, CurLoc, Relations, &NodeKind);
410   llvm::DenseSet<SymbolID> VirtualMethods;
411   for (const auto &E : Candidates) {
412     const NamedDecl *D = E.first;
413     if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D)) {
414       // Special case: virtual void ^method() = 0: jump to all overrides.
415       // FIXME: extend it to ^virtual, unfortunately, virtual location is not
416       // saved in the AST.
417       if (CMD->isPureVirtual()) {
418         if (TouchedIdentifier && SM.getSpellingLoc(CMD->getLocation()) ==
419                                      TouchedIdentifier->location()) {
420           VirtualMethods.insert(getSymbolID(CMD));
421           LocateASTReferentMetric.record(1, "method-to-override");
422         }
423       }
424       // Special case: void foo() ^override: jump to the overridden method.
425       if (NodeKind.isSame(ASTNodeKind::getFromNodeKind<OverrideAttr>()) ||
426           NodeKind.isSame(ASTNodeKind::getFromNodeKind<FinalAttr>())) {
427         // We may be overridding multiple methods - offer them all.
428         for (const NamedDecl *ND : CMD->overridden_methods())
429           AddResultDecl(ND);
430         continue;
431       }
432     }
433 
434     // Special case: the cursor is on an alias, prefer other results.
435     // This targets "using ns::^Foo", where the target is more interesting.
436     // This does not trigger on renaming aliases:
437     //   `using Foo = ^Bar` already targets Bar via a TypeLoc
438     //   `using ^Foo = Bar` has no other results, as Underlying is filtered.
439     if (E.second & DeclRelation::Alias && Candidates.size() > 1 &&
440         // beginLoc/endLoc are a token range, so rewind the identifier we're in.
441         SM.isPointWithin(TouchedIdentifier ? TouchedIdentifier->location()
442                                            : CurLoc,
443                          D->getBeginLoc(), D->getEndLoc()))
444       continue;
445 
446     // Special case: the point of declaration of a template specialization,
447     // it's more useful to navigate to the template declaration.
448     if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
449       if (TouchedIdentifier &&
450           D->getLocation() == TouchedIdentifier->location()) {
451         LocateASTReferentMetric.record(1, "template-specialization-to-primary");
452         AddResultDecl(CTSD->getSpecializedTemplate());
453         continue;
454       }
455     }
456 
457     // Special case: if the class name is selected, also map Objective-C
458     // categories and category implementations back to their class interface.
459     //
460     // Since `TouchedIdentifier` might refer to the `ObjCCategoryImplDecl`
461     // instead of the `ObjCCategoryDecl` we intentionally check the contents
462     // of the locs when checking for class name equivalence.
463     if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D))
464       if (const auto *ID = CD->getClassInterface())
465         if (TouchedIdentifier &&
466             (CD->getLocation() == TouchedIdentifier->location() ||
467              ID->getName() == TouchedIdentifier->text(SM))) {
468           LocateASTReferentMetric.record(1, "objc-category-to-class");
469           AddResultDecl(ID);
470         }
471 
472     LocateASTReferentMetric.record(1, "regular");
473     // Otherwise the target declaration is the right one.
474     AddResultDecl(D);
475   }
476   enhanceLocatedSymbolsFromIndex(Result, Index, MainFilePath);
477 
478   auto Overrides = findImplementors(VirtualMethods, RelationKind::OverriddenBy,
479                                     Index, MainFilePath);
480   Result.insert(Result.end(), Overrides.begin(), Overrides.end());
481   return Result;
482 }
483 
484 std::vector<LocatedSymbol> locateSymbolForType(const ParsedAST &AST,
485                                                const QualType &Type,
486                                                const SymbolIndex *Index) {
487   const auto &SM = AST.getSourceManager();
488   auto MainFilePath = AST.tuPath();
489 
490   // FIXME: this sends unique_ptr<Foo> to unique_ptr<T>.
491   // Likely it would be better to send it to Foo (heuristically) or to both.
492   auto Decls = targetDecl(DynTypedNode::create(Type.getNonReferenceType()),
493                           DeclRelation::TemplatePattern | DeclRelation::Alias,
494                           AST.getHeuristicResolver());
495   if (Decls.empty())
496     return {};
497 
498   std::vector<LocatedSymbol> Results;
499   const auto &ASTContext = AST.getASTContext();
500 
501   for (const NamedDecl *D : Decls) {
502     D = getPreferredDecl(D);
503 
504     auto Loc = makeLocation(ASTContext, nameLocation(*D, SM), MainFilePath);
505     if (!Loc)
506       continue;
507 
508     Results.emplace_back();
509     Results.back().Name = printName(ASTContext, *D);
510     Results.back().PreferredDeclaration = *Loc;
511     Results.back().ID = getSymbolID(D);
512     if (const NamedDecl *Def = getDefinition(D))
513       Results.back().Definition =
514           makeLocation(ASTContext, nameLocation(*Def, SM), MainFilePath);
515   }
516   enhanceLocatedSymbolsFromIndex(Results, Index, MainFilePath);
517 
518   return Results;
519 }
520 
521 bool tokenSpelledAt(SourceLocation SpellingLoc, const syntax::TokenBuffer &TB) {
522   auto ExpandedTokens = TB.expandedTokens(
523       TB.sourceManager().getMacroArgExpandedLocation(SpellingLoc));
524   return !ExpandedTokens.empty();
525 }
526 
527 llvm::StringRef sourcePrefix(SourceLocation Loc, const SourceManager &SM) {
528   auto D = SM.getDecomposedLoc(Loc);
529   bool Invalid = false;
530   llvm::StringRef Buf = SM.getBufferData(D.first, &Invalid);
531   if (Invalid || D.second > Buf.size())
532     return "";
533   return Buf.substr(0, D.second);
534 }
535 
536 bool isDependentName(ASTNodeKind NodeKind) {
537   return NodeKind.isSame(ASTNodeKind::getFromNodeKind<OverloadExpr>()) ||
538          NodeKind.isSame(
539              ASTNodeKind::getFromNodeKind<CXXDependentScopeMemberExpr>()) ||
540          NodeKind.isSame(
541              ASTNodeKind::getFromNodeKind<DependentScopeDeclRefExpr>());
542 }
543 
544 } // namespace
545 
546 std::vector<LocatedSymbol> locateSymbolTextually(const SpelledWord &Word,
547                                                  ParsedAST &AST,
548                                                  const SymbolIndex *Index,
549                                                  llvm::StringRef MainFilePath,
550                                                  ASTNodeKind NodeKind) {
551   // Don't use heuristics if this is a real identifier, or not an
552   // identifier.
553   // Exception: dependent names, because those may have useful textual
554   // matches that AST-based heuristics cannot find.
555   if ((Word.ExpandedToken && !isDependentName(NodeKind)) ||
556       !Word.LikelyIdentifier || !Index)
557     return {};
558   // We don't want to handle words in string literals. (It'd be nice to list
559   // *allowed* token kinds explicitly, but comment Tokens aren't retained).
560   if (Word.PartOfSpelledToken &&
561       isStringLiteral(Word.PartOfSpelledToken->kind()))
562     return {};
563 
564   const auto &SM = AST.getSourceManager();
565   // Look up the selected word in the index.
566   FuzzyFindRequest Req;
567   Req.Query = Word.Text.str();
568   Req.ProximityPaths = {MainFilePath.str()};
569   // Find the namespaces to query by lexing the file.
570   Req.Scopes =
571       visibleNamespaces(sourcePrefix(Word.Location, SM), AST.getLangOpts());
572   // FIXME: For extra strictness, consider AnyScope=false.
573   Req.AnyScope = true;
574   // We limit the results to 3 further below. This limit is to avoid fetching
575   // too much data, while still likely having enough for 3 results to remain
576   // after additional filtering.
577   Req.Limit = 10;
578   bool TooMany = false;
579   using ScoredLocatedSymbol = std::pair<float, LocatedSymbol>;
580   std::vector<ScoredLocatedSymbol> ScoredResults;
581   Index->fuzzyFind(Req, [&](const Symbol &Sym) {
582     // Only consider exact name matches, including case.
583     // This is to avoid too many false positives.
584     // We could relax this in the future (e.g. to allow for typos) if we make
585     // the query more accurate by other means.
586     if (Sym.Name != Word.Text)
587       return;
588 
589     // Exclude constructor results. They have the same name as the class,
590     // but we don't have enough context to prefer them over the class.
591     if (Sym.SymInfo.Kind == index::SymbolKind::Constructor)
592       return;
593 
594     auto MaybeDeclLoc =
595         indexToLSPLocation(Sym.CanonicalDeclaration, MainFilePath);
596     if (!MaybeDeclLoc) {
597       log("locateSymbolNamedTextuallyAt: {0}", MaybeDeclLoc.takeError());
598       return;
599     }
600     LocatedSymbol Located;
601     Located.PreferredDeclaration = *MaybeDeclLoc;
602     Located.Name = (Sym.Name + Sym.TemplateSpecializationArgs).str();
603     Located.ID = Sym.ID;
604     if (Sym.Definition) {
605       auto MaybeDefLoc = indexToLSPLocation(Sym.Definition, MainFilePath);
606       if (!MaybeDefLoc) {
607         log("locateSymbolNamedTextuallyAt: {0}", MaybeDefLoc.takeError());
608         return;
609       }
610       Located.PreferredDeclaration = *MaybeDefLoc;
611       Located.Definition = *MaybeDefLoc;
612     }
613 
614     if (ScoredResults.size() >= 5) {
615       // If we have more than 5 results, don't return anything,
616       // as confidence is too low.
617       // FIXME: Alternatively, try a stricter query?
618       TooMany = true;
619       return;
620     }
621 
622     SymbolQualitySignals Quality;
623     Quality.merge(Sym);
624     SymbolRelevanceSignals Relevance;
625     Relevance.Name = Sym.Name;
626     Relevance.Query = SymbolRelevanceSignals::Generic;
627     Relevance.merge(Sym);
628     auto Score = evaluateSymbolAndRelevance(Quality.evaluateHeuristics(),
629                                             Relevance.evaluateHeuristics());
630     dlog("locateSymbolNamedTextuallyAt: {0}{1} = {2}\n{3}{4}\n", Sym.Scope,
631          Sym.Name, Score, Quality, Relevance);
632 
633     ScoredResults.push_back({Score, std::move(Located)});
634   });
635 
636   if (TooMany) {
637     vlog("Heuristic index lookup for {0} returned too many candidates, ignored",
638          Word.Text);
639     return {};
640   }
641 
642   llvm::sort(ScoredResults,
643              [](const ScoredLocatedSymbol &A, const ScoredLocatedSymbol &B) {
644                return A.first > B.first;
645              });
646   std::vector<LocatedSymbol> Results;
647   for (auto &Res : std::move(ScoredResults))
648     Results.push_back(std::move(Res.second));
649   if (Results.empty())
650     vlog("No heuristic index definition for {0}", Word.Text);
651   else
652     log("Found definition heuristically in index for {0}", Word.Text);
653   return Results;
654 }
655 
656 const syntax::Token *findNearbyIdentifier(const SpelledWord &Word,
657                                           const syntax::TokenBuffer &TB) {
658   // Don't use heuristics if this is a real identifier.
659   // Unlikely identifiers are OK if they were used as identifiers nearby.
660   if (Word.ExpandedToken)
661     return nullptr;
662   // We don't want to handle words in string literals. (It'd be nice to list
663   // *allowed* token kinds explicitly, but comment Tokens aren't retained).
664   if (Word.PartOfSpelledToken &&
665       isStringLiteral(Word.PartOfSpelledToken->kind()))
666     return {};
667 
668   const SourceManager &SM = TB.sourceManager();
669   // We prefer the closest possible token, line-wise. Backwards is penalized.
670   // Ties are implicitly broken by traversal order (first-one-wins).
671   auto File = SM.getFileID(Word.Location);
672   unsigned WordLine = SM.getSpellingLineNumber(Word.Location);
673   auto Cost = [&](SourceLocation Loc) -> unsigned {
674     assert(SM.getFileID(Loc) == File && "spelled token in wrong file?");
675     unsigned Line = SM.getSpellingLineNumber(Loc);
676     return Line >= WordLine ? Line - WordLine : 2 * (WordLine - Line);
677   };
678   const syntax::Token *BestTok = nullptr;
679   unsigned BestCost = -1;
680   // Search bounds are based on word length:
681   // - forward: 2^N lines
682   // - backward: 2^(N-1) lines.
683   unsigned MaxDistance =
684       1U << std::min<unsigned>(Word.Text.size(),
685                                std::numeric_limits<unsigned>::digits - 1);
686   // Line number for SM.translateLineCol() should be one-based, also
687   // SM.translateLineCol() can handle line number greater than
688   // number of lines in the file.
689   // - LineMin = max(1, WordLine + 1 - 2^(N-1))
690   // - LineMax = WordLine + 1 + 2^N
691   unsigned LineMin =
692       WordLine + 1 <= MaxDistance / 2 ? 1 : WordLine + 1 - MaxDistance / 2;
693   unsigned LineMax = WordLine + 1 + MaxDistance;
694   SourceLocation LocMin = SM.translateLineCol(File, LineMin, 1);
695   assert(LocMin.isValid());
696   SourceLocation LocMax = SM.translateLineCol(File, LineMax, 1);
697   assert(LocMax.isValid());
698 
699   // Updates BestTok and BestCost if Tok is a good candidate.
700   // May return true if the cost is too high for this token.
701   auto Consider = [&](const syntax::Token &Tok) {
702     if (Tok.location() < LocMin || Tok.location() > LocMax)
703       return true; // we are too far from the word, break the outer loop.
704     if (!(Tok.kind() == tok::identifier && Tok.text(SM) == Word.Text))
705       return false;
706     // No point guessing the same location we started with.
707     if (Tok.location() == Word.Location)
708       return false;
709     // We've done cheap checks, compute cost so we can break the caller's loop.
710     unsigned TokCost = Cost(Tok.location());
711     if (TokCost >= BestCost)
712       return true; // causes the outer loop to break.
713     // Allow locations that might be part of the AST, and macros (even if empty)
714     // but not things like disabled preprocessor sections.
715     if (!(tokenSpelledAt(Tok.location(), TB) || TB.expansionStartingAt(&Tok)))
716       return false;
717     // We already verified this token is an improvement.
718     BestCost = TokCost;
719     BestTok = &Tok;
720     return false;
721   };
722   auto SpelledTokens = TB.spelledTokens(File);
723   // Find where the word occurred in the token stream, to search forward & back.
724   auto *I = llvm::partition_point(SpelledTokens, [&](const syntax::Token &T) {
725     assert(SM.getFileID(T.location()) == SM.getFileID(Word.Location));
726     return T.location() < Word.Location; // Comparison OK: same file.
727   });
728   // Search for matches after the cursor.
729   for (const syntax::Token &Tok : llvm::ArrayRef(I, SpelledTokens.end()))
730     if (Consider(Tok))
731       break; // costs of later tokens are greater...
732   // Search for matches before the cursor.
733   for (const syntax::Token &Tok :
734        llvm::reverse(llvm::ArrayRef(SpelledTokens.begin(), I)))
735     if (Consider(Tok))
736       break;
737 
738   if (BestTok)
739     vlog(
740         "Word {0} under cursor {1} isn't a token (after PP), trying nearby {2}",
741         Word.Text, Word.Location.printToString(SM),
742         BestTok->location().printToString(SM));
743 
744   return BestTok;
745 }
746 
747 std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
748                                           const SymbolIndex *Index) {
749   const auto &SM = AST.getSourceManager();
750   auto MainFilePath = AST.tuPath();
751 
752   if (auto File = locateFileReferent(Pos, AST, MainFilePath))
753     return {std::move(*File)};
754 
755   auto CurLoc = sourceLocationInMainFile(SM, Pos);
756   if (!CurLoc) {
757     elog("locateSymbolAt failed to convert position to source location: {0}",
758          CurLoc.takeError());
759     return {};
760   }
761 
762   const syntax::Token *TouchedIdentifier = nullptr;
763   auto TokensTouchingCursor =
764       syntax::spelledTokensTouching(*CurLoc, AST.getTokens());
765   for (const syntax::Token &Tok : TokensTouchingCursor) {
766     if (Tok.kind() == tok::identifier) {
767       if (auto Macro = locateMacroReferent(Tok, AST, MainFilePath))
768         // Don't look at the AST or index if we have a macro result.
769         // (We'd just return declarations referenced from the macro's
770         // expansion.)
771         return {*std::move(Macro)};
772 
773       TouchedIdentifier = &Tok;
774       break;
775     }
776 
777     if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) {
778       // go-to-definition on auto should find the definition of the deduced
779       // type, if possible
780       if (auto Deduced = getDeducedType(AST.getASTContext(), Tok.location())) {
781         auto LocSym = locateSymbolForType(AST, *Deduced, Index);
782         if (!LocSym.empty())
783           return LocSym;
784       }
785     }
786   }
787 
788   ASTNodeKind NodeKind;
789   auto ASTResults = locateASTReferent(*CurLoc, TouchedIdentifier, AST,
790                                       MainFilePath, Index, NodeKind);
791   if (!ASTResults.empty())
792     return ASTResults;
793 
794   // If the cursor can't be resolved directly, try fallback strategies.
795   auto Word =
796       SpelledWord::touching(*CurLoc, AST.getTokens(), AST.getLangOpts());
797   if (Word) {
798     // Is the same word nearby a real identifier that might refer to something?
799     if (const syntax::Token *NearbyIdent =
800             findNearbyIdentifier(*Word, AST.getTokens())) {
801       if (auto Macro = locateMacroReferent(*NearbyIdent, AST, MainFilePath)) {
802         log("Found macro definition heuristically using nearby identifier {0}",
803             Word->Text);
804         return {*std::move(Macro)};
805       }
806       ASTResults = locateASTReferent(NearbyIdent->location(), NearbyIdent, AST,
807                                      MainFilePath, Index, NodeKind);
808       if (!ASTResults.empty()) {
809         log("Found definition heuristically using nearby identifier {0}",
810             NearbyIdent->text(SM));
811         return ASTResults;
812       }
813       vlog("No definition found using nearby identifier {0} at {1}", Word->Text,
814            Word->Location.printToString(SM));
815     }
816     // No nearby word, or it didn't refer to anything either. Try the index.
817     auto TextualResults =
818         locateSymbolTextually(*Word, AST, Index, MainFilePath, NodeKind);
819     if (!TextualResults.empty())
820       return TextualResults;
821   }
822 
823   return {};
824 }
825 
826 std::vector<DocumentLink> getDocumentLinks(ParsedAST &AST) {
827   const auto &SM = AST.getSourceManager();
828 
829   std::vector<DocumentLink> Result;
830   for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) {
831     if (Inc.Resolved.empty())
832       continue;
833     auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset);
834     const auto *HashTok = AST.getTokens().spelledTokenContaining(HashLoc);
835     assert(HashTok && "got inclusion at wrong offset");
836     const auto *IncludeTok = std::next(HashTok);
837     const auto *FileTok = std::next(IncludeTok);
838     // FileTok->range is not sufficient here, as raw lexing wouldn't yield
839     // correct tokens for angled filenames. Hence we explicitly use
840     // Inc.Written's length.
841     auto FileRange =
842         syntax::FileRange(SM, FileTok->location(), Inc.Written.length())
843             .toCharRange(SM);
844 
845     Result.push_back(
846         DocumentLink({halfOpenToRange(SM, FileRange),
847                       URIForFile::canonicalize(Inc.Resolved, AST.tuPath())}));
848   }
849 
850   return Result;
851 }
852 
853 namespace {
854 
855 /// Collects references to symbols within the main file.
856 class ReferenceFinder : public index::IndexDataConsumer {
857 public:
858   struct Reference {
859     syntax::Token SpelledTok;
860     index::SymbolRoleSet Role;
861     const Decl *Container;
862 
863     Range range(const SourceManager &SM) const {
864       return halfOpenToRange(SM, SpelledTok.range(SM).toCharRange(SM));
865     }
866   };
867 
868   ReferenceFinder(const ParsedAST &AST,
869                   const llvm::ArrayRef<const NamedDecl *> Targets,
870                   bool PerToken)
871       : PerToken(PerToken), AST(AST) {
872     for (const NamedDecl *ND : Targets)
873       TargetDecls.insert(ND->getCanonicalDecl());
874   }
875 
876   std::vector<Reference> take() && {
877     llvm::sort(References, [](const Reference &L, const Reference &R) {
878       auto LTok = L.SpelledTok.location();
879       auto RTok = R.SpelledTok.location();
880       return std::tie(LTok, L.Role) < std::tie(RTok, R.Role);
881     });
882     // We sometimes see duplicates when parts of the AST get traversed twice.
883     References.erase(std::unique(References.begin(), References.end(),
884                                  [](const Reference &L, const Reference &R) {
885                                    auto LTok = L.SpelledTok.location();
886                                    auto RTok = R.SpelledTok.location();
887                                    return std::tie(LTok, L.Role) ==
888                                           std::tie(RTok, R.Role);
889                                  }),
890                      References.end());
891     return std::move(References);
892   }
893 
894   bool
895   handleDeclOccurrence(const Decl *D, index::SymbolRoleSet Roles,
896                        llvm::ArrayRef<index::SymbolRelation> Relations,
897                        SourceLocation Loc,
898                        index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
899     if (!TargetDecls.contains(D->getCanonicalDecl()))
900       return true;
901     const SourceManager &SM = AST.getSourceManager();
902     if (!isInsideMainFile(Loc, SM))
903       return true;
904     const auto &TB = AST.getTokens();
905 
906     llvm::SmallVector<SourceLocation, 1> Locs;
907     if (PerToken) {
908       // Check whether this is one of the few constructs where the reference
909       // can be split over several tokens.
910       if (auto *OME = llvm::dyn_cast_or_null<ObjCMessageExpr>(ASTNode.OrigE)) {
911         OME->getSelectorLocs(Locs);
912       } else if (auto *OMD =
913                      llvm::dyn_cast_or_null<ObjCMethodDecl>(ASTNode.OrigD)) {
914         OMD->getSelectorLocs(Locs);
915       }
916       // Sanity check: we expect the *first* token to match the reported loc.
917       // Otherwise, maybe it was e.g. some other kind of reference to a Decl.
918       if (!Locs.empty() && Locs.front() != Loc)
919         Locs.clear(); // First token doesn't match, assume our guess was wrong.
920     }
921     if (Locs.empty())
922       Locs.push_back(Loc);
923 
924     SymbolCollector::Options CollectorOpts;
925     CollectorOpts.CollectMainFileSymbols = true;
926     for (SourceLocation L : Locs) {
927       L = SM.getFileLoc(L);
928       if (const auto *Tok = TB.spelledTokenContaining(L))
929         References.push_back(
930             {*Tok, Roles,
931              SymbolCollector::getRefContainer(ASTNode.Parent, CollectorOpts)});
932     }
933     return true;
934   }
935 
936 private:
937   bool PerToken; // If true, report 3 references for split ObjC selector names.
938   std::vector<Reference> References;
939   const ParsedAST &AST;
940   llvm::DenseSet<const Decl *> TargetDecls;
941 };
942 
943 std::vector<ReferenceFinder::Reference>
944 findRefs(const llvm::ArrayRef<const NamedDecl *> TargetDecls, ParsedAST &AST,
945          bool PerToken) {
946   ReferenceFinder RefFinder(AST, TargetDecls, PerToken);
947   index::IndexingOptions IndexOpts;
948   IndexOpts.SystemSymbolFilter =
949       index::IndexingOptions::SystemSymbolFilterKind::All;
950   IndexOpts.IndexFunctionLocals = true;
951   IndexOpts.IndexParametersInDeclarations = true;
952   IndexOpts.IndexTemplateParameters = true;
953   indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(),
954                      AST.getLocalTopLevelDecls(), RefFinder, IndexOpts);
955   return std::move(RefFinder).take();
956 }
957 
958 const Stmt *getFunctionBody(DynTypedNode N) {
959   if (const auto *FD = N.get<FunctionDecl>())
960     return FD->getBody();
961   if (const auto *FD = N.get<BlockDecl>())
962     return FD->getBody();
963   if (const auto *FD = N.get<LambdaExpr>())
964     return FD->getBody();
965   if (const auto *FD = N.get<ObjCMethodDecl>())
966     return FD->getBody();
967   return nullptr;
968 }
969 
970 const Stmt *getLoopBody(DynTypedNode N) {
971   if (const auto *LS = N.get<ForStmt>())
972     return LS->getBody();
973   if (const auto *LS = N.get<CXXForRangeStmt>())
974     return LS->getBody();
975   if (const auto *LS = N.get<WhileStmt>())
976     return LS->getBody();
977   if (const auto *LS = N.get<DoStmt>())
978     return LS->getBody();
979   return nullptr;
980 }
981 
982 // AST traversal to highlight control flow statements under some root.
983 // Once we hit further control flow we prune the tree (or at least restrict
984 // what we highlight) so we capture e.g. breaks from the outer loop only.
985 class FindControlFlow : public RecursiveASTVisitor<FindControlFlow> {
986   // Types of control-flow statements we might highlight.
987   enum Target {
988     Break = 1,
989     Continue = 2,
990     Return = 4,
991     Case = 8,
992     Throw = 16,
993     Goto = 32,
994     All = Break | Continue | Return | Case | Throw | Goto,
995   };
996   int Ignore = 0;     // bitmask of Target - what are we *not* highlighting?
997   SourceRange Bounds; // Half-open, restricts reported targets.
998   std::vector<SourceLocation> &Result;
999   const SourceManager &SM;
1000 
1001   // Masks out targets for a traversal into D.
1002   // Traverses the subtree using Delegate() if any targets remain.
1003   template <typename Func>
1004   bool filterAndTraverse(DynTypedNode D, const Func &Delegate) {
1005     auto RestoreIgnore = llvm::make_scope_exit(
1006         [OldIgnore(Ignore), this] { Ignore = OldIgnore; });
1007     if (getFunctionBody(D))
1008       Ignore = All;
1009     else if (getLoopBody(D))
1010       Ignore |= Continue | Break;
1011     else if (D.get<SwitchStmt>())
1012       Ignore |= Break | Case;
1013     // Prune tree if we're not looking for anything.
1014     return (Ignore == All) ? true : Delegate();
1015   }
1016 
1017   void found(Target T, SourceLocation Loc) {
1018     if (T & Ignore)
1019       return;
1020     if (SM.isBeforeInTranslationUnit(Loc, Bounds.getBegin()) ||
1021         SM.isBeforeInTranslationUnit(Bounds.getEnd(), Loc))
1022       return;
1023     Result.push_back(Loc);
1024   }
1025 
1026 public:
1027   FindControlFlow(SourceRange Bounds, std::vector<SourceLocation> &Result,
1028                   const SourceManager &SM)
1029       : Bounds(Bounds), Result(Result), SM(SM) {}
1030 
1031   // When traversing function or loops, limit targets to those that still
1032   // refer to the original root.
1033   bool TraverseDecl(Decl *D) {
1034     return !D || filterAndTraverse(DynTypedNode::create(*D), [&] {
1035       return RecursiveASTVisitor::TraverseDecl(D);
1036     });
1037   }
1038   bool TraverseStmt(Stmt *S) {
1039     return !S || filterAndTraverse(DynTypedNode::create(*S), [&] {
1040       return RecursiveASTVisitor::TraverseStmt(S);
1041     });
1042   }
1043 
1044   // Add leaves that we found and want.
1045   bool VisitReturnStmt(ReturnStmt *R) {
1046     found(Return, R->getReturnLoc());
1047     return true;
1048   }
1049   bool VisitBreakStmt(BreakStmt *B) {
1050     found(Break, B->getBreakLoc());
1051     return true;
1052   }
1053   bool VisitContinueStmt(ContinueStmt *C) {
1054     found(Continue, C->getContinueLoc());
1055     return true;
1056   }
1057   bool VisitSwitchCase(SwitchCase *C) {
1058     found(Case, C->getKeywordLoc());
1059     return true;
1060   }
1061   bool VisitCXXThrowExpr(CXXThrowExpr *T) {
1062     found(Throw, T->getThrowLoc());
1063     return true;
1064   }
1065   bool VisitGotoStmt(GotoStmt *G) {
1066     // Goto is interesting if its target is outside the root.
1067     if (const auto *LD = G->getLabel()) {
1068       if (SM.isBeforeInTranslationUnit(LD->getLocation(), Bounds.getBegin()) ||
1069           SM.isBeforeInTranslationUnit(Bounds.getEnd(), LD->getLocation()))
1070         found(Goto, G->getGotoLoc());
1071     }
1072     return true;
1073   }
1074 };
1075 
1076 // Given a location within a switch statement, return the half-open range that
1077 // covers the case it's contained in.
1078 // We treat `case X: case Y: ...` as one case, and assume no other fallthrough.
1079 SourceRange findCaseBounds(const SwitchStmt &Switch, SourceLocation Loc,
1080                            const SourceManager &SM) {
1081   // Cases are not stored in order, sort them first.
1082   // (In fact they seem to be stored in reverse order, don't rely on this)
1083   std::vector<const SwitchCase *> Cases;
1084   for (const SwitchCase *Case = Switch.getSwitchCaseList(); Case;
1085        Case = Case->getNextSwitchCase())
1086     Cases.push_back(Case);
1087   llvm::sort(Cases, [&](const SwitchCase *L, const SwitchCase *R) {
1088     return SM.isBeforeInTranslationUnit(L->getKeywordLoc(), R->getKeywordLoc());
1089   });
1090 
1091   // Find the first case after the target location, the end of our range.
1092   auto CaseAfter = llvm::partition_point(Cases, [&](const SwitchCase *C) {
1093     return !SM.isBeforeInTranslationUnit(Loc, C->getKeywordLoc());
1094   });
1095   SourceLocation End = CaseAfter == Cases.end() ? Switch.getEndLoc()
1096                                                 : (*CaseAfter)->getKeywordLoc();
1097 
1098   // Our target can be before the first case - cases are optional!
1099   if (CaseAfter == Cases.begin())
1100     return SourceRange(Switch.getBeginLoc(), End);
1101   // The start of our range is usually the previous case, but...
1102   auto CaseBefore = std::prev(CaseAfter);
1103   // ... rewind CaseBefore to the first in a `case A: case B: ...` sequence.
1104   while (CaseBefore != Cases.begin() &&
1105          (*std::prev(CaseBefore))->getSubStmt() == *CaseBefore)
1106     --CaseBefore;
1107   return SourceRange((*CaseBefore)->getKeywordLoc(), End);
1108 }
1109 
1110 // Returns the locations of control flow statements related to N. e.g.:
1111 //   for    => branches: break/continue/return/throw
1112 //   break  => controlling loop (forwhile/do), and its related control flow
1113 //   return => all returns/throws from the same function
1114 // When an inner block is selected, we include branches bound to outer blocks
1115 // as these are exits from the inner block. e.g. return in a for loop.
1116 // FIXME: We don't analyze catch blocks, throw is treated the same as return.
1117 std::vector<SourceLocation> relatedControlFlow(const SelectionTree::Node &N) {
1118   const SourceManager &SM =
1119       N.getDeclContext().getParentASTContext().getSourceManager();
1120   std::vector<SourceLocation> Result;
1121 
1122   // First, check if we're at a node that can resolve to a root.
1123   enum class Cur { None, Break, Continue, Return, Case, Throw } Cursor;
1124   if (N.ASTNode.get<BreakStmt>()) {
1125     Cursor = Cur::Break;
1126   } else if (N.ASTNode.get<ContinueStmt>()) {
1127     Cursor = Cur::Continue;
1128   } else if (N.ASTNode.get<ReturnStmt>()) {
1129     Cursor = Cur::Return;
1130   } else if (N.ASTNode.get<CXXThrowExpr>()) {
1131     Cursor = Cur::Throw;
1132   } else if (N.ASTNode.get<SwitchCase>()) {
1133     Cursor = Cur::Case;
1134   } else if (const GotoStmt *GS = N.ASTNode.get<GotoStmt>()) {
1135     // We don't know what root to associate with, but highlight the goto/label.
1136     Result.push_back(GS->getGotoLoc());
1137     if (const auto *LD = GS->getLabel())
1138       Result.push_back(LD->getLocation());
1139     Cursor = Cur::None;
1140   } else {
1141     Cursor = Cur::None;
1142   }
1143 
1144   const Stmt *Root = nullptr; // Loop or function body to traverse.
1145   SourceRange Bounds;
1146   // Look up the tree for a root (or just at this node if we didn't find a leaf)
1147   for (const auto *P = &N; P; P = P->Parent) {
1148     // return associates with enclosing function
1149     if (const Stmt *FunctionBody = getFunctionBody(P->ASTNode)) {
1150       if (Cursor == Cur::Return || Cursor == Cur::Throw) {
1151         Root = FunctionBody;
1152       }
1153       break; // other leaves don't cross functions.
1154     }
1155     // break/continue associate with enclosing loop.
1156     if (const Stmt *LoopBody = getLoopBody(P->ASTNode)) {
1157       if (Cursor == Cur::None || Cursor == Cur::Break ||
1158           Cursor == Cur::Continue) {
1159         Root = LoopBody;
1160         // Highlight the loop keyword itself.
1161         // FIXME: for do-while, this only covers the `do`..
1162         Result.push_back(P->ASTNode.getSourceRange().getBegin());
1163         break;
1164       }
1165     }
1166     // For switches, users think of case statements as control flow blocks.
1167     // We highlight only occurrences surrounded by the same case.
1168     // We don't detect fallthrough (other than 'case X, case Y').
1169     if (const auto *SS = P->ASTNode.get<SwitchStmt>()) {
1170       if (Cursor == Cur::Break || Cursor == Cur::Case) {
1171         Result.push_back(SS->getSwitchLoc()); // Highlight the switch.
1172         Root = SS->getBody();
1173         // Limit to enclosing case, if there is one.
1174         Bounds = findCaseBounds(*SS, N.ASTNode.getSourceRange().getBegin(), SM);
1175         break;
1176       }
1177     }
1178     // If we didn't start at some interesting node, we're done.
1179     if (Cursor == Cur::None)
1180       break;
1181   }
1182   if (Root) {
1183     if (!Bounds.isValid())
1184       Bounds = Root->getSourceRange();
1185     FindControlFlow(Bounds, Result, SM).TraverseStmt(const_cast<Stmt *>(Root));
1186   }
1187   return Result;
1188 }
1189 
1190 DocumentHighlight toHighlight(const ReferenceFinder::Reference &Ref,
1191                               const SourceManager &SM) {
1192   DocumentHighlight DH;
1193   DH.range = Ref.range(SM);
1194   if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Write))
1195     DH.kind = DocumentHighlightKind::Write;
1196   else if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Read))
1197     DH.kind = DocumentHighlightKind::Read;
1198   else
1199     DH.kind = DocumentHighlightKind::Text;
1200   return DH;
1201 }
1202 
1203 std::optional<DocumentHighlight> toHighlight(SourceLocation Loc,
1204                                              const syntax::TokenBuffer &TB) {
1205   Loc = TB.sourceManager().getFileLoc(Loc);
1206   if (const auto *Tok = TB.spelledTokenContaining(Loc)) {
1207     DocumentHighlight Result;
1208     Result.range = halfOpenToRange(
1209         TB.sourceManager(),
1210         CharSourceRange::getCharRange(Tok->location(), Tok->endLocation()));
1211     return Result;
1212   }
1213   return std::nullopt;
1214 }
1215 
1216 } // namespace
1217 
1218 std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
1219                                                       Position Pos) {
1220   const SourceManager &SM = AST.getSourceManager();
1221   // FIXME: show references to macro within file?
1222   auto CurLoc = sourceLocationInMainFile(SM, Pos);
1223   if (!CurLoc) {
1224     llvm::consumeError(CurLoc.takeError());
1225     return {};
1226   }
1227   std::vector<DocumentHighlight> Result;
1228   auto TryTree = [&](SelectionTree ST) {
1229     if (const SelectionTree::Node *N = ST.commonAncestor()) {
1230       DeclRelationSet Relations =
1231           DeclRelation::TemplatePattern | DeclRelation::Alias;
1232       auto TargetDecls =
1233           targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
1234       if (!TargetDecls.empty()) {
1235         // FIXME: we may get multiple DocumentHighlights with the same location
1236         // and different kinds, deduplicate them.
1237         for (const auto &Ref : findRefs(TargetDecls, AST, /*PerToken=*/true))
1238           Result.push_back(toHighlight(Ref, SM));
1239         return true;
1240       }
1241       auto ControlFlow = relatedControlFlow(*N);
1242       if (!ControlFlow.empty()) {
1243         for (SourceLocation Loc : ControlFlow)
1244           if (auto Highlight = toHighlight(Loc, AST.getTokens()))
1245             Result.push_back(std::move(*Highlight));
1246         return true;
1247       }
1248     }
1249     return false;
1250   };
1251 
1252   unsigned Offset =
1253       AST.getSourceManager().getDecomposedSpellingLoc(*CurLoc).second;
1254   SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Offset,
1255                             Offset, TryTree);
1256   return Result;
1257 }
1258 
1259 std::vector<LocatedSymbol> findImplementations(ParsedAST &AST, Position Pos,
1260                                                const SymbolIndex *Index) {
1261   // We rely on index to find the implementations in subclasses.
1262   // FIXME: Index can be stale, so we may loose some latest results from the
1263   // main file.
1264   if (!Index)
1265     return {};
1266   const SourceManager &SM = AST.getSourceManager();
1267   auto CurLoc = sourceLocationInMainFile(SM, Pos);
1268   if (!CurLoc) {
1269     elog("Failed to convert position to source location: {0}",
1270          CurLoc.takeError());
1271     return {};
1272   }
1273   DeclRelationSet Relations =
1274       DeclRelation::TemplatePattern | DeclRelation::Alias;
1275   llvm::DenseSet<SymbolID> IDs;
1276   RelationKind QueryKind = RelationKind::OverriddenBy;
1277   for (const NamedDecl *ND : getDeclAtPosition(AST, *CurLoc, Relations)) {
1278     if (const auto *CXXMD = llvm::dyn_cast<CXXMethodDecl>(ND)) {
1279       if (CXXMD->isVirtual()) {
1280         IDs.insert(getSymbolID(ND));
1281         QueryKind = RelationKind::OverriddenBy;
1282       }
1283     } else if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
1284       IDs.insert(getSymbolID(RD));
1285       QueryKind = RelationKind::BaseOf;
1286     }
1287   }
1288   return findImplementors(std::move(IDs), QueryKind, Index, AST.tuPath());
1289 }
1290 
1291 namespace {
1292 // Recursively finds all the overridden methods of `CMD` in complete type
1293 // hierarchy.
1294 void getOverriddenMethods(const CXXMethodDecl *CMD,
1295                           llvm::DenseSet<SymbolID> &OverriddenMethods) {
1296   if (!CMD)
1297     return;
1298   for (const CXXMethodDecl *Base : CMD->overridden_methods()) {
1299     if (auto ID = getSymbolID(Base))
1300       OverriddenMethods.insert(ID);
1301     getOverriddenMethods(Base, OverriddenMethods);
1302   }
1303 }
1304 
1305 std::optional<std::string>
1306 stringifyContainerForMainFileRef(const Decl *Container) {
1307   // FIXME We might also want to display the signature here
1308   // When doing so, remember to also add the Signature to index results!
1309   if (auto *ND = llvm::dyn_cast_if_present<NamedDecl>(Container))
1310     return printQualifiedName(*ND);
1311   return {};
1312 }
1313 
1314 std::optional<ReferencesResult>
1315 maybeFindIncludeReferences(ParsedAST &AST, Position Pos,
1316                            URIForFile URIMainFile) {
1317   const auto &Includes = AST.getIncludeStructure().MainFileIncludes;
1318   auto IncludeOnLine = llvm::find_if(Includes, [&Pos](const Inclusion &Inc) {
1319     return Inc.HashLine == Pos.line;
1320   });
1321   if (IncludeOnLine == Includes.end())
1322     return std::nullopt;
1323 
1324   const SourceManager &SM = AST.getSourceManager();
1325   ReferencesResult Results;
1326   auto Converted = convertIncludes(AST);
1327   include_cleaner::walkUsed(
1328       AST.getLocalTopLevelDecls(), collectMacroReferences(AST),
1329       &AST.getPragmaIncludes(), AST.getPreprocessor(),
1330       [&](const include_cleaner::SymbolReference &Ref,
1331           llvm::ArrayRef<include_cleaner::Header> Providers) {
1332         if (Ref.RT != include_cleaner::RefType::Explicit ||
1333             !isPreferredProvider(*IncludeOnLine, Converted, Providers))
1334           return;
1335 
1336         auto Loc = SM.getFileLoc(Ref.RefLocation);
1337         // File locations can be outside of the main file if macro is
1338         // expanded through an #include.
1339         while (SM.getFileID(Loc) != SM.getMainFileID())
1340           Loc = SM.getIncludeLoc(SM.getFileID(Loc));
1341 
1342         ReferencesResult::Reference Result;
1343         const auto *Token = AST.getTokens().spelledTokenContaining(Loc);
1344         assert(Token && "references expected token here");
1345         Result.Loc.range = Range{sourceLocToPosition(SM, Token->location()),
1346                                  sourceLocToPosition(SM, Token->endLocation())};
1347         Result.Loc.uri = URIMainFile;
1348         Results.References.push_back(std::move(Result));
1349       });
1350   if (Results.References.empty())
1351     return std::nullopt;
1352 
1353   // Add the #include line to the references list.
1354   ReferencesResult::Reference Result;
1355   Result.Loc.range = rangeTillEOL(SM.getBufferData(SM.getMainFileID()),
1356                                   IncludeOnLine->HashOffset);
1357   Result.Loc.uri = URIMainFile;
1358   Results.References.push_back(std::move(Result));
1359   return Results;
1360 }
1361 } // namespace
1362 
1363 ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
1364                                 const SymbolIndex *Index, bool AddContext) {
1365   ReferencesResult Results;
1366   const SourceManager &SM = AST.getSourceManager();
1367   auto MainFilePath = AST.tuPath();
1368   auto URIMainFile = URIForFile::canonicalize(MainFilePath, MainFilePath);
1369   auto CurLoc = sourceLocationInMainFile(SM, Pos);
1370   if (!CurLoc) {
1371     llvm::consumeError(CurLoc.takeError());
1372     return {};
1373   }
1374 
1375   const auto IncludeReferences =
1376       maybeFindIncludeReferences(AST, Pos, URIMainFile);
1377   if (IncludeReferences)
1378     return *IncludeReferences;
1379 
1380   llvm::DenseSet<SymbolID> IDsToQuery, OverriddenMethods;
1381 
1382   const auto *IdentifierAtCursor =
1383       syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
1384   std::optional<DefinedMacro> Macro;
1385   if (IdentifierAtCursor)
1386     Macro = locateMacroAt(*IdentifierAtCursor, AST.getPreprocessor());
1387   if (Macro) {
1388     // Handle references to macro.
1389     if (auto MacroSID = getSymbolID(Macro->Name, Macro->Info, SM)) {
1390       // Collect macro references from main file.
1391       const auto &IDToRefs = AST.getMacros().MacroRefs;
1392       auto Refs = IDToRefs.find(MacroSID);
1393       if (Refs != IDToRefs.end()) {
1394         for (const auto &Ref : Refs->second) {
1395           ReferencesResult::Reference Result;
1396           Result.Loc.range = Ref.toRange(SM);
1397           Result.Loc.uri = URIMainFile;
1398           if (Ref.IsDefinition) {
1399             Result.Attributes |= ReferencesResult::Declaration;
1400             Result.Attributes |= ReferencesResult::Definition;
1401           }
1402           Results.References.push_back(std::move(Result));
1403         }
1404       }
1405       IDsToQuery.insert(MacroSID);
1406     }
1407   } else {
1408     // Handle references to Decls.
1409 
1410     DeclRelationSet Relations =
1411         DeclRelation::TemplatePattern | DeclRelation::Alias;
1412     std::vector<const NamedDecl *> Decls =
1413         getDeclAtPosition(AST, *CurLoc, Relations);
1414     llvm::SmallVector<const NamedDecl *> TargetsInMainFile;
1415     for (const NamedDecl *D : Decls) {
1416       auto ID = getSymbolID(D);
1417       if (!ID)
1418         continue;
1419       TargetsInMainFile.push_back(D);
1420       // Not all symbols can be referenced from outside (e.g. function-locals).
1421       // TODO: we could skip TU-scoped symbols here (e.g. static functions) if
1422       // we know this file isn't a header. The details might be tricky.
1423       if (D->getParentFunctionOrMethod())
1424         continue;
1425       IDsToQuery.insert(ID);
1426     }
1427 
1428     RelationsRequest OverriddenBy;
1429     if (Index) {
1430       OverriddenBy.Predicate = RelationKind::OverriddenBy;
1431       for (const NamedDecl *ND : Decls) {
1432         // Special case: For virtual methods, report decl/def of overrides and
1433         // references to all overridden methods in complete type hierarchy.
1434         if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(ND)) {
1435           if (CMD->isVirtual()) {
1436             if (auto ID = getSymbolID(CMD))
1437               OverriddenBy.Subjects.insert(ID);
1438             getOverriddenMethods(CMD, OverriddenMethods);
1439           }
1440         }
1441       }
1442     }
1443 
1444     // We traverse the AST to find references in the main file.
1445     auto MainFileRefs = findRefs(TargetsInMainFile, AST, /*PerToken=*/false);
1446     // We may get multiple refs with the same location and different Roles, as
1447     // cross-reference is only interested in locations, we deduplicate them
1448     // by the location to avoid emitting duplicated locations.
1449     MainFileRefs.erase(std::unique(MainFileRefs.begin(), MainFileRefs.end(),
1450                                    [](const ReferenceFinder::Reference &L,
1451                                       const ReferenceFinder::Reference &R) {
1452                                      return L.SpelledTok.location() ==
1453                                             R.SpelledTok.location();
1454                                    }),
1455                        MainFileRefs.end());
1456     for (const auto &Ref : MainFileRefs) {
1457       ReferencesResult::Reference Result;
1458       Result.Loc.range = Ref.range(SM);
1459       Result.Loc.uri = URIMainFile;
1460       if (AddContext)
1461         Result.Loc.containerName =
1462             stringifyContainerForMainFileRef(Ref.Container);
1463       if (Ref.Role & static_cast<unsigned>(index::SymbolRole::Declaration))
1464         Result.Attributes |= ReferencesResult::Declaration;
1465       // clang-index doesn't report definitions as declarations, but they are.
1466       if (Ref.Role & static_cast<unsigned>(index::SymbolRole::Definition))
1467         Result.Attributes |=
1468             ReferencesResult::Definition | ReferencesResult::Declaration;
1469       Results.References.push_back(std::move(Result));
1470     }
1471     // Add decl/def of overridding methods.
1472     if (Index && !OverriddenBy.Subjects.empty()) {
1473       LookupRequest ContainerLookup;
1474       // Different overrides will always be contained in different classes, so
1475       // we have a one-to-one mapping between SymbolID and index here, thus we
1476       // don't need to use std::vector as the map's value type.
1477       llvm::DenseMap<SymbolID, size_t> RefIndexForContainer;
1478       Index->relations(OverriddenBy, [&](const SymbolID &Subject,
1479                                          const Symbol &Object) {
1480         if (Limit && Results.References.size() >= Limit) {
1481           Results.HasMore = true;
1482           return;
1483         }
1484         const auto LSPLocDecl =
1485             toLSPLocation(Object.CanonicalDeclaration, MainFilePath);
1486         const auto LSPLocDef = toLSPLocation(Object.Definition, MainFilePath);
1487         if (LSPLocDecl && LSPLocDecl != LSPLocDef) {
1488           ReferencesResult::Reference Result;
1489           Result.Loc = {std::move(*LSPLocDecl), std::nullopt};
1490           Result.Attributes =
1491               ReferencesResult::Declaration | ReferencesResult::Override;
1492           RefIndexForContainer.insert({Object.ID, Results.References.size()});
1493           ContainerLookup.IDs.insert(Object.ID);
1494           Results.References.push_back(std::move(Result));
1495         }
1496         if (LSPLocDef) {
1497           ReferencesResult::Reference Result;
1498           Result.Loc = {std::move(*LSPLocDef), std::nullopt};
1499           Result.Attributes = ReferencesResult::Declaration |
1500                               ReferencesResult::Definition |
1501                               ReferencesResult::Override;
1502           RefIndexForContainer.insert({Object.ID, Results.References.size()});
1503           ContainerLookup.IDs.insert(Object.ID);
1504           Results.References.push_back(std::move(Result));
1505         }
1506       });
1507 
1508       if (!ContainerLookup.IDs.empty() && AddContext)
1509         Index->lookup(ContainerLookup, [&](const Symbol &Container) {
1510           auto Ref = RefIndexForContainer.find(Container.ID);
1511           assert(Ref != RefIndexForContainer.end());
1512           Results.References[Ref->getSecond()].Loc.containerName =
1513               Container.Scope.str() + Container.Name.str();
1514         });
1515     }
1516   }
1517   // Now query the index for references from other files.
1518   auto QueryIndex = [&](llvm::DenseSet<SymbolID> IDs, bool AllowAttributes,
1519                         bool AllowMainFileSymbols) {
1520     if (IDs.empty() || !Index || Results.HasMore)
1521       return;
1522     RefsRequest Req;
1523     Req.IDs = std::move(IDs);
1524     if (Limit) {
1525       if (Limit < Results.References.size()) {
1526         // We've already filled our quota, still check the index to correctly
1527         // return the `HasMore` info.
1528         Req.Limit = 0;
1529       } else {
1530         // Query index only for the remaining size.
1531         Req.Limit = Limit - Results.References.size();
1532       }
1533     }
1534     LookupRequest ContainerLookup;
1535     llvm::DenseMap<SymbolID, std::vector<size_t>> RefIndicesForContainer;
1536     Results.HasMore |= Index->refs(Req, [&](const Ref &R) {
1537       auto LSPLoc = toLSPLocation(R.Location, MainFilePath);
1538       // Avoid indexed results for the main file - the AST is authoritative.
1539       if (!LSPLoc ||
1540           (!AllowMainFileSymbols && LSPLoc->uri.file() == MainFilePath))
1541         return;
1542       ReferencesResult::Reference Result;
1543       Result.Loc = {std::move(*LSPLoc), std::nullopt};
1544       if (AllowAttributes) {
1545         if ((R.Kind & RefKind::Declaration) == RefKind::Declaration)
1546           Result.Attributes |= ReferencesResult::Declaration;
1547         // FIXME: our index should definitely store def | decl separately!
1548         if ((R.Kind & RefKind::Definition) == RefKind::Definition)
1549           Result.Attributes |=
1550               ReferencesResult::Declaration | ReferencesResult::Definition;
1551       }
1552       if (AddContext) {
1553         SymbolID Container = R.Container;
1554         ContainerLookup.IDs.insert(Container);
1555         RefIndicesForContainer[Container].push_back(Results.References.size());
1556       }
1557       Results.References.push_back(std::move(Result));
1558     });
1559 
1560     if (!ContainerLookup.IDs.empty() && AddContext)
1561       Index->lookup(ContainerLookup, [&](const Symbol &Container) {
1562         auto Ref = RefIndicesForContainer.find(Container.ID);
1563         assert(Ref != RefIndicesForContainer.end());
1564         auto ContainerName = Container.Scope.str() + Container.Name.str();
1565         for (auto I : Ref->getSecond()) {
1566           Results.References[I].Loc.containerName = ContainerName;
1567         }
1568       });
1569   };
1570   QueryIndex(std::move(IDsToQuery), /*AllowAttributes=*/true,
1571              /*AllowMainFileSymbols=*/false);
1572   // For a virtual method: Occurrences of BaseMethod should be treated as refs
1573   // and not as decl/def. Allow symbols from main file since AST does not report
1574   // these.
1575   QueryIndex(std::move(OverriddenMethods), /*AllowAttributes=*/false,
1576              /*AllowMainFileSymbols=*/true);
1577   return Results;
1578 }
1579 
1580 std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
1581   const SourceManager &SM = AST.getSourceManager();
1582   auto CurLoc = sourceLocationInMainFile(SM, Pos);
1583   if (!CurLoc) {
1584     llvm::consumeError(CurLoc.takeError());
1585     return {};
1586   }
1587   auto MainFilePath = AST.tuPath();
1588   std::vector<SymbolDetails> Results;
1589 
1590   // We also want the targets of using-decls, so we include
1591   // DeclRelation::Underlying.
1592   DeclRelationSet Relations = DeclRelation::TemplatePattern |
1593                               DeclRelation::Alias | DeclRelation::Underlying;
1594   for (const NamedDecl *D : getDeclAtPosition(AST, *CurLoc, Relations)) {
1595     D = getPreferredDecl(D);
1596 
1597     SymbolDetails NewSymbol;
1598     std::string QName = printQualifiedName(*D);
1599     auto SplitQName = splitQualifiedName(QName);
1600     NewSymbol.containerName = std::string(SplitQName.first);
1601     NewSymbol.name = std::string(SplitQName.second);
1602 
1603     if (NewSymbol.containerName.empty()) {
1604       if (const auto *ParentND =
1605               dyn_cast_or_null<NamedDecl>(D->getDeclContext()))
1606         NewSymbol.containerName = printQualifiedName(*ParentND);
1607     }
1608     llvm::SmallString<32> USR;
1609     if (!index::generateUSRForDecl(D, USR)) {
1610       NewSymbol.USR = std::string(USR);
1611       NewSymbol.ID = SymbolID(NewSymbol.USR);
1612     }
1613     if (const NamedDecl *Def = getDefinition(D))
1614       NewSymbol.definitionRange = makeLocation(
1615           AST.getASTContext(), nameLocation(*Def, SM), MainFilePath);
1616     NewSymbol.declarationRange =
1617         makeLocation(AST.getASTContext(), nameLocation(*D, SM), MainFilePath);
1618 
1619     Results.push_back(std::move(NewSymbol));
1620   }
1621 
1622   const auto *IdentifierAtCursor =
1623       syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
1624   if (!IdentifierAtCursor)
1625     return Results;
1626 
1627   if (auto M = locateMacroAt(*IdentifierAtCursor, AST.getPreprocessor())) {
1628     SymbolDetails NewMacro;
1629     NewMacro.name = std::string(M->Name);
1630     llvm::SmallString<32> USR;
1631     if (!index::generateUSRForMacro(NewMacro.name, M->Info->getDefinitionLoc(),
1632                                     SM, USR)) {
1633       NewMacro.USR = std::string(USR);
1634       NewMacro.ID = SymbolID(NewMacro.USR);
1635     }
1636     Results.push_back(std::move(NewMacro));
1637   }
1638 
1639   return Results;
1640 }
1641 
1642 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LocatedSymbol &S) {
1643   OS << S.Name << ": " << S.PreferredDeclaration;
1644   if (S.Definition)
1645     OS << " def=" << *S.Definition;
1646   return OS;
1647 }
1648 
1649 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
1650                               const ReferencesResult::Reference &R) {
1651   OS << R.Loc;
1652   if (R.Attributes & ReferencesResult::Declaration)
1653     OS << " [decl]";
1654   if (R.Attributes & ReferencesResult::Definition)
1655     OS << " [def]";
1656   if (R.Attributes & ReferencesResult::Override)
1657     OS << " [override]";
1658   return OS;
1659 }
1660 
1661 template <typename HierarchyItem>
1662 static std::optional<HierarchyItem>
1663 declToHierarchyItem(const NamedDecl &ND, llvm::StringRef TUPath) {
1664   ASTContext &Ctx = ND.getASTContext();
1665   auto &SM = Ctx.getSourceManager();
1666   SourceLocation NameLoc = nameLocation(ND, Ctx.getSourceManager());
1667   SourceLocation BeginLoc = SM.getFileLoc(ND.getBeginLoc());
1668   SourceLocation EndLoc = SM.getFileLoc(ND.getEndLoc());
1669   const auto DeclRange =
1670       toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc});
1671   if (!DeclRange)
1672     return std::nullopt;
1673   const auto FE = SM.getFileEntryRefForID(SM.getFileID(NameLoc));
1674   if (!FE)
1675     return std::nullopt;
1676   auto FilePath = getCanonicalPath(*FE, SM.getFileManager());
1677   if (!FilePath)
1678     return std::nullopt; // Not useful without a uri.
1679 
1680   Position NameBegin = sourceLocToPosition(SM, NameLoc);
1681   Position NameEnd = sourceLocToPosition(
1682       SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts()));
1683 
1684   index::SymbolInfo SymInfo = index::getSymbolInfo(&ND);
1685   // FIXME: This is not classifying constructors, destructors and operators
1686   // correctly.
1687   SymbolKind SK = indexSymbolKindToSymbolKind(SymInfo.Kind);
1688 
1689   HierarchyItem HI;
1690   HI.name = printName(Ctx, ND);
1691   // FIXME: Populate HI.detail the way we do in symbolToHierarchyItem?
1692   HI.kind = SK;
1693   HI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()),
1694                    sourceLocToPosition(SM, DeclRange->getEnd())};
1695   HI.selectionRange = Range{NameBegin, NameEnd};
1696   if (!HI.range.contains(HI.selectionRange)) {
1697     // 'selectionRange' must be contained in 'range', so in cases where clang
1698     // reports unrelated ranges we need to reconcile somehow.
1699     HI.range = HI.selectionRange;
1700   }
1701 
1702   HI.uri = URIForFile::canonicalize(*FilePath, TUPath);
1703 
1704   return HI;
1705 }
1706 
1707 static std::optional<TypeHierarchyItem>
1708 declToTypeHierarchyItem(const NamedDecl &ND, llvm::StringRef TUPath) {
1709   auto Result = declToHierarchyItem<TypeHierarchyItem>(ND, TUPath);
1710   if (Result) {
1711     Result->deprecated = ND.isDeprecated();
1712     // Compute the SymbolID and store it in the 'data' field.
1713     // This allows typeHierarchy/resolve to be used to
1714     // resolve children of items returned in a previous request
1715     // for parents.
1716     Result->data.symbolID = getSymbolID(&ND);
1717   }
1718   return Result;
1719 }
1720 
1721 static std::optional<CallHierarchyItem>
1722 declToCallHierarchyItem(const NamedDecl &ND, llvm::StringRef TUPath) {
1723   auto Result = declToHierarchyItem<CallHierarchyItem>(ND, TUPath);
1724   if (!Result)
1725     return Result;
1726   if (ND.isDeprecated())
1727     Result->tags.push_back(SymbolTag::Deprecated);
1728   if (auto ID = getSymbolID(&ND))
1729     Result->data = ID.str();
1730   return Result;
1731 }
1732 
1733 template <typename HierarchyItem>
1734 static std::optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S,
1735                                                           PathRef TUPath) {
1736   auto Loc = symbolToLocation(S, TUPath);
1737   if (!Loc) {
1738     elog("Failed to convert symbol to hierarchy item: {0}", Loc.takeError());
1739     return std::nullopt;
1740   }
1741   HierarchyItem HI;
1742   HI.name = std::string(S.Name);
1743   HI.detail = (S.Scope + S.Name).str();
1744   HI.kind = indexSymbolKindToSymbolKind(S.SymInfo.Kind);
1745   HI.selectionRange = Loc->range;
1746   // FIXME: Populate 'range' correctly
1747   // (https://github.com/clangd/clangd/issues/59).
1748   HI.range = HI.selectionRange;
1749   HI.uri = Loc->uri;
1750 
1751   return HI;
1752 }
1753 
1754 static std::optional<TypeHierarchyItem>
1755 symbolToTypeHierarchyItem(const Symbol &S, PathRef TUPath) {
1756   auto Result = symbolToHierarchyItem<TypeHierarchyItem>(S, TUPath);
1757   if (Result) {
1758     Result->deprecated = (S.Flags & Symbol::Deprecated);
1759     Result->data.symbolID = S.ID;
1760   }
1761   return Result;
1762 }
1763 
1764 static std::optional<CallHierarchyItem>
1765 symbolToCallHierarchyItem(const Symbol &S, PathRef TUPath) {
1766   auto Result = symbolToHierarchyItem<CallHierarchyItem>(S, TUPath);
1767   if (!Result)
1768     return Result;
1769   Result->data = S.ID.str();
1770   if (S.Flags & Symbol::Deprecated)
1771     Result->tags.push_back(SymbolTag::Deprecated);
1772   return Result;
1773 }
1774 
1775 static void fillSubTypes(const SymbolID &ID,
1776                          std::vector<TypeHierarchyItem> &SubTypes,
1777                          const SymbolIndex *Index, int Levels, PathRef TUPath) {
1778   RelationsRequest Req;
1779   Req.Subjects.insert(ID);
1780   Req.Predicate = RelationKind::BaseOf;
1781   Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) {
1782     if (std::optional<TypeHierarchyItem> ChildSym =
1783             symbolToTypeHierarchyItem(Object, TUPath)) {
1784       if (Levels > 1) {
1785         ChildSym->children.emplace();
1786         fillSubTypes(Object.ID, *ChildSym->children, Index, Levels - 1, TUPath);
1787       }
1788       SubTypes.emplace_back(std::move(*ChildSym));
1789     }
1790   });
1791 }
1792 
1793 using RecursionProtectionSet = llvm::SmallSet<const CXXRecordDecl *, 4>;
1794 
1795 // Extracts parents from AST and populates the type hierarchy item.
1796 static void fillSuperTypes(const CXXRecordDecl &CXXRD, llvm::StringRef TUPath,
1797                            TypeHierarchyItem &Item,
1798                            RecursionProtectionSet &RPSet) {
1799   Item.parents.emplace();
1800   Item.data.parents.emplace();
1801   // typeParents() will replace dependent template specializations
1802   // with their class template, so to avoid infinite recursion for
1803   // certain types of hierarchies, keep the templates encountered
1804   // along the parent chain in a set, and stop the recursion if one
1805   // starts to repeat.
1806   auto *Pattern = CXXRD.getDescribedTemplate() ? &CXXRD : nullptr;
1807   if (Pattern) {
1808     if (!RPSet.insert(Pattern).second) {
1809       return;
1810     }
1811   }
1812 
1813   for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) {
1814     if (std::optional<TypeHierarchyItem> ParentSym =
1815             declToTypeHierarchyItem(*ParentDecl, TUPath)) {
1816       fillSuperTypes(*ParentDecl, TUPath, *ParentSym, RPSet);
1817       Item.data.parents->emplace_back(ParentSym->data);
1818       Item.parents->emplace_back(std::move(*ParentSym));
1819     }
1820   }
1821 
1822   if (Pattern) {
1823     RPSet.erase(Pattern);
1824   }
1825 }
1826 
1827 std::vector<const CXXRecordDecl *> findRecordTypeAt(ParsedAST &AST,
1828                                                     Position Pos) {
1829   auto RecordFromNode = [&AST](const SelectionTree::Node *N) {
1830     std::vector<const CXXRecordDecl *> Records;
1831     if (!N)
1832       return Records;
1833 
1834     // Note: explicitReferenceTargets() will search for both template
1835     // instantiations and template patterns, and prefer the former if available
1836     // (generally, one will be available for non-dependent specializations of a
1837     // class template).
1838     auto Decls = explicitReferenceTargets(N->ASTNode, DeclRelation::Underlying,
1839                                           AST.getHeuristicResolver());
1840     for (const NamedDecl *D : Decls) {
1841 
1842       if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1843         // If this is a variable, use the type of the variable.
1844         if (const auto *RD = VD->getType().getTypePtr()->getAsCXXRecordDecl())
1845           Records.push_back(RD);
1846         continue;
1847       }
1848 
1849       if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
1850         // If this is a method, use the type of the class.
1851         Records.push_back(Method->getParent());
1852         continue;
1853       }
1854 
1855       // We don't handle FieldDecl because it's not clear what behaviour
1856       // the user would expect: the enclosing class type (as with a
1857       // method), or the field's type (as with a variable).
1858 
1859       if (auto *RD = dyn_cast<CXXRecordDecl>(D))
1860         Records.push_back(RD);
1861     }
1862     return Records;
1863   };
1864 
1865   const SourceManager &SM = AST.getSourceManager();
1866   std::vector<const CXXRecordDecl *> Result;
1867   auto Offset = positionToOffset(SM.getBufferData(SM.getMainFileID()), Pos);
1868   if (!Offset) {
1869     llvm::consumeError(Offset.takeError());
1870     return Result;
1871   }
1872   SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), *Offset,
1873                             *Offset, [&](SelectionTree ST) {
1874                               Result = RecordFromNode(ST.commonAncestor());
1875                               return !Result.empty();
1876                             });
1877   return Result;
1878 }
1879 
1880 // Return the type most associated with an AST node.
1881 // This isn't precisely defined: we want "go to type" to do something useful.
1882 static QualType typeForNode(const SelectionTree::Node *N) {
1883   // If we're looking at a namespace qualifier, walk up to what it's qualifying.
1884   // (If we're pointing at a *class* inside a NNS, N will be a TypeLoc).
1885   while (N && N->ASTNode.get<NestedNameSpecifierLoc>())
1886     N = N->Parent;
1887   if (!N)
1888     return QualType();
1889 
1890   // If we're pointing at a type => return it.
1891   if (const TypeLoc *TL = N->ASTNode.get<TypeLoc>()) {
1892     if (llvm::isa<DeducedType>(TL->getTypePtr()))
1893       if (auto Deduced = getDeducedType(
1894               N->getDeclContext().getParentASTContext(), TL->getBeginLoc()))
1895         return *Deduced;
1896     // Exception: an alias => underlying type.
1897     if (llvm::isa<TypedefType>(TL->getTypePtr()))
1898       return TL->getTypePtr()->getLocallyUnqualifiedSingleStepDesugaredType();
1899     return TL->getType();
1900   }
1901 
1902   // Constructor initializers => the type of thing being initialized.
1903   if (const auto *CCI = N->ASTNode.get<CXXCtorInitializer>()) {
1904     if (const FieldDecl *FD = CCI->getAnyMember())
1905       return FD->getType();
1906     if (const Type *Base = CCI->getBaseClass())
1907       return QualType(Base, 0);
1908   }
1909 
1910   // Base specifier => the base type.
1911   if (const auto *CBS = N->ASTNode.get<CXXBaseSpecifier>())
1912     return CBS->getType();
1913 
1914   if (const Decl *D = N->ASTNode.get<Decl>()) {
1915     struct Visitor : ConstDeclVisitor<Visitor, QualType> {
1916       QualType VisitValueDecl(const ValueDecl *D) { return D->getType(); }
1917       // Declaration of a type => that type.
1918       QualType VisitTypeDecl(const TypeDecl *D) {
1919         return QualType(D->getTypeForDecl(), 0);
1920       }
1921       // Exception: alias declaration => the underlying type, not the alias.
1922       QualType VisitTypedefNameDecl(const TypedefNameDecl *D) {
1923         return D->getUnderlyingType();
1924       }
1925       // Look inside templates.
1926       QualType VisitTemplateDecl(const TemplateDecl *D) {
1927         return Visit(D->getTemplatedDecl());
1928       }
1929     } V;
1930     return V.Visit(D);
1931   }
1932 
1933   if (const Stmt *S = N->ASTNode.get<Stmt>()) {
1934     struct Visitor : ConstStmtVisitor<Visitor, QualType> {
1935       // Null-safe version of visit simplifies recursive calls below.
1936       QualType type(const Stmt *S) { return S ? Visit(S) : QualType(); }
1937 
1938       // In general, expressions => type of expression.
1939       QualType VisitExpr(const Expr *S) {
1940         return S->IgnoreImplicitAsWritten()->getType();
1941       }
1942       QualType VisitMemberExpr(const MemberExpr *S) {
1943         // The `foo` in `s.foo()` pretends not to have a real type!
1944         if (S->getType()->isSpecificBuiltinType(BuiltinType::BoundMember))
1945           return Expr::findBoundMemberType(S);
1946         return VisitExpr(S);
1947       }
1948       // Exceptions for void expressions that operate on a type in some way.
1949       QualType VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
1950         return S->getDestroyedType();
1951       }
1952       QualType VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
1953         return S->getDestroyedType();
1954       }
1955       QualType VisitCXXThrowExpr(const CXXThrowExpr *S) {
1956         return S->getSubExpr()->getType();
1957       }
1958       QualType VisitCoyieldExpr(const CoyieldExpr *S) {
1959         return type(S->getOperand());
1960       }
1961       // Treat a designated initializer like a reference to the field.
1962       QualType VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
1963         // In .foo.bar we want to jump to bar's type, so find *last* field.
1964         for (auto &D : llvm::reverse(S->designators()))
1965           if (D.isFieldDesignator())
1966             if (const auto *FD = D.getFieldDecl())
1967               return FD->getType();
1968         return QualType();
1969       }
1970 
1971       // Control flow statements that operate on data: use the data type.
1972       QualType VisitSwitchStmt(const SwitchStmt *S) {
1973         return type(S->getCond());
1974       }
1975       QualType VisitWhileStmt(const WhileStmt *S) { return type(S->getCond()); }
1976       QualType VisitDoStmt(const DoStmt *S) { return type(S->getCond()); }
1977       QualType VisitIfStmt(const IfStmt *S) { return type(S->getCond()); }
1978       QualType VisitCaseStmt(const CaseStmt *S) { return type(S->getLHS()); }
1979       QualType VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
1980         return S->getLoopVariable()->getType();
1981       }
1982       QualType VisitReturnStmt(const ReturnStmt *S) {
1983         return type(S->getRetValue());
1984       }
1985       QualType VisitCoreturnStmt(const CoreturnStmt *S) {
1986         return type(S->getOperand());
1987       }
1988       QualType VisitCXXCatchStmt(const CXXCatchStmt *S) {
1989         return S->getCaughtType();
1990       }
1991       QualType VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
1992         return type(S->getThrowExpr());
1993       }
1994       QualType VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
1995         return S->getCatchParamDecl() ? S->getCatchParamDecl()->getType()
1996                                       : QualType();
1997       }
1998     } V;
1999     return V.Visit(S);
2000   }
2001 
2002   return QualType();
2003 }
2004 
2005 // Given a type targeted by the cursor, return one or more types that are more interesting
2006 // to target.
2007 static void unwrapFindType(
2008     QualType T, const HeuristicResolver* H, llvm::SmallVector<QualType>& Out) {
2009   if (T.isNull())
2010     return;
2011 
2012   // If there's a specific type alias, point at that rather than unwrapping.
2013   if (const auto* TDT = T->getAs<TypedefType>())
2014     return Out.push_back(QualType(TDT, 0));
2015 
2016   // Pointers etc => pointee type.
2017   if (const auto *PT = T->getAs<PointerType>())
2018     return unwrapFindType(PT->getPointeeType(), H, Out);
2019   if (const auto *RT = T->getAs<ReferenceType>())
2020     return unwrapFindType(RT->getPointeeType(), H, Out);
2021   if (const auto *AT = T->getAsArrayTypeUnsafe())
2022     return unwrapFindType(AT->getElementType(), H, Out);
2023 
2024   // Function type => return type.
2025   if (auto *FT = T->getAs<FunctionType>())
2026     return unwrapFindType(FT->getReturnType(), H, Out);
2027   if (auto *CRD = T->getAsCXXRecordDecl()) {
2028     if (CRD->isLambda())
2029       return unwrapFindType(CRD->getLambdaCallOperator()->getReturnType(), H,
2030                             Out);
2031     // FIXME: more cases we'd prefer the return type of the call operator?
2032     //        std::function etc?
2033   }
2034 
2035   // For smart pointer types, add the underlying type
2036   if (H)
2037     if (auto PointeeType = H->getPointeeType(T.getNonReferenceType());
2038         !PointeeType.isNull()) {
2039       unwrapFindType(PointeeType, H, Out);
2040       return Out.push_back(T);
2041     }
2042 
2043   return Out.push_back(T);
2044 }
2045 
2046 // Convenience overload, to allow calling this without the out-parameter
2047 static llvm::SmallVector<QualType> unwrapFindType(
2048     QualType T, const HeuristicResolver* H) {
2049   llvm::SmallVector<QualType> Result;
2050   unwrapFindType(T, H, Result);
2051   return Result;
2052 }
2053 
2054 std::vector<LocatedSymbol> findType(ParsedAST &AST, Position Pos,
2055                                     const SymbolIndex *Index) {
2056   const SourceManager &SM = AST.getSourceManager();
2057   auto Offset = positionToOffset(SM.getBufferData(SM.getMainFileID()), Pos);
2058   std::vector<LocatedSymbol> Result;
2059   if (!Offset) {
2060     elog("failed to convert position {0} for findTypes: {1}", Pos,
2061          Offset.takeError());
2062     return Result;
2063   }
2064   // The general scheme is: position -> AST node -> type -> declaration.
2065   auto SymbolsFromNode =
2066       [&](const SelectionTree::Node *N) -> std::vector<LocatedSymbol> {
2067     std::vector<LocatedSymbol> LocatedSymbols;
2068 
2069     // NOTE: unwrapFindType might return duplicates for something like
2070     // unique_ptr<unique_ptr<T>>. Let's *not* remove them, because it gives you some
2071     // information about the type you may have not known before
2072     // (since unique_ptr<unique_ptr<T>> != unique_ptr<T>).
2073     for (const QualType& Type : unwrapFindType(typeForNode(N), AST.getHeuristicResolver()))
2074       llvm::copy(locateSymbolForType(AST, Type, Index),
2075                  std::back_inserter(LocatedSymbols));
2076 
2077     return LocatedSymbols;
2078   };
2079   SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), *Offset,
2080                             *Offset, [&](SelectionTree ST) {
2081                               Result = SymbolsFromNode(ST.commonAncestor());
2082                               return !Result.empty();
2083                             });
2084   return Result;
2085 }
2086 
2087 std::vector<const CXXRecordDecl *> typeParents(const CXXRecordDecl *CXXRD) {
2088   std::vector<const CXXRecordDecl *> Result;
2089 
2090   // If this is an invalid instantiation, instantiation of the bases
2091   // may not have succeeded, so fall back to the template pattern.
2092   if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CXXRD)) {
2093     if (CTSD->isInvalidDecl())
2094       CXXRD = CTSD->getSpecializedTemplate()->getTemplatedDecl();
2095   }
2096 
2097   // Can't query bases without a definition.
2098   if (!CXXRD->hasDefinition())
2099     return Result;
2100 
2101   for (auto Base : CXXRD->bases()) {
2102     const CXXRecordDecl *ParentDecl = nullptr;
2103 
2104     const Type *Type = Base.getType().getTypePtr();
2105     if (const RecordType *RT = Type->getAs<RecordType>()) {
2106       ParentDecl = RT->getAsCXXRecordDecl();
2107     }
2108 
2109     if (!ParentDecl) {
2110       // Handle a dependent base such as "Base<T>" by using the primary
2111       // template.
2112       if (const TemplateSpecializationType *TS =
2113               Type->getAs<TemplateSpecializationType>()) {
2114         TemplateName TN = TS->getTemplateName();
2115         if (TemplateDecl *TD = TN.getAsTemplateDecl()) {
2116           ParentDecl = dyn_cast<CXXRecordDecl>(TD->getTemplatedDecl());
2117         }
2118       }
2119     }
2120 
2121     if (ParentDecl)
2122       Result.push_back(ParentDecl);
2123   }
2124 
2125   return Result;
2126 }
2127 
2128 std::vector<TypeHierarchyItem>
2129 getTypeHierarchy(ParsedAST &AST, Position Pos, int ResolveLevels,
2130                  TypeHierarchyDirection Direction, const SymbolIndex *Index,
2131                  PathRef TUPath) {
2132   std::vector<TypeHierarchyItem> Results;
2133   for (const auto *CXXRD : findRecordTypeAt(AST, Pos)) {
2134 
2135     bool WantChildren = Direction == TypeHierarchyDirection::Children ||
2136                         Direction == TypeHierarchyDirection::Both;
2137 
2138     // If we're looking for children, we're doing the lookup in the index.
2139     // The index does not store relationships between implicit
2140     // specializations, so if we have one, use the template pattern instead.
2141     // Note that this needs to be done before the declToTypeHierarchyItem(),
2142     // otherwise the type hierarchy item would misleadingly contain the
2143     // specialization parameters, while the children would involve classes
2144     // that derive from other specializations of the template.
2145     if (WantChildren) {
2146       if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CXXRD))
2147         CXXRD = CTSD->getTemplateInstantiationPattern();
2148     }
2149 
2150     std::optional<TypeHierarchyItem> Result =
2151         declToTypeHierarchyItem(*CXXRD, AST.tuPath());
2152     if (!Result)
2153       continue;
2154 
2155     RecursionProtectionSet RPSet;
2156     fillSuperTypes(*CXXRD, AST.tuPath(), *Result, RPSet);
2157 
2158     if (WantChildren && ResolveLevels > 0) {
2159       Result->children.emplace();
2160 
2161       if (Index) {
2162         if (auto ID = getSymbolID(CXXRD))
2163           fillSubTypes(ID, *Result->children, Index, ResolveLevels, TUPath);
2164       }
2165     }
2166     Results.emplace_back(std::move(*Result));
2167   }
2168 
2169   return Results;
2170 }
2171 
2172 std::optional<std::vector<TypeHierarchyItem>>
2173 superTypes(const TypeHierarchyItem &Item, const SymbolIndex *Index) {
2174   std::vector<TypeHierarchyItem> Results;
2175   if (!Item.data.parents)
2176     return std::nullopt;
2177   if (Item.data.parents->empty())
2178     return Results;
2179   LookupRequest Req;
2180   llvm::DenseMap<SymbolID, const TypeHierarchyItem::ResolveParams *> IDToData;
2181   for (const auto &Parent : *Item.data.parents) {
2182     Req.IDs.insert(Parent.symbolID);
2183     IDToData[Parent.symbolID] = &Parent;
2184   }
2185   Index->lookup(Req, [&Item, &Results, &IDToData](const Symbol &S) {
2186     if (auto THI = symbolToTypeHierarchyItem(S, Item.uri.file())) {
2187       THI->data = *IDToData.lookup(S.ID);
2188       Results.emplace_back(std::move(*THI));
2189     }
2190   });
2191   return Results;
2192 }
2193 
2194 std::vector<TypeHierarchyItem> subTypes(const TypeHierarchyItem &Item,
2195                                         const SymbolIndex *Index) {
2196   std::vector<TypeHierarchyItem> Results;
2197   fillSubTypes(Item.data.symbolID, Results, Index, 1, Item.uri.file());
2198   for (auto &ChildSym : Results)
2199     ChildSym.data.parents = {Item.data};
2200   return Results;
2201 }
2202 
2203 void resolveTypeHierarchy(TypeHierarchyItem &Item, int ResolveLevels,
2204                           TypeHierarchyDirection Direction,
2205                           const SymbolIndex *Index) {
2206   // We only support typeHierarchy/resolve for children, because for parents
2207   // we ignore ResolveLevels and return all levels of parents eagerly.
2208   if (!Index || Direction == TypeHierarchyDirection::Parents ||
2209       ResolveLevels == 0)
2210     return;
2211 
2212   Item.children.emplace();
2213   fillSubTypes(Item.data.symbolID, *Item.children, Index, ResolveLevels,
2214                Item.uri.file());
2215 }
2216 
2217 std::vector<CallHierarchyItem>
2218 prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath) {
2219   std::vector<CallHierarchyItem> Result;
2220   const auto &SM = AST.getSourceManager();
2221   auto Loc = sourceLocationInMainFile(SM, Pos);
2222   if (!Loc) {
2223     elog("prepareCallHierarchy failed to convert position to source location: "
2224          "{0}",
2225          Loc.takeError());
2226     return Result;
2227   }
2228   for (const NamedDecl *Decl : getDeclAtPosition(AST, *Loc, {})) {
2229     if (!(isa<DeclContext>(Decl) &&
2230           cast<DeclContext>(Decl)->isFunctionOrMethod()) &&
2231         Decl->getKind() != Decl::Kind::FunctionTemplate &&
2232         !(Decl->getKind() == Decl::Kind::Var &&
2233           !cast<VarDecl>(Decl)->isLocalVarDecl()) &&
2234         Decl->getKind() != Decl::Kind::Field)
2235       continue;
2236     if (auto CHI = declToCallHierarchyItem(*Decl, AST.tuPath()))
2237       Result.emplace_back(std::move(*CHI));
2238   }
2239   return Result;
2240 }
2241 
2242 std::vector<CallHierarchyIncomingCall>
2243 incomingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
2244   std::vector<CallHierarchyIncomingCall> Results;
2245   if (!Index || Item.data.empty())
2246     return Results;
2247   auto ID = SymbolID::fromStr(Item.data);
2248   if (!ID) {
2249     elog("incomingCalls failed to find symbol: {0}", ID.takeError());
2250     return Results;
2251   }
2252   // In this function, we find incoming calls based on the index only.
2253   // In principle, the AST could have more up-to-date information about
2254   // occurrences within the current file. However, going from a SymbolID
2255   // to an AST node isn't cheap, particularly when the declaration isn't
2256   // in the main file.
2257   // FIXME: Consider also using AST information when feasible.
2258   RefsRequest Request;
2259   Request.IDs.insert(*ID);
2260   Request.WantContainer = true;
2261   // We could restrict more specifically to calls by introducing a new RefKind,
2262   // but non-call references (such as address-of-function) can still be
2263   // interesting as they can indicate indirect calls.
2264   Request.Filter = RefKind::Reference;
2265   // Initially store the ranges in a map keyed by SymbolID of the caller.
2266   // This allows us to group different calls with the same caller
2267   // into the same CallHierarchyIncomingCall.
2268   llvm::DenseMap<SymbolID, std::vector<Location>> CallsIn;
2269   // We can populate the ranges based on a refs request only. As we do so, we
2270   // also accumulate the container IDs into a lookup request.
2271   LookupRequest ContainerLookup;
2272   Index->refs(Request, [&](const Ref &R) {
2273     auto Loc = indexToLSPLocation(R.Location, Item.uri.file());
2274     if (!Loc) {
2275       elog("incomingCalls failed to convert location: {0}", Loc.takeError());
2276       return;
2277     }
2278     CallsIn[R.Container].push_back(*Loc);
2279 
2280     ContainerLookup.IDs.insert(R.Container);
2281   });
2282   // Perform the lookup request and combine its results with CallsIn to
2283   // get complete CallHierarchyIncomingCall objects.
2284   Index->lookup(ContainerLookup, [&](const Symbol &Caller) {
2285     auto It = CallsIn.find(Caller.ID);
2286     assert(It != CallsIn.end());
2287     if (auto CHI = symbolToCallHierarchyItem(Caller, Item.uri.file())) {
2288       std::vector<Range> FromRanges;
2289       for (const Location &L : It->second) {
2290         if (L.uri != CHI->uri) {
2291           // Call location not in same file as caller.
2292           // This can happen in some edge cases. There's not much we can do,
2293           // since the protocol only allows returning ranges interpreted as
2294           // being in the caller's file.
2295           continue;
2296         }
2297         FromRanges.push_back(L.range);
2298       }
2299       Results.push_back(
2300           CallHierarchyIncomingCall{std::move(*CHI), std::move(FromRanges)});
2301     }
2302   });
2303   // Sort results by name of container.
2304   llvm::sort(Results, [](const CallHierarchyIncomingCall &A,
2305                          const CallHierarchyIncomingCall &B) {
2306     return A.from.name < B.from.name;
2307   });
2308   return Results;
2309 }
2310 
2311 std::vector<CallHierarchyOutgoingCall>
2312 outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
2313   std::vector<CallHierarchyOutgoingCall> Results;
2314   if (!Index || Item.data.empty())
2315     return Results;
2316   auto ID = SymbolID::fromStr(Item.data);
2317   if (!ID) {
2318     elog("outgoingCalls failed to find symbol: {0}", ID.takeError());
2319     return Results;
2320   }
2321   // In this function, we find outgoing calls based on the index only.
2322   ContainedRefsRequest Request;
2323   Request.ID = *ID;
2324   // Initially store the ranges in a map keyed by SymbolID of the callee.
2325   // This allows us to group different calls to the same function
2326   // into the same CallHierarchyOutgoingCall.
2327   llvm::DenseMap<SymbolID, std::vector<Range>> CallsOut;
2328   // We can populate the ranges based on a refs request only. As we do so, we
2329   // also accumulate the callee IDs into a lookup request.
2330   LookupRequest CallsOutLookup;
2331   Index->containedRefs(Request, [&](const auto &R) {
2332     auto Loc = indexToLSPLocation(R.Location, Item.uri.file());
2333     if (!Loc) {
2334       elog("outgoingCalls failed to convert location: {0}", Loc.takeError());
2335       return;
2336     }
2337     auto It = CallsOut.try_emplace(R.Symbol, std::vector<Range>{}).first;
2338     It->second.push_back(Loc->range);
2339 
2340     CallsOutLookup.IDs.insert(R.Symbol);
2341   });
2342   // Perform the lookup request and combine its results with CallsOut to
2343   // get complete CallHierarchyOutgoingCall objects.
2344   Index->lookup(CallsOutLookup, [&](const Symbol &Callee) {
2345     // The containedRefs request should only return symbols which are
2346     // function-like, i.e. symbols for which references to them can be "calls".
2347     using SK = index::SymbolKind;
2348     auto Kind = Callee.SymInfo.Kind;
2349     assert(Kind == SK::Function || Kind == SK::InstanceMethod ||
2350            Kind == SK::ClassMethod || Kind == SK::StaticMethod ||
2351            Kind == SK::Constructor || Kind == SK::Destructor ||
2352            Kind == SK::ConversionFunction);
2353     (void)Kind;
2354     (void)SK::Function;
2355 
2356     auto It = CallsOut.find(Callee.ID);
2357     assert(It != CallsOut.end());
2358     if (auto CHI = symbolToCallHierarchyItem(Callee, Item.uri.file()))
2359       Results.push_back(
2360           CallHierarchyOutgoingCall{std::move(*CHI), std::move(It->second)});
2361   });
2362   // Sort results by name of the callee.
2363   llvm::sort(Results, [](const CallHierarchyOutgoingCall &A,
2364                          const CallHierarchyOutgoingCall &B) {
2365     return A.to.name < B.to.name;
2366   });
2367   return Results;
2368 }
2369 
2370 llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST,
2371                                                  const FunctionDecl *FD) {
2372   if (!FD->hasBody())
2373     return {};
2374   llvm::DenseSet<const Decl *> DeclRefs;
2375   findExplicitReferences(
2376       FD,
2377       [&](ReferenceLoc Ref) {
2378         for (const Decl *D : Ref.Targets) {
2379           if (!index::isFunctionLocalSymbol(D) && !D->isTemplateParameter() &&
2380               !Ref.IsDecl)
2381             DeclRefs.insert(D);
2382         }
2383       },
2384       AST.getHeuristicResolver());
2385   return DeclRefs;
2386 }
2387 
2388 } // namespace clangd
2389 } // namespace clang
2390