summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/CodeGen/CGExprScalar.cpp')
-rw-r--r--clang/CodeGen/CGExprScalar.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/clang/CodeGen/CGExprScalar.cpp b/clang/CodeGen/CGExprScalar.cpp
index 85831d5dd36..52b022b6611 100644
--- a/clang/CodeGen/CGExprScalar.cpp
+++ b/clang/CodeGen/CGExprScalar.cpp
@@ -41,9 +41,14 @@ class VISIBILITY_HIDDEN ScalarExprEmitter
: public StmtVisitor<ScalarExprEmitter, Value*> {
CodeGenFunction &CGF;
llvm::LLVMFoldingBuilder &Builder;
+ CGObjCRuntime *Runtime;
+
+
public:
- ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
+ ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf),
+ Builder(CGF.Builder),
+ Runtime(CGF.CGM.getObjCRuntime()) {
}
@@ -120,6 +125,7 @@ public:
return llvm::ConstantInt::get(EC->getInitVal());
return EmitLoadOfLValue(E);
}
+ Value *VisitObjCMessageExpr(ObjCMessageExpr *E);
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }
Value *VisitOCUVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
@@ -443,6 +449,47 @@ Value *ScalarExprEmitter::VisitExpr(Expr *E) {
return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
}
+Value *ScalarExprEmitter::VisitObjCMessageExpr(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.
+
+ // Find the receiver
+ llvm::Value * Receiver = CGF.EmitScalarExpr(E->getReceiver());
+
+ // Process the arguments
+ unsigned int ArgC = E->getNumArgs();
+ llvm::SmallVector<llvm::Value*, 16> Args;
+ for(unsigned i=0 ; i<ArgC ; i++) {
+ Expr *ArgExpr = E->getArg(i);
+ QualType ArgTy = ArgExpr->getType();
+ if (!CGF.hasAggregateLLVMType(ArgTy)) {
+ // Scalar argument is passed by-value.
+ Args.push_back(CGF.EmitScalarExpr(ArgExpr));
+ } else if (ArgTy->isComplexType()) {
+ // Make a temporary alloca to pass the argument.
+ llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
+ CGF.EmitComplexExprIntoAddr(ArgExpr, DestMem, false);
+ Args.push_back(DestMem);
+ } else {
+ llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
+ CGF.EmitAggExpr(ArgExpr, DestMem, false);
+ Args.push_back(DestMem);
+ }
+ }
+
+ // Get the selector string
+ std::string SelStr = E->getSelector().getName();
+ llvm::Constant *Selector = CGF.CGM.GetAddrOfConstantString(SelStr);
+ ConvertType(E->getType());
+ return Runtime->generateMessageSend(Builder,
+ ConvertType(E->getType()),
+ Receiver,
+ Selector,
+ &Args[0],
+ Args.size());
+}
+
Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
// Emit subscript expressions in rvalue context's. For most cases, this just
// loads the lvalue formed by the subscript expr. However, we have to be
OpenPOWER on IntegriCloud