clang-tools  16.0.0git
FindTarget.cpp
Go to the documentation of this file.
1 //===--- FindTarget.cpp - What does an AST node refer to? -----------------===//
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 
9 #include "FindTarget.h"
10 #include "AST.h"
11 #include "HeuristicResolver.h"
12 #include "support/Logger.h"
13 #include "clang/AST/ASTTypeTraits.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclBase.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/DeclVisitor.h"
19 #include "clang/AST/DeclarationName.h"
20 #include "clang/AST/Expr.h"
21 #include "clang/AST/ExprCXX.h"
22 #include "clang/AST/ExprConcepts.h"
23 #include "clang/AST/ExprObjC.h"
24 #include "clang/AST/NestedNameSpecifier.h"
25 #include "clang/AST/PrettyPrinter.h"
26 #include "clang/AST/RecursiveASTVisitor.h"
27 #include "clang/AST/StmtVisitor.h"
28 #include "clang/AST/TemplateBase.h"
29 #include "clang/AST/Type.h"
30 #include "clang/AST/TypeLoc.h"
31 #include "clang/AST/TypeLocVisitor.h"
32 #include "clang/AST/TypeVisitor.h"
33 #include "clang/Basic/LangOptions.h"
34 #include "clang/Basic/SourceLocation.h"
35 #include "clang/Basic/SourceManager.h"
36 #include "clang/Basic/Specifiers.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallVector.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/Compiler.h"
42 #include "llvm/Support/raw_ostream.h"
43 #include <iterator>
44 #include <string>
45 #include <utility>
46 #include <vector>
47 
48 namespace clang {
49 namespace clangd {
50 namespace {
51 
52 LLVM_ATTRIBUTE_UNUSED std::string nodeToString(const DynTypedNode &N) {
53  std::string S = std::string(N.getNodeKind().asStringRef());
54  {
55  llvm::raw_string_ostream OS(S);
56  OS << ": ";
57  N.print(OS, PrintingPolicy(LangOptions()));
58  }
59  std::replace(S.begin(), S.end(), '\n', ' ');
60  return S;
61 }
62 
63 const NamedDecl *getTemplatePattern(const NamedDecl *D) {
64  if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
65  if (const auto *Result = CRD->getTemplateInstantiationPattern())
66  return Result;
67  // getTemplateInstantiationPattern returns null if the Specialization is
68  // incomplete (e.g. the type didn't need to be complete), fall back to the
69  // primary template.
70  if (CRD->getTemplateSpecializationKind() == TSK_Undeclared)
71  if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(CRD))
72  return Spec->getSpecializedTemplate()->getTemplatedDecl();
73  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
74  return FD->getTemplateInstantiationPattern();
75  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
76  // Hmm: getTIP returns its arg if it's not an instantiation?!
77  VarDecl *T = VD->getTemplateInstantiationPattern();
78  return (T == D) ? nullptr : T;
79  } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
80  return ED->getInstantiatedFromMemberEnum();
81  } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
82  if (const auto *Parent = llvm::dyn_cast<NamedDecl>(D->getDeclContext()))
83  if (const DeclContext *ParentPat =
84  dyn_cast_or_null<DeclContext>(getTemplatePattern(Parent)))
85  for (const NamedDecl *BaseND : ParentPat->lookup(D->getDeclName()))
86  if (!BaseND->isImplicit() && BaseND->getKind() == D->getKind())
87  return BaseND;
88  } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
89  if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
90  if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
91  for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
92  return BaseECD;
93  }
94  }
95  }
96  return nullptr;
97 }
98 
99 // Returns true if the `TypedefNameDecl` should not be reported.
100 bool shouldSkipTypedef(const TypedefNameDecl *TD) {
101  // These should be treated as keywords rather than decls - the typedef is an
102  // odd implementation detail.
103  if (TD == TD->getASTContext().getObjCInstanceTypeDecl() ||
104  TD == TD->getASTContext().getObjCIdDecl())
105  return true;
106  return false;
107 }
108 
109 // TargetFinder locates the entities that an AST node refers to.
110 //
111 // Typically this is (possibly) one declaration and (possibly) one type, but
112 // may be more:
113 // - for ambiguous nodes like OverloadExpr
114 // - if we want to include e.g. both typedefs and the underlying type
115 //
116 // This is organized as a set of mutually recursive helpers for particular node
117 // types, but for most nodes this is a short walk rather than a deep traversal.
118 //
119 // It's tempting to do e.g. typedef resolution as a second normalization step,
120 // after finding the 'primary' decl etc. But we do this monolithically instead
121 // because:
122 // - normalization may require these traversals again (e.g. unwrapping a
123 // typedef reveals a decltype which must be traversed)
124 // - it doesn't simplify that much, e.g. the first stage must still be able
125 // to yield multiple decls to handle OverloadExpr
126 // - there are cases where it's required for correctness. e.g:
127 // template<class X> using pvec = vector<x*>; pvec<int> x;
128 // There's no Decl `pvec<int>`, we must choose `pvec<X>` or `vector<int*>`
129 // and both are lossy. We must know upfront what the caller ultimately wants.
130 struct TargetFinder {
131  using RelSet = DeclRelationSet;
132  using Rel = DeclRelation;
133 
134 private:
135  const HeuristicResolver *Resolver;
136  llvm::SmallDenseMap<const NamedDecl *,
137  std::pair<RelSet, /*InsertionOrder*/ size_t>>
138  Decls;
139  llvm::SmallDenseMap<const Decl *, RelSet> Seen;
140  RelSet Flags;
141 
142  template <typename T> void debug(T &Node, RelSet Flags) {
143  dlog("visit [{0}] {1}", Flags, nodeToString(DynTypedNode::create(Node)));
144  }
145 
146  void report(const NamedDecl *D, RelSet Flags) {
147  dlog("--> [{0}] {1}", Flags, nodeToString(DynTypedNode::create(*D)));
148  auto It = Decls.try_emplace(D, std::make_pair(Flags, Decls.size()));
149  // If already exists, update the flags.
150  if (!It.second)
151  It.first->second.first |= Flags;
152  }
153 
154 public:
155  TargetFinder(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
156 
157  llvm::SmallVector<std::pair<const NamedDecl *, RelSet>, 1> takeDecls() const {
158  using ValTy = std::pair<const NamedDecl *, RelSet>;
159  llvm::SmallVector<ValTy, 1> Result;
160  Result.resize(Decls.size());
161  for (const auto &Elem : Decls)
162  Result[Elem.second.second] = {Elem.first, Elem.second.first};
163  return Result;
164  }
165 
166  void add(const Decl *Dcl, RelSet Flags) {
167  const NamedDecl *D = llvm::dyn_cast_or_null<NamedDecl>(Dcl);
168  if (!D)
169  return;
170  debug(*D, Flags);
171 
172  // Avoid recursion (which can arise in the presence of heuristic
173  // resolution of dependent names) by exiting early if we have
174  // already seen this decl with all flags in Flags.
175  auto Res = Seen.try_emplace(D);
176  if (!Res.second && Res.first->second.contains(Flags))
177  return;
178  Res.first->second |= Flags;
179 
180  if (const UsingDirectiveDecl *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
181  D = UDD->getNominatedNamespaceAsWritten();
182 
183  if (const TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) {
184  add(TND->getUnderlyingType(), Flags | Rel::Underlying);
185  Flags |= Rel::Alias; // continue with the alias.
186  } else if (const UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
187  // no Underlying as this is a non-renaming alias.
188  for (const UsingShadowDecl *S : UD->shadows())
189  add(S->getUnderlyingDecl(), Flags);
190  Flags |= Rel::Alias; // continue with the alias.
191  } else if (const UsingEnumDecl *UED = dyn_cast<UsingEnumDecl>(D)) {
192  // UsingEnumDecl is not an alias at all, just a reference.
193  D = UED->getEnumDecl();
194  } else if (const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) {
195  add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying);
196  Flags |= Rel::Alias; // continue with the alias
197  } else if (const UnresolvedUsingValueDecl *UUVD =
198  dyn_cast<UnresolvedUsingValueDecl>(D)) {
199  if (Resolver) {
200  for (const NamedDecl *Target : Resolver->resolveUsingValueDecl(UUVD)) {
201  add(Target, Flags); // no Underlying as this is a non-renaming alias
202  }
203  }
204  Flags |= Rel::Alias; // continue with the alias
205  } else if (isa<UnresolvedUsingTypenameDecl>(D)) {
206  // FIXME: improve common dependent scope using name lookup in primary
207  // templates.
208  Flags |= Rel::Alias;
209  } else if (const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
210  // Include the introducing UsingDecl, but don't traverse it. This may end
211  // up including *all* shadows, which we don't want.
212  // Don't apply this logic to UsingEnumDecl, which can't easily be
213  // conflated with the aliases it introduces.
214  if (llvm::isa<UsingDecl>(USD->getIntroducer()))
215  report(USD->getIntroducer(), Flags | Rel::Alias);
216  // Shadow decls are synthetic and not themselves interesting.
217  // Record the underlying decl instead, if allowed.
218  D = USD->getTargetDecl();
219  } else if (const auto *DG = dyn_cast<CXXDeductionGuideDecl>(D)) {
220  D = DG->getDeducedTemplate();
221  } else if (const ObjCImplementationDecl *IID =
222  dyn_cast<ObjCImplementationDecl>(D)) {
223  // Treat ObjC{Interface,Implementation}Decl as if they were a decl/def
224  // pair as long as the interface isn't implicit.
225  if (const auto *CID = IID->getClassInterface())
226  if (const auto *DD = CID->getDefinition())
227  if (!DD->isImplicitInterfaceDecl())
228  D = DD;
229  } else if (const ObjCCategoryImplDecl *CID =
230  dyn_cast<ObjCCategoryImplDecl>(D)) {
231  // Treat ObjC{Category,CategoryImpl}Decl as if they were a decl/def pair.
232  D = CID->getCategoryDecl();
233  }
234  if (!D)
235  return;
236 
237  if (const Decl *Pat = getTemplatePattern(D)) {
238  assert(Pat != D);
239  add(Pat, Flags | Rel::TemplatePattern);
240  // Now continue with the instantiation.
241  Flags |= Rel::TemplateInstantiation;
242  }
243 
244  report(D, Flags);
245  }
246 
247  void add(const Stmt *S, RelSet Flags) {
248  if (!S)
249  return;
250  debug(*S, Flags);
251  struct Visitor : public ConstStmtVisitor<Visitor> {
252  TargetFinder &Outer;
253  RelSet Flags;
254  Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}
255 
256  void VisitCallExpr(const CallExpr *CE) {
257  Outer.add(CE->getCalleeDecl(), Flags);
258  }
259  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
260  Outer.add(E->getNamedConcept(), Flags);
261  }
262  void VisitDeclRefExpr(const DeclRefExpr *DRE) {
263  const Decl *D = DRE->getDecl();
264  // UsingShadowDecl allows us to record the UsingDecl.
265  // getFoundDecl() returns the wrong thing in other cases (templates).
266  if (auto *USD = llvm::dyn_cast<UsingShadowDecl>(DRE->getFoundDecl()))
267  D = USD;
268  Outer.add(D, Flags);
269  }
270  void VisitMemberExpr(const MemberExpr *ME) {
271  const Decl *D = ME->getMemberDecl();
272  if (auto *USD =
273  llvm::dyn_cast<UsingShadowDecl>(ME->getFoundDecl().getDecl()))
274  D = USD;
275  Outer.add(D, Flags);
276  }
277  void VisitOverloadExpr(const OverloadExpr *OE) {
278  for (auto *D : OE->decls())
279  Outer.add(D, Flags);
280  }
281  void VisitSizeOfPackExpr(const SizeOfPackExpr *SE) {
282  Outer.add(SE->getPack(), Flags);
283  }
284  void VisitCXXConstructExpr(const CXXConstructExpr *CCE) {
285  Outer.add(CCE->getConstructor(), Flags);
286  }
287  void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {
288  for (const DesignatedInitExpr::Designator &D :
289  llvm::reverse(DIE->designators()))
290  if (D.isFieldDesignator()) {
291  Outer.add(D.getField(), Flags);
292  // We don't know which designator was intended, we assume the outer.
293  break;
294  }
295  }
296  void VisitGotoStmt(const GotoStmt *Goto) {
297  if (auto *LabelDecl = Goto->getLabel())
298  Outer.add(LabelDecl, Flags);
299  }
300  void VisitLabelStmt(const LabelStmt *Label) {
301  if (auto *LabelDecl = Label->getDecl())
302  Outer.add(LabelDecl, Flags);
303  }
304  void
305  VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
306  if (Outer.Resolver) {
307  for (const NamedDecl *D : Outer.Resolver->resolveMemberExpr(E)) {
308  Outer.add(D, Flags);
309  }
310  }
311  }
312  void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
313  if (Outer.Resolver) {
314  for (const NamedDecl *D : Outer.Resolver->resolveDeclRefExpr(E)) {
315  Outer.add(D, Flags);
316  }
317  }
318  }
319  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
320  Outer.add(OIRE->getDecl(), Flags);
321  }
322  void VisitObjCMessageExpr(const ObjCMessageExpr *OME) {
323  Outer.add(OME->getMethodDecl(), Flags);
324  }
325  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
326  if (OPRE->isExplicitProperty())
327  Outer.add(OPRE->getExplicitProperty(), Flags);
328  else {
329  if (OPRE->isMessagingGetter())
330  Outer.add(OPRE->getImplicitPropertyGetter(), Flags);
331  if (OPRE->isMessagingSetter())
332  Outer.add(OPRE->getImplicitPropertySetter(), Flags);
333  }
334  }
335  void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
336  Outer.add(OPE->getProtocol(), Flags);
337  }
338  void VisitOpaqueValueExpr(const OpaqueValueExpr *OVE) {
339  Outer.add(OVE->getSourceExpr(), Flags);
340  }
341  void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) {
342  Outer.add(POE->getSyntacticForm(), Flags);
343  }
344  void VisitCXXNewExpr(const CXXNewExpr *CNE) {
345  Outer.add(CNE->getOperatorNew(), Flags);
346  }
347  void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE) {
348  Outer.add(CDE->getOperatorDelete(), Flags);
349  }
350  };
351  Visitor(*this, Flags).Visit(S);
352  }
353 
354  void add(QualType T, RelSet Flags) {
355  if (T.isNull())
356  return;
357  debug(T, Flags);
358  struct Visitor : public TypeVisitor<Visitor> {
359  TargetFinder &Outer;
360  RelSet Flags;
361  Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}
362 
363  void VisitTagType(const TagType *TT) {
364  Outer.add(TT->getAsTagDecl(), Flags);
365  }
366 
367  void VisitElaboratedType(const ElaboratedType *ET) {
368  Outer.add(ET->desugar(), Flags);
369  }
370 
371  void VisitUsingType(const UsingType *ET) {
372  Outer.add(ET->getFoundDecl(), Flags);
373  }
374 
375  void VisitInjectedClassNameType(const InjectedClassNameType *ICNT) {
376  Outer.add(ICNT->getDecl(), Flags);
377  }
378 
379  void VisitDecltypeType(const DecltypeType *DTT) {
380  Outer.add(DTT->getUnderlyingType(), Flags | Rel::Underlying);
381  }
382  void VisitDeducedType(const DeducedType *DT) {
383  // FIXME: In practice this doesn't work: the AutoType you find inside
384  // TypeLoc never has a deduced type. https://llvm.org/PR42914
385  Outer.add(DT->getDeducedType(), Flags);
386  }
387  void VisitUnresolvedUsingType(const UnresolvedUsingType *UUT) {
388  Outer.add(UUT->getDecl(), Flags);
389  }
390  void VisitDeducedTemplateSpecializationType(
391  const DeducedTemplateSpecializationType *DTST) {
392  if (const auto *USD = DTST->getTemplateName().getAsUsingShadowDecl())
393  Outer.add(USD, Flags);
394 
395  // FIXME: This is a workaround for https://llvm.org/PR42914,
396  // which is causing DTST->getDeducedType() to be empty. We
397  // fall back to the template pattern and miss the instantiation
398  // even when it's known in principle. Once that bug is fixed,
399  // the following code can be removed (the existing handling in
400  // VisitDeducedType() is sufficient).
401  if (auto *TD = DTST->getTemplateName().getAsTemplateDecl())
402  Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
403  }
404  void VisitDependentNameType(const DependentNameType *DNT) {
405  if (Outer.Resolver) {
406  for (const NamedDecl *ND :
407  Outer.Resolver->resolveDependentNameType(DNT)) {
408  Outer.add(ND, Flags);
409  }
410  }
411  }
412  void VisitDependentTemplateSpecializationType(
413  const DependentTemplateSpecializationType *DTST) {
414  if (Outer.Resolver) {
415  for (const NamedDecl *ND :
416  Outer.Resolver->resolveTemplateSpecializationType(DTST)) {
417  Outer.add(ND, Flags);
418  }
419  }
420  }
421  void VisitTypedefType(const TypedefType *TT) {
422  if (shouldSkipTypedef(TT->getDecl()))
423  return;
424  Outer.add(TT->getDecl(), Flags);
425  }
426  void
427  VisitTemplateSpecializationType(const TemplateSpecializationType *TST) {
428  // Have to handle these case-by-case.
429 
430  if (const auto *UTN = TST->getTemplateName().getAsUsingShadowDecl())
431  Outer.add(UTN, Flags);
432 
433  // templated type aliases: there's no specialized/instantiated using
434  // decl to point to. So try to find a decl for the underlying type
435  // (after substitution), and failing that point to the (templated) using
436  // decl.
437  if (TST->isTypeAlias()) {
438  Outer.add(TST->getAliasedType(), Flags | Rel::Underlying);
439  // Don't *traverse* the alias, which would result in traversing the
440  // template of the underlying type.
441  Outer.report(
442  TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl(),
443  Flags | Rel::Alias | Rel::TemplatePattern);
444  }
445  // specializations of template template parameters aren't instantiated
446  // into decls, so they must refer to the parameter itself.
447  else if (const auto *Parm =
448  llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
449  TST->getTemplateName().getAsTemplateDecl()))
450  Outer.add(Parm, Flags);
451  // class template specializations have a (specialized) CXXRecordDecl.
452  else if (const CXXRecordDecl *RD = TST->getAsCXXRecordDecl())
453  Outer.add(RD, Flags); // add(Decl) will despecialize if needed.
454  else {
455  // fallback: the (un-specialized) declaration from primary template.
456  if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
457  Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
458  }
459  }
460  void
461  VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT) {
462  Outer.add(STTPT->getReplacementType(), Flags);
463  }
464  void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT) {
465  Outer.add(TTPT->getDecl(), Flags);
466  }
467  void VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
468  Outer.add(OIT->getDecl(), Flags);
469  }
470  };
471  Visitor(*this, Flags).Visit(T.getTypePtr());
472  }
473 
474  void add(const NestedNameSpecifier *NNS, RelSet Flags) {
475  if (!NNS)
476  return;
477  debug(*NNS, Flags);
478  switch (NNS->getKind()) {
479  case NestedNameSpecifier::Namespace:
480  add(NNS->getAsNamespace(), Flags);
481  return;
482  case NestedNameSpecifier::NamespaceAlias:
483  add(NNS->getAsNamespaceAlias(), Flags);
484  return;
485  case NestedNameSpecifier::Identifier:
486  if (Resolver) {
487  add(QualType(Resolver->resolveNestedNameSpecifierToType(NNS), 0),
488  Flags);
489  }
490  return;
491  case NestedNameSpecifier::TypeSpec:
492  case NestedNameSpecifier::TypeSpecWithTemplate:
493  add(QualType(NNS->getAsType(), 0), Flags);
494  return;
495  case NestedNameSpecifier::Global:
496  // This should be TUDecl, but we can't get a pointer to it!
497  return;
498  case NestedNameSpecifier::Super:
499  add(NNS->getAsRecordDecl(), Flags);
500  return;
501  }
502  llvm_unreachable("unhandled NestedNameSpecifier::SpecifierKind");
503  }
504 
505  void add(const CXXCtorInitializer *CCI, RelSet Flags) {
506  if (!CCI)
507  return;
508  debug(*CCI, Flags);
509 
510  if (CCI->isAnyMemberInitializer())
511  add(CCI->getAnyMember(), Flags);
512  // Constructor calls contain a TypeLoc node, so we don't handle them here.
513  }
514 
515  void add(const TemplateArgument &Arg, RelSet Flags) {
516  // Only used for template template arguments.
517  // For type and non-type template arguments, SelectionTree
518  // will hit a more specific node (e.g. a TypeLoc or a
519  // DeclRefExpr).
520  if (Arg.getKind() == TemplateArgument::Template ||
521  Arg.getKind() == TemplateArgument::TemplateExpansion) {
522  if (TemplateDecl *TD =
523  Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) {
524  report(TD, Flags);
525  }
526  if (const auto *USD =
527  Arg.getAsTemplateOrTemplatePattern().getAsUsingShadowDecl())
528  add(USD, Flags);
529  }
530  }
531 };
532 
533 } // namespace
534 
535 llvm::SmallVector<std::pair<const NamedDecl *, DeclRelationSet>, 1>
536 allTargetDecls(const DynTypedNode &N, const HeuristicResolver *Resolver) {
537  dlog("allTargetDecls({0})", nodeToString(N));
538  TargetFinder Finder(Resolver);
540  if (const Decl *D = N.get<Decl>())
541  Finder.add(D, Flags);
542  else if (const Stmt *S = N.get<Stmt>())
543  Finder.add(S, Flags);
544  else if (const NestedNameSpecifierLoc *NNSL = N.get<NestedNameSpecifierLoc>())
545  Finder.add(NNSL->getNestedNameSpecifier(), Flags);
546  else if (const NestedNameSpecifier *NNS = N.get<NestedNameSpecifier>())
547  Finder.add(NNS, Flags);
548  else if (const TypeLoc *TL = N.get<TypeLoc>())
549  Finder.add(TL->getType(), Flags);
550  else if (const QualType *QT = N.get<QualType>())
551  Finder.add(*QT, Flags);
552  else if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>())
553  Finder.add(CCI, Flags);
554  else if (const TemplateArgumentLoc *TAL = N.get<TemplateArgumentLoc>())
555  Finder.add(TAL->getArgument(), Flags);
556  else if (const CXXBaseSpecifier *CBS = N.get<CXXBaseSpecifier>())
557  Finder.add(CBS->getTypeSourceInfo()->getType(), Flags);
558  else if (const ObjCProtocolLoc *PL = N.get<ObjCProtocolLoc>())
559  Finder.add(PL->getProtocol(), Flags);
560  return Finder.takeDecls();
561 }
562 
563 llvm::SmallVector<const NamedDecl *, 1>
564 targetDecl(const DynTypedNode &N, DeclRelationSet Mask,
565  const HeuristicResolver *Resolver) {
566  llvm::SmallVector<const NamedDecl *, 1> Result;
567  for (const auto &Entry : allTargetDecls(N, Resolver)) {
568  if (!(Entry.second & ~Mask))
569  Result.push_back(Entry.first);
570  }
571  return Result;
572 }
573 
574 llvm::SmallVector<const NamedDecl *, 1>
576  const HeuristicResolver *Resolver) {
577  assert(!(Mask & (DeclRelation::TemplatePattern |
579  "explicitReferenceTargets handles templates on its own");
580  auto Decls = allTargetDecls(N, Resolver);
581 
582  // We prefer to return template instantiation, but fallback to template
583  // pattern if instantiation is not available.
585 
586  llvm::SmallVector<const NamedDecl *, 1> TemplatePatterns;
587  llvm::SmallVector<const NamedDecl *, 1> Targets;
588  bool SeenTemplateInstantiations = false;
589  for (auto &D : Decls) {
590  if (D.second & ~Mask)
591  continue;
592  if (D.second & DeclRelation::TemplatePattern) {
593  TemplatePatterns.push_back(D.first);
594  continue;
595  }
597  SeenTemplateInstantiations = true;
598  Targets.push_back(D.first);
599  }
600  if (!SeenTemplateInstantiations)
601  Targets.insert(Targets.end(), TemplatePatterns.begin(),
602  TemplatePatterns.end());
603  return Targets;
604 }
605 
606 namespace {
607 llvm::SmallVector<ReferenceLoc> refInDecl(const Decl *D,
608  const HeuristicResolver *Resolver) {
609  struct Visitor : ConstDeclVisitor<Visitor> {
610  Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
611 
612  const HeuristicResolver *Resolver;
613  llvm::SmallVector<ReferenceLoc> Refs;
614 
615  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
616  // We want to keep it as non-declaration references, as the
617  // "using namespace" declaration doesn't have a name.
618  Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
619  D->getIdentLocation(),
620  /*IsDecl=*/false,
621  {D->getNominatedNamespaceAsWritten()}});
622  }
623 
624  void VisitUsingDecl(const UsingDecl *D) {
625  // "using ns::identifier;" is a non-declaration reference.
626  Refs.push_back(ReferenceLoc{
627  D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,
628  explicitReferenceTargets(DynTypedNode::create(*D),
629  DeclRelation::Underlying, Resolver)});
630  }
631 
632  void VisitUsingEnumDecl(const UsingEnumDecl *D) {
633  // "using enum ns::E" is a non-declaration reference.
634  // The reference is covered by the embedded typeloc.
635  // Don't use the default VisitNamedDecl, which would report a declaration.
636  }
637 
638  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
639  // For namespace alias, "namespace Foo = Target;", we add two references.
640  // Add a declaration reference for Foo.
641  VisitNamedDecl(D);
642  // Add a non-declaration reference for Target.
643  Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
644  D->getTargetNameLoc(),
645  /*IsDecl=*/false,
646  {D->getAliasedNamespace()}});
647  }
648 
649  void VisitNamedDecl(const NamedDecl *ND) {
650  // We choose to ignore {Class, Function, Var, TypeAlias}TemplateDecls. As
651  // as their underlying decls, covering the same range, will be visited.
652  if (llvm::isa<ClassTemplateDecl>(ND) ||
653  llvm::isa<FunctionTemplateDecl>(ND) ||
654  llvm::isa<VarTemplateDecl>(ND) ||
655  llvm::isa<TypeAliasTemplateDecl>(ND))
656  return;
657  // FIXME: decide on how to surface destructors when we need them.
658  if (llvm::isa<CXXDestructorDecl>(ND))
659  return;
660  // Filter anonymous decls, name location will point outside the name token
661  // and the clients are not prepared to handle that.
662  if (ND->getDeclName().isIdentifier() &&
663  !ND->getDeclName().getAsIdentifierInfo())
664  return;
665  Refs.push_back(ReferenceLoc{getQualifierLoc(*ND),
666  ND->getLocation(),
667  /*IsDecl=*/true,
668  {ND}});
669  }
670 
671  void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *DG) {
672  // The class template name in a deduction guide targets the class
673  // template.
674  Refs.push_back(ReferenceLoc{DG->getQualifierLoc(),
675  DG->getNameInfo().getLoc(),
676  /*IsDecl=*/false,
677  {DG->getDeducedTemplate()}});
678  }
679 
680  void VisitObjCMethodDecl(const ObjCMethodDecl *OMD) {
681  // The name may have several tokens, we can only report the first.
682  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
683  OMD->getSelectorStartLoc(),
684  /*IsDecl=*/true,
685  {OMD}});
686  }
687 
688  void VisitObjCCategoryDecl(const ObjCCategoryDecl *OCD) {
689  // getLocation is the extended class's location, not the category's.
690  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
691  OCD->getLocation(),
692  /*IsDecl=*/false,
693  {OCD->getClassInterface()}});
694  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
695  OCD->getCategoryNameLoc(),
696  /*IsDecl=*/true,
697  {OCD}});
698  }
699 
700  void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *OCID) {
701  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
702  OCID->getLocation(),
703  /*IsDecl=*/false,
704  {OCID->getClassInterface()}});
705  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
706  OCID->getCategoryNameLoc(),
707  /*IsDecl=*/true,
708  {OCID->getCategoryDecl()}});
709  }
710  };
711 
712  Visitor V{Resolver};
713  V.Visit(D);
714  return V.Refs;
715 }
716 
717 llvm::SmallVector<ReferenceLoc> refInStmt(const Stmt *S,
718  const HeuristicResolver *Resolver) {
719  struct Visitor : ConstStmtVisitor<Visitor> {
720  Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
721 
722  const HeuristicResolver *Resolver;
723  // FIXME: handle more complicated cases: more ObjC, designated initializers.
724  llvm::SmallVector<ReferenceLoc> Refs;
725 
726  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
727  Refs.push_back(ReferenceLoc{E->getNestedNameSpecifierLoc(),
728  E->getConceptNameLoc(),
729  /*IsDecl=*/false,
730  {E->getNamedConcept()}});
731  }
732 
733  void VisitDeclRefExpr(const DeclRefExpr *E) {
734  Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
735  E->getNameInfo().getLoc(),
736  /*IsDecl=*/false,
737  {E->getFoundDecl()}});
738  }
739 
740  void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
741  Refs.push_back(ReferenceLoc{
742  E->getQualifierLoc(), E->getNameInfo().getLoc(), /*IsDecl=*/false,
743  explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});
744  }
745 
746  void VisitMemberExpr(const MemberExpr *E) {
747  // Skip destructor calls to avoid duplication: TypeLoc within will be
748  // visited separately.
749  if (llvm::isa<CXXDestructorDecl>(E->getFoundDecl().getDecl()))
750  return;
751  Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
752  E->getMemberNameInfo().getLoc(),
753  /*IsDecl=*/false,
754  {E->getFoundDecl()}});
755  }
756 
757  void
758  VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
759  Refs.push_back(ReferenceLoc{
760  E->getQualifierLoc(), E->getMemberNameInfo().getLoc(),
761  /*IsDecl=*/false,
762  explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});
763  }
764 
765  void VisitOverloadExpr(const OverloadExpr *E) {
766  Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
767  E->getNameInfo().getLoc(),
768  /*IsDecl=*/false,
769  llvm::SmallVector<const NamedDecl *, 1>(
770  E->decls().begin(), E->decls().end())});
771  }
772 
773  void VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
774  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
775  E->getPackLoc(),
776  /*IsDecl=*/false,
777  {E->getPack()}});
778  }
779 
780  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
781  Refs.push_back(ReferenceLoc{
782  NestedNameSpecifierLoc(), E->getLocation(),
783  /*IsDecl=*/false,
784  // Select the getter, setter, or @property depending on the call.
785  explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});
786  }
787 
788  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
789  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
790  OIRE->getLocation(),
791  /*IsDecl=*/false,
792  {OIRE->getDecl()}});
793  }
794 
795  void VisitObjCMessageExpr(const ObjCMessageExpr *E) {
796  // The name may have several tokens, we can only report the first.
797  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
798  E->getSelectorStartLoc(),
799  /*IsDecl=*/false,
800  {E->getMethodDecl()}});
801  }
802 
803  void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {
804  for (const DesignatedInitExpr::Designator &D : DIE->designators()) {
805  if (!D.isFieldDesignator())
806  continue;
807 
808  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
809  D.getFieldLoc(),
810  /*IsDecl=*/false,
811  {D.getField()}});
812  }
813  }
814 
815  void VisitGotoStmt(const GotoStmt *GS) {
816  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
817  GS->getLabelLoc(),
818  /*IsDecl=*/false,
819  {GS->getLabel()}});
820  }
821 
822  void VisitLabelStmt(const LabelStmt *LS) {
823  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
824  LS->getIdentLoc(),
825  /*IsDecl=*/true,
826  {LS->getDecl()}});
827  }
828  };
829 
830  Visitor V{Resolver};
831  V.Visit(S);
832  return V.Refs;
833 }
834 
835 llvm::SmallVector<ReferenceLoc>
836 refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
837  struct Visitor : TypeLocVisitor<Visitor> {
838  Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
839 
840  const HeuristicResolver *Resolver;
841  llvm::SmallVector<ReferenceLoc> Refs;
842 
843  void VisitElaboratedTypeLoc(ElaboratedTypeLoc L) {
844  // We only know about qualifier, rest if filled by inner locations.
845  size_t InitialSize = Refs.size();
846  Visit(L.getNamedTypeLoc().getUnqualifiedLoc());
847  size_t NewSize = Refs.size();
848  // Add qualifier for the newly-added refs.
849  for (unsigned I = InitialSize; I < NewSize; ++I) {
850  ReferenceLoc *Ref = &Refs[I];
851  // Fill in the qualifier.
852  assert(!Ref->Qualifier.hasQualifier() && "qualifier already set");
853  Ref->Qualifier = L.getQualifierLoc();
854  }
855  }
856 
857  void VisitUsingTypeLoc(UsingTypeLoc L) {
858  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
859  L.getLocalSourceRange().getBegin(),
860  /*IsDecl=*/false,
861  {L.getFoundDecl()}});
862  }
863 
864  void VisitTagTypeLoc(TagTypeLoc L) {
865  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
866  L.getNameLoc(),
867  /*IsDecl=*/false,
868  {L.getDecl()}});
869  }
870 
871  void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {
872  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
873  L.getNameLoc(),
874  /*IsDecl=*/false,
875  {L.getDecl()}});
876  }
877 
878  void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
879  // We must ensure template type aliases are included in results if they
880  // were written in the source code, e.g. in
881  // template <class T> using valias = vector<T>;
882  // ^valias<int> x;
883  // 'explicitReferenceTargets' will return:
884  // 1. valias with mask 'Alias'.
885  // 2. 'vector<int>' with mask 'Underlying'.
886  // we want to return only #1 in this case.
887  Refs.push_back(ReferenceLoc{
888  NestedNameSpecifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
889  explicitReferenceTargets(DynTypedNode::create(L.getType()),
890  DeclRelation::Alias, Resolver)});
891  }
892  void VisitDeducedTemplateSpecializationTypeLoc(
893  DeducedTemplateSpecializationTypeLoc L) {
894  Refs.push_back(ReferenceLoc{
895  NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
896  explicitReferenceTargets(DynTypedNode::create(L.getType()),
897  DeclRelation::Alias, Resolver)});
898  }
899 
900  void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
901  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
902  TL.getNameLoc(),
903  /*IsDecl=*/false,
904  {TL.getDecl()}});
905  }
906 
907  void VisitDependentTemplateSpecializationTypeLoc(
908  DependentTemplateSpecializationTypeLoc L) {
909  Refs.push_back(
910  ReferenceLoc{L.getQualifierLoc(), L.getTemplateNameLoc(),
911  /*IsDecl=*/false,
913  DynTypedNode::create(L.getType()), {}, Resolver)});
914  }
915 
916  void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
917  Refs.push_back(
918  ReferenceLoc{L.getQualifierLoc(), L.getNameLoc(),
919  /*IsDecl=*/false,
921  DynTypedNode::create(L.getType()), {}, Resolver)});
922  }
923 
924  void VisitTypedefTypeLoc(TypedefTypeLoc L) {
925  if (shouldSkipTypedef(L.getTypedefNameDecl()))
926  return;
927  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
928  L.getNameLoc(),
929  /*IsDecl=*/false,
930  {L.getTypedefNameDecl()}});
931  }
932 
933  void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc L) {
934  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
935  L.getNameLoc(),
936  /*IsDecl=*/false,
937  {L.getIFaceDecl()}});
938  }
939  };
940 
941  Visitor V{Resolver};
942  V.Visit(L.getUnqualifiedLoc());
943  return V.Refs;
944 }
945 
946 class ExplicitReferenceCollector
947  : public RecursiveASTVisitor<ExplicitReferenceCollector> {
948 public:
949  ExplicitReferenceCollector(llvm::function_ref<void(ReferenceLoc)> Out,
950  const HeuristicResolver *Resolver)
951  : Out(Out), Resolver(Resolver) {
952  assert(Out);
953  }
954 
955  bool VisitTypeLoc(TypeLoc TTL) {
956  if (TypeLocsToSkip.count(TTL.getBeginLoc()))
957  return true;
958  visitNode(DynTypedNode::create(TTL));
959  return true;
960  }
961 
962  bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) {
963  // ElaboratedTypeLoc will reports information for its inner type loc.
964  // Otherwise we loose information about inner types loc's qualifier.
965  TypeLoc Inner = L.getNamedTypeLoc().getUnqualifiedLoc();
966  if (L.getBeginLoc() == Inner.getBeginLoc())
967  return RecursiveASTVisitor::TraverseTypeLoc(Inner);
968  else
969  TypeLocsToSkip.insert(Inner.getBeginLoc());
970  return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L);
971  }
972 
973  bool VisitStmt(Stmt *S) {
974  visitNode(DynTypedNode::create(*S));
975  return true;
976  }
977 
978  bool TraverseOpaqueValueExpr(OpaqueValueExpr *OVE) {
979  visitNode(DynTypedNode::create(*OVE));
980  // Not clear why the source expression is skipped by default...
981  // FIXME: can we just make RecursiveASTVisitor do this?
982  return RecursiveASTVisitor::TraverseStmt(OVE->getSourceExpr());
983  }
984 
985  bool TraversePseudoObjectExpr(PseudoObjectExpr *POE) {
986  visitNode(DynTypedNode::create(*POE));
987  // Traverse only the syntactic form to find the *written* references.
988  // (The semantic form also contains lots of duplication)
989  return RecursiveASTVisitor::TraverseStmt(POE->getSyntacticForm());
990  }
991 
992  // We re-define Traverse*, since there's no corresponding Visit*.
993  // TemplateArgumentLoc is the only way to get locations for references to
994  // template template parameters.
995  bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) {
996  switch (A.getArgument().getKind()) {
997  case TemplateArgument::Template:
998  case TemplateArgument::TemplateExpansion:
999  reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
1000  A.getTemplateNameLoc(),
1001  /*IsDecl=*/false,
1002  {A.getArgument()
1003  .getAsTemplateOrTemplatePattern()
1004  .getAsTemplateDecl()}},
1005  DynTypedNode::create(A.getArgument()));
1006  break;
1007  case TemplateArgument::Declaration:
1008  break; // FIXME: can this actually happen in TemplateArgumentLoc?
1009  case TemplateArgument::Integral:
1010  case TemplateArgument::Null:
1011  case TemplateArgument::NullPtr:
1012  break; // no references.
1015  case TemplateArgument::Expression:
1016  break; // Handled by VisitType and VisitExpression.
1017  };
1018  return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A);
1019  }
1020 
1021  bool VisitDecl(Decl *D) {
1022  visitNode(DynTypedNode::create(*D));
1023  return true;
1024  }
1025 
1026  // We have to use Traverse* because there is no corresponding Visit*.
1027  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc L) {
1028  if (!L.getNestedNameSpecifier())
1029  return true;
1030  visitNode(DynTypedNode::create(L));
1031  // Inner type is missing information about its qualifier, skip it.
1032  if (auto TL = L.getTypeLoc())
1033  TypeLocsToSkip.insert(TL.getBeginLoc());
1034  return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(L);
1035  }
1036 
1037  bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc) {
1038  visitNode(DynTypedNode::create(ProtocolLoc));
1039  return true;
1040  }
1041 
1042  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
1043  visitNode(DynTypedNode::create(*Init));
1044  return RecursiveASTVisitor::TraverseConstructorInitializer(Init);
1045  }
1046 
1047 private:
1048  /// Obtain information about a reference directly defined in \p N. Does not
1049  /// recurse into child nodes, e.g. do not expect references for constructor
1050  /// initializers
1051  ///
1052  /// Any of the fields in the returned structure can be empty, but not all of
1053  /// them, e.g.
1054  /// - for implicitly generated nodes (e.g. MemberExpr from range-based-for),
1055  /// source location information may be missing,
1056  /// - for dependent code, targets may be empty.
1057  ///
1058  /// (!) For the purposes of this function declarations are not considered to
1059  /// be references. However, declarations can have references inside them,
1060  /// e.g. 'namespace foo = std' references namespace 'std' and this
1061  /// function will return the corresponding reference.
1062  llvm::SmallVector<ReferenceLoc> explicitReference(DynTypedNode N) {
1063  if (auto *D = N.get<Decl>())
1064  return refInDecl(D, Resolver);
1065  if (auto *S = N.get<Stmt>())
1066  return refInStmt(S, Resolver);
1067  if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) {
1068  // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases.
1069  return {ReferenceLoc{
1070  NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false,
1072  DynTypedNode::create(*NNSL->getNestedNameSpecifier()),
1073  DeclRelation::Alias, Resolver)}};
1074  }
1075  if (const TypeLoc *TL = N.get<TypeLoc>())
1076  return refInTypeLoc(*TL, Resolver);
1077  if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) {
1078  // Other type initializers (e.g. base initializer) are handled by visiting
1079  // the typeLoc.
1080  if (CCI->isAnyMemberInitializer()) {
1081  return {ReferenceLoc{NestedNameSpecifierLoc(),
1082  CCI->getMemberLocation(),
1083  /*IsDecl=*/false,
1084  {CCI->getAnyMember()}}};
1085  }
1086  }
1087  if (const ObjCProtocolLoc *PL = N.get<ObjCProtocolLoc>())
1088  return {ReferenceLoc{NestedNameSpecifierLoc(),
1089  PL->getLocation(),
1090  /*IsDecl=*/false,
1091  {PL->getProtocol()}}};
1092 
1093  // We do not have location information for other nodes (QualType, etc)
1094  return {};
1095  }
1096 
1097  void visitNode(DynTypedNode N) {
1098  for (auto &R : explicitReference(N))
1099  reportReference(std::move(R), N);
1100  }
1101 
1102  void reportReference(ReferenceLoc &&Ref, DynTypedNode N) {
1103  // Strip null targets that can arise from invalid code.
1104  // (This avoids having to check for null everywhere we insert)
1105  llvm::erase_value(Ref.Targets, nullptr);
1106  // Our promise is to return only references from the source code. If we lack
1107  // location information, skip these nodes.
1108  // Normally this should not happen in practice, unless there are bugs in the
1109  // traversals or users started the traversal at an implicit node.
1110  if (Ref.NameLoc.isInvalid()) {
1111  dlog("invalid location at node {0}", nodeToString(N));
1112  return;
1113  }
1114  Out(Ref);
1115  }
1116 
1117  llvm::function_ref<void(ReferenceLoc)> Out;
1118  const HeuristicResolver *Resolver;
1119  /// TypeLocs starting at these locations must be skipped, see
1120  /// TraverseElaboratedTypeSpecifierLoc for details.
1121  llvm::DenseSet<SourceLocation> TypeLocsToSkip;
1122 };
1123 } // namespace
1124 
1125 void findExplicitReferences(const Stmt *S,
1126  llvm::function_ref<void(ReferenceLoc)> Out,
1127  const HeuristicResolver *Resolver) {
1128  assert(S);
1129  ExplicitReferenceCollector(Out, Resolver).TraverseStmt(const_cast<Stmt *>(S));
1130 }
1132  llvm::function_ref<void(ReferenceLoc)> Out,
1133  const HeuristicResolver *Resolver) {
1134  assert(D);
1135  ExplicitReferenceCollector(Out, Resolver).TraverseDecl(const_cast<Decl *>(D));
1136 }
1137 void findExplicitReferences(const ASTContext &AST,
1138  llvm::function_ref<void(ReferenceLoc)> Out,
1139  const HeuristicResolver *Resolver) {
1140  ExplicitReferenceCollector(Out, Resolver)
1141  .TraverseAST(const_cast<ASTContext &>(AST));
1142 }
1143 
1144 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelation R) {
1145  switch (R) {
1146 #define REL_CASE(X) \
1147  case DeclRelation::X: \
1148  return OS << #X;
1149  REL_CASE(Alias);
1153 #undef REL_CASE
1154  }
1155  llvm_unreachable("Unhandled DeclRelation enum");
1156 }
1157 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelationSet RS) {
1158  const char *Sep = "";
1159  for (unsigned I = 0; I < RS.S.size(); ++I) {
1160  if (RS.S.test(I)) {
1161  OS << Sep << static_cast<DeclRelation>(I);
1162  Sep = "|";
1163  }
1164  }
1165  return OS;
1166 }
1167 
1168 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ReferenceLoc R) {
1169  // note we cannot print R.NameLoc without a source manager.
1170  OS << "targets = {";
1171  llvm::SmallVector<std::string> Targets;
1172  for (const NamedDecl *T : R.Targets) {
1173  llvm::raw_string_ostream Target(Targets.emplace_back());
1175  }
1176  llvm::sort(Targets);
1177  OS << llvm::join(Targets, ", ");
1178  OS << "}";
1179  if (R.Qualifier) {
1180  OS << ", qualifier = '";
1181  R.Qualifier.getNestedNameSpecifier()->print(OS,
1182  PrintingPolicy(LangOptions()));
1183  OS << "'";
1184  }
1185  if (R.IsDecl)
1186  OS << ", decl";
1187  return OS;
1188 }
1189 
1190 } // namespace clangd
1191 } // namespace clang
dlog
#define dlog(...)
Definition: Logger.h:101
Pack
ArrayRef< const ParmVarDecl * > Pack
Definition: AST.cpp:794
RecursiveASTVisitor
Flags
MixFlags Flags
Definition: EasilySwappableParametersCheck.cpp:1097
Label
std::string Label
Definition: InlayHintTests.cpp:46
E
const Expr * E
Definition: AvoidBindCheck.cpp:88
Type
NodeType Type
Definition: HTMLGenerator.cpp:74
Refs
RefSlab Refs
Definition: SymbolCollectorTests.cpp:312
clang::clangd::getQualifierLoc
NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND)
Returns a nested name specifier loc of ND if it was present in the source, e.g.
Definition: AST.cpp:205
clang::clangd::DeclRelation
DeclRelation
Definition: FindTarget.h:93
Outer
std::pair< Context, Canceler > Outer
Definition: CancellationTests.cpp:48
clang::tidy::cppcoreguidelines::join
static std::string join(ArrayRef< SpecialMemberFunctionsCheck::SpecialMemberFunctionKind > SMFS, llvm::StringRef AndOr)
Definition: SpecialMemberFunctionsCheck.cpp:78
clang::clangd::HeuristicResolver
Definition: HeuristicResolver.h:45
clang::clangd::DeclRelationSet
Definition: FindTarget.h:173
FindTarget.h
ns1::ns2::A
@ A
Definition: CategoricalFeature.h:3
clang::clangd::ReferenceLoc::Qualifier
NestedNameSpecifierLoc Qualifier
Contains qualifier written in the code, if any, e.g. 'ns::' for 'ns::foo'.
Definition: FindTarget.h:128
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
Inner
std::pair< Context, Canceler > Inner
Definition: CancellationTests.cpp:48
clang::clangd::printQualifiedName
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
Definition: AST.cpp:183
Logger.h
clang::clangd::printTemplateSpecializationArgs
std::string printTemplateSpecializationArgs(const NamedDecl &ND)
Prints template arguments of a decl as written in the source code, including enclosing '<' and '>',...
Definition: AST.cpp:266
clang::clangd::replace
static std::string replace(llvm::StringRef Haystack, llvm::StringRef Needle, llvm::StringRef Repl)
Definition: TestIndex.cpp:30
clang::clangd::explicitReferenceTargets
llvm::SmallVector< const NamedDecl *, 1 > explicitReferenceTargets(DynTypedNode N, DeclRelationSet Mask, const HeuristicResolver *Resolver)
Find declarations explicitly referenced in the source code defined by N.
Definition: FindTarget.cpp:575
clang::clangd::DeclRelation::Underlying
@ Underlying
This is the underlying declaration for a renaming-alias, decltype etc.
clang::clangd::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
Definition: CodeComplete.cpp:2217
Parm
Params Parm
Definition: ConfigCompileTests.cpp:42
Parent
const Node * Parent
Definition: ExtractFunction.cpp:157
Entry
Definition: Modularize.cpp:427
HeuristicResolver.h
REL_CASE
#define REL_CASE(X)
DeducedType
QualType DeducedType
Definition: AST.cpp:563
clang::clangd::ReferenceLoc
Information about a reference written in the source code, independent of the actual AST node that thi...
Definition: FindTarget.h:126
CE
CaptureExpr CE
Definition: AvoidBindCheck.cpp:67
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
clang::clangd::allTargetDecls
llvm::SmallVector< std::pair< const NamedDecl *, DeclRelationSet >, 1 > allTargetDecls(const DynTypedNode &N, const HeuristicResolver *Resolver)
Similar to targetDecl(), however instead of applying a filter, all possible decls are returned along ...
Definition: FindTarget.cpp:536
clang::clangd::targetDecl
llvm::SmallVector< const NamedDecl *, 1 > targetDecl(const DynTypedNode &N, DeclRelationSet Mask, const HeuristicResolver *Resolver)
targetDecl() finds the declaration referred to by an AST node.
Definition: FindTarget.cpp:564
clang::clangd::ReferenceLoc::IsDecl
bool IsDecl
True if the reference is a declaration or definition;.
Definition: FindTarget.h:132
clang::clangd::DeclRelation::TemplateInstantiation
@ TemplateInstantiation
This is the template instantiation that was referred to.
Out
CompiledFragmentImpl & Out
Definition: ConfigCompile.cpp:99
clang::clangd::findExplicitReferences
void findExplicitReferences(const Stmt *S, llvm::function_ref< void(ReferenceLoc)> Out, const HeuristicResolver *Resolver)
Recursively traverse S and report all references explicitly written in the code.
Definition: FindTarget.cpp:1125
clang::clangd::DeclRelation::TemplatePattern
@ TemplatePattern
This is the pattern the template specialization was instantiated from.
clang::clangd::ReferenceLoc::Targets
llvm::SmallVector< const NamedDecl *, 1 > Targets
A list of targets referenced by this name.
Definition: FindTarget.h:138
clang::clangd::DeclRelation::Alias
@ Alias
This declaration is an alias that was referred to.
AST.h