diff options
author | Anders Carlsson <andersca@mac.com> | 2009-07-31 21:48:56 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-07-31 21:48:56 +0000 |
commit | 12905987c4ab9fb705f88f56b35298f730c8dbd5 (patch) | |
tree | 3b569799670c9844589594e4f6ef26340ddee9e3 /lib/CodeGen/CGExprConstant.cpp | |
parent | 82b56961dcb813674dbda3c5f5aaee703d55741c (diff) |
Remove the old struct builder code.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77738 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprConstant.cpp')
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 178 |
1 files changed, 1 insertions, 177 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 0e9d20928c..cdc8bdb970 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -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) { |