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; }