diff options
author | dim <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 |
commit | 36c49e3f258dced101949edabd72e9bc3f1dedc4 (patch) | |
tree | 0bbe07708f7571f8b5291f6d7b96c102b7c99dee /lib/CodeGen/CGRecordLayoutBuilder.cpp | |
parent | fc84956ac8b7cd244ef30e7a4d4d38a58dec5904 (diff) | |
download | FreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.zip FreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.tar.gz |
Vendor import of clang r114020 (from the release_28 branch):
http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020
Approved by: rpaulo (mentor)
Diffstat (limited to 'lib/CodeGen/CGRecordLayoutBuilder.cpp')
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 9f16875..77a319f 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -18,6 +18,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" #include "CodeGenTypes.h" +#include "CGCXXABI.h" #include "llvm/DerivedTypes.h" #include "llvm/Type.h" #include "llvm/Support/Debug.h" @@ -45,10 +46,9 @@ public: typedef std::pair<const CXXRecordDecl *, unsigned> LLVMBaseInfo; llvm::SmallVector<LLVMBaseInfo, 16> LLVMNonVirtualBases; - /// ContainsPointerToDataMember - Whether one of the fields in this record - /// layout is a pointer to data member, or a struct that contains pointer to - /// data member. - bool ContainsPointerToDataMember; + /// IsZeroInitializable - Whether this struct can be C++ + /// zero-initialized with an LLVM zeroinitializer. + bool IsZeroInitializable; /// Packed - Whether the resulting LLVM struct will be packed or not. bool Packed; @@ -115,14 +115,14 @@ private: unsigned getTypeAlignment(const llvm::Type *Ty) const; - /// CheckForPointerToDataMember - Check if the given type contains a pointer + /// CheckZeroInitializable - Check if the given type contains a pointer /// to data member. - void CheckForPointerToDataMember(QualType T); - void CheckForPointerToDataMember(const CXXRecordDecl *RD); + void CheckZeroInitializable(QualType T); + void CheckZeroInitializable(const CXXRecordDecl *RD); public: CGRecordLayoutBuilder(CodeGenTypes &Types) - : ContainsPointerToDataMember(false), Packed(false), Types(Types), + : IsZeroInitializable(true), Packed(false), Types(Types), Alignment(0), AlignmentAsLLVMStruct(1), BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { } @@ -157,15 +157,12 @@ void CGRecordLayoutBuilder::Layout(const RecordDecl *D) { LayoutFields(D); } -static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, - const FieldDecl *FD, - uint64_t FieldOffset, - uint64_t FieldSize) { - const RecordDecl *RD = FD->getParent(); - const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD); - uint64_t ContainingTypeSizeInBits = RL.getSize(); - unsigned ContainingTypeAlign = RL.getAlignment(); - +CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, + const FieldDecl *FD, + uint64_t FieldOffset, + uint64_t FieldSize, + uint64_t ContainingTypeSizeInBits, + unsigned ContainingTypeAlign) { const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(FD->getType()); uint64_t TypeSizeInBytes = Types.getTargetData().getTypeAllocSize(Ty); uint64_t TypeSizeInBits = TypeSizeInBytes * 8; @@ -255,6 +252,19 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, return CGBitFieldInfo(FieldSize, NumComponents, Components, IsSigned); } +CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, + const FieldDecl *FD, + uint64_t FieldOffset, + uint64_t FieldSize) { + const RecordDecl *RD = FD->getParent(); + const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD); + uint64_t ContainingTypeSizeInBits = RL.getSize(); + unsigned ContainingTypeAlign = RL.getAlignment(); + + return MakeInfo(Types, FD, FieldOffset, FieldSize, ContainingTypeSizeInBits, + ContainingTypeAlign); +} + void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D, uint64_t FieldOffset) { uint64_t FieldSize = @@ -287,7 +297,8 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D, // Add the bit field info. LLVMBitFields.push_back( - LLVMBitFieldInfo(D, ComputeBitFieldInfo(Types, D, FieldOffset, FieldSize))); + LLVMBitFieldInfo(D, CGBitFieldInfo::MakeInfo(Types, D, FieldOffset, + FieldSize))); AppendBytes(NumBytesToAppend); @@ -311,8 +322,7 @@ bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D, return true; } - // Check if we have a pointer to data member in this field. - CheckForPointerToDataMember(D->getType()); + CheckZeroInitializable(D->getType()); assert(FieldOffset % 8 == 0 && "FieldOffset is not on a byte boundary!"); uint64_t FieldOffsetInBytes = FieldOffset / 8; @@ -380,7 +390,8 @@ CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field, // Add the bit field info. LLVMBitFields.push_back( - LLVMBitFieldInfo(Field, ComputeBitFieldInfo(Types, Field, 0, FieldSize))); + LLVMBitFieldInfo(Field, CGBitFieldInfo::MakeInfo(Types, Field, + 0, FieldSize))); return FieldTy; } @@ -458,7 +469,7 @@ void CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl, return; } - CheckForPointerToDataMember(BaseDecl); + CheckZeroInitializable(BaseDecl); // FIXME: Actually use a better type than [sizeof(BaseDecl) x i8] when we can. AppendPadding(BaseOffset / 8, 1); @@ -603,9 +614,9 @@ unsigned CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty) const { return Types.getTargetData().getABITypeAlignment(Ty); } -void CGRecordLayoutBuilder::CheckForPointerToDataMember(QualType T) { +void CGRecordLayoutBuilder::CheckZeroInitializable(QualType T) { // This record already contains a member pointer. - if (ContainsPointerToDataMember) + if (!IsZeroInitializable) return; // Can only have member pointers if we're compiling C++. @@ -615,21 +626,17 @@ void CGRecordLayoutBuilder::CheckForPointerToDataMember(QualType T) { T = Types.getContext().getBaseElementType(T); if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) { - if (!MPT->getPointeeType()->isFunctionType()) { - // We have a pointer to data member. - ContainsPointerToDataMember = true; - } + if (!Types.getCXXABI().isZeroInitializable(MPT)) + IsZeroInitializable = false; } else if (const RecordType *RT = T->getAs<RecordType>()) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - - return CheckForPointerToDataMember(RD); + CheckZeroInitializable(RD); } } -void -CGRecordLayoutBuilder::CheckForPointerToDataMember(const CXXRecordDecl *RD) { +void CGRecordLayoutBuilder::CheckZeroInitializable(const CXXRecordDecl *RD) { // This record already contains a member pointer. - if (ContainsPointerToDataMember) + if (!IsZeroInitializable) return; // FIXME: It would be better if there was a way to explicitly compute the @@ -638,8 +645,8 @@ CGRecordLayoutBuilder::CheckForPointerToDataMember(const CXXRecordDecl *RD) { const CGRecordLayout &Layout = Types.getCGRecordLayout(RD); - if (Layout.containsPointerToDataMember()) - ContainsPointerToDataMember = true; + if (!Layout.isZeroInitializable()) + IsZeroInitializable = false; } CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) { @@ -652,7 +659,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) { Builder.Packed); CGRecordLayout *RL = - new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember); + new CGRecordLayout(Ty, Builder.IsZeroInitializable); // Add all the non-virtual base field numbers. RL->NonVirtualBaseFields.insert(Builder.LLVMNonVirtualBases.begin(), @@ -723,7 +730,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) { void CGRecordLayout::print(llvm::raw_ostream &OS) const { OS << "<CGRecordLayout\n"; OS << " LLVMType:" << *LLVMType << "\n"; - OS << " ContainsPointerToDataMember:" << ContainsPointerToDataMember << "\n"; + OS << " IsZeroInitializable:" << IsZeroInitializable << "\n"; OS << " BitFields:[\n"; // Print bit-field infos in declaration order. |