]> granicus.if.org Git - clang/commitdiff
Push a return-value slot throughout ObjC message-send codegen. Will be
authorJohn McCall <rjmccall@apple.com>
Sat, 22 May 2010 01:48:05 +0000 (01:48 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 22 May 2010 01:48:05 +0000 (01:48 +0000)
critical for ObjC++ correctness;  hard to test independently of various
required Sema changes, though.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104422 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGObjCRuntime.h
lib/CodeGen/CodeGenFunction.h

index 3bf2f8a52025f58fbf1a94cd52c73b365436bb8a..aa32bb8d8d028dccbbad08361b011df52ecc544f 100644 (file)
@@ -37,6 +37,10 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
   bool IgnoreResult;
   bool IsInitializer;
   bool RequiresGCollection;
+
+  ReturnValueSlot getReturnValueSlot() const {
+    return ReturnValueSlot(DestPtr, VolatileDest);
+  }
 public:
   AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
                  bool ignore, bool isinit, bool requiresGCollection)
@@ -299,7 +303,7 @@ void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
   // If the struct doesn't require GC, we can just pass the destination
   // directly to EmitCall.
   if (!RequiresGCollection) {
-    CGF.EmitCallExpr(E, ReturnValueSlot(DestPtr, VolatileDest));
+    CGF.EmitCallExpr(E, getReturnValueSlot());
     return;
   }
   
@@ -308,19 +312,16 @@ void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
 }
 
 void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
-  RValue RV = CGF.EmitObjCMessageExpr(E);
-  EmitFinalDestCopy(E, RV);
+  CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
 }
 
 void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-  RValue RV = CGF.EmitObjCPropertyGet(E);
-  EmitFinalDestCopy(E, RV);
+  CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
 }
 
 void AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr(
                                    ObjCImplicitSetterGetterRefExpr *E) {
-  RValue RV = CGF.EmitObjCPropertyGet(E);
-  EmitFinalDestCopy(E, RV);
+  CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
 }
 
 void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
index 674f50234e550ea1464e14d3a5c5ade5bcbe7132..6efba44b0e9478b397adfaa575c588dc95367c52 100644 (file)
@@ -47,7 +47,8 @@ llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
 }
 
 
-RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
+RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
+                                            ReturnValueSlot Return) {
   // Only the lookup mechanism and first two arguments of the method
   // implementation vary between runtimes.  We can get the receiver and
   // arguments in generic code.
@@ -93,7 +94,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
     // super is only valid in an Objective-C method
     const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
     bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
-    return Runtime.GenerateMessageSendSuper(*this, E->getType(),
+    return Runtime.GenerateMessageSendSuper(*this, Return, E->getType(),
                                             E->getSelector(),
                                             OMD->getClassInterface(),
                                             isCategoryImpl,
@@ -103,7 +104,8 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
                                             E->getMethodDecl());
   }
 
-  return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
+  return Runtime.GenerateMessageSend(*this, Return, E->getType(),
+                                     E->getSelector(),
                                      Receiver, Args, OID,
                                      E->getMethodDecl());
 }
@@ -506,12 +508,14 @@ QualType CodeGenFunction::TypeOfSelfObject() {
 }
 
 RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,
-                                                 const Selector &S) {
+                                                 const Selector &S,
+                                                 ReturnValueSlot Return) {
   llvm::Value *Receiver = LoadObjCSelf();
   const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
   bool isClassMessage = OMD->isClassMethod();
   bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
   return CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
+                                                       Return,
                                                        Exp->getType(),
                                                        S,
                                                        OMD->getClassInterface(),
@@ -522,15 +526,16 @@ RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,
 
 }
 
-RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
+RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp,
+                                            ReturnValueSlot Return) {
   Exp = Exp->IgnoreParens();
   // FIXME: Split it into two separate routines.
   if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
     Selector S = E->getProperty()->getGetterName();
     if (isa<ObjCSuperExpr>(E->getBase()))
-      return EmitObjCSuperPropertyGet(E, S);
+      return EmitObjCSuperPropertyGet(E, S, Return);
     return CGM.getObjCRuntime().
-             GenerateMessageSend(*this, Exp->getType(), S,
+             GenerateMessageSend(*this, Return, Exp->getType(), S,
                                  EmitScalarExpr(E->getBase()),
                                  CallArgList());
   } else {
@@ -542,11 +547,11 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
       const ObjCInterfaceDecl *OID = KE->getInterfaceDecl();
       Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
     } else if (isa<ObjCSuperExpr>(KE->getBase()))
-      return EmitObjCSuperPropertyGet(KE, S);
+      return EmitObjCSuperPropertyGet(KE, S, Return);
     else
       Receiver = EmitScalarExpr(KE->getBase());
     return CGM.getObjCRuntime().
-             GenerateMessageSend(*this, Exp->getType(), S,
+             GenerateMessageSend(*this, Return, Exp->getType(), S,
                                  Receiver,
                                  CallArgList(), KE->getInterfaceDecl());
   }
@@ -562,6 +567,7 @@ void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp,
   bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
   Args.push_back(std::make_pair(Src, Exp->getType()));
   CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
+                                                ReturnValueSlot(),
                                                 Exp->getType(),
                                                 S,
                                                 OMD->getClassInterface(),
@@ -583,7 +589,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
     }
     CallArgList Args;
     Args.push_back(std::make_pair(Src, E->getType()));
-    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+                                             getContext().VoidTy, S,
                                              EmitScalarExpr(E->getBase()),
                                              Args);
   } else if (const ObjCImplicitSetterGetterRefExpr *E =
@@ -600,7 +607,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
     } else
       Receiver = EmitScalarExpr(E->getBase());
     Args.push_back(std::make_pair(Src, E->getType()));
-    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+                                             getContext().VoidTy, S,
                                              Receiver,
                                              Args, E->getInterfaceDecl());
   } else
@@ -667,7 +675,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
                                 getContext().UnsignedLongTy));
 
   RValue CountRV =
-    CGM.getObjCRuntime().GenerateMessageSend(*this,
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
                                              getContext().UnsignedLongTy,
                                              FastEnumSel,
                                              Collection, Args);
@@ -792,7 +800,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
   EmitBlock(FetchMore);
 
   CountRV =
-    CGM.getObjCRuntime().GenerateMessageSend(*this,
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
                                              getContext().UnsignedLongTy,
                                              FastEnumSel,
                                              Collection, Args);
index b7cfa6c8ac12b634172e4dd8f980fc567e8c6f86..6c25afeb9ad3e03ccee78b0348a740c1ef3dffec 100644 (file)
@@ -142,6 +142,7 @@ public:
   virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
   virtual CodeGen::RValue
   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                      ReturnValueSlot Return,
                       QualType ResultType,
                       Selector Sel,
                       llvm::Value *Receiver,
@@ -150,6 +151,7 @@ public:
                       const ObjCMethodDecl *Method);
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot Return,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
@@ -455,6 +457,7 @@ llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
 ///should be called.
 CodeGen::RValue
 CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                    ReturnValueSlot Return,
                                     QualType ResultType,
                                     Selector Sel,
                                     const ObjCInterfaceDecl *Class,
@@ -582,7 +585,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
   llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 3);
 
   llvm::Instruction *call;
-  RValue msgRet = CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs,
+  RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
       0, &call);
   call->setMetadata(msgSendMDKind, node);
   return msgRet;
@@ -591,6 +594,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
 /// Generate code for a message send expression.
 CodeGen::RValue
 CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                               ReturnValueSlot Return,
                                QualType ResultType,
                                Selector Sel,
                                llvm::Value *Receiver,
@@ -726,7 +730,7 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
     cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node);
   }
   llvm::Instruction *call;
-  RValue msgRet = CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs,
+  RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
       0, &call);
   call->setMetadata(msgSendMDKind, node);
 
