Remove the old struct builder code.

llvm-svn: 77738
This commit is contained in:
Anders Carlsson 2009-07-31 21:48:56 +00:00
parent 67829f6493
commit 1726aaa4fc
1 changed files with 1 additions and 177 deletions

View File

@ -467,188 +467,12 @@ public:
return llvm::ConstantArray::get(AType, Elts);
}
void InsertBitfieldIntoStruct(std::vector<llvm::Constant*>& Elts,
FieldDecl* Field, Expr* E) {
// Calculate the value to insert
llvm::Constant *C = CGM.EmitConstantExpr(E, Field->getType(), CGF);
if (!C)
return;
llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C);
if (!CI) {
CGM.ErrorUnsupported(E, "bitfield initialization");
return;
}
llvm::APInt V = CI->getValue();
// Calculate information about the relevant field
const llvm::Type* Ty = CI->getType();
const llvm::TargetData &TD = CGM.getTypes().getTargetData();
unsigned size = TD.getTypeAllocSizeInBits(Ty);
CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
unsigned FieldOffset = Info.FieldNo * size;
FieldOffset += Info.Start;
// Find where to start the insertion
// FIXME: This is O(n^2) in the number of bit-fields!
// FIXME: This won't work if the struct isn't completely packed!
unsigned offset = 0, i = 0;
while (offset < (FieldOffset & -8))
offset += TD.getTypeAllocSizeInBits(Elts[i++]->getType());
// Advance over 0 sized elements (must terminate in bounds since
// the bitfield must have a size).
while (TD.getTypeAllocSizeInBits(Elts[i]->getType()) == 0)
++i;
// Promote the size of V if necessary
// FIXME: This should never occur, but currently it can because initializer
// constants are cast to bool, and because clang is not enforcing bitfield
// width limits.
if (Info.Size > V.getBitWidth())
V.zext(Info.Size);
// Insert the bits into the struct
// FIXME: This algorthm is only correct on X86!
// FIXME: THis algorthm assumes bit-fields only have byte-size elements!
unsigned bitsToInsert = Info.Size;
unsigned curBits = std::min(8 - (FieldOffset & 7), bitsToInsert);
unsigned byte = V.getLoBits(curBits).getZExtValue() << (FieldOffset & 7);
do {
llvm::Constant* byteC =
llvm::ConstantInt::get(llvm::Type::Int8Ty, byte);
Elts[i] = llvm::ConstantExpr::getOr(Elts[i], byteC);
++i;
V = V.lshr(curBits);
bitsToInsert -= curBits;
if (!bitsToInsert)
break;
curBits = bitsToInsert > 8 ? 8 : bitsToInsert;
byte = V.getLoBits(curBits).getZExtValue();
} while (true);
}
llvm::Constant *EmitStructInitialization(InitListExpr *ILE) {
return ConstStructBuilder::BuildStruct(CGM, CGF, ILE);
// FIXME: Remove the old struct builder once we're sure that the new one
// works well enough!
const llvm::StructType *SType =
cast<llvm::StructType>(ConvertType(ILE->getType()));
RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl();
std::vector<llvm::Constant*> Elts;
// Initialize the whole structure to zero.
// FIXME: This doesn't handle member pointers correctly!
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
bool RewriteType = false;
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end();
EltNo < ILE->getNumInits() && Field != FieldEnd; ++Field) {
if (Field->isBitField()) {
if (!Field->getIdentifier())
continue;
InsertBitfieldIntoStruct(Elts, *Field, ILE->getInit(EltNo));
} else {
unsigned FieldNo = CGM.getTypes().getLLVMFieldNo(*Field);
llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(EltNo),
Field->getType(), CGF);
if (!C) return 0;
RewriteType |= (C->getType() != Elts[FieldNo]->getType());
Elts[FieldNo] = C;
}
EltNo++;
}
if (RewriteType) {
// FIXME: Make this work for non-packed structs
assert(SType->isPacked() && "Cannot recreate unpacked structs");
std::vector<const llvm::Type*> Types;
for (unsigned i = 0; i < Elts.size(); ++i)
Types.push_back(Elts[i]->getType());
SType = llvm::StructType::get(Types, true);
}
return llvm::ConstantStruct::get(SType, Elts);
}
llvm::Constant *EmitUnion(llvm::Constant *C, const llvm::Type *Ty) {
if (!C)
return 0;
// Build a struct with the union sub-element as the first member,
// and padded to the appropriate size
std::vector<llvm::Constant*> Elts;
std::vector<const llvm::Type*> Types;
Elts.push_back(C);
Types.push_back(C->getType());
unsigned CurSize = CGM.getTargetData().getTypeAllocSize(C->getType());
unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(Ty);
assert(CurSize <= TotalSize && "Union size mismatch!");
if (unsigned NumPadBytes = TotalSize - CurSize) {
const llvm::Type *Ty = llvm::Type::Int8Ty;
if (NumPadBytes > 1)
Ty = llvm::ArrayType::get(Ty, NumPadBytes);
Elts.push_back(llvm::Constant::getNullValue(Ty));
Types.push_back(Ty);
}
llvm::StructType* STy = llvm::StructType::get(Types, false);
return llvm::ConstantStruct::get(STy, Elts);
}
llvm::Constant *EmitUnionInitialization(InitListExpr *ILE) {
return ConstStructBuilder::BuildStruct(CGM, CGF, ILE);
const llvm::Type *Ty = ConvertType(ILE->getType());
FieldDecl* curField = ILE->getInitializedFieldInUnion();
if (!curField) {
// There's no field to initialize, so value-initialize the union.
#ifndef NDEBUG
// Make sure that it's really an empty and not a failure of
// semantic analysis.
RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl();
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end();
Field != FieldEnd; ++Field)
assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
#endif
return llvm::Constant::getNullValue(Ty);
}
if (curField->isBitField()) {
// Create a dummy struct for bit-field insertion
unsigned NumElts = CGM.getTargetData().getTypeAllocSize(Ty);
llvm::Constant* NV =
llvm::Constant::getNullValue(llvm::Type::Int8Ty);
std::vector<llvm::Constant*> Elts(NumElts, NV);
InsertBitfieldIntoStruct(Elts, curField, ILE->getInit(0));
const llvm::ArrayType *RetTy =
llvm::ArrayType::get(NV->getType(), NumElts);
return llvm::ConstantArray::get(RetTy, Elts);
}
llvm::Constant *InitElem;
if (ILE->getNumInits() > 0) {
Expr *Init = ILE->getInit(0);
InitElem = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
} else {
InitElem = CGM.EmitNullConstant(curField->getType());
}
return EmitUnion(InitElem, Ty);
}
llvm::Constant *EmitVectorInitialization(InitListExpr *ILE) {