forked from OSchip/llvm-project
libclang: add clang_getTypeSpelling(CXType CT)
Adds a function clang_getTypeSpelling(CXType CT) that returns a CXString containing the underlying type. Patch by Ben Gertzfield. llvm-svn: 175299
This commit is contained in:
parent
d4c1a2063c
commit
0035372bb7
|
@ -32,7 +32,7 @@
|
|||
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
|
||||
*/
|
||||
#define CINDEX_VERSION_MAJOR 0
|
||||
#define CINDEX_VERSION_MINOR 11
|
||||
#define CINDEX_VERSION_MINOR 12
|
||||
|
||||
#define CINDEX_VERSION_ENCODE(major, minor) ( \
|
||||
((major) * 10000) \
|
||||
|
@ -2694,6 +2694,14 @@ typedef struct {
|
|||
*/
|
||||
CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Pretty-print the underlying type using the rules of the
|
||||
* language of the translation unit from which it came.
|
||||
*
|
||||
* If the type is invalid, an empty string is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_getTypeSpelling(CXType CT);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the underlying type of a typedef declaration.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
typedef int FooType;
|
||||
int *p;
|
||||
int *f(int *p, char *x, FooType z, int arr[5], void (*fn)(int)) {
|
||||
fn(*p);
|
||||
const FooType w = z;
|
||||
return p + z + arr[3];
|
||||
}
|
||||
typedef double OtherType;
|
||||
typedef int ArrayType[5];
|
||||
int __attribute__((vector_size(16))) x;
|
||||
typedef int __attribute__((vector_size(16))) int4_t;
|
||||
|
||||
// RUN: c-index-test -test-print-type %s | FileCheck %s
|
||||
// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int *] [Pointer] [void (*)(int)] [Pointer]] [isPOD=0]
|
||||
// CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: ParmDecl=arr:3:40 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
|
||||
// CHECK: ParmDecl=fn:3:55 (Definition) [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1]
|
||||
// CHECK: ParmDecl=:3:62 (Definition) [type=int] [typekind=Int] [isPOD=1]
|
||||
// CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: CallExpr=fn:3:55 [type=void] [typekind=Void] [isPOD=0]
|
||||
// CHECK: DeclRefExpr=fn:3:55 [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1]
|
||||
// CHECK: UnaryOperator= [type=int] [typekind=Int] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: VarDecl=w:5:17 (Definition) [type=const FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: ArraySubscriptExpr= [type=int] [typekind=Int] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=arr:3:40 [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
|
||||
// CHECK: TypedefDecl=OtherType:8:16 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
|
||||
// CHECK: TypedefDecl=ArrayType:9:13 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
|
||||
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
|
||||
// CHECK: VarDecl=x:10:38 [type=__attribute__((__vector_size__(4 * sizeof(int)))) int] [typekind=Vector] [isPOD=1]
|
||||
// CHECK: TypedefDecl=int4_t:11:46 (Definition) [type=int4_t] [typekind=Typedef] [canonicaltype=__attribute__((__vector_size__(4 * sizeof(int)))) int] [canonicaltypekind=Vector] [isPOD=1]
|
|
@ -0,0 +1,56 @@
|
|||
namespace outer {
|
||||
|
||||
template<typename T>
|
||||
struct Foo {
|
||||
T t;
|
||||
};
|
||||
|
||||
namespace inner {
|
||||
|
||||
struct Bar {
|
||||
Bar(outer::Foo<bool>* foo) { };
|
||||
|
||||
typedef int FooType;
|
||||
int *p;
|
||||
int *f(int *p, char *x, FooType z) {
|
||||
const FooType w = z;
|
||||
return p + z;
|
||||
}
|
||||
typedef double OtherType;
|
||||
typedef int ArrayType[5];
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// RUN: c-index-test -test-print-type %s | FileCheck %s
|
||||
// CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: TemplateTypeParameter=T:3:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
|
||||
// CHECK: FieldDecl=t:5:5 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
|
||||
// CHECK: TypeRef=T:3:19 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
|
||||
// CHECK: Namespace=inner:8:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: StructDecl=Bar:10:8 (Definition) [type=outer::inner::Bar] [typekind=Record] [isPOD=0]
|
||||
// CHECK: CXXConstructor=Bar:11:3 (Definition) [type=void (outer::Foo<bool> *)] [typekind=FunctionProto] [canonicaltype=void (outer::Foo<bool> *)] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0]
|
||||
// CHECK: ParmDecl=foo:11:25 (Definition) [type=outer::Foo<bool> *] [typekind=Pointer] [canonicaltype=outer::Foo<bool> *] [canonicaltypekind=Pointer] [isPOD=1]
|
||||
// CHECK: NamespaceRef=outer:1:11 [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: TypedefDecl=FooType:13:15 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: FieldDecl=p:14:8 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: CXXMethod=f:15:8 (Definition) [type=int *(int *, char *, FooType)] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int)] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef]] [isPOD=0]
|
||||
// CHECK: ParmDecl=p:15:15 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: ParmDecl=x:15:24 (Definition) [type=char *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: ParmDecl=z:15:35 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: TypeRef=FooType:13:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: VarDecl=w:16:19 (Definition) [type=const FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: TypeRef=FooType:13:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=z:15:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
|
||||
// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=p:15:15 [type=int *] [typekind=Pointer] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=z:15:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
|
||||
// CHECK: TypedefDecl=OtherType:19:18 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
|
||||
// CHECK: TypedefDecl=ArrayType:20:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
|
|
@ -0,0 +1,10 @@
|
|||
@interface Foo
|
||||
@property (readonly) id x;
|
||||
-(int) mymethod;
|
||||
-(const id) mymethod2:(id)x blah:(Class)y boo:(SEL)z;
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -test-print-type %s | FileCheck %s
|
||||
// CHECK: ObjCPropertyDecl=x:2:25 [type=id] [typekind=ObjCId] [canonicaltype=id] [canonicaltypekind=ObjCObjectPointer] [isPOD=1]
|
||||
// CHECK: ObjCInstanceMethodDecl=mymethod:3:8 [type=] [typekind=Invalid] [resulttype=int] [resulttypekind=Int] [isPOD=0]
|
||||
// CHECK: ObjCInstanceMethodDecl=mymethod2:blah:boo::4:13 [type=] [typekind=Invalid] [resulttype=const id] [resulttypekind=ObjCId] [args= [id] [ObjCId] [Class] [ObjCClass] [SEL] [ObjCSel]] [isPOD=0]
|
|
@ -1,28 +0,0 @@
|
|||
typedef int FooType;
|
||||
int *p;
|
||||
int *f(int *p, char *x, FooType z) {
|
||||
const FooType w = z;
|
||||
return p + z;
|
||||
}
|
||||
typedef double OtherType;
|
||||
typedef int ArrayType[5];
|
||||
|
||||
// RUN: c-index-test -test-print-typekind %s | FileCheck %s
|
||||
// CHECK: TypedefDecl=FooType:1:13 (Definition) typekind=Typedef [canonical=Int] [isPOD=1]
|
||||
// CHECK: VarDecl=p:2:6 typekind=Pointer [isPOD=1]
|
||||
// CHECK: FunctionDecl=f:3:6 (Definition) typekind=FunctionProto [canonical=FunctionProto] [result=Pointer] [args= Pointer Pointer Typedef] [isPOD=0]
|
||||
// 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=Typedef [canonical=Int] [isPOD=1]
|
||||
// CHECK: CompoundStmt= typekind=Invalid [isPOD=0]
|
||||
// CHECK: DeclStmt= typekind=Invalid [isPOD=0]
|
||||
// CHECK: VarDecl=w:4:17 (Definition) typekind=Typedef const [canonical=Int] [isPOD=1]
|
||||
// CHECK: TypeRef=FooType:1:13 typekind=Typedef [canonical=Int] [isPOD=1]
|
||||
// CHECK: DeclRefExpr=z:3:33 typekind=Typedef [canonical=Int] [isPOD=1]
|
||||
// CHECK: ReturnStmt= typekind=Invalid [isPOD=0]
|
||||
// CHECK: BinaryOperator= typekind=Pointer [isPOD=1]
|
||||
// CHECK: DeclRefExpr=p:3:13 typekind=Pointer [isPOD=1]
|
||||
// CHECK: DeclRefExpr=z:3:33 typekind=Typedef [canonical=Int] [isPOD=1]
|
||||
// CHECK: TypedefDecl=OtherType:7:16 (Definition) typekind=Typedef [canonical=Double] [isPOD=1]
|
||||
// CHECK: TypedefDecl=ArrayType:8:13 (Definition) typekind=Typedef [canonical=ConstantArray] [isPOD=1]
|
|
@ -1,10 +0,0 @@
|
|||
@interface Foo
|
||||
@property (readonly) id x;
|
||||
-(int) mymethod;
|
||||
-(const id) mymethod2:(id)x blah:(Class)y boo:(SEL)z;
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -test-print-typekind %s | FileCheck %s
|
||||
// CHECK: ObjCPropertyDecl=x:2:25 typekind=ObjCId [canonical=ObjCObjectPointer]
|
||||
// CHECK: ObjCInstanceMethodDecl=mymethod:3:8 typekind=Invalid [result=Int]
|
||||
// CHECK: ObjCInstanceMethodDecl=mymethod2:blah:boo::4:13 typekind=Invalid [result=ObjCId] [args= ObjCId ObjCClass ObjCSel]
|
|
@ -1,6 +0,0 @@
|
|||
int __attribute__((vector_size(16))) x;
|
||||
typedef int __attribute__((vector_size(16))) int4_t;
|
||||
|
||||
// RUN: c-index-test -test-print-typekind %s | FileCheck %s
|
||||
// CHECK: VarDecl=x:1:38 typekind=Vector [isPOD=1]
|
||||
// CHECK: TypedefDecl=int4_t:2:46 (Definition) typekind=Typedef [canonical=Vector] [isPOD=1]
|
|
@ -1083,36 +1083,42 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
|
|||
/* Typekind testing. */
|
||||
/******************************************************************************/
|
||||
|
||||
static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
|
||||
static void PrintTypeAndTypeKind(CXType T, const char *Format) {
|
||||
CXString TypeSpelling, TypeKindSpelling;
|
||||
|
||||
TypeSpelling = clang_getTypeSpelling(T);
|
||||
TypeKindSpelling = clang_getTypeKindSpelling(T.kind);
|
||||
printf(Format,
|
||||
clang_getCString(TypeSpelling),
|
||||
clang_getCString(TypeKindSpelling));
|
||||
clang_disposeString(TypeSpelling);
|
||||
clang_disposeString(TypeKindSpelling);
|
||||
}
|
||||
|
||||
static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
|
||||
CXClientData d) {
|
||||
if (!clang_isInvalid(clang_getCursorKind(cursor))) {
|
||||
CXType T = clang_getCursorType(cursor);
|
||||
CXString S = clang_getTypeKindSpelling(T.kind);
|
||||
PrintCursor(cursor, NULL);
|
||||
printf(" typekind=%s", clang_getCString(S));
|
||||
PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
|
||||
if (clang_isConstQualifiedType(T))
|
||||
printf(" const");
|
||||
if (clang_isVolatileQualifiedType(T))
|
||||
printf(" volatile");
|
||||
if (clang_isRestrictQualifiedType(T))
|
||||
printf(" restrict");
|
||||
clang_disposeString(S);
|
||||
/* Print the canonical type if it is different. */
|
||||
{
|
||||
CXType CT = clang_getCanonicalType(T);
|
||||
if (!clang_equalTypes(T, CT)) {
|
||||
CXString CS = clang_getTypeKindSpelling(CT.kind);
|
||||
printf(" [canonical=%s]", clang_getCString(CS));
|
||||
clang_disposeString(CS);
|
||||
PrintTypeAndTypeKind(CT, " [canonicaltype=%s] [canonicaltypekind=%s]");
|
||||
}
|
||||
}
|
||||
/* Print the return type if it exists. */
|
||||
{
|
||||
CXType RT = clang_getCursorResultType(cursor);
|
||||
if (RT.kind != CXType_Invalid) {
|
||||
CXString RS = clang_getTypeKindSpelling(RT.kind);
|
||||
printf(" [result=%s]", clang_getCString(RS));
|
||||
clang_disposeString(RS);
|
||||
PrintTypeAndTypeKind(RT, " [resulttype=%s] [resulttypekind=%s]");
|
||||
}
|
||||
}
|
||||
/* Print the argument types if they exist. */
|
||||
|
@ -1124,9 +1130,7 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
|
|||
for (i = 0; i < numArgs; ++i) {
|
||||
CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
|
||||
if (T.kind != CXType_Invalid) {
|
||||
CXString S = clang_getTypeKindSpelling(T.kind);
|
||||
printf(" %s", clang_getCString(S));
|
||||
clang_disposeString(S);
|
||||
PrintTypeAndTypeKind(T, " [%s] [%s]");
|
||||
}
|
||||
}
|
||||
printf("]");
|
||||
|
@ -3543,7 +3547,7 @@ static void print_usage(void) {
|
|||
" c-index-test -test-inclusion-stack-tu <AST file>\n");
|
||||
fprintf(stderr,
|
||||
" c-index-test -test-print-linkage-source {<args>}*\n"
|
||||
" c-index-test -test-print-typekind {<args>}*\n"
|
||||
" c-index-test -test-print-type {<args>}*\n"
|
||||
" c-index-test -test-print-bitwidth {<args>}*\n"
|
||||
" c-index-test -print-usr [<CursorKind> {<args>}]*\n"
|
||||
" c-index-test -print-usr-file <file>\n"
|
||||
|
@ -3625,9 +3629,9 @@ int cindextest_main(int argc, const char **argv) {
|
|||
else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0)
|
||||
return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage,
|
||||
NULL);
|
||||
else if (argc > 2 && strcmp(argv[1], "-test-print-typekind") == 0)
|
||||
else if (argc > 2 && strcmp(argv[1], "-test-print-type") == 0)
|
||||
return perform_test_load_source(argc - 2, argv + 2, "all",
|
||||
PrintTypeKind, 0);
|
||||
PrintType, 0);
|
||||
else if (argc > 2 && strcmp(argv[1], "-test-print-bitwidth") == 0)
|
||||
return perform_test_load_source(argc - 2, argv + 2, "all",
|
||||
PrintBitWidth, 0);
|
||||
|
|
|
@ -200,6 +200,21 @@ CXType clang_getCursorType(CXCursor C) {
|
|||
return MakeCXType(QualType(), TU);
|
||||
}
|
||||
|
||||
CXString clang_getTypeSpelling(CXType CT) {
|
||||
QualType T = GetQualType(CT);
|
||||
if (T.isNull())
|
||||
return cxstring::createEmpty();
|
||||
|
||||
CXTranslationUnit TU = GetTU(CT);
|
||||
SmallString<64> Str;
|
||||
llvm::raw_svector_ostream OS(Str);
|
||||
PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
|
||||
|
||||
T.print(OS, PP);
|
||||
|
||||
return cxstring::createDup(OS.str());
|
||||
}
|
||||
|
||||
CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
|
||||
using namespace cxcursor;
|
||||
CXTranslationUnit TU = cxcursor::getCursorTU(C);
|
||||
|
|
|
@ -205,6 +205,7 @@ clang_getTranslationUnitCursor
|
|||
clang_getTranslationUnitSpelling
|
||||
clang_getTypeDeclaration
|
||||
clang_getTypeKindSpelling
|
||||
clang_getTypeSpelling
|
||||
clang_getTypedefDeclUnderlyingType
|
||||
clang_hashCursor
|
||||
clang_indexLoc_getCXSourceLocation
|
||||
|
|
Loading…
Reference in New Issue