12 #include "clang/AST/ASTTypeTraits.h"
13 #include "clang/AST/Decl.h"
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/DeclVisitor.h"
17 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/ExprConcepts.h"
21 #include "clang/AST/ExprObjC.h"
22 #include "clang/AST/NestedNameSpecifier.h"
23 #include "clang/AST/PrettyPrinter.h"
24 #include "clang/AST/RecursiveASTVisitor.h"
25 #include "clang/AST/StmtVisitor.h"
26 #include "clang/AST/TemplateBase.h"
27 #include "clang/AST/Type.h"
28 #include "clang/AST/TypeLoc.h"
29 #include "clang/AST/TypeLocVisitor.h"
30 #include "clang/AST/TypeVisitor.h"
31 #include "clang/Basic/LangOptions.h"
32 #include "clang/Basic/OperatorKinds.h"
33 #include "clang/Basic/SourceLocation.h"
34 #include "clang/Basic/Specifiers.h"
35 #include "llvm/ADT/STLExtras.h"
36 #include "llvm/ADT/SmallVector.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/Compiler.h"
39 #include "llvm/Support/raw_ostream.h"
47 using ast_type_traits::DynTypedNode;
49 LLVM_ATTRIBUTE_UNUSED std::string
50 nodeToString(
const ast_type_traits::DynTypedNode &N) {
51 std::string S = std::string(N.getNodeKind().asStringRef());
53 llvm::raw_string_ostream
OS(S);
55 N.print(
OS, PrintingPolicy(LangOptions()));
64 CXXRecordDecl *resolveTypeToRecordDecl(
const Type *T) {
66 if (
const auto *ICNT = T->getAs<InjectedClassNameType>()) {
67 T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
69 const auto *TST = T->getAs<TemplateSpecializationType>();
72 const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
73 TST->getTemplateName().getAsTemplateDecl());
76 return TD->getTemplatedDecl();
92 std::vector<const NamedDecl *> getMembersReferencedViaDependentName(
94 llvm::function_ref<DeclarationName(ASTContext &)> NameFactory,
95 bool IsNonstaticMember) {
98 if (
auto *ET = T->getAs<EnumType>()) {
100 ET->getDecl()->lookup(NameFactory(ET->getDecl()->getASTContext()));
101 return {Result.begin(), Result.end()};
103 if (
auto *RD = resolveTypeToRecordDecl(T)) {
104 if (!RD->hasDefinition())
106 RD = RD->getDefinition();
107 DeclarationName
Name = NameFactory(RD->getASTContext());
108 return RD->lookupDependentName(
Name, [=](
const NamedDecl *D) {
109 return IsNonstaticMember ? D->isCXXInstanceMember()
110 : !D->isCXXInstanceMember();
119 const Type *getPointeeType(
const Type *T) {
123 if (T->isPointerType()) {
124 return T->getAs<PointerType>()->getPointeeType().getTypePtrOrNull();
131 auto ArrowOps = getMembersReferencedViaDependentName(
133 [](ASTContext &
Ctx) {
134 return Ctx.DeclarationNames.getCXXOperatorName(OO_Arrow);
137 if (ArrowOps.empty())
146 auto *TST = T->getAs<TemplateSpecializationType>();
149 if (TST->getNumArgs() == 0)
151 const TemplateArgument &FirstArg = TST->getArg(0);
154 return FirstArg.getAsType().getTypePtrOrNull();
159 std::vector<const NamedDecl *> resolveDependentExprToDecls(
const Expr *
E) {
160 assert(
E->isTypeDependent());
161 if (
const auto *ME = dyn_cast<CXXDependentScopeMemberExpr>(
E)) {
162 const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
164 BaseType = getPointeeType(BaseType);
166 return getMembersReferencedViaDependentName(
167 BaseType, [ME](ASTContext &) {
return ME->getMember(); },
170 if (
const auto *RE = dyn_cast<DependentScopeDeclRefExpr>(
E)) {
171 return getMembersReferencedViaDependentName(
172 RE->getQualifier()->getAsType(),
173 [RE](ASTContext &) {
return RE->getDeclName(); },
179 const NamedDecl *getTemplatePattern(
const NamedDecl *D) {
180 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
181 if (
const auto *Result = CRD->getTemplateInstantiationPattern())
186 if (CRD->getTemplateSpecializationKind() == TSK_Undeclared)
187 if (
const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(CRD))
188 return Spec->getSpecializedTemplate()->getTemplatedDecl();
189 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
190 return FD->getTemplateInstantiationPattern();
191 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
193 VarDecl *T = VD->getTemplateInstantiationPattern();
194 return (T == D) ? nullptr : T;
195 }
else if (
const auto *ED = dyn_cast<EnumDecl>(D)) {
196 return ED->getInstantiatedFromMemberEnum();
197 }
else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
198 if (
const auto *
Parent = llvm::dyn_cast<NamedDecl>(D->getDeclContext()))
199 if (
const DeclContext *ParentPat =
200 dyn_cast_or_null<DeclContext>(getTemplatePattern(
Parent)))
201 for (
const NamedDecl *BaseND : ParentPat->lookup(D->getDeclName()))
202 if (!BaseND->isImplicit() && BaseND->getKind() == D->getKind())
204 }
else if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
205 if (
const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
206 if (
const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
207 for (
const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
245 struct TargetFinder {
246 using RelSet = DeclRelationSet;
250 llvm::SmallDenseMap<
const NamedDecl *,
251 std::pair<RelSet,
size_t>>
255 template <
typename T>
void debug(T &Node, RelSet
Flags) {
257 nodeToString(ast_type_traits::DynTypedNode::create(Node)));
260 void report(
const NamedDecl *D, RelSet
Flags) {
262 nodeToString(ast_type_traits::DynTypedNode::create(*D)));
263 auto It = Decls.try_emplace(D, std::make_pair(
Flags, Decls.size()));
266 It.first->second.first |=
Flags;
270 llvm::SmallVector<std::pair<const NamedDecl *, RelSet>, 1> takeDecls()
const {
271 using ValTy = std::pair<const NamedDecl *, RelSet>;
272 llvm::SmallVector<ValTy, 1> Result;
273 Result.resize(Decls.size());
274 for (
const auto &Elem : Decls)
275 Result[Elem.second.second] = {Elem.first, Elem.second.first};
279 void add(
const Decl *Dcl, RelSet
Flags) {
280 const NamedDecl *D = llvm::dyn_cast_or_null<NamedDecl>(Dcl);
284 if (
const UsingDirectiveDecl *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
285 D = UDD->getNominatedNamespaceAsWritten();
287 if (
const TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) {
290 }
else if (
const UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
291 for (
const UsingShadowDecl *S : UD->shadows())
294 }
else if (
const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) {
297 }
else if (
const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
303 D = USD->getTargetDecl();
307 if (
const Decl *Pat = getTemplatePattern(D)) {
317 void add(
const Stmt *S, RelSet
Flags) {
321 struct Visitor :
public ConstStmtVisitor<Visitor> {
326 void VisitCallExpr(
const CallExpr *
CE) {
329 void VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *
E) {
332 void VisitDeclRefExpr(
const DeclRefExpr *DRE) {
333 const Decl *D = DRE->getDecl();
336 if (
auto *USD = llvm::dyn_cast<UsingShadowDecl>(DRE->getFoundDecl()))
340 void VisitMemberExpr(
const MemberExpr *ME) {
341 const Decl *D = ME->getMemberDecl();
343 llvm::dyn_cast<UsingShadowDecl>(ME->getFoundDecl().getDecl()))
347 void VisitOverloadExpr(
const OverloadExpr *OE) {
348 for (
auto *D : OE->decls())
351 void VisitSizeOfPackExpr(
const SizeOfPackExpr *SE) {
354 void VisitCXXConstructExpr(
const CXXConstructExpr *CCE) {
357 void VisitDesignatedInitExpr(
const DesignatedInitExpr *DIE) {
358 for (
const DesignatedInitExpr::Designator &D :
359 llvm::reverse(DIE->designators()))
360 if (D.isFieldDesignator()) {
366 void VisitGotoStmt(
const GotoStmt *Goto) {
367 if (
auto *LabelDecl = Goto->getLabel())
370 void VisitLabelStmt(
const LabelStmt *Label) {
371 if (
auto *LabelDecl = Label->getDecl())
375 VisitCXXDependentScopeMemberExpr(
const CXXDependentScopeMemberExpr *
E) {
376 for (
const NamedDecl *D : resolveDependentExprToDecls(
E)) {
380 void VisitDependentScopeDeclRefExpr(
const DependentScopeDeclRefExpr *
E) {
381 for (
const NamedDecl *D : resolveDependentExprToDecls(
E)) {
385 void VisitObjCIvarRefExpr(
const ObjCIvarRefExpr *OIRE) {
388 void VisitObjCMessageExpr(
const ObjCMessageExpr *OME) {
391 void VisitObjCPropertyRefExpr(
const ObjCPropertyRefExpr *OPRE) {
392 if (OPRE->isExplicitProperty())
393 Outer.add(OPRE->getExplicitProperty(),
Flags);
395 if (OPRE->isMessagingGetter())
396 Outer.add(OPRE->getImplicitPropertyGetter(),
Flags);
397 if (OPRE->isMessagingSetter())
398 Outer.add(OPRE->getImplicitPropertySetter(),
Flags);
401 void VisitObjCProtocolExpr(
const ObjCProtocolExpr *OPE) {
404 void VisitOpaqueValueExpr(
const OpaqueValueExpr *OVE) {
407 void VisitPseudoObjectExpr(
const PseudoObjectExpr *POE) {
411 Visitor(*
this,
Flags).Visit(S);
414 void add(QualType T, RelSet
Flags) {
418 struct Visitor :
public TypeVisitor<Visitor> {
423 void VisitTagType(
const TagType *TT) {
427 void VisitElaboratedType(
const ElaboratedType *ET) {
431 void VisitInjectedClassNameType(
const InjectedClassNameType *ICNT) {
435 void VisitDecltypeType(
const DecltypeType *DTT) {
443 void VisitDeducedTemplateSpecializationType(
444 const DeducedTemplateSpecializationType *DTST) {
451 if (
auto *TD = DTST->getTemplateName().getAsTemplateDecl())
454 void VisitTypedefType(
const TypedefType *TT) {
458 VisitTemplateSpecializationType(
const TemplateSpecializationType *TST) {
465 if (TST->isTypeAlias()) {
470 TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl(),
475 else if (
const auto *
Parm =
476 llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
477 TST->getTemplateName().getAsTemplateDecl()))
480 else if (
const CXXRecordDecl *RD = TST->getAsCXXRecordDecl())
484 if (
auto *TD = TST->getTemplateName().getAsTemplateDecl())
488 void VisitTemplateTypeParmType(
const TemplateTypeParmType *TTPT) {
491 void VisitObjCInterfaceType(
const ObjCInterfaceType *OIT) {
494 void VisitObjCObjectType(
const ObjCObjectType *OOT) {
497 if (OOT->isObjCQualifiedId() && OOT->getNumProtocols() == 1)
501 Visitor(*
this,
Flags).Visit(T.getTypePtr());
504 void add(
const NestedNameSpecifier *NNS, RelSet
Flags) {
508 switch (NNS->getKind()) {
512 add(NNS->getAsNamespace(),
Flags);
514 case NestedNameSpecifier::NamespaceAlias:
515 add(NNS->getAsNamespaceAlias(),
Flags);
517 case NestedNameSpecifier::TypeSpec:
518 case NestedNameSpecifier::TypeSpecWithTemplate:
519 add(QualType(NNS->getAsType(), 0),
Flags);
521 case NestedNameSpecifier::Global:
524 case NestedNameSpecifier::Super:
525 add(NNS->getAsRecordDecl(),
Flags);
528 llvm_unreachable(
"unhandled NestedNameSpecifier::SpecifierKind");
531 void add(
const CXXCtorInitializer *CCI, RelSet
Flags) {
536 if (CCI->isAnyMemberInitializer())
537 add(CCI->getAnyMember(),
Flags);
544 llvm::SmallVector<std::pair<const NamedDecl *, DeclRelationSet>, 1>
546 dlog(
"allTargetDecls({0})", nodeToString(N));
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);
564 return Finder.takeDecls();
567 llvm::SmallVector<const NamedDecl *, 1>
569 llvm::SmallVector<const NamedDecl *, 1> Result;
571 if (!(
Entry.second & ~Mask))
572 Result.push_back(
Entry.first);
577 llvm::SmallVector<const NamedDecl *, 1>
581 "explicitReferenceTargets handles templates on its own");
588 llvm::SmallVector<const NamedDecl *, 1> TemplatePatterns;
589 llvm::SmallVector<const NamedDecl *, 1> Targets;
590 bool SeenTemplateInstantiations =
false;
591 for (
auto &D : Decls) {
592 if (D.second & ~Mask)
595 TemplatePatterns.push_back(D.first);
599 SeenTemplateInstantiations =
true;
600 Targets.push_back(D.first);
602 if (!SeenTemplateInstantiations)
603 Targets.insert(Targets.end(), TemplatePatterns.begin(),
604 TemplatePatterns.end());
609 llvm::SmallVector<ReferenceLoc, 2> refInDecl(
const Decl *D) {
610 struct Visitor : ConstDeclVisitor<Visitor> {
611 llvm::SmallVector<ReferenceLoc, 2>
Refs;
613 void VisitUsingDirectiveDecl(
const UsingDirectiveDecl *D) {
616 Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
617 D->getIdentLocation(),
619 {D->getNominatedNamespaceAsWritten()}});
622 void VisitUsingDecl(
const UsingDecl *D) {
625 ReferenceLoc{D->getQualifierLoc(), D->getLocation(),
false,
630 void VisitNamespaceAliasDecl(
const NamespaceAliasDecl *D) {
635 Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
636 D->getTargetNameLoc(),
638 {D->getAliasedNamespace()}});
641 void VisitNamedDecl(
const NamedDecl *ND) {
644 if (llvm::isa<ClassTemplateDecl>(ND) ||
645 llvm::isa<FunctionTemplateDecl>(ND) ||
646 llvm::isa<VarTemplateDecl>(ND) ||
647 llvm::isa<TypeAliasTemplateDecl>(ND))
650 if (llvm::isa<CXXDestructorDecl>(ND))
654 if (ND->getDeclName().isIdentifier() &&
655 !ND->getDeclName().getAsIdentifierInfo())
669 llvm::SmallVector<ReferenceLoc, 2> refInStmt(
const Stmt *S) {
670 struct Visitor : ConstStmtVisitor<Visitor> {
672 llvm::SmallVector<ReferenceLoc, 2>
Refs;
674 void VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *
E) {
675 Refs.push_back(ReferenceLoc{
E->getNestedNameSpecifierLoc(),
676 E->getConceptNameLoc(),
678 {
E->getNamedConcept()}});
681 void VisitDeclRefExpr(
const DeclRefExpr *
E) {
682 Refs.push_back(ReferenceLoc{
E->getQualifierLoc(),
683 E->getNameInfo().getLoc(),
685 {
E->getFoundDecl()}});
688 void VisitDependentScopeDeclRefExpr(
const DependentScopeDeclRefExpr *
E) {
689 Refs.push_back(ReferenceLoc{
690 E->getQualifierLoc(),
E->getNameInfo().getLoc(),
false,
694 void VisitMemberExpr(
const MemberExpr *
E) {
697 if (llvm::dyn_cast<CXXDestructorDecl>(
E->getFoundDecl().getDecl()))
699 Refs.push_back(ReferenceLoc{
E->getQualifierLoc(),
700 E->getMemberNameInfo().getLoc(),
702 {
E->getFoundDecl()}});
706 VisitCXXDependentScopeMemberExpr(
const CXXDependentScopeMemberExpr *
E) {
708 ReferenceLoc{
E->getQualifierLoc(),
E->getMemberNameInfo().getLoc(),
713 void VisitOverloadExpr(
const OverloadExpr *
E) {
714 Refs.push_back(ReferenceLoc{
E->getQualifierLoc(),
715 E->getNameInfo().getLoc(),
717 llvm::SmallVector<const NamedDecl *, 1>(
718 E->decls().begin(),
E->decls().end())});
721 void VisitSizeOfPackExpr(
const SizeOfPackExpr *
E) {
722 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
728 void VisitObjCPropertyRefExpr(
const ObjCPropertyRefExpr *
E) {
729 Refs.push_back(ReferenceLoc{
730 NestedNameSpecifierLoc(),
E->getLocation(),
736 void VisitDesignatedInitExpr(
const DesignatedInitExpr *DIE) {
737 for (
const DesignatedInitExpr::Designator &D : DIE->designators()) {
738 if (!D.isFieldDesignator())
741 llvm::SmallVector<const NamedDecl *, 1> Targets;
743 Targets.push_back(D.getField());
744 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), D.getFieldLoc(),
745 false, std::move(Targets)});
749 void VisitGotoStmt(
const GotoStmt *GS) {
750 llvm::SmallVector<const NamedDecl *, 1> Targets;
751 if (
const auto *L = GS->getLabel())
752 Targets.push_back(L);
753 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), GS->getLabelLoc(),
754 false, std::move(Targets)});
757 void VisitLabelStmt(
const LabelStmt *LS) {
758 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
770 llvm::SmallVector<ReferenceLoc, 2> refInTypeLoc(TypeLoc L) {
771 struct Visitor : TypeLocVisitor<Visitor> {
772 llvm::Optional<ReferenceLoc> Ref;
774 void VisitElaboratedTypeLoc(ElaboratedTypeLoc L) {
776 Visit(L.getNamedTypeLoc().getUnqualifiedLoc());
780 assert(!Ref->Qualifier.hasQualifier() &&
"qualifier already set");
781 Ref->Qualifier = L.getQualifierLoc();
784 void VisitTagTypeLoc(TagTypeLoc L) {
785 Ref = ReferenceLoc{NestedNameSpecifierLoc(),
791 void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {
792 Ref = ReferenceLoc{NestedNameSpecifierLoc(),
798 void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
808 NestedNameSpecifierLoc(), L.getTemplateNameLoc(),
false,
812 void VisitDeducedTemplateSpecializationTypeLoc(
813 DeducedTemplateSpecializationTypeLoc L) {
815 NestedNameSpecifierLoc(), L.getNameLoc(),
false,
820 void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
821 Ref = ReferenceLoc{NestedNameSpecifierLoc(),
827 void VisitDependentTemplateSpecializationTypeLoc(
828 DependentTemplateSpecializationTypeLoc L) {
830 L.getQualifierLoc(), L.getTemplateNameLoc(),
false,
834 void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
836 L.getQualifierLoc(), L.getNameLoc(),
false,
840 void VisitTypedefTypeLoc(TypedefTypeLoc L) {
841 Ref = ReferenceLoc{NestedNameSpecifierLoc(),
844 {L.getTypedefNameDecl()}};
849 V.Visit(L.getUnqualifiedLoc());
855 class ExplicitReferenceCollector
856 :
public RecursiveASTVisitor<ExplicitReferenceCollector> {
858 ExplicitReferenceCollector(llvm::function_ref<
void(ReferenceLoc)>
Out)
863 bool VisitTypeLoc(TypeLoc TTL) {
864 if (TypeLocsToSkip.count(TTL.getBeginLoc().getRawEncoding()))
866 visitNode(DynTypedNode::create(TTL));
870 bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) {
873 TypeLoc
Inner = L.getNamedTypeLoc().getUnqualifiedLoc();
874 TypeLocsToSkip.insert(
Inner.getBeginLoc().getRawEncoding());
875 return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L);
878 bool VisitStmt(Stmt *S) {
879 visitNode(DynTypedNode::create(*S));
883 bool TraverseOpaqueValueExpr(OpaqueValueExpr *OVE) {
884 visitNode(DynTypedNode::create(*OVE));
887 return RecursiveASTVisitor::TraverseStmt(OVE->getSourceExpr());
890 bool TraversePseudoObjectExpr(PseudoObjectExpr *POE) {
891 visitNode(DynTypedNode::create(*POE));
894 return RecursiveASTVisitor::TraverseStmt(POE->getSyntacticForm());
900 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) {
901 llvm::SmallVector<const NamedDecl *, 1> Targets;
902 switch (A.getArgument().getKind()) {
903 case TemplateArgument::Template:
904 case TemplateArgument::TemplateExpansion:
905 if (
const auto *D = A.getArgument()
906 .getAsTemplateOrTemplatePattern()
907 .getAsTemplateDecl())
908 Targets.push_back(D);
909 reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
910 A.getTemplateNameLoc(),
912 DynTypedNode::create(A.getArgument()));
916 case TemplateArgument::Integral:
918 case TemplateArgument::NullPtr:
920 case TemplateArgument::Pack:
922 case TemplateArgument::Expression:
925 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A);
928 bool VisitDecl(
Decl *D) {
929 visitNode(DynTypedNode::create(*D));
934 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc L) {
935 if (!L.getNestedNameSpecifier())
937 visitNode(DynTypedNode::create(L));
939 if (
auto TL = L.getTypeLoc())
940 TypeLocsToSkip.insert(TL.getBeginLoc().getRawEncoding());
941 return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(L);
944 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
945 visitNode(DynTypedNode::create(*Init));
946 return RecursiveASTVisitor::TraverseConstructorInitializer(Init);
964 llvm::SmallVector<ReferenceLoc, 2> explicitReference(DynTypedNode N) {
965 if (
auto *D = N.get<
Decl>())
967 if (
auto *S = N.get<Stmt>())
969 if (
auto *NNSL = N.get<NestedNameSpecifierLoc>()) {
971 return {ReferenceLoc{
972 NNSL->getPrefix(), NNSL->getLocalBeginLoc(),
false,
974 DynTypedNode::create(*NNSL->getNestedNameSpecifier()),
977 if (
const TypeLoc *TL = N.get<TypeLoc>())
978 return refInTypeLoc(*TL);
979 if (
const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) {
982 if (CCI->isAnyMemberInitializer()) {
983 return {ReferenceLoc{NestedNameSpecifierLoc(),
984 CCI->getMemberLocation(),
986 {CCI->getAnyMember()}}};
993 void visitNode(DynTypedNode N) {
994 for (
const auto &R : explicitReference(N))
995 reportReference(R, N);
998 void reportReference(
const ReferenceLoc &Ref, DynTypedNode N) {
1003 if (Ref.NameLoc.isInvalid()) {
1004 dlog(
"invalid location at node {0}", nodeToString(N));
1010 llvm::function_ref<void(ReferenceLoc)>
Out;
1013 llvm::DenseSet<
unsigned> TypeLocsToSkip;
1020 ExplicitReferenceCollector(
Out).TraverseStmt(const_cast<Stmt *>(S));
1025 ExplicitReferenceCollector(
Out).TraverseDecl(const_cast<Decl *>(D));
1029 ExplicitReferenceCollector(
Out).TraverseAST(const_cast<ASTContext &>(AST));
1034 #define REL_CASE(X) \
1035 case DeclRelation::X: \
1043 llvm_unreachable(
"Unhandled DeclRelation enum");
1046 const char *Sep =
"";
1047 for (
unsigned I = 0; I < RS.S.size(); ++I) {
1049 OS << Sep << static_cast<DeclRelation>(I);
1058 OS <<
"targets = {";
1060 for (
const NamedDecl *T : R.
Targets) {
1069 OS <<
", qualifier = '";
1071 PrintingPolicy(LangOptions()));