diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 8 |
3 files changed, 27 insertions, 11 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 2af3a15cdb..7e78e7df52 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -846,17 +846,8 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, QualType FieldType = CGF.getContext().getCanonicalType(Field->getType()); llvm::Value *ThisPtr = CGF.LoadCXXThis(); - LValue LHS; - if (FieldType->isReferenceType()) { - // FIXME: This is really ugly; should be refactored somehow - unsigned idx = CGF.CGM.getTypes().getLLVMFieldNo(Field); - llvm::Value *V = CGF.Builder.CreateStructGEP(ThisPtr, idx, "tmp"); - assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs"); - LHS = LValue::MakeAddr(V, CGF.MakeQualifiers(FieldType)); - } else { - LHS = CGF.EmitLValueForField(ThisPtr, Field, 0); - } - + LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0); + // If we are initializing an anonymous union field, drill down to the field. if (MemberInit->getAnonUnionMember()) { Field = MemberInit->getAnonUnionMember(); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index da85626b86..605f77975f 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1486,6 +1486,23 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue, return LValue::MakeAddr(V, Quals); } +LValue +CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value* BaseValue, + const FieldDecl* Field, + unsigned CVRQualifiers) { + QualType FieldType = Field->getType(); + + if (!FieldType->isReferenceType()) + return EmitLValueForField(BaseValue, Field, CVRQualifiers); + + unsigned idx = CGM.getTypes().getLLVMFieldNo(Field); + llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp"); + + assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs"); + + return LValue::MakeAddr(V, MakeQualifiers(FieldType)); +} + LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){ const llvm::Type *LTy = ConvertType(E->getType()); llvm::Value *DeclPtr = CreateTempAlloca(LTy, ".compoundliteral"); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 98e00ba047..734e475fef 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1014,6 +1014,14 @@ public: const ObjCIvarDecl *Ivar); LValue EmitLValueForField(llvm::Value* Base, const FieldDecl* Field, unsigned CVRQualifiers); + + /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that + /// if the Field is a reference, this will return the address of the reference + /// and not the address of the value stored in the reference. + LValue EmitLValueForFieldInitialization(llvm::Value* Base, + const FieldDecl* Field, + unsigned CVRQualifiers); + LValue EmitLValueForIvar(QualType ObjectTy, llvm::Value* Base, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers); |