mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-10 04:45:56 +03:00
Introduce needsCodegen.
This is a backport of the code from 2.065.
This commit is contained in:
parent
bef0a62622
commit
7c289fd673
7 changed files with 167 additions and 36 deletions
|
@ -921,6 +921,9 @@ public:
|
||||||
void toObjFile(int multiobj); // compile to .obj file
|
void toObjFile(int multiobj); // compile to .obj file
|
||||||
int cvMember(unsigned char *p);
|
int cvMember(unsigned char *p);
|
||||||
void buildClosure(IRState *irs); // Should this be inside or outside the #if IN_DMD?
|
void buildClosure(IRState *irs); // Should this be inside or outside the #if IN_DMD?
|
||||||
|
#endif
|
||||||
|
#if IN_LLVM // backported from 2.065
|
||||||
|
bool needsCodegen();
|
||||||
#endif
|
#endif
|
||||||
FuncDeclaration *isFuncDeclaration() { return this; }
|
FuncDeclaration *isFuncDeclaration() { return this; }
|
||||||
|
|
||||||
|
|
|
@ -821,6 +821,35 @@ void Dsymbol::addComment(utf8_t *comment)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IN_LLVM // backported from 2.065
|
||||||
|
/****************************************
|
||||||
|
* Returns true if this symbol is defined in non-root module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool Dsymbol::inNonRoot()
|
||||||
|
{
|
||||||
|
Dsymbol *s = parent;
|
||||||
|
for (; s; s = s->parent)
|
||||||
|
{
|
||||||
|
if (TemplateInstance *ti = s->isTemplateInstance())
|
||||||
|
{
|
||||||
|
if (ti->isTemplateMixin())
|
||||||
|
continue;
|
||||||
|
if (!ti->instantiatingModule || !ti->instantiatingModule->isRoot())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (Module *m = s->isModule())
|
||||||
|
{
|
||||||
|
if (!m->isRoot())
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/********************************* OverloadSet ****************************/
|
/********************************* OverloadSet ****************************/
|
||||||
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|
|
|
@ -231,6 +231,9 @@ public:
|
||||||
virtual void checkCtorConstInit() { }
|
virtual void checkCtorConstInit() { }
|
||||||
|
|
||||||
virtual void addComment(utf8_t *comment);
|
virtual void addComment(utf8_t *comment);
|
||||||
|
#if IN_LLVM // backported from 2.065
|
||||||
|
bool inNonRoot();
|
||||||
|
#endif
|
||||||
virtual void emitComment(Scope *sc);
|
virtual void emitComment(Scope *sc);
|
||||||
void emitDitto(Scope *sc);
|
void emitDitto(Scope *sc);
|
||||||
|
|
||||||
|
|
87
dmd2/func.c
87
dmd2/func.c
|
@ -3965,6 +3965,93 @@ bool FuncDeclaration::hasNestedFrameRefs()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IN_LLVM // backported from 2.065
|
||||||
|
/***********************************************
|
||||||
|
* Returns true if this function is not defined in non-root module, nor
|
||||||
|
* obviously instantiated in non-root module.
|
||||||
|
*
|
||||||
|
* Note: ti->instantiatingModule does not stabilize until semantic analysis is completed,
|
||||||
|
* so don't call this function during semantic analysis to return precise result.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool FuncDeclaration::needsCodegen()
|
||||||
|
{
|
||||||
|
assert(semanticRun == PASSsemantic3done);
|
||||||
|
|
||||||
|
for (FuncDeclaration *fd = this; fd; )
|
||||||
|
{
|
||||||
|
if (!fd->inTemplateInstance() && fd->inNonRoot())
|
||||||
|
return false;
|
||||||
|
if (fd->isNested())
|
||||||
|
fd = fd->toParent2()->isFuncDeclaration();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The issue is that if the importee is compiled with a different -debug
|
||||||
|
* setting than the importer, the importer may believe it exists
|
||||||
|
* in the compiled importee when it does not, when the instantiation
|
||||||
|
* is behind a conditional debug declaration.
|
||||||
|
*/
|
||||||
|
// workaround for Bugzilla 11239
|
||||||
|
if (global.params.useUnitTests ||
|
||||||
|
global.params.allInst ||
|
||||||
|
global.params.debuglevel)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FuncDeclaration *fd = this;
|
||||||
|
Lagain:
|
||||||
|
TemplateInstance *ti = fd->inTemplateInstance();
|
||||||
|
if (ti && ti->instantiatingModule && !ti->instantiatingModule->isRoot())
|
||||||
|
{
|
||||||
|
Module *mi = ti->instantiatingModule;
|
||||||
|
|
||||||
|
// If mi imports any root modules, we still need to generate the code.
|
||||||
|
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
||||||
|
{
|
||||||
|
Module *m = Module::amodules[i];
|
||||||
|
m->insearch = 0;
|
||||||
|
}
|
||||||
|
bool importsRoot = false;
|
||||||
|
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
||||||
|
{
|
||||||
|
Module *m = Module::amodules[i];
|
||||||
|
if (m->isRoot() && mi->imports(m))
|
||||||
|
{
|
||||||
|
importsRoot = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
||||||
|
{
|
||||||
|
Module *m = Module::amodules[i];
|
||||||
|
m->insearch = 0;
|
||||||
|
}
|
||||||
|
if (!importsRoot)
|
||||||
|
{
|
||||||
|
//printf("instantiated by %s %s\n", ti->instantiatingModule->toChars(), ti->toChars());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd->isNested())
|
||||||
|
{
|
||||||
|
/* Bugzilla 11863: The enclosing function must have its code generated first.
|
||||||
|
* Therefore if parent is instantiated in non-root, this function also prevent
|
||||||
|
* code generation.
|
||||||
|
*/
|
||||||
|
fd = fd->toParent2()->isFuncDeclaration();
|
||||||
|
if (fd)
|
||||||
|
goto Lagain;
|
||||||
|
}
|
||||||
|
//if (AggregateDeclaration *ad = fd->isMember2()) { ... }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* Return the function's parameter list, and whether
|
* Return the function's parameter list, and whether
|
||||||
* it is variadic or not.
|
* it is variadic or not.
|
||||||
|
|
|
@ -801,6 +801,7 @@ static void dumpPredefinedVersions()
|
||||||
}
|
}
|
||||||
|
|
||||||
static Module *entrypoint = NULL;
|
static Module *entrypoint = NULL;
|
||||||
|
static Module *rootHasMain = NULL;
|
||||||
|
|
||||||
/// Callback to generate a C main() function, invoked by the frontend.
|
/// Callback to generate a C main() function, invoked by the frontend.
|
||||||
void genCmain(Scope *sc)
|
void genCmain(Scope *sc)
|
||||||
|
@ -830,7 +831,7 @@ void genCmain(Scope *sc)
|
||||||
|
|
||||||
char v = global.params.verbose;
|
char v = global.params.verbose;
|
||||||
global.params.verbose = 0;
|
global.params.verbose = 0;
|
||||||
m->importedFrom = sc->module;
|
m->importedFrom = m;
|
||||||
m->importAll(NULL);
|
m->importAll(NULL);
|
||||||
m->semantic();
|
m->semantic();
|
||||||
m->semantic2();
|
m->semantic2();
|
||||||
|
@ -838,6 +839,7 @@ void genCmain(Scope *sc)
|
||||||
global.params.verbose = v;
|
global.params.verbose = v;
|
||||||
|
|
||||||
entrypoint = m;
|
entrypoint = m;
|
||||||
|
rootHasMain = sc->module;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@ -1252,7 +1254,7 @@ int main(int argc, char **argv)
|
||||||
if (global.params.obj)
|
if (global.params.obj)
|
||||||
{
|
{
|
||||||
llvm::Module* lm = m->genLLVMModule(context);
|
llvm::Module* lm = m->genLLVMModule(context);
|
||||||
if (entrypoint && entrypoint->importedFrom == m)
|
if (entrypoint && rootHasMain == m)
|
||||||
{
|
{
|
||||||
#if LDC_LLVM_VER >= 303
|
#if LDC_LLVM_VER >= 303
|
||||||
llvm::Linker linker(lm);
|
llvm::Linker linker(lm);
|
||||||
|
|
|
@ -928,44 +928,44 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||||
|
|
||||||
if (fd->ir.defined) return;
|
if (fd->ir.defined) return;
|
||||||
|
|
||||||
// Skip generating code for this part of a TemplateInstance if it has been
|
if ((fd->type && fd->type->ty == Tfunction && static_cast<TypeFunction *>(fd->type)->next == NULL) ||
|
||||||
// instantiated by any non-root module (i.e. a module not listed on the
|
(fd->type && fd->type->ty == Tfunction && static_cast<TypeFunction *>(fd->type)->next->ty == Terror))
|
||||||
// command line).
|
|
||||||
// See DMD's FuncDeclaration::toObjFile. Check this before calling
|
|
||||||
// DtoDeclareFunction DtoDeclareFunction to avoid touching unanalyzed code.
|
|
||||||
TemplateInstance *ti = fd->inTemplateInstance();
|
|
||||||
if (!global.params.useUnitTests &&
|
|
||||||
ti && ti->instantiatingModule && !ti->instantiatingModule->isRoot())
|
|
||||||
{
|
{
|
||||||
Module *mi = ti->instantiatingModule;
|
IF_LOG Logger::println("Ignoring; no return type or return error type");
|
||||||
|
|
||||||
// If mi imports any root modules, we still need to generate the code.
|
|
||||||
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
|
||||||
{
|
|
||||||
Module *m = Module::amodules[i];
|
|
||||||
m->insearch = 0;
|
|
||||||
}
|
|
||||||
bool importsRoot = false;
|
|
||||||
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
|
||||||
{
|
|
||||||
Module *m = Module::amodules[i];
|
|
||||||
if (m->isRoot() && mi->imports(m))
|
|
||||||
{
|
|
||||||
importsRoot = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
|
||||||
{
|
|
||||||
Module *m = Module::amodules[i];
|
|
||||||
m->insearch = 0;
|
|
||||||
}
|
|
||||||
if (!importsRoot)
|
|
||||||
{
|
|
||||||
IF_LOG Logger::println("Ignoring; already instantiated in %s (%s)", ti->instantiatingModule->toChars(), ti->toChars());
|
|
||||||
fd->ir.defined = true;
|
fd->ir.defined = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fd->isUnitTestDeclaration() && !global.params.useUnitTests)
|
||||||
|
{
|
||||||
|
IF_LOG Logger::println("No code generation for unit test declaration %s", fd->toChars());
|
||||||
|
fd->ir.defined = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd->semanticRun == PASSsemanticdone)
|
||||||
|
{
|
||||||
|
/* What happened is this function failed semantic3() with errors,
|
||||||
|
* but the errors were gagged.
|
||||||
|
* Try to reproduce those errors, and then fail.
|
||||||
|
*/
|
||||||
|
error("errors compiling function %s", fd->toPrettyChars());
|
||||||
|
fd->ir.defined = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(fd->semanticRun == PASSsemantic3done);
|
||||||
|
assert(fd->ident != Id::empty);
|
||||||
|
|
||||||
|
// Skip generating code for this part of a TemplateInstance if it has been
|
||||||
|
// instantiated by any non-root module (i.e. a module not listed on the
|
||||||
|
// command line).
|
||||||
|
// Check this before calling DtoDeclareFunction to avoid touching
|
||||||
|
// unanalyzed code.
|
||||||
|
if (!fd->needsCodegen())
|
||||||
|
{
|
||||||
|
IF_LOG Logger::println("No code generation for %s", fd->toChars());
|
||||||
|
fd->ir.defined = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DtoDeclareFunction(fd);
|
DtoDeclareFunction(fd);
|
||||||
|
|
|
@ -2839,6 +2839,13 @@ DValue* FuncExp::toElem(IRState* p)
|
||||||
// We need to actually codegen the function here, as literals are not added
|
// We need to actually codegen the function here, as literals are not added
|
||||||
// to the module member list.
|
// to the module member list.
|
||||||
fd->codegen(p);
|
fd->codegen(p);
|
||||||
|
if (!fd->ir.irFunc)
|
||||||
|
{
|
||||||
|
// See DtoDefineFunction for reasons why codegen was suppressed.
|
||||||
|
// Instead just declare the function.
|
||||||
|
DtoDeclareFunction(fd);
|
||||||
|
assert(!fd->isNested());
|
||||||
|
}
|
||||||
assert(fd->ir.irFunc->func);
|
assert(fd->ir.irFunc->func);
|
||||||
|
|
||||||
if (fd->isNested()) {
|
if (fd->isNested()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue