diff options
author | Anders Carlsson <andersca@mac.com> | 2010-11-22 18:42:14 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-11-22 18:42:14 +0000 |
commit | ada4b32749458644272d90e34e4149c307376e59 (patch) | |
tree | adfee2bb119aad7f1c677e387076d84f4914be46 /lib/CodeGen/CGExprConstant.cpp | |
parent | f27f03e215cbd7a7bdfb35a95e524c9eea8ba940 (diff) |
Refactor the null-initialization for record types and make it handle bases that aren't i8 arrays.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119980 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprConstant.cpp')
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 160 |
1 files changed, 85 insertions, 75 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 567e485899..9002253e72 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -964,8 +964,7 @@ FillInNullDataMemberPointers(CodeGenModule &CGM, QualType T, 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 @@ FillInNullDataMemberPointers(CodeGenModule &CGM, QualType T, } } +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 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) { 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!"); |