From: Eli Friedman Date: Tue, 20 May 2008 00:11:07 +0000 (+0000) Subject: Restructure constant structure init codegen so that it's possible to X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=017cbdfd5417d4d31ae6406421276f90269f75e2;p=clang Restructure constant structure init codegen so that it's possible to implement bitfield codegen (although I don't envy the person who implements it). This also prevents a crash on code like that from PR2309 (it's still broken, but it fails more gracefully). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51285 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index d495cd38be..a0484bc35e 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -91,7 +91,6 @@ public: // Copy initializer elements. unsigned i = 0; for (; i < NumInitableElts; ++i) { - llvm::Constant *C = Visit(ILE->getInit(i)); assert (C && "Failed to create initializer expression"); Elts.push_back(C); @@ -107,42 +106,35 @@ public: llvm::Constant *EmitStructInitialization(InitListExpr *ILE, const llvm::StructType *SType) { - TagDecl *TD = ILE->getType()->getAsRecordType()->getDecl(); + RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl(); std::vector Elts; - const CGRecordLayout *CGR = CGM.getTypes().getCGRecordLayout(TD); - unsigned NumInitElements = ILE->getNumInits(); - unsigned NumElements = SType->getNumElements(); - - // Initialising an structure requires us to automatically - // initialise any elements that have not been initialised explicitly - unsigned NumInitableElts = std::min(NumInitElements, NumElements); + + // Initialize the whole structure to zero. + for (unsigned i = 0; i < SType->getNumElements(); ++i) { + const llvm::Type *FieldTy = SType->getElementType(i); + Elts.push_back(llvm::Constant::getNullValue(FieldTy)); + } // Copy initializer elements. Skip padding fields. unsigned EltNo = 0; // Element no in ILE - unsigned FieldNo = 0; // Field no in SType - while (EltNo < NumInitableElts) { - - // Zero initialize padding field. - if (CGR->isPaddingField(FieldNo)) { - const llvm::Type *FieldTy = SType->getElementType(FieldNo); - Elts.push_back(llvm::Constant::getNullValue(FieldTy)); - FieldNo++; + int FieldNo = 0; // Field no in RecordDecl + while (EltNo < ILE->getNumInits() && FieldNo < RD->getNumMembers()) { + FieldDecl* curField = RD->getMember(FieldNo); + FieldNo++; + if (!curField->getIdentifier()) continue; - } - + llvm::Constant *C = Visit(ILE->getInit(EltNo)); assert (C && "Failed to create initializer expression"); - Elts.push_back(C); + + if (curField->isBitField()) { + CGM.WarnUnsupported(ILE->getInit(EltNo), "bitfield initialization"); + } else { + Elts[CGM.getTypes().getLLVMFieldNo(curField)] = C; + } EltNo++; - FieldNo++; } - - // Initialize remaining structure elements. - for (unsigned i = Elts.size(); i < NumElements; ++i) { - const llvm::Type *FieldTy = SType->getElementType(i); - Elts.push_back(llvm::Constant::getNullValue(FieldTy)); - } - + return llvm::ConstantStruct::get(SType, Elts); } @@ -158,7 +150,6 @@ public: // Copy initializer elements. unsigned i = 0; for (; i < NumElements; ++i) { - llvm::Constant *C = Visit(ILE->getInit(i)); assert (C && "Failed to create initializer expression"); Elts.push_back(C);