clang-tools  14.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/OperatorKinds.h"
35 #include "clang/Basic/SourceLocation.h"
36 #include "clang/Basic/Specifiers.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallVector.h"
39 #include "llvm/Support/Casting.h"
40 #include "llvm/Support/Compiler.h"
41 #include "llvm/Support/raw_ostream.h"
42 #include <iterator>
43 #include <utility>
44 #include <vector>
45 
46 namespace clang {
47 namespace clangd {
48 namespace {
49 
50 LLVM_ATTRIBUTE_UNUSED std::string nodeToString(const DynTypedNode &N) {
51  std::string S = std::string(N.getNodeKind().asStringRef());
52  {
53  llvm::raw_string_ostream OS(S);
54  OS << ": ";
55  N.print(OS, PrintingPolicy(LangOptions()));
56  }
57  std::replace(S.begin(), S.end(), '\n', ' ');
58  return S;
59 }
60 
61 const NamedDecl *getTemplatePattern(const NamedDecl *D) {
62  if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
63  if (const auto *Result = CRD->getTemplateInstantiationPattern())
64  return Result;
65  // getTemplateInstantiationPattern returns null if the Specialization is
66  // incomplete (e.g. the type didn't need to be complete), fall back to the
67  // primary template.
68  if (CRD->getTemplateSpecializationKind() == TSK_Undeclared)
69  if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(CRD))
70  return Spec->getSpecializedTemplate()->getTemplatedDecl();
71  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
72  return FD->getTemplateInstantiationPattern();
73  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
74  // Hmm: getTIP returns its arg if it's not an instantiation?!
75  VarDecl *T = VD->getTemplateInstantiationPattern();
76  return (T == D) ? nullptr : T;
77  } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
78  return ED->getInstantiatedFromMemberEnum();
79  } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
80  if (const auto *Parent = llvm::dyn_cast<NamedDecl>(D->getDeclContext()))
81  if (const DeclContext *ParentPat =
82  dyn_cast_or_null<DeclContext>(getTemplatePattern(Parent)))
83  for (const NamedDecl *BaseND : ParentPat->lookup(D->getDeclName()))
84  if (!BaseND->isImplicit() && BaseND->getKind() == D->getKind())
85  return BaseND;
86  } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
87  if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
88  if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
89  for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
90  return BaseECD;
91  }
92  }
93  }
94  return nullptr;
95 }
96 
97 // Returns true if the `TypedefNameDecl` should not be reported.
98 bool shouldSkipTypedef(const TypedefNameDecl *TD) {
99  // These should be treated as keywords rather than decls - the typedef is an
100  // odd implementation detail.
101  if (TD == TD->getASTContext().getObjCInstanceTypeDecl() ||
102  TD == TD->getASTContext().getObjCIdDecl())
103  return true;
104  return false;
105 }
106 
107 // TargetFinder locates the entities that an AST node refers to.
108 //
109 // Typically this is (possibly) one declaration and (possibly) one type, but
110 // may be more:
111 // - for ambiguous nodes like OverloadExpr
112 // - if we want to include e.g. both typedefs and the underlying type
113 //
114 // This is organized as a set of mutually recursive helpers for particular node
115 // types, but for most nodes this is a short walk rather than a deep traversal.
116 //
117 // It's tempting to do e.g. typedef resolution as a second normalization step,
118 // after finding the 'primary' decl etc. But we do this monolithically instead
119 // because:
120 // - normalization may require these traversals again (e.g. unwrapping a
121 // typedef reveals a decltype which must be traversed)
122 // - it doesn't simplify that much, e.g. the first stage must still be able
123 // to yield multiple decls to handle OverloadExpr
124 // - there are cases where it's required for correctness. e.g:
125 // template<class X> using pvec = vector<x*>; pvec<int> x;
126 // There's no Decl `pvec<int>`, we must choose `pvec<X>` or `vector<int*>`
127 // and both are lossy. We must know upfront what the caller ultimately wants.
128 //
129 // FIXME: improve common dependent scope using name lookup in primary templates.
130 // We currently handle several dependent constructs, but some others remain to
131 // be handled:
132 // - UnresolvedUsingTypenameDecl
133 struct TargetFinder {
134  using RelSet = DeclRelationSet;
135  using Rel = DeclRelation;
136 
137 private:
138  const HeuristicResolver *Resolver;
139  llvm::SmallDenseMap<const NamedDecl *,
140  std::pair<RelSet, /*InsertionOrder*/ size_t>>
141  Decls;
142  llvm::SmallDenseMap<const Decl *, RelSet> Seen;
143  RelSet Flags;
144 
145  template <typename T> void debug(T &Node, RelSet Flags) {
146  dlog("visit [{0}] {1}", Flags, nodeToString(DynTypedNode::create(Node)));
147  }
148 
149  void report(const NamedDecl *D, RelSet Flags) {
150  dlog("--> [{0}] {1}", Flags, nodeToString(DynTypedNode::create(*D)));
151  auto It = Decls.try_emplace(D, std::make_pair(Flags, Decls.size()));
152  // If already exists, update the flags.
153  if (!It.second)
154  It.first->second.first |= Flags;
155  }
156 
157 public:
158  TargetFinder(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
159 
160  llvm::SmallVector<std::pair<const NamedDecl *, RelSet>, 1> takeDecls() const {
161  using ValTy = std::pair<const NamedDecl *, RelSet>;
162  llvm::SmallVector<ValTy, 1> Result;
163  Result.resize(Decls.size());
164  for (const auto &Elem : Decls)
165  Result[Elem.second.second] = {Elem.first, Elem.second.first};
166  return Result;
167  }
168 
169  void add(const Decl *Dcl, RelSet Flags) {
170  const NamedDecl *D = llvm::dyn_cast_or_null<NamedDecl>(Dcl);
171  if (!D)
172  return;
173  debug(*D, Flags);
174 
175  // Avoid recursion (which can arise in the presence of heuristic
176  // resolution of dependent names) by exiting early if we have
177  // already seen this decl with all flags in Flags.
178  auto Res = Seen.try_emplace(D);
179  if (!Res.second && Res.first->second.contains(Flags))
180  return;
181  Res.first->second |= Flags;
182 
183  if (const UsingDirectiveDecl *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
184  D = UDD->getNominatedNamespaceAsWritten();
185 
186  if (const TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) {
187  add(TND->getUnderlyingType(), Flags | Rel::Underlying);
188  Flags |= Rel::Alias; // continue with the alias.
189  } else if (const UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
190  // no Underlying as this is a non-renaming alias.
191  for (const UsingShadowDecl *S : UD->shadows())
192  add(S->getUnderlyingDecl(), Flags);
193  Flags |= Rel::Alias; // continue with the alias.
194  } else if (const UsingEnumDecl *UED = dyn_cast<UsingEnumDecl>(D)) {
195  add(UED->getEnumDecl(), Flags);
196  Flags |= Rel::Alias; // continue with the alias.
197  } else if (const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) {
198  add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying);
199  Flags |= Rel::Alias; // continue with the alias
200  } else if (const UnresolvedUsingValueDecl *UUVD =
201  dyn_cast<UnresolvedUsingValueDecl>(D)) {
202  if (Resolver) {
203  for (const NamedDecl *Target : Resolver->resolveUsingValueDecl(UUVD)) {
204  add(Target, Flags); // no Underlying as this is a non-renaming alias
205  }
206  }
207  Flags |= Rel::Alias; // continue with the alias
208  } else if (const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
209  // Include the Introducing decl, but don't traverse it. This may end up
210  // including *all* shadows, which we don't want.
211  report(USD->getIntroducer(), Flags | Rel::Alias);
212  // Shadow decls are synthetic and not themselves interesting.
213  // Record the underlying decl instead, if allowed.
214  D = USD->getTargetDecl();
215  } else if (const auto *DG = dyn_cast<CXXDeductionGuideDecl>(D)) {
216  D = DG->getDeducedTemplate();
217  } else if (const ObjCImplementationDecl *IID =
218  dyn_cast<ObjCImplementationDecl>(D)) {
219  // Treat ObjC{Interface,Implementation}Decl as if they were a decl/def
220  // pair as long as the interface isn't implicit.
221  if (const auto *CID = IID->getClassInterface())
222  if (const auto *DD = CID->getDefinition())
223  if (!DD->isImplicitInterfaceDecl())
224  D = DD;
225  } else if (const ObjCCategoryImplDecl *CID =
226  dyn_cast<ObjCCategoryImplDecl>(D)) {
227  // Treat ObjC{Category,CategoryImpl}Decl as if they were a decl/def pair.
228  D = CID->getCategoryDecl();
229  }
230  if (!D)
231  return;
232 
233  if (const Decl *Pat = getTemplatePattern(D)) {
234  assert(Pat != D);
235  add(Pat, Flags | Rel::TemplatePattern);
236  // Now continue with the instantiation.
237  Flags |= Rel::TemplateInstantiation;
238  }
239 
240  report(D, Flags);
241  }
242 
243  void add(const Stmt *S, RelSet Flags) {
244  if (!S)
245  return;
246  debug(*S, Flags);
247  struct Visitor : public ConstStmtVisitor<Visitor> {
248  TargetFinder &Outer;
249  RelSet Flags;
250  Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}
251 
252  void VisitCallExpr(const CallExpr *CE) {
253  Outer.add(CE->getCalleeDecl(), Flags);
254  }
255  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
256  Outer.add(E->getNamedConcept(), Flags);
257  }
258  void VisitDeclRefExpr(const DeclRefExpr *DRE) {
259  const Decl *D = DRE->getDecl();
260  // UsingShadowDecl allows us to record the UsingDecl.
261  // getFoundDecl() returns the wrong thing in other cases (templates).
262  if (auto *USD = llvm::dyn_cast<UsingShadowDecl>(DRE->getFoundDecl()))
263  D = USD;
264  Outer.add(D, Flags);
265  }
266  void VisitMemberExpr(const MemberExpr *ME) {
267  const Decl *D = ME->getMemberDecl();
268  if (auto *USD =
269  llvm::dyn_cast<UsingShadowDecl>(ME->getFoundDecl().getDecl()))
270  D = USD;
271  Outer.add(D, Flags);
272  }
273  void VisitOverloadExpr(const OverloadExpr *OE) {
274  for (auto *D : OE->decls())
275  Outer.add(D, Flags);
276  }
277  void VisitSizeOfPackExpr(const SizeOfPackExpr *SE) {
278  Outer.add(SE->getPack(), Flags);
279  }
280  void VisitCXXConstructExpr(const CXXConstructExpr *CCE) {
281  Outer.add(CCE->getConstructor(), Flags);
282  }
283  void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {
284  for (const DesignatedInitExpr::Designator &D :
285  llvm::reverse(DIE->designators()))
286  if (D.isFieldDesignator()) {
287  Outer.add(D.getField(), Flags);
288  // We don't know which designator was intended, we assume the outer.
289  break;
290  }
291  }
292  void VisitGotoStmt(const GotoStmt *Goto) {
293  if (auto *LabelDecl = Goto->getLabel())
294  Outer.add(LabelDecl, Flags);
295  }
296  void VisitLabelStmt(const LabelStmt *Label) {
297  if (auto *LabelDecl = Label->getDecl())
298  Outer.add(LabelDecl, Flags);
299  }
300  void
301  VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
302  if (Outer.Resolver) {
303  for (const NamedDecl *D : Outer.Resolver->resolveMemberExpr(E)) {
304  Outer.add(D, Flags);
305  }
306  }
307  }
308  void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
309  if (Outer.Resolver) {
310  for (const NamedDecl *D : Outer.Resolver->resolveDeclRefExpr(E)) {
311  Outer.add(D, Flags);
312  }
313  }
314  }
315  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
316  Outer.add(OIRE->getDecl(), Flags);
317  }
318  void VisitObjCMessageExpr(const ObjCMessageExpr *OME) {
319  Outer.add(OME->getMethodDecl(), Flags);
320  }
321  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
322  if (OPRE->isExplicitProperty())
323  Outer.add(OPRE->getExplicitProperty(), Flags);
324  else {
325  if (OPRE->isMessagingGetter())
326  Outer.add(OPRE->getImplicitPropertyGetter(), Flags);
327  if (OPRE->isMessagingSetter())
328  Outer.add(OPRE->getImplicitPropertySetter(), Flags);
329  }
330  }
331  void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
332  Outer.add(OPE->getProtocol(), Flags);
333  }
334  void VisitOpaqueValueExpr(const OpaqueValueExpr *OVE) {
335  Outer.add(OVE->getSourceExpr(), Flags);
336  }
337  void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) {
338  Outer.add(POE->getSyntacticForm(), Flags);
339  }
340  void VisitCXXNewExpr(const CXXNewExpr *CNE) {
341  Outer.add(CNE->getOperatorNew(), Flags);
342  }
343  void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE) {
344  Outer.add(CDE->getOperatorDelete(), Flags);
345  }
346  };
347  Visitor(*this, Flags).Visit(S);
348  }
349 
350  void add(QualType T, RelSet Flags) {
351  if (T.isNull())
352  return;
353  debug(T, Flags);
354  struct Visitor : public TypeVisitor<Visitor> {
355  TargetFinder &Outer;
356  RelSet Flags;
357  Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}
358 
359  void VisitTagType(const TagType *TT) {
360  Outer.add(TT->getAsTagDecl(), Flags);
361  }
362 
363  void VisitElaboratedType(const ElaboratedType *ET) {
364  Outer.add(ET->desugar(), Flags);
365  }
366 
367  void VisitInjectedClassNameType(const InjectedClassNameType *ICNT) {
368  Outer.add(ICNT->getDecl(), Flags);
369  }
370 
371  void VisitDecltypeType(const DecltypeType *DTT) {
372  Outer.add(DTT->getUnderlyingType(), Flags | Rel::Underlying);
373  }
374  void VisitDeducedType(const DeducedType *DT) {
375  // FIXME: In practice this doesn't work: the AutoType you find inside
376  // TypeLoc never has a deduced type. https://llvm.org/PR42914
377  Outer.add(DT->getDeducedType(), Flags | Rel::Underlying);
378  }
379  void VisitDeducedTemplateSpecializationType(
380  const DeducedTemplateSpecializationType *DTST) {
381  // FIXME: This is a workaround for https://llvm.org/PR42914,
382  // which is causing DTST->getDeducedType() to be empty. We
383  // fall back to the template pattern and miss the instantiation
384  // even when it's known in principle. Once that bug is fixed,
385  // this method can be removed (the existing handling in
386  // VisitDeducedType() is sufficient).
387  if (auto *TD = DTST->getTemplateName().getAsTemplateDecl())
388  Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
389  }
390  void VisitDependentNameType(const DependentNameType *DNT) {
391  if (Outer.Resolver) {
392  for (const NamedDecl *ND :
393  Outer.Resolver->resolveDependentNameType(DNT)) {
394  Outer.add(ND, Flags);
395  }
396  }
397  }
398  void VisitDependentTemplateSpecializationType(
399  const DependentTemplateSpecializationType *DTST) {
400  if (Outer.Resolver) {
401  for (const NamedDecl *ND :
402  Outer.Resolver->resolveTemplateSpecializationType(DTST)) {
403  Outer.add(ND, Flags);
404  }
405  }
406  }
407  void VisitTypedefType(const TypedefType *TT) {
408  if (shouldSkipTypedef(TT->getDecl()))
409  return;
410  Outer.add(TT->getDecl(), Flags);
411  }
412  void
413  VisitTemplateSpecializationType(const TemplateSpecializationType *TST) {
414  // Have to handle these case-by-case.
415 
416  // templated type aliases: there's no specialized/instantiated using
417  // decl to point to. So try to find a decl for the underlying type
418  // (after substitution), and failing that point to the (templated) using
419  // decl.
420  if (TST->isTypeAlias()) {
421  Outer.add(TST->getAliasedType(), Flags | Rel::Underlying);
422  // Don't *traverse* the alias, which would result in traversing the
423  // template of the underlying type.
424  Outer.report(
425  TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl(),
426  Flags | Rel::Alias | Rel::TemplatePattern);
427  }
428  // specializations of template template parameters aren't instantiated
429  // into decls, so they must refer to the parameter itself.
430  else if (const auto *Parm =
431  llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
432  TST->getTemplateName().getAsTemplateDecl()))
433  Outer.add(Parm, Flags);
434  // class template specializations have a (specialized) CXXRecordDecl.
435  else if (const CXXRecordDecl *RD = TST->getAsCXXRecordDecl())
436  Outer.add(RD, Flags); // add(Decl) will despecialize if needed.
437  else {
438  // fallback: the (un-specialized) declaration from primary template.
439  if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
440  Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
441  }
442  }
443  void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT) {
444  Outer.add(TTPT->getDecl(), Flags);
445  }
446  void VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
447  Outer.add(OIT->getDecl(), Flags);
448  }
449  void VisitObjCObjectType(const ObjCObjectType *OOT) {
450  // Make all of the protocols targets since there's no child nodes for
451  // protocols. This isn't needed for the base type, which *does* have a
452  // child `ObjCInterfaceTypeLoc`. This structure is a hack, but it works
453  // well for go-to-definition.
454  unsigned NumProtocols = OOT->getNumProtocols();
455  for (unsigned I = 0; I < NumProtocols; I++)
456  Outer.add(OOT->getProtocol(I), Flags);
457  }
458  };
459  Visitor(*this, Flags).Visit(T.getTypePtr());
460  }
461 
462  void add(const NestedNameSpecifier *NNS, RelSet Flags) {
463  if (!NNS)
464  return;
465  debug(*NNS, Flags);
466  switch (NNS->getKind()) {
467  case NestedNameSpecifier::Namespace:
468  add(NNS->getAsNamespace(), Flags);
469  return;
470  case NestedNameSpecifier::NamespaceAlias:
471  add(NNS->getAsNamespaceAlias(), Flags);
472  return;
473  case NestedNameSpecifier::Identifier:
474  if (Resolver) {
475  add(QualType(Resolver->resolveNestedNameSpecifierToType(NNS), 0),
476  Flags);
477  }
478  return;
479  case NestedNameSpecifier::TypeSpec:
480  case NestedNameSpecifier::TypeSpecWithTemplate:
481  add(QualType(NNS->getAsType(), 0), Flags);
482  return;
483  case NestedNameSpecifier::Global:
484  // This should be TUDecl, but we can't get a pointer to it!
485  return;
486  case NestedNameSpecifier::Super:
487  add(NNS->getAsRecordDecl(), Flags);
488  return;
489  }
490  llvm_unreachable("unhandled NestedNameSpecifier::SpecifierKind");
491  }
492 
493  void add(const CXXCtorInitializer *CCI, RelSet Flags) {
494  if (!CCI)
495  return;
496  debug(*CCI, Flags);
497 
498  if (CCI->isAnyMemberInitializer())
499  add(CCI->getAnyMember(), Flags);
500  // Constructor calls contain a TypeLoc node, so we don't handle them here.
501  }
502 
503  void add(const TemplateArgument &Arg, RelSet Flags) {
504  // Only used for template template arguments.
505  // For type and non-type template arguments, SelectionTree
506  // will hit a more specific node (e.g. a TypeLoc or a
507  // DeclRefExpr).
508  if (Arg.getKind() == TemplateArgument::Template ||
509  Arg.getKind() == TemplateArgument::TemplateExpansion) {
510  if (TemplateDecl *TD = Arg.getAsTemplate().getAsTemplateDecl()) {
511  report(TD, Flags);
512  }
513  }
514  }
515 };
516 
517 } // namespace
518 
519 llvm::SmallVector<std::pair<const NamedDecl *, DeclRelationSet>, 1>
520 allTargetDecls(const DynTypedNode &N, const HeuristicResolver *Resolver) {
521  dlog("allTargetDecls({0})", nodeToString(N));
522  TargetFinder Finder(Resolver);
524  if (const Decl *D = N.get<Decl>())
525  Finder.add(D, Flags);
526  else if (const Stmt *S = N.get<Stmt>())
527  Finder.add(S, Flags);
528  else if (const NestedNameSpecifierLoc *NNSL = N.get<NestedNameSpecifierLoc>())
529  Finder.add(NNSL->getNestedNameSpecifier(), Flags);
530  else if (const NestedNameSpecifier *NNS = N.get<NestedNameSpecifier>())
531  Finder.add(NNS, Flags);
532  else if (const TypeLoc *TL = N.get<TypeLoc>())
533  Finder.add(TL->getType(), Flags);
534  else if (const QualType *QT = N.get<QualType>())
535  Finder.add(*QT, Flags);
536  else if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>())
537  Finder.add(CCI, Flags);
538  else if (const TemplateArgumentLoc *TAL = N.get<TemplateArgumentLoc>())
539  Finder.add(TAL->getArgument(), Flags);
540  else if (const CXXBaseSpecifier *CBS = N.get<CXXBaseSpecifier>())
541  Finder.add(CBS->getTypeSourceInfo()->getType(), Flags);
542  return Finder.takeDecls();
543 }
544 
545 llvm::SmallVector<const NamedDecl *, 1>
546 targetDecl(const DynTypedNode &N, DeclRelationSet Mask,
547  const HeuristicResolver *Resolver) {
548  llvm::SmallVector<const NamedDecl *, 1> Result;
549  for (const auto &Entry : allTargetDecls(N, Resolver)) {
550  if (!(Entry.second & ~Mask))
551  Result.push_back(Entry.first);
552  }
553  return Result;
554 }
555 
556 llvm::SmallVector<const NamedDecl *, 1>
558  const HeuristicResolver *Resolver) {
559  assert(!(Mask & (DeclRelation::TemplatePattern |
561  "explicitReferenceTargets handles templates on its own");
562  auto Decls = allTargetDecls(N, Resolver);
563 
564  // We prefer to return template instantiation, but fallback to template
565  // pattern if instantiation is not available.
567 
568  llvm::SmallVector<const NamedDecl *, 1> TemplatePatterns;
569  llvm::SmallVector<const NamedDecl *, 1> Targets;
570  bool SeenTemplateInstantiations = false;
571  for (auto &D : Decls) {
572  if (D.second & ~Mask)
573  continue;
574  if (D.second & DeclRelation::TemplatePattern) {
575  TemplatePatterns.push_back(D.first);
576  continue;
577  }
579  SeenTemplateInstantiations = true;
580  Targets.push_back(D.first);
581  }
582  if (!SeenTemplateInstantiations)
583  Targets.insert(Targets.end(), TemplatePatterns.begin(),
584  TemplatePatterns.end());
585  return Targets;
586 }
587 
588 namespace {
589 llvm::SmallVector<ReferenceLoc> refInDecl(const Decl *D,
590  const HeuristicResolver *Resolver) {
591  struct Visitor : ConstDeclVisitor<Visitor> {
592  Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
593 
594  const HeuristicResolver *Resolver;
595  llvm::SmallVector<ReferenceLoc> Refs;
596 
597  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
598  // We want to keep it as non-declaration references, as the
599  // "using namespace" declaration doesn't have a name.
600  Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
601  D->getIdentLocation(),
602  /*IsDecl=*/false,
603  {D->getNominatedNamespaceAsWritten()}});
604  }
605 
606  void VisitUsingDecl(const UsingDecl *D) {
607  // "using ns::identifier;" is a non-declaration reference.
608  Refs.push_back(ReferenceLoc{
609  D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,
610  explicitReferenceTargets(DynTypedNode::create(*D),
611  DeclRelation::Underlying, Resolver)});
612  }
613 
614  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
615  // For namespace alias, "namespace Foo = Target;", we add two references.
616  // Add a declaration reference for Foo.
617  VisitNamedDecl(D);
618  // Add a non-declaration reference for Target.
619  Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
620  D->getTargetNameLoc(),
621  /*IsDecl=*/false,
622  {D->getAliasedNamespace()}});
623  }
624 
625  void VisitNamedDecl(const NamedDecl *ND) {
626  // We choose to ignore {Class, Function, Var, TypeAlias}TemplateDecls. As
627  // as their underlying decls, covering the same range, will be visited.
628  if (llvm::isa<ClassTemplateDecl>(ND) ||
629  llvm::isa<FunctionTemplateDecl>(ND) ||
630  llvm::isa<VarTemplateDecl>(ND) ||
631  llvm::isa<TypeAliasTemplateDecl>(ND))
632  return;
633  // FIXME: decide on how to surface destructors when we need them.
634  if (llvm::isa<CXXDestructorDecl>(ND))
635  return;
636  // Filter anonymous decls, name location will point outside the name token
637  // and the clients are not prepared to handle that.
638  if (ND->getDeclName().isIdentifier() &&
639  !ND->getDeclName().getAsIdentifierInfo())
640  return;
641  Refs.push_back(ReferenceLoc{getQualifierLoc(*ND),
642  ND->getLocation(),
643  /*IsDecl=*/true,
644  {ND}});
645  }
646 
647  void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *DG) {
648  // The class template name in a deduction guide targets the class
649  // template.
650  Refs.push_back(ReferenceLoc{DG->getQualifierLoc(),
651  DG->getNameInfo().getLoc(),
652  /*IsDecl=*/false,
653  {DG->getDeducedTemplate()}});
654  }
655 
656  void VisitObjCMethodDecl(const ObjCMethodDecl *OMD) {
657  // The name may have several tokens, we can only report the first.
658  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
659  OMD->getSelectorStartLoc(),
660  /*IsDecl=*/true,
661  {OMD}});
662  }
663 
664  void visitProtocolList(
665  llvm::iterator_range<ObjCProtocolList::iterator> Protocols,
666  llvm::iterator_range<const SourceLocation *> Locations) {
667  for (const auto &P : llvm::zip(Protocols, Locations)) {
668  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
669  std::get<1>(P),
670  /*IsDecl=*/false,
671  {std::get<0>(P)}});
672  }
673  }
674 
675  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *OID) {
676  if (OID->isThisDeclarationADefinition())
677  visitProtocolList(OID->protocols(), OID->protocol_locs());
678  Base::VisitObjCInterfaceDecl(OID); // Visit the interface's name.
679  }
680 
681  void VisitObjCCategoryDecl(const ObjCCategoryDecl *OCD) {
682  visitProtocolList(OCD->protocols(), OCD->protocol_locs());
683  // getLocation is the extended class's location, not the category's.
684  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
685  OCD->getLocation(),
686  /*IsDecl=*/false,
687  {OCD->getClassInterface()}});
688  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
689  OCD->getCategoryNameLoc(),
690  /*IsDecl=*/true,
691  {OCD}});
692  }
693 
694  void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *OCID) {
695  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
696  OCID->getLocation(),
697  /*IsDecl=*/false,
698  {OCID->getClassInterface()}});
699  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
700  OCID->getCategoryNameLoc(),
701  /*IsDecl=*/true,
702  {OCID->getCategoryDecl()}});
703  }
704 
705  void VisitObjCProtocolDecl(const ObjCProtocolDecl *OPD) {
706  if (OPD->isThisDeclarationADefinition())
707  visitProtocolList(OPD->protocols(), OPD->protocol_locs());
708  Base::VisitObjCProtocolDecl(OPD); // Visit the protocol's name.
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 VisitTagTypeLoc(TagTypeLoc L) {
858  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
859  L.getNameLoc(),
860  /*IsDecl=*/false,
861  {L.getDecl()}});
862  }
863 
864  void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {
865  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
866  L.getNameLoc(),
867  /*IsDecl=*/false,
868  {L.getDecl()}});
869  }
870 
871  void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
872  // We must ensure template type aliases are included in results if they
873  // were written in the source code, e.g. in
874  // template <class T> using valias = vector<T>;
875  // ^valias<int> x;
876  // 'explicitReferenceTargets' will return:
877  // 1. valias with mask 'Alias'.
878  // 2. 'vector<int>' with mask 'Underlying'.
879  // we want to return only #1 in this case.
880  Refs.push_back(ReferenceLoc{
881  NestedNameSpecifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
882  explicitReferenceTargets(DynTypedNode::create(L.getType()),
883  DeclRelation::Alias, Resolver)});
884  }
885  void VisitDeducedTemplateSpecializationTypeLoc(
886  DeducedTemplateSpecializationTypeLoc L) {
887  Refs.push_back(ReferenceLoc{
888  NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
889  explicitReferenceTargets(DynTypedNode::create(L.getType()),
890  DeclRelation::Alias, Resolver)});
891  }
892 
893  void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
894  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
895  TL.getNameLoc(),
896  /*IsDecl=*/false,
897  {TL.getDecl()}});
898  }
899 
900  void VisitDependentTemplateSpecializationTypeLoc(
901  DependentTemplateSpecializationTypeLoc L) {
902  Refs.push_back(
903  ReferenceLoc{L.getQualifierLoc(), L.getTemplateNameLoc(),
904  /*IsDecl=*/false,
906  DynTypedNode::create(L.getType()), {}, Resolver)});
907  }
908 
909  void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
910  Refs.push_back(
911  ReferenceLoc{L.getQualifierLoc(), L.getNameLoc(),
912  /*IsDecl=*/false,
914  DynTypedNode::create(L.getType()), {}, Resolver)});
915  }
916 
917  void VisitTypedefTypeLoc(TypedefTypeLoc L) {
918  if (shouldSkipTypedef(L.getTypedefNameDecl()))
919  return;
920  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
921  L.getNameLoc(),
922  /*IsDecl=*/false,
923  {L.getTypedefNameDecl()}});
924  }
925 
926  void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc L) {
927  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
928  L.getNameLoc(),
929  /*IsDecl=*/false,
930  {L.getIFaceDecl()}});
931  }
932 
933  void VisitObjCObjectTypeLoc(ObjCObjectTypeLoc L) {
934  unsigned NumProtocols = L.getNumProtocols();
935  for (unsigned I = 0; I < NumProtocols; I++) {
936  Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
937  L.getProtocolLoc(I),
938  /*IsDecl=*/false,
939  {L.getProtocol(I)}});
940  }
941  }
942  };
943 
944  Visitor V{Resolver};
945  V.Visit(L.getUnqualifiedLoc());
946  return V.Refs;
947 }
948 
949 class ExplicitReferenceCollector
950  : public RecursiveASTVisitor<ExplicitReferenceCollector> {
951 public:
952  ExplicitReferenceCollector(llvm::function_ref<void(ReferenceLoc)> Out,
953  const HeuristicResolver *Resolver)
954  : Out(Out), Resolver(Resolver) {
955  assert(Out);
956  }
957 
958  bool VisitTypeLoc(TypeLoc TTL) {
959  if (TypeLocsToSkip.count(TTL.getBeginLoc()))
960  return true;
961  visitNode(DynTypedNode::create(TTL));
962  return true;
963  }
964 
965  bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) {
966  // ElaboratedTypeLoc will reports information for its inner type loc.
967  // Otherwise we loose information about inner types loc's qualifier.
968  TypeLoc Inner = L.getNamedTypeLoc().getUnqualifiedLoc();
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.
1013  case TemplateArgument::Pack:
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 TraverseConstructorInitializer(CXXCtorInitializer *Init) {
1038  visitNode(DynTypedNode::create(*Init));
1039  return RecursiveASTVisitor::TraverseConstructorInitializer(Init);
1040  }
1041 
1042 private:
1043  /// Obtain information about a reference directly defined in \p N. Does not
1044  /// recurse into child nodes, e.g. do not expect references for constructor
1045  /// initializers
1046  ///
1047  /// Any of the fields in the returned structure can be empty, but not all of
1048  /// them, e.g.
1049  /// - for implicitly generated nodes (e.g. MemberExpr from range-based-for),
1050  /// source location information may be missing,
1051  /// - for dependent code, targets may be empty.
1052  ///
1053  /// (!) For the purposes of this function declarations are not considered to
1054  /// be references. However, declarations can have references inside them,
1055  /// e.g. 'namespace foo = std' references namespace 'std' and this
1056  /// function will return the corresponding reference.
1057  llvm::SmallVector<ReferenceLoc> explicitReference(DynTypedNode N) {
1058  if (auto *D = N.get<Decl>())
1059  return refInDecl(D, Resolver);
1060  if (auto *S = N.get<Stmt>())
1061  return refInStmt(S, Resolver);
1062  if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) {
1063  // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases.
1064  return {ReferenceLoc{
1065  NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false,
1067  DynTypedNode::create(*NNSL->getNestedNameSpecifier()),
1068  DeclRelation::Alias, Resolver)}};
1069  }
1070  if (const TypeLoc *TL = N.get<TypeLoc>())
1071  return refInTypeLoc(*TL, Resolver);
1072  if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) {
1073  // Other type initializers (e.g. base initializer) are handled by visiting
1074  // the typeLoc.
1075  if (CCI->isAnyMemberInitializer()) {
1076  return {ReferenceLoc{NestedNameSpecifierLoc(),
1077  CCI->getMemberLocation(),
1078  /*IsDecl=*/false,
1079  {CCI->getAnyMember()}}};
1080  }
1081  }
1082  // We do not have location information for other nodes (QualType, etc)
1083  return {};
1084  }
1085 
1086  void visitNode(DynTypedNode N) {
1087  for (auto &R : explicitReference(N))
1088  reportReference(std::move(R), N);
1089  }
1090 
1091  void reportReference(ReferenceLoc &&Ref, DynTypedNode N) {
1092  // Strip null targets that can arise from invalid code.
1093  // (This avoids having to check for null everywhere we insert)
1094  llvm::erase_value(Ref.Targets, nullptr);
1095  // Our promise is to return only references from the source code. If we lack
1096  // location information, skip these nodes.
1097  // Normally this should not happen in practice, unless there are bugs in the
1098  // traversals or users started the traversal at an implicit node.
1099  if (Ref.NameLoc.isInvalid()) {
1100  dlog("invalid location at node {0}", nodeToString(N));
1101  return;
1102  }
1103  Out(Ref);
1104  }
1105 
1106  llvm::function_ref<void(ReferenceLoc)> Out;
1107  const HeuristicResolver *Resolver;
1108  /// TypeLocs starting at these locations must be skipped, see
1109  /// TraverseElaboratedTypeSpecifierLoc for details.
1110  llvm::DenseSet<SourceLocation> TypeLocsToSkip;
1111 };
1112 } // namespace
1113 
1114 void findExplicitReferences(const Stmt *S,
1115  llvm::function_ref<void(ReferenceLoc)> Out,
1116  const HeuristicResolver *Resolver) {
1117  assert(S);
1118  ExplicitReferenceCollector(Out, Resolver).TraverseStmt(const_cast<Stmt *>(S));
1119 }
1121  llvm::function_ref<void(ReferenceLoc)> Out,
1122  const HeuristicResolver *Resolver) {
1123  assert(D);
1124  ExplicitReferenceCollector(Out, Resolver).TraverseDecl(const_cast<Decl *>(D));
1125 }
1126 void findExplicitReferences(const ASTContext &AST,
1127  llvm::function_ref<void(ReferenceLoc)> Out,
1128  const HeuristicResolver *Resolver) {
1129  ExplicitReferenceCollector(Out, Resolver)
1130  .TraverseAST(const_cast<ASTContext &>(AST));
1131 }
1132 
1133 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelation R) {
1134  switch (R) {
1135 #define REL_CASE(X) \
1136  case DeclRelation::X: \
1137  return OS << #X;
1138  REL_CASE(Alias);
1142 #undef REL_CASE
1143  }
1144  llvm_unreachable("Unhandled DeclRelation enum");
1145 }
1146 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelationSet RS) {
1147  const char *Sep = "";
1148  for (unsigned I = 0; I < RS.S.size(); ++I) {
1149  if (RS.S.test(I)) {
1150  OS << Sep << static_cast<DeclRelation>(I);
1151  Sep = "|";
1152  }
1153  }
1154  return OS;
1155 }
1156 
1157 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ReferenceLoc R) {
1158  // note we cannot print R.NameLoc without a source manager.
1159  OS << "targets = {";
1160  bool First = true;
1161  for (const NamedDecl *T : R.Targets) {
1162  if (!First)
1163  OS << ", ";
1164  else
1165  First = false;
1167  }
1168  OS << "}";
1169  if (R.Qualifier) {
1170  OS << ", qualifier = '";
1171  R.Qualifier.getNestedNameSpecifier()->print(OS,
1172  PrintingPolicy(LangOptions()));
1173  OS << "'";
1174  }
1175  if (R.IsDecl)
1176  OS << ", decl";
1177  return OS;
1178 }
1179 
1180 } // namespace clangd
1181 } // namespace clang
dlog
#define dlog(...)
Definition: Logger.h:102
RecursiveASTVisitor
Flags
MixFlags Flags
Definition: EasilySwappableParametersCheck.cpp:1086
Label
std::string Label
Definition: InlayHintTests.cpp:38
E
const Expr * E
Definition: AvoidBindCheck.cpp:88
Type
NodeType Type
Definition: HTMLGenerator.cpp:73
Refs
RefSlab Refs
Definition: SymbolCollectorTests.cpp:311
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:193
clang::clangd::DeclRelation
DeclRelation
Definition: FindTarget.h:96
Outer
std::pair< Context, Canceler > Outer
Definition: CancellationTests.cpp:49
clang::clangd::HeuristicResolver
Definition: HeuristicResolver.h:46
clang::clangd::DeclRelationSet
Definition: FindTarget.h:176
FindTarget.h
Target
std::string Target
Definition: QueryDriverDatabase.cpp:64
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:131
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:49
clang::clangd::printQualifiedName
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
Definition: AST.cpp:174
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:254
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:557
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:2013
Parm
Params Parm
Definition: ConfigCompileTests.cpp:41
Parent
const Node * Parent
Definition: ExtractFunction.cpp:152
Entry
Definition: Modularize.cpp:428
HeuristicResolver.h
REL_CASE
#define REL_CASE(X)
DeducedType
QualType DeducedType
Definition: AST.cpp:471
clang::clangd::ReferenceLoc
Information about a reference written in the source code, independent of the actual AST node that thi...
Definition: FindTarget.h:129
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:163
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:520
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:546
clang::clangd::ReferenceLoc::IsDecl
bool IsDecl
True if the reference is a declaration or definition;.
Definition: FindTarget.h:135
clang::clangd::DeclRelation::TemplateInstantiation
@ TemplateInstantiation
This is the template instantiation that was referred to.
Out
CompiledFragmentImpl & Out
Definition: ConfigCompile.cpp:100
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:1114
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:141
clang::clangd::DeclRelation::Alias
@ Alias
This declaration is an alias that was referred to.
AST.h