diff options
author | Warren Hunt <whunt@google.com> | 2013-11-01 23:59:41 +0000 |
---|---|---|
committer | Warren Hunt <whunt@google.com> | 2013-11-01 23:59:41 +0000 |
commit | 5ae586ad459617f6266ceb4aa7ccf132b73f65fd (patch) | |
tree | 45f565c044a4d6a4064befafc1b51d8dd7c27ac5 /clang | |
parent | 365bd0c88cb36f5d92bca3b396fbb0fbe36bc44a (diff) | |
download | bcm5719-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.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 22 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-misalignedarray.cpp | 23 |
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)]; |