// Parameters fnames are assumed to be already mangled! static void createFwdDecl(LINK linkage, Type *returntype, ArrayParam<llvm::StringRef> fnames, ArrayParam<Type *> paramtypes, ArrayParam<StorageClass> paramsSTC = {}, AttrSet attribset = AttrSet()) { Parameters *params = nullptr; if (!paramtypes.empty()) { params = new Parameters(); for (size_t i = 0, e = paramtypes.size(); i < e; ++i) { StorageClass stc = paramsSTC.empty() ? 0 : paramsSTC[i]; params->push(new Parameter(stc, paramtypes[i], nullptr, nullptr)); } } int varargs = 0; auto dty = new TypeFunction(params, returntype, varargs, linkage); // the call to DtoType performs many actions such as rewriting the function // type and storing it in dty auto llfunctype = llvm::cast<llvm::FunctionType>(DtoType(dty)); assert(dty->ctype); auto attrs = dty->ctype->getIrFuncTy().getParamAttrs(gABI->passThisBeforeSret(dty)); attrs.merge(attribset); for (auto fname : fnames) { llvm::Function *fn = llvm::Function::Create( llfunctype, llvm::GlobalValue::ExternalLinkage, fname, M); fn->setAttributes(attrs); fn->setCallingConv(gABI->callingConv(fn->getFunctionType(), linkage)); } }
// Parameters fnames are assumed to be already mangled! static void createFwdDecl(LINK linkage, Type *returntype, ArrayParam<llvm::StringRef> fnames, ArrayParam<Type *> paramtypes, ArrayParam<StorageClass> paramsSTC = {}, AttrSet attribset = AttrSet()) { Parameters *params = nullptr; if (!paramtypes.empty()) { params = new Parameters(); for (size_t i = 0, e = paramtypes.size(); i < e; ++i) { StorageClass stc = paramsSTC.empty() ? 0 : paramsSTC[i]; params->push(Parameter::create(stc, paramtypes[i], nullptr, nullptr)); } } int varargs = 0; auto dty = TypeFunction::create(params, returntype, varargs, linkage); // the call to DtoType performs many actions such as rewriting the function // type and storing it in dty auto llfunctype = llvm::cast<llvm::FunctionType>(DtoType(dty)); assert(dty->ctype); auto attrs = dty->ctype->getIrFuncTy().getParamAttrs(gABI->passThisBeforeSret(dty)); attrs.merge(attribset); for (auto fname : fnames) { llvm::Function *fn = llvm::Function::Create( llfunctype, llvm::GlobalValue::ExternalLinkage, fname, M); fn->setAttributes(attrs); // On x86_64, always set 'uwtable' for System V ABI compatibility. // FIXME: Move to better place (abi-x86-64.cpp?) // NOTE: There are several occurances if this line. if (global.params.targetTriple->getArch() == llvm::Triple::x86_64) { fn->addFnAttr(LLAttribute::UWTable); } fn->setCallingConv(gABI->callingConv(fn->getFunctionType(), linkage)); } }