mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 00:55:49 +03:00
Only non-typesafe variadics need to take LLVM varargs (#2127)
* gen/functions: Re-clang-format, minor style cleanup [nfc] * Only non-typesafe variadics need to take LLVM varargs GitHub: Fixes #2121.
This commit is contained in:
parent
ebfdc25323
commit
c9112f3daf
3 changed files with 34 additions and 37 deletions
|
@ -123,20 +123,14 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
|
|||
++nextLLArgIdx;
|
||||
}
|
||||
|
||||
// vararg functions are special too
|
||||
if (f->varargs) {
|
||||
if (f->linkage == LINKd) {
|
||||
// d style with hidden args
|
||||
// 2 (array) is handled by the frontend
|
||||
if (f->varargs == 1) {
|
||||
// _arguments
|
||||
newIrFty.arg_arguments =
|
||||
new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
|
||||
++nextLLArgIdx;
|
||||
}
|
||||
}
|
||||
|
||||
newIrFty.c_vararg = true;
|
||||
// Non-typesafe variadics (both C and D styles) are also variadics on the LLVM
|
||||
// level.
|
||||
const bool isLLVMVariadic = (f->varargs == 1);
|
||||
if (isLLVMVariadic && f->linkage == LINKd) {
|
||||
// Add extra `_arguments` parameter for D-style variadic functions.
|
||||
newIrFty.arg_arguments =
|
||||
new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
|
||||
++nextLLArgIdx;
|
||||
}
|
||||
|
||||
// if this _Dmain() doesn't have an argument, we force it to have one
|
||||
|
@ -226,7 +220,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
|
|||
}
|
||||
|
||||
irFty.funcType =
|
||||
LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg);
|
||||
LLFunctionType::get(irFty.ret->ltype, argtypes, isLLVMVariadic);
|
||||
|
||||
IF_LOG Logger::cout() << "Final function type: " << *irFty.funcType << "\n";
|
||||
|
||||
|
@ -518,15 +512,13 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
|||
vafunc = DtoDeclareVaFunction(fdecl);
|
||||
}
|
||||
|
||||
// calling convention
|
||||
LINK link = f->linkage;
|
||||
if (vafunc || DtoIsIntrinsic(fdecl)
|
||||
// DMD treats _Dmain as having C calling convention and this has been
|
||||
// hardcoded into druntime, even if the frontend type has D linkage.
|
||||
// See Bugzilla issue 9028.
|
||||
|| fdecl->isMain()) {
|
||||
link = LINKc;
|
||||
}
|
||||
// Calling convention.
|
||||
//
|
||||
// DMD treats _Dmain as having C calling convention and this has been
|
||||
// hardcoded into druntime, even if the frontend type has D linkage (Bugzilla
|
||||
// issue 9028).
|
||||
const bool forceC = vafunc || DtoIsIntrinsic(fdecl) || fdecl->isMain();
|
||||
const auto link = forceC ? LINKc : f->linkage;
|
||||
|
||||
// mangled name
|
||||
std::string mangledName = getMangledName(fdecl, link);
|
||||
|
@ -540,8 +532,9 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
|||
func = LLFunction::Create(functype, llvm::GlobalValue::ExternalLinkage,
|
||||
mangledName, &gIR->module);
|
||||
} else if (func->getFunctionType() != functype) {
|
||||
error(fdecl->loc, "Function type does not match previously declared "
|
||||
"function with the same mangled name: %s",
|
||||
error(fdecl->loc,
|
||||
"Function type does not match previously declared "
|
||||
"function with the same mangled name: %s",
|
||||
mangleExact(fdecl));
|
||||
fatal();
|
||||
}
|
||||
|
@ -793,8 +786,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
llvm::Function *func = getIrFunc(fd)->getLLVMFunc();
|
||||
assert(nullptr != func);
|
||||
if (!linkageAvailableExternally &&
|
||||
(func->getLinkage() ==
|
||||
llvm::GlobalValue::AvailableExternallyLinkage)) {
|
||||
(func->getLinkage() == llvm::GlobalValue::AvailableExternallyLinkage)) {
|
||||
// Fix linkage
|
||||
const auto lwc = lowerFuncLinkage(fd);
|
||||
setLinkage(lwc, func);
|
||||
|
@ -817,8 +809,9 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
// This function failed semantic3() with errors but the errors were gagged.
|
||||
// In contrast to DMD we immediately bail out here, since other parts of
|
||||
// the codegen expect irFunc to be set for defined functions.
|
||||
error(fd->loc, "Internal Compiler Error: function not fully analyzed; "
|
||||
"previous unreported errors compiling %s?",
|
||||
error(fd->loc,
|
||||
"Internal Compiler Error: function not fully analyzed; "
|
||||
"previous unreported errors compiling %s?",
|
||||
fd->toPrettyChars());
|
||||
fatal();
|
||||
}
|
||||
|
@ -878,8 +871,9 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
assert(fd->ident != Id::empty);
|
||||
|
||||
if (fd->semanticRun != PASSsemantic3done) {
|
||||
error(fd->loc, "Internal Compiler Error: function not fully analyzed; "
|
||||
"previous unreported errors compiling %s?",
|
||||
error(fd->loc,
|
||||
"Internal Compiler Error: function not fully analyzed; "
|
||||
"previous unreported errors compiling %s?",
|
||||
fd->toPrettyChars());
|
||||
fatal();
|
||||
}
|
||||
|
@ -1063,8 +1057,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
gIR->scopebb());
|
||||
|
||||
// copy _arguments to a memory location
|
||||
irFunc->_arguments =
|
||||
DtoAllocaDump(irFunc->_arguments, 0, "_arguments_mem");
|
||||
irFunc->_arguments = DtoAllocaDump(irFunc->_arguments, 0, "_arguments_mem");
|
||||
|
||||
// Push cleanup block that calls va_end to match the va_start call.
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue