skalinichev added a project: clang-c.
skalinichev updated this revision to Diff 80179.

https://reviews.llvm.org/D27384

Files:
  test/Index/print-type.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===================================================================
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -143,6 +143,16 @@
   return static_cast<CXTranslationUnit>(CT.data[1]);
 }
 
+template <typename T>
+static CXType GetTemplateArgumentType(const T &TA, unsigned i, CXTranslationUnit TU) {
+  if (TA.size() <= i)
+    return MakeCXType(QualType(), TU);
+  const TemplateArgument &A = TA[i];
+  if (A.getKind() != TemplateArgument::Type)
+    return MakeCXType(QualType(), TU);
+  return MakeCXType(A.getAsType(), TU);
+}
+
 extern "C" {
 
 CXType clang_getCursorType(CXCursor C) {
@@ -926,9 +936,16 @@
     return -1;
   const TemplateSpecializationType *Specialization =
     T->getAs<TemplateSpecializationType>();
-  if (!Specialization)
+  if (Specialization)
+    return Specialization->template_arguments().size();
+  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
+  if (!RecordDecl)
     return -1;
-  return Specialization->template_arguments().size();
+  const ClassTemplateSpecializationDecl *TemplateDecl =
+    dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
+  if (!TemplateDecl)
+    return -1;
+  return TemplateDecl->getTemplateArgs().size();
 }
 
 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
@@ -938,15 +955,19 @@
 
   const TemplateSpecializationType *Specialization =
     T->getAs<TemplateSpecializationType>();
-  if (!Specialization)
-    return MakeCXType(QualType(), GetTU(CT));
-  auto TA = Specialization->template_arguments();
-  if (TA.size() <= i)
+  if (Specialization) {
+    auto TA = Specialization->template_arguments();
+    return GetTemplateArgumentType(TA, i, GetTU(CT));
+  }
+  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
+  if (!RecordDecl)
     return MakeCXType(QualType(), GetTU(CT));
-  const TemplateArgument &A = TA[i];
-  if (A.getKind() != TemplateArgument::Type)
+  const ClassTemplateSpecializationDecl *TemplateDecl =
+    dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
+  if (!TemplateDecl)
     return MakeCXType(QualType(), GetTU(CT));
-  return MakeCXType(A.getAsType(), GetTU(CT));
+  const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs();
+  return GetTemplateArgumentType(TA, i, GetTU(CT));
 }
 
 unsigned clang_Type_visitFields(CXType PT,
Index: test/Index/print-type.cpp
===================================================================
--- test/Index/print-type.cpp
+++ test/Index/print-type.cpp
@@ -61,6 +61,15 @@
 
 struct TypeAliasUser { TypeAlias<int> foo; };
 
+template<typename T>
+struct Specialization {};
+
+template<>
+struct Specialization<int>;
+
+Specialization<Specialization<bool>& > templRefParam;
+auto autoTemplRefParam = templRefParam;
+
 // RUN: c-index-test -test-print-type %s -std=c++14 | FileCheck %s
 // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
@@ -157,3 +166,14 @@
 // CHECK: TemplateTypeParameter=T:59:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: FieldDecl=foo:62:39 (Definition) [type=TypeAlias<int>] [typekind=Unexposed] [canonicaltype=outer::Qux<int>] [canonicaltypekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=1]
 // CHECK: TemplateRef=TypeAlias:60:1 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: ClassTemplate=Specialization:65:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:64:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: StructDecl=Specialization:68:8 [Specialization of Specialization:65:8] [type=Specialization<int>] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0]
+// CHECK: VarDecl=templRefParam:70:40 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: TemplateRef=Specialization:65:8 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TemplateRef=Specialization:65:8 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: CallExpr=Specialization:65:8 [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: VarDecl=autoTemplRefParam:71:6 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Auto] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: CallExpr=Specialization:65:8 [type=Specialization<Specialization<bool> &>] [typekind=Auto] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: UnexposedExpr=templRefParam:70:40 [type=const Specialization<Specialization<bool> &>] [typekind=Record] const [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: DeclRefExpr=templRefParam:70:40 [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to