[cfe-commits] r119980 - /cfe/trunk/lib/CodeGen/CGExprConstant.cpp
Anders Carlsson
andersca at mac.com
Mon Nov 22 10:42:14 PST 2010
Author: andersca
Date: Mon Nov 22 12:42:14 2010
New Revision: 119980
URL: http://llvm.org/viewvc/llvm-project?rev=119980&view=rev
Log:
Refactor the null-initialization for record types and make it handle bases that aren't i8 arrays.
Modified:
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=119980&r1=119979&r2=119980&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Mon Nov 22 12:42:14 2010
@@ -964,8 +964,7 @@
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
E = RD->bases_end(); I != E; ++I) {
if (I->isVirtual()) {
- // FIXME: We should initialize null pointer to data members in virtual
- // bases here.
+ // Ignore virtual bases.
continue;
}
@@ -1015,6 +1014,89 @@
}
}
+static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
+ const CXXRecordDecl *RD) {
+ QualType T = CGM.getContext().getTagDeclType(RD);
+
+ const llvm::StructType *STy =
+ cast<llvm::StructType>(CGM.getTypes().ConvertTypeForMem(T));
+ unsigned NumElements = STy->getNumElements();
+ std::vector<llvm::Constant *> Elements(NumElements);
+
+ const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD);
+
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ if (I->isVirtual()) {
+ // Ignore virtual bases.
+ continue;
+ }
+
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ // Ignore empty bases.
+ if (BaseDecl->isEmpty())
+ continue;
+
+ // Ignore bases that don't have any pointer to data members.
+ if (CGM.getTypes().isZeroInitializable(BaseDecl))
+ continue;
+
+ unsigned BaseFieldNo = Layout.getNonVirtualBaseLLVMFieldNo(BaseDecl);
+ const llvm::Type *BaseTy = STy->getElementType(BaseFieldNo);
+
+ if (isa<llvm::StructType>(BaseTy)) {
+ // We can just emit the base as a null constant.
+ Elements[BaseFieldNo] = EmitNullConstant(CGM, BaseDecl);
+ continue;
+ }
+
+ // Some bases are represented as arrays of i8 if the size of the
+ // base is smaller than its corresponding LLVM type.
+ // Figure out how many elements this base array has.
+ const llvm::ArrayType *BaseArrayTy = cast<llvm::ArrayType>(BaseTy);
+ unsigned NumBaseElements = BaseArrayTy->getNumElements();
+
+ // Fill in null data member pointers.
+ std::vector<llvm::Constant *> BaseElements(NumBaseElements);
+ FillInNullDataMemberPointers(CGM, I->getType(), BaseElements, 0);
+
+ // Now go through all other elements and zero them out.
+ if (NumBaseElements) {
+ const llvm::Type* Int8Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+ llvm::Constant *Zero = llvm::Constant::getNullValue(Int8Ty);
+ for (unsigned I = 0; I != NumBaseElements; ++I) {
+ if (!BaseElements[I])
+ BaseElements[I] = Zero;
+ }
+ }
+
+ Elements[BaseFieldNo] = llvm::ConstantArray::get(BaseArrayTy, BaseElements);
+ }
+
+ // Visit all fields.
+ for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+ I != E; ++I) {
+ const FieldDecl *FD = *I;
+
+ // Ignore bit fields.
+ if (FD->isBitField())
+ continue;
+
+ unsigned FieldNo = Layout.getLLVMFieldNo(FD);
+ Elements[FieldNo] = CGM.EmitNullConstant(FD->getType());
+ }
+
+ // Now go through all other fields and zero them out.
+ for (unsigned i = 0; i != NumElements; ++i) {
+ if (!Elements[i])
+ Elements[i] = llvm::Constant::getNullValue(STy->getElementType(i));
+ }
+
+ return llvm::ConstantStruct::get(STy, Elements);
+}
+
llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
if (getTypes().isZeroInitializable(T))
return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
@@ -1036,79 +1118,7 @@
if (const RecordType *RT = T->getAs<RecordType>()) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- const llvm::StructType *STy =
- cast<llvm::StructType>(getTypes().ConvertTypeForMem(T));
- unsigned NumElements = STy->getNumElements();
- std::vector<llvm::Constant *> Elements(NumElements);
-
- const CGRecordLayout &Layout = getTypes().getCGRecordLayout(RD);
-
- // Go through all bases and fill in any null pointer to data members.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- if (I->isVirtual()) {
- // FIXME: We should initialize null pointer to data members in virtual
- // bases here.
- continue;
- }
-
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
- // Ignore empty bases.
- if (BaseDecl->isEmpty())
- continue;
-
- // Ignore bases that don't have any pointer to data members.
- if (getTypes().isZeroInitializable(BaseDecl))
- continue;
-
- // Currently, all bases are arrays of i8. Figure out how many elements
- // this base array has.
- unsigned BaseFieldNo = Layout.getNonVirtualBaseLLVMFieldNo(BaseDecl);
- const llvm::ArrayType *BaseArrayTy =
- cast<llvm::ArrayType>(STy->getElementType(BaseFieldNo));
-
- unsigned NumBaseElements = BaseArrayTy->getNumElements();
- std::vector<llvm::Constant *> BaseElements(NumBaseElements);
-
- // Now fill in null data member pointers.
- FillInNullDataMemberPointers(*this, I->getType(), BaseElements, 0);
-
- // Now go through all other elements and zero them out.
- if (NumBaseElements) {
- llvm::Constant *Zero =
- llvm::ConstantInt::get(llvm::Type::getInt8Ty(getLLVMContext()), 0);
-
- for (unsigned I = 0; I != NumBaseElements; ++I) {
- if (!BaseElements[I])
- BaseElements[I] = Zero;
- }
- }
-
- Elements[BaseFieldNo] = llvm::ConstantArray::get(BaseArrayTy,
- BaseElements);
- }
-
- for (RecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end(); I != E; ++I) {
- const FieldDecl *FD = *I;
-
- // Ignore bit fields.
- if (FD->isBitField())
- continue;
-
- unsigned FieldNo = Layout.getLLVMFieldNo(FD);
- Elements[FieldNo] = EmitNullConstant(FD->getType());
- }
-
- // Now go through all other fields and zero them out.
- for (unsigned i = 0; i != NumElements; ++i) {
- if (!Elements[i])
- Elements[i] = llvm::Constant::getNullValue(STy->getElementType(i));
- }
-
- return llvm::ConstantStruct::get(STy, Elements);
+ return ::EmitNullConstant(*this, RD);
}
assert(T->isMemberPointerType() && "Should only see member pointers here!");
More information about the cfe-commits
mailing list