[libclang] Expose record layout info via new libclang functions:

clang_Type_getAlignOf
clang_Type_getSizeOf
clang_Type_getOffsetOf
clang_Cursor_isBitField

Patch by Loïc Jaquemet!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179251 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index ce9e491..e97cb30 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1144,6 +1144,61 @@
   return CXChildVisit_Recurse;
 }
 
+static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
+                                             CXClientData d) {
+  CXType T;
+  enum CXCursorKind K = clang_getCursorKind(cursor);
+  if (clang_isInvalid(K))
+    return CXChildVisit_Recurse;
+  T = clang_getCursorType(cursor);
+  PrintCursor(cursor, NULL);
+  PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
+  /* Print the type sizeof if applicable. */
+  {
+    long long Size = clang_Type_getSizeOf(T);
+    if (Size >= 0 || Size < -1 ) {
+      printf(" [sizeof=%lld]", Size);
+    }
+  }
+  /* Print the type alignof if applicable. */
+  {
+    long long Align = clang_Type_getAlignOf(T);
+    if (Align >= 0 || Align < -1) {
+      printf(" [alignof=%lld]", Align);
+    }
+  }
+  /* Print the record field offset if applicable. */
+  {
+    const char *FieldName = clang_getCString(clang_getCursorSpelling(cursor));
+    /* recurse to get the root anonymous record parent */
+    CXCursor Parent, Root;
+    if (clang_getCursorKind(cursor) == CXCursor_FieldDecl ) {
+      const char *RootParentName;
+      Root = Parent = p;
+      do {
+        Root = Parent;
+        RootParentName = clang_getCString(clang_getCursorSpelling(Root));
+        Parent = clang_getCursorSemanticParent(Root);
+      } while ( clang_getCursorType(Parent).kind == CXType_Record &&
+                !strcmp(RootParentName, "") );
+      /* if RootParentName is "", record is anonymous. */
+      {
+        long long Offset = clang_Type_getOffsetOf(clang_getCursorType(Root),
+                                                  FieldName);
+        printf(" [offsetof=%lld]", Offset);
+      }
+    }
+  }
+  /* Print if its a bitfield */
+  {
+    int IsBitfield = clang_Cursor_isBitField(cursor);
+    if (IsBitfield)
+      printf(" [BitFieldSize=%d]", clang_getFieldDeclBitWidth(cursor));
+  }
+  printf("\n");
+  return CXChildVisit_Recurse;
+}
+
 /******************************************************************************/
 /* Bitwidth testing.                                                          */
 /******************************************************************************/
@@ -3642,6 +3697,7 @@
   fprintf(stderr,
     "       c-index-test -test-print-linkage-source {<args>}*\n"
     "       c-index-test -test-print-type {<args>}*\n"
+    "       c-index-test -test-print-type-size {<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"
@@ -3728,6 +3784,9 @@
   else if (argc > 2 && strcmp(argv[1], "-test-print-type") == 0)
     return perform_test_load_source(argc - 2, argv + 2, "all",
                                     PrintType, 0);
+  else if (argc > 2 && strcmp(argv[1], "-test-print-type-size") == 0)
+    return perform_test_load_source(argc - 2, argv + 2, "all",
+                                    PrintTypeSize, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-bitwidth") == 0)
     return perform_test_load_source(argc - 2, argv + 2, "all",
                                     PrintBitWidth, 0);