Mercurial > projects > ddmd
diff main.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | d706d958e4e8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,1105 @@ +module main; + +import dmd.Array; +import dmd.Module; +import dmd.Global; +import dmd.VersionCondition; +import dmd.DebugCondition; +import dmd.Loc; +import dmd.Lexer; +import dmd.OutBuffer; +import dmd.FileName; +import dmd.Type; +import dmd.File; +import dmd.Id; +import dmd.Identifier; +import dmd.Library; +import dmd.TOK; +import dmd.String; +import dmd.backend.glue; + +import std.stdarg; +import std.string : toStringz; +import std.contracts; + +import core.stdc.string; +import core.stdc.stdio; +import core.stdc.ctype; +import core.stdc.errno; +import core.stdc.stdlib; +import core.stdc.limits; + +import core.memory; + +import dlib.CrashHandler; +import dbg.ui.CrashWindow; + +import dmd.Util; + +bool loop = true; + +enum ExitCode +{ + EXIT_SUCCESS = 0, +} + +version (Windows) +{ + private import core.stdc.wchar_; +} + +extern (C) void gc_init(); +extern (C) void gc_term(); +extern (C) void _minit(); +extern (C) void _moduleCtor(); +extern (C) void _moduleDtor(); +extern (C) void thread_joinAll(); + +shared bool _d_isHalting = false; + +import win32.windows; + +extern (C) int main(int argc, char **argv) +{ + char[][] args; + int result; + + version (OSX) + { /* OSX does not provide a way to get at the top of the + * stack, except for the magic value 0xC0000000. + * But as far as the gc is concerned, argv is at the top + * of the main thread's stack, so save the address of that. + */ + __osx_stack_end = cast(void*)&argv; + } + + version (Posix) + { + _STI_monitor_staticctor(); + _STI_critical_init(); + } + + version (Windows) + { + wchar_t* wcbuf = GetCommandLineW(); + size_t wclen = wcslen(wcbuf); + int wargc = 0; + wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc); + assert(wargc == argc); + + char* cargp = null; + size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, null); + + cargp = cast(char*) alloca(cargl); + args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc]; + + for (size_t i = 0, p = 0; i < wargc; i++) + { + int wlen = wcslen(wargs[i]); + int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, null); + args[i] = cargp[p .. p+clen]; + p += clen; assert(p <= cargl); + WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, null); + } + LocalFree(cast(HANDLE)wargs); + wargs = null; + wargc = 0; + } + else version (Posix) + { + char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof); + scope(exit) free(am); + + for (size_t i = 0; i < argc; i++) + { + auto len = strlen(argv[i]); + am[i] = argv[i][0 .. len]; + } + args = am[0 .. argc]; + } + + gc_init(); + version (Windows) + _minit(); + _moduleCtor(); + + CrashHandlerInit(); + GC.disable(); + + result = main(cast(string[])args); + + thread_joinAll(); + _d_isHalting = true; + _moduleDtor(); + gc_term(); + + version (Posix) + { + _STD_critical_term(); + _STD_monitor_staticdtor(); + } + + return result; +} + +int main(string[] args) +{ + Array files = new Array(); + Array libmodules = new Array(); + Module m; + int status = ExitCode.EXIT_SUCCESS; + int argcstart = args.length; + int setdebuglib = 0; + + global = new Global(); + +/// if (response_expand(&argc,&argv)) // expand response files +/// error("can't open response file"); + + files.reserve(args.length - 1); + + // Set default values + global.params.argv0 = args[0]; + global.params.link = 1; + global.params.useAssert = 1; + global.params.useInvariants = 1; + global.params.useIn = 1; + global.params.useOut = 1; + global.params.useArrayBounds = 1; + global.params.useSwitchError = 1; + global.params.useInline = 0; + global.params.obj = 1; + global.params.Dversion = 2; + global.params.quiet = 1; + + global.params.linkswitches = new Array(); + global.params.libfiles = new Array(); + global.params.objfiles = new Array(); + global.params.ddocfiles = new Array(); + +version (TARGET_WINDOS) { + global.params.defaultlibname = "phobos"; +} else version (XXX) { //#elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS + global.params.defaultlibname = "phobos2"; +} else version (TARGET_NET) { +} else { + static assert(false, "fix this"); +} + + // Predefine version identifiers + VersionCondition.addPredefinedGlobalIdent("DigitalMars"); + +version (TARGET_WINDOS) { + VersionCondition.addPredefinedGlobalIdent("Windows"); + global.params.isWindows = 1; +version (TARGET_NET) { + // TARGET_NET macro is NOT mutually-exclusive with TARGET_WINDOS + VersionCondition.addPredefinedGlobalIdent("D_NET"); +} +} else version (TARGET_LINUX) { + VersionCondition.addPredefinedGlobalIdent("Posix"); + VersionCondition.addPredefinedGlobalIdent("linux"); + global.params.isLinux = 1; +} else version (TARGET_OSX) { + VersionCondition.addPredefinedGlobalIdent("Posix"); + VersionCondition.addPredefinedGlobalIdent("OSX"); + global.params.isOSX = 1; + + // For legacy compatibility + VersionCondition.addPredefinedGlobalIdent("darwin"); +} else version (TARGET_FREEBSD) { + VersionCondition.addPredefinedGlobalIdent("Posix"); + VersionCondition.addPredefinedGlobalIdent("FreeBSD"); + global.params.isFreeBSD = 1; +} else version (TARGET_SOLARIS) { + VersionCondition.addPredefinedGlobalIdent("Posix"); + VersionCondition.addPredefinedGlobalIdent("Solaris"); + global.params.isSolaris = 1; +} else { + static assert (false, "fix this"); +} + + VersionCondition.addPredefinedGlobalIdent("LittleEndian"); + //VersionCondition.addPredefinedGlobalIdent("D_Bits"); +version (DMDV2) { + VersionCondition.addPredefinedGlobalIdent("D_Version2"); +} + VersionCondition.addPredefinedGlobalIdent("all"); + +version (_WIN32) { + inifile(args[0], "sc.ini"); +} else version (XXX) {///linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 + inifile(argv[0], "dmd.conf"); +} else { + static assert (false, "fix this"); +} + args = getenv_setargv("DFLAGS", args); + +version (disabled) { + for (i = 0; i < argc; i++) + { + writef("argv[%d] = '%s'\n", i, argv[i]); + } +} + + foreach(i; 1..args.length) + { + auto arg = args[i]; + auto p = arg.ptr; + if (*p == '-') + { + arg = arg[1..$]; + if (arg == "d") + global.params.useDeprecated = 1; + else if (arg == "c") + global.params.link = 0; + else if (arg == "cov") + global.params.cov = 1; +///version (XXX) {// TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS +/// else if (arg == "fPIC") +/// global.params.pic = 1; +///} + else if (arg == "multiobj") + global.params.multiobj = 1; + else if (arg == "g") + global.params.symdebug = 1; + else if (arg == "gc") + global.params.symdebug = 2; + else if (arg == "gt") + { error("use -profile instead of -gt\n"); + global.params.trace = 1; + } + else if (arg == "m64") + global.params.isX86_64 = 1; + else if (arg == "profile") + global.params.trace = 1; + else if (arg == "v") + global.params.verbose = 1; +///version (DMDV2) { + else if (arg == "vtls") + global.params.vtls = 1; +///} + else if (arg == "v1") + { +version (DMDV1) { + global.params.Dversion = 1; +} else { + error("use DMD 1.0 series compilers for -v1 switch"); + break; +} + } + else if (arg == "w") + global.params.warnings = 1; + else if (arg == "O") + global.params.optimize = 1; + else if (p[1] == 'o') + { + switch (p[2]) + { + case '-': + global.params.obj = 0; + break; + + case 'd': + if (!p[3]) + goto Lnoarg; + global.params.objdir = arg[(p - arg.ptr) + 3..$]; + break; + + case 'f': + { + if (!p[3]) + goto Lnoarg; + + global.params.objname = arg[(p - arg.ptr) + 3..$]; + break; + } + + case 'p': + if (p[3]) + goto Lerror; + global.params.preservePaths = 1; + break; + + case 0: + error("-o no longer supported, use -of or -od"); + break; + + default: + goto Lerror; + } + } + else if (p[1] == 'D') + { global.params.doDocComments = 1; + switch (p[2]) + { + case 'd': + if (!p[3]) + goto Lnoarg; + global.params.docdir = arg[(p - arg.ptr) + 3..$]; + break; + case 'f': + if (!p[3]) + goto Lnoarg; + global.params.docname = arg[(p - arg.ptr) + 3..$]; + break; + + case 0: + break; + + default: + goto Lerror; + } + } +///version (_DH) { + else if (p[1] == 'H') + { global.params.doHdrGeneration = 1; + switch (p[2]) + { + case 'd': + if (!p[3]) + goto Lnoarg; + global.params.hdrdir = arg[(p - arg.ptr) + 3..$]; + break; + + case 'f': + if (!p[3]) + goto Lnoarg; + global.params.hdrname = arg[(p - arg.ptr) + 3..$]; + break; + + case 0: + break; + + default: + goto Lerror; + } + } +///} + else if (arg == "ignore") + global.params.ignoreUnsupportedPragmas = 1; + else if (arg == "inline") + global.params.useInline = 1; + else if (arg == "lib") + global.params.lib = 1; + else if (arg == "nofloat") + global.params.nofloat = 1; + else if (arg == "quiet") + global.params.quiet = 1; + else if (arg == "release") + global.params.release = 1; +///version (DMDV2) { + else if (arg == "safe") + global.params.safe = 1; +///} + else if (arg == "unittest") + global.params.useUnitTests = 1; + else if (p[1] == 'I') + { + if (!global.params.imppath) + global.params.imppath = new Array(); + global.params.imppath.push(cast(void*)new String(arg[(p - arg.ptr) + 2..$])); /// + } + else if (p[1] == 'J') + { + if (!global.params.fileImppath) + global.params.fileImppath = new Array(); + global.params.fileImppath.push(cast(void*)new String(arg[(p - arg.ptr) + 2..$])); + } + else if (memcmp(p + 1, "debug".ptr, 5) == 0 && p[6] != 'l') + { + // Parse: + // -debug + // -debug=number + // -debug=identifier + if (p[6] == '=') + { + if (isdigit(p[7])) + { long level; + + errno = 0; + level = strtol(p + 7, cast(char**)&p, 10); + if (*p || errno || level > INT_MAX) + goto Lerror; + DebugCondition.setGlobalLevel(cast(int)level); + } + else if (Lexer.isValidIdentifier(arg[(p - arg.ptr) + 7..$])) /// + DebugCondition.addGlobalIdent(p + 7); + else + goto Lerror; + } + else if (p[6]) + goto Lerror; + else + global.params.debuglevel = 1; + } + else if (memcmp(p + 1, "version".ptr, 5) == 0) + { + // Parse: + // -version=number + // -version=identifier + if (p[8] == '=') + { + if (isdigit(p[9])) + { long level; + + errno = 0; + level = strtol(p + 9, cast(char**)&p, 10); /// + if (*p || errno || level > INT_MAX) + goto Lerror; + VersionCondition.setGlobalLevel(cast(int)level); + } + else if (Lexer.isValidIdentifier(arg[(p - arg.ptr) + 9..$])) /// + VersionCondition.addGlobalIdent(arg[(p - arg.ptr) + 9..$]); + else + goto Lerror; + } + else + goto Lerror; + } + else if (arg == "-b") + global.params.debugb = 1; + else if (arg == "-c") + global.params.debugc = 1; + else if (arg == "-f") + global.params.debugf = 1; + else if (arg == "-help") + { usage(); + exit(EXIT_SUCCESS); + } + else if (arg == "-r") + global.params.debugr = 1; + else if (arg == "-x") + global.params.debugx = 1; + else if (arg == "-y") + global.params.debugy = 1; + else if (p[1] == 'L') + { + global.params.linkswitches.push(cast(void*)p + 2); + } + else if (memcmp(p + 1, "defaultlib=".ptr, 11) == 0) + { + global.params.defaultlibname = p + 1 + 11; + } + else if (memcmp(p + 1, "debuglib=".ptr, 9) == 0) + { + setdebuglib = 1; + global.params.debuglibname = p + 1 + 9; + } + else if (memcmp(p + 1, "deps=".ptr, 5) == 0) + { + global.params.moduleDepsFile = arg[(p - arg.ptr) + 1 + 5..$]; + if (!global.params.moduleDepsFile[0]) + goto Lnoarg; + global.params.moduleDeps = new OutBuffer; + } + else if (memcmp(p + 1, "man".ptr, 3) == 0) + { +version (_WIN32) { +version (DMDV1) { + browse("http://www.digitalmars.com/d/1.0/dmd-windows.html"); +} else { + browse("http://www.digitalmars.com/d/2.0/dmd-windows.html"); +} +} +version (linux) { +version (DMDV1) { + browse("http://www.digitalmars.com/d/1.0/dmd-linux.html"); +} else { + browse("http://www.digitalmars.com/d/2.0/dmd-linux.html"); +} +} +version (__APPLE__) { +version (DMDV1) { + browse("http://www.digitalmars.com/d/1.0/dmd-osx.html"); +} else { + browse("http://www.digitalmars.com/d/2.0/dmd-osx.html"); +} +} +version (__FreeBSD__) { +version (DMDV1) { + browse("http://www.digitalmars.com/d/1.0/dmd-freebsd.html"); +} else { + browse("http://www.digitalmars.com/d/2.0/dmd-freebsd.html"); +} +} + exit(EXIT_SUCCESS); + } + else if (arg == "run") + { global.params.run = 1; + global.params.runargs_length = ((i >= argcstart) ? args.length : argcstart) - i - 1; + if (global.params.runargs_length) + { + files.push(cast(void*)args[i + 1].ptr); + global.params.runargs = args[i + 2..$]; + i += global.params.runargs_length; + global.params.runargs_length--; + } + else + { global.params.run = 0; + goto Lnoarg; + } + } + else + { + Lerror: + error("unrecognized switch '%s'", args[i]); + continue; + + Lnoarg: + error("argument expected for switch '%s'", args[i]); + continue; + } + } + else + { +version (TARGET_WINDOS) { + string ext = FileName.ext(p[0..arg.length]); + if (ext != null && FileName.compare(ext, "exe") == 0) + { + global.params.objname = arg[(p - arg.ptr)..$]; + continue; + } +} + files.push(cast(void*)new String(arg[(p - arg.ptr)..$])); + } + } + if (global.errors) + { + fatal(); + } + if (files.dim == 0) + { usage(); + return EXIT_FAILURE; + } + + if (!setdebuglib) + global.params.debuglibname = global.params.defaultlibname; + +version (TARGET_OSX) { + global.params.pic = 1; +} + + if (global.params.release) + { global.params.useInvariants = 0; + global.params.useIn = 0; + global.params.useOut = 0; + global.params.useAssert = 0; + global.params.useArrayBounds = 0; + global.params.useSwitchError = 0; + } + + if (global.params.run) + global.params.quiet = 1; + + if (global.params.useUnitTests) + global.params.useAssert = 1; + + if (!global.params.obj || global.params.lib) + global.params.link = 0; + + if (global.params.link) + { + global.params.exefile = global.params.objname; + global.params.oneobj = 1; + if (global.params.objname) + { + /* Use this to name the one object file with the same + * name as the exe file. + */ + global.params.objname = FileName.forceExt(global.params.objname, global.obj_ext).toChars(); + + /* If output directory is given, use that path rather than + * the exe file path. + */ + if (global.params.objdir) + { + string name = FileName.name(global.params.objname); + global.params.objname = FileName.combine(global.params.objdir, name); + } + } + } + else if (global.params.lib) + { + global.params.libname = global.params.objname; + global.params.objname = null; + + // Haven't investigated handling these options with multiobj + if (!global.params.cov && !global.params.trace) + global.params.multiobj = 1; + } + else if (global.params.run) + { + error("flags conflict with -run"); + fatal(); + } + else + { + if (global.params.objname && files.dim > 1) + { + global.params.oneobj = 1; + //error("multiple source files, but only one .obj name"); + //fatal(); + } + } + if (global.params.isX86_64) + { + VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86_64"); + VersionCondition.addPredefinedGlobalIdent("X86_64"); + VersionCondition.addPredefinedGlobalIdent("D_LP64"); +version (TARGET_WINDOS) { + VersionCondition.addPredefinedGlobalIdent("Win64"); +} + } + else + { + VersionCondition.addPredefinedGlobalIdent("D_InlineAsm"); + VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86"); + VersionCondition.addPredefinedGlobalIdent("X86"); +version (TARGET_WINDOS) { + VersionCondition.addPredefinedGlobalIdent("Win32"); +} + } + if (global.params.doDocComments) + VersionCondition.addPredefinedGlobalIdent("D_Ddoc"); + if (global.params.cov) + VersionCondition.addPredefinedGlobalIdent("D_Coverage"); + if (global.params.pic) + VersionCondition.addPredefinedGlobalIdent("D_PIC"); +version (DMDV2) { + if (global.params.useUnitTests) + VersionCondition.addPredefinedGlobalIdent("unittest"); +} + + // Initialization + Type.init(); + Id.initialize(); + Module.init(); + initPrecedence(); + + backend_init(); + + //printf("%d source files\n",files.dim); + + // Build import search path + if (global.params.imppath) + { + for (int i = 0; i < global.params.imppath.dim; i++) + { + string path = (cast(String)global.params.imppath.data[i]).str; + string[] a = FileName.splitPath(path); + + global.path ~= a; + } + } + + // Build string import search path + if (global.params.fileImppath) + { + for (int i = 0; i < global.params.fileImppath.dim; i++) + { + string path = (cast(String)global.params.fileImppath.data[i]).str; + string[] a = FileName.splitPath(path); + + global.filePath ~= a; + } + } + + // Create Modules + Array modules = new Array(); + modules.reserve(files.dim); + int firstmodule = 1; + for (int i = 0; i < files.dim; i++) + { + string ext; + string name; + + String s = cast(String) files.data[i]; + string mp = s.str; + +version (_WIN32) { + char[] copy = null; + // Convert / to \ so linker will work + foreach (j, c; mp) + { + if (c == '/') { + if (copy is null) copy = mp.dup; + copy[j] = '\\'; + } + } + + if (copy !is null) mp = assumeUnique(copy); +} + string p = mp; + + p = FileName.name(p); // strip path + ext = FileName.ext(p); + + if (ext.length != 0) + { /* Deduce what to do with a file based on its extension + */ + if (FileName.equals(ext, global.obj_ext)) + { + global.params.objfiles.push(files.data[i]); + libmodules.push(files.data[i]); + continue; + } + + if (FileName.equals(ext, global.lib_ext)) + { + global.params.libfiles.push(files.data[i]); + libmodules.push(files.data[i]); + continue; + } + + if (ext == global.ddoc_ext) + { + global.params.ddocfiles.push(files.data[i]); + continue; + } + +version (TARGET_WINDOS) { + if (FileName.equals(ext, "res")) + { + global.params.resfile = (cast(immutable(char)*)files.data[i])[0..0]; /// !!! + continue; + } + + if (FileName.equals(ext, "def")) + { + global.params.deffile = (cast(immutable(char)*)files.data[i])[0..0]; + continue; + } + + if (FileName.equals(ext, "exe")) + { + assert(0); // should have already been handled + } +} + + /* Examine extension to see if it is a valid + * D source file extension + */ + if (FileName.equals(ext, global.mars_ext) || + FileName.equals(ext, global.hdr_ext) || + FileName.equals(ext, "dd") || + FileName.equals(ext, "htm") || + FileName.equals(ext, "html") || + FileName.equals(ext, "xhtml")) + { + immutable(char)* e = ext.ptr; + e--; // skip onto '.' + assert(*e == '.'); + + immutable(char)* n = p.ptr; + + name = n[0..(e-n)]; // strip extension + + if (name.length == 0 || name == ".." || name == ".") + { + Linvalid: + error("invalid file name '%s'", (cast(String)files.data[i]).str); + fatal(); + } + } + else + { error("unrecognized file extension %s\n", ext); + fatal(); + } + } + else + { + name = p; + if (!*name) + goto Linvalid; + } + + /* At this point, name is the D source file name stripped of + * its path and extension. + */ + + Identifier id = new Identifier(name, TOK.TOKreserved); + m = new Module((cast(String) files.data[i]).str, id, global.params.doDocComments, global.params.doHdrGeneration); + modules.push(cast(void*)m); + + if (firstmodule) + { + global.params.objfiles.push(cast(void*)m.objfile.name); + firstmodule = 0; + } + } + + // Read files +//version = ASYNCREAD; +version (ASYNCREAD) { + // Multi threaded + AsyncRead *aw = AsyncRead.create(modules.dim); + for (i = 0; i < modules.dim; i++) + { + m = cast(Module *)modules.data[i]; + aw.addFile(m.srcfile); + } + aw.start(); +} else { + // Single threaded + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + m.read(Loc(0)); + } +} + + // Parse files + int anydocfiles = 0; + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("parse %s\n", m.toChars()); + if (!Module.rootModule) + Module.rootModule = m; + m.importedFrom = m; + if (!global.params.oneobj || i == 0 || m.isDocFile) + m.deleteObjFile(); +version (ASYNCREAD) { + if (aw.read(i)) + { + error("cannot read file %s", m.srcfile.name.toChars()); + } +} + + //while (loop) {} + m.parse(); + if (m.isDocFile) + { + anydocfiles = 1; + m.gendocfile(); + + // Remove m from list of modules + modules.remove(i); + i--; + + // Remove m's object file from list of object files + for (int j = 0; j < global.params.objfiles.dim; j++) + { + if (m.objfile.name.str == (cast(FileName)global.params.objfiles.data[j]).str) + { + global.params.objfiles.remove(j); + break; + } + } + + if (global.params.objfiles.dim == 0) + global.params.link = 0; + } + } +version (ASYNCREAD) { + AsyncRead.dispose(aw); +} + + if (anydocfiles && modules.dim && + (global.params.oneobj || global.params.objname)) + { + error("conflicting Ddoc and obj generation options"); + fatal(); + } + if (global.errors) + fatal(); +version (_DH) { + if (global.params.doHdrGeneration) + { + /* Generate 'header' import files. + * Since 'header' import files must be independent of command + * line switches and what else is imported, they are generated + * before any semantic analysis. + */ + for (i = 0; i < modules.dim; i++) + { + m = cast(Module *)modules.data[i]; + if (global.params.verbose) + writef("import %s\n", m.toChars()); + m.genhdrfile(); + } + } + if (global.errors) + fatal(); +} + + // Do semantic analysis + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("semantic %s\n", m.toChars()); + m.semantic(); + } + if (global.errors) + fatal(); + + // Do pass 2 semantic analysis + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("semantic2 %s\n", m.toChars()); + m.semantic2(); + } + if (global.errors) + fatal(); + + // Do pass 3 semantic analysis + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("semantic3 %s\n", m.toChars()); + m.semantic3(); + } + if (global.errors) + fatal(); + + if (global.params.moduleDeps !is null) + { + assert(global.params.moduleDepsFile !is null); + + File deps = new File(global.params.moduleDepsFile); + OutBuffer ob = global.params.moduleDeps; + deps.setbuffer(cast(void*)ob.data, ob.offset); + deps.writev(); + } + + + // Scan for functions to inline + if (global.params.useInline) + { + /* The problem with useArrayBounds and useAssert is that the + * module being linked to may not have generated them, so if + * we inline functions from those modules, the symbols for them will + * not be found at link time. + */ + if (!global.params.useArrayBounds && !global.params.useAssert) + { + // Do pass 3 semantic analysis on all imported modules, + // since otherwise functions in them cannot be inlined + for (int i = 0; i < Module.amodules.dim; i++) + { + m = cast(Module)Module.amodules.data[i]; + if (global.params.verbose) + writef("semantic3 %s\n", m.toChars()); + m.semantic3(); + } + if (global.errors) + fatal(); + } + + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("inline scan %s\n", m.toChars()); + + m.inlineScan(); + } + } + if (global.errors) + fatal(); + + Library library = null; + if (global.params.lib) + { + library = new Library(); + library.setFilename(global.params.objdir, global.params.libname); + + // Add input object and input library files to output library + for (int i = 0; i < libmodules.dim; i++) + { + string p = (cast(String)libmodules.data[i]).str; + library.addObject(p, null, 0); + } + } + + // Generate output files + if (global.params.oneobj) + { + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("code %s\n", m.toChars()); + if (i == 0) + obj_start(cast(char*)toStringz(m.srcfile.toChars())); + m.genobjfile(0); + if (!global.errors && global.params.doDocComments) + m.gendocfile(); + } + if (!global.errors && modules.dim) + { + obj_end(library, (cast(Module)modules.data[0]).objfile); + } + } + else + { + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("code %s\n", m.toChars()); + if (global.params.obj) + { + obj_start(cast(char*)toStringz(m.srcfile.toChars())); + m.genobjfile(global.params.multiobj); + obj_end(library, m.objfile); + obj_write_deferred(library); + } + if (global.errors) + { + if (!global.params.lib) + m.deleteObjFile(); + } + else + { + if (global.params.doDocComments) + m.gendocfile(); + } + } + } + + if (global.params.lib && !global.errors) + library.write(); + + backend_term(); + if (global.errors) + fatal(); + + if (!global.params.objfiles.dim) + { + if (global.params.link) + error("no object files to link"); + } + else + { + if (global.params.link) + status = runLINK(); + + if (global.params.run) + { + if (!status) + { + status = runProgram(); + + /* Delete .obj files and .exe file + */ + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + m.deleteObjFile(); + if (global.params.oneobj) + break; + } + deleteExeFile(); + } + } + } + + return status; +} \ No newline at end of file