summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorWarren Hunt <whunt@google.com>2013-11-01 23:59:41 +0000
committerWarren Hunt <whunt@google.com>2013-11-01 23:59:41 +0000
commit5ae586ad459617f6266ceb4aa7ccf132b73f65fd (patch)
tree45f565c044a4d6a4064befafc1b51d8dd7c27ac5 /clang
parent365bd0c88cb36f5d92bca3b396fbb0fbe36bc44a (diff)
downloadbcm5719-llvm-5ae586ad459617f6266ceb4aa7ccf132b73f65fd.tar.gz
bcm5719-llvm-5ae586ad459617f6266ceb4aa7ccf132b73f65fd.zip
Improves compatibility with cl.exe when laying out array fields
Differential Revision: http://llvm-reviews.chandlerc.com/D2090 Clang was "improperly" over-aligning arrays with sizes are not a multiple of their alignment. This behavior was removed in microsoft 32 bit mode. In addition, after examination of ASTContext::getTypeInfoImpl, a redundant code block in MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo was deleted. llvm-svn: 193898
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/ASTContext.cpp8
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp22
-rw-r--r--clang/test/Layout/ms-x86-misalignedarray.cpp23
3 files changed, 32 insertions, 21 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 88e1d04ddf8..2ed345aec8d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1387,7 +1387,9 @@ static getConstantArrayInfoInChars(const ASTContext &Context,
"Overflow in array type char size evaluation");
uint64_t Width = EltInfo.first.getQuantity() * Size;
unsigned Align = EltInfo.second.getQuantity();
- Width = llvm::RoundUpToAlignment(Width, Align);
+ if (!Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+ Context.getTargetInfo().getPointerWidth(0) == 64)
+ Width = llvm::RoundUpToAlignment(Width, Align);
return std::make_pair(CharUnits::fromQuantity(Width),
CharUnits::fromQuantity(Align));
}
@@ -1460,7 +1462,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
"Overflow in array type bit size evaluation");
Width = EltInfo.first*Size;
Align = EltInfo.second;
- Width = llvm::RoundUpToAlignment(Width, Align);
+ if (!getTargetInfo().getCXXABI().isMicrosoft() ||
+ getTargetInfo().getPointerWidth(0) == 64)
+ Width = llvm::RoundUpToAlignment(Width, Align);
break;
}
case Type::ExtVector:
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index fb35343a477..87d00bc9f5d 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2140,23 +2140,8 @@ public:
std::pair<CharUnits, CharUnits>
MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo(const FieldDecl *FD) {
- std::pair<CharUnits, CharUnits> FieldInfo;
- if (FD->getType()->isIncompleteArrayType()) {
- // This is a flexible array member; we can't directly
- // query getTypeInfo about these, so we figure it out here.
- // Flexible array members don't have any size, but they
- // have to be aligned appropriately for their element type.
- FieldInfo.first = CharUnits::Zero();
- const ArrayType *ATy = Context.getAsArrayType(FD->getType());
- FieldInfo.second = Context.getTypeAlignInChars(ATy->getElementType());
- } else if (const ReferenceType *RT = FD->getType()->getAs<ReferenceType>()) {
- unsigned AS = RT->getPointeeType().getAddressSpace();
- FieldInfo.first = Context
- .toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(AS));
- FieldInfo.second = Context
- .toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(AS));
- } else
- FieldInfo = Context.getTypeInfoInChars(FD->getType());
+ std::pair<CharUnits, CharUnits> FieldInfo =
+ Context.getTypeInfoInChars(FD->getType());
// If we're not on win32 and using ms_struct the field alignment will be wrong
// for 64 bit types, so we fix that here.
@@ -2187,8 +2172,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo(const FieldDecl *FD) {
void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
IsUnion = RD->isUnion();
- Is64BitMode = RD->getASTContext().getTargetInfo().getTriple().getArch() ==
- llvm::Triple::x86_64;
+ Is64BitMode = Context.getTargetInfo().getPointerWidth(0) == 64;
Size = CharUnits::Zero();
Alignment = CharUnits::One();
diff --git a/clang/test/Layout/ms-x86-misalignedarray.cpp b/clang/test/Layout/ms-x86-misalignedarray.cpp
new file mode 100644
index 00000000000..f6887daf15b
--- /dev/null
+++ b/clang/test/Layout/ms-x86-misalignedarray.cpp
@@ -0,0 +1,23 @@
+// 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
+
+struct T0 { char c; };
+struct T2 : virtual T0 { };
+struct T3 { T2 a[1]; char c; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct T3
+// CHECK: 0 | struct T2 [1] a
+// CHECK: 5 | char c
+// CHECK: | [sizeof=8, align=4
+// CHECK: | nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: 0 | struct T3
+// CHECK-X64: 0 | struct T2 [1] a
+// CHECK-X64: 16 | char c
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=24, nvalign=8]
+
+int a[sizeof(T3)];
OpenPOWER on IntegriCloud