mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-29 14:40:40 +03:00
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:
parent
2898e5cac3
commit
39e3e3a678
8 changed files with 32 additions and 52 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue