diff options
author | John McCall <rjmccall@apple.com> | 2011-02-15 06:40:56 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-02-15 06:40:56 +0000 |
commit | 0217dfc2bab62042cf046534faa61cfaff30a155 (patch) | |
tree | 8b681e9eba05479d6231e4bb387fcc0d03ac8fe6 /clang/lib/CodeGen/CGRecordLayout.h | |
parent | 98196b4ebb2a7048169832701acd7ca7852834b7 (diff) | |
download | bcm5719-llvm-0217dfc2bab62042cf046534faa61cfaff30a155.tar.gz bcm5719-llvm-0217dfc2bab62042cf046534faa61cfaff30a155.zip |
Perform zero-initialization of virtual base classes when emitting
a zero constant for a complete class. rdar://problem/8424975
To make this happen, track the field indexes for virtual bases
in the complete object. I'm curious whether we might be better
off making CGRecordLayoutBuilder *much* more reliant on
ASTRecordLayout; we're currently duplicating an awful lot of the ABI
layout logic.
llvm-svn: 125555
Diffstat (limited to 'clang/lib/CodeGen/CGRecordLayout.h')
-rw-r--r-- | clang/lib/CodeGen/CGRecordLayout.h | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayout.h b/clang/lib/CodeGen/CGRecordLayout.h index 2a7aa359659..30da05f421f 100644 --- a/clang/lib/CodeGen/CGRecordLayout.h +++ b/clang/lib/CodeGen/CGRecordLayout.h @@ -173,12 +173,13 @@ class CGRecordLayout { void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT private: - /// The LLVM type corresponding to this record layout. - llvm::PATypeHolder LLVMType; + /// The LLVM type corresponding to this record layout; used when + /// laying it out as a complete object. + llvm::PATypeHolder CompleteObjectType; - /// The LLVM type for the non-virtual part of this record layout, used for - /// laying out the record as a base. - llvm::PATypeHolder NonVirtualBaseLLVMType; + /// The LLVM type for the non-virtual part of this record layout; + /// used when laying it out as a base subobject. + llvm::PATypeHolder BaseSubobjectType; /// Map from (non-bit-field) struct field to the corresponding llvm struct /// type field no. This info is populated by record builder. @@ -190,26 +191,41 @@ private: // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single // map for both virtual and non virtual bases. - llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBaseFields; + llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases; - /// Whether one of the fields in this record layout is a pointer to data - /// member, or a struct that contains pointer to data member. + /// Map from virtual bases to their field index in the complete object. + llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases; + + /// False if any direct or indirect subobject of this class, when + /// considered as a complete object, requires a non-zero bitpattern + /// when zero-initialized. bool IsZeroInitializable : 1; -public: - CGRecordLayout(const llvm::StructType *LLVMType, - const llvm::StructType *NonVirtualBaseLLVMType, - bool IsZeroInitializable) - : LLVMType(LLVMType), NonVirtualBaseLLVMType(NonVirtualBaseLLVMType), - IsZeroInitializable(IsZeroInitializable) {} + /// False if any direct or indirect subobject of this class, when + /// considered as a base subobject, requires a non-zero bitpattern + /// when zero-initialized. + bool IsZeroInitializableAsBase : 1; - /// \brief Return the LLVM type associated with this record. +public: + CGRecordLayout(const llvm::StructType *CompleteObjectType, + const llvm::StructType *BaseSubobjectType, + bool IsZeroInitializable, + bool IsZeroInitializableAsBase) + : CompleteObjectType(CompleteObjectType), + BaseSubobjectType(BaseSubobjectType), + IsZeroInitializable(IsZeroInitializable), + IsZeroInitializableAsBase(IsZeroInitializableAsBase) {} + + /// \brief Return the "complete object" LLVM type associated with + /// this record. const llvm::StructType *getLLVMType() const { - return cast<llvm::StructType>(LLVMType.get()); + return cast<llvm::StructType>(CompleteObjectType.get()); } - const llvm::StructType *getNonVirtualBaseLLVMType() const { - return cast<llvm::StructType>(NonVirtualBaseLLVMType.get()); + /// \brief Return the "base subobject" LLVM type associated with + /// this record. + const llvm::StructType *getBaseSubobjectLLVMType() const { + return cast<llvm::StructType>(BaseSubobjectType.get()); } /// \brief Check whether this struct can be C++ zero-initialized @@ -218,6 +234,12 @@ public: return IsZeroInitializable; } + /// \brief Check whether this struct can be C++ zero-initialized + /// with a zeroinitializer when considered as a base subobject. + bool isZeroInitializableAsBase() const { + return IsZeroInitializableAsBase; + } + /// \brief Return llvm::StructType element number that corresponds to the /// field FD. unsigned getLLVMFieldNo(const FieldDecl *FD) const { @@ -227,8 +249,15 @@ public: } unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const { - assert(NonVirtualBaseFields.count(RD) && "Invalid non-virtual base!"); - return NonVirtualBaseFields.lookup(RD); + assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!"); + return NonVirtualBases.lookup(RD); + } + + /// \brief Return the LLVM field index corresponding to the given + /// virtual base. Only valid when operating on the complete object. + unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const { + assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!"); + return CompleteObjectVirtualBases.lookup(base); } /// \brief Return the BitFieldInfo that corresponds to the field FD. @@ -236,7 +265,7 @@ public: assert(FD->isBitField() && "Invalid call for non bit-field decl!"); llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator it = BitFields.find(FD); - assert(it != BitFields.end() && "Unable to find bitfield info"); + assert(it != BitFields.end() && "Unable to find bitfield info"); return it->second; } |