index 4609d30f0e1dfb9220bb1c9ee46e2a8a31067954..d3bafd7eda78ac61919cb9ce6abc71869caf0320 100644 (file)
@@ -973,6 +973,7 @@ protected:
                                           bool AddToUsed);
 
   CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+                                        ReturnValueSlot Return,
                                         QualType ResultType,
                                         llvm::Value *Sel,
                                         llvm::Value *Arg0,
@@ -1039,6 +1040,7 @@ private:
   llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
 
   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
+                                  ReturnValueSlot Return,
                                   QualType ResultType,
                                   Selector Sel,
                                   llvm::Value *Arg0,
@@ -1126,6 +1128,7 @@ public:
   virtual llvm::Function *ModuleInitFunction();
 
   virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                              ReturnValueSlot Return,
                                               QualType ResultType,
                                               Selector Sel,
                                               llvm::Value *Receiver,
@@ -1135,6 +1138,7 @@ public:
 
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot Return,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
@@ -1279,6 +1283,7 @@ private:
                                    ObjCProtocolDecl::protocol_iterator end);
 
   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
+                                  ReturnValueSlot Return,
                                   QualType ResultType,
                                   Selector Sel,
                                   llvm::Value *Receiver,
@@ -1354,6 +1359,7 @@ public:
   virtual llvm::Function *ModuleInitFunction();
 
   virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                              ReturnValueSlot Return,
                                               QualType ResultType,
                                               Selector Sel,
                                               llvm::Value *Receiver,
@@ -1363,6 +1369,7 @@ public:
 
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot Return,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
@@ -1515,6 +1522,7 @@ llvm::Constant *CGObjCCommonMac::GenerateConstantString(
 /// which class's method should be called.
 CodeGen::RValue
 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                    ReturnValueSlot Return,
                                     QualType ResultType,
                                     Selector Sel,
                                     const ObjCInterfaceDecl *Class,
@@ -1566,7 +1574,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
   Target = CGF.Builder.CreateBitCast(Target, ClassTy);
   CGF.Builder.CreateStore(Target,
                           CGF.Builder.CreateStructGEP(ObjCSuper, 1));
-  return EmitLegacyMessageSend(CGF, ResultType,
+  return EmitLegacyMessageSend(CGF, Return, ResultType,
                                EmitSelector(CGF.Builder, Sel),
                                ObjCSuper, ObjCTypes.SuperPtrCTy,
                                true, CallArgs, Method, ObjCTypes);
@@ -1574,13 +1582,14 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
 
 /// Generate code for a message send expression.
 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                               ReturnValueSlot Return,
                                                QualType ResultType,
                                                Selector Sel,
                                                llvm::Value *Receiver,
                                                const CallArgList &CallArgs,
                                                const ObjCInterfaceDecl *Class,
                                                const ObjCMethodDecl *Method) {
-  return EmitLegacyMessageSend(CGF, ResultType,
+  return EmitLegacyMessageSend(CGF, Return, ResultType,
                                EmitSelector(CGF.Builder, Sel),
                                Receiver, CGF.getContext().getObjCIdType(),
                                false, CallArgs, Method, ObjCTypes);
@@ -1588,6 +1597,7 @@ CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
 
 CodeGen::RValue
 CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+                                       ReturnValueSlot Return,
                                        QualType ResultType,
                                        llvm::Value *Sel,
                                        llvm::Value *Arg0,
@@ -1634,7 +1644,7 @@ CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
   assert(Fn && "EmitLegacyMessageSend - unknown API");
   Fn = llvm::ConstantExpr::getBitCast(Fn,
                                       llvm::PointerType::getUnqual(FTy));
-  return CGF.EmitCall(FnInfo, Fn, ReturnValueSlot(), ActualArgs);
+  return CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
 }
 
 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
@@ -5115,6 +5125,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
 
 CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
   CodeGen::CodeGenFunction &CGF,
+  ReturnValueSlot Return,
   QualType ResultType,
   Selector Sel,
   llvm::Value *Receiver,
@@ -5214,12 +5225,13 @@ CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
   const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true);
   Callee = CGF.Builder.CreateBitCast(Callee,
                                      llvm::PointerType::getUnqual(FTy));
-  return CGF.EmitCall(FnInfo1, Callee, ReturnValueSlot(), ActualArgs);
+  return CGF.EmitCall(FnInfo1, Callee, Return, ActualArgs);
 }
 
 /// Generate code for a message send expression in the nonfragile abi.
 CodeGen::RValue
 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                            ReturnValueSlot Return,
                                             QualType ResultType,
                                             Selector Sel,
                                             llvm::Value *Receiver,
