mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Fixed two issues with nested functions as template alias parameters.
Fixes #131 (GitHub).
This commit is contained in:
@@ -193,6 +193,14 @@ void DtoResolveNestedContext(Loc loc, ClassDeclaration *decl, LLValue *value)
|
||||
|
||||
// store into right location
|
||||
if (!llvm::dyn_cast<llvm::UndefValue>(nest)) {
|
||||
// Need to make sure the declaration has already been resolved, because
|
||||
// when multiple source files are specified on the command line, the
|
||||
// frontend sometimes adds "nested" (i.e. a template in module B
|
||||
// instantiated from module A with a type from module A instantiates
|
||||
// another template from module B) into the wrong module, messing up
|
||||
// our codegen order.
|
||||
DtoResolveDsymbol(decl);
|
||||
|
||||
size_t idx = decl->vthis->ir.irField->index;
|
||||
LLValue* gep = DtoGEPi(value,0,idx,".vthis");
|
||||
DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep);
|
||||
|
||||
@@ -324,18 +324,28 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
assert(0 && "not global/function");
|
||||
}
|
||||
|
||||
// The following breaks for nested naked functions and the implicitly
|
||||
// generated __require/__ensure functions for in/out contracts. The reason
|
||||
// If the function needs to be defined in the current module, check if it
|
||||
// is a nested function and we can declare it as internal.
|
||||
bool canInternalize = mustDefine;
|
||||
|
||||
// Nested naked functions and the implicitly generated __require/__ensure
|
||||
// functions for in/out contracts cannot be internalized. The reason
|
||||
// for the latter is that contract functions, despite being nested, can be
|
||||
// referenced from other D modules e.g. in the case of contracts on
|
||||
// interface methods (where __require/__ensure are emitted to the module
|
||||
// where the interface is declared, but an actual interface implementation
|
||||
// can be in a completely different place).
|
||||
bool skipNestedCheck = !mustDefine;
|
||||
if (!skipNestedCheck)
|
||||
if (canInternalize)
|
||||
{
|
||||
if (FuncDeclaration* fd = sym->isFuncDeclaration())
|
||||
skipNestedCheck = (fd->naked != 0) ||
|
||||
(fd->ident == Id::require) || (fd->ident == Id::ensure);
|
||||
{
|
||||
if ((fd->naked != 0) ||
|
||||
(fd->ident == Id::require) || (fd->ident == Id::ensure))
|
||||
{
|
||||
canInternalize = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Any symbol nested in a function that cannot be inlined can't be
|
||||
// referenced directly from outside that function, so we can give
|
||||
@@ -350,11 +360,26 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
// ---
|
||||
// if instances get emitted in multiple object files because they'd use
|
||||
// different instances of 'i'.
|
||||
if (!skipNestedCheck) {
|
||||
for (Dsymbol* parent = sym->parent; parent ; parent = parent->parent) {
|
||||
// TODO: Check if we are giving away too much inlining potential due to
|
||||
// canInline being overly conservative here.
|
||||
if (canInternalize)
|
||||
{
|
||||
for (Dsymbol* parent = sym->parent; parent ; parent = parent->parent)
|
||||
{
|
||||
FuncDeclaration *fd = parent->isFuncDeclaration();
|
||||
if (fd && !fd->canInline(fd->needThis()))
|
||||
return llvm::GlobalValue::InternalLinkage;
|
||||
{
|
||||
// We also cannot internalize nested functions which are
|
||||
// leaked to the outside via a templated return type, because
|
||||
// that type will also be codegen'd in any caller modules (see
|
||||
// GitHub issue #131).
|
||||
// Since we can't easily determine if this is really the case
|
||||
// here, just don't internalize it if the parent returns a
|
||||
// template at all, to be safe.
|
||||
TypeFunction* tf = static_cast<TypeFunction*>(fd->type);
|
||||
if (!DtoIsTemplateInstance(tf->next->toDsymbol(fd->scope)))
|
||||
return llvm::GlobalValue::InternalLinkage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Submodule tests/d2/dmd-testsuite updated: 3c31326cd2...a4a9f28605
Reference in New Issue
Block a user