]> granicus.if.org Git - clang/commitdiff
-fdump-record-layouts: Sort nvbases by offset before printing them
authorReid Kleckner <reid@kleckner.net>
Fri, 28 Feb 2014 01:03:09 +0000 (01:03 +0000)
committerReid Kleckner <reid@kleckner.net>
Fri, 28 Feb 2014 01:03:09 +0000 (01:03 +0000)
It makes our -fdump-record-layouts a little more sane.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202457 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/RecordLayoutBuilder.cpp
test/Layout/ms-x86-primary-bases.cpp
test/Layout/ms-x86-vfvb-alignment.cpp
test/Sema/ms_class_layout.cpp

index 11835c901cbb345f2775a209480e7003a929e834..06f6ecb3dd4ef3f717beb5131dcccf38877067a0 100644 (file)
@@ -3102,19 +3102,34 @@ static void DumpCXXRecordLayout(raw_ostream &OS,
     OS << '(' << *RD << " vftable pointer)\n";
   }
 
-  // Dump (non-virtual) bases
+  // Collect nvbases.
+  SmallVector<const CXXRecordDecl *, 4> Bases;
   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
+                                                E = RD->bases_end();
+       I != E; ++I) {
     assert(!I->getType()->isDependentType() &&
            "Cannot layout class with dependent bases.");
-    if (I->isVirtual())
-      continue;
+    if (!I->isVirtual())
+      Bases.push_back(I->getType()->getAsCXXRecordDecl());
+  }
 
-    const CXXRecordDecl *Base =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+  // Sort nvbases by offset.
+  struct BaseOffsetComparator {
+    const ASTRecordLayout &RL;
+    BaseOffsetComparator(const ASTRecordLayout &RL) : RL(RL) {}
+    bool operator()(const CXXRecordDecl *L, const CXXRecordDecl *R) const {
+      return RL.getBaseClassOffset(L) < RL.getBaseClassOffset(R);
+    }
+  };
+  BaseOffsetComparator Cmp(Layout);
+  std::stable_sort(Bases.begin(), Bases.end(), Cmp);
 
+  // Dump (non-virtual) bases
+  for (SmallVectorImpl<const CXXRecordDecl *>::iterator I = Bases.begin(),
+                                                        E = Bases.end();
+       I != E; ++I) {
+    const CXXRecordDecl *Base = *I;
     CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
-
     DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
                         Base == PrimaryBase ? "(primary base)" : "(base)",
                         /*IncludeVirtualBases=*/false);
index bb6b89c6fcb052779118f7a2b06dc257b2026832..b5bd041fa116635be19aea27adb069cecad43cea 100644 (file)
@@ -170,11 +170,11 @@ struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf(
 // CHECK: *** Dumping AST Record Layout
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct AX
-// CHECK-NEXT:    8 |   struct B0X (base)
-// CHECK-NEXT:    8 |     int a
 // CHECK-NEXT:    0 |   struct B1X (primary base)
 // CHECK-NEXT:    0 |     (B1X vftable pointer)
 // CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B0X (base)
+// CHECK-NEXT:    8 |     int a
 // CHECK-NEXT:   12 |   int a
 // CHECK-NEXT:      | [sizeof=16, align=4
 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
@@ -182,11 +182,11 @@ struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf(
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct AX
-// CHECK-X64-NEXT:   16 |   struct B0X (base)
-// CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:    0 |   struct B1X (primary base)
 // CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
 // CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B0X (base)
+// CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:   20 |   int a
 // CHECK-X64-NEXT:      | [sizeof=24, align=8
 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
@@ -195,21 +195,21 @@ struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf(
 
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct BX
-// CHECK-NEXT:    8 |   struct B0X (base)
-// CHECK-NEXT:    8 |     int a
 // CHECK-NEXT:    0 |   struct B1X (primary base)
 // CHECK-NEXT:    0 |     (B1X vftable pointer)
 // CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B0X (base)
+// CHECK-NEXT:    8 |     int a
 // CHECK-NEXT:   12 |   int a
 // CHECK-NEXT:      | [sizeof=16, align=4
 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct BX
-// CHECK-X64-NEXT:   16 |   struct B0X (base)
-// CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:    0 |   struct B1X (primary base)
 // CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
 // CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B0X (base)
+// CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:   20 |   int a
 // CHECK-X64-NEXT:      | [sizeof=24, align=8
 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
index 7ec0c5f466ec1c8390ee0d6af71fdb89927360fe..f65adc15a666a0e81fcd192582d1e40a7ee6c795 100644 (file)
@@ -200,12 +200,12 @@ struct G : B2, B6, virtual B1 { int a; G() : a(0xf0000010) {} };
 // CHECK: *** Dumping AST Record Layout
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct G
-// CHECK-NEXT:    8 |   struct B2 (base)
-// CHECK-NEXT:    8 |     (B2 vbtable pointer)
-// CHECK-NEXT:   12 |     int a
 // CHECK-NEXT:    0 |   struct B6 (primary base)
 // CHECK-NEXT:    0 |     (B6 vftable pointer)
 // CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B2 (base)
+// CHECK-NEXT:    8 |     (B2 vbtable pointer)
+// CHECK-NEXT:   12 |     int a
 // CHECK-NEXT:   16 |   int a
 // CHECK-NEXT:   20 |   struct B1 (virtual base)
 // CHECK-NEXT:   20 |     char a
@@ -214,12 +214,12 @@ struct G : B2, B6, virtual B1 { int a; G() : a(0xf0000010) {} };
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct G
-// CHECK-X64-NEXT:   16 |   struct B2 (base)
-// CHECK-X64-NEXT:   16 |     (B2 vbtable pointer)
-// CHECK-X64-NEXT:   24 |     int a
 // CHECK-X64-NEXT:    0 |   struct B6 (primary base)
 // CHECK-X64-NEXT:    0 |     (B6 vftable pointer)
 // CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B2 (base)
+// CHECK-X64-NEXT:   16 |     (B2 vbtable pointer)
+// CHECK-X64-NEXT:   24 |     int a
 // CHECK-X64-NEXT:   32 |   int a
 // CHECK-X64-NEXT:   40 |   struct B1 (virtual base)
 // CHECK-X64-NEXT:   40 |     char a
index eea310ad672eb10a9535e899356929775c6f7afa..896d3edfda38cfd3772c9f9fb242ad9e432b09b2 100644 (file)
@@ -470,12 +470,12 @@ int main() {
 // CHECK: %struct.DV = type { %struct.BV }
 
 // CHECK:       0 | struct EV
-// CHECK-NEXT:  4 |   struct CV (base)
-// CHECK-NEXT:  4 |     (CV vbtable pointer)
 // CHECK-NEXT:  0 |   struct DV (primary base)
 // CHECK-NEXT:  0 |     struct BV (primary base)
 // CHECK-NEXT:  0 |       struct AV (primary base)
 // CHECK-NEXT:  0 |         (AV vftable pointer)
+// CHECK-NEXT:  4 |   struct CV (base)
+// CHECK-NEXT:  4 |     (CV vbtable pointer)
 // CHECK-NEXT:  8 |   (vtordisp for vbase BV)
 // CHECK-NEXT: 12 |   struct BV (virtual base)
 // CHECK-NEXT: 12 |     struct AV (primary base)