- Rebase and change createCXString -> createDup
    - Merge tests and remove options struct.
    - Clarify docblock comment.
    - Bump minor version.
    - Fix braces.
    - Put brackets around both type and typekind output.

Hi gribozavr, jordan_rose,

http://llvm-reviews.chandlerc.com/D409

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D409?vs=988&id=992#toc

Files:
  include/clang-c/Index.h
  test/Index/print-type.c
  test/Index/print-type.cpp
  test/Index/print-typekind.c
  test/Index/print-typekind.m
  test/Index/vector-types.c
  tools/c-index-test/c-index-test.c
  tools/libclang/CXType.cpp
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -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)                       \
@@ -2695,6 +2695,14 @@
 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.
  *
  * If the cursor does not reference a typedef declaration, an invalid type is
Index: test/Index/print-type.c
===================================================================
--- /dev/null
+++ test/Index/print-type.c
@@ -0,0 +1,29 @@
+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: TypedefDecl=FooType:1:13 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: VarDecl=p:2:6 [type=int *] [typekind=Pointer] [isPOD=1]
+// CHECK: FunctionDecl=f:3:6 (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: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: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: VarDecl=w:4: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: 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: TypedefDecl=OtherType:7:16 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
+// CHECK: TypedefDecl=ArrayType:8:13 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
+// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
Index: test/Index/print-type.cpp
===================================================================
--- /dev/null
+++ test/Index/print-type.cpp
@@ -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]
Index: test/Index/print-typekind.c
===================================================================
--- test/Index/print-typekind.c
+++ test/Index/print-typekind.c
@@ -7,22 +7,22 @@
 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]
+// RUN: c-index-test -test-print-type %s | FileCheck %s
+// CHECK: TypedefDecl=FooType:1:13 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: VarDecl=p:2:6 [type=int *] [typekind=Pointer] [isPOD=1]
+// CHECK: FunctionDecl=f:3:6 (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: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: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: VarDecl=w:4: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: 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: TypedefDecl=OtherType:7:16 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
+// CHECK: TypedefDecl=ArrayType:8:13 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
Index: test/Index/print-typekind.m
===================================================================
--- test/Index/print-typekind.m
+++ test/Index/print-typekind.m
@@ -4,7 +4,7 @@
 -(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]
+// 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]
Index: test/Index/vector-types.c
===================================================================
--- test/Index/vector-types.c
+++ test/Index/vector-types.c
@@ -1,6 +1,6 @@
 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]
+// RUN: c-index-test -test-print-type %s | FileCheck %s
+// CHECK: VarDecl=x:1:38 [type=__attribute__((__vector_size__(4 * sizeof(int)))) int] [typekind=Vector] [isPOD=1]
+// CHECK: TypedefDecl=int4_t:2:46 (Definition) [type=int4_t] [typekind=Typedef] [canonicaltype=__attribute__((__vector_size__(4 * sizeof(int)))) int] [canonicaltypekind=Vector] [isPOD=1]
Index: tools/c-index-test/c-index-test.c
===================================================================
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1083,36 +1083,57 @@
 /* Typekind testing.                                                          */
 /******************************************************************************/
 
-static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
-                                             CXClientData d) {
+typedef enum {
+  PRINT_TYPE,
+  PRINT_TYPEKIND
+} PrintTypeMode;
+
+static void PrintTypeForMode(
+  CXType T,
+  PrintTypeMode mode,
+  const char *fmt) {
+  CXString S;
+
+  switch (mode) {
+    case PRINT_TYPE:
+      S = clang_getTypeSpelling(T);
+      break;
+    case PRINT_TYPEKIND:
+      S = clang_getTypeKindSpelling(T.kind);
+      break;
+  }
+
+  printf(fmt, clang_getCString(S));
+  clang_disposeString(S);
+}
+
+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));
+    PrintTypeForMode(T, PRINT_TYPE, " [type=%s]");
+    PrintTypeForMode(T, PRINT_TYPEKIND, " [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);
+        PrintTypeForMode(CT, PRINT_TYPE, " [canonicaltype=%s]");
+        PrintTypeForMode(CT, PRINT_TYPEKIND, " [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);
+        PrintTypeForMode(RT, PRINT_TYPE, " [resulttype=%s]");
+        PrintTypeForMode(RT, PRINT_TYPEKIND, " [resulttypekind=%s]");
       }
     }
     /* Print the argument types if they exist. */
@@ -1124,9 +1145,8 @@
         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);
+            PrintTypeForMode(T, PRINT_TYPE, " [%s]");
+            PrintTypeForMode(T, PRINT_TYPEKIND, " [%s]");
           }
         }
         printf("]");
@@ -3544,6 +3564,7 @@
   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"
@@ -3624,10 +3645,11 @@
                                 PrintInclusionStack);
   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)
+                                    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);
@@ -3645,7 +3667,6 @@
     return write_pch_file(argv[2], argc - 3, argv + 3);
   else if (argc > 2 && strcmp(argv[1], "-compilation-db") == 0)
     return perform_test_compilation_db(argv[argc-1], argc - 3, argv + 2);
-
   print_usage();
   return 1;
 }
Index: tools/libclang/CXType.cpp
===================================================================
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -200,6 +200,21 @@
   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);
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to