summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGRecordLayout.h
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-02-15 06:40:56 +0000
committerJohn McCall <rjmccall@apple.com>2011-02-15 06:40:56 +0000
commit0217dfc2bab62042cf046534faa61cfaff30a155 (patch)
tree8b681e9eba05479d6231e4bb387fcc0d03ac8fe6 /clang/lib/CodeGen/CGRecordLayout.h
parent98196b4ebb2a7048169832701acd7ca7852834b7 (diff)
downloadbcm5719-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.h71
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;
}
OpenPOWER on IntegriCloud