@@ -5227,10 +5239,11 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
                                             const ObjCInterfaceDecl *Class,
                                             const ObjCMethodDecl *Method) {
   return LegacyDispatchedSelector(Sel)
-    ? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
+    ? EmitLegacyMessageSend(CGF, Return, ResultType,
+                            EmitSelector(CGF.Builder, Sel),
                             Receiver, CGF.getContext().getObjCIdType(),
                             false, CallArgs, Method, ObjCTypes)
-    : EmitMessageSend(CGF, ResultType, Sel,
+    : EmitMessageSend(CGF, Return, ResultType, Sel,
                       Receiver, CGF.getContext().getObjCIdType(),
                       false, CallArgs);
 }
@@ -5337,6 +5350,7 @@ llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
 /// which class's method should be called.
 CodeGen::RValue
 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                                 ReturnValueSlot Return,
                                                  QualType ResultType,
                                                  Selector Sel,
                                                  const ObjCInterfaceDecl *Class,
@@ -5379,10 +5393,11 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
                           CGF.Builder.CreateStructGEP(ObjCSuper, 1));
 
   return (LegacyDispatchedSelector(Sel))
-    ? EmitLegacyMessageSend(CGF, ResultType,EmitSelector(CGF.Builder, Sel),
+    ? EmitLegacyMessageSend(CGF, Return, ResultType,
+                            EmitSelector(CGF.Builder, Sel),
                             ObjCSuper, ObjCTypes.SuperPtrCTy,
                             true, CallArgs, Method, ObjCTypes)
-    : EmitMessageSend(CGF, ResultType, Sel,
+    : EmitMessageSend(CGF, Return, ResultType, Sel,
                       ObjCSuper, ObjCTypes.SuperPtrCTy,
                       true, CallArgs);
 }
index 654ad0a4bfaea5519ed272f48cb88e5b59088362..8de7f10b8612459b021b0280184697ec6f22172b 100644 (file)
@@ -119,6 +119,7 @@ public:
   /// a property setter or getter.
   virtual CodeGen::RValue
   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                      ReturnValueSlot ReturnSlot,
                       QualType ResultType,
                       Selector Sel,
                       llvm::Value *Receiver,
@@ -134,6 +135,7 @@ public:
   /// a property setter or getter.
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot ReturnSlot,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
index bac05ba70512d02f31648bd3686a5d3781ceb156..dcc65cc2e8077d2d0404c93f0f3b94e06d803d24 100644 (file)
@@ -1150,9 +1150,12 @@ public:
   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
-  RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
-  RValue EmitObjCPropertyGet(const Expr *E);
-  RValue EmitObjCSuperPropertyGet(const Expr *Exp, const Selector &S);
+  RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
+                             ReturnValueSlot Return = ReturnValueSlot());
+  RValue EmitObjCPropertyGet(const Expr *E,
+                             ReturnValueSlot Return = ReturnValueSlot());
+  RValue EmitObjCSuperPropertyGet(const Expr *Exp, const Selector &S,
+                                  ReturnValueSlot Return = ReturnValueSlot());
   void EmitObjCPropertySet(const Expr *E, RValue Src);
   void EmitObjCSuperPropertySet(const Expr *E, const Selector &S, RValue Src);