diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 50 | ||||
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 10 |
3 files changed, 59 insertions, 16 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index cafe5761ca..872e3d1af4 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -803,17 +803,46 @@ LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) { E->getType().getCVRQualifiers()); } -LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { +llvm::Value *CodeGenFunction::EmitIvarOffset(ObjCInterfaceDecl *Interface, + const ObjCIvarDecl *Ivar) { // Objective-C objects are traditionally C structures with their layout // defined at compile-time. In some implementations, their layout is not // defined until run time in order to allow instance variables to be added to // a class without recompiling all of the subclasses. If this is the case // then the CGObjCRuntime subclass must return true to LateBoundIvars and // implement the lookup itself. - if (CGM.getObjCRuntime().LateBoundIVars()) { - return EmitUnsupportedLValue(E, "late-bound instance variables"); - } + if (CGM.getObjCRuntime().LateBoundIVars()) + assert(0 && "late-bound ivars are unsupported"); + + const llvm::Type *InterfaceLTy = + CGM.getTypes().ConvertType(getContext().getObjCInterfaceType(Interface)); + const llvm::StructLayout *Layout = + CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceLTy)); + uint64_t Offset = + Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Ivar)); + + return llvm::ConstantInt::get(CGM.getTypes().ConvertType(getContext().LongTy), + Offset); +} +LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + unsigned CVRQualifiers) { + // See comment in EmitIvarOffset. + if (CGM.getObjCRuntime().LateBoundIVars()) + assert(0 && "late-bound ivars are unsupported"); + + if (Ivar->isBitField()) + assert(0 && "ivar bitfields are unsupported"); + + // TODO: Add a special case for isa (index 0) + unsigned Index = CGM.getTypes().getLLVMFieldNo(Ivar); + + llvm::Value *V = Builder.CreateStructGEP(BaseValue, Index, "tmp"); + return LValue::MakeAddr(V, Ivar->getType().getCVRQualifiers()|CVRQualifiers); +} + +LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { // FIXME: A lot of the code below could be shared with EmitMemberExpr. llvm::Value *BaseValue = 0; const Expr *BaseExpr = E->getBase(); @@ -829,17 +858,8 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { BaseValue = BaseLV.getAddress(); CVRQualifiers = BaseExpr->getType().getCVRQualifiers(); } - - const ObjCIvarDecl *Field = E->getDecl(); - if (Field->isBitField()) - return EmitUnsupportedLValue(E, "ivar bitfields"); - - // TODO: Add a special case for isa (index 0) - unsigned Index = CGM.getTypes().getLLVMFieldNo(Field); - - llvm::Value *V = Builder.CreateStructGEP(BaseValue, Index, "tmp"); - return LValue::MakeAddr(V, - Field->getType().getCVRQualifiers()|CVRQualifiers); + + return EmitLValueForIvar(BaseValue, E->getDecl(), CVRQualifiers); } LValue diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index bf3469e538..c7ee22a2c3 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -399,6 +399,21 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) { EmitBlock(AfterFor); } +void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { + if (RV.isScalar()) { + Builder.CreateStore(RV.getScalarVal(), ReturnValue); + } else if (RV.isAggregate()) { + EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); + } else { + StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); + } + Builder.CreateBr(ReturnBlock); + + // Emit a block after the branch so that dead code after a return has some + // place to go. + EmitBlock(llvm::BasicBlock::Create()); +} + /// EmitReturnStmt - Note that due to GCC extensions, this can have an operand /// if the function returns void, or may be missing one if the function returns /// non-void. Fun stuff :). diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index fee9e6f9b3..36130cf6a8 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -40,6 +40,8 @@ namespace clang { class FunctionDecl; class FunctionTypeProto; class LabelStmt; + class ObjCInterfaceDecl; + class ObjCIvarDecl; class ObjCMethodDecl; class ObjCPropertyImplDecl; class TargetInfo; @@ -334,9 +336,13 @@ public: LValue EmitMemberExpr(const MemberExpr *E); LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E); + llvm::Value *EmitIvarOffset(ObjCInterfaceDecl *Interface, + const ObjCIvarDecl *Ivar); LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field, bool isUnion, unsigned CVRQualifiers); - + LValue EmitLValueForIvar(llvm::Value* Base, const ObjCIvarDecl *Ivar, + unsigned CVRQualifiers); + LValue EmitCXXConditionDeclLValue(const CXXConditionDeclExpr *E); LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E); @@ -442,6 +448,8 @@ private: /// instructions in IndirectSwitches. void EmitIndirectSwitches(); + void EmitReturnOfRValue(RValue RV, QualType Ty); + /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty /// from function arguments into \arg Dst. See ABIArgInfo::Expand. /// |