Add NeXT runtime support for generating methods.
Change CodeGenFunction::EmitParmDecl to take either a ParmVarDecl or an
ImplicitParamDecl.
Drop hasAggregateLLVMType from CodeGenModule.cpp (use version in
CodeGenFunction).
Change the Objective-C method generation to use EmitParmDecl for
implicit parameters.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54838 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 61b9534..8cb1536 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -14,6 +14,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"
@@ -22,6 +23,7 @@
#include "llvm/Module.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Target/TargetData.h"
+#include <sstream>
using namespace clang;
@@ -194,6 +196,11 @@
/// the name.
llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
+ /// GetNameForMethod - Return a name for the given method.
+ /// \param[out] NameOut - The return value.
+ void GetNameForMethod(const ObjCMethodDecl *OMD,
+ std::string &NameOut);
+
public:
CGObjCMac(CodeGen::CodeGenModule &cgm);
virtual llvm::Constant *GenerateConstantString(const std::string &String);
@@ -606,7 +613,57 @@
}
void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ClassDecl) {
- assert(0 && "Cannot generate class for Mac runtime.");
+ //assert(0 && "Cannot generate class for Mac runtime.");
+}
+
+llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
+ const llvm::Type *ReturnTy =
+ CGM.getTypes().ConvertReturnType(OMD->getResultType());
+ const llvm::Type *SelfTy =
+ CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
+
+ std::vector<const llvm::Type*> ArgTys;
+ ArgTys.reserve(1 + 2 + OMD->param_size());
+
+ // FIXME: This is not something we should have to be dealing with
+ // here.
+ bool useStructRet =
+ CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
+ if (useStructRet) {
+ ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
+ ReturnTy = llvm::Type::VoidTy;
+ }
+
+ // Implicit arguments
+ ArgTys.push_back(SelfTy);
+ ArgTys.push_back(ObjCTypes.SelectorPtrTy);
+
+ for (ObjCMethodDecl::param_const_iterator
+ i = OMD->param_begin(), e = OMD->param_end();
+ i != e; ++i) {
+ const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
+ if (Ty->isFirstClassType()) {
+ ArgTys.push_back(Ty);
+ } else {
+ ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
+ }
+ }
+
+ std::string Name;
+ GetNameForMethod(OMD, Name);
+
+ llvm::Function *Method =
+ llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
+ ArgTys,
+ OMD->isVariadic()),
+ llvm::GlobalValue::InternalLinkage,
+ Name,
+ &CGM.getModule());
+
+ if (useStructRet)
+ Method->addParamAttr(1, llvm::ParamAttr::StructRet);
+
+ return Method;
}
llvm::Function *CGObjCMac::ModuleInitFunction() {
@@ -616,11 +673,6 @@
return NULL;
}
-llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
- assert(0 && "Cannot generate method preamble for Mac runtime.");
- return 0;
-}
-
/* *** Private Interface *** */
/// EmitImageInfo - Emit the image info marker used to encode some module
@@ -786,6 +838,19 @@
return getConstantGEP(Entry, 0, 0);
}
+void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
+ std::string &NameOut) {
+ // FIXME: Find the mangling GCC uses.
+ std::stringstream s;
+ s << (D->isInstance() ? "-" : "+");
+ s << "[";
+ s << D->getClassInterface()->getName();
+ s << " ";
+ s << D->getSelector().getName();
+ s << "]";
+ NameOut = s.str();
+}
+
void CGObjCMac::FinishModule() {
EmitModuleInfo();