summaryrefslogtreecommitdiff
path: root/test/Layout
diff options
context:
space:
mode:
authorWarren Hunt <whunt@google.com>2013-12-06 00:01:17 +0000
committerWarren Hunt <whunt@google.com>2013-12-06 00:01:17 +0000
commit5ec042b219241ea73f33a143a0e5735c2f57886b (patch)
tree41a962cb129ea99b26781df6c7a43207178e21d1 /test/Layout
parentb5d65e84c9b9f5e9e059ae5c30dd1a3b37c4246f (diff)
downloadclang-5ec042b219241ea73f33a143a0e5735c2f57886b.tar.gz
Support MS-ABI's concept of "Required Alignment" imposed by
__declspec(align()) This patch implements required alignment in a way that makes __declspec(align()) and #pragma pack play correctly together. In the MS-ABI, __declspec(align()) is a hard rule and cannot be overridden by #pragma pack. This cases each record to have two interesting alignments "preferred alignment" (which matches Itanium's concept of alignment) and "required alignment" which is an alignment that must never be violated, even in the case of #pragma pack. This patch introduces the concept of Required Alignment to the record builder and tracks/uses it appropriately. Test cases are included. Differential Revision: http://llvm-reviews.chandlerc.com/D2283 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196549 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Layout')
-rw-r--r--test/Layout/ms-x86-pack-and-align.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/test/Layout/ms-x86-pack-and-align.cpp b/test/Layout/ms-x86-pack-and-align.cpp
new file mode 100644
index 0000000000..f9f2b30f5f
--- /dev/null
+++ b/test/Layout/ms-x86-pack-and-align.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: | FileCheck %s -check-prefix CHECK-X64
+
+extern "C" int printf(const char *fmt, ...);
+char buffer[419430400];
+
+struct A {
+ char a;
+ A() {
+ printf("A = %d\n", (int)((char*)this - buffer));
+ printf("A.a = %d\n", (int)((char*)&a - buffer));
+ }
+};
+
+struct B {
+ __declspec(align(4)) long long a;
+ B() {
+ printf("B = %d\n", (int)((char*)this - buffer));
+ printf("B.a = %d\n", (int)((char*)&a - buffer));
+ }
+};
+
+#pragma pack(push, 2)
+struct X {
+ B a;
+ char b;
+ int c;
+ X() {
+ printf("X = %d\n", (int)((char*)this - buffer));
+ printf("X.a = %d\n", (int)((char*)&a - buffer));
+ printf("X.b = %d\n", (int)((char*)&b - buffer));
+ printf("X.c = %d\n", (int)((char*)&c - buffer));
+ }
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct X
+// CHECK: 0 | struct B a
+// CHECK: 0 | long long a
+// CHECK: 8 | char b
+// CHECK: 10 | int c
+// CHECK: | [sizeof=16, align=4
+// CHECK: | nvsize=16, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: 0 | struct X
+// CHECK-X64: 0 | struct B a
+// CHECK-X64: 0 | long long a
+// CHECK-X64: 8 | char b
+// CHECK-X64: 10 | int c
+// CHECK-X64: | [sizeof=16, align=4
+// CHECK-X64: | nvsize=16, nvalign=4]
+
+struct Y : A, B {
+ char a;
+ int b;
+ Y() {
+ printf("Y = %d\n", (int)((char*)this - buffer));
+ printf("Y.a = %d\n", (int)((char*)&a - buffer));
+ printf("Y.b = %d\n", (int)((char*)&b - buffer));
+ }
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct Y
+// CHECK: 0 | struct A (base)
+// CHECK: 0 | char a
+// CHECK: 4 | struct B (base)
+// CHECK: 4 | long long a
+// CHECK: 12 | char a
+// CHECK: 14 | int b
+// CHECK: | [sizeof=20, align=4
+// CHECK: | nvsize=20, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: 0 | struct Y
+// CHECK-X64: 0 | struct A (base)
+// CHECK-X64: 0 | char a
+// CHECK-X64: 4 | struct B (base)
+// CHECK-X64: 4 | long long a
+// CHECK-X64: 12 | char a
+// CHECK-X64: 14 | int b
+// CHECK-X64: | [sizeof=20, align=4
+// CHECK-X64: | nvsize=20, nvalign=4]
+
+struct Z : virtual B {
+ char a;
+ int b;
+ Z() {
+ printf("Z = %d\n", (int)((char*)this - buffer));
+ printf("Z.a = %d\n", (int)((char*)&a - buffer));
+ printf("Z.b = %d\n", (int)((char*)&b - buffer));
+ }
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct Z
+// CHECK: 0 | (Z vbtable pointer)
+// CHECK: 4 | char a
+// CHECK: 6 | int b
+// CHECK: 12 | struct B (virtual base)
+// CHECK: 12 | long long a
+// CHECK: | [sizeof=20, align=4
+// CHECK: | nvsize=10, nvalign=2]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: 0 | struct Z
+// CHECK-X64: 0 | (Z vbtable pointer)
+// CHECK-X64: 8 | char a
+// CHECK-X64: 10 | int b
+// CHECK-X64: 16 | struct B (virtual base)
+// CHECK-X64: 16 | long long a
+// CHECK-X64: | [sizeof=24, align=4
+// CHECK-X64: | nvsize=14, nvalign=2]
+
+#pragma pack(pop)
+
+int a[
+sizeof(X)+
+sizeof(Y)+
+sizeof(Z)];