This patch adds support for sender-aware dispatch in Objective-C for the GNU runtime, when
compiled with -fobjc-sender-dependent-dispatch. This is used in AOP, COP, implementing object planes, and a few other things. Patch by David Chisnall. llvm-svn: 72275
This commit is contained in:
		
							parent
							
								
									162af638a9
								
							
						
					
					
						commit
						a4404f21d1
					
				| 
						 | 
				
			
			@ -36,6 +36,8 @@ public:
 | 
			
		|||
    
 | 
			
		||||
  unsigned ObjC1             : 1;  // Objective-C 1 support enabled.
 | 
			
		||||
  unsigned ObjC2             : 1;  // Objective-C 2 support enabled.
 | 
			
		||||
  unsigned ObjCSenderDispatch: 1;  // Objective-C 2 three-dimensional dispatch
 | 
			
		||||
                                   // enabled.
 | 
			
		||||
  unsigned ObjCNonFragileABI : 1;  // Objective-C modern abi enabled
 | 
			
		||||
    
 | 
			
		||||
  unsigned PascalStrings     : 1;  // Allow Pascal strings
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -425,6 +425,7 @@ OPTION("-fobjc-gc-only", fobjc_gc_only, Flag, f_Group, INVALID, "", 0, 0, 0)
 | 
			
		|||
OPTION("-fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, "", 0, 0, 0)
 | 
			
		||||
OPTION("-fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
 | 
			
		||||
OPTION("-fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, "", 0, 0, 0)
 | 
			
		||||
OPTION("-fobjc-sender-dependent-dispatch", fobjc_sender_dependent_dispatch, Flag, f_Group, INVALID, "", 0, 0, 0)
 | 
			
		||||
OPTION("-fobjc-tight-layout", fobjc_tight_layout, Flag, f_Group, INVALID, "", 0, 0, 0)
 | 
			
		||||
OPTION("-fobjc", fobjc, Flag, f_Group, INVALID, "", 0, 0, 0)
 | 
			
		||||
OPTION("-fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -417,8 +417,8 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
 | 
			
		|||
  CallArgList ActualArgs;
 | 
			
		||||
 | 
			
		||||
  ActualArgs.push_back(
 | 
			
		||||
	  std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 
 | 
			
		||||
	  CGF.getContext().getObjCIdType()));
 | 
			
		||||
    std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 
 | 
			
		||||
    CGF.getContext().getObjCIdType()));
 | 
			
		||||
  ActualArgs.push_back(std::make_pair(RValue::get(cmd),
 | 
			
		||||
                                      CGF.getContext().getObjCSelType()));
 | 
			
		||||
  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
 | 
			
		||||
| 
						 | 
				
			
			@ -427,15 +427,36 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
 | 
			
		|||
  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
 | 
			
		||||
  const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false);
 | 
			
		||||
 | 
			
		||||
  llvm::Value *imp;
 | 
			
		||||
  std::vector<const llvm::Type*> Params;
 | 
			
		||||
  Params.push_back(Receiver->getType());
 | 
			
		||||
  Params.push_back(SelectorTy);
 | 
			
		||||
  llvm::Constant *lookupFunction = 
 | 
			
		||||
    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
 | 
			
		||||
          llvm::PointerType::getUnqual(impType), Params, true),
 | 
			
		||||
        "objc_msg_lookup");
 | 
			
		||||
  // For sender-aware dispatch, we pass the sender as the third argument to a
 | 
			
		||||
  // lookup function.  When sending messages from C code, the sender is nil.
 | 
			
		||||
  // objc_msg_lookup_sender(id receiver, SEL selector, id sender);
 | 
			
		||||
  if (CGM.getContext().getLangOptions().ObjCSenderDispatch) {
 | 
			
		||||
    llvm::Value *self;
 | 
			
		||||
 | 
			
		||||
  llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
 | 
			
		||||
    if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) {
 | 
			
		||||
      self = CGF.LoadObjCSelf();
 | 
			
		||||
    } else {
 | 
			
		||||
      self = llvm::ConstantPointerNull::get(IdTy);
 | 
			
		||||
    }
 | 
			
		||||
    Params.push_back(self->getType());
 | 
			
		||||
    llvm::Constant *lookupFunction = 
 | 
			
		||||
      CGM.CreateRuntimeFunction(llvm::FunctionType::get(
 | 
			
		||||
          llvm::PointerType::getUnqual(impType), Params, true),
 | 
			
		||||
        "objc_msg_lookup_sender");
 | 
			
		||||
 | 
			
		||||
    imp = CGF.Builder.CreateCall3(lookupFunction, Receiver, cmd, self);
 | 
			
		||||
  } else {
 | 
			
		||||
    llvm::Constant *lookupFunction = 
 | 
			
		||||
    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
 | 
			
		||||
        llvm::PointerType::getUnqual(impType), Params, true),
 | 
			
		||||
      "objc_msg_lookup");
 | 
			
		||||
 | 
			
		||||
    imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return CGF.EmitCall(FnInfo, imp, ActualArgs);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -479,6 +479,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 | 
			
		|||
  Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
 | 
			
		||||
  Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only);
 | 
			
		||||
  Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc);
 | 
			
		||||
  Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
 | 
			
		||||
  // FIXME: Should we remove this?
 | 
			
		||||
  Args.AddLastArg(CmdArgs, options::OPT_fobjc_nonfragile_abi);
 | 
			
		||||
  Args.AddLastArg(CmdArgs, options::OPT_fobjc_tight_layout);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,6 +280,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
 | 
			
		|||
  if (LangOpts.ObjC2)
 | 
			
		||||
    DefineBuiltinMacro(Buf, "OBJC_NEW_PROPERTIES");
 | 
			
		||||
 | 
			
		||||
  if (LangOpts.ObjCSenderDispatch)
 | 
			
		||||
    DefineBuiltinMacro(Buf, "__OBJC_SENDER_AWARE_DISPATCH__");
 | 
			
		||||
 | 
			
		||||
  if (LangOpts.PascalStrings)
 | 
			
		||||
    DefineBuiltinMacro(Buf, "__PASCAL_STRINGS__");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -445,6 +445,10 @@ OverflowChecking("ftrapv",
 | 
			
		|||
                 llvm::cl::desc("Trap on integer overflow"),
 | 
			
		||||
                 llvm::cl::init(false));
 | 
			
		||||
 | 
			
		||||
static llvm::cl::opt<bool>
 | 
			
		||||
ObjCSenderDispatch("fobjc-sender-dependent-dispatch",
 | 
			
		||||
				 llvm::cl::desc("Enable sender-dependent dispatch for"
 | 
			
		||||
					 "Objective-C messages"), llvm::cl::init(false));
 | 
			
		||||
 | 
			
		||||
/// InitializeBaseLanguage - Handle the -x foo options.
 | 
			
		||||
static void InitializeBaseLanguage() {
 | 
			
		||||
| 
						 | 
				
			
			@ -828,6 +832,8 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
 | 
			
		|||
  if (ObjCNonFragileABI)
 | 
			
		||||
    Options.ObjCNonFragileABI = 1;
 | 
			
		||||
 | 
			
		||||
  Options.ObjCSenderDispatch = ObjCSenderDispatch;
 | 
			
		||||
  
 | 
			
		||||
  if (EmitAllDecls)
 | 
			
		||||
    Options.EmitAllDecls = 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue