r230474 - Revert r230446, "MS ABI: Try to respect external AST source record layouts"
NAKAMURA Takumi
geek4civic at gmail.com
Wed Feb 25 02:32:13 PST 2015
Author: chapuni
Date: Wed Feb 25 04:32:13 2015
New Revision: 230474
URL: http://llvm.org/viewvc/llvm-project?rev=230474&view=rev
Log:
Revert r230446, "MS ABI: Try to respect external AST source record layouts"
It fails on Clang::PCH/headersearch.cpp for targeting msvc.
Modified:
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/test/CodeGenCXX/override-layout.cpp
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=230474&r1=230473&r2=230474&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed Feb 25 04:32:13 2015
@@ -55,52 +55,6 @@ struct BaseSubobjectInfo {
const BaseSubobjectInfo *Derived;
};
-/// \brief Externally provided layout. Typically used when the AST source, such
-/// as DWARF, lacks all the information that was available at compile time, such
-/// as alignment attributes on fields and pragmas in effect.
-struct ExternalLayout {
- ExternalLayout() : Size(0), Align(0) {}
-
- /// \brief Overall record size in bits.
- uint64_t Size;
-
- /// \brief Overall record alignment in bits.
- uint64_t Align;
-
- /// \brief Record field offsets in bits.
- llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsets;
-
- /// \brief Direct, non-virtual base offsets.
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsets;
-
- /// \brief Virtual base offsets.
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> VirtualBaseOffsets;
-
- /// Get the offset of the given field. The external source must provide
- /// entries for all fields in the record.
- uint64_t getExternalFieldOffset(const FieldDecl *FD) {
- assert(FieldOffsets.count(FD) &&
- "Field does not have an external offset");
- return FieldOffsets[FD];
- }
-
- bool getExternalNVBaseOffset(const CXXRecordDecl *RD, CharUnits &BaseOffset) {
- auto Known = BaseOffsets.find(RD);
- if (Known == BaseOffsets.end())
- return false;
- BaseOffset = Known->second;
- return true;
- }
-
- bool getExternalVBaseOffset(const CXXRecordDecl *RD, CharUnits &BaseOffset) {
- auto Known = VirtualBaseOffsets.find(RD);
- if (Known == VirtualBaseOffsets.end())
- return false;
- BaseOffset = Known->second;
- return true;
- }
-};
-
/// EmptySubobjectMap - Keeps track of which empty subobjects exist at different
/// offsets while laying out a C++ class.
class EmptySubobjectMap {
@@ -587,7 +541,7 @@ protected:
/// \brief Whether the external AST source has provided a layout for this
/// record.
- unsigned UseExternalLayout : 1;
+ unsigned ExternalLayout : 1;
/// \brief Whether we need to infer alignment, even when we have an
/// externally-provided layout.
@@ -653,14 +607,26 @@ protected:
/// avoid visiting virtual bases more than once.
llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
- /// Valid if UseExternalLayout is true.
- ExternalLayout External;
+ /// \brief Externally-provided size.
+ uint64_t ExternalSize;
+
+ /// \brief Externally-provided alignment.
+ uint64_t ExternalAlign;
+
+ /// \brief Externally-provided field offsets.
+ llvm::DenseMap<const FieldDecl *, uint64_t> ExternalFieldOffsets;
+
+ /// \brief Externally-provided direct, non-virtual base offsets.
+ llvm::DenseMap<const CXXRecordDecl *, CharUnits> ExternalBaseOffsets;
+
+ /// \brief Externally-provided virtual base offsets.
+ llvm::DenseMap<const CXXRecordDecl *, CharUnits> ExternalVirtualBaseOffsets;
RecordLayoutBuilder(const ASTContext &Context,
EmptySubobjectMap *EmptySubobjects)
: Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()),
- UseExternalLayout(false), InferAlignment(false),
+ ExternalLayout(false), InferAlignment(false),
Packed(false), IsUnion(false), IsMac68kAlign(false), IsMsStruct(false),
UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0),
MaxFieldAlignment(CharUnits::Zero()),
@@ -1168,12 +1134,21 @@ CharUnits RecordLayoutBuilder::LayoutBas
// Query the external layout to see if it provides an offset.
bool HasExternalLayout = false;
- if (UseExternalLayout) {
+ if (ExternalLayout) {
llvm::DenseMap<const CXXRecordDecl *, CharUnits>::iterator Known;
- if (Base->IsVirtual)
- HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset);
- else
- HasExternalLayout = External.getExternalVBaseOffset(Base->Class, Offset);
+ if (Base->IsVirtual) {
+ Known = ExternalVirtualBaseOffsets.find(Base->Class);
+ if (Known != ExternalVirtualBaseOffsets.end()) {
+ Offset = Known->second;
+ HasExternalLayout = true;
+ }
+ } else {
+ Known = ExternalBaseOffsets.find(Base->Class);
+ if (Known != ExternalBaseOffsets.end()) {
+ Offset = Known->second;
+ HasExternalLayout = true;
+ }
+ }
}
CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlignment();
@@ -1260,15 +1235,18 @@ void RecordLayoutBuilder::InitializeLayo
// If there is an external AST source, ask it for the various offsets.
if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
- if (ExternalASTSource *Source = Context.getExternalSource()) {
- UseExternalLayout = Source->layoutRecordType(
- RD, External.Size, External.Align, External.FieldOffsets,
- External.BaseOffsets, External.VirtualBaseOffsets);
-
+ if (ExternalASTSource *External = Context.getExternalSource()) {
+ ExternalLayout = External->layoutRecordType(RD,
+ ExternalSize,
+ ExternalAlign,
+ ExternalFieldOffsets,
+ ExternalBaseOffsets,
+ ExternalVirtualBaseOffsets);
+
// Update based on external alignment.
- if (UseExternalLayout) {
- if (External.Align > 0) {
- Alignment = Context.toCharUnitsFromBits(External.Align);
+ if (ExternalLayout) {
+ if (ExternalAlign > 0) {
+ Alignment = Context.toCharUnitsFromBits(ExternalAlign);
} else {
// The external source didn't have alignment information; infer it.
InferAlignment = true;
@@ -1610,7 +1588,7 @@ void RecordLayoutBuilder::LayoutBitField
// If we're using external layout, give the external layout a chance
// to override this information.
- if (UseExternalLayout)
+ if (ExternalLayout)
FieldOffset = updateExternalFieldOffset(D, FieldOffset);
// Okay, place the bitfield at the calculated offset.
@@ -1626,7 +1604,7 @@ void RecordLayoutBuilder::LayoutBitField
FieldAlign = UnpackedFieldAlign = 1;
// Diagnose differences in layout due to padding or packing.
- if (!UseExternalLayout)
+ if (!ExternalLayout)
CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset,
UnpackedFieldAlign, FieldPacked, D);
@@ -1749,7 +1727,7 @@ void RecordLayoutBuilder::LayoutField(co
UnpackedFieldOffset =
UnpackedFieldOffset.RoundUpToAlignment(UnpackedFieldAlign);
- if (UseExternalLayout) {
+ if (ExternalLayout) {
FieldOffset = Context.toCharUnitsFromBits(
updateExternalFieldOffset(D, Context.toBits(FieldOffset)));
@@ -1772,7 +1750,7 @@ void RecordLayoutBuilder::LayoutField(co
// Place this field at the current location.
FieldOffsets.push_back(Context.toBits(FieldOffset));
- if (!UseExternalLayout)
+ if (!ExternalLayout)
CheckFieldPadding(Context.toBits(FieldOffset), UnpaddedFieldOffset,
Context.toBits(UnpackedFieldOffset),
Context.toBits(UnpackedFieldAlign), FieldPacked, D);
@@ -1824,15 +1802,15 @@ void RecordLayoutBuilder::FinishLayout(c
uint64_t RoundedSize
= llvm::RoundUpToAlignment(getSizeInBits(), Context.toBits(Alignment));
- if (UseExternalLayout) {
+ if (ExternalLayout) {
// If we're inferring alignment, and the external size is smaller than
// our size after we've rounded up to alignment, conservatively set the
// alignment to 1.
- if (InferAlignment && External.Size < RoundedSize) {
+ if (InferAlignment && ExternalSize < RoundedSize) {
Alignment = CharUnits::One();
InferAlignment = false;
}
- setSize(External.Size);
+ setSize(ExternalSize);
return;
}
@@ -1868,7 +1846,7 @@ void RecordLayoutBuilder::UpdateAlignmen
CharUnits UnpackedNewAlignment) {
// The alignment is not modified when using 'mac68k' alignment or when
// we have an externally-supplied layout that also provides overall alignment.
- if (IsMac68kAlign || (UseExternalLayout && !InferAlignment))
+ if (IsMac68kAlign || (ExternalLayout && !InferAlignment))
return;
if (NewAlignment > Alignment) {
@@ -1887,8 +1865,11 @@ void RecordLayoutBuilder::UpdateAlignmen
uint64_t
RecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field,
uint64_t ComputedOffset) {
- uint64_t ExternalFieldOffset = External.getExternalFieldOffset(Field);
-
+ assert(ExternalFieldOffsets.find(Field) != ExternalFieldOffsets.end() &&
+ "Field does not have an external offset");
+
+ uint64_t ExternalFieldOffset = ExternalFieldOffsets[Field];
+
if (InferAlignment && ExternalFieldOffset < ComputedOffset) {
// The externally-supplied field offset is before the field offset we
// computed. Assume that the structure is packed.
@@ -2270,13 +2251,6 @@ public:
/// \brief True if this class is zero sized or first base is zero sized or
/// has this property. Only used for MS-ABI.
bool LeadsWithZeroSizedBase : 1;
-
- /// \brief True if the external AST source provided a layout for this record.
- bool UseExternalLayout : 1;
-
- /// \brief The layout provided by the external AST source. Only active if
- /// UseExternalLayout is true.
- ExternalLayout External;
};
} // namespace
@@ -2396,13 +2370,6 @@ void MicrosoftRecordLayoutBuilder::initi
// Packed attribute forces max field alignment to be 1.
if (RD->hasAttr<PackedAttr>())
MaxFieldAlignment = CharUnits::One();
-
- // Try to respect the external layout if present.
- UseExternalLayout = false;
- if (ExternalASTSource *Source = Context.getExternalSource())
- UseExternalLayout = Source->layoutRecordType(
- RD, External.Size, External.Align, External.FieldOffsets,
- External.BaseOffsets, External.VirtualBaseOffsets);
}
void
@@ -2507,18 +2474,7 @@ void MicrosoftRecordLayoutBuilder::layou
BaseLayout.leadsWithZeroSizedBase())
Size++;
ElementInfo Info = getAdjustedElementInfo(BaseLayout);
- CharUnits BaseOffset;
-
- // Respect the external AST source base offset, if present.
- bool FoundBase = false;
- if (UseExternalLayout) {
- FoundBase = External.getExternalNVBaseOffset(BaseDecl, BaseOffset);
- if (FoundBase)
- assert(BaseOffset >= Size && "base offset already allocated");
- }
-
- if (!FoundBase)
- BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
+ CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
Bases.insert(std::make_pair(BaseDecl, BaseOffset));
Size = BaseOffset + BaseLayout.getNonVirtualSize();
PreviousBaseLayout = &BaseLayout;
@@ -2542,14 +2498,7 @@ void MicrosoftRecordLayoutBuilder::layou
placeFieldAtOffset(CharUnits::Zero());
Size = std::max(Size, Info.Size);
} else {
- CharUnits FieldOffset;
- if (UseExternalLayout) {
- FieldOffset =
- Context.toCharUnitsFromBits(External.getExternalFieldOffset(FD));
- assert(FieldOffset >= Size && "field offset already allocated");
- } else {
- FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
- }
+ CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
placeFieldAtOffset(FieldOffset);
Size = FieldOffset + Info.Size;
}
@@ -2623,16 +2572,14 @@ void MicrosoftRecordLayoutBuilder::injec
CharUnits InjectionSite = VBPtrOffset;
// But before we do, make sure it's properly aligned.
VBPtrOffset = VBPtrOffset.RoundUpToAlignment(PointerInfo.Alignment);
- // Shift everything after the vbptr down, unless we're using an external
- // layout.
- if (UseExternalLayout)
- return;
// Determine where the first field should be laid out after the vbptr.
CharUnits FieldStart = VBPtrOffset + PointerInfo.Size;
// Make sure that the amount we push the fields back by is a multiple of the
// alignment.
CharUnits Offset = (FieldStart - InjectionSite).RoundUpToAlignment(
std::max(RequiredAlignment, Alignment));
+ // Increase the size of the object and push back all fields by the offset
+ // amount.
Size += Offset;
for (uint64_t &FieldOffset : FieldOffsets)
FieldOffset += Context.toBits(Offset);
@@ -2699,18 +2646,7 @@ void MicrosoftRecordLayoutBuilder::layou
}
// Insert the virtual base.
ElementInfo Info = getAdjustedElementInfo(BaseLayout);
- CharUnits BaseOffset;
-
- // Respect the external AST source base offset, if present.
- bool FoundBase = false;
- if (UseExternalLayout) {
- FoundBase = External.getExternalVBaseOffset(BaseDecl, BaseOffset);
- if (FoundBase)
- assert(BaseOffset >= Size && "base offset already allocated");
- }
- if (!FoundBase)
- BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
-
+ CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
VBases.insert(std::make_pair(BaseDecl,
ASTRecordLayout::VBaseInfo(BaseOffset, HasVtordisp)));
Size = BaseOffset + BaseLayout.getNonVirtualSize();
@@ -2740,12 +2676,6 @@ void MicrosoftRecordLayoutBuilder::final
else
Size = MinEmptyStructSize;
}
-
- if (UseExternalLayout) {
- Size = Context.toCharUnitsFromBits(External.Size);
- if (External.Align)
- Alignment = Context.toCharUnitsFromBits(External.Align);
- }
}
// Recursively walks the non-virtual bases of a class and determines if any of
@@ -2884,7 +2814,7 @@ ASTContext::getASTRecordLayout(const Rec
const ASTRecordLayout *NewEntry = nullptr;
- if (isMsLayout(D)) {
+ if (isMsLayout(D) && !D->getASTContext().getExternalSource()) {
NewEntry = BuildMicrosoftASTRecordLayout(D);
} else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
EmptySubobjectMap EmptySubobjects(*this, RD);
Modified: cfe/trunk/test/CodeGenCXX/override-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/override-layout.cpp?rev=230474&r1=230473&r2=230474&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/override-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/override-layout.cpp Wed Feb 25 04:32:13 2015
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.layouts
-// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.before
-// RUN: %clang_cc1 -w -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after
+// RUN: %clang_cc1 -fdump-record-layouts-simple %s > %t.layouts
+// RUN: %clang_cc1 -fdump-record-layouts-simple %s > %t.before
+// RUN: %clang_cc1 -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after
// RUN: diff -u %t.before %t.after
// RUN: FileCheck %s < %t.after
More information about the cfe-commits
mailing list