# HG changeset patch # User Frits van Bommel # Date 1239632163 -7200 # Node ID 7e5547d8e59fc18d82d61445bfd3cf444d2c3b55 # Parent 9430d4959ab44ba384c40cd0866760a76ca1c060 Give all symbols nested in functions internal linkage, unless it's one of the other special cases. (for example: this shouldn't be done if the symbol in question is also nested in a template; such symbols should get template-like linkage) diff -r 9430d4959ab4 -r 7e5547d8e59f gen/tollvm.cpp --- a/gen/tollvm.cpp Mon Apr 13 12:19:18 2009 +0200 +++ b/gen/tollvm.cpp Mon Apr 13 16:16:03 2009 +0200 @@ -272,9 +272,6 @@ // template if (needsTemplateLinkage(sym)) return TEMPLATE_LINKAGE_TYPE; - // local static - else if (sym->parent && sym->parent->isFuncDeclaration()) - return llvm::GlobalValue::InternalLinkage; } // function else if (FuncDeclaration* fdecl = sym->isFuncDeclaration()) @@ -311,7 +308,25 @@ { assert(0 && "not global/function"); } - + + // 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. + // + // Note: This must be checked after things like template member-ness or + // symbols nested in templates would get duplicated for each module, + // breaking things like + // --- + // int counter(T)() { static int i; return i++; }" + // --- + // if instances get emitted in multiple object files because they'd use + // different instances of 'i'. + for (Dsymbol* parent = sym->parent; parent ; parent = parent->parent) { + if (parent->isFuncDeclaration()) + return llvm::GlobalValue::InternalLinkage; + } + // default to external linkage return llvm::GlobalValue::ExternalLinkage; }