From 8e56fe69a4b27fd96864e3d4a8ffe0ef4d9a46bf Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 20 May 2009 21:13:41 +0200 Subject: [PATCH] Merged xfBuild patch for dependency tree generation. See #286. --- dmd/import.c | 103 ++++++++++++++++++++++++++++++++++++++++++++- dmd/mars.h | 6 ++- gen/cl_options.cpp | 5 +++ gen/cl_options.h | 1 + gen/main.cpp | 21 ++++++++- 5 files changed, 133 insertions(+), 3 deletions(-) diff --git a/dmd/import.c b/dmd/import.c index be0ddee8..0c4b5837 100644 --- a/dmd/import.c +++ b/dmd/import.c @@ -116,6 +116,25 @@ void Import::load(Scope *sc) //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg); } +char* escapePath(char* fname, char* buffer, int bufLen) { + char* res = buffer; + bufLen -= 2; // for \0 and an occasional escape char + int dst = 0; + for (; dst < bufLen && *fname; ++dst, ++fname) { + switch (*fname) { + case '(': + case ')': + case '\\': + buffer[dst++] = '\\'; + // fall through + + default: + buffer[dst] = *fname; + } + } + buffer[dst] = '\0'; + return buffer; +} void Import::semantic(Scope *sc) { @@ -169,6 +188,68 @@ void Import::semantic(Scope *sc) sc = sc->pop(); } //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg); + + + if (global.params.moduleDeps != NULL) { + char fnameBuf[262]; // MAX_PATH+2 + + OutBuffer *const ob = global.params.moduleDeps; + ob->printf("%s (%s) : ", + sc->module->toPrettyChars(), + escapePath(sc->module->srcfile->toChars(), fnameBuf, sizeof(fnameBuf) / sizeof(*fnameBuf)) + ); + + char* protStr = ""; + switch (sc->protection) { + case PROTpublic: protStr = "public"; break; + case PROTprivate: protStr = "private"; break; + case PROTpackage: protStr = "package"; break; + default: break; + } + ob->writestring(protStr); + if (isstatic) { + ob->writestring(" static"); + } + ob->writestring(" : "); + + if (this->packages) { + for (size_t i = 0; i < this->packages->dim; i++) { + Identifier *pid = (Identifier *)this->packages->data[i]; + ob->printf("%s.", pid->toChars()); + } + } + + ob->printf("%s (%s)", + this->id->toChars(), + mod ? escapePath(mod->srcfile->toChars(), fnameBuf, sizeof(fnameBuf) / sizeof(*fnameBuf)) : "???" + ); + + if (aliasId) { + ob->printf(" -> %s", aliasId->toChars()); + } else { + if (names.dim > 0) { + ob->writestring(" : "); + for (size_t i = 0; i < names.dim; i++) + { + if (i > 0) { + ob->writebyte(','); + } + + Identifier *name = (Identifier *)names.data[i]; + Identifier *alias = (Identifier *)aliases.data[i]; + + if (!alias) { + ob->printf("%s", name->toChars()); + alias = name; + } else { + ob->printf("%s=%s", alias->toChars(), name->toChars()); + } + } + } + } + + ob->writenl(); + } } void Import::semantic2(Scope *sc) @@ -260,7 +341,27 @@ void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->printf("%s.", pid->toChars()); } } - buf->printf("%s;", id->toChars()); + buf->printf("%s", id->toChars()); + if (names.dim > 0) { + buf->writebyte(':'); + for (size_t i = 0; i < names.dim; i++) + { + if (i > 0) { + buf->writebyte(','); + } + + Identifier *name = (Identifier *)names.data[i]; + Identifier *alias = (Identifier *)aliases.data[i]; + + if (!alias) { + buf->printf("%s", name->toChars()); + alias = name; + } else { + buf->printf("%s=%s", alias->toChars(), name->toChars()); + } + } + } + buf->writebyte(';'); buf->writenl(); } diff --git a/dmd/mars.h b/dmd/mars.h index c4f3818d..a8b874a8 100644 --- a/dmd/mars.h +++ b/dmd/mars.h @@ -117,6 +117,7 @@ the target object file format: struct Array; +struct OutBuffer; // LDC enum ARCH @@ -204,7 +205,10 @@ struct Param Array *debuglibnames; // default libraries for debug builds const char *xmlname; // filename for XML output - + + OutBuffer *moduleDeps; // buffer and filename for emitting module deps + char *moduleDepsFile; + // Hidden debug switches bool debuga; bool debugb; diff --git a/gen/cl_options.cpp b/gen/cl_options.cpp index 7e787330..561b2a1f 100644 --- a/gen/cl_options.cpp +++ b/gen/cl_options.cpp @@ -200,6 +200,11 @@ static cl::list linkerSwitches("L", cl::Prefix); +cl::opt moduleDepsFile("deps", + cl::desc("Write module dependencies to filename"), + cl::value_desc("filename")); + + cl::opt > mArch("march", cl::desc("Architecture to generate code for:")); diff --git a/gen/cl_options.h b/gen/cl_options.h index c7a8b67d..0350ad2e 100644 --- a/gen/cl_options.h +++ b/gen/cl_options.h @@ -35,6 +35,7 @@ namespace opts { extern cl::opt hdrFile; #endif extern cl::list versions; + extern cl::opt moduleDepsFile; extern cl::opt > mArch; diff --git a/gen/main.cpp b/gen/main.cpp index da7f5aa6..dea29e56 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -143,7 +143,9 @@ int main(int argc, char** argv) global.params.libfiles = new Array(); global.params.objfiles = new Array(); global.params.ddocfiles = new Array(); - + + global.params.moduleDeps = NULL; + global.params.moduleDepsFile = NULL; // Set predefined version identifiers VersionCondition::addPredefinedGlobalIdent("LLVM"); @@ -222,6 +224,12 @@ int main(int argc, char** argv) global.params.hdrdir || global.params.hdrname; #endif + initFromString(global.params.moduleDepsFile, moduleDepsFile); + if (global.params.moduleDepsFile != NULL) + { + global.params.moduleDeps = new OutBuffer; + } + processVersions(debugArgs, "debug", DebugCondition::setGlobalLevel, DebugCondition::addGlobalIdent); @@ -830,6 +838,17 @@ int main(int argc, char** argv) if (global.errors) fatal(); + // write module dependencies to file if requested + if (global.params.moduleDepsFile != NULL) + { + assert (global.params.moduleDepsFile != NULL); + + File deps(global.params.moduleDepsFile); + OutBuffer* ob = global.params.moduleDeps; + deps.setbuffer((void*)ob->data, ob->offset); + deps.write(); + } + // collects llvm modules to be linked if singleobj is passed std::vector llvmModules;