From: Douglas Gregor Date: Sat, 2 Oct 2010 21:57:58 +0000 (+0000) Subject: Teach clang_getCursorType() about base specifiers and other references X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3f0fee315cbfa37e0c47904836948e9d0cca9eda;p=clang Teach clang_getCursorType() about base specifiers and other references to types. Also, teach clang_getTypeDeclaration() about template specializations, injected-class-names, and elaborated types. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115425 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/index-templates.cpp b/test/Index/index-templates.cpp index f55090739f..b657c17faf 100644 --- a/test/Index/index-templates.cpp +++ b/test/Index/index-templates.cpp @@ -95,6 +95,11 @@ struct map; void f(map >); +template class Pair; + +template +struct SuperPair : Pair, Pair { }; + // 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] @@ -168,6 +173,12 @@ void f(map >); // CHECK-LOAD: index-templates.cpp:85:20: DeclRefExpr=t:82:18 Extent=[85:20 - 85:21] // CHECK-LOAD: index-templates.cpp:85:23: TypeRef=second_type:83:13 Extent=[85:23 - 85:34] // CHECK-LOAD: index-templates.cpp:85:35: DeclRefExpr=u:82:23 Extent=[85:35 - 85:36] +// CHECK-LOAD: index-templates.cpp:101:8: ClassTemplate=SuperPair:101:8 (Definition) Extent=[100:1 - 101:50] +// CHECK-LOAD: index-templates.cpp:100:19: TemplateTypeParameter=T:100:19 (Definition) Extent=[100:19 - 100:20] +// CHECK-LOAD: index-templates.cpp:100:31: TemplateTypeParameter=U:100:31 (Definition) Extent=[100:31 - 100:32] +// CHECK-LOAD: index-templates.cpp:101:20: C++ base class specifier=Pair:98:16 [access=public isVirtual=false] Extent=[101:20 - 101:34] +// CHECK-LOAD: index-templates.cpp:101:36: C++ base class specifier=Pair:76:8 [access=public isVirtual=false] Extent=[101:36 - 101:46] + // 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.22S0_# Extent=[3:1 - 4:22] @@ -193,4 +204,4 @@ void f(map >); // CHECK-USRS: index-templates.cpp c:index-templates.cpp@464 Extent=[27:31 - 27:32] // CHECK-USRS-NOT: type // CHECK-USRS: index-templates.cpp c:@S@Z3 Extent=[33:1 - 33:14] -// CHECK-USES: index-templates.cpp c:@F@f#$@S@map>#$@S@Z4#$@S@Pair>#I#S1_#$@S@compare>#$@S@Pair>#S1_#S2_#$@C@allocator>#S4_# +// CHECK-USRS: index-templates.cpp c:@F@f#$@S@map>#$@S@Z4#$@S@Pair>#I#S1_#$@S@compare>#$@S@Pair>#S1_#S2_#$@C@allocator>#S4_# diff --git a/test/Index/print-typekind.c b/test/Index/print-typekind.c index 18189c3c74..d521f06ed0 100644 --- a/test/Index/print-typekind.c +++ b/test/Index/print-typekind.c @@ -12,11 +12,11 @@ int *f(int *p, char *x, FooType z) { // CHECK: ParmDecl=p:3:13 (Definition) typekind=Pointer [isPOD=1] // CHECK: ParmDecl=x:3:22 (Definition) typekind=Pointer [isPOD=1] // CHECK: ParmDecl=z:3:33 (Definition) typekind=Typedef [canonical=Int] [isPOD=1] -// CHECK: TypeRef=FooType:1:13 typekind=Invalid [isPOD=0] +// CHECK: TypeRef=FooType:1:13 typekind=Typedef [canonical=Int] [isPOD=1] // CHECK: UnexposedStmt= typekind=Invalid [isPOD=0] // CHECK: UnexposedStmt= typekind=Invalid [isPOD=0] // CHECK: VarDecl=w:4:11 (Definition) typekind=Typedef [canonical=Int] [isPOD=1] -// CHECK: TypeRef=FooType:1:13 typekind=Invalid [isPOD=0] +// CHECK: TypeRef=FooType:1:13 typekind=Typedef [canonical=Int] [isPOD=1] // CHECK: DeclRefExpr=z:3:33 typekind=Typedef [canonical=Int] [isPOD=1] // CHECK: UnexposedStmt= typekind=Invalid [isPOD=0] // CHECK: UnexposedExpr= typekind=Pointer [isPOD=1] diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp index aa173cae32..05912b1db3 100644 --- a/tools/libclang/CXType.cpp +++ b/tools/libclang/CXType.cpp @@ -18,6 +18,7 @@ #include "clang/AST/Type.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/Frontend/ASTUnit.h" using namespace clang; @@ -106,6 +107,8 @@ static inline ASTUnit* GetASTU(CXType CT) { extern "C" { CXType clang_getCursorType(CXCursor C) { + using namespace cxcursor; + ASTUnit *AU = cxcursor::getCursorASTUnit(C); if (clang_isExpression(C.kind)) { @@ -128,6 +131,40 @@ CXType clang_getCursorType(CXCursor C) { return MakeCXType(FD->getType(), AU); return MakeCXType(QualType(), AU); } + + if (clang_isReference(C.kind)) { + switch (C.kind) { + case CXCursor_ObjCSuperClassRef: + return MakeCXType( + QualType(getCursorObjCSuperClassRef(C).first->getTypeForDecl(), + 0), + AU); + + case CXCursor_ObjCClassRef: + return MakeCXType( + QualType(getCursorObjCClassRef(C).first->getTypeForDecl(), + 0), + AU); + + case CXCursor_TypeRef: + return MakeCXType(QualType(getCursorTypeRef(C).first->getTypeForDecl(), + 0), + AU); + + case CXCursor_CXXBaseSpecifier: + return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), AU); + + case CXCursor_ObjCProtocolRef: + case CXCursor_TemplateRef: + case CXCursor_NamespaceRef: + case CXCursor_MemberRef: + case CXCursor_OverloadedDeclRef: + default: + break; + } + + return MakeCXType(QualType(), AU); + } return MakeCXType(QualType(), AU); } @@ -185,22 +222,41 @@ CXCursor clang_getTypeDeclaration(CXType CT) { Decl *D = 0; +try_again: switch (TP->getTypeClass()) { - case Type::Typedef: - D = cast(TP)->getDecl(); - break; - case Type::ObjCObject: - D = cast(TP)->getInterface(); - break; - case Type::ObjCInterface: - D = cast(TP)->getDecl(); - break; - case Type::Record: - case Type::Enum: - D = cast(TP)->getDecl(); - break; - default: - break; + case Type::Typedef: + D = cast(TP)->getDecl(); + break; + case Type::ObjCObject: + D = cast(TP)->getInterface(); + break; + case Type::ObjCInterface: + D = cast(TP)->getDecl(); + break; + case Type::Record: + case Type::Enum: + D = cast(TP)->getDecl(); + break; + case Type::TemplateSpecialization: + if (const RecordType *Record = TP->getAs()) + D = Record->getDecl(); + else + D = cast(TP)->getTemplateName() + .getAsTemplateDecl(); + break; + + case Type::InjectedClassName: + D = cast(TP)->getDecl(); + break; + + // FIXME: Template type parameters! + + case Type::Elaborated: + TP = cast(TP)->getNamedType().getTypePtr(); + goto try_again; + + default: + break; } if (!D)