forked from OSchip/llvm-project
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). llvm-svn: 51285
This commit is contained in:
parent
8d0b976e7c
commit
247ee87e26
|
@ -91,7 +91,6 @@ public:
|
||||||
// Copy initializer elements.
|
// Copy initializer elements.
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (; i < NumInitableElts; ++i) {
|
for (; i < NumInitableElts; ++i) {
|
||||||
|
|
||||||
llvm::Constant *C = Visit(ILE->getInit(i));
|
llvm::Constant *C = Visit(ILE->getInit(i));
|
||||||
assert (C && "Failed to create initializer expression");
|
assert (C && "Failed to create initializer expression");
|
||||||
Elts.push_back(C);
|
Elts.push_back(C);
|
||||||
|
@ -107,42 +106,35 @@ public:
|
||||||
llvm::Constant *EmitStructInitialization(InitListExpr *ILE,
|
llvm::Constant *EmitStructInitialization(InitListExpr *ILE,
|
||||||
const llvm::StructType *SType) {
|
const llvm::StructType *SType) {
|
||||||
|
|
||||||
TagDecl *TD = ILE->getType()->getAsRecordType()->getDecl();
|
RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
|
||||||
std::vector<llvm::Constant*> Elts;
|
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.
|
// Initialize the whole structure to zero.
|
||||||
unsigned EltNo = 0; // Element no in ILE
|
for (unsigned i = 0; i < SType->getNumElements(); ++i) {
|
||||||
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) {
|
|
||||||
const llvm::Type *FieldTy = SType->getElementType(i);
|
const llvm::Type *FieldTy = SType->getElementType(i);
|
||||||
Elts.push_back(llvm::Constant::getNullValue(FieldTy));
|
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);
|
return llvm::ConstantStruct::get(SType, Elts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +150,6 @@ public:
|
||||||
// Copy initializer elements.
|
// Copy initializer elements.
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (; i < NumElements; ++i) {
|
for (; i < NumElements; ++i) {
|
||||||
|
|
||||||
llvm::Constant *C = Visit(ILE->getInit(i));
|
llvm::Constant *C = Visit(ILE->getInit(i));
|
||||||
assert (C && "Failed to create initializer expression");
|
assert (C && "Failed to create initializer expression");
|
||||||
Elts.push_back(C);
|
Elts.push_back(C);
|
||||||
|
|
Loading…
Reference in New Issue