From 39e3e3a67860a12bdd8064584d9265f3502d09c3 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Mon, 31 Dec 2012 02:39:47 +0100 Subject: [PATCH] Replace template symbol module fix with more localized hack. This reverts commit c4adbedcc, which would have fixed the problem at its roots, but caused strange template function attribute inference failures in D-YAML, presumably due to the different order of semantic3 execution on the templates. --- dmd2/declaration.h | 10 ++++++++++ dmd2/func.c | 4 ++++ dmd2/module.c | 42 ------------------------------------------ dmd2/module.h | 5 +---- dmd2/template.c | 6 ++++++ gen/llvmhelpers.cpp | 13 +++++++++---- gen/llvmhelpers.h | 2 +- gen/todebug.cpp | 2 +- 8 files changed, 32 insertions(+), 52 deletions(-) diff --git a/dmd2/declaration.h b/dmd2/declaration.h index 7e63faa4..25586839 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -968,6 +968,16 @@ struct FuncLiteralDeclaration : FuncDeclaration FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; } const char *kind(); + +#if IN_LLVM + // If this is only used as alias parameter to a template instantiation, + // keep track of which one, as the function will only be codegen'ed in the + // module the template instance is pushed to, which is not always the same + // as this->module because of the importedFrom check in + // TemplateInstance::semantic and the fact that importedFrom is only set + // once for the first module. + TemplateInstance *owningTemplate; +#endif }; struct CtorDeclaration : FuncDeclaration diff --git a/dmd2/func.c b/dmd2/func.c index 24ac03eb..65b017d7 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -3448,6 +3448,10 @@ FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, this->fes = fes; this->treq = NULL; //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars()); + +#if IN_LLVM + this->owningTemplate = NULL; +#endif } Dsymbol *FuncLiteralDeclaration::syntaxCopy(Dsymbol *s) diff --git a/dmd2/module.c b/dmd2/module.c index a957e11c..135b8571 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -936,28 +936,6 @@ void Module::semantic(Scope* unused_sc) } #endif -#if IN_LLVM - // If this is a root module (i.e. one we generate an object file for), - // make sure all template instances created as part of semantic analysis - // of this module are actually emitted during codegen for this module, and - // not while generating another random module that happened to import a - // given module "first" (the frontend usually only sets importedFrom once). - // This is especially important for LDC, as we base the decision of whether - // to actually emit code for a declaration (mustDefineSymbol) on whether - // the module being codegen'ed is the module the symbol was defined in. - if (importedFrom == this) - { - for (size_t i = 0; i < members->dim; i++) - { - Import *s = (*members)[i]->isImport(); - if (s) - { - s->mod->updateImportedFrom(this); - } - } - } -#endif - // Do semantic() on members that don't depend on others for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; @@ -1282,26 +1260,6 @@ int Module::selfImports() } -#if IN_LLVM -void Module::updateImportedFrom(Module *newRoot) -{ - // If this is also a root, there is nothing to do. - if (importedFrom == this || importedFrom == newRoot) - return; - - importedFrom = newRoot; - for (size_t i = 0; i < members->dim; i++) - { - Import *s = (*members)[i]->isImport(); - if (s) - { - s->mod->updateImportedFrom(newRoot); - } - } -} -#endif - - /* =========================== ModuleDeclaration ===================== */ ModuleDeclaration::ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe) diff --git a/dmd2/module.h b/dmd2/module.h index f59285af..71730021 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -196,10 +196,7 @@ struct Module : Package void genmoduleinfo(); #if IN_LLVM - /// Recursively sets the importedFrom field of any non-root modules - /// imported by this (including the module itself) to the given module. - void updateImportedFrom(Module *newRoot); - + // LDC llvm::Module* genLLVMModule(llvm::LLVMContext& context, Ir* sir); void buildTargetFiles(bool singleObj); File* buildFilePath(const char* forcename, const char* path, const char* ext); diff --git a/dmd2/template.c b/dmd2/template.c index dd2a67fa..250d9043 100644 --- a/dmd2/template.c +++ b/dmd2/template.c @@ -1864,6 +1864,7 @@ void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Obj sa = ((FuncExp *)ea)->td; else sa = ((FuncExp *)ea)->fd; + s = new AliasDeclaration(0, tp->ident, sa); } else if (ea) @@ -5700,6 +5701,11 @@ void TemplateInstance::declareParameters(Scope *sc) //printf("\ttdtypes[%d] = %p\n", i, o); tempdecl->declareParameter(sc, tp, o); +#if IN_LLVM + if (Dsymbol *sa = isDsymbol(o)) + if (FuncLiteralDeclaration *fld = sa->isFuncLiteralDeclaration()) + fld->owningTemplate = this; +#endif } } diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index f458ff89..79cab3f8 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -962,13 +962,18 @@ DValue* DtoPaintType(Loc& loc, DValue* val, Type* to) // TEMPLATE HELPERS ////////////////////////////////////////////////////////////////////////////////////////*/ -TemplateInstance* DtoIsTemplateInstance(Dsymbol* s) +TemplateInstance* DtoIsTemplateInstance(Dsymbol* s, bool checkLiteralOwner) { if (!s) return NULL; if (s->isTemplateInstance() && !s->isTemplateMixin()) return s->isTemplateInstance(); - else if (s->parent) - return DtoIsTemplateInstance(s->parent); + if (FuncLiteralDeclaration* fld = s->isFuncLiteralDeclaration()) + { + if (checkLiteralOwner && fld->owningTemplate) + return fld->owningTemplate; + } + if (s->parent) + return DtoIsTemplateInstance(s->parent, checkLiteralOwner); return NULL; } @@ -1676,7 +1681,7 @@ bool mustDefineSymbol(Dsymbol* s) return false; } - TemplateInstance* tinst = DtoIsTemplateInstance(s); + TemplateInstance* tinst = DtoIsTemplateInstance(s, true); if (tinst) { if (!global.params.singleObj) diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 5ab4b810..023153b3 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -103,7 +103,7 @@ DValue* DtoCast(Loc& loc, DValue* val, Type* to); DValue* DtoPaintType(Loc& loc, DValue* val, Type* to); // is template instance check, returns module where instantiated -TemplateInstance* DtoIsTemplateInstance(Dsymbol* s); +TemplateInstance* DtoIsTemplateInstance(Dsymbol* s, bool checkLiteralOwner = false); /// Generate code for the symbol. /// Dispatches as appropriate. diff --git a/gen/todebug.cpp b/gen/todebug.cpp index e50f9b6c..bb7e0784 100644 --- a/gen/todebug.cpp +++ b/gen/todebug.cpp @@ -35,7 +35,7 @@ using namespace llvm::dwarf; static Module* getDefinedModule(Dsymbol* s) { // templates are defined in current module - if (DtoIsTemplateInstance(s)) + if (DtoIsTemplateInstance(s, true)) { return gIR->dmodule; }