diff options
author | Nuno Lopes <nunoplopes@sapo.pt> | 2009-01-17 00:48:48 +0000 |
---|---|---|
committer | Nuno Lopes <nunoplopes@sapo.pt> | 2009-01-17 00:48:48 +0000 |
commit | 81e51e2c5bf1e4edc3b70040e2083fa83d314e40 (patch) | |
tree | d016d1eeab8587d9f11738b51c19cae383196e85 /lib/CodeGen/CGExprConstant.cpp | |
parent | 0b7a158d120ac8d78c114a823e17eedfec6b6658 (diff) |
add support for usage of cast to union thing with static vars
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62387 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprConstant.cpp')
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 41875522ed..72674f77fb 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -61,6 +61,12 @@ public: } llvm::Constant *VisitCastExpr(CastExpr* E) { + // GCC cast to union extension + if (E->getType()->isUnionType()) { + const llvm::Type *Ty = ConvertType(E->getType()); + return EmitUnion(CGM.EmitConstantExpr(E->getSubExpr(), CGF), Ty); + } + llvm::Constant *C = Visit(E->getSubExpr()); return EmitConversion(C, E->getSubExpr()->getType(), E->getType()); @@ -217,6 +223,27 @@ public: return llvm::ConstantStruct::get(SType, Elts); } + llvm::Constant *EmitUnion(llvm::Constant *C, const llvm::Type *Ty) { + // 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().getTypeStoreSize(C->getType()); + unsigned TotalSize = CGM.getTargetData().getTypeStoreSize(Ty); + while (CurSize < TotalSize) { + Elts.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty)); + Types.push_back(llvm::Type::Int8Ty); + CurSize++; + } + + // This always generates a packed struct + // FIXME: Try to generate an unpacked struct when we can + llvm::StructType* STy = llvm::StructType::get(Types, true); + return llvm::ConstantStruct::get(STy, Elts); + } + llvm::Constant *EmitUnionInitialization(InitListExpr *ILE) { RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl(); const llvm::Type *Ty = ConvertType(ILE->getType()); @@ -248,26 +275,7 @@ public: return llvm::ConstantArray::get(RetTy, Elts); } - llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(0), CGF); - - // 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().getTypeStoreSize(C->getType()); - unsigned TotalSize = CGM.getTargetData().getTypeStoreSize(Ty); - while (CurSize < TotalSize) { - Elts.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty)); - Types.push_back(llvm::Type::Int8Ty); - CurSize++; - } - - // This always generates a packed struct - // FIXME: Try to generate an unpacked struct when we can - llvm::StructType* STy = llvm::StructType::get(Types, true); - return llvm::ConstantStruct::get(STy, Elts); + return EmitUnion(CGM.EmitConstantExpr(ILE->getInit(0), CGF), Ty); } llvm::Constant *EmitVectorInitialization(InitListExpr *ILE) { |