Index: CodeGen/CodeGenModule.cpp =================================================================== --- CodeGen/CodeGenModule.cpp (revision 46353) +++ CodeGen/CodeGenModule.cpp (working copy) @@ -293,13 +293,6 @@ /// struct typed variables. static llvm::Constant *GenerateAggregateInit(const InitListExpr *ILE, CodeGenModule &CGM) { - if (ILE->getType()->isVoidType()) { - // FIXME: Remove this when sema of initializers is finished (and the code - // below). - CGM.WarnUnsupported(ILE, "initializer"); - return 0; - } - assert((ILE->getType()->isArrayType() || ILE->getType()->isStructureType() || ILE->getType()->isVectorType()) && "Bad type for init list!"); @@ -311,38 +304,76 @@ const llvm::CompositeType *CType = cast(Types.ConvertType(ILE->getType())); assert(CType); - std::vector Elts; - + + if (ILE->getType()->isStructureType()) { + const llvm::StructType *SType = cast(CType); + const RecordDecl* structDecl = ILE->getType()->getAsRecordType()->getDecl(); + // The number of declarations in the C struct + unsigned numMembers = structDecl->getNumMembers() - + structDecl->hasFlexibleArrayMember(); + // The number of members in the raw LLVM struct. + unsigned numLLVMElements = SType->getNumElements(); + // At the end of the following two loops, Elts will contain + // initializers for all the members of the LLVM struct. + std::vector Elts(numLLVMElements); + for (unsigned curMember = 0, curInit = 0; curMember < numMembers; ++curMember) { + if (curInit >= ILE->getNumInits()) { + // No more initializers; the rest of the struct is filled + // with null below. + break; + } + const FieldDecl *curField = structDecl->getMember(curMember); + if (!curField->getIdentifier()) { + // Initializers can't initialize unnamed fields, e.g. "int : 20;" + continue; + } + const Expr* expr = ILE->getInit(curInit); + ++curInit; + // FIXME: This doesn't work properly for initializers + // that aren't fully braced. + llvm::Constant* fieldValue = GenerateConstantExpr(expr, CGM); + assert(!curField->isBitField() && "Cannot initialize bitfields yet"); + // Fill in the appropriate field in the LLVM struct. + // Types.getLLVMFieldNo(curField) is often equal to curMember, + // but padding and bitfields mess that up, so it's simpler + // to just grab the right field. + Elts[Types.getLLVMFieldNo(curField)] = fieldValue; + } + for (unsigned i = 0; i < Elts.size(); i++) { + if (Elts[i] == 0) { + // Fill in all the uninitialized members with null + // In theory, we could fill in padding fields with undef, + // but it would be more complicated. + Elts[i] = llvm::Constant::getNullValue(SType->getElementType(i)); + } + } + return llvm::ConstantStruct::get(SType, Elts); + } + + std::vector Elts; // Initialising an array requires us to automatically initialise any // elements that have not been initialised explicitly const llvm::ArrayType *AType = 0; const llvm::Type *AElemTy = 0; unsigned NumArrayElements = 0; - + // If this is an array, we may have to truncate the initializer if ((AType = dyn_cast(CType))) { NumArrayElements = AType->getNumElements(); AElemTy = AType->getElementType(); NumInitableElts = std::min(NumInitableElts, NumArrayElements); } - + // Copy initializer elements. unsigned i = 0; for (i = 0; i < NumInitableElts; ++i) { llvm::Constant *C = GenerateConstantExpr(ILE->getInit(i), CGM); - // FIXME: Remove this when sema of initializers is finished (and the code - // above). - if (C == 0 && ILE->getInit(i)->getType()->isVoidType()) { - if (ILE->getType()->isVoidType()) return 0; - return llvm::UndefValue::get(CType); - } assert (C && "Failed to create initialiser expression"); Elts.push_back(C); } - if (ILE->getType()->isStructureType()) - return llvm::ConstantStruct::get(cast(CType), Elts); - + // FIXME: What about a vector initializer that doesn't have + // enough elements? if (ILE->getType()->isVectorType()) return llvm::ConstantVector::get(cast(CType), Elts);