From: Chris Lattner Date: Fri, 4 Apr 2008 04:07:35 +0000 (+0000) Subject: Codegen assignment to self correctly, patch by David Chisnall! X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c8aa5f1f264fb230c38182adab944232bb160c2b;p=clang Codegen assignment to self correctly, patch by David Chisnall! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49201 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index c80cecc76e..a3155c4efa 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -83,8 +83,8 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) { assert(Init && "Unable to create initialiser for static decl"); std::string ContextName; - if (CurFuncDecl) - ContextName = CurFuncDecl->getName(); + if (const FunctionDecl * FD = dyn_cast(CurFuncDecl)) + ContextName = FD->getName(); else assert(0 && "Unknown context for block var decl"); // FIXME Handle objc. diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 66aeea3540..c80b6a7a8b 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -386,7 +386,13 @@ LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) { } LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) { - std::string FunctionName(CurFuncDecl->getName()); + std::string FunctionName; + if(const FunctionDecl *FD = dyn_cast(CurFuncDecl)) { + FunctionName = FD->getName(); + } + else { + assert(0 && "Attempting to load predefined constant for invalid decl type"); + } std::string GlobalVarName; switch (E->getIdentType()) { @@ -404,7 +410,7 @@ LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) { break; } - GlobalVarName += CurFuncDecl->getName(); + GlobalVarName += FunctionName; // FIXME: Can cache/reuse these within the module. llvm::Constant *C=llvm::ConstantArray::get(FunctionName); @@ -581,8 +587,10 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { // Get object pointer and coerce object pointer to correct type. llvm::Value *Object = EmitLValue(E->getBase()).getAddress(); + Object = Builder.CreateLoad(Object, E->getDecl()->getName()); if (Object->getType() != ObjectType) Object = Builder.CreateBitCast(Object, ObjectType); + // Return a pointer to the right element. return LValue::MakeAddr(Builder.CreateStructGEP(Object, Index, diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index cc7d8e97e4..a50e66660f 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -484,8 +484,7 @@ Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { llvm::Value *SelPtr = Builder.CreateStructGEP(Selector, 0); return Runtime->generateMessageSend(Builder, ConvertType(E->getType()), - // FIXME: Self can be assigned to! - CGF.CurFn->arg_begin(), + CGF.LoadObjCSelf(), Receiver, SelPtr, &Args[0], Args.size()); } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index c804098ec9..a07eaff305 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -97,7 +97,13 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { // TODO: Add something to AST to let the runtime specify the names and types // of these. llvm::Value *&DMEntry = LocalDeclMap[&(*OMD->getSelfDecl())]; - DMEntry = AI; + const llvm::Type *SelfTy = AI->getType(); + llvm::Value *DeclPtr = new llvm::AllocaInst(SelfTy, 0, "self.addr", + AllocaInsertPt); + + // Store the initial value into the alloca. + Builder.CreateStore(AI, DeclPtr); + DMEntry = DeclPtr; ++AI; ++AI; @@ -130,13 +136,22 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { assert(!verifyFunction(*CurFn) && "Generated method is not well formed."); } +llvm::Value *CodeGenFunction::LoadObjCSelf(void) +{ + if(const ObjCMethodDecl *OMD = dyn_cast(CurFuncDecl)) { + llvm::Value *SelfPtr = LocalDeclMap[&(*OMD->getSelfDecl())]; + return Builder.CreateLoad(SelfPtr, "self"); + } + return NULL; +} + void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { LLVMIntTy = ConvertType(getContext().IntTy); LLVMPointerWidth = static_cast( getContext().getTypeSize(getContext().getPointerType(getContext().VoidTy))); CurFuncDecl = FD; - FnRetTy = CurFuncDecl->getType()->getAsFunctionType()->getResultType(); + FnRetTy = FD->getType()->getAsFunctionType()->getResultType(); CurFn = cast(CGM.GetAddrOfFunctionDecl(FD, true)); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 121b7953bd..61a0d744f6 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -246,7 +246,8 @@ public: typedef std::pair ComplexPairTy; llvm::LLVMFoldingBuilder Builder; - const FunctionDecl *CurFuncDecl; + // Holds the Decl for the current function or method + const Decl *CurFuncDecl; QualType FnRetTy; llvm::Function *CurFn; @@ -293,6 +294,8 @@ public: void GenerateCode(const FunctionDecl *FD); const llvm::Type *ConvertType(QualType T); + + llvm::Value *LoadObjCSelf(); /// hasAggregateLLVMType - Return true if the specified AST type will map into /// an aggregate LLVM type or is void.