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.
This commit is contained in:
David Nadlinger 2012-12-31 02:39:47 +01:00
parent 2898e5cac3
commit 39e3e3a678
8 changed files with 32 additions and 52 deletions

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

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

View file

@ -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)

View file

@ -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.

View file

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