Index: test/Index/print-type.cpp =================================================================== --- test/Index/print-type.cpp +++ test/Index/print-type.cpp @@ -61,6 +61,15 @@ struct TypeAliasUser { TypeAlias foo; }; +template +struct Specialization {}; + +template<> +struct Specialization; + +Specialization& > 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] [typekind=Unexposed] [canonicaltype=outer::Qux] [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] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0] +// CHECK: VarDecl=templRefParam:70:40 (Definition) [type=Specialization &>] [typekind=Unexposed] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [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 &>] [typekind=Unexposed] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: VarDecl=autoTemplRefParam:71:6 (Definition) [type=Specialization &>] [typekind=Auto] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: CallExpr=Specialization:65:8 [type=Specialization &>] [typekind=Auto] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: UnexposedExpr=templRefParam:70:40 [type=const Specialization &>] [typekind=Record] const [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: DeclRefExpr=templRefParam:70:40 [type=Specialization &>] [typekind=Unexposed] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] Index: tools/libclang/CXType.cpp =================================================================== --- tools/libclang/CXType.cpp +++ tools/libclang/CXType.cpp @@ -143,6 +143,16 @@ return static_cast(CT.data[1]); } +template +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(); - 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(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(); - 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(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,