From 73e498ace103ce695a95aceef67519c6c3718dbb Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sat, 30 Apr 2011 15:30:57 +0400 Subject: [PATCH] Do not use internal linkage for a function nested in a small function that can be inlined from other modules --- gen/tollvm.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 475db48f..f01cf84c 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -310,10 +310,10 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) if (FuncDeclaration* fd = sym->isFuncDeclaration()) skipNestedCheck = (fd->naked != 0); - // Any symbol nested in a function can't be referenced directly from - // outside that function, so we can give such symbols internal linkage. - // This holds even if nested indirectly, such as member functions of - // aggregates nested in functions. + // Any symbol nested in a function that cannot be inlined can't be + // referenced directly from outside that function, so we can give + // such symbols internal linkage. This holds even if nested indirectly, + // such as member functions of aggregates nested in functions. // // Note: This must be checked after things like template member-ness or // symbols nested in templates would get duplicated for each module, @@ -323,11 +323,13 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) // --- // if instances get emitted in multiple object files because they'd use // different instances of 'i'. - if (!skipNestedCheck) + if (!skipNestedCheck) { for (Dsymbol* parent = sym->parent; parent ; parent = parent->parent) { - if (parent->isFuncDeclaration()) + FuncDeclaration *fd = parent->isFuncDeclaration(); + if (fd && !fd->canInline(fd->needThis())) return llvm::GlobalValue::InternalLinkage; } + } // default to external linkage return llvm::GlobalValue::ExternalLinkage;