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.

llvm-svn: 54838
This commit is contained in:
Daniel Dunbar 2008-08-16 03:19:19 +00:00
parent 8bc821ae7c
commit a94ecd2a0b
6 changed files with 93 additions and 50 deletions

View File

@ -191,7 +191,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
/// Emit an alloca (or GlobalValue depending on target)
/// for the specified parameter and set up LocalDeclMap.
void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) {
void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) {
// FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
assert(isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) &&
"Invalid argument to EmitParmDecl");
QualType Ty = D.getType();
llvm::Value *DeclPtr;

View File

@ -124,45 +124,31 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
// Emit allocs for param decls. Give the LLVM Argument nodes names.
llvm::Function::arg_iterator AI = CurFn->arg_begin();
// Name the struct return argument.
if (hasAggregateLLVMType(OMD->getResultType())) {
AI->setName("agg.result");
++AI;
}
// Add implicit parameters to the decl map.
// TODO: Add something to AST to let the runtime specify the names and types
// of these.
llvm::Value *&SelfEntry = LocalDeclMap[OMD->getSelfDecl()];
const llvm::Type *IPTy = AI->getType();
llvm::Value *DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
".addr", AllocaInsertPt);
// Store the initial value into the alloca.
Builder.CreateStore(AI, DeclPtr);
SelfEntry = DeclPtr;
// Add implicit parameters to the decl map.
EmitParmDecl(*OMD->getSelfDecl(), AI);
++AI;
EmitParmDecl(*OMD->getCmdDecl(), AI);
++AI;
llvm::Value *&CmdEntry = LocalDeclMap[OMD->getCmdDecl()];
IPTy = AI->getType();
DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
".addr", AllocaInsertPt);
// Store the initial value into the alloca.
Builder.CreateStore(AI, DeclPtr);
CmdEntry = DeclPtr;
for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
assert(AI != CurFn->arg_end() && "Argument mismatch!");
EmitParmDecl(*OMD->getParamDecl(i), AI);
}
assert(AI == CurFn->arg_end() && "Argument mismatch");
GenerateFunction(OMD->getBody());
}
llvm::Value *CodeGenFunction::LoadObjCSelf(void)
{
if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl)) {
ValueDecl *Decl = OMD->getSelfDecl();
llvm::Value *SelfPtr = LocalDeclMap[&(*(Decl))];
return Builder.CreateLoad(SelfPtr, "self");
}
return NULL;
llvm::Value *CodeGenFunction::LoadObjCSelf(void) {
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
}
CGObjCRuntime::~CGObjCRuntime() {}

View File

@ -951,16 +951,6 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD) {
llvm::GlobalValue::InternalLinkage,
FunctionName,
&TheModule);
llvm::Function::arg_iterator AI = Method->arg_begin();
// Name the struct return argument.
// FIXME: This is probably the wrong test.
if (!ReturnTy->isFirstClassType() && ReturnTy != llvm::Type::VoidTy) {
AI->setName("agg.result");
++AI;
}
AI->setName("self");
++AI;
AI->setName("_cmd");
return Method;
}

View File

@ -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 @@ private:
/// 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::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
}
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 @@ llvm::Function *CGObjCMac::ModuleInitFunction() {
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 @@ llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
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();

View File

@ -298,6 +298,8 @@ public:
const llvm::Type *ConvertType(QualType T);
/// LoadObjCSelf - Load the value of self. This function is only
/// valid while generating code for an Objective-C method.
llvm::Value *LoadObjCSelf();
/// isObjCPointerType - Return true if the specificed AST type will map onto
@ -368,7 +370,9 @@ public:
void EmitBlockVarDecl(const VarDecl &D);
void EmitLocalBlockVarDecl(const VarDecl &D);
void EmitStaticBlockVarDecl(const VarDecl &D);
void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
/// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
void EmitParmDecl(const VarDecl &D, llvm::Value *Arg);
//===--------------------------------------------------------------------===//
// Statement Emission

View File

@ -166,11 +166,6 @@ void CodeGenModule::EmitAnnotations() {
gv->setSection("llvm.metadata");
}
bool hasAggregateLLVMType(QualType T) {
return !T->isRealType() && !T->isPointerLikeType() &&
!T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
}
void CodeGenModule::SetGlobalValueAttributes(const FunctionDecl *FD,
llvm::GlobalValue *GV) {
// TODO: Set up linkage and many other things. Note, this is a simple
@ -208,7 +203,7 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
if (FuncAttrs)
ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
// Note that there is parallel code in CodeGenFunction::EmitCallExpr
bool AggregateReturn = hasAggregateLLVMType(FD->getResultType());
bool AggregateReturn = CodeGenFunction::hasAggregateLLVMType(FD->getResultType());
if (AggregateReturn)
ParamAttrList.push_back(
llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet));