arphaman created this revision. This patch extends the set of relationships that are recorded by the indexer by adding support for the 'SpecializationOf' relationship.
Repository: rL LLVM https://reviews.llvm.org/D32010 Files: include/clang/Index/IndexSymbol.h lib/Index/IndexDecl.cpp lib/Index/IndexSymbol.cpp lib/Index/IndexTypeSourceInfo.cpp lib/Index/IndexingContext.cpp lib/Index/IndexingContext.h test/Index/Core/index-source.cpp
Index: test/Index/Core/index-source.cpp =================================================================== --- test/Index/Core/index-source.cpp +++ test/Index/Core/index-source.cpp @@ -50,6 +50,12 @@ // CHECK-NEXT: RelChild | TemplCls | c:@ST>1#T@TemplCls }; +template<> +class TemplCls<double> { +// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | TemplCls | c:@S@TemplCls>#d | <no-cgname> | Def,RelSpecialization | rel: 1 +// CHECK: RelSpecialization | TemplCls | c:@ST>1#T@TemplCls +}; + TemplCls<int> gtv(0); // CHECK: [[@LINE-1]]:1 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Ref,RelCont | rel: 1 @@ -91,3 +97,17 @@ // CHECK: [[@LINE+2]]:5 | variable/C | gvf | c:@gvf | _gvf | Def | rel: 0 // CHECK: [[@LINE+1]]:11 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Ref,Read,RelCont | rel: 1 int gvf = tmplVar<float>; + +template<typename A, typename B> +class PartialSpecilizationClass { }; +// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Def | rel: 0 + +template<typename B> +class PartialSpecilizationClass<int, B *> { }; +// CHECK: [[@LINE-1]]:7 | class(Gen,TPS)/C++ | PartialSpecilizationClass | c:@SP>1#T@PartialSpecilizationClass>#I#*t0.0 | <no-cgname> | Def,RelSpecialization | rel: 1 +// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass + +template<> +class PartialSpecilizationClass<int, int> { }; +// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#I#I | <no-cgname> | Def,RelSpecialization | rel: 1 +// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass Index: lib/Index/IndexingContext.h =================================================================== --- lib/Index/IndexingContext.h +++ lib/Index/IndexingContext.h @@ -80,7 +80,8 @@ bool indexDecl(const Decl *D); - void indexTagDecl(const TagDecl *D); + void indexTagDecl(const TagDecl *D, + ArrayRef<SymbolRelation> Relations = None); void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent, const DeclContext *DC = nullptr, Index: lib/Index/IndexingContext.cpp =================================================================== --- lib/Index/IndexingContext.cpp +++ lib/Index/IndexingContext.cpp @@ -233,6 +233,7 @@ case SymbolRole::RelationReceivedBy: case SymbolRole::RelationCalledBy: case SymbolRole::RelationContainedBy: + case SymbolRole::RelationSpecializationOf: return true; } llvm_unreachable("Unsupported SymbolRole value!"); Index: lib/Index/IndexTypeSourceInfo.cpp =================================================================== --- lib/Index/IndexTypeSourceInfo.cpp +++ lib/Index/IndexTypeSourceInfo.cpp @@ -208,11 +208,12 @@ } } -void IndexingContext::indexTagDecl(const TagDecl *D) { +void IndexingContext::indexTagDecl(const TagDecl *D, + ArrayRef<SymbolRelation> Relations) { if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D)) return; - if (handleDecl(D)) { + if (handleDecl(D, /*Roles=*/SymbolRoleSet(), Relations)) { if (D->isThisDeclarationADefinition()) { indexNestedNameSpecifierLoc(D->getQualifierLoc(), D); if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) { Index: lib/Index/IndexSymbol.cpp =================================================================== --- lib/Index/IndexSymbol.cpp +++ lib/Index/IndexSymbol.cpp @@ -346,6 +346,7 @@ APPLY_FOR_ROLE(RelationAccessorOf); APPLY_FOR_ROLE(RelationContainedBy); APPLY_FOR_ROLE(RelationIBTypeOf); + APPLY_FOR_ROLE(RelationSpecializationOf); #undef APPLY_FOR_ROLE @@ -386,6 +387,7 @@ case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break; case SymbolRole::RelationContainedBy: OS << "RelCont"; break; case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break; + case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break; } }); } Index: lib/Index/IndexDecl.cpp =================================================================== --- lib/Index/IndexDecl.cpp +++ lib/Index/IndexDecl.cpp @@ -495,8 +495,18 @@ ClassTemplateSpecializationDecl *D) { // FIXME: Notify subsequent callbacks if info comes from implicit // instantiation. - if (D->isThisDeclarationADefinition()) - IndexCtx.indexTagDecl(D); + if (D->isThisDeclarationADefinition()) { + llvm::PointerUnion<ClassTemplateDecl *, + ClassTemplatePartialSpecializationDecl *> + Template = D->getSpecializedTemplateOrPartial(); + const Decl *SpecializationOf = + Template.is<ClassTemplateDecl *>() + ? (Decl *)Template.get<ClassTemplateDecl *>() + : Template.get<ClassTemplatePartialSpecializationDecl *>(); + IndexCtx.indexTagDecl( + D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf), + SpecializationOf)); + } return true; } Index: include/clang/Index/IndexSymbol.h =================================================================== --- include/clang/Index/IndexSymbol.h +++ include/clang/Index/IndexSymbol.h @@ -106,8 +106,9 @@ RelationAccessorOf = 1 << 15, RelationContainedBy = 1 << 16, RelationIBTypeOf = 1 << 17, + RelationSpecializationOf = 1 << 18, }; -static const unsigned SymbolRoleBitNum = 18; +static const unsigned SymbolRoleBitNum = 19; typedef unsigned SymbolRoleSet; /// Represents a relation to another symbol for a symbol occurrence.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits