forked from OSchip/llvm-project
parent
7718d7a2eb
commit
ed93c3c3b3
|
@ -385,14 +385,6 @@ EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) {
|
|||
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 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
|
|||
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.
|
||||
|
|
|
@ -258,13 +258,15 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
|||
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 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
|||
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!");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue