[cfe-commits] r52681 - in /cfe/trunk/lib/CodeGen: CGExprAgg.cpp CGObjC.cpp CGObjCGNU.cpp CodeGenFunction.h
Chris Lattner
sabre at nondot.org
Tue Jun 24 10:04:18 PDT 2008
Author: lattner
Date: Tue Jun 24 12:04:18 2008
New Revision: 52681
URL: http://llvm.org/viewvc/llvm-project?rev=52681&view=rev
Log:
"Support for Objective-C message sends which return structures. Also includes a small fix for constant string handling that should have been in the last patch (sorry!) and a hook for generating selectors (rest of this implementation to follow in the next patch)."
Patch by David Chisnall!
Modified:
cfe/trunk/lib/CodeGen/CGExprAgg.cpp
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=52681&r1=52680&r2=52681&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Tue Jun 24 12:04:18 2008
@@ -86,6 +86,8 @@
void VisitOverloadExpr(const OverloadExpr *E);
void VisitBinComma(const BinaryOperator *E);
+ void VisitObjCMessageExpr(ObjCMessageExpr *E);
+
void VisitConditionalOperator(const ConditionalOperator *CO);
void VisitInitListExpr(InitListExpr *E);
@@ -202,6 +204,16 @@
EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
}
+void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E)
+{
+ RValue RV = RValue::getAggregate(CGF.EmitObjCMessageExpr(E));
+
+ // If the result is ignored, don't copy from the value.
+ if (DestPtr == 0)
+ return;
+
+ EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
+}
void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E)
{
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=52681&r1=52680&r2=52681&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Jun 24 12:04:18 2008
@@ -21,9 +21,88 @@
using namespace clang;
using namespace CodeGen;
+/// Emits an instance of NSConstantString representing the object.
llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
- std::string S(E->getString()->getStrData(), E->getString()->getByteLength());
- return CGM.GetAddrOfConstantCFString(S);
+ return CGM.getObjCRuntime()->GenerateConstantString(
+ E->getString()->getStrData(), E->getString()->getByteLength());
+}
+
+/// Emit a selector.
+llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
+ // Untyped selector.
+ // Note that this implementation allows for non-constant strings to be passed
+ // as arguments to @selector(). Currently, the only thing preventing this
+ // behaviour is the type checking in the front end.
+ return CGM.getObjCRuntime()->GetSelector(Builder,
+ CGM.GetAddrOfConstantString(E->getSelector().getName()), 0);
+}
+
+
+
+llvm::Value *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.
+
+ CGObjCRuntime *Runtime = CGM.getObjCRuntime();
+ const Expr *ReceiverExpr = E->getReceiver();
+ bool isSuperMessage = false;
+ // Find the receiver
+ llvm::Value *Receiver;
+ if (!ReceiverExpr) {
+ const char * classname = E->getClassName()->getName();
+ if (!strcmp(classname, "super")) {
+ classname = E->getMethodDecl()->getClassInterface()->getName();
+ }
+ llvm::Value *ClassName = CGM.GetAddrOfConstantString(classname);
+ ClassName = Builder.CreateStructGEP(ClassName, 0);
+ Receiver = Runtime->LookupClass(Builder, ClassName);
+ } else if (dyn_cast<PreDefinedExpr>(E->getReceiver())) {
+ isSuperMessage = true;
+ Receiver = LoadObjCSelf();
+ } else {
+ 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);
+ }
+ }
+
+ // Get the selector string
+ std::string SelStr = E->getSelector().getName();
+ llvm::Constant *Selector = CGM.GetAddrOfConstantString(SelStr);
+
+ llvm::Value *SelPtr = Builder.CreateStructGEP(Selector, 0);
+ if (isSuperMessage) {
+ const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl);
+ assert(OMD && "super is only valid in an Objective-C method");
+ const char *SuperClass = OMD->getClassInterface()->getSuperClass()->getName();
+ return Runtime->GenerateMessageSendSuper(Builder, ConvertType(E->getType()),
+ Receiver, SuperClass,
+ Receiver, SelPtr,
+ &Args[0], Args.size());
+ }
+ return Runtime->GenerateMessageSend(Builder, ConvertType(E->getType()),
+ LoadObjCSelf(),
+ Receiver, SelPtr,
+ &Args[0], Args.size());
}
/// Generate an Objective-C method. An Objective-C method is a C function with
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=52681&r1=52680&r2=52681&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Tue Jun 24 12:04:18 2008
@@ -405,11 +405,14 @@
if (!ReturnTy->isSingleValueType()) {
llvm::Value *Return = Builder.CreateAlloca(ReturnTy);
Args.push_back(Return);
- return 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());
}
@@ -887,7 +890,7 @@
bool isClassMethod,
bool isVarArg) {
std::vector<const llvm::Type*> Args;
- if (!ReturnTy->isFirstClassType() && ReturnTy != llvm::Type::VoidTy) {
+ if (!ReturnTy->isSingleValueType() && ReturnTy != llvm::Type::VoidTy) {
Args.push_back(llvm::PointerType::getUnqual(ReturnTy));
ReturnTy = llvm::Type::VoidTy;
}
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=52681&r1=52680&r2=52681&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jun 24 12:04:18 2008
@@ -451,6 +451,10 @@
bool isSplat = false);
llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
+ llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
+ llvm::Value *EmitObjCMessageExpr(const ObjCMessageExpr *E);
+
+
//===--------------------------------------------------------------------===//
// Expression Emission
More information about the cfe-commits
mailing list