Author: majnemer Date: Sat Jul 25 15:18:14 2015 New Revision: 243225 URL: http://llvm.org/viewvc/llvm-project?rev=243225&view=rev Log: [AST] Rename RecordLayoutBuilder to ItaniumRecordLayoutBuilder
RecordLayoutBuilder is an inaccruate name because it does not build all records. It only builds layouts for targets using the Itanium C++ ABI. Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=243225&r1=243224&r2=243225&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Sat Jul 25 15:18:14 2015 @@ -1774,7 +1774,6 @@ public: /// record (struct/union/class) \p D, which indicates its size and field /// position information. const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; - const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const; /// \brief Get or compute information about the layout of the specified /// Objective-C interface. Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=243225&r1=243224&r2=243225&view=diff ============================================================================== --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original) +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Sat Jul 25 15:18:14 2015 @@ -564,7 +564,7 @@ void EmptySubobjectMap::UpdateEmptyField typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> ClassSetTy; -class RecordLayoutBuilder { +class ItaniumRecordLayoutBuilder { protected: // FIXME: Remove this and make the appropriate fields public. friend class clang::ASTContext; @@ -655,19 +655,18 @@ protected: /// Valid if UseExternalLayout is true. ExternalLayout External; - RecordLayoutBuilder(const ASTContext &Context, - EmptySubobjectMap *EmptySubobjects) - : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), - Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()), - UseExternalLayout(false), InferAlignment(false), - Packed(false), IsUnion(false), IsMac68kAlign(false), IsMsStruct(false), - UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0), - MaxFieldAlignment(CharUnits::Zero()), - DataSize(0), NonVirtualSize(CharUnits::Zero()), - NonVirtualAlignment(CharUnits::One()), - PrimaryBase(nullptr), PrimaryBaseIsVirtual(false), - HasOwnVFPtr(false), - FirstNearlyEmptyVBase(nullptr) {} + ItaniumRecordLayoutBuilder(const ASTContext &Context, + EmptySubobjectMap *EmptySubobjects) + : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), + Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()), + UseExternalLayout(false), InferAlignment(false), Packed(false), + IsUnion(false), IsMac68kAlign(false), IsMsStruct(false), + UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0), + MaxFieldAlignment(CharUnits::Zero()), DataSize(0), + NonVirtualSize(CharUnits::Zero()), + NonVirtualAlignment(CharUnits::One()), PrimaryBase(nullptr), + PrimaryBaseIsVirtual(false), HasOwnVFPtr(false), + FirstNearlyEmptyVBase(nullptr) {} void Layout(const RecordDecl *D); void Layout(const CXXRecordDecl *D); @@ -781,13 +780,12 @@ protected: void setDataSize(CharUnits NewSize) { DataSize = Context.toBits(NewSize); } void setDataSize(uint64_t NewSize) { DataSize = NewSize; } - RecordLayoutBuilder(const RecordLayoutBuilder &) = delete; - void operator=(const RecordLayoutBuilder &) = delete; + ItaniumRecordLayoutBuilder(const ItaniumRecordLayoutBuilder &) = delete; + void operator=(const ItaniumRecordLayoutBuilder &) = delete; }; } // end anonymous namespace -void -RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { +void ItaniumRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { for (const auto &I : RD->bases()) { assert(!I.getType()->isDependentType() && "Cannot layout class with dependent bases."); @@ -816,7 +814,7 @@ RecordLayoutBuilder::SelectPrimaryVBase( } /// DeterminePrimaryBase - Determine the primary base of the given class. -void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { +void ItaniumRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { // If the class isn't dynamic, it won't have a primary base. if (!RD->isDynamicClass()) return; @@ -863,10 +861,8 @@ void RecordLayoutBuilder::DeterminePrima assert(!PrimaryBase && "Should not get here with a primary base!"); } -BaseSubobjectInfo * -RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, - bool IsVirtual, - BaseSubobjectInfo *Derived) { +BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo( + const CXXRecordDecl *RD, bool IsVirtual, BaseSubobjectInfo *Derived) { BaseSubobjectInfo *Info; if (IsVirtual) { @@ -942,7 +938,8 @@ RecordLayoutBuilder::ComputeBaseSubobjec return Info; } -void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) { +void ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo( + const CXXRecordDecl *RD) { for (const auto &I : RD->bases()) { bool IsVirtual = I.isVirtual(); @@ -965,8 +962,8 @@ void RecordLayoutBuilder::ComputeBaseSub } } -void -RecordLayoutBuilder::EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign) { +void ItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment( + CharUnits UnpackedBaseAlign) { CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign; // The maximum field alignment overrides base align. @@ -983,8 +980,8 @@ RecordLayoutBuilder::EnsureVTablePointer UpdateAlignment(BaseAlign, UnpackedBaseAlign); } -void -RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { +void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases( + const CXXRecordDecl *RD) { // Then, determine the primary base class. DeterminePrimaryBase(RD); @@ -1053,7 +1050,8 @@ RecordLayoutBuilder::LayoutNonVirtualBas } } -void RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) { +void ItaniumRecordLayoutBuilder::LayoutNonVirtualBase( + const BaseSubobjectInfo *Base) { // Layout the base. CharUnits Offset = LayoutBase(Base); @@ -1064,9 +1062,8 @@ void RecordLayoutBuilder::LayoutNonVirtu AddPrimaryVirtualBaseOffsets(Base, Offset); } -void -RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, - CharUnits Offset) { +void ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets( + const BaseSubobjectInfo *Info, CharUnits Offset) { // This base isn't interesting, it has no virtual bases. if (!Info->Class->getNumVBases()) return; @@ -1098,9 +1095,8 @@ RecordLayoutBuilder::AddPrimaryVirtualBa } } -void -RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, - const CXXRecordDecl *MostDerivedClass) { +void ItaniumRecordLayoutBuilder::LayoutVirtualBases( + const CXXRecordDecl *RD, const CXXRecordDecl *MostDerivedClass) { const CXXRecordDecl *PrimaryBase; bool PrimaryBaseIsVirtual; @@ -1145,7 +1141,8 @@ RecordLayoutBuilder::LayoutVirtualBases( } } -void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) { +void ItaniumRecordLayoutBuilder::LayoutVirtualBase( + const BaseSubobjectInfo *Base) { assert(!Base->Derived && "Trying to lay out a primary virtual base!"); // Layout the base. @@ -1159,7 +1156,8 @@ void RecordLayoutBuilder::LayoutVirtualB AddPrimaryVirtualBaseOffsets(Base, Offset); } -CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { +CharUnits +ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class); @@ -1228,7 +1226,7 @@ CharUnits RecordLayoutBuilder::LayoutBas return Offset; } -void RecordLayoutBuilder::InitializeLayout(const Decl *D) { +void ItaniumRecordLayoutBuilder::InitializeLayout(const Decl *D) { if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) { IsUnion = RD->isUnion(); IsMsStruct = RD->isMsStruct(Context); @@ -1276,7 +1274,7 @@ void RecordLayoutBuilder::InitializeLayo } } -void RecordLayoutBuilder::Layout(const RecordDecl *D) { +void ItaniumRecordLayoutBuilder::Layout(const RecordDecl *D) { InitializeLayout(D); LayoutFields(D); @@ -1285,7 +1283,7 @@ void RecordLayoutBuilder::Layout(const R FinishLayout(D); } -void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { +void ItaniumRecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { InitializeLayout(RD); // Lay out the vtable and the non-virtual bases. @@ -1325,7 +1323,7 @@ void RecordLayoutBuilder::Layout(const C #endif } -void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) { +void ItaniumRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) { if (ObjCInterfaceDecl *SD = D->getSuperClass()) { const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD); @@ -1348,7 +1346,7 @@ void RecordLayoutBuilder::Layout(const O FinishLayout(D); } -void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) { +void ItaniumRecordLayoutBuilder::LayoutFields(const RecordDecl *D) { // Layout each field, for now, just sequentially, respecting alignment. In // the future, this will need to be tweakable by targets. bool InsertExtraPadding = D->mayInsertExtraPadding(/*EmitRemark=*/true); @@ -1369,10 +1367,10 @@ roundUpSizeToCharAlignment(uint64_t Size return llvm::RoundUpToAlignment(Size, CharAlignment); } -void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, - uint64_t TypeSize, - bool FieldPacked, - const FieldDecl *D) { +void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, + uint64_t TypeSize, + bool FieldPacked, + const FieldDecl *D) { assert(Context.getLangOpts().CPlusPlus && "Can only have wide bit-fields in C++!"); @@ -1436,7 +1434,7 @@ void RecordLayoutBuilder::LayoutWideBitF UpdateAlignment(TypeAlign); } -void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { +void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); uint64_t FieldSize = D->getBitWidthValue(Context); TypeInfo FieldInfo = Context.getTypeInfo(D->getType()); @@ -1671,8 +1669,8 @@ void RecordLayoutBuilder::LayoutBitField Context.toCharUnitsFromBits(UnpackedFieldAlign)); } -void RecordLayoutBuilder::LayoutField(const FieldDecl *D, - bool InsertExtraPadding) { +void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, + bool InsertExtraPadding) { if (D->isBitField()) { LayoutBitField(D); return; @@ -1799,7 +1797,7 @@ void RecordLayoutBuilder::LayoutField(co UpdateAlignment(FieldAlign, UnpackedFieldAlign); } -void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) { +void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) { // In C++, records cannot be of size 0. if (Context.getLangOpts().CPlusPlus && getSizeInBits() == 0) { if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { @@ -1863,8 +1861,8 @@ void RecordLayoutBuilder::FinishLayout(c } } -void RecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment, - CharUnits UnpackedNewAlignment) { +void ItaniumRecordLayoutBuilder::UpdateAlignment( + CharUnits NewAlignment, 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)) @@ -1884,8 +1882,8 @@ void RecordLayoutBuilder::UpdateAlignmen } uint64_t -RecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field, - uint64_t ComputedOffset) { +ItaniumRecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field, + uint64_t ComputedOffset) { uint64_t ExternalFieldOffset = External.getExternalFieldOffset(Field); if (InferAlignment && ExternalFieldOffset < ComputedOffset) { @@ -1913,12 +1911,9 @@ static unsigned getPaddingDiagFromTagKin } } -void RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset, - uint64_t UnpaddedOffset, - uint64_t UnpackedOffset, - unsigned UnpackedAlign, - bool isPacked, - const FieldDecl *D) { +void ItaniumRecordLayoutBuilder::CheckFieldPadding( + uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset, + unsigned UnpackedAlign, bool isPacked, const FieldDecl *D) { // We let objc ivars without warning, objc interfaces generally are not used // for padding tricks. if (isa<ObjCIvarDecl>(D)) @@ -2020,8 +2015,8 @@ static const CXXMethodDecl *computeKeyFu return nullptr; } -DiagnosticBuilder -RecordLayoutBuilder::Diag(SourceLocation Loc, unsigned DiagID) { +DiagnosticBuilder ItaniumRecordLayoutBuilder::Diag(SourceLocation Loc, + unsigned DiagID) { return Context.getDiagnostics().Report(Loc, DiagID); } @@ -2067,8 +2062,8 @@ static bool mustSkipTailPadding(TargetCX llvm_unreachable("bad tail-padding use kind"); } -static bool isMsLayout(const RecordDecl* D) { - return D->getASTContext().getTargetInfo().getCXXABI().isMicrosoft(); +static bool isMsLayout(const ASTContext &Context) { + return Context.getTargetInfo().getCXXABI().isMicrosoft(); } // This section contains an implementation of struct layout that is, up to the @@ -2833,32 +2828,6 @@ void MicrosoftRecordLayoutBuilder::compu } } -/// \brief Get or compute information about the layout of the specified record -/// (struct/union/class), which indicates its size and field position -/// information. -const ASTRecordLayout * -ASTContext::BuildMicrosoftASTRecordLayout(const RecordDecl *D) const { - MicrosoftRecordLayoutBuilder Builder(*this); - if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { - Builder.cxxLayout(RD); - return new (*this) ASTRecordLayout( - *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, - Builder.HasOwnVFPtr, - Builder.HasOwnVFPtr || Builder.PrimaryBase, - Builder.VBPtrOffset, Builder.NonVirtualSize, Builder.FieldOffsets.data(), - Builder.FieldOffsets.size(), Builder.NonVirtualSize, - Builder.Alignment, CharUnits::Zero(), Builder.PrimaryBase, - false, Builder.SharedVBPtrBase, - Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase, - Builder.Bases, Builder.VBases); - } else { - Builder.layout(D); - return new (*this) ASTRecordLayout( - *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, - Builder.Size, Builder.FieldOffsets.data(), Builder.FieldOffsets.size()); - } -} - /// getASTRecordLayout - Get or compute information about the layout of the /// specified record (struct/union/class), which indicates its size and field /// position information. @@ -2885,54 +2854,63 @@ ASTContext::getASTRecordLayout(const Rec const ASTRecordLayout *NewEntry = nullptr; - if (isMsLayout(D)) { - NewEntry = BuildMicrosoftASTRecordLayout(D); - } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { - EmptySubobjectMap EmptySubobjects(*this, RD); - RecordLayoutBuilder Builder(*this, &EmptySubobjects); - Builder.Layout(RD); - - // In certain situations, we are allowed to lay out objects in the - // tail-padding of base classes. This is ABI-dependent. - // FIXME: this should be stored in the record layout. - bool skipTailPadding = - mustSkipTailPadding(getTargetInfo().getCXXABI(), cast<CXXRecordDecl>(D)); - - // FIXME: This should be done in FinalizeLayout. - CharUnits DataSize = - skipTailPadding ? Builder.getSize() : Builder.getDataSize(); - CharUnits NonVirtualSize = - skipTailPadding ? DataSize : Builder.NonVirtualSize; - NewEntry = - new (*this) ASTRecordLayout(*this, Builder.getSize(), - Builder.Alignment, - /*RequiredAlignment : used by MS-ABI)*/ - Builder.Alignment, - Builder.HasOwnVFPtr, - RD->isDynamicClass(), - CharUnits::fromQuantity(-1), - DataSize, - Builder.FieldOffsets.data(), - Builder.FieldOffsets.size(), - NonVirtualSize, - Builder.NonVirtualAlignment, - EmptySubobjects.SizeOfLargestEmptySubobject, - Builder.PrimaryBase, - Builder.PrimaryBaseIsVirtual, - nullptr, false, false, - Builder.Bases, Builder.VBases); + if (isMsLayout(*this)) { + MicrosoftRecordLayoutBuilder Builder(*this); + if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { + Builder.cxxLayout(RD); + NewEntry = new (*this) ASTRecordLayout( + *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, + Builder.HasOwnVFPtr, Builder.HasOwnVFPtr || Builder.PrimaryBase, + Builder.VBPtrOffset, Builder.NonVirtualSize, + Builder.FieldOffsets.data(), Builder.FieldOffsets.size(), + Builder.NonVirtualSize, Builder.Alignment, CharUnits::Zero(), + Builder.PrimaryBase, false, Builder.SharedVBPtrBase, + Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase, + Builder.Bases, Builder.VBases); + } else { + Builder.layout(D); + NewEntry = new (*this) ASTRecordLayout( + *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, + Builder.Size, Builder.FieldOffsets.data(), + Builder.FieldOffsets.size()); + } } else { - RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr); - Builder.Layout(D); + if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { + EmptySubobjectMap EmptySubobjects(*this, RD); + ItaniumRecordLayoutBuilder Builder(*this, &EmptySubobjects); + Builder.Layout(RD); + + // In certain situations, we are allowed to lay out objects in the + // tail-padding of base classes. This is ABI-dependent. + // FIXME: this should be stored in the record layout. + bool skipTailPadding = + mustSkipTailPadding(getTargetInfo().getCXXABI(), RD); + + // FIXME: This should be done in FinalizeLayout. + CharUnits DataSize = + skipTailPadding ? Builder.getSize() : Builder.getDataSize(); + CharUnits NonVirtualSize = + skipTailPadding ? DataSize : Builder.NonVirtualSize; + NewEntry = new (*this) ASTRecordLayout( + *this, Builder.getSize(), Builder.Alignment, + /*RequiredAlignment : used by MS-ABI)*/ + Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(), + CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets.data(), + Builder.FieldOffsets.size(), NonVirtualSize, + Builder.NonVirtualAlignment, + EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase, + Builder.PrimaryBaseIsVirtual, nullptr, false, false, Builder.Bases, + Builder.VBases); + } else { + ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr); + Builder.Layout(D); - NewEntry = - new (*this) ASTRecordLayout(*this, Builder.getSize(), - Builder.Alignment, - /*RequiredAlignment : used by MS-ABI)*/ - Builder.Alignment, - Builder.getSize(), - Builder.FieldOffsets.data(), - Builder.FieldOffsets.size()); + NewEntry = new (*this) ASTRecordLayout( + *this, Builder.getSize(), Builder.Alignment, + /*RequiredAlignment : used by MS-ABI)*/ + Builder.Alignment, Builder.getSize(), Builder.FieldOffsets.data(), + Builder.FieldOffsets.size()); + } } ASTRecordLayouts[D] = NewEntry; @@ -3042,7 +3020,7 @@ ASTContext::getObjCLayout(const ObjCInte return getObjCLayout(D, nullptr); } - RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr); + ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr); Builder.Layout(D); const ASTRecordLayout *NewEntry = @@ -3093,7 +3071,7 @@ static void DumpCXXRecordLayout(raw_ostr bool HasOwnVBPtr = Layout.hasOwnVBPtr(); // Vtable pointer. - if (RD->isDynamicClass() && !PrimaryBase && !isMsLayout(RD)) { + if (RD->isDynamicClass() && !PrimaryBase && !isMsLayout(C)) { PrintOffset(OS, Offset, IndentLevel); OS << '(' << *RD << " vtable pointer)\n"; } else if (HasOwnVFPtr) { @@ -3175,7 +3153,7 @@ static void DumpCXXRecordLayout(raw_ostr PrintIndentNoOffset(OS, IndentLevel - 1); OS << "[sizeof=" << Layout.getSize().getQuantity(); - if (!isMsLayout(RD)) + if (!isMsLayout(C)) OS << ", dsize=" << Layout.getDataSize().getQuantity(); OS << ", align=" << Layout.getAlignment().getQuantity() << '\n'; @@ -3202,7 +3180,7 @@ void ASTContext::DumpRecordLayout(const OS << "\nLayout: "; OS << "<ASTRecordLayout\n"; OS << " Size:" << toBits(Info.getSize()) << "\n"; - if (!isMsLayout(RD)) + if (!isMsLayout(*this)) OS << " DataSize:" << toBits(Info.getDataSize()) << "\n"; OS << " Alignment:" << toBits(Info.getAlignment()) << "\n"; OS << " FieldOffsets: ["; _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits