[cfe-commits] r43390 - in /cfe/trunk: CodeGen/CGExpr.cpp CodeGen/CodeGenTypes.cpp test/CodeGen/union.c
Devang Patel
dpatel at apple.com
Fri Oct 26 12:42:18 PDT 2007
Author: dpatel
Date: Fri Oct 26 14:42:18 2007
New Revision: 43390
URL: http://llvm.org/viewvc/llvm-project?rev=43390&view=rev
Log:
Codegen union member references.
Added:
cfe/trunk/test/CodeGen/union.c
Modified:
cfe/trunk/CodeGen/CGExpr.cpp
cfe/trunk/CodeGen/CodeGenTypes.cpp
Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=43390&r1=43389&r2=43390&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Fri Oct 26 14:42:18 2007
@@ -385,14 +385,6 @@
LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
Expr *BaseExpr = E->getBase();
- // FIXME: Handle union members.
- if (BaseExpr->getType()->isUnionType()) {
- fprintf(stderr, "Unimplemented lvalue expr!\n");
- E->dump(getContext().SourceMgr);
- llvm::Type *Ty = llvm::PointerType::get(ConvertType(E->getType()));
- return LValue::MakeAddr(llvm::UndefValue::get(Ty));
- }
-
llvm::Value *BaseValue = NULL;
if (BaseExpr->isLvalue() == Expr::LV_Valid) {
LValue BaseLV = EmitLValue(BaseExpr);
@@ -412,7 +404,16 @@
llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty),
llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) };
- return LValue::MakeAddr(Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp"));
+ llvm::Value *V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp");
+ // Match union field type.
+ if (BaseExpr->getType()->isUnionType()) {
+ const llvm::Type * FieldTy = ConvertType(Field->getType());
+ const llvm::PointerType * BaseTy = cast<llvm::PointerType>(BaseValue->getType());
+ if (FieldTy != BaseTy->getElementType()) {
+ V = Builder.CreateBitCast(V, llvm::PointerType::get(FieldTy), "tmp");
+ }
+ }
+ return LValue::MakeAddr(V);
// FIXME: If record field does not have one to one match with llvm::StructType
// field then apply appropriate masks to select only member field bits.
Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=43390&r1=43389&r2=43390&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Fri Oct 26 14:42:18 2007
@@ -258,13 +258,15 @@
const RecordDecl *RD = cast<const RecordDecl>(TD);
// Just use the largest element of the union, breaking ties with the
// highest aligned member.
- std::vector<const llvm::Type*> Fields;
+
if (RD->getNumMembers() != 0) {
std::pair<uint64_t, unsigned> MaxElt =
Context.getTypeInfo(RD->getMember(0)->getType(), SourceLocation());
unsigned MaxEltNo = 0;
-
+ addFieldInfo(RD->getMember(0), 0); // Each field gets first slot.
+ // FIXME : Move union field handling in RecordOrganize
for (unsigned i = 1, e = RD->getNumMembers(); i != e; ++i) {
+ addFieldInfo(RD->getMember(i), 0); // Each field gets first slot.
std::pair<uint64_t, unsigned> EltInfo =
Context.getTypeInfo(RD->getMember(i)->getType(), SourceLocation());
if (EltInfo.first > MaxElt.first ||
@@ -274,10 +276,19 @@
MaxEltNo = i;
}
}
-
- Fields.push_back(ConvertType(RD->getMember(MaxEltNo)->getType()));
- }
- ResultType = llvm::StructType::get(Fields);
+
+ RecordOrganizer RO;
+ RO.addField(RD->getMember(MaxEltNo));
+ RO.layoutFields(*this);
+
+ // Get llvm::StructType.
+ RecordLayoutInfo *RLI = new RecordLayoutInfo(RO.getLLVMType());
+ ResultType = RLI->getLLVMType();
+ RecordLayouts[ResultType] = RLI;
+ } else {
+ std::vector<const llvm::Type*> Fields;
+ ResultType = llvm::StructType::get(Fields);
+ }
} else {
assert(0 && "FIXME: Implement tag decl kind!");
}
Added: cfe/trunk/test/CodeGen/union.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/union.c?rev=43390&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/union.c (added)
+++ cfe/trunk/test/CodeGen/union.c Fri Oct 26 14:42:18 2007
@@ -0,0 +1,18 @@
+// RUN: clang %s -emit-llvm
+
+union {
+ int a;
+ float b;
+} u;
+
+void f() {
+ u.b = 11;
+}
+
+int f2( float __x ) {
+ union{
+ float __f;
+ unsigned int __u;
+ }__u;
+ return (int)(__u.__u >> 31);
+}
More information about the cfe-commits
mailing list