[cfe-commits] r112780 - in /cfe/trunk: include/clang-c/Index.h include/clang/AST/DeclTemplate.h test/Index/index-templates.cpp tools/c-index-test/c-index-test.c tools/libclang/CIndexCXX.cpp tools/libclang/libclang.darwin.exports tools/libclang/libclang.exports

Douglas Gregor dgregor at apple.com
Wed Sep 1 17:07:54 PDT 2010


Author: dgregor
Date: Wed Sep  1 19:07:54 2010
New Revision: 112780

URL: http://llvm.org/viewvc/llvm-project?rev=112780&view=rev
Log:
Introduce a new libclang function,
clang_getSpecializedCursorTemplate(), which determines the template
(or member thereof) that the given cursor specializes or from which it
was instantiated. This routine can be used to establish a link between
templates and their instantiations/specializations.


Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/test/Index/index-templates.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/CIndexCXX.cpp
    cfe/trunk/tools/libclang/libclang.darwin.exports
    cfe/trunk/tools/libclang/libclang.exports

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=112780&r1=112779&r2=112780&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Wed Sep  1 19:07:54 2010
@@ -1751,6 +1751,36 @@
 CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C);
   
 /**
+ * \brief Given a cursor that may represent a specialization or instantiation
+ * of a template, retrieve the cursor that represents the template that it
+ * specializes or from which it was instantiated.
+ *
+ * This routine determines the template involved both for explicit 
+ * specializations of templates and for implicit instantiations of the template,
+ * both of which are referred to as "specializations". For a class template
+ * specialization (e.g., \c std::vector<bool>), this routine will return 
+ * either the primary template (\c std::vector) or, if the specialization was
+ * instantiated from a class template partial specialization, the class template
+ * partial specialization. For a class template partial specialization and a
+ * function template specialization (including instantiations), this
+ * this routine will return the specialized template.
+ *
+ * For members of a class template (e.g., member functions, member classes, or
+ * static data members), returns the specialized or instantiated member. 
+ * Although not strictly "templates" in the C++ language, members of class
+ * templates have the same notions of specializations and instantiations that
+ * templates do, so this routine treats them similarly.
+ *
+ * \param C A cursor that may be a specialization of a template or a member
+ * of a template.
+ *
+ * \returns If the given cursor is a specialization or instantiation of a 
+ * template or a member thereof, the template or member that it specializes or
+ * from which it was instantiated. Otherwise, returns a NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C);
+  
+/**
  * @}
  */
 

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=112780&r1=112779&r2=112780&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Wed Sep  1 19:07:54 2010
@@ -1300,7 +1300,8 @@
     if (getSpecializationKind() != TSK_ImplicitInstantiation &&
         getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
         getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
-      return (ClassTemplateDecl*)0;
+      return llvm::PointerUnion<ClassTemplateDecl *,
+                                ClassTemplatePartialSpecializationDecl *>();
 
     if (SpecializedPartialSpecialization *PartialSpec
           = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())

Modified: cfe/trunk/test/Index/index-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/index-templates.cpp?rev=112780&r1=112779&r2=112780&view=diff
==============================================================================
--- cfe/trunk/test/Index/index-templates.cpp (original)
+++ cfe/trunk/test/Index/index-templates.cpp Wed Sep  1 19:07:54 2010
@@ -44,6 +44,8 @@
 template<typename T, Unsigned Value>
 struct value_c;
 
+template class vector<int*>;
+
 // RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-LOAD %s
 // CHECK-LOAD: index-templates.cpp:4:6: FunctionTemplate=f:4:6 Extent=[3:1 - 4:22]
 // CHECK-LOAD: index-templates.cpp:3:19: TemplateTypeParameter=T:3:19 (Definition) Extent=[3:19 - 3:20]
@@ -61,14 +63,14 @@
 // CHECK-LOAD: index-templates.cpp:8:31: TemplateTypeParameter=Alloc:8:31 (Definition) Extent=[8:31 - 8:36]
 // CHECK-LOAD: index-templates.cpp:8:39: TemplateRef=allocator:6:28 Extent=[8:39 - 8:48]
 // CHECK-LOAD: index-templates.cpp:10:8: CXXMethod=clear:10:8 Extent=[10:8 - 10:15]
-// CHECK-LOAD: index-templates.cpp:14:7: ClassTemplatePartialSpecialization=vector:14:7 (Definition) Extent=[13:1 - 14:21]
+// CHECK-LOAD: index-templates.cpp:14:7: ClassTemplatePartialSpecialization=vector:14:7 (Definition) [Specialization of vector:9:7] Extent=[13:1 - 14:21]
 // CHECK-LOAD: index-templates.cpp:13:19: TemplateTypeParameter=T:13:19 (Definition) Extent=[13:19 - 13:20]
 // CHECK-LOAD: index-templates.cpp:16:8: StructDecl=Z1:16:8 (Definition) Extent=[16:1 - 16:14]
-// CHECK-LOAD: index-templates.cpp:18:16: ClassDecl=vector:18:16 (Definition) Extent=[18:1 - 18:22]
+// CHECK-LOAD: index-templates.cpp:18:16: ClassDecl=vector:18:16 (Definition) [Specialization of vector:9:7] Extent=[18:1 - 18:22]
 // CHECK-LOAD: index-templates.cpp:18:23: TypeRef=struct Z1:16:8 Extent=[18:23 - 18:25]
 // CHECK-LOAD-NOT: CXXMethod=clear
 // CHECK-LOAD: index-templates.cpp:20:8: StructDecl=Z2:20:8 (Definition) Extent=[20:1 - 20:14]
-// CHECK-LOAD: index-templates.cpp:23:7: ClassDecl=vector:23:7 (Definition) Extent=[22:1 - 25:2]
+// CHECK-LOAD: index-templates.cpp:23:7: ClassDecl=vector:23:7 (Definition) [Specialization of vector:9:7] Extent=[22:1 - 25:2]
 // CHECK-LOAD: index-templates.cpp:23:14: TypeRef=struct Z2:20:8 Extent=[23:14 - 23:16]
 // CHECK-LOAD: index-templates.cpp:24:8: CXXMethod=clear:24:8 Extent=[24:8 - 24:15]
 // CHECK-LOAD: index-templates.cpp:28:8: ClassTemplate=Y:28:8 (Definition) Extent=[27:1 - 31:2]
@@ -94,6 +96,7 @@
 // CHECK-LOAD: index-templates.cpp:44:19: TemplateTypeParameter=T:44:19 (Definition) Extent=[44:19 - 44:20]
 // CHECK-LOAD: index-templates.cpp:44:31: NonTypeTemplateParameter=Value:44:31 (Definition) Extent=[44:22 - 44:36]
 // CHECK-LOAD: index-templates.cpp:44:22: TypeRef=Unsigned:42:18 Extent=[44:22 - 44:30]
+// CHECK-LOAD: index-templates.cpp:47:16: ClassDecl=vector:47:16 (Definition) [Specialization of vector:14:7] Extent=[47:1 - 47:22]
 
 // RUN: c-index-test -test-load-source-usrs all %s | FileCheck -check-prefix=CHECK-USRS %s
 // CHECK-USRS: index-templates.cpp c:@FT@>3#T#Nt0.0#t>2#T#Nt1.0f#>t0.22t0.0# Extent=[3:1 - 4:22]

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=112780&r1=112779&r2=112780&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Wed Sep  1 19:07:54 2010
@@ -166,7 +166,8 @@
     CXString string, ks;
     CXCursor Referenced;
     unsigned line, column;
-
+    CXCursor SpecializationOf;
+    
     ks = clang_getCursorKindSpelling(Cursor.kind);
     string = clang_getCursorSpelling(Cursor);
     printf("%s=%s", clang_getCString(ks),
@@ -224,6 +225,16 @@
       printf(" [access=%s isVirtual=%s]", accessStr,
              isVirtual ? "true" : "false");
     }
+    
+    SpecializationOf = clang_getSpecializedCursorTemplate(Cursor);
+    if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) {
+      CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf);
+      CXString Name = clang_getCursorSpelling(SpecializationOf);
+      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+      printf(" [Specialization of %s:%d:%d]", 
+             clang_getCString(Name), line, column);
+      clang_disposeString(Name);
+    }
   }
 }
 

Modified: cfe/trunk/tools/libclang/CIndexCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCXX.cpp?rev=112780&r1=112779&r2=112780&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCXX.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCXX.cpp Wed Sep  1 19:07:54 2010
@@ -19,6 +19,7 @@
 
 using namespace clang;
 using namespace clang::cxstring;
+using namespace clang::cxcursor;
 
 extern "C" {
 
@@ -26,7 +27,7 @@
   if (C.kind != CXCursor_CXXBaseSpecifier)
     return 0;
   
-  CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+  CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
   return B->isVirtual();
 }
 
@@ -34,7 +35,7 @@
   if (C.kind != CXCursor_CXXBaseSpecifier)
     return CX_CXXInvalidAccessSpecifier;
   
-  CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+  CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
   switch (B->getAccessSpecifier()) {
     case AS_public: return CX_CXXPublic;
     case AS_protected: return CX_CXXProtected;
@@ -78,4 +79,46 @@
   return CXCursor_NoDeclFound;
 }
 
+CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return clang_getNullCursor();
+    
+  Decl *D = getCursorDecl(C);
+  if (!D)
+    return clang_getNullCursor();
+  
+  Decl *Template = 0;
+  if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
+    if (ClassTemplatePartialSpecializationDecl *PartialSpec
+          = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
+      Template = PartialSpec->getSpecializedTemplate();
+    else if (ClassTemplateSpecializationDecl *ClassSpec 
+               = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
+      llvm::PointerUnion<ClassTemplateDecl *,
+                         ClassTemplatePartialSpecializationDecl *> Result
+        = ClassSpec->getSpecializedTemplateOrPartial();
+      if (Result.is<ClassTemplateDecl *>())
+        Template = Result.get<ClassTemplateDecl *>();
+      else
+        Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
+      
+    } else 
+      Template = CXXRecord->getInstantiatedFromMemberClass();
+  } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+    Template = Function->getPrimaryTemplate();
+    if (!Template)
+      Template = Function->getInstantiatedFromMemberFunction();
+  } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    if (Var->isStaticDataMember())
+      Template = Var->getInstantiatedFromStaticDataMember();
+  } else if (RedeclarableTemplateDecl *Tmpl
+                                        = dyn_cast<RedeclarableTemplateDecl>(D))
+    Template = Tmpl->getInstantiatedFromMemberTemplate();
+  
+  if (!Template)
+    return clang_getNullCursor();
+  
+  return MakeCXCursor(Template, getCursorASTUnit(C));
+}
+  
 } // end extern "C"

Modified: cfe/trunk/tools/libclang/libclang.darwin.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.darwin.exports?rev=112780&r1=112779&r2=112780&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.darwin.exports (original)
+++ cfe/trunk/tools/libclang/libclang.darwin.exports Wed Sep  1 19:07:54 2010
@@ -78,6 +78,7 @@
 _clang_getRangeEnd
 _clang_getRangeStart
 _clang_getResultType
+_clang_getSpecializedCursorTemplate
 _clang_getTemplateCursorKind
 _clang_getTokenExtent
 _clang_getTokenKind

Modified: cfe/trunk/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=112780&r1=112779&r2=112780&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Wed Sep  1 19:07:54 2010
@@ -78,6 +78,7 @@
 clang_getRangeEnd
 clang_getRangeStart
 clang_getResultType
+clang_getSpecializedCursorTemplate
 clang_getTemplateCursorKind
 clang_getTokenExtent
 clang_getTokenKind





More information about the cfe-commits mailing list