forked from OSchip/llvm-project
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:
parent
8bc821ae7c
commit
a94ecd2a0b
|
@ -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;
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue