1 //===--- FindTarget.cpp - What does an AST node refer to? -----------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "FindTarget.h"
11 #include "HeuristicResolver.h"
12 #include "support/Logger.h"
13 #include "clang/AST/ASTConcept.h"
14 #include "clang/AST/ASTTypeTraits.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/DeclVisitor.h"
20 #include "clang/AST/DeclarationName.h"
21 #include "clang/AST/Expr.h"
22 #include "clang/AST/ExprCXX.h"
23 #include "clang/AST/ExprConcepts.h"
24 #include "clang/AST/ExprObjC.h"
25 #include "clang/AST/NestedNameSpecifier.h"
26 #include "clang/AST/PrettyPrinter.h"
27 #include "clang/AST/RecursiveASTVisitor.h"
28 #include "clang/AST/StmtVisitor.h"
29 #include "clang/AST/TemplateBase.h"
30 #include "clang/AST/Type.h"
31 #include "clang/AST/TypeLoc.h"
32 #include "clang/AST/TypeLocVisitor.h"
33 #include "clang/AST/TypeVisitor.h"
34 #include "clang/Basic/LangOptions.h"
35 #include "clang/Basic/SourceLocation.h"
36 #include "clang/Basic/SourceManager.h"
37 #include "clang/Basic/Specifiers.h"
38 #include "llvm/ADT/STLExtras.h"
39 #include "llvm/ADT/SmallVector.h"
40 #include "llvm/ADT/StringExtras.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/Compiler.h"
43 #include "llvm/Support/raw_ostream.h"
53 LLVM_ATTRIBUTE_UNUSED
std::string
nodeToString(const DynTypedNode
&N
) {
54 std::string S
= std::string(N
.getNodeKind().asStringRef());
56 llvm::raw_string_ostream
OS(S
);
58 N
.print(OS
, PrintingPolicy(LangOptions()));
60 std::replace(S
.begin(), S
.end(), '\n', ' ');
64 const NamedDecl
*getTemplatePattern(const NamedDecl
*D
) {
65 if (const CXXRecordDecl
*CRD
= dyn_cast
<CXXRecordDecl
>(D
)) {
66 if (const auto *Result
= CRD
->getTemplateInstantiationPattern())
68 // getTemplateInstantiationPattern returns null if the Specialization is
69 // incomplete (e.g. the type didn't need to be complete), fall back to the
71 if (CRD
->getTemplateSpecializationKind() == TSK_Undeclared
)
72 if (const auto *Spec
= dyn_cast
<ClassTemplateSpecializationDecl
>(CRD
))
73 return Spec
->getSpecializedTemplate()->getTemplatedDecl();
74 } else if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
75 return FD
->getTemplateInstantiationPattern();
76 } else if (auto *VD
= dyn_cast
<VarDecl
>(D
)) {
77 // Hmm: getTIP returns its arg if it's not an instantiation?!
78 VarDecl
*T
= VD
->getTemplateInstantiationPattern();
79 return (T
== D
) ? nullptr : T
;
80 } else if (const auto *ED
= dyn_cast
<EnumDecl
>(D
)) {
81 return ED
->getInstantiatedFromMemberEnum();
82 } else if (isa
<FieldDecl
>(D
) || isa
<TypedefNameDecl
>(D
)) {
83 if (const auto *Parent
= llvm::dyn_cast
<NamedDecl
>(D
->getDeclContext()))
84 if (const DeclContext
*ParentPat
=
85 dyn_cast_or_null
<DeclContext
>(getTemplatePattern(Parent
)))
86 for (const NamedDecl
*BaseND
: ParentPat
->lookup(D
->getDeclName()))
87 if (!BaseND
->isImplicit() && BaseND
->getKind() == D
->getKind())
89 } else if (const auto *ECD
= dyn_cast
<EnumConstantDecl
>(D
)) {
90 if (const auto *ED
= dyn_cast
<EnumDecl
>(ECD
->getDeclContext())) {
91 if (const EnumDecl
*Pattern
= ED
->getInstantiatedFromMemberEnum()) {
92 for (const NamedDecl
*BaseECD
: Pattern
->lookup(ECD
->getDeclName()))
100 // Returns true if the `TypedefNameDecl` should not be reported.
101 bool shouldSkipTypedef(const TypedefNameDecl
*TD
) {
102 // These should be treated as keywords rather than decls - the typedef is an
103 // odd implementation detail.
104 if (TD
== TD
->getASTContext().getObjCInstanceTypeDecl() ||
105 TD
== TD
->getASTContext().getObjCIdDecl())
110 // TargetFinder locates the entities that an AST node refers to.
112 // Typically this is (possibly) one declaration and (possibly) one type, but
114 // - for ambiguous nodes like OverloadExpr
115 // - if we want to include e.g. both typedefs and the underlying type
117 // This is organized as a set of mutually recursive helpers for particular node
118 // types, but for most nodes this is a short walk rather than a deep traversal.
120 // It's tempting to do e.g. typedef resolution as a second normalization step,
121 // after finding the 'primary' decl etc. But we do this monolithically instead
123 // - normalization may require these traversals again (e.g. unwrapping a
124 // typedef reveals a decltype which must be traversed)
125 // - it doesn't simplify that much, e.g. the first stage must still be able
126 // to yield multiple decls to handle OverloadExpr
127 // - there are cases where it's required for correctness. e.g:
128 // template<class X> using pvec = vector<x*>; pvec<int> x;
129 // There's no Decl `pvec<int>`, we must choose `pvec<X>` or `vector<int*>`
130 // and both are lossy. We must know upfront what the caller ultimately wants.
131 struct TargetFinder
{
132 using RelSet
= DeclRelationSet
;
133 using Rel
= DeclRelation
;
136 const HeuristicResolver
*Resolver
;
137 llvm::SmallDenseMap
<const NamedDecl
*,
138 std::pair
<RelSet
, /*InsertionOrder*/ size_t>>
140 llvm::SmallDenseMap
<const Decl
*, RelSet
> Seen
;
143 template <typename T
> void debug(T
&Node
, RelSet Flags
) {
144 dlog("visit [{0}] {1}", Flags
, nodeToString(DynTypedNode::create(Node
)));
147 void report(const NamedDecl
*D
, RelSet Flags
) {
148 dlog("--> [{0}] {1}", Flags
, nodeToString(DynTypedNode::create(*D
)));
149 auto It
= Decls
.try_emplace(D
, std::make_pair(Flags
, Decls
.size()));
150 // If already exists, update the flags.
152 It
.first
->second
.first
|= Flags
;
156 TargetFinder(const HeuristicResolver
*Resolver
) : Resolver(Resolver
) {}
158 llvm::SmallVector
<std::pair
<const NamedDecl
*, RelSet
>, 1> takeDecls() const {
159 using ValTy
= std::pair
<const NamedDecl
*, RelSet
>;
160 llvm::SmallVector
<ValTy
, 1> Result
;
161 Result
.resize(Decls
.size());
162 for (const auto &Elem
: Decls
)
163 Result
[Elem
.second
.second
] = {Elem
.first
, Elem
.second
.first
};
167 void add(const Decl
*Dcl
, RelSet Flags
) {
168 const NamedDecl
*D
= llvm::dyn_cast_or_null
<NamedDecl
>(Dcl
);
173 // Avoid recursion (which can arise in the presence of heuristic
174 // resolution of dependent names) by exiting early if we have
175 // already seen this decl with all flags in Flags.
176 auto Res
= Seen
.try_emplace(D
);
177 if (!Res
.second
&& Res
.first
->second
.contains(Flags
))
179 Res
.first
->second
|= Flags
;
181 if (const UsingDirectiveDecl
*UDD
= llvm::dyn_cast
<UsingDirectiveDecl
>(D
))
182 D
= UDD
->getNominatedNamespaceAsWritten();
184 if (const TypedefNameDecl
*TND
= dyn_cast
<TypedefNameDecl
>(D
)) {
185 add(TND
->getUnderlyingType(), Flags
| Rel::Underlying
);
186 Flags
|= Rel::Alias
; // continue with the alias.
187 } else if (const UsingDecl
*UD
= dyn_cast
<UsingDecl
>(D
)) {
188 // no Underlying as this is a non-renaming alias.
189 for (const UsingShadowDecl
*S
: UD
->shadows())
190 add(S
->getUnderlyingDecl(), Flags
);
191 Flags
|= Rel::Alias
; // continue with the alias.
192 } else if (const UsingEnumDecl
*UED
= dyn_cast
<UsingEnumDecl
>(D
)) {
193 // UsingEnumDecl is not an alias at all, just a reference.
194 D
= UED
->getEnumDecl();
195 } else if (const auto *NAD
= dyn_cast
<NamespaceAliasDecl
>(D
)) {
196 add(NAD
->getUnderlyingDecl(), Flags
| Rel::Underlying
);
197 Flags
|= Rel::Alias
; // continue with the alias
198 } else if (const UnresolvedUsingValueDecl
*UUVD
=
199 dyn_cast
<UnresolvedUsingValueDecl
>(D
)) {
201 for (const NamedDecl
*Target
: Resolver
->resolveUsingValueDecl(UUVD
)) {
202 add(Target
, Flags
); // no Underlying as this is a non-renaming alias
205 Flags
|= Rel::Alias
; // continue with the alias
206 } else if (isa
<UnresolvedUsingTypenameDecl
>(D
)) {
207 // FIXME: improve common dependent scope using name lookup in primary
210 } else if (const UsingShadowDecl
*USD
= dyn_cast
<UsingShadowDecl
>(D
)) {
211 // Include the introducing UsingDecl, but don't traverse it. This may end
212 // up including *all* shadows, which we don't want.
213 // Don't apply this logic to UsingEnumDecl, which can't easily be
214 // conflated with the aliases it introduces.
215 if (llvm::isa
<UsingDecl
>(USD
->getIntroducer()))
216 report(USD
->getIntroducer(), Flags
| Rel::Alias
);
217 // Shadow decls are synthetic and not themselves interesting.
218 // Record the underlying decl instead, if allowed.
219 D
= USD
->getTargetDecl();
220 } else if (const auto *DG
= dyn_cast
<CXXDeductionGuideDecl
>(D
)) {
221 D
= DG
->getDeducedTemplate();
222 } else if (const ObjCImplementationDecl
*IID
=
223 dyn_cast
<ObjCImplementationDecl
>(D
)) {
224 // Treat ObjC{Interface,Implementation}Decl as if they were a decl/def
225 // pair as long as the interface isn't implicit.
226 if (const auto *CID
= IID
->getClassInterface())
227 if (const auto *DD
= CID
->getDefinition())
228 if (!DD
->isImplicitInterfaceDecl())
230 } else if (const ObjCCategoryImplDecl
*CID
=
231 dyn_cast
<ObjCCategoryImplDecl
>(D
)) {
232 // Treat ObjC{Category,CategoryImpl}Decl as if they were a decl/def pair.
233 D
= CID
->getCategoryDecl();
238 if (const Decl
*Pat
= getTemplatePattern(D
)) {
240 add(Pat
, Flags
| Rel::TemplatePattern
);
241 // Now continue with the instantiation.
242 Flags
|= Rel::TemplateInstantiation
;
248 void add(const Stmt
*S
, RelSet Flags
) {
252 struct Visitor
: public ConstStmtVisitor
<Visitor
> {
255 Visitor(TargetFinder
&Outer
, RelSet Flags
) : Outer(Outer
), Flags(Flags
) {}
257 void VisitCallExpr(const CallExpr
*CE
) {
258 Outer
.add(CE
->getCalleeDecl(), Flags
);
260 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr
*E
) {
261 Outer
.add(E
->getConceptReference(), Flags
);
263 void VisitDeclRefExpr(const DeclRefExpr
*DRE
) {
264 const Decl
*D
= DRE
->getDecl();
265 // UsingShadowDecl allows us to record the UsingDecl.
266 // getFoundDecl() returns the wrong thing in other cases (templates).
267 if (auto *USD
= llvm::dyn_cast
<UsingShadowDecl
>(DRE
->getFoundDecl()))
271 void VisitMemberExpr(const MemberExpr
*ME
) {
272 const Decl
*D
= ME
->getMemberDecl();
274 llvm::dyn_cast
<UsingShadowDecl
>(ME
->getFoundDecl().getDecl()))
278 void VisitOverloadExpr(const OverloadExpr
*OE
) {
279 for (auto *D
: OE
->decls())
282 void VisitSizeOfPackExpr(const SizeOfPackExpr
*SE
) {
283 Outer
.add(SE
->getPack(), Flags
);
285 void VisitCXXConstructExpr(const CXXConstructExpr
*CCE
) {
286 Outer
.add(CCE
->getConstructor(), Flags
);
288 void VisitDesignatedInitExpr(const DesignatedInitExpr
*DIE
) {
289 for (const DesignatedInitExpr::Designator
&D
:
290 llvm::reverse(DIE
->designators()))
291 if (D
.isFieldDesignator()) {
292 Outer
.add(D
.getFieldDecl(), Flags
);
293 // We don't know which designator was intended, we assume the outer.
297 void VisitGotoStmt(const GotoStmt
*Goto
) {
298 if (auto *LabelDecl
= Goto
->getLabel())
299 Outer
.add(LabelDecl
, Flags
);
301 void VisitLabelStmt(const LabelStmt
*Label
) {
302 if (auto *LabelDecl
= Label
->getDecl())
303 Outer
.add(LabelDecl
, Flags
);
306 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr
*E
) {
307 if (Outer
.Resolver
) {
308 for (const NamedDecl
*D
: Outer
.Resolver
->resolveMemberExpr(E
)) {
313 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr
*E
) {
314 if (Outer
.Resolver
) {
315 for (const NamedDecl
*D
: Outer
.Resolver
->resolveDeclRefExpr(E
)) {
320 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr
*OIRE
) {
321 Outer
.add(OIRE
->getDecl(), Flags
);
323 void VisitObjCMessageExpr(const ObjCMessageExpr
*OME
) {
324 Outer
.add(OME
->getMethodDecl(), Flags
);
326 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr
*OPRE
) {
327 if (OPRE
->isExplicitProperty())
328 Outer
.add(OPRE
->getExplicitProperty(), Flags
);
330 if (OPRE
->isMessagingGetter())
331 Outer
.add(OPRE
->getImplicitPropertyGetter(), Flags
);
332 if (OPRE
->isMessagingSetter())
333 Outer
.add(OPRE
->getImplicitPropertySetter(), Flags
);
336 void VisitObjCProtocolExpr(const ObjCProtocolExpr
*OPE
) {
337 Outer
.add(OPE
->getProtocol(), Flags
);
339 void VisitOpaqueValueExpr(const OpaqueValueExpr
*OVE
) {
340 Outer
.add(OVE
->getSourceExpr(), Flags
);
342 void VisitPseudoObjectExpr(const PseudoObjectExpr
*POE
) {
343 Outer
.add(POE
->getSyntacticForm(), Flags
);
345 void VisitCXXNewExpr(const CXXNewExpr
*CNE
) {
346 Outer
.add(CNE
->getOperatorNew(), Flags
);
348 void VisitCXXDeleteExpr(const CXXDeleteExpr
*CDE
) {
349 Outer
.add(CDE
->getOperatorDelete(), Flags
);
352 VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator
*RBO
) {
353 Outer
.add(RBO
->getDecomposedForm().InnerBinOp
, Flags
);
356 Visitor(*this, Flags
).Visit(S
);
359 void add(QualType T
, RelSet Flags
) {
363 struct Visitor
: public TypeVisitor
<Visitor
> {
366 Visitor(TargetFinder
&Outer
, RelSet Flags
) : Outer(Outer
), Flags(Flags
) {}
368 void VisitTagType(const TagType
*TT
) {
369 Outer
.add(TT
->getAsTagDecl(), Flags
);
372 void VisitElaboratedType(const ElaboratedType
*ET
) {
373 Outer
.add(ET
->desugar(), Flags
);
376 void VisitUsingType(const UsingType
*ET
) {
377 Outer
.add(ET
->getFoundDecl(), Flags
);
380 void VisitInjectedClassNameType(const InjectedClassNameType
*ICNT
) {
381 Outer
.add(ICNT
->getDecl(), Flags
);
384 void VisitDecltypeType(const DecltypeType
*DTT
) {
385 Outer
.add(DTT
->getUnderlyingType(), Flags
| Rel::Underlying
);
387 void VisitDeducedType(const DeducedType
*DT
) {
388 // FIXME: In practice this doesn't work: the AutoType you find inside
389 // TypeLoc never has a deduced type. https://llvm.org/PR42914
390 Outer
.add(DT
->getDeducedType(), Flags
);
392 void VisitUnresolvedUsingType(const UnresolvedUsingType
*UUT
) {
393 Outer
.add(UUT
->getDecl(), Flags
);
395 void VisitDeducedTemplateSpecializationType(
396 const DeducedTemplateSpecializationType
*DTST
) {
397 if (const auto *USD
= DTST
->getTemplateName().getAsUsingShadowDecl())
398 Outer
.add(USD
, Flags
);
400 // FIXME: This is a workaround for https://llvm.org/PR42914,
401 // which is causing DTST->getDeducedType() to be empty. We
402 // fall back to the template pattern and miss the instantiation
403 // even when it's known in principle. Once that bug is fixed,
404 // the following code can be removed (the existing handling in
405 // VisitDeducedType() is sufficient).
406 if (auto *TD
= DTST
->getTemplateName().getAsTemplateDecl())
407 Outer
.add(TD
->getTemplatedDecl(), Flags
| Rel::TemplatePattern
);
409 void VisitDependentNameType(const DependentNameType
*DNT
) {
410 if (Outer
.Resolver
) {
411 for (const NamedDecl
*ND
:
412 Outer
.Resolver
->resolveDependentNameType(DNT
)) {
413 Outer
.add(ND
, Flags
);
417 void VisitDependentTemplateSpecializationType(
418 const DependentTemplateSpecializationType
*DTST
) {
419 if (Outer
.Resolver
) {
420 for (const NamedDecl
*ND
:
421 Outer
.Resolver
->resolveTemplateSpecializationType(DTST
)) {
422 Outer
.add(ND
, Flags
);
426 void VisitTypedefType(const TypedefType
*TT
) {
427 if (shouldSkipTypedef(TT
->getDecl()))
429 Outer
.add(TT
->getDecl(), Flags
);
432 VisitTemplateSpecializationType(const TemplateSpecializationType
*TST
) {
433 // Have to handle these case-by-case.
435 if (const auto *UTN
= TST
->getTemplateName().getAsUsingShadowDecl())
436 Outer
.add(UTN
, Flags
);
438 // templated type aliases: there's no specialized/instantiated using
439 // decl to point to. So try to find a decl for the underlying type
440 // (after substitution), and failing that point to the (templated) using
442 if (TST
->isTypeAlias()) {
443 Outer
.add(TST
->getAliasedType(), Flags
| Rel::Underlying
);
444 // Don't *traverse* the alias, which would result in traversing the
445 // template of the underlying type.
447 TST
->getTemplateName().getAsTemplateDecl()->getTemplatedDecl(),
448 Flags
| Rel::Alias
| Rel::TemplatePattern
);
450 // specializations of template template parameters aren't instantiated
451 // into decls, so they must refer to the parameter itself.
452 else if (const auto *Parm
=
453 llvm::dyn_cast_or_null
<TemplateTemplateParmDecl
>(
454 TST
->getTemplateName().getAsTemplateDecl()))
455 Outer
.add(Parm
, Flags
);
456 // class template specializations have a (specialized) CXXRecordDecl.
457 else if (const CXXRecordDecl
*RD
= TST
->getAsCXXRecordDecl())
458 Outer
.add(RD
, Flags
); // add(Decl) will despecialize if needed.
460 // fallback: the (un-specialized) declaration from primary template.
461 if (auto *TD
= TST
->getTemplateName().getAsTemplateDecl())
462 Outer
.add(TD
->getTemplatedDecl(), Flags
| Rel::TemplatePattern
);
466 VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType
*STTPT
) {
467 Outer
.add(STTPT
->getReplacementType(), Flags
);
469 void VisitTemplateTypeParmType(const TemplateTypeParmType
*TTPT
) {
470 Outer
.add(TTPT
->getDecl(), Flags
);
472 void VisitObjCInterfaceType(const ObjCInterfaceType
*OIT
) {
473 Outer
.add(OIT
->getDecl(), Flags
);
476 Visitor(*this, Flags
).Visit(T
.getTypePtr());
479 void add(const NestedNameSpecifier
*NNS
, RelSet Flags
) {
483 switch (NNS
->getKind()) {
484 case NestedNameSpecifier::Namespace
:
485 add(NNS
->getAsNamespace(), Flags
);
487 case NestedNameSpecifier::NamespaceAlias
:
488 add(NNS
->getAsNamespaceAlias(), Flags
);
490 case NestedNameSpecifier::Identifier
:
492 add(QualType(Resolver
->resolveNestedNameSpecifierToType(NNS
), 0),
496 case NestedNameSpecifier::TypeSpec
:
497 case NestedNameSpecifier::TypeSpecWithTemplate
:
498 add(QualType(NNS
->getAsType(), 0), Flags
);
500 case NestedNameSpecifier::Global
:
501 // This should be TUDecl, but we can't get a pointer to it!
503 case NestedNameSpecifier::Super
:
504 add(NNS
->getAsRecordDecl(), Flags
);
507 llvm_unreachable("unhandled NestedNameSpecifier::SpecifierKind");
510 void add(const CXXCtorInitializer
*CCI
, RelSet Flags
) {
515 if (CCI
->isAnyMemberInitializer())
516 add(CCI
->getAnyMember(), Flags
);
517 // Constructor calls contain a TypeLoc node, so we don't handle them here.
520 void add(const TemplateArgument
&Arg
, RelSet Flags
) {
521 // Only used for template template arguments.
522 // For type and non-type template arguments, SelectionTree
523 // will hit a more specific node (e.g. a TypeLoc or a
525 if (Arg
.getKind() == TemplateArgument::Template
||
526 Arg
.getKind() == TemplateArgument::TemplateExpansion
) {
527 if (TemplateDecl
*TD
=
528 Arg
.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) {
531 if (const auto *USD
=
532 Arg
.getAsTemplateOrTemplatePattern().getAsUsingShadowDecl())
537 void add(const ConceptReference
*CR
, RelSet Flags
) {
538 add(CR
->getNamedConcept(), Flags
);
544 llvm::SmallVector
<std::pair
<const NamedDecl
*, DeclRelationSet
>, 1>
545 allTargetDecls(const DynTypedNode
&N
, const HeuristicResolver
*Resolver
) {
546 dlog("allTargetDecls({0})", nodeToString(N
));
547 TargetFinder
Finder(Resolver
);
548 DeclRelationSet Flags
;
549 if (const Decl
*D
= N
.get
<Decl
>())
550 Finder
.add(D
, Flags
);
551 else if (const Stmt
*S
= N
.get
<Stmt
>())
552 Finder
.add(S
, Flags
);
553 else if (const NestedNameSpecifierLoc
*NNSL
= N
.get
<NestedNameSpecifierLoc
>())
554 Finder
.add(NNSL
->getNestedNameSpecifier(), Flags
);
555 else if (const NestedNameSpecifier
*NNS
= N
.get
<NestedNameSpecifier
>())
556 Finder
.add(NNS
, Flags
);
557 else if (const TypeLoc
*TL
= N
.get
<TypeLoc
>())
558 Finder
.add(TL
->getType(), Flags
);
559 else if (const QualType
*QT
= N
.get
<QualType
>())
560 Finder
.add(*QT
, Flags
);
561 else if (const CXXCtorInitializer
*CCI
= N
.get
<CXXCtorInitializer
>())
562 Finder
.add(CCI
, Flags
);
563 else if (const TemplateArgumentLoc
*TAL
= N
.get
<TemplateArgumentLoc
>())
564 Finder
.add(TAL
->getArgument(), Flags
);
565 else if (const CXXBaseSpecifier
*CBS
= N
.get
<CXXBaseSpecifier
>())
566 Finder
.add(CBS
->getTypeSourceInfo()->getType(), Flags
);
567 else if (const ObjCProtocolLoc
*PL
= N
.get
<ObjCProtocolLoc
>())
568 Finder
.add(PL
->getProtocol(), Flags
);
569 else if (const ConceptReference
*CR
= N
.get
<ConceptReference
>())
570 Finder
.add(CR
, Flags
);
571 return Finder
.takeDecls();
574 llvm::SmallVector
<const NamedDecl
*, 1>
575 targetDecl(const DynTypedNode
&N
, DeclRelationSet Mask
,
576 const HeuristicResolver
*Resolver
) {
577 llvm::SmallVector
<const NamedDecl
*, 1> Result
;
578 for (const auto &Entry
: allTargetDecls(N
, Resolver
)) {
579 if (!(Entry
.second
& ~Mask
))
580 Result
.push_back(Entry
.first
);
585 llvm::SmallVector
<const NamedDecl
*, 1>
586 explicitReferenceTargets(DynTypedNode N
, DeclRelationSet Mask
,
587 const HeuristicResolver
*Resolver
) {
588 assert(!(Mask
& (DeclRelation::TemplatePattern
|
589 DeclRelation::TemplateInstantiation
)) &&
590 "explicitReferenceTargets handles templates on its own");
591 auto Decls
= allTargetDecls(N
, Resolver
);
593 // We prefer to return template instantiation, but fallback to template
594 // pattern if instantiation is not available.
595 Mask
|= DeclRelation::TemplatePattern
| DeclRelation::TemplateInstantiation
;
597 llvm::SmallVector
<const NamedDecl
*, 1> TemplatePatterns
;
598 llvm::SmallVector
<const NamedDecl
*, 1> Targets
;
599 bool SeenTemplateInstantiations
= false;
600 for (auto &D
: Decls
) {
601 if (D
.second
& ~Mask
)
603 if (D
.second
& DeclRelation::TemplatePattern
) {
604 TemplatePatterns
.push_back(D
.first
);
607 if (D
.second
& DeclRelation::TemplateInstantiation
)
608 SeenTemplateInstantiations
= true;
609 Targets
.push_back(D
.first
);
611 if (!SeenTemplateInstantiations
)
612 Targets
.insert(Targets
.end(), TemplatePatterns
.begin(),
613 TemplatePatterns
.end());
618 llvm::SmallVector
<ReferenceLoc
> refInDecl(const Decl
*D
,
619 const HeuristicResolver
*Resolver
) {
620 struct Visitor
: ConstDeclVisitor
<Visitor
> {
621 Visitor(const HeuristicResolver
*Resolver
) : Resolver(Resolver
) {}
623 const HeuristicResolver
*Resolver
;
624 llvm::SmallVector
<ReferenceLoc
> Refs
;
626 void VisitUsingDirectiveDecl(const UsingDirectiveDecl
*D
) {
627 // We want to keep it as non-declaration references, as the
628 // "using namespace" declaration doesn't have a name.
629 Refs
.push_back(ReferenceLoc
{D
->getQualifierLoc(),
630 D
->getIdentLocation(),
632 {D
->getNominatedNamespaceAsWritten()}});
635 void VisitUsingDecl(const UsingDecl
*D
) {
636 // "using ns::identifier;" is a non-declaration reference.
637 Refs
.push_back(ReferenceLoc
{
638 D
->getQualifierLoc(), D
->getLocation(), /*IsDecl=*/false,
639 explicitReferenceTargets(DynTypedNode::create(*D
),
640 DeclRelation::Underlying
, Resolver
)});
643 void VisitUsingEnumDecl(const UsingEnumDecl
*D
) {
644 // "using enum ns::E" is a non-declaration reference.
645 // The reference is covered by the embedded typeloc.
646 // Don't use the default VisitNamedDecl, which would report a declaration.
649 void VisitNamespaceAliasDecl(const NamespaceAliasDecl
*D
) {
650 // For namespace alias, "namespace Foo = Target;", we add two references.
651 // Add a declaration reference for Foo.
653 // Add a non-declaration reference for Target.
654 Refs
.push_back(ReferenceLoc
{D
->getQualifierLoc(),
655 D
->getTargetNameLoc(),
657 {D
->getAliasedNamespace()}});
660 void VisitNamedDecl(const NamedDecl
*ND
) {
661 // We choose to ignore {Class, Function, Var, TypeAlias}TemplateDecls. As
662 // as their underlying decls, covering the same range, will be visited.
663 if (llvm::isa
<ClassTemplateDecl
>(ND
) ||
664 llvm::isa
<FunctionTemplateDecl
>(ND
) ||
665 llvm::isa
<VarTemplateDecl
>(ND
) ||
666 llvm::isa
<TypeAliasTemplateDecl
>(ND
))
668 // FIXME: decide on how to surface destructors when we need them.
669 if (llvm::isa
<CXXDestructorDecl
>(ND
))
671 // Filter anonymous decls, name location will point outside the name token
672 // and the clients are not prepared to handle that.
673 if (ND
->getDeclName().isIdentifier() &&
674 !ND
->getDeclName().getAsIdentifierInfo())
676 Refs
.push_back(ReferenceLoc
{getQualifierLoc(*ND
),
682 void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl
*DG
) {
683 // The class template name in a deduction guide targets the class
685 Refs
.push_back(ReferenceLoc
{DG
->getQualifierLoc(),
686 DG
->getNameInfo().getLoc(),
688 {DG
->getDeducedTemplate()}});
691 void VisitObjCMethodDecl(const ObjCMethodDecl
*OMD
) {
692 // The name may have several tokens, we can only report the first.
693 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
694 OMD
->getSelectorStartLoc(),
699 void VisitObjCCategoryDecl(const ObjCCategoryDecl
*OCD
) {
700 // getLocation is the extended class's location, not the category's.
701 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
704 {OCD
->getClassInterface()}});
705 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
706 OCD
->getCategoryNameLoc(),
711 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl
*OCID
) {
712 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
715 {OCID
->getClassInterface()}});
716 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
717 OCID
->getCategoryNameLoc(),
719 {OCID
->getCategoryDecl()}});
720 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
721 OCID
->getCategoryNameLoc(),
726 void VisitObjCImplementationDecl(const ObjCImplementationDecl
*OIMD
) {
727 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
730 {OIMD
->getClassInterface()}});
731 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
743 llvm::SmallVector
<ReferenceLoc
> refInStmt(const Stmt
*S
,
744 const HeuristicResolver
*Resolver
) {
745 struct Visitor
: ConstStmtVisitor
<Visitor
> {
746 Visitor(const HeuristicResolver
*Resolver
) : Resolver(Resolver
) {}
748 const HeuristicResolver
*Resolver
;
749 // FIXME: handle more complicated cases: more ObjC, designated initializers.
750 llvm::SmallVector
<ReferenceLoc
> Refs
;
752 void VisitDeclRefExpr(const DeclRefExpr
*E
) {
753 Refs
.push_back(ReferenceLoc
{E
->getQualifierLoc(),
754 E
->getNameInfo().getLoc(),
756 {E
->getFoundDecl()}});
759 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr
*E
) {
760 Refs
.push_back(ReferenceLoc
{
761 E
->getQualifierLoc(), E
->getNameInfo().getLoc(), /*IsDecl=*/false,
762 explicitReferenceTargets(DynTypedNode::create(*E
), {}, Resolver
)});
765 void VisitMemberExpr(const MemberExpr
*E
) {
766 // Skip destructor calls to avoid duplication: TypeLoc within will be
767 // visited separately.
768 if (llvm::isa
<CXXDestructorDecl
>(E
->getFoundDecl().getDecl()))
770 Refs
.push_back(ReferenceLoc
{E
->getQualifierLoc(),
771 E
->getMemberNameInfo().getLoc(),
773 {E
->getFoundDecl()}});
777 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr
*E
) {
778 Refs
.push_back(ReferenceLoc
{
779 E
->getQualifierLoc(), E
->getMemberNameInfo().getLoc(),
781 explicitReferenceTargets(DynTypedNode::create(*E
), {}, Resolver
)});
784 void VisitOverloadExpr(const OverloadExpr
*E
) {
785 Refs
.push_back(ReferenceLoc
{E
->getQualifierLoc(),
786 E
->getNameInfo().getLoc(),
788 llvm::SmallVector
<const NamedDecl
*, 1>(
789 E
->decls().begin(), E
->decls().end())});
792 void VisitSizeOfPackExpr(const SizeOfPackExpr
*E
) {
793 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
799 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr
*E
) {
800 Refs
.push_back(ReferenceLoc
{
801 NestedNameSpecifierLoc(), E
->getLocation(),
803 // Select the getter, setter, or @property depending on the call.
804 explicitReferenceTargets(DynTypedNode::create(*E
), {}, Resolver
)});
807 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr
*OIRE
) {
808 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
814 void VisitObjCMessageExpr(const ObjCMessageExpr
*E
) {
815 // The name may have several tokens, we can only report the first.
816 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
817 E
->getSelectorStartLoc(),
819 {E
->getMethodDecl()}});
822 void VisitDesignatedInitExpr(const DesignatedInitExpr
*DIE
) {
823 for (const DesignatedInitExpr::Designator
&D
: DIE
->designators()) {
824 if (!D
.isFieldDesignator())
827 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
830 {D
.getFieldDecl()}});
834 void VisitGotoStmt(const GotoStmt
*GS
) {
835 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
841 void VisitLabelStmt(const LabelStmt
*LS
) {
842 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
854 llvm::SmallVector
<ReferenceLoc
>
855 refInTypeLoc(TypeLoc L
, const HeuristicResolver
*Resolver
) {
856 struct Visitor
: TypeLocVisitor
<Visitor
> {
857 Visitor(const HeuristicResolver
*Resolver
) : Resolver(Resolver
) {}
859 const HeuristicResolver
*Resolver
;
860 llvm::SmallVector
<ReferenceLoc
> Refs
;
862 void VisitElaboratedTypeLoc(ElaboratedTypeLoc L
) {
863 // We only know about qualifier, rest if filled by inner locations.
864 size_t InitialSize
= Refs
.size();
865 Visit(L
.getNamedTypeLoc().getUnqualifiedLoc());
866 size_t NewSize
= Refs
.size();
867 // Add qualifier for the newly-added refs.
868 for (unsigned I
= InitialSize
; I
< NewSize
; ++I
) {
869 ReferenceLoc
*Ref
= &Refs
[I
];
870 // Fill in the qualifier.
871 assert(!Ref
->Qualifier
.hasQualifier() && "qualifier already set");
872 Ref
->Qualifier
= L
.getQualifierLoc();
876 void VisitUsingTypeLoc(UsingTypeLoc L
) {
877 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
878 L
.getLocalSourceRange().getBegin(),
880 {L
.getFoundDecl()}});
883 void VisitTagTypeLoc(TagTypeLoc L
) {
884 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
890 void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L
) {
891 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
897 void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L
) {
898 // We must ensure template type aliases are included in results if they
899 // were written in the source code, e.g. in
900 // template <class T> using valias = vector<T>;
902 // 'explicitReferenceTargets' will return:
903 // 1. valias with mask 'Alias'.
904 // 2. 'vector<int>' with mask 'Underlying'.
905 // we want to return only #1 in this case.
906 Refs
.push_back(ReferenceLoc
{
907 NestedNameSpecifierLoc(), L
.getTemplateNameLoc(), /*IsDecl=*/false,
908 explicitReferenceTargets(DynTypedNode::create(L
.getType()),
909 DeclRelation::Alias
, Resolver
)});
911 void VisitDeducedTemplateSpecializationTypeLoc(
912 DeducedTemplateSpecializationTypeLoc L
) {
913 Refs
.push_back(ReferenceLoc
{
914 NestedNameSpecifierLoc(), L
.getNameLoc(), /*IsDecl=*/false,
915 explicitReferenceTargets(DynTypedNode::create(L
.getType()),
916 DeclRelation::Alias
, Resolver
)});
919 void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL
) {
920 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
926 void VisitDependentTemplateSpecializationTypeLoc(
927 DependentTemplateSpecializationTypeLoc L
) {
929 ReferenceLoc
{L
.getQualifierLoc(), L
.getTemplateNameLoc(),
931 explicitReferenceTargets(
932 DynTypedNode::create(L
.getType()), {}, Resolver
)});
935 void VisitDependentNameTypeLoc(DependentNameTypeLoc L
) {
937 ReferenceLoc
{L
.getQualifierLoc(), L
.getNameLoc(),
939 explicitReferenceTargets(
940 DynTypedNode::create(L
.getType()), {}, Resolver
)});
943 void VisitTypedefTypeLoc(TypedefTypeLoc L
) {
944 if (shouldSkipTypedef(L
.getTypedefNameDecl()))
946 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
949 {L
.getTypedefNameDecl()}});
952 void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc L
) {
953 Refs
.push_back(ReferenceLoc
{NestedNameSpecifierLoc(),
956 {L
.getIFaceDecl()}});
961 V
.Visit(L
.getUnqualifiedLoc());
965 class ExplicitReferenceCollector
966 : public RecursiveASTVisitor
<ExplicitReferenceCollector
> {
968 ExplicitReferenceCollector(llvm::function_ref
<void(ReferenceLoc
)> Out
,
969 const HeuristicResolver
*Resolver
)
970 : Out(Out
), Resolver(Resolver
) {
974 bool VisitTypeLoc(TypeLoc TTL
) {
975 if (TypeLocsToSkip
.count(TTL
.getBeginLoc()))
977 visitNode(DynTypedNode::create(TTL
));
981 bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L
) {
982 // ElaboratedTypeLoc will reports information for its inner type loc.
983 // Otherwise we loose information about inner types loc's qualifier.
984 TypeLoc Inner
= L
.getNamedTypeLoc().getUnqualifiedLoc();
985 if (L
.getBeginLoc() == Inner
.getBeginLoc())
986 return RecursiveASTVisitor::TraverseTypeLoc(Inner
);
988 TypeLocsToSkip
.insert(Inner
.getBeginLoc());
989 return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L
);
992 bool VisitStmt(Stmt
*S
) {
993 visitNode(DynTypedNode::create(*S
));
997 bool TraverseOpaqueValueExpr(OpaqueValueExpr
*OVE
) {
998 visitNode(DynTypedNode::create(*OVE
));
999 // Not clear why the source expression is skipped by default...
1000 // FIXME: can we just make RecursiveASTVisitor do this?
1001 return RecursiveASTVisitor::TraverseStmt(OVE
->getSourceExpr());
1004 bool TraversePseudoObjectExpr(PseudoObjectExpr
*POE
) {
1005 visitNode(DynTypedNode::create(*POE
));
1006 // Traverse only the syntactic form to find the *written* references.
1007 // (The semantic form also contains lots of duplication)
1008 return RecursiveASTVisitor::TraverseStmt(POE
->getSyntacticForm());
1011 // We re-define Traverse*, since there's no corresponding Visit*.
1012 // TemplateArgumentLoc is the only way to get locations for references to
1013 // template template parameters.
1014 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A
) {
1015 switch (A
.getArgument().getKind()) {
1016 case TemplateArgument::Template
:
1017 case TemplateArgument::TemplateExpansion
:
1018 reportReference(ReferenceLoc
{A
.getTemplateQualifierLoc(),
1019 A
.getTemplateNameLoc(),
1022 .getAsTemplateOrTemplatePattern()
1023 .getAsTemplateDecl()}},
1024 DynTypedNode::create(A
.getArgument()));
1026 case TemplateArgument::Declaration
:
1027 break; // FIXME: can this actually happen in TemplateArgumentLoc?
1028 case TemplateArgument::Integral
:
1029 case TemplateArgument::Null
:
1030 case TemplateArgument::NullPtr
:
1031 break; // no references.
1032 case TemplateArgument::Pack
:
1033 case TemplateArgument::Type
:
1034 case TemplateArgument::Expression
:
1035 break; // Handled by VisitType and VisitExpression.
1037 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A
);
1040 bool VisitDecl(Decl
*D
) {
1041 visitNode(DynTypedNode::create(*D
));
1045 // We have to use Traverse* because there is no corresponding Visit*.
1046 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc L
) {
1047 if (!L
.getNestedNameSpecifier())
1049 visitNode(DynTypedNode::create(L
));
1050 // Inner type is missing information about its qualifier, skip it.
1051 if (auto TL
= L
.getTypeLoc())
1052 TypeLocsToSkip
.insert(TL
.getBeginLoc());
1053 return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(L
);
1056 bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc
) {
1057 visitNode(DynTypedNode::create(ProtocolLoc
));
1061 bool TraverseConstructorInitializer(CXXCtorInitializer
*Init
) {
1062 visitNode(DynTypedNode::create(*Init
));
1063 return RecursiveASTVisitor::TraverseConstructorInitializer(Init
);
1066 bool VisitConceptReference(const ConceptReference
*CR
) {
1067 visitNode(DynTypedNode::create(*CR
));
1072 /// Obtain information about a reference directly defined in \p N. Does not
1073 /// recurse into child nodes, e.g. do not expect references for constructor
1076 /// Any of the fields in the returned structure can be empty, but not all of
1078 /// - for implicitly generated nodes (e.g. MemberExpr from range-based-for),
1079 /// source location information may be missing,
1080 /// - for dependent code, targets may be empty.
1082 /// (!) For the purposes of this function declarations are not considered to
1083 /// be references. However, declarations can have references inside them,
1084 /// e.g. 'namespace foo = std' references namespace 'std' and this
1085 /// function will return the corresponding reference.
1086 llvm::SmallVector
<ReferenceLoc
> explicitReference(DynTypedNode N
) {
1087 if (auto *D
= N
.get
<Decl
>())
1088 return refInDecl(D
, Resolver
);
1089 if (auto *S
= N
.get
<Stmt
>())
1090 return refInStmt(S
, Resolver
);
1091 if (auto *NNSL
= N
.get
<NestedNameSpecifierLoc
>()) {
1092 // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases.
1093 return {ReferenceLoc
{
1094 NNSL
->getPrefix(), NNSL
->getLocalBeginLoc(), false,
1095 explicitReferenceTargets(
1096 DynTypedNode::create(*NNSL
->getNestedNameSpecifier()),
1097 DeclRelation::Alias
, Resolver
)}};
1099 if (const TypeLoc
*TL
= N
.get
<TypeLoc
>())
1100 return refInTypeLoc(*TL
, Resolver
);
1101 if (const CXXCtorInitializer
*CCI
= N
.get
<CXXCtorInitializer
>()) {
1102 // Other type initializers (e.g. base initializer) are handled by visiting
1104 if (CCI
->isAnyMemberInitializer()) {
1105 return {ReferenceLoc
{NestedNameSpecifierLoc(),
1106 CCI
->getMemberLocation(),
1108 {CCI
->getAnyMember()}}};
1111 if (const ObjCProtocolLoc
*PL
= N
.get
<ObjCProtocolLoc
>())
1112 return {ReferenceLoc
{NestedNameSpecifierLoc(),
1115 {PL
->getProtocol()}}};
1116 if (const ConceptReference
*CR
= N
.get
<ConceptReference
>())
1117 return {ReferenceLoc
{CR
->getNestedNameSpecifierLoc(),
1118 CR
->getConceptNameLoc(),
1120 {CR
->getNamedConcept()}}};
1122 // We do not have location information for other nodes (QualType, etc)
1126 void visitNode(DynTypedNode N
) {
1127 for (auto &R
: explicitReference(N
))
1128 reportReference(std::move(R
), N
);
1131 void reportReference(ReferenceLoc
&&Ref
, DynTypedNode N
) {
1132 // Strip null targets that can arise from invalid code.
1133 // (This avoids having to check for null everywhere we insert)
1134 llvm::erase(Ref
.Targets
, nullptr);
1135 // Our promise is to return only references from the source code. If we lack
1136 // location information, skip these nodes.
1137 // Normally this should not happen in practice, unless there are bugs in the
1138 // traversals or users started the traversal at an implicit node.
1139 if (Ref
.NameLoc
.isInvalid()) {
1140 dlog("invalid location at node {0}", nodeToString(N
));
1146 llvm::function_ref
<void(ReferenceLoc
)> Out
;
1147 const HeuristicResolver
*Resolver
;
1148 /// TypeLocs starting at these locations must be skipped, see
1149 /// TraverseElaboratedTypeSpecifierLoc for details.
1150 llvm::DenseSet
<SourceLocation
> TypeLocsToSkip
;
1154 void findExplicitReferences(const Stmt
*S
,
1155 llvm::function_ref
<void(ReferenceLoc
)> Out
,
1156 const HeuristicResolver
*Resolver
) {
1158 ExplicitReferenceCollector(Out
, Resolver
).TraverseStmt(const_cast<Stmt
*>(S
));
1160 void findExplicitReferences(const Decl
*D
,
1161 llvm::function_ref
<void(ReferenceLoc
)> Out
,
1162 const HeuristicResolver
*Resolver
) {
1164 ExplicitReferenceCollector(Out
, Resolver
).TraverseDecl(const_cast<Decl
*>(D
));
1166 void findExplicitReferences(const ASTContext
&AST
,
1167 llvm::function_ref
<void(ReferenceLoc
)> Out
,
1168 const HeuristicResolver
*Resolver
) {
1169 ExplicitReferenceCollector(Out
, Resolver
)
1170 .TraverseAST(const_cast<ASTContext
&>(AST
));
1173 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, DeclRelation R
) {
1175 #define REL_CASE(X) \
1176 case DeclRelation::X: \
1179 REL_CASE(Underlying
);
1180 REL_CASE(TemplateInstantiation
);
1181 REL_CASE(TemplatePattern
);
1184 llvm_unreachable("Unhandled DeclRelation enum");
1186 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, DeclRelationSet RS
) {
1187 const char *Sep
= "";
1188 for (unsigned I
= 0; I
< RS
.S
.size(); ++I
) {
1190 OS
<< Sep
<< static_cast<DeclRelation
>(I
);
1197 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, ReferenceLoc R
) {
1198 // note we cannot print R.NameLoc without a source manager.
1199 OS
<< "targets = {";
1200 llvm::SmallVector
<std::string
> Targets
;
1201 for (const NamedDecl
*T
: R
.Targets
) {
1202 llvm::raw_string_ostream
Target(Targets
.emplace_back());
1203 Target
<< printQualifiedName(*T
) << printTemplateSpecializationArgs(*T
);
1205 llvm::sort(Targets
);
1206 OS
<< llvm::join(Targets
, ", ");
1209 OS
<< ", qualifier = '";
1210 R
.Qualifier
.getNestedNameSpecifier()->print(OS
,
1211 PrintingPolicy(LangOptions()));
1219 } // namespace clangd
1220 } // namespace clang