mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-02 18:58:15 +00:00
Trim CGObjCRuntime::GenerateMessageSend[Super]
- Returns an RValue. - Reduced to only taking the CodeGenFunction, Expr, and Receiver. - Becomes responsible for emitting the arguments. Add CodeGenFunction::EmitCallExprExt - Takes optional extra arguments to insert at the head of the call. - This allows the Obj-C runtimes to call into this and isolates the argument and call instruction generation code to one place. Upshot is that we now pass structures (more) correctly. Also, fix one aspect of generating methods which take structure arguments (for NeXT). This probably needs to be merged with the SetFunctionAttributes code in CodeGenModule.cpp llvm-svn: 55223
This commit is contained in:
parent
f440440616
commit
97db84ce6d
@ -776,7 +776,15 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,
|
||||
// type.
|
||||
FnType = FnType->getAsPointerType()->getPointeeType();
|
||||
QualType ResultType = FnType->getAsFunctionType()->getResultType();
|
||||
return EmitCallExprExt(Callee, ResultType, ArgBeg, ArgEnd, 0, 0);
|
||||
}
|
||||
|
||||
RValue CodeGenFunction::EmitCallExprExt(llvm::Value *Callee,
|
||||
QualType ResultType,
|
||||
CallExpr::const_arg_iterator ArgBeg,
|
||||
CallExpr::const_arg_iterator ArgEnd,
|
||||
llvm::Value **ExtraArgs,
|
||||
unsigned NumExtraArgs) {
|
||||
llvm::SmallVector<llvm::Value*, 16> Args;
|
||||
|
||||
// Handle struct-return functions by passing a pointer to the location that
|
||||
@ -787,6 +795,8 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,
|
||||
// FIXME: set the stret attribute on the argument.
|
||||
}
|
||||
|
||||
Args.insert(Args.end(), ExtraArgs, ExtraArgs + NumExtraArgs);
|
||||
|
||||
for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I) {
|
||||
QualType ArgTy = I->getType();
|
||||
|
||||
@ -812,7 +822,7 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,
|
||||
if (hasAggregateLLVMType(ResultType))
|
||||
ParamAttrList.push_back(
|
||||
llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet));
|
||||
unsigned increment = hasAggregateLLVMType(ResultType) ? 2 : 1;
|
||||
unsigned increment = NumExtraArgs + (hasAggregateLLVMType(ResultType) ? 2 : 1);
|
||||
|
||||
unsigned i = 0;
|
||||
for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I, ++i) {
|
||||
|
@ -202,10 +202,12 @@ void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
||||
RValue RV = RValue::getAggregate(CGF.EmitObjCMessageExpr(E));
|
||||
RValue RV = CGF.EmitObjCMessageExpr(E);
|
||||
assert(RV.isAggregate() && "Return value must be aggregate value!");
|
||||
|
||||
// If the result is ignored, don't copy from the value.
|
||||
if (DestPtr == 0)
|
||||
// FIXME: If the source is volatile, we must read from it.
|
||||
return;
|
||||
|
||||
EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
|
||||
|
@ -131,7 +131,6 @@ public:
|
||||
return llvm::ConstantInt::get(EC->getInitVal());
|
||||
return EmitLoadOfLValue(E);
|
||||
}
|
||||
Value *VisitObjCMessageExpr(ObjCMessageExpr *E);
|
||||
Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E);
|
||||
Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E);
|
||||
Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { return EmitLoadOfLValue(E);}
|
||||
@ -186,7 +185,11 @@ public:
|
||||
Value *VisitCallExpr(const CallExpr *E) {
|
||||
return CGF.EmitCallExpr(E).getScalarVal();
|
||||
}
|
||||
|
||||
|
||||
Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
||||
return CGF.EmitObjCMessageExpr(E).getScalarVal();
|
||||
}
|
||||
|
||||
Value *VisitStmtExpr(const StmtExpr *E);
|
||||
|
||||
// Unary Operators.
|
||||
@ -466,10 +469,6 @@ Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
||||
return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
||||
return CGF.EmitObjCMessageExpr(E);
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
||||
return CGF.EmitObjCSelectorExpr(E);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
|
||||
}
|
||||
|
||||
|
||||
llvm::Value *CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
|
||||
RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
|
||||
// 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.
|
||||
@ -74,38 +74,14 @@ llvm::Value *CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
|
||||
Receiver = EmitScalarExpr(E->getReceiver());
|
||||
}
|
||||
|
||||
// Process the arguments
|
||||
unsigned ArgC = E->getNumArgs();
|
||||
llvm::SmallVector<llvm::Value*, 16> Args;
|
||||
for (unsigned i = 0; i != ArgC; ++i) {
|
||||
const Expr *ArgExpr = E->getArg(i);
|
||||
QualType ArgTy = ArgExpr->getType();
|
||||
if (!hasAggregateLLVMType(ArgTy)) {
|
||||
// Scalar argument is passed by-value.
|
||||
Args.push_back(EmitScalarExpr(ArgExpr));
|
||||
} else if (ArgTy->isAnyComplexType()) {
|
||||
// Make a temporary alloca to pass the argument.
|
||||
llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
|
||||
EmitComplexExprIntoAddr(ArgExpr, DestMem, false);
|
||||
Args.push_back(DestMem);
|
||||
} else {
|
||||
llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
|
||||
EmitAggExpr(ArgExpr, DestMem, false);
|
||||
Args.push_back(DestMem);
|
||||
}
|
||||
}
|
||||
|
||||
if (isSuperMessage) {
|
||||
// super is only valid in an Objective-C method
|
||||
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
|
||||
return Runtime.GenerateMessageSendSuper(Builder, ConvertType(E->getType()),
|
||||
OMD->getClassInterface()->getSuperClass(),
|
||||
Receiver, E->getSelector(),
|
||||
&Args[0], Args.size());
|
||||
return Runtime.GenerateMessageSendSuper(*this, E,
|
||||
OMD->getClassInterface()->getSuperClass(),
|
||||
Receiver);
|
||||
}
|
||||
return Runtime.GenerateMessageSend(Builder, ConvertType(E->getType()),
|
||||
Receiver, E->getSelector(),
|
||||
&Args[0], Args.size());
|
||||
return Runtime.GenerateMessageSend(*this, E, Receiver);
|
||||
}
|
||||
|
||||
/// Generate an Objective-C method. An Objective-C method is a C function with
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "CGObjCRuntime.h"
|
||||
#include "CodeGenModule.h"
|
||||
#include "CodeGenFunction.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
@ -93,19 +94,15 @@ private:
|
||||
public:
|
||||
CGObjCGNU(CodeGen::CodeGenModule &cgm);
|
||||
virtual llvm::Constant *GenerateConstantString(const std::string &String);
|
||||
virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC);
|
||||
virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
const ObjCInterfaceDecl *SuperClass,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC);
|
||||
virtual CodeGen::RValue
|
||||
GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
llvm::Value *Receiver);
|
||||
virtual CodeGen::RValue
|
||||
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
const ObjCInterfaceDecl *Super,
|
||||
llvm::Value *Receiver);
|
||||
virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
|
||||
const ObjCInterfaceDecl *OID);
|
||||
virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
|
||||
@ -236,16 +233,15 @@ llvm::Constant *CGObjCGNU::GenerateConstantString(const std::string &Str) {
|
||||
///Generates a message send where the super is the receiver. This is a message
|
||||
///send to self with special delivery semantics indicating which class's method
|
||||
///should be called.
|
||||
llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
const ObjCInterfaceDecl *SuperClass,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC) {
|
||||
CodeGen::RValue
|
||||
CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
const ObjCInterfaceDecl *SuperClass,
|
||||
llvm::Value *Receiver) {
|
||||
const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
|
||||
// TODO: This should be cached, not looked up every time.
|
||||
llvm::Value *ReceiverClass = GetClass(Builder, SuperClass);
|
||||
llvm::Value *cmd = GetSelector(Builder, Sel);
|
||||
llvm::Value *ReceiverClass = GetClass(CGF.Builder, SuperClass);
|
||||
llvm::Value *cmd = GetSelector(CGF.Builder, E->getSelector());
|
||||
std::vector<const llvm::Type*> impArgTypes;
|
||||
impArgTypes.push_back(Receiver->getType());
|
||||
impArgTypes.push_back(SelectorTy);
|
||||
@ -257,10 +253,10 @@ llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
|
||||
// Construct the structure used to look up the IMP
|
||||
llvm::StructType *ObjCSuperTy = llvm::StructType::get(Receiver->getType(),
|
||||
IdTy, NULL);
|
||||
llvm::Value *ObjCSuper = Builder.CreateAlloca(ObjCSuperTy);
|
||||
llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy);
|
||||
// FIXME: volatility
|
||||
Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
|
||||
Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
|
||||
CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0));
|
||||
CGF.Builder.CreateStore(ReceiverClass, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
|
||||
|
||||
// Get the IMP
|
||||
llvm::Constant *lookupFunction =
|
||||
@ -269,25 +265,24 @@ llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
|
||||
llvm::PointerType::getUnqual(ObjCSuperTy),
|
||||
SelectorTy, NULL);
|
||||
llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
|
||||
llvm::Value *imp = Builder.CreateCall(lookupFunction, lookupArgs,
|
||||
llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
|
||||
lookupArgs+2);
|
||||
|
||||
// Call the method
|
||||
llvm::SmallVector<llvm::Value*, 8> callArgs;
|
||||
callArgs.push_back(Receiver);
|
||||
callArgs.push_back(cmd);
|
||||
callArgs.insert(callArgs.end(), ArgV, ArgV+ArgC);
|
||||
return Builder.CreateCall(imp, callArgs.begin(), callArgs.end());
|
||||
llvm::Value *Args[2];
|
||||
Args[0] = Receiver;
|
||||
Args[1] = cmd;
|
||||
return CGF.EmitCallExprExt(imp, E->getType(), E->arg_begin(), E->arg_end(),
|
||||
Args, 2);
|
||||
}
|
||||
|
||||
/// Generate code for a message send expression.
|
||||
llvm::Value *CGObjCGNU::GenerateMessageSend(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC) {
|
||||
llvm::Value *cmd = GetSelector(Builder, Sel);
|
||||
CodeGen::RValue
|
||||
CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
llvm::Value *Receiver) {
|
||||
const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
|
||||
llvm::Value *cmd = GetSelector(CGF.Builder, E->getSelector());
|
||||
|
||||
// Look up the method implementation.
|
||||
std::vector<const llvm::Type*> impArgTypes;
|
||||
@ -313,22 +308,14 @@ llvm::Value *CGObjCGNU::GenerateMessageSend(llvm::IRBuilder<> &Builder,
|
||||
TheModule.getOrInsertFunction("objc_msg_lookup",
|
||||
llvm::PointerType::getUnqual(impType),
|
||||
Receiver->getType(), SelectorTy, NULL);
|
||||
llvm::Value *imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
|
||||
llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
|
||||
|
||||
// Call the method.
|
||||
llvm::SmallVector<llvm::Value*, 16> Args;
|
||||
if (!ReturnTy->isSingleValueType()) {
|
||||
llvm::Value *Return = Builder.CreateAlloca(ReturnTy);
|
||||
Args.push_back(Return);
|
||||
}
|
||||
Args.push_back(Receiver);
|
||||
Args.push_back(cmd);
|
||||
Args.insert(Args.end(), ArgV, ArgV+ArgC);
|
||||
if (!ReturnTy->isSingleValueType()) {
|
||||
Builder.CreateCall(imp, Args.begin(), Args.end());
|
||||
return Args[0];
|
||||
}
|
||||
return Builder.CreateCall(imp, Args.begin(), Args.end());
|
||||
llvm::Value *Args[2];
|
||||
Args[0] = Receiver;
|
||||
Args[1] = cmd;
|
||||
return CGF.EmitCallExprExt(imp, E->getType(), E->arg_begin(), E->arg_end(),
|
||||
Args, 2);
|
||||
}
|
||||
|
||||
/// Generates a MethodList. Used in construction of a objc_class and
|
||||
|
@ -297,21 +297,15 @@ public:
|
||||
CGObjCMac(CodeGen::CodeGenModule &cgm);
|
||||
virtual llvm::Constant *GenerateConstantString(const std::string &String);
|
||||
|
||||
virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC);
|
||||
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
llvm::Value *Receiver);
|
||||
|
||||
virtual llvm::Value *
|
||||
GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
virtual CodeGen::RValue
|
||||
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
const ObjCInterfaceDecl *SuperClass,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC);
|
||||
llvm::Value *Receiver);
|
||||
|
||||
virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
|
||||
const ObjCInterfaceDecl *ID);
|
||||
@ -422,30 +416,24 @@ llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
|
||||
/// Generates a message send where the super is the receiver. This is
|
||||
/// a message send to self with special delivery semantics indicating
|
||||
/// which class's method should be called.
|
||||
llvm::Value *
|
||||
CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
CodeGen::RValue
|
||||
CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
const ObjCInterfaceDecl *SuperClass,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC) {
|
||||
llvm::Value *Receiver) {
|
||||
assert(0 && "Cannot generate message send to super for Mac runtime.");
|
||||
return 0;
|
||||
return CodeGen::RValue::get(0);
|
||||
}
|
||||
|
||||
/// Generate code for a message send expression.
|
||||
llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC) {
|
||||
CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
llvm::Value *Receiver) {
|
||||
const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
|
||||
llvm::Function *F = ObjCTypes.getMessageSendFn();
|
||||
llvm::Value **Args = new llvm::Value*[ArgC+2];
|
||||
Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
|
||||
Args[1] = EmitSelector(Builder, Sel);
|
||||
std::copy(ArgV, ArgV+ArgC, Args+2);
|
||||
llvm::Value *Args[2];
|
||||
Args[0] = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
|
||||
Args[1] = EmitSelector(CGF.Builder, E->getSelector());
|
||||
|
||||
std::vector<const llvm::Type*> Params;
|
||||
Params.push_back(ObjCTypes.ObjectPtrTy);
|
||||
@ -455,10 +443,10 @@ llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
|
||||
true);
|
||||
llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
|
||||
llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
|
||||
llvm::CallInst *CI = Builder.CreateCall(C,
|
||||
Args, Args+ArgC+2, "tmp");
|
||||
delete[] Args;
|
||||
return Builder.CreateBitCast(CI, ReturnTy, "tmp");
|
||||
return CGF.EmitCallExprExt(C, E->getType(),
|
||||
E->arg_begin(),
|
||||
E->arg_end(),
|
||||
Args, 2);
|
||||
}
|
||||
|
||||
llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
|
||||
@ -1185,7 +1173,7 @@ llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
|
||||
i = OMD->param_begin(), e = OMD->param_end();
|
||||
i != e; ++i) {
|
||||
const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
|
||||
if (Ty->isFirstClassType()) {
|
||||
if (Ty->isSingleValueType()) {
|
||||
ArgTys.push_back(Ty);
|
||||
} else {
|
||||
ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
|
||||
@ -1203,8 +1191,21 @@ llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
|
||||
Name,
|
||||
&CGM.getModule());
|
||||
|
||||
if (useStructRet)
|
||||
unsigned Offset = 3; // Return plus self and selector implicit args.
|
||||
if (useStructRet) {
|
||||
Method->addParamAttr(1, llvm::ParamAttr::StructRet);
|
||||
++Offset;
|
||||
}
|
||||
|
||||
// FIXME: This is horrible, we need to be reusing the machinery in
|
||||
// CodeGenModule.cpp (SetFunctionAttributes).
|
||||
for (ObjCMethodDecl::param_const_iterator
|
||||
i = OMD->param_begin(), e = OMD->param_end();
|
||||
i != e; ++i, ++Offset) {
|
||||
const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
|
||||
if (!Ty->isSingleValueType())
|
||||
Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
|
||||
}
|
||||
|
||||
return Method;
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "llvm/Support/IRBuilder.h"
|
||||
#include <string>
|
||||
|
||||
#include "CGValue.h"
|
||||
|
||||
namespace llvm {
|
||||
class Constant;
|
||||
class Type;
|
||||
@ -29,9 +31,14 @@ namespace llvm {
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
namespace CodeGen {
|
||||
class CodeGenFunction;
|
||||
}
|
||||
|
||||
class ObjCCategoryImplDecl;
|
||||
class ObjCImplementationDecl;
|
||||
class ObjCInterfaceDecl;
|
||||
class ObjCMessageExpr;
|
||||
class ObjCMethodDecl;
|
||||
class ObjCProtocolDecl;
|
||||
class Selector;
|
||||
@ -70,23 +77,18 @@ public:
|
||||
virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
|
||||
|
||||
/// Generate an Objective-C message send operation.
|
||||
virtual llvm::Value *GenerateMessageSend(BuilderType &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC) = 0;
|
||||
virtual CodeGen::RValue
|
||||
GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
llvm::Value *Receiver) = 0;
|
||||
|
||||
/// Generate an Objective-C message send operation to the super
|
||||
/// class.
|
||||
virtual llvm::Value *
|
||||
GenerateMessageSendSuper(llvm::IRBuilder<true> &Builder,
|
||||
const llvm::Type *ReturnTy,
|
||||
const ObjCInterfaceDecl *SuperClassName,
|
||||
llvm::Value *Receiver,
|
||||
Selector Sel,
|
||||
llvm::Value** ArgV,
|
||||
unsigned ArgC) = 0;
|
||||
virtual CodeGen::RValue
|
||||
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
||||
const ObjCMessageExpr *E,
|
||||
const ObjCInterfaceDecl *SuperClass,
|
||||
llvm::Value *Receiver) = 0;
|
||||
|
||||
/// Emit the code to return the named protocol as an object, as in a
|
||||
/// @protocol expression.
|
||||
|
@ -24,13 +24,13 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "CGValue.h"
|
||||
|
||||
namespace llvm {
|
||||
class BasicBlock;
|
||||
class Module;
|
||||
}
|
||||
|
||||
#include "CGValue.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class Decl;
|
||||
@ -286,6 +286,13 @@ public:
|
||||
CallExpr::const_arg_iterator ArgBeg,
|
||||
CallExpr::const_arg_iterator ArgEnd);
|
||||
|
||||
RValue EmitCallExprExt(llvm::Value *Callee,
|
||||
QualType ResultType,
|
||||
CallExpr::const_arg_iterator ArgBeg,
|
||||
CallExpr::const_arg_iterator ArgEnd,
|
||||
llvm::Value **ExtraArgs,
|
||||
unsigned NumExtraArgs);
|
||||
|
||||
RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
|
||||
llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
@ -298,7 +305,7 @@ public:
|
||||
llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
|
||||
llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
|
||||
llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
|
||||
llvm::Value *EmitObjCMessageExpr(const ObjCMessageExpr *E);
|
||||
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user