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 d495cd3..a0484bc 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -91,7 +91,6 @@
// 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 @@
llvm::Constant *EmitStructInitialization(InitListExpr *ILE,
const llvm::StructType *SType) {
- TagDecl *TD = ILE->getType()->getAsRecordType()->getDecl();
+ RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
std::vector<llvm::Constant*> 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);
- // 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++;
- continue;
- }
-
- llvm::Constant *C = Visit(ILE->getInit(EltNo));
- assert (C && "Failed to create initializer expression");
- Elts.push_back(C);
- EltNo++;
- FieldNo++;
- }
-
- // Initialize remaining structure elements.
- for (unsigned i = Elts.size(); i < NumElements; ++i) {
+ // 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
+ 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");
+
+ if (curField->isBitField()) {
+ CGM.WarnUnsupported(ILE->getInit(EltNo), "bitfield initialization");
+ } else {
+ Elts[CGM.getTypes().getLLVMFieldNo(curField)] = C;
+ }
+ EltNo++;
+ }
+
return llvm::ConstantStruct::get(SType, Elts);
}
@@ -158,7 +150,6 @@
// 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);