From 25463648a78f5b2d26b820485b4398fb27a5c6f5 Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 29 Aug 2013 10:51:02 +0900 Subject: [PATCH] Fix genCmain code to remove ambiguity of `&main` expression It was introduced by pull#2476, but the expression `&main` which is implicitly inserted would conflict with two extern(C) and (D) "main" functions in user module. Instead, separate the entry-point code in the hidden module __entrypoint.d --- src/func.c | 43 ----------------------------------- src/mars.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/func.c b/src/func.c index 9d6532d3f892..b2280796ae6f 100644 --- a/src/func.c +++ b/src/func.c @@ -3466,49 +3466,6 @@ FuncDeclaration *FuncDeclaration::genCfunc(Parameters *args, Type *treturn, Iden return fd; } -/************************************ - * Generate C main() in response to seeing D main(). - * This used to be in druntime, but contained a reference to _Dmain - * which didn't work when druntime was made into a dll and was linked - * to a program, such as a C++ program, that didn't have a _Dmain. - */ - -void genCmain(Scope *sc) -{ - /* The D code to be generated is provided as D source code in the form of a string. - * Note that Solaris, for unknown reasons, requires both a main() and an _main() - */ - static utf8_t code[] = "extern(C) {\n\ - int _d_run_main(int argc, char **argv, void* mainFunc);\n\ - int main(int argc, char **argv) { return _d_run_main(argc, argv, &main); }\n\ - version (Solaris) int _main(int argc, char** argv) { return main(argc, argv); }\n\ - }\n\ - "; - - Parser p(sc->module, code, sizeof(code) / sizeof(code[0]), 0); - p.loc = Loc(); - p.nextToken(); - Dsymbols *decl = p.parseDeclDefs(0); - assert(p.token.value == TOKeof); - - sc = sc->push(); - sc->parent = sc->module->importedFrom; - sc->stc = 0; - - for (size_t i = 0; i < decl->dim; ++i) - { Dsymbol *s = (*decl)[i]; - sc->module->importedFrom->members->push(s); - s->addMember(sc, sc->module->importedFrom, 1); - } - - for (size_t i = 0; i < decl->dim; ++i) - { Dsymbol *s = (*decl)[i]; - s->semantic(sc); - } - - sc->pop(); -} - const char *FuncDeclaration::kind() { return "function"; diff --git a/src/mars.c b/src/mars.c index 239c52562985..9c54c79b6ee9 100644 --- a/src/mars.c +++ b/src/mars.c @@ -30,7 +30,7 @@ #include "id.h" #include "cond.h" #include "expression.h" -#include "lexer.h" +#include "parse.h" #include "lib.h" #include "json.h" @@ -431,6 +431,50 @@ extern "C" } #endif +static Module *entrypoint = NULL; + +/************************************ + * Generate C main() in response to seeing D main(). + * This used to be in druntime, but contained a reference to _Dmain + * which didn't work when druntime was made into a dll and was linked + * to a program, such as a C++ program, that didn't have a _Dmain. + */ + +void genCmain(Scope *sc) +{ + if (entrypoint) + return; + + /* The D code to be generated is provided as D source code in the form of a string. + * Note that Solaris, for unknown reasons, requires both a main() and an _main() + */ + static utf8_t code[] = "extern(C) {\n\ + int _d_run_main(int argc, char **argv, void* mainFunc);\n\ + int _Dmain(char[][] args);\n\ + int main(int argc, char **argv) { return _d_run_main(argc, argv, &_Dmain); }\n\ + version (Solaris) int _main(int argc, char** argv) { return main(argc, argv); }\n\ + }\n\ + "; + + Module *m = new Module("__entrypoint.d", NULL, 0, 0); + + Parser p(m, code, sizeof(code) / sizeof(code[0]), 0); + p.loc = Loc(); + p.nextToken(); + m->members = p.parseModule(); + assert(p.token.value == TOKeof); + + char v = global.params.verbose; + global.params.verbose = 0; + m->importAll(NULL); + m->semantic(); + m->semantic2(); + m->semantic3(); + global.params.verbose = v; + + entrypoint = m; +} + int tryMain(size_t argc, char *argv[]) { mem.init(); // initialize storage allocator @@ -1650,14 +1694,21 @@ Language changes listed by -transition=id:\n\ if (global.params.oneobj) { + if (modules.dim) + obj_start(m->srcfile->toChars()); for (size_t i = 0; i < modules.dim; i++) { m = modules[i]; if (global.params.verbose) printf("code %s\n", m->toChars()); - if (i == 0) - obj_start(m->srcfile->toChars()); m->genobjfile(0); + if (i == 0 && entrypoint) + { + char v = global.params.verbose; + global.params.verbose = 0; + entrypoint->genobjfile(0); + global.params.verbose = v; + } if (!global.errors && global.params.doDocComments) m->gendocfile(); } @@ -1674,8 +1725,16 @@ Language changes listed by -transition=id:\n\ if (global.params.verbose) printf("code %s\n", m->toChars()); if (global.params.obj) - { obj_start(m->srcfile->toChars()); + { + obj_start(m->srcfile->toChars()); m->genobjfile(global.params.multiobj); + if (i == 0 && entrypoint) + { + char v = global.params.verbose; + global.params.verbose = 0; + entrypoint->genobjfile(global.params.multiobj); + global.params.verbose = v; + } obj_end(library, m->objfile); obj_write_deferred(library); }