comparison clang-tools-extra/clangd/FindTarget.cpp @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents 0572611fdcc8
children 5f17cb93ff66
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
6 // 6 //
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 8
9 #include "FindTarget.h" 9 #include "FindTarget.h"
10 #include "AST.h" 10 #include "AST.h"
11 #include "HeuristicResolver.h"
11 #include "support/Logger.h" 12 #include "support/Logger.h"
12 #include "clang/AST/ASTTypeTraits.h" 13 #include "clang/AST/ASTTypeTraits.h"
13 #include "clang/AST/Decl.h" 14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclBase.h"
14 #include "clang/AST/DeclCXX.h" 16 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/DeclTemplate.h" 17 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/DeclVisitor.h" 18 #include "clang/AST/DeclVisitor.h"
17 #include "clang/AST/DeclarationName.h" 19 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/Expr.h" 20 #include "clang/AST/Expr.h"
42 #include <vector> 44 #include <vector>
43 45
44 namespace clang { 46 namespace clang {
45 namespace clangd { 47 namespace clangd {
46 namespace { 48 namespace {
47 using ast_type_traits::DynTypedNode; 49
48 50 LLVM_ATTRIBUTE_UNUSED std::string nodeToString(const DynTypedNode &N) {
49 LLVM_ATTRIBUTE_UNUSED std::string
50 nodeToString(const ast_type_traits::DynTypedNode &N) {
51 std::string S = std::string(N.getNodeKind().asStringRef()); 51 std::string S = std::string(N.getNodeKind().asStringRef());
52 { 52 {
53 llvm::raw_string_ostream OS(S); 53 llvm::raw_string_ostream OS(S);
54 OS << ": "; 54 OS << ": ";
55 N.print(OS, PrintingPolicy(LangOptions())); 55 N.print(OS, PrintingPolicy(LangOptions()));
56 } 56 }
57 std::replace(S.begin(), S.end(), '\n', ' '); 57 std::replace(S.begin(), S.end(), '\n', ' ');
58 return S; 58 return S;
59 }
60
61 // Given a dependent type and a member name, heuristically resolve the
62 // name to one or more declarations.
63 // The current heuristic is simply to look up the name in the primary
64 // template. This is a heuristic because the template could potentially
65 // have specializations that declare different members.
66 // Multiple declarations could be returned if the name is overloaded
67 // (e.g. an overloaded method in the primary template).
68 // This heuristic will give the desired answer in many cases, e.g.
69 // for a call to vector<T>::size().
70 // The name to look up is provided in the form of a factory that takes
71 // an ASTContext, because an ASTContext may be needed to obtain the
72 // name (e.g. if it's an operator name), but the caller may not have
73 // access to an ASTContext.
74 std::vector<const NamedDecl *> getMembersReferencedViaDependentName(
75 const Type *T,
76 llvm::function_ref<DeclarationName(ASTContext &)> NameFactory,
77 bool IsNonstaticMember) {
78 if (!T)
79 return {};
80 if (auto *ET = T->getAs<EnumType>()) {
81 auto Result =
82 ET->getDecl()->lookup(NameFactory(ET->getDecl()->getASTContext()));
83 return {Result.begin(), Result.end()};
84 }
85 if (auto *ICNT = T->getAs<InjectedClassNameType>()) {
86 T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
87 }
88 auto *TST = T->getAs<TemplateSpecializationType>();
89 if (!TST)
90 return {};
91 const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
92 TST->getTemplateName().getAsTemplateDecl());
93 if (!TD)
94 return {};
95 CXXRecordDecl *RD = TD->getTemplatedDecl();
96 if (!RD->hasDefinition())
97 return {};
98 RD = RD->getDefinition();
99 DeclarationName Name = NameFactory(RD->getASTContext());
100 return RD->lookupDependentName(Name, [=](const NamedDecl *D) {
101 return IsNonstaticMember ? D->isCXXInstanceMember()
102 : !D->isCXXInstanceMember();
103 });
104 }
105
106 // Given the type T of a dependent expression that appears of the LHS of a "->",
107 // heuristically find a corresponding pointee type in whose scope we could look
108 // up the name appearing on the RHS.
109 const Type *getPointeeType(const Type *T) {
110 if (!T)
111 return nullptr;
112
113 if (T->isPointerType()) {
114 return T->getAs<PointerType>()->getPointeeType().getTypePtrOrNull();
115 }
116
117 // Try to handle smart pointer types.
118
119 // Look up operator-> in the primary template. If we find one, it's probably a
120 // smart pointer type.
121 auto ArrowOps = getMembersReferencedViaDependentName(
122 T,
123 [](ASTContext &Ctx) {
124 return Ctx.DeclarationNames.getCXXOperatorName(OO_Arrow);
125 },
126 /*IsNonStaticMember=*/true);
127 if (ArrowOps.empty())
128 return nullptr;
129
130 // Getting the return type of the found operator-> method decl isn't useful,
131 // because we discarded template arguments to perform lookup in the primary
132 // template scope, so the return type would just have the form U* where U is a
133 // template parameter type.
134 // Instead, just handle the common case where the smart pointer type has the
135 // form of SmartPtr<X, ...>, and assume X is the pointee type.
136 auto *TST = T->getAs<TemplateSpecializationType>();
137 if (!TST)
138 return nullptr;
139 if (TST->getNumArgs() == 0)
140 return nullptr;
141 const TemplateArgument &FirstArg = TST->getArg(0);
142 if (FirstArg.getKind() != TemplateArgument::Type)
143 return nullptr;
144 return FirstArg.getAsType().getTypePtrOrNull();
145 } 59 }
146 60
147 const NamedDecl *getTemplatePattern(const NamedDecl *D) { 61 const NamedDecl *getTemplatePattern(const NamedDecl *D) {
148 if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) { 62 if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
149 if (const auto *Result = CRD->getTemplateInstantiationPattern()) 63 if (const auto *Result = CRD->getTemplateInstantiationPattern())
201 // template<class X> using pvec = vector<x*>; pvec<int> x; 115 // template<class X> using pvec = vector<x*>; pvec<int> x;
202 // There's no Decl `pvec<int>`, we must choose `pvec<X>` or `vector<int*>` 116 // There's no Decl `pvec<int>`, we must choose `pvec<X>` or `vector<int*>`
203 // and both are lossy. We must know upfront what the caller ultimately wants. 117 // and both are lossy. We must know upfront what the caller ultimately wants.
204 // 118 //
205 // FIXME: improve common dependent scope using name lookup in primary templates. 119 // FIXME: improve common dependent scope using name lookup in primary templates.
206 // e.g. template<typename T> int foo() { return std::vector<T>().size(); } 120 // We currently handle several dependent constructs, but some others remain to
207 // formally size() is unresolved, but the primary template is a good guess. 121 // be handled:
208 // This affects:
209 // - DependentTemplateSpecializationType,
210 // - DependentNameType
211 // - UnresolvedUsingValueDecl
212 // - UnresolvedUsingTypenameDecl 122 // - UnresolvedUsingTypenameDecl
213 struct TargetFinder { 123 struct TargetFinder {
214 using RelSet = DeclRelationSet; 124 using RelSet = DeclRelationSet;
215 using Rel = DeclRelation; 125 using Rel = DeclRelation;
216 126
217 private: 127 private:
128 const HeuristicResolver *Resolver;
218 llvm::SmallDenseMap<const NamedDecl *, 129 llvm::SmallDenseMap<const NamedDecl *,
219 std::pair<RelSet, /*InsertionOrder*/ size_t>> 130 std::pair<RelSet, /*InsertionOrder*/ size_t>>
220 Decls; 131 Decls;
132 llvm::SmallDenseMap<const Decl *, RelSet> Seen;
221 RelSet Flags; 133 RelSet Flags;
222 134
223 template <typename T> void debug(T &Node, RelSet Flags) { 135 template <typename T> void debug(T &Node, RelSet Flags) {
224 dlog("visit [{0}] {1}", Flags, 136 dlog("visit [{0}] {1}", Flags, nodeToString(DynTypedNode::create(Node)));
225 nodeToString(ast_type_traits::DynTypedNode::create(Node)));
226 } 137 }
227 138
228 void report(const NamedDecl *D, RelSet Flags) { 139 void report(const NamedDecl *D, RelSet Flags) {
229 dlog("--> [{0}] {1}", Flags, 140 dlog("--> [{0}] {1}", Flags, nodeToString(DynTypedNode::create(*D)));
230 nodeToString(ast_type_traits::DynTypedNode::create(*D)));
231 auto It = Decls.try_emplace(D, std::make_pair(Flags, Decls.size())); 141 auto It = Decls.try_emplace(D, std::make_pair(Flags, Decls.size()));
232 // If already exists, update the flags. 142 // If already exists, update the flags.
233 if (!It.second) 143 if (!It.second)
234 It.first->second.first |= Flags; 144 It.first->second.first |= Flags;
235 } 145 }
236 146
237 public: 147 public:
148 TargetFinder(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
149
238 llvm::SmallVector<std::pair<const NamedDecl *, RelSet>, 1> takeDecls() const { 150 llvm::SmallVector<std::pair<const NamedDecl *, RelSet>, 1> takeDecls() const {
239 using ValTy = std::pair<const NamedDecl *, RelSet>; 151 using ValTy = std::pair<const NamedDecl *, RelSet>;
240 llvm::SmallVector<ValTy, 1> Result; 152 llvm::SmallVector<ValTy, 1> Result;
241 Result.resize(Decls.size()); 153 Result.resize(Decls.size());
242 for (const auto &Elem : Decls) 154 for (const auto &Elem : Decls)
247 void add(const Decl *Dcl, RelSet Flags) { 159 void add(const Decl *Dcl, RelSet Flags) {
248 const NamedDecl *D = llvm::dyn_cast_or_null<NamedDecl>(Dcl); 160 const NamedDecl *D = llvm::dyn_cast_or_null<NamedDecl>(Dcl);
249 if (!D) 161 if (!D)
250 return; 162 return;
251 debug(*D, Flags); 163 debug(*D, Flags);
164
165 // Avoid recursion (which can arise in the presence of heuristic
166 // resolution of dependent names) by exiting early if we have
167 // already seen this decl with all flags in Flags.
168 auto Res = Seen.try_emplace(D);
169 if (!Res.second && Res.first->second.contains(Flags))
170 return;
171 Res.first->second |= Flags;
172
252 if (const UsingDirectiveDecl *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D)) 173 if (const UsingDirectiveDecl *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
253 D = UDD->getNominatedNamespaceAsWritten(); 174 D = UDD->getNominatedNamespaceAsWritten();
254 175
255 if (const TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) { 176 if (const TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) {
256 add(TND->getUnderlyingType(), Flags | Rel::Underlying); 177 add(TND->getUnderlyingType(), Flags | Rel::Underlying);
257 Flags |= Rel::Alias; // continue with the alias. 178 Flags |= Rel::Alias; // continue with the alias.
258 } else if (const UsingDecl *UD = dyn_cast<UsingDecl>(D)) { 179 } else if (const UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
180 // no Underlying as this is a non-renaming alias.
259 for (const UsingShadowDecl *S : UD->shadows()) 181 for (const UsingShadowDecl *S : UD->shadows())
260 add(S->getUnderlyingDecl(), Flags | Rel::Underlying); 182 add(S->getUnderlyingDecl(), Flags);
261 Flags |= Rel::Alias; // continue with the alias. 183 Flags |= Rel::Alias; // continue with the alias.
262 } else if (const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) { 184 } else if (const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) {
263 add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying); 185 add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying);
186 Flags |= Rel::Alias; // continue with the alias
187 } else if (const UnresolvedUsingValueDecl *UUVD =
188 dyn_cast<UnresolvedUsingValueDecl>(D)) {
189 if (Resolver) {
190 for (const NamedDecl *Target : Resolver->resolveUsingValueDecl(UUVD)) {
191 add(Target, Flags); // no Underlying as this is a non-renaming alias
192 }
193 }
264 Flags |= Rel::Alias; // continue with the alias 194 Flags |= Rel::Alias; // continue with the alias
265 } else if (const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) { 195 } else if (const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
266 // Include the using decl, but don't traverse it. This may end up 196 // Include the using decl, but don't traverse it. This may end up
267 // including *all* shadows, which we don't want. 197 // including *all* shadows, which we don't want.
268 report(USD->getUsingDecl(), Flags | Rel::Alias); 198 report(USD->getUsingDecl(), Flags | Rel::Alias);
269 // Shadow decls are synthetic and not themselves interesting. 199 // Shadow decls are synthetic and not themselves interesting.
270 // Record the underlying decl instead, if allowed. 200 // Record the underlying decl instead, if allowed.
271 D = USD->getTargetDecl(); 201 D = USD->getTargetDecl();
272 Flags |= Rel::Underlying; // continue with the underlying decl. 202 } else if (const auto *DG = dyn_cast<CXXDeductionGuideDecl>(D)) {
273 } 203 D = DG->getDeducedTemplate();
204 } else if (const ObjCImplementationDecl *IID =
205 dyn_cast<ObjCImplementationDecl>(D)) {
206 // Treat ObjC{Interface,Implementation}Decl as if they were a decl/def
207 // pair as long as the interface isn't implicit.
208 if (const auto *CID = IID->getClassInterface())
209 if (const auto *DD = CID->getDefinition())
210 if (!DD->isImplicitInterfaceDecl())
211 D = DD;
212 } else if (const ObjCCategoryImplDecl *CID =
213 dyn_cast<ObjCCategoryImplDecl>(D)) {
214 // Treat ObjC{Category,CategoryImpl}Decl as if they were a decl/def pair.
215 D = CID->getCategoryDecl();
216 }
217 if (!D)
218 return;
274 219
275 if (const Decl *Pat = getTemplatePattern(D)) { 220 if (const Decl *Pat = getTemplatePattern(D)) {
276 assert(Pat != D); 221 assert(Pat != D);
277 add(Pat, Flags | Rel::TemplatePattern); 222 add(Pat, Flags | Rel::TemplatePattern);
278 // Now continue with the instantiation. 223 // Now continue with the instantiation.
339 if (auto *LabelDecl = Label->getDecl()) 284 if (auto *LabelDecl = Label->getDecl())
340 Outer.add(LabelDecl, Flags); 285 Outer.add(LabelDecl, Flags);
341 } 286 }
342 void 287 void
343 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) { 288 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
344 const Type *BaseType = E->getBaseType().getTypePtrOrNull(); 289 if (Outer.Resolver) {
345 if (E->isArrow()) { 290 for (const NamedDecl *D : Outer.Resolver->resolveMemberExpr(E)) {
346 BaseType = getPointeeType(BaseType); 291 Outer.add(D, Flags);
292 }
347 } 293 }
348 for (const NamedDecl *D : getMembersReferencedViaDependentName(
349 BaseType, [E](ASTContext &) { return E->getMember(); },
350 /*IsNonstaticMember=*/true)) {
351 Outer.add(D, Flags);
352 }
353 } 294 }
354 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) { 295 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
355 for (const NamedDecl *D : getMembersReferencedViaDependentName( 296 if (Outer.Resolver) {
356 E->getQualifier()->getAsType(), 297 for (const NamedDecl *D : Outer.Resolver->resolveDeclRefExpr(E)) {
357 [E](ASTContext &) { return E->getDeclName(); }, 298 Outer.add(D, Flags);
358 /*IsNonstaticMember=*/false)) { 299 }
359 Outer.add(D, Flags);
360 } 300 }
361 } 301 }
362 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) { 302 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
363 Outer.add(OIRE->getDecl(), Flags); 303 Outer.add(OIRE->getDecl(), Flags);
364 } 304 }
381 void VisitOpaqueValueExpr(const OpaqueValueExpr *OVE) { 321 void VisitOpaqueValueExpr(const OpaqueValueExpr *OVE) {
382 Outer.add(OVE->getSourceExpr(), Flags); 322 Outer.add(OVE->getSourceExpr(), Flags);
383 } 323 }
384 void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) { 324 void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) {
385 Outer.add(POE->getSyntacticForm(), Flags); 325 Outer.add(POE->getSyntacticForm(), Flags);
326 }
327 void VisitCXXNewExpr(const CXXNewExpr *CNE) {
328 Outer.add(CNE->getOperatorNew(), Flags);
329 }
330 void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE) {
331 Outer.add(CDE->getOperatorDelete(), Flags);
386 } 332 }
387 }; 333 };
388 Visitor(*this, Flags).Visit(S); 334 Visitor(*this, Flags).Visit(S);
389 } 335 }
390 336
425 // even when it's known in principle. Once that bug is fixed, 371 // even when it's known in principle. Once that bug is fixed,
426 // this method can be removed (the existing handling in 372 // this method can be removed (the existing handling in
427 // VisitDeducedType() is sufficient). 373 // VisitDeducedType() is sufficient).
428 if (auto *TD = DTST->getTemplateName().getAsTemplateDecl()) 374 if (auto *TD = DTST->getTemplateName().getAsTemplateDecl())
429 Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern); 375 Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
376 }
377 void VisitDependentNameType(const DependentNameType *DNT) {
378 if (Outer.Resolver) {
379 for (const NamedDecl *ND :
380 Outer.Resolver->resolveDependentNameType(DNT)) {
381 Outer.add(ND, Flags);
382 }
383 }
384 }
385 void VisitDependentTemplateSpecializationType(
386 const DependentTemplateSpecializationType *DTST) {
387 if (Outer.Resolver) {
388 for (const NamedDecl *ND :
389 Outer.Resolver->resolveTemplateSpecializationType(DTST)) {
390 Outer.add(ND, Flags);
391 }
392 }
430 } 393 }
431 void VisitTypedefType(const TypedefType *TT) { 394 void VisitTypedefType(const TypedefType *TT) {
432 Outer.add(TT->getDecl(), Flags); 395 Outer.add(TT->getDecl(), Flags);
433 } 396 }
434 void 397 void
467 } 430 }
468 void VisitObjCInterfaceType(const ObjCInterfaceType *OIT) { 431 void VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
469 Outer.add(OIT->getDecl(), Flags); 432 Outer.add(OIT->getDecl(), Flags);
470 } 433 }
471 void VisitObjCObjectType(const ObjCObjectType *OOT) { 434 void VisitObjCObjectType(const ObjCObjectType *OOT) {
472 // FIXME: ObjCObjectTypeLoc has no children for the protocol list, so 435 // Make all of the protocols targets since there's no child nodes for
473 // there is no node in id<Foo> that refers to ObjCProtocolDecl Foo. 436 // protocols. This isn't needed for the base type, which *does* have a
474 if (OOT->isObjCQualifiedId() && OOT->getNumProtocols() == 1) 437 // child `ObjCInterfaceTypeLoc`. This structure is a hack, but it works
475 Outer.add(OOT->getProtocol(0), Flags); 438 // well for go-to-definition.
439 unsigned NumProtocols = OOT->getNumProtocols();
440 for (unsigned I = 0; I < NumProtocols; I++)
441 Outer.add(OOT->getProtocol(I), Flags);
476 } 442 }
477 }; 443 };
478 Visitor(*this, Flags).Visit(T.getTypePtr()); 444 Visitor(*this, Flags).Visit(T.getTypePtr());
479 } 445 }
480 446
481 void add(const NestedNameSpecifier *NNS, RelSet Flags) { 447 void add(const NestedNameSpecifier *NNS, RelSet Flags) {
482 if (!NNS) 448 if (!NNS)
483 return; 449 return;
484 debug(*NNS, Flags); 450 debug(*NNS, Flags);
485 switch (NNS->getKind()) { 451 switch (NNS->getKind()) {
486 case NestedNameSpecifier::Identifier:
487 return;
488 case NestedNameSpecifier::Namespace: 452 case NestedNameSpecifier::Namespace:
489 add(NNS->getAsNamespace(), Flags); 453 add(NNS->getAsNamespace(), Flags);
490 return; 454 return;
491 case NestedNameSpecifier::NamespaceAlias: 455 case NestedNameSpecifier::NamespaceAlias:
492 add(NNS->getAsNamespaceAlias(), Flags); 456 add(NNS->getAsNamespaceAlias(), Flags);
457 return;
458 case NestedNameSpecifier::Identifier:
459 if (Resolver) {
460 add(QualType(Resolver->resolveNestedNameSpecifierToType(NNS), 0),
461 Flags);
462 }
493 return; 463 return;
494 case NestedNameSpecifier::TypeSpec: 464 case NestedNameSpecifier::TypeSpec:
495 case NestedNameSpecifier::TypeSpecWithTemplate: 465 case NestedNameSpecifier::TypeSpecWithTemplate:
496 add(QualType(NNS->getAsType(), 0), Flags); 466 add(QualType(NNS->getAsType(), 0), Flags);
497 return; 467 return;
512 482
513 if (CCI->isAnyMemberInitializer()) 483 if (CCI->isAnyMemberInitializer())
514 add(CCI->getAnyMember(), Flags); 484 add(CCI->getAnyMember(), Flags);
515 // Constructor calls contain a TypeLoc node, so we don't handle them here. 485 // Constructor calls contain a TypeLoc node, so we don't handle them here.
516 } 486 }
487
488 void add(const TemplateArgument &Arg, RelSet Flags) {
489 // Only used for template template arguments.
490 // For type and non-type template arguments, SelectionTree
491 // will hit a more specific node (e.g. a TypeLoc or a
492 // DeclRefExpr).
493 if (Arg.getKind() == TemplateArgument::Template ||
494 Arg.getKind() == TemplateArgument::TemplateExpansion) {
495 if (TemplateDecl *TD = Arg.getAsTemplate().getAsTemplateDecl()) {
496 report(TD, Flags);
497 }
498 }
499 }
517 }; 500 };
518 501
519 } // namespace 502 } // namespace
520 503
521 llvm::SmallVector<std::pair<const NamedDecl *, DeclRelationSet>, 1> 504 llvm::SmallVector<std::pair<const NamedDecl *, DeclRelationSet>, 1>
522 allTargetDecls(const ast_type_traits::DynTypedNode &N) { 505 allTargetDecls(const DynTypedNode &N, const HeuristicResolver *Resolver) {
523 dlog("allTargetDecls({0})", nodeToString(N)); 506 dlog("allTargetDecls({0})", nodeToString(N));
524 TargetFinder Finder; 507 TargetFinder Finder(Resolver);
525 DeclRelationSet Flags; 508 DeclRelationSet Flags;
526 if (const Decl *D = N.get<Decl>()) 509 if (const Decl *D = N.get<Decl>())
527 Finder.add(D, Flags); 510 Finder.add(D, Flags);
528 else if (const Stmt *S = N.get<Stmt>()) 511 else if (const Stmt *S = N.get<Stmt>())
529 Finder.add(S, Flags); 512 Finder.add(S, Flags);
535 Finder.add(TL->getType(), Flags); 518 Finder.add(TL->getType(), Flags);
536 else if (const QualType *QT = N.get<QualType>()) 519 else if (const QualType *QT = N.get<QualType>())
537 Finder.add(*QT, Flags); 520 Finder.add(*QT, Flags);
538 else if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) 521 else if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>())
539 Finder.add(CCI, Flags); 522 Finder.add(CCI, Flags);
540 523 else if (const TemplateArgumentLoc *TAL = N.get<TemplateArgumentLoc>())
524 Finder.add(TAL->getArgument(), Flags);
525 else if (const CXXBaseSpecifier *CBS = N.get<CXXBaseSpecifier>())
526 Finder.add(CBS->getTypeSourceInfo()->getType(), Flags);
541 return Finder.takeDecls(); 527 return Finder.takeDecls();
542 } 528 }
543 529
544 llvm::SmallVector<const NamedDecl *, 1> 530 llvm::SmallVector<const NamedDecl *, 1>
545 targetDecl(const ast_type_traits::DynTypedNode &N, DeclRelationSet Mask) { 531 targetDecl(const DynTypedNode &N, DeclRelationSet Mask,
532 const HeuristicResolver *Resolver) {
546 llvm::SmallVector<const NamedDecl *, 1> Result; 533 llvm::SmallVector<const NamedDecl *, 1> Result;
547 for (const auto &Entry : allTargetDecls(N)) { 534 for (const auto &Entry : allTargetDecls(N, Resolver)) {
548 if (!(Entry.second & ~Mask)) 535 if (!(Entry.second & ~Mask))
549 Result.push_back(Entry.first); 536 Result.push_back(Entry.first);
550 } 537 }
551 return Result; 538 return Result;
552 } 539 }
553 540
554 llvm::SmallVector<const NamedDecl *, 1> 541 llvm::SmallVector<const NamedDecl *, 1>
555 explicitReferenceTargets(DynTypedNode N, DeclRelationSet Mask) { 542 explicitReferenceTargets(DynTypedNode N, DeclRelationSet Mask,
543 const HeuristicResolver *Resolver) {
556 assert(!(Mask & (DeclRelation::TemplatePattern | 544 assert(!(Mask & (DeclRelation::TemplatePattern |
557 DeclRelation::TemplateInstantiation)) && 545 DeclRelation::TemplateInstantiation)) &&
558 "explicitReferenceTargets handles templates on its own"); 546 "explicitReferenceTargets handles templates on its own");
559 auto Decls = allTargetDecls(N); 547 auto Decls = allTargetDecls(N, Resolver);
560 548
561 // We prefer to return template instantiation, but fallback to template 549 // We prefer to return template instantiation, but fallback to template
562 // pattern if instantiation is not available. 550 // pattern if instantiation is not available.
563 Mask |= DeclRelation::TemplatePattern | DeclRelation::TemplateInstantiation; 551 Mask |= DeclRelation::TemplatePattern | DeclRelation::TemplateInstantiation;
564 552
581 TemplatePatterns.end()); 569 TemplatePatterns.end());
582 return Targets; 570 return Targets;
583 } 571 }
584 572
585 namespace { 573 namespace {
586 llvm::SmallVector<ReferenceLoc, 2> refInDecl(const Decl *D) { 574 llvm::SmallVector<ReferenceLoc> refInDecl(const Decl *D,
575 const HeuristicResolver *Resolver) {
587 struct Visitor : ConstDeclVisitor<Visitor> { 576 struct Visitor : ConstDeclVisitor<Visitor> {
588 llvm::SmallVector<ReferenceLoc, 2> Refs; 577 Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
578
579 const HeuristicResolver *Resolver;
580 llvm::SmallVector<ReferenceLoc> Refs;
589 581
590 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 582 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
591 // We want to keep it as non-declaration references, as the 583 // We want to keep it as non-declaration references, as the
592 // "using namespace" declaration doesn't have a name. 584 // "using namespace" declaration doesn't have a name.
593 Refs.push_back(ReferenceLoc{D->getQualifierLoc(), 585 Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
596 {D->getNominatedNamespaceAsWritten()}}); 588 {D->getNominatedNamespaceAsWritten()}});
597 } 589 }
598 590
599 void VisitUsingDecl(const UsingDecl *D) { 591 void VisitUsingDecl(const UsingDecl *D) {
600 // "using ns::identifier;" is a non-declaration reference. 592 // "using ns::identifier;" is a non-declaration reference.
601 Refs.push_back( 593 Refs.push_back(ReferenceLoc{
602 ReferenceLoc{D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false, 594 D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,
603 explicitReferenceTargets(DynTypedNode::create(*D), 595 explicitReferenceTargets(DynTypedNode::create(*D),
604 DeclRelation::Underlying)}); 596 DeclRelation::Underlying, Resolver)});
605 } 597 }
606 598
607 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 599 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
608 // For namespace alias, "namespace Foo = Target;", we add two references. 600 // For namespace alias, "namespace Foo = Target;", we add two references.
609 // Add a declaration reference for Foo. 601 // Add a declaration reference for Foo.
634 Refs.push_back(ReferenceLoc{getQualifierLoc(*ND), 626 Refs.push_back(ReferenceLoc{getQualifierLoc(*ND),
635 ND->getLocation(), 627 ND->getLocation(),
636 /*IsDecl=*/true, 628 /*IsDecl=*/true,
637 {ND}}); 629 {ND}});
638 } 630 }
631
632 void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *DG) {
633 // The class template name in a deduction guide targets the class
634 // template.
635 Refs.push_back(ReferenceLoc{DG->getQualifierLoc(),
636 DG->getNameInfo().getLoc(),
637 /*IsDecl=*/false,
638 {DG->getDeducedTemplate()}});
639 }
640
641 void VisitObjCMethodDecl(const ObjCMethodDecl *OMD) {
642 // The name may have several tokens, we can only report the first.
643 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
644 OMD->getSelectorStartLoc(),
645 /*IsDecl=*/true,
646 {OMD}});
647 }
648
649 void visitProtocolList(
650 llvm::iterator_range<ObjCProtocolList::iterator> Protocols,
651 llvm::iterator_range<const SourceLocation *> Locations) {
652 for (const auto &P : llvm::zip(Protocols, Locations)) {
653 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
654 std::get<1>(P),
655 /*IsDecl=*/false,
656 {std::get<0>(P)}});
657 }
658 }
659
660 void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *OID) {
661 if (OID->isThisDeclarationADefinition())
662 visitProtocolList(OID->protocols(), OID->protocol_locs());
663 Base::VisitObjCInterfaceDecl(OID); // Visit the interface's name.
664 }
665
666 void VisitObjCCategoryDecl(const ObjCCategoryDecl *OCD) {
667 visitProtocolList(OCD->protocols(), OCD->protocol_locs());
668 // getLocation is the extended class's location, not the category's.
669 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
670 OCD->getLocation(),
671 /*IsDecl=*/false,
672 {OCD->getClassInterface()}});
673 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
674 OCD->getCategoryNameLoc(),
675 /*IsDecl=*/true,
676 {OCD}});
677 }
678
679 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *OCID) {
680 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
681 OCID->getLocation(),
682 /*IsDecl=*/false,
683 {OCID->getClassInterface()}});
684 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
685 OCID->getCategoryNameLoc(),
686 /*IsDecl=*/true,
687 {OCID->getCategoryDecl()}});
688 }
689
690 void VisitObjCProtocolDecl(const ObjCProtocolDecl *OPD) {
691 if (OPD->isThisDeclarationADefinition())
692 visitProtocolList(OPD->protocols(), OPD->protocol_locs());
693 Base::VisitObjCProtocolDecl(OPD); // Visit the protocol's name.
694 }
639 }; 695 };
640 696
641 Visitor V; 697 Visitor V{Resolver};
642 V.Visit(D); 698 V.Visit(D);
643 return V.Refs; 699 return V.Refs;
644 } 700 }
645 701
646 llvm::SmallVector<ReferenceLoc, 2> refInStmt(const Stmt *S) { 702 llvm::SmallVector<ReferenceLoc> refInStmt(const Stmt *S,
703 const HeuristicResolver *Resolver) {
647 struct Visitor : ConstStmtVisitor<Visitor> { 704 struct Visitor : ConstStmtVisitor<Visitor> {
705 Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
706
707 const HeuristicResolver *Resolver;
648 // FIXME: handle more complicated cases: more ObjC, designated initializers. 708 // FIXME: handle more complicated cases: more ObjC, designated initializers.
649 llvm::SmallVector<ReferenceLoc, 2> Refs; 709 llvm::SmallVector<ReferenceLoc> Refs;
650 710
651 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) { 711 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
652 Refs.push_back(ReferenceLoc{E->getNestedNameSpecifierLoc(), 712 Refs.push_back(ReferenceLoc{E->getNestedNameSpecifierLoc(),
653 E->getConceptNameLoc(), 713 E->getConceptNameLoc(),
654 /*IsDecl=*/false, 714 /*IsDecl=*/false,
663 } 723 }
664 724
665 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) { 725 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
666 Refs.push_back(ReferenceLoc{ 726 Refs.push_back(ReferenceLoc{
667 E->getQualifierLoc(), E->getNameInfo().getLoc(), /*IsDecl=*/false, 727 E->getQualifierLoc(), E->getNameInfo().getLoc(), /*IsDecl=*/false,
668 explicitReferenceTargets(DynTypedNode::create(*E), {})}); 728 explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});
669 } 729 }
670 730
671 void VisitMemberExpr(const MemberExpr *E) { 731 void VisitMemberExpr(const MemberExpr *E) {
672 // Skip destructor calls to avoid duplication: TypeLoc within will be 732 // Skip destructor calls to avoid duplication: TypeLoc within will be
673 // visited separately. 733 // visited separately.
674 if (llvm::dyn_cast<CXXDestructorDecl>(E->getFoundDecl().getDecl())) 734 if (llvm::isa<CXXDestructorDecl>(E->getFoundDecl().getDecl()))
675 return; 735 return;
676 Refs.push_back(ReferenceLoc{E->getQualifierLoc(), 736 Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
677 E->getMemberNameInfo().getLoc(), 737 E->getMemberNameInfo().getLoc(),
678 /*IsDecl=*/false, 738 /*IsDecl=*/false,
679 {E->getFoundDecl()}}); 739 {E->getFoundDecl()}});
680 } 740 }
681 741
682 void 742 void
683 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) { 743 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
684 Refs.push_back( 744 Refs.push_back(ReferenceLoc{
685 ReferenceLoc{E->getQualifierLoc(), E->getMemberNameInfo().getLoc(), 745 E->getQualifierLoc(), E->getMemberNameInfo().getLoc(),
686 /*IsDecl=*/false, 746 /*IsDecl=*/false,
687 explicitReferenceTargets(DynTypedNode::create(*E), {})}); 747 explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});
688 } 748 }
689 749
690 void VisitOverloadExpr(const OverloadExpr *E) { 750 void VisitOverloadExpr(const OverloadExpr *E) {
691 Refs.push_back(ReferenceLoc{E->getQualifierLoc(), 751 Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
692 E->getNameInfo().getLoc(), 752 E->getNameInfo().getLoc(),
705 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) { 765 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
706 Refs.push_back(ReferenceLoc{ 766 Refs.push_back(ReferenceLoc{
707 NestedNameSpecifierLoc(), E->getLocation(), 767 NestedNameSpecifierLoc(), E->getLocation(),
708 /*IsDecl=*/false, 768 /*IsDecl=*/false,
709 // Select the getter, setter, or @property depending on the call. 769 // Select the getter, setter, or @property depending on the call.
710 explicitReferenceTargets(DynTypedNode::create(*E), {})}); 770 explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});
771 }
772
773 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
774 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
775 OIRE->getLocation(),
776 /*IsDecl=*/false,
777 {OIRE->getDecl()}});
778 }
779
780 void VisitObjCMessageExpr(const ObjCMessageExpr *E) {
781 // The name may have several tokens, we can only report the first.
782 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
783 E->getSelectorStartLoc(),
784 /*IsDecl=*/false,
785 {E->getMethodDecl()}});
711 } 786 }
712 787
713 void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) { 788 void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {
714 for (const DesignatedInitExpr::Designator &D : DIE->designators()) { 789 for (const DesignatedInitExpr::Designator &D : DIE->designators()) {
715 if (!D.isFieldDesignator()) 790 if (!D.isFieldDesignator())
716 continue; 791 continue;
717 792
718 llvm::SmallVector<const NamedDecl *, 1> Targets; 793 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
719 if (D.getField()) 794 D.getFieldLoc(),
720 Targets.push_back(D.getField()); 795 /*IsDecl=*/false,
721 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), D.getFieldLoc(), 796 {D.getField()}});
722 /*IsDecl=*/false, std::move(Targets)});
723 } 797 }
724 } 798 }
725 799
726 void VisitGotoStmt(const GotoStmt *GS) { 800 void VisitGotoStmt(const GotoStmt *GS) {
727 llvm::SmallVector<const NamedDecl *, 1> Targets; 801 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
728 if (const auto *L = GS->getLabel()) 802 GS->getLabelLoc(),
729 Targets.push_back(L); 803 /*IsDecl=*/false,
730 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), GS->getLabelLoc(), 804 {GS->getLabel()}});
731 /*IsDecl=*/false, std::move(Targets)});
732 } 805 }
733 806
734 void VisitLabelStmt(const LabelStmt *LS) { 807 void VisitLabelStmt(const LabelStmt *LS) {
735 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), 808 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
736 LS->getIdentLoc(), 809 LS->getIdentLoc(),
737 /*IsDecl=*/true, 810 /*IsDecl=*/true,
738 {LS->getDecl()}}); 811 {LS->getDecl()}});
739 } 812 }
740 }; 813 };
741 814
742 Visitor V; 815 Visitor V{Resolver};
743 V.Visit(S); 816 V.Visit(S);
744 return V.Refs; 817 return V.Refs;
745 } 818 }
746 819
747 llvm::SmallVector<ReferenceLoc, 2> refInTypeLoc(TypeLoc L) { 820 llvm::SmallVector<ReferenceLoc>
821 refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
748 struct Visitor : TypeLocVisitor<Visitor> { 822 struct Visitor : TypeLocVisitor<Visitor> {
749 llvm::Optional<ReferenceLoc> Ref; 823 Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}
824
825 const HeuristicResolver *Resolver;
826 llvm::SmallVector<ReferenceLoc> Refs;
750 827
751 void VisitElaboratedTypeLoc(ElaboratedTypeLoc L) { 828 void VisitElaboratedTypeLoc(ElaboratedTypeLoc L) {
752 // We only know about qualifier, rest if filled by inner locations. 829 // We only know about qualifier, rest if filled by inner locations.
830 size_t InitialSize = Refs.size();
753 Visit(L.getNamedTypeLoc().getUnqualifiedLoc()); 831 Visit(L.getNamedTypeLoc().getUnqualifiedLoc());
754 // Fill in the qualifier. 832 size_t NewSize = Refs.size();
755 if (!Ref) 833 // Add qualifier for the newly-added refs.
756 return; 834 for (unsigned I = InitialSize; I < NewSize; ++I) {
757 assert(!Ref->Qualifier.hasQualifier() && "qualifier already set"); 835 ReferenceLoc *Ref = &Refs[I];
758 Ref->Qualifier = L.getQualifierLoc(); 836 // Fill in the qualifier.
837 assert(!Ref->Qualifier.hasQualifier() && "qualifier already set");
838 Ref->Qualifier = L.getQualifierLoc();
839 }
759 } 840 }
760 841
761 void VisitTagTypeLoc(TagTypeLoc L) { 842 void VisitTagTypeLoc(TagTypeLoc L) {
762 Ref = ReferenceLoc{NestedNameSpecifierLoc(), 843 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
763 L.getNameLoc(), 844 L.getNameLoc(),
764 /*IsDecl=*/false, 845 /*IsDecl=*/false,
765 {L.getDecl()}}; 846 {L.getDecl()}});
766 } 847 }
767 848
768 void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) { 849 void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {
769 Ref = ReferenceLoc{NestedNameSpecifierLoc(), 850 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
770 L.getNameLoc(), 851 L.getNameLoc(),
771 /*IsDecl=*/false, 852 /*IsDecl=*/false,
772 {L.getDecl()}}; 853 {L.getDecl()}});
773 } 854 }
774 855
775 void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) { 856 void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
776 // We must ensure template type aliases are included in results if they 857 // We must ensure template type aliases are included in results if they
777 // were written in the source code, e.g. in 858 // were written in the source code, e.g. in
779 // ^valias<int> x; 860 // ^valias<int> x;
780 // 'explicitReferenceTargets' will return: 861 // 'explicitReferenceTargets' will return:
781 // 1. valias with mask 'Alias'. 862 // 1. valias with mask 'Alias'.
782 // 2. 'vector<int>' with mask 'Underlying'. 863 // 2. 'vector<int>' with mask 'Underlying'.
783 // we want to return only #1 in this case. 864 // we want to return only #1 in this case.
784 Ref = ReferenceLoc{ 865 Refs.push_back(ReferenceLoc{
785 NestedNameSpecifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false, 866 NestedNameSpecifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
786 explicitReferenceTargets(DynTypedNode::create(L.getType()), 867 explicitReferenceTargets(DynTypedNode::create(L.getType()),
787 DeclRelation::Alias)}; 868 DeclRelation::Alias, Resolver)});
788 } 869 }
789 void VisitDeducedTemplateSpecializationTypeLoc( 870 void VisitDeducedTemplateSpecializationTypeLoc(
790 DeducedTemplateSpecializationTypeLoc L) { 871 DeducedTemplateSpecializationTypeLoc L) {
791 Ref = ReferenceLoc{ 872 Refs.push_back(ReferenceLoc{
792 NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false, 873 NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
793 explicitReferenceTargets(DynTypedNode::create(L.getType()), 874 explicitReferenceTargets(DynTypedNode::create(L.getType()),
794 DeclRelation::Alias)}; 875 DeclRelation::Alias, Resolver)});
795 } 876 }
796 877
797 void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 878 void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
798 Ref = ReferenceLoc{NestedNameSpecifierLoc(), 879 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
799 TL.getNameLoc(), 880 TL.getNameLoc(),
800 /*IsDecl=*/false, 881 /*IsDecl=*/false,
801 {TL.getDecl()}}; 882 {TL.getDecl()}});
802 } 883 }
803 884
804 void VisitDependentTemplateSpecializationTypeLoc( 885 void VisitDependentTemplateSpecializationTypeLoc(
805 DependentTemplateSpecializationTypeLoc L) { 886 DependentTemplateSpecializationTypeLoc L) {
806 Ref = ReferenceLoc{ 887 Refs.push_back(
807 L.getQualifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false, 888 ReferenceLoc{L.getQualifierLoc(), L.getTemplateNameLoc(),
808 explicitReferenceTargets(DynTypedNode::create(L.getType()), {})}; 889 /*IsDecl=*/false,
890 explicitReferenceTargets(
891 DynTypedNode::create(L.getType()), {}, Resolver)});
809 } 892 }
810 893
811 void VisitDependentNameTypeLoc(DependentNameTypeLoc L) { 894 void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
812 Ref = ReferenceLoc{ 895 Refs.push_back(
813 L.getQualifierLoc(), L.getNameLoc(), /*IsDecl=*/false, 896 ReferenceLoc{L.getQualifierLoc(), L.getNameLoc(),
814 explicitReferenceTargets(DynTypedNode::create(L.getType()), {})}; 897 /*IsDecl=*/false,
898 explicitReferenceTargets(
899 DynTypedNode::create(L.getType()), {}, Resolver)});
815 } 900 }
816 901
817 void VisitTypedefTypeLoc(TypedefTypeLoc L) { 902 void VisitTypedefTypeLoc(TypedefTypeLoc L) {
818 Ref = ReferenceLoc{NestedNameSpecifierLoc(), 903 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
819 L.getNameLoc(), 904 L.getNameLoc(),
820 /*IsDecl=*/false, 905 /*IsDecl=*/false,
821 {L.getTypedefNameDecl()}}; 906 {L.getTypedefNameDecl()}});
907 }
908
909 void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc L) {
910 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
911 L.getNameLoc(),
912 /*IsDecl=*/false,
913 {L.getIFaceDecl()}});
914 }
915
916 void VisitObjCObjectTypeLoc(ObjCObjectTypeLoc L) {
917 unsigned NumProtocols = L.getNumProtocols();
918 for (unsigned I = 0; I < NumProtocols; I++) {
919 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
920 L.getProtocolLoc(I),
921 /*IsDecl=*/false,
922 {L.getProtocol(I)}});
923 }
822 } 924 }
823 }; 925 };
824 926
825 Visitor V; 927 Visitor V{Resolver};
826 V.Visit(L.getUnqualifiedLoc()); 928 V.Visit(L.getUnqualifiedLoc());
827 if (!V.Ref) 929 return V.Refs;
828 return {};
829 return {*V.Ref};
830 } 930 }
831 931
832 class ExplicitReferenceCollector 932 class ExplicitReferenceCollector
833 : public RecursiveASTVisitor<ExplicitReferenceCollector> { 933 : public RecursiveASTVisitor<ExplicitReferenceCollector> {
834 public: 934 public:
835 ExplicitReferenceCollector(llvm::function_ref<void(ReferenceLoc)> Out) 935 ExplicitReferenceCollector(llvm::function_ref<void(ReferenceLoc)> Out,
836 : Out(Out) { 936 const HeuristicResolver *Resolver)
937 : Out(Out), Resolver(Resolver) {
837 assert(Out); 938 assert(Out);
838 } 939 }
839 940
840 bool VisitTypeLoc(TypeLoc TTL) { 941 bool VisitTypeLoc(TypeLoc TTL) {
841 if (TypeLocsToSkip.count(TTL.getBeginLoc().getRawEncoding())) 942 if (TypeLocsToSkip.count(TTL.getBeginLoc()))
842 return true; 943 return true;
843 visitNode(DynTypedNode::create(TTL)); 944 visitNode(DynTypedNode::create(TTL));
844 return true; 945 return true;
845 } 946 }
846 947
847 bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) { 948 bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) {
848 // ElaboratedTypeLoc will reports information for its inner type loc. 949 // ElaboratedTypeLoc will reports information for its inner type loc.
849 // Otherwise we loose information about inner types loc's qualifier. 950 // Otherwise we loose information about inner types loc's qualifier.
850 TypeLoc Inner = L.getNamedTypeLoc().getUnqualifiedLoc(); 951 TypeLoc Inner = L.getNamedTypeLoc().getUnqualifiedLoc();
851 TypeLocsToSkip.insert(Inner.getBeginLoc().getRawEncoding()); 952 TypeLocsToSkip.insert(Inner.getBeginLoc());
852 return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L); 953 return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L);
853 } 954 }
854 955
855 bool VisitStmt(Stmt *S) { 956 bool VisitStmt(Stmt *S) {
856 visitNode(DynTypedNode::create(*S)); 957 visitNode(DynTypedNode::create(*S));
873 974
874 // We re-define Traverse*, since there's no corresponding Visit*. 975 // We re-define Traverse*, since there's no corresponding Visit*.
875 // TemplateArgumentLoc is the only way to get locations for references to 976 // TemplateArgumentLoc is the only way to get locations for references to
876 // template template parameters. 977 // template template parameters.
877 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) { 978 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) {
878 llvm::SmallVector<const NamedDecl *, 1> Targets;
879 switch (A.getArgument().getKind()) { 979 switch (A.getArgument().getKind()) {
880 case TemplateArgument::Template: 980 case TemplateArgument::Template:
881 case TemplateArgument::TemplateExpansion: 981 case TemplateArgument::TemplateExpansion:
882 if (const auto *D = A.getArgument()
883 .getAsTemplateOrTemplatePattern()
884 .getAsTemplateDecl())
885 Targets.push_back(D);
886 reportReference(ReferenceLoc{A.getTemplateQualifierLoc(), 982 reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
887 A.getTemplateNameLoc(), 983 A.getTemplateNameLoc(),
888 /*IsDecl=*/false, Targets}, 984 /*IsDecl=*/false,
985 {A.getArgument()
986 .getAsTemplateOrTemplatePattern()
987 .getAsTemplateDecl()}},
889 DynTypedNode::create(A.getArgument())); 988 DynTypedNode::create(A.getArgument()));
890 break; 989 break;
891 case TemplateArgument::Declaration: 990 case TemplateArgument::Declaration:
892 break; // FIXME: can this actually happen in TemplateArgumentLoc? 991 break; // FIXME: can this actually happen in TemplateArgumentLoc?
893 case TemplateArgument::Integral: 992 case TemplateArgument::Integral:
912 if (!L.getNestedNameSpecifier()) 1011 if (!L.getNestedNameSpecifier())
913 return true; 1012 return true;
914 visitNode(DynTypedNode::create(L)); 1013 visitNode(DynTypedNode::create(L));
915 // Inner type is missing information about its qualifier, skip it. 1014 // Inner type is missing information about its qualifier, skip it.
916 if (auto TL = L.getTypeLoc()) 1015 if (auto TL = L.getTypeLoc())
917 TypeLocsToSkip.insert(TL.getBeginLoc().getRawEncoding()); 1016 TypeLocsToSkip.insert(TL.getBeginLoc());
918 return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(L); 1017 return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(L);
919 } 1018 }
920 1019
921 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { 1020 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
922 visitNode(DynTypedNode::create(*Init)); 1021 visitNode(DynTypedNode::create(*Init));
936 /// 1035 ///
937 /// (!) For the purposes of this function declarations are not considered to 1036 /// (!) For the purposes of this function declarations are not considered to
938 /// be references. However, declarations can have references inside them, 1037 /// be references. However, declarations can have references inside them,
939 /// e.g. 'namespace foo = std' references namespace 'std' and this 1038 /// e.g. 'namespace foo = std' references namespace 'std' and this
940 /// function will return the corresponding reference. 1039 /// function will return the corresponding reference.
941 llvm::SmallVector<ReferenceLoc, 2> explicitReference(DynTypedNode N) { 1040 llvm::SmallVector<ReferenceLoc> explicitReference(DynTypedNode N) {
942 if (auto *D = N.get<Decl>()) 1041 if (auto *D = N.get<Decl>())
943 return refInDecl(D); 1042 return refInDecl(D, Resolver);
944 if (auto *S = N.get<Stmt>()) 1043 if (auto *S = N.get<Stmt>())
945 return refInStmt(S); 1044 return refInStmt(S, Resolver);
946 if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) { 1045 if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) {
947 // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases. 1046 // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases.
948 return {ReferenceLoc{ 1047 return {ReferenceLoc{
949 NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false, 1048 NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false,
950 explicitReferenceTargets( 1049 explicitReferenceTargets(
951 DynTypedNode::create(*NNSL->getNestedNameSpecifier()), 1050 DynTypedNode::create(*NNSL->getNestedNameSpecifier()),
952 DeclRelation::Alias)}}; 1051 DeclRelation::Alias, Resolver)}};
953 } 1052 }
954 if (const TypeLoc *TL = N.get<TypeLoc>()) 1053 if (const TypeLoc *TL = N.get<TypeLoc>())
955 return refInTypeLoc(*TL); 1054 return refInTypeLoc(*TL, Resolver);
956 if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) { 1055 if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) {
957 // Other type initializers (e.g. base initializer) are handled by visiting 1056 // Other type initializers (e.g. base initializer) are handled by visiting
958 // the typeLoc. 1057 // the typeLoc.
959 if (CCI->isAnyMemberInitializer()) { 1058 if (CCI->isAnyMemberInitializer()) {
960 return {ReferenceLoc{NestedNameSpecifierLoc(), 1059 return {ReferenceLoc{NestedNameSpecifierLoc(),
966 // We do not have location information for other nodes (QualType, etc) 1065 // We do not have location information for other nodes (QualType, etc)
967 return {}; 1066 return {};
968 } 1067 }
969 1068
970 void visitNode(DynTypedNode N) { 1069 void visitNode(DynTypedNode N) {
971 for (const auto &R : explicitReference(N)) 1070 for (auto &R : explicitReference(N))
972 reportReference(R, N); 1071 reportReference(std::move(R), N);
973 } 1072 }
974 1073
975 void reportReference(const ReferenceLoc &Ref, DynTypedNode N) { 1074 void reportReference(ReferenceLoc &&Ref, DynTypedNode N) {
1075 // Strip null targets that can arise from invalid code.
1076 // (This avoids having to check for null everywhere we insert)
1077 llvm::erase_value(Ref.Targets, nullptr);
976 // Our promise is to return only references from the source code. If we lack 1078 // Our promise is to return only references from the source code. If we lack
977 // location information, skip these nodes. 1079 // location information, skip these nodes.
978 // Normally this should not happen in practice, unless there are bugs in the 1080 // Normally this should not happen in practice, unless there are bugs in the
979 // traversals or users started the traversal at an implicit node. 1081 // traversals or users started the traversal at an implicit node.
980 if (Ref.NameLoc.isInvalid()) { 1082 if (Ref.NameLoc.isInvalid()) {
983 } 1085 }
984 Out(Ref); 1086 Out(Ref);
985 } 1087 }
986 1088
987 llvm::function_ref<void(ReferenceLoc)> Out; 1089 llvm::function_ref<void(ReferenceLoc)> Out;
1090 const HeuristicResolver *Resolver;
988 /// TypeLocs starting at these locations must be skipped, see 1091 /// TypeLocs starting at these locations must be skipped, see
989 /// TraverseElaboratedTypeSpecifierLoc for details. 1092 /// TraverseElaboratedTypeSpecifierLoc for details.
990 llvm::DenseSet</*SourceLocation*/ unsigned> TypeLocsToSkip; 1093 llvm::DenseSet<SourceLocation> TypeLocsToSkip;
991 }; 1094 };
992 } // namespace 1095 } // namespace
993 1096
994 void findExplicitReferences(const Stmt *S, 1097 void findExplicitReferences(const Stmt *S,
995 llvm::function_ref<void(ReferenceLoc)> Out) { 1098 llvm::function_ref<void(ReferenceLoc)> Out,
1099 const HeuristicResolver *Resolver) {
996 assert(S); 1100 assert(S);
997 ExplicitReferenceCollector(Out).TraverseStmt(const_cast<Stmt *>(S)); 1101 ExplicitReferenceCollector(Out, Resolver).TraverseStmt(const_cast<Stmt *>(S));
998 } 1102 }
999 void findExplicitReferences(const Decl *D, 1103 void findExplicitReferences(const Decl *D,
1000 llvm::function_ref<void(ReferenceLoc)> Out) { 1104 llvm::function_ref<void(ReferenceLoc)> Out,
1105 const HeuristicResolver *Resolver) {
1001 assert(D); 1106 assert(D);
1002 ExplicitReferenceCollector(Out).TraverseDecl(const_cast<Decl *>(D)); 1107 ExplicitReferenceCollector(Out, Resolver).TraverseDecl(const_cast<Decl *>(D));
1003 } 1108 }
1004 void findExplicitReferences(const ASTContext &AST, 1109 void findExplicitReferences(const ASTContext &AST,
1005 llvm::function_ref<void(ReferenceLoc)> Out) { 1110 llvm::function_ref<void(ReferenceLoc)> Out,
1006 ExplicitReferenceCollector(Out).TraverseAST(const_cast<ASTContext &>(AST)); 1111 const HeuristicResolver *Resolver) {
1112 ExplicitReferenceCollector(Out, Resolver)
1113 .TraverseAST(const_cast<ASTContext &>(AST));
1007 } 1114 }
1008 1115
1009 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelation R) { 1116 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelation R) {
1010 switch (R) { 1117 switch (R) {
1011 #define REL_CASE(X) \ 1118 #define REL_CASE(X) \