16
16
#include " clang/AST/DeclCXX.h"
17
17
#include " clang/AST/DeclObjC.h"
18
18
#include " clang/AST/DeclTemplate.h"
19
+ #include " clang/AST/DeclVisitor.h"
19
20
#include " clang/AST/DeclarationName.h"
20
21
#include " clang/AST/ExprCXX.h"
21
22
#include " clang/AST/NestedNameSpecifier.h"
22
23
#include " clang/AST/PrettyPrinter.h"
23
24
#include " clang/AST/RecursiveASTVisitor.h"
24
25
#include " clang/AST/Stmt.h"
26
+ #include " clang/AST/StmtVisitor.h"
25
27
#include " clang/AST/TemplateBase.h"
26
28
#include " clang/AST/TypeLoc.h"
27
29
#include " clang/Basic/Builtins.h"
@@ -636,7 +638,7 @@ static NamedDecl *getOnlyInstantiationImpl(TemplateDeclTy *TD) {
636
638
return Only;
637
639
}
638
640
639
- NamedDecl *getOnlyInstantiation (NamedDecl *TemplatedDecl) {
641
+ NamedDecl *getOnlyInstantiation (const NamedDecl *TemplatedDecl) {
640
642
if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate ()) {
641
643
if (auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
642
644
return getOnlyInstantiationImpl (CTD);
@@ -648,6 +650,197 @@ NamedDecl *getOnlyInstantiation(NamedDecl *TemplatedDecl) {
648
650
return nullptr ;
649
651
}
650
652
653
+ NamedDecl *getOnlyInstantiatedDecls (const NamedDecl *DependentDecl) {
654
+ if (auto *Instantiation = getOnlyInstantiation (DependentDecl))
655
+ return Instantiation;
656
+ NamedDecl *OuterTemplate = nullptr ;
657
+ for (auto *DC = DependentDecl->getDeclContext (); isa<CXXRecordDecl>(DC);
658
+ DC = DC->getParent ()) {
659
+ auto *RD = cast<CXXRecordDecl>(DC);
660
+ if (auto *I = getOnlyInstantiation (RD)) {
661
+ OuterTemplate = I;
662
+ break ;
663
+ }
664
+ }
665
+
666
+ if (!OuterTemplate)
667
+ return nullptr ;
668
+
669
+ struct Visitor : DeclVisitor<Visitor, NamedDecl *> {
670
+ const NamedDecl *TemplatedDecl;
671
+ Visitor (const NamedDecl *TemplatedDecl) : TemplatedDecl(TemplatedDecl) {}
672
+
673
+ NamedDecl *VisitCXXRecordDecl (CXXRecordDecl *RD) {
674
+ if (RD->getTemplateInstantiationPattern () == TemplatedDecl)
675
+ return RD;
676
+ for (auto *F : RD->decls ()) {
677
+ if (auto *Injected = llvm::dyn_cast<CXXRecordDecl>(F);
678
+ Injected && Injected->isInjectedClassName ())
679
+ continue ;
680
+ if (NamedDecl *ND = Visit (F))
681
+ return ND;
682
+ }
683
+ return nullptr ;
684
+ }
685
+
686
+ NamedDecl *VisitClassTemplateDecl (ClassTemplateDecl *CTD) {
687
+ unsigned Size = llvm::range_size (CTD->specializations ());
688
+ if (Size != 1 )
689
+ return nullptr ;
690
+ return Visit (*CTD->spec_begin ());
691
+ }
692
+
693
+ NamedDecl *VisitFunctionTemplateDecl (FunctionTemplateDecl *FTD) {
694
+ unsigned Size = llvm::range_size (FTD->specializations ());
695
+ if (Size != 1 )
696
+ return nullptr ;
697
+ return Visit (*FTD->spec_begin ());
698
+ }
699
+
700
+ NamedDecl *VisitFunctionDecl (FunctionDecl *FD) {
701
+ if (FD->getTemplateInstantiationPattern () == TemplatedDecl)
702
+ return FD;
703
+ return nullptr ;
704
+ }
705
+
706
+ NamedDecl *VisitVarDecl (VarDecl *VD) {
707
+ if (VD->getCanonicalDecl ()->getSourceRange () ==
708
+ TemplatedDecl->getCanonicalDecl ()->getSourceRange ())
709
+ return VD;
710
+ return nullptr ;
711
+ }
712
+
713
+ NamedDecl *VisitFieldDecl (FieldDecl *FD) {
714
+ if (FD->getCanonicalDecl ()->getSourceRange () ==
715
+ TemplatedDecl->getCanonicalDecl ()->getSourceRange ())
716
+ return FD;
717
+ return nullptr ;
718
+ }
719
+ };
720
+ return Visitor (DependentDecl).Visit (OuterTemplate);
721
+ }
722
+
723
+ std::optional<DynTypedNode>
724
+ getOnlyInstantiatedNode (const DeclContext *StartingPoint,
725
+ const DynTypedNode &DependentNode) {
726
+ if (auto *CTD = DependentNode.get <ClassTemplateDecl>())
727
+ return getOnlyInstantiatedNode (
728
+ StartingPoint, DynTypedNode::create (*CTD->getTemplatedDecl ()));
729
+ if (auto *FTD = DependentNode.get <FunctionTemplateDecl>())
730
+ return getOnlyInstantiatedNode (
731
+ StartingPoint, DynTypedNode::create (*FTD->getTemplatedDecl ()));
732
+
733
+ if (auto *FD = DependentNode.get <FunctionDecl>()) {
734
+ auto *ID = getOnlyInstantiatedDecls (FD);
735
+ if (!ID)
736
+ return std::nullopt;
737
+ return DynTypedNode::create (*ID);
738
+ }
739
+ if (auto *RD = DependentNode.get <CXXRecordDecl>()) {
740
+ auto *ID = getOnlyInstantiatedDecls (RD);
741
+ if (!ID)
742
+ return std::nullopt;
743
+ return DynTypedNode::create (*ID);
744
+ }
745
+
746
+ NamedDecl *InstantiatedEnclosingDecl = nullptr ;
747
+ for (auto *DC = StartingPoint; DC;
748
+ DC = DC->getParent ()) {
749
+ auto *ND = llvm::dyn_cast<NamedDecl>(DC);
750
+ if (!ND)
751
+ continue ;
752
+ InstantiatedEnclosingDecl = getOnlyInstantiatedDecls (ND);
753
+ if (InstantiatedEnclosingDecl)
754
+ break ;
755
+ }
756
+
757
+ if (!InstantiatedEnclosingDecl)
758
+ return std::nullopt;
759
+
760
+ auto *InstantiatedFunctionDecl =
761
+ llvm::dyn_cast<FunctionDecl>(InstantiatedEnclosingDecl);
762
+ if (!InstantiatedFunctionDecl)
763
+ return std::nullopt;
764
+
765
+ struct FullExprVisitor : RecursiveASTVisitor<FullExprVisitor> {
766
+ const DynTypedNode &DependentNode;
767
+ Stmt *Result;
768
+ FullExprVisitor (const DynTypedNode &DependentNode)
769
+ : DependentNode(DependentNode), Result(nullptr ) {}
770
+
771
+ bool shouldVisitTemplateInstantiations () const { return true ; }
772
+
773
+ bool shouldVisitImplicitCode () const { return true ; }
774
+
775
+ bool VisitStmt (Stmt *S) {
776
+ if (S->getSourceRange () == DependentNode.getSourceRange ()) {
777
+ Result = S;
778
+ return false ;
779
+ }
780
+ return true ;
781
+ }
782
+ };
783
+
784
+ FullExprVisitor Visitor (DependentNode);
785
+ Visitor.TraverseFunctionDecl (InstantiatedFunctionDecl);
786
+ if (Visitor.Result )
787
+ return DynTypedNode::create (*Visitor.Result );
788
+ return std::nullopt;
789
+ }
790
+
791
+ NamedDecl *
792
+ getOnlyInstantiationForMemberFunction (const CXXMethodDecl *TemplatedDecl) {
793
+ if (auto *MemberInstantiation = getOnlyInstantiation (TemplatedDecl))
794
+ return MemberInstantiation;
795
+ NamedDecl *OuterTemplate = nullptr ;
796
+ for (auto *DC = TemplatedDecl->getDeclContext (); isa<CXXRecordDecl>(DC);
797
+ DC = DC->getParent ()) {
798
+ auto *RD = cast<CXXRecordDecl>(DC);
799
+ if (auto *I = getOnlyInstantiation (RD)) {
800
+ OuterTemplate = I;
801
+ break ;
802
+ }
803
+ }
804
+ if (!OuterTemplate)
805
+ return nullptr ;
806
+ struct Visitor : DeclVisitor<Visitor, NamedDecl *> {
807
+ const CXXMethodDecl *TD;
808
+ Visitor (const CXXMethodDecl *TemplatedDecl) : TD(TemplatedDecl) {}
809
+ NamedDecl *VisitCXXRecordDecl (CXXRecordDecl *RD) {
810
+ for (auto *F : RD->decls ()) {
811
+ if (!isa<NamedDecl>(F))
812
+ continue ;
813
+ if (NamedDecl *ND = Visit (F))
814
+ return ND;
815
+ }
816
+ return nullptr ;
817
+ }
818
+
819
+ NamedDecl *VisitClassTemplateDecl (ClassTemplateDecl *CTD) {
820
+ unsigned Size = llvm::range_size (CTD->specializations ());
821
+ if (Size != 1 )
822
+ return nullptr ;
823
+ return Visit (*CTD->spec_begin ());
824
+ }
825
+
826
+ NamedDecl *VisitFunctionTemplateDecl (FunctionTemplateDecl *FTD) {
827
+ unsigned Size = llvm::range_size (FTD->specializations ());
828
+ if (Size != 1 )
829
+ return nullptr ;
830
+ return Visit (*FTD->spec_begin ());
831
+ }
832
+
833
+ NamedDecl *VisitCXXMethodDecl (CXXMethodDecl *MD) {
834
+ auto *Pattern = MD->getTemplateInstantiationPattern ();
835
+ if (Pattern == TD)
836
+ return MD;
837
+ return nullptr ;
838
+ }
839
+
840
+ };
841
+ return Visitor (TemplatedDecl).Visit (OuterTemplate);
842
+ }
843
+
651
844
std::vector<const Attr *> getAttributes (const DynTypedNode &N) {
652
845
std::vector<const Attr *> Result;
653
846
if (const auto *TL = N.get <TypeLoc>()) {
0 commit comments