forked from OSchip/llvm-project
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
This commit is contained in:
parent
365bd0c88c
commit
5ae586ad45
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)];
|
Loading…
Reference in New Issue