root/main.d

Revision 191:52188e7e3fb5, 35.5 kB (checked in by korDen@korDen-pc, 2 months ago)

Fixed deprecated features, now compiles with DMD2.058

Also changed Array allocation policy:
Now doesn't reallocate but malloc's, followed by a memcpy (no free).
(this fixes a crash while compiling druntime. Same bug in dmd)

Line 
1 module main;
2
3 import dmd.Macro;
4 import dmd.Array;
5 import dmd.Module;
6 import dmd.Global;
7 import dmd.VersionCondition;
8 import dmd.DebugCondition;
9 import dmd.Loc;
10 import dmd.Lexer;
11 import dmd.OutBuffer;
12 import dmd.FileName;
13 import dmd.Type;
14 import dmd.File;
15 import dmd.Id;
16 import dmd.Identifier;
17 import dmd.Json;
18 import dmd.Library;
19 import dmd.TOK;
20 import dmd.String;
21 import dmd.backend.glue;
22
23 import core.vararg;
24 import std.string : toStringz;
25 import std.exception;
26
27 import core.stdc.string;
28 import core.stdc.stdio;
29 import core.stdc.ctype;
30 import core.stdc.errno;
31 import core.stdc.stdlib;
32 import core.stdc.limits;
33
34 import core.memory;
35
36 version (Windows)
37     import dbg.CallStackInfo;
38
39 import dmd.Util;
40
41 enum ExitCode
42 {
43     EXIT_SUCCESS = 0,
44 }
45
46 //version = CrashHandler;
47
48 version (CrashHandler) {
49 version(Linux)
50 {
51 extern (C) extern __gshared bool rt_trapExceptions;
52
53 static this() {
54     rt_trapExceptions = false;
55 }
56
57 }
58
59
60 version(Windows)
61 {
62
63 version (Windows)
64 {
65     private import core.stdc.wchar_;
66
67     extern (Windows) alias int function() FARPROC;
68     extern (Windows) FARPROC    GetProcAddress(void*, in char*);
69     extern (Windows) void*      LoadLibraryA(in char*);
70     extern (Windows) int        FreeLibrary(void*);
71     extern (Windows) void*      LocalFree(void*);
72     extern (Windows) wchar_t*   GetCommandLineW();
73     extern (Windows) wchar_t**  CommandLineToArgvW(wchar_t*, int*);
74     extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
75     pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
76 }
77
78 shared bool _d_isHalting = false;
79 __gshared string[] _d_args = null;
80
81 version(Posix)
82 {
83     extern (C) void _STI_monitor_staticctor();
84     extern (C) void _STD_monitor_staticdtor();
85     extern (C) void _STI_critical_init();
86     extern (C) void _STD_critical_term();
87 }
88
89 extern (C) void gc_init();
90 extern (C) void gc_term();
91 extern (C) void _minit();
92 extern (C) void _moduleCtor();
93 extern (C) void _moduleDtor();
94 extern (C) bool runModuleUnitTests();
95 extern (C) void thread_joinAll();
96
97 import rt.memory;
98
99 extern (C) int main(int argc, char** argv)
100 {
101     char[][] args;
102     int result;
103
104     version (OSX)
105     {   /* OSX does not provide a way to get at the top of the
106          * stack, except for the magic value 0xC0000000.
107          * But as far as the gc is concerned, argv is at the top
108          * of the main thread's stack, so save the address of that.
109          */
110         __osx_stack_end = cast(void*)&argv;
111     }
112
113     version (FreeBSD) version (D_InlineAsm_X86)
114     {
115         /*
116          * FreeBSD/i386 sets the FPU precision mode to 53 bit double.
117          * Make it 64 bit extended.
118          */
119         ushort fpucw;
120         asm
121         {
122             fstsw   fpucw;
123             or      fpucw, 0b11_00_111111; // 11: use 64 bit extended-precision
124                                            // 111111: mask all FP exceptions
125             fldcw   fpucw;
126         }
127     }
128
129     version (Posix)
130     {
131         _STI_monitor_staticctor();
132         _STI_critical_init();
133     }
134
135     version (Windows)
136     {
137         wchar_t*  wcbuf = GetCommandLineW();
138         size_t    wclen = wcslen(wcbuf);
139         int       wargc = 0;
140         wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
141         assert(wargc == argc);
142
143         char*     cargp = null;
144         size_t    cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
145
146         cargp = cast(char*) alloca(cargl);
147         args  = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
148
149         for (size_t i = 0, p = 0; i < wargc; i++)
150         {
151             int wlen = wcslen(wargs[i]);
152             int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
153             args[i]  = cargp[p .. p+clen];
154             p += clen; assert(p <= cargl);
155             WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
156         }
157         LocalFree(wargs);
158         wargs = null;
159         wargc = 0;
160     }
161     else version (Posix)
162     {
163         char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
164         scope(exit) free(am);
165
166         for (size_t i = 0; i < argc; i++)
167         {
168             auto len = strlen(argv[i]);
169             am[i] = argv[i][0 .. len];
170         }
171         args = am[0 .. argc];
172     }
173     _d_args = cast(string[]) args;
174    
175     void runMain()
176     {
177         CrashHandlerInit();
178         //  while (true)
179         {
180             result = main(_d_args);
181         }
182     }
183
184     void runAll()
185     {
186         gc_init();
187         initStaticDataGC();
188         version (Windows)
189             _minit();
190         _moduleCtor();
191         _moduleTlsCtor();
192         if (runModuleUnitTests())
193             runMain();
194         else
195             result = EXIT_FAILURE;
196         _moduleTlsDtor();
197         thread_joinAll();
198         _d_isHalting = true;
199         _moduleDtor();
200         gc_term();
201     }
202
203     runAll();
204
205     version (Posix)
206     {
207         _STD_critical_term();
208         _STD_monitor_staticdtor();
209     }
210     return result;
211 }
212
213 }
214 }
215
216 int main(string[] args)
217 {
218     GC.disable();
219    
220     Array files = new Array();
221     Array libmodules = new Array();
222     Module m;
223     int status = ExitCode.EXIT_SUCCESS;
224     int argcstart = args.length;
225     int setdebuglib = 0;
226     byte noboundscheck = 0;
227    
228     global = new Global();
229
230 ///    if (response_expand(&argc,&argv))        // expand response files
231 ///        error("can't open response file");
232
233     files.reserve(args.length - 1);
234
235     // Set default values
236     global.params.argv0 = args[0];
237     global.params.link = 1;
238     global.params.useAssert = 1;
239     global.params.useInvariants = 1;
240     global.params.useIn = 1;
241     global.params.useOut = 1;
242     global.params.useArrayBounds = 2;   // default to all functions
243     global.params.useSwitchError = 1;
244     global.params.useInline = 0;
245     global.params.obj = 1;
246     global.params.Dversion = 2;
247     global.params.quiet = 1;
248
249     global.params.linkswitches = new Array();
250     global.params.libfiles = new Array();
251     global.params.objfiles = new Array();
252     global.params.ddocfiles = new Array();
253
254 version (TARGET_WINDOS) {
255     global.params.defaultlibname = "phobos";
256 } else version (POSIX) { //#elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
257     global.params.defaultlibname = "phobos2";
258 } else version (TARGET_NET) {
259 } else {
260     static assert(false, "fix this");
261 }
262
263     // Predefine version identifiers
264     VersionCondition.addPredefinedGlobalIdent("DigitalMars");
265
266 version (TARGET_WINDOS) {
267     VersionCondition.addPredefinedGlobalIdent("Windows");
268     global.params.isWindows = 1;
269 version (TARGET_NET) {
270     // TARGET_NET macro is NOT mutually-exclusive with TARGET_WINDOS
271     VersionCondition.addPredefinedGlobalIdent("D_NET");
272 }
273 } else version (TARGET_LINUX) {
274     VersionCondition.addPredefinedGlobalIdent("Posix");
275     VersionCondition.addPredefinedGlobalIdent("linux");
276     global.params.isLinux = 1;
277 } else version (TARGET_OSX) {
278     VersionCondition.addPredefinedGlobalIdent("Posix");
279     VersionCondition.addPredefinedGlobalIdent("OSX");
280     global.params.isOSX = 1;
281
282     // For legacy compatibility
283     VersionCondition.addPredefinedGlobalIdent("darwin");
284 } else version (TARGET_FREEBSD) {
285     VersionCondition.addPredefinedGlobalIdent("Posix");
286     VersionCondition.addPredefinedGlobalIdent("FreeBSD");
287     global.params.isFreeBSD = 1;
288 } else version (TARGET_SOLARIS) {
289     VersionCondition.addPredefinedGlobalIdent("Posix");
290     VersionCondition.addPredefinedGlobalIdent("Solaris");
291     global.params.isSolaris = 1;
292 } else {
293         static assert (false, "fix this");
294 }
295
296     VersionCondition.addPredefinedGlobalIdent("LittleEndian");
297     //VersionCondition.addPredefinedGlobalIdent("D_Bits");
298 version (DMDV2) {
299     VersionCondition.addPredefinedGlobalIdent("D_Version2");
300 }
301     VersionCondition.addPredefinedGlobalIdent("all");
302
303 version (Windows)
304 {
305     inifile(args[0], "sc.ini");
306 }
307  else version (Posix) ///linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
308 {
309     inifile(args[0], "dmd.conf");
310 }
311 else
312 {
313     static assert (false, "fix this");
314 }
315     args = getenv_setargv("DFLAGS", args);
316
317 version (disabled) {
318     for (i = 0; i < argc; i++)
319     {
320         writef("argv[%d] = '%s'\n", i, argv[i]);
321     }
322 }
323
324     foreach(i; 1..args.length)
325     {
326         auto arg = args[i];
327         auto p = arg.ptr;
328         if (*p == '-')
329         {
330             arg = arg[1..$];
331             if (arg == "d")
332                 global.params.useDeprecated = 1;
333             else if (arg == "c")
334                 global.params.link = 0;
335             else if (arg == "cov")
336                 global.params.cov = 1;
337 ///version (XXX) {// TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
338 ///            else if (arg == "fPIC")
339 ///                global.params.pic = 1;
340 ///}
341             else if (arg == "map")
342                 global.params.map = 1;
343             else if (arg == "multiobj")
344                 global.params.multiobj = 1;
345             else if (arg == "g")
346                 global.params.symdebug = 1;
347             else if (arg == "gc")
348                 global.params.symdebug = 2;
349             else if (arg == "gt")
350             {        error("use -profile instead of -gt\n");
351                 global.params.trace = 1;
352             }
353             else if (arg == "m64")
354                 global.params.isX86_64 = 1;
355             else if (arg == "profile")
356                 global.params.trace = 1;
357             else if (arg == "v")
358                 global.params.verbose = 1;
359 ///version (DMDV2) {
360             else if (arg == "vtls")
361                 global.params.vtls = 1;
362 ///}
363             else if (arg == "v1")
364             {
365 version (DMDV1) {
366                 global.params.Dversion = 1;
367 } else {
368                 error("use DMD 1.0 series compilers for -v1 switch");
369                 break;
370 }
371             }
372             else if (arg == "w")
373                 global.params.warnings = 1;
374             else if (arg == "O")
375                 global.params.optimize = 1;
376             else if (p[1] == 'o')
377             {
378                 switch (p[2])
379                 {
380                     case '-':
381                         global.params.obj = 0;
382                         break;
383
384                     case 'd':
385                         if (!p[3])
386                             goto Lnoarg;
387                         global.params.objdir = arg[(p - arg.ptr) + 3..$];
388                         break;
389
390                     case 'f':
391                     {
392                         if (!p[3])
393                             goto Lnoarg;
394                            
395                         global.params.objname = arg[(p - arg.ptr) + 3..$];
396                         break;
397                     }
398
399                     case 'p':
400                         if (p[3])
401                             goto Lerror;
402                         global.params.preservePaths = 1;
403                         break;
404
405                     case 0:
406                         error("-o no longer supported, use -of or -od");
407                         break;
408
409                     default:
410                         goto Lerror;
411                 }
412             }
413             else if (p[1] == 'D')
414             {        global.params.doDocComments = 1;
415                 switch (p[2])
416                 {
417                     case 'd':
418                         if (!p[3])
419                             goto Lnoarg;
420                         global.params.docdir = arg[(p - arg.ptr) + 3..$];
421                         break;
422                     case 'f':
423                         if (!p[3])
424                             goto Lnoarg;
425                         global.params.docname = arg[(p - arg.ptr) + 3..$];
426                         break;
427
428                     case 0:
429                         break;
430
431                     default:
432                         goto Lerror;
433                 }
434             }
435 ///version (_DH) {
436             else if (p[1] == 'H')
437             {        global.params.doHdrGeneration = 1;
438                 switch (p[2])
439                 {
440                     case 'd':
441                         if (!p[3])
442                             goto Lnoarg;
443                         global.params.hdrdir = arg[(p - arg.ptr) + 3..$];
444                         break;
445
446                     case 'f':
447                         if (!p[3])
448                             goto Lnoarg;
449                         global.params.hdrname = arg[(p - arg.ptr) + 3..$];
450                         break;
451
452                     case 0:
453                         break;
454
455                     default:
456                         goto Lerror;
457                 }
458             }
459 ///}
460             else if (p[1] == 'X')
461             {
462                 global.params.doXGeneration = 1;
463                 switch (p[2])
464                 {
465                     case 'f':
466                     if (!p[3])
467                         goto Lnoarg;
468                     global.params.xfilename = arg[(p - arg.ptr) + 3..$];
469                     break;
470    
471                     case 0:
472                     break;
473    
474                     default:
475                     goto Lerror;
476                 }
477             }
478
479             else if (arg == "ignore")
480                 global.params.ignoreUnsupportedPragmas = 1;
481             else if (arg == "inline")
482                 global.params.useInline = 1;
483             else if (arg == "lib")
484                 global.params.lib = 1;
485             else if (arg == "nofloat")
486                 global.params.nofloat = 1;
487             else if (arg == "quiet")
488                 global.params.quiet = 1;
489             else if (arg == "release")
490                 global.params.release = 1;
491 ///version (DMDV2) {
492             else if (arg == "noboundscheck")
493                 noboundscheck = 1;
494 ///}
495             else if (arg == "unittest")
496                 global.params.useUnitTests = 1;
497             else if (p[1] == 'I')
498             {
499                 global.params.imppath.push(cast(void*)new String(arg[(p - arg.ptr) + 2..$]));   ///
500             }
501             else if (p[1] == 'J')
502             {
503                 if (!global.params.fileImppath)
504                     global.params.fileImppath = new Array();
505                 global.params.fileImppath.push(cast(void*)new String(arg[(p - arg.ptr) + 2..$]));
506             }
507             else if (memcmp(p + 1, "debug".ptr, 5) == 0 && p[6] != 'l')
508             {
509                 // Parse:
510                 //        -debug
511                 //        -debug=number
512                 //        -debug=identifier
513                 if (p[6] == '=')
514                 {
515                     if (isdigit(p[7]))
516                     {        long level;
517
518                         errno = 0;
519                         level = strtol(p + 7, cast(char**)&p, 10);
520                         if (*p || errno || level > INT_MAX)
521                             goto Lerror;
522                         DebugCondition.setGlobalLevel(cast(int)level);
523                     }
524                     else if (Lexer.isValidIdentifier(arg[(p - arg.ptr) + 7..$]))        ///
525                         DebugCondition.addGlobalIdent(p + 7);
526                     else
527                         goto Lerror;
528                 }
529                 else if (p[6])
530                     goto Lerror;
531                 else
532                     global.params.debuglevel = 1;
533             }
534             else if (memcmp(p + 1, "version".ptr, 5) == 0)
535             {
536                 // Parse:
537                 //        -version=number
538                 //        -version=identifier
539                 if (p[8] == '=')
540                 {
541                     if (isdigit(p[9]))
542                     {        long level;
543
544                         errno = 0;
545                         level = strtol(p + 9, cast(char**)&p, 10);  ///
546                         if (*p || errno || level > INT_MAX)
547                             goto Lerror;
548                         VersionCondition.setGlobalLevel(cast(int)level);
549                     }
550                     else if (Lexer.isValidIdentifier(arg[(p - arg.ptr) + 9..$]))    ///
551                         VersionCondition.addGlobalIdent(arg[(p - arg.ptr) + 9..$]);
552                     else
553                         goto Lerror;
554                 }
555                 else
556                     goto Lerror;
557             }
558             else if (arg == "-b")
559                 global.params.debugb = 1;
560             else if (arg == "-c")
561                 global.params.debugc = 1;
562             else if (arg == "-f")
563                 global.params.debugf = 1;
564             else if (arg == "-help")
565             {        usage();
566                 exit(EXIT_SUCCESS);
567             }
568             else if (arg == "-r")
569                 global.params.debugr = 1;
570             else if (arg == "-x")
571                 global.params.debugx = 1;
572             else if (arg == "-y")
573                 global.params.debugy = 1;
574             else if (p[1] == 'L')
575             {
576                 global.params.linkswitches.push(cast(void*)p + 2);
577             }
578             else if (memcmp(p + 1, "defaultlib=".ptr, 11) == 0)
579             {
580                 global.params.defaultlibname = p + 1 + 11;
581             }
582             else if (memcmp(p + 1, "debuglib=".ptr, 9) == 0)
583             {
584                 setdebuglib = 1;
585                 global.params.debuglibname = p + 1 + 9;
586             }
587             else if (memcmp(p + 1, "deps=".ptr, 5) == 0)
588             {
589                 global.params.moduleDepsFile = arg[(p - arg.ptr) + 1 + 5..$];
590                 if (!global.params.moduleDepsFile[0])
591                     goto Lnoarg;
592                 global.params.moduleDeps = new OutBuffer;
593             }
594             else if (memcmp(p + 1, "man".ptr, 3) == 0)
595             {
596 version (Windows) {
597 version (DMDV1) {
598                 browse("http://www.digitalmars.com/d/1.0/dmd-windows.html");
599 } else {
600                 browse("http://www.digitalmars.com/d/2.0/dmd-windows.html");
601 }
602 }
603 version (linux) {
604 version (DMDV1) {
605                 browse("http://www.digitalmars.com/d/1.0/dmd-linux.html");
606 } else {
607                 browse("http://www.digitalmars.com/d/2.0/dmd-linux.html");
608 }
609 }
610 version (__APPLE__) {
611 version (DMDV1) {
612                 browse("http://www.digitalmars.com/d/1.0/dmd-osx.html");
613 } else {
614                 browse("http://www.digitalmars.com/d/2.0/dmd-osx.html");
615 }
616 }
617 version (__FreeBSD__) {
618 version (DMDV1) {
619                 browse("http://www.digitalmars.com/d/1.0/dmd-freebsd.html");
620 } else {
621                 browse("http://www.digitalmars.com/d/2.0/dmd-freebsd.html");
622 }
623 }
624                 exit(EXIT_SUCCESS);
625             }
626             else if (arg == "run")
627             {        global.params.run = 1;
628                 global.params.runargs_length = ((i >= argcstart) ? args.length : argcstart) - i - 1;
629                 if (global.params.runargs_length)
630                 {
631                     files.push(cast(void*)args[i + 1].ptr);
632                     global.params.runargs = args[i + 2..$];
633                     i += global.params.runargs_length;
634                     global.params.runargs_length--;
635                 }
636                 else
637                 {   global.params.run = 0;
638                     goto Lnoarg;
639                 }
640             }
641             else
642             {
643              Lerror:
644                 error("unrecognized switch '%s'", args[i]);
645                 continue;
646
647              Lnoarg:
648                 error("argument expected for switch '%s'", args[i]);
649                 continue;
650             }
651         }
652         else
653         {
654 version (TARGET_WINDOS) {
655             string ext = FileName.ext(p[0..arg.length]);
656             if (ext != null && FileName.compare(ext, "exe") == 0)
657             {
658                 global.params.objname = arg[(p - arg.ptr)..$];
659                 continue;
660             }
661 }
662             files.push(cast(void*)new String(arg[(p - arg.ptr)..$]));
663         }
664     }
665     if (global.errors)
666     {
667         fatal();
668     }
669     if (files.dim == 0)
670     {        usage();
671         return EXIT_FAILURE;
672     }
673
674     if (!setdebuglib)
675         global.params.debuglibname = global.params.defaultlibname;
676
677 version (TARGET_OSX) {
678     global.params.pic = 1;
679 }
680
681     if (global.params.release)
682     {
683         global.params.useInvariants = 0;
684         global.params.useIn = 0;
685         global.params.useOut = 0;
686         global.params.useAssert = 0;
687         global.params.useArrayBounds = 0;
688         global.params.useSwitchError = 0;
689     }
690    
691     if (noboundscheck)
692         global.params.useArrayBounds = 0;
693    
694     if (global.params.run)
695         global.params.quiet = 1;
696
697     if (global.params.useUnitTests)
698         global.params.useAssert = 1;
699
700     if (!global.params.obj || global.params.lib)
701         global.params.link = 0;
702
703     if (global.params.link)
704     {
705         global.params.exefile = global.params.objname;
706         global.params.oneobj = 1;
707         if (global.params.objname)
708         {
709             /* Use this to name the one object file with the same
710              * name as the exe file.
711              */
712             global.params.objname = FileName.forceExt(global.params.objname, global.obj_ext).toChars();
713
714             /* If output directory is given, use that path rather than
715              * the exe file path.
716              */
717             if (global.params.objdir)
718             {
719                 string name = FileName.name(global.params.objname);
720                 global.params.objname = FileName.combine(global.params.objdir, name);
721             }
722         }
723     }
724     else if (global.params.lib)
725     {
726         global.params.libname = global.params.objname;
727         global.params.objname = null;
728
729         // Haven't investigated handling these options with multiobj
730         if (!global.params.cov && !global.params.trace)
731             global.params.multiobj = 1;
732     }
733     else if (global.params.run)
734     {
735         error("flags conflict with -run");
736         fatal();
737     }
738     else
739     {
740         if (global.params.objname && files.dim > 1)
741         {
742             global.params.oneobj = 1;
743             //error("multiple source files, but only one .obj name");
744             //fatal();
745         }
746     }
747     if (global.params.isX86_64)
748     {
749         VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86_64");
750         VersionCondition.addPredefinedGlobalIdent("X86_64");
751         VersionCondition.addPredefinedGlobalIdent("D_LP64");
752 version (TARGET_WINDOS) {
753         VersionCondition.addPredefinedGlobalIdent("Win64");
754 }
755     }
756     else
757     {
758         VersionCondition.addPredefinedGlobalIdent("D_InlineAsm");
759         VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86");
760         VersionCondition.addPredefinedGlobalIdent("X86");
761 version (TARGET_WINDOS) {
762         VersionCondition.addPredefinedGlobalIdent("Win32");
763 }
764     }
765     if (global.params.doDocComments)
766         VersionCondition.addPredefinedGlobalIdent("D_Ddoc");
767     if (global.params.cov)
768         VersionCondition.addPredefinedGlobalIdent("D_Coverage");
769     if (global.params.pic)
770         VersionCondition.addPredefinedGlobalIdent("D_PIC");
771 version (DMDV2) {
772     if (global.params.useUnitTests)
773         VersionCondition.addPredefinedGlobalIdent("unittest");
774 }
775
776     // Initialization
777     Type.init();
778     Id.initialize();
779     initPrecedence();
780     global.initClasssym();
781
782     backend_init();
783
784     //printf("%d source files\n",files.dim);
785
786     // Build import search path
787     if (global.params.imppath)
788     {
789         for (int i = 0; i < global.params.imppath.dim; i++)
790         {
791             string path = (cast(String)global.params.imppath.data[i]).str;
792             string[] a = FileName.splitPath(path);
793
794             global.path ~= a;
795         }
796     }
797
798     // Build string import search path
799     if (global.params.fileImppath)
800     {
801         for (int i = 0; i < global.params.fileImppath.dim; i++)
802         {
803             string path = (cast(String)global.params.fileImppath.data[i]).str;
804             string[] a = FileName.splitPath(path);
805            
806             global.filePath ~= a;
807         }
808     }
809
810     // Create Modules
811     Array modules = new Array();
812     modules.reserve(files.dim);
813     int firstmodule = 1;
814     for (int i = 0; i < files.dim; i++)
815     {
816         string ext;
817         string name;
818
819         String s = cast(String) files.data[i];
820         string mp = s.str;
821
822 version (Windows) {
823         char[] copy = null;
824         // Convert / to \ so linker will work
825         foreach (j, c; mp)
826         {
827             if (c == '/') {
828                 if (copy is null) copy = mp.dup;
829                 copy[j] = '\\';
830             }
831         }
832
833         if (copy !is null) mp = assumeUnique(copy);
834 }
835         string p = mp;
836        
837         p = FileName.name(p);                // strip path
838         ext = FileName.ext(p);
839        
840         if (ext.length != 0)
841         {   /* Deduce what to do with a file based on its extension
842              */
843             if (FileName.equals(ext, global.obj_ext))
844             {
845                 global.params.objfiles.push(files.data[i]);
846                 libmodules.push(files.data[i]);
847                 continue;
848             }
849
850             if (FileName.equals(ext, global.lib_ext))
851             {
852                 global.params.libfiles.push(files.data[i]);
853                 libmodules.push(files.data[i]);
854                 continue;
855             }
856
857             if (ext == global.ddoc_ext)
858             {
859                 global.params.ddocfiles.push(files.data[i]);
860                 continue;
861             }
862            
863             if (FileName.equals(ext, global.json_ext))
864             {
865                 global.params.doXGeneration = 1;
866                 global.params.xfilename = (cast(String)files.data[i]).str;
867                 continue;
868             }
869            
870             if (FileName.equals(ext, global.map_ext))
871             {
872                 global.params.mapfile = (cast(String)files.data[i]).str;
873                 continue;
874             }
875
876 version (TARGET_WINDOS)
877 {
878             if (FileName.equals(ext, "res"))
879             {
880                 global.params.resfile = (cast(String)files.data[i]).str;
881                 continue;
882             }
883
884             if (FileName.equals(ext, "def"))
885             {
886                 global.params.deffile = (cast(String)files.data[i]).str;
887                 continue;
888             }
889
890             if (FileName.equals(ext, "exe"))
891             {
892                 assert(0);        // should have already been handled
893             }
894 }
895
896             /* Examine extension to see if it is a valid
897              * D source file extension
898              */
899             if (FileName.equals(ext, global.mars_ext) ||
900                 FileName.equals(ext, global.hdr_ext) ||
901                 FileName.equals(ext, "dd") ||
902                 FileName.equals(ext, "htm") ||
903                 FileName.equals(ext, "html") ||
904                 FileName.equals(ext, "xhtml"))
905             {
906                 immutable(char)* e = ext.ptr;
907                 e--;                        // skip onto '.'
908                 assert(*e == '.');
909                
910                 immutable(char)* n = p.ptr;
911
912                 name = n[0..(e-n)]; // strip extension
913
914                 if (name.length == 0 || name == ".." || name == ".")
915                 {
916                 Linvalid:
917                     error("invalid file name '%s'", (cast(String)files.data[i]).str);
918                     fatal();
919                 }
920             }
921             else
922             {        error("unrecognized file extension %s\n", ext);
923                 fatal();
924             }
925         }
926         else
927         {
928             name = p;
929             if (!*name.ptr)
930                 goto Linvalid;
931         }
932
933         /* At this point, name is the D source file name stripped of
934          * its path and extension.
935          */
936
937         Identifier id = new Identifier(name, TOK.TOKreserved);
938         m = new Module((cast(String) files.data[i]).str, id, global.params.doDocComments, global.params.doHdrGeneration);
939         modules.push(cast(void*)m);
940
941         if (firstmodule)
942         {
943             global.params.objfiles.push(cast(void*)m.objfile.name);
944             firstmodule = 0;
945         }
946     }
947
948     // Read files
949 //version = ASYNCREAD;
950 version (ASYNCREAD) {
951     // Multi threaded
952     AsyncRead *aw = AsyncRead.create(modules.dim);
953     for (i = 0; i < modules.dim; i++)
954     {
955         m = cast(Module *)modules.data[i];
956         aw.addFile(m.srcfile);
957     }
958     aw.start();
959 } else {
960     // Single threaded
961     for (int i = 0; i < modules.dim; i++)
962     {
963         m = cast(Module)modules.data[i];
964         m.read(Loc(0));
965     }
966 }
967
968     // Parse files
969     int anydocfiles = 0;
970     for (int i = 0; i < modules.dim; i++)
971     {
972         m = cast(Module)modules.data[i];
973         if (global.params.verbose)
974             writef("parse     %s\n", m.toChars());
975         if (!global.rootModule)
976             global.rootModule = m;
977         m.importedFrom = m;
978         if (!global.params.oneobj || i == 0 || m.isDocFile)
979             m.deleteObjFile();
980 version (ASYNCREAD) {
981         if (aw.read(i))
982         {
983             error("cannot read file %s", m.srcfile.name.toChars());
984         }
985 }
986
987         m.parse();
988         if (m.isDocFile)
989         {
990             anydocfiles = 1;
991             m.gendocfile();
992
993             // Remove m from list of modules
994             modules.remove(i);
995             i--;
996
997             // Remove m's object file from list of object files
998             for (int j = 0; j < global.params.objfiles.dim; j++)
999             {
1000                 if (m.objfile.name.str == (cast(FileName)global.params.objfiles.data[j]).str)
1001                 {
1002                     global.params.objfiles.remove(j);
1003                     break;
1004                 }
1005             }
1006
1007             if (global.params.objfiles.dim == 0)
1008                 global.params.link = 0;
1009         }
1010     }
1011 version (ASYNCREAD) {
1012     AsyncRead.dispose(aw);
1013 }
1014
1015     if (anydocfiles && modules.dim &&
1016         (global.params.oneobj || global.params.objname))
1017     {
1018         error("conflicting Ddoc and obj generation options");
1019         fatal();
1020     }
1021     if (global.errors)
1022         fatal();
1023 version (_DH)
1024 {
1025     if (global.params.doHdrGeneration)
1026     {
1027         /* Generate 'header' import files.
1028          * Since 'header' import files must be independent of command
1029          * line switches and what else is imported, they are generated
1030          * before any semantic analysis.
1031          */
1032         for (i = 0; i < modules.dim; i++)
1033         {
1034             m = cast(Module)modules.data[i];
1035             if (global.params.verbose)
1036                 writef("import    %s\n", m.toChars());
1037             m.genhdrfile();
1038         }
1039     }
1040     if (global.errors)
1041         fatal();
1042 }
1043     //load all unconditional imports for better symbol resolving
1044     for (int i = 0; i < modules.dim; i++)
1045     {
1046         m = cast(Module)modules.data[i];
1047         if (global.params.verbose)
1048             writef("importall %s\n", m.toChars());
1049         m.importAll(null);
1050     }
1051     if (global.errors)
1052         fatal();
1053        
1054     // Do semantic analysis
1055     for (int i = 0; i < modules.dim; i++)
1056     {
1057         m = cast(Module)modules.data[i];
1058         if (global.params.verbose)
1059             writef("semantic  %s\n", m.toChars());
1060         m.semantic();
1061     }
1062     if (global.errors)
1063         fatal();
1064    
1065     global.dprogress = 1;
1066     Module.runDeferredSemantic();
1067    
1068     // Do pass 2 semantic analysis
1069     for (int i = 0; i < modules.dim; i++)
1070     {
1071         m = cast(Module)modules.data[i];
1072         if (global.params.verbose)
1073             writef("semantic2 %s\n", m.toChars());
1074         m.semantic2();
1075     }
1076     if (global.errors)
1077         fatal();
1078
1079     // Do pass 3 semantic analysis
1080     for (int i = 0; i < modules.dim; i++)
1081     {
1082         m = cast(Module)modules.data[i];
1083         if (global.params.verbose)
1084             writef("semantic3 %s\n", m.toChars());
1085         m.semantic3();
1086     }
1087     if (global.errors)
1088         fatal();
1089    
1090     if (global.params.moduleDeps !is null)
1091     {
1092         assert(global.params.moduleDepsFile !is null);
1093
1094         File deps = new File(global.params.moduleDepsFile);
1095         OutBuffer ob = global.params.moduleDeps;
1096         deps.setbuffer(cast(void*)ob.data, ob.offset);
1097         deps.writev();
1098     }
1099
1100
1101     // Scan for functions to inline
1102     if (global.params.useInline)
1103     {
1104         /* The problem with useArrayBounds and useAssert is that the
1105          * module being linked to may not have generated them, so if
1106          * we inline functions from those modules, the symbols for them will
1107          * not be found at link time.
1108          */
1109         if (!global.params.useArrayBounds && !global.params.useAssert)
1110         {
1111             // Do pass 3 semantic analysis on all imported modules,
1112             // since otherwise functions in them cannot be inlined
1113             for (int i = 0; i < global.amodules.dim; i++)
1114             {
1115                 m = cast(Module)global.amodules.data[i];
1116                 if (global.params.verbose)
1117                     writef("semantic3 %s\n", m.toChars());
1118                 m.semantic3();
1119             }
1120             if (global.errors)
1121                 fatal();
1122         }
1123
1124         for (int i = 0; i < modules.dim; i++)
1125         {
1126             m = cast(Module)modules.data[i];
1127             if (global.params.verbose)
1128                 writef("inline scan %s\n", m.toChars());
1129                
1130             m.inlineScan();
1131         }
1132     }
1133     if (global.errors)
1134         fatal();
1135
1136     Library library = null;
1137     if (global.params.lib)
1138     {
1139         library = new Library();
1140         library.setFilename(global.params.objdir, global.params.libname);
1141
1142         // Add input object and input library files to output library
1143         for (int i = 0; i < libmodules.dim; i++)
1144         {
1145             string p = (cast(String)libmodules.data[i]).str;
1146             library.addObject(p, null, 0);
1147         }
1148     }
1149
1150     // Generate output files
1151     if (global.params.doXGeneration)
1152         json_generate(modules);
1153    
1154     if (global.params.oneobj)
1155     {
1156         for (int i = 0; i < modules.dim; i++)
1157         {
1158             m = cast(Module)modules.data[i];
1159             if (global.params.verbose)
1160                 writef("code      %s\n", m.toChars());
1161             if (i == 0)
1162                 obj_start(cast(char*)toStringz(m.srcfile.toChars()));
1163             m.genobjfile(0);
1164             if (!global.errors && global.params.doDocComments)
1165                 m.gendocfile();
1166         }
1167         if (!global.errors && modules.dim)
1168         {
1169             obj_end(library, (cast(Module)modules.data[0]).objfile);
1170         }
1171     }
1172     else
1173     {
1174         for (int i = 0; i < modules.dim; i++)
1175         {
1176             m = cast(Module)modules.data[i];
1177             if (global.params.verbose)
1178                 writef("code      %s\n", m.toChars());
1179             if (global.params.obj)
1180             { 
1181                 obj_start(cast(char*)toStringz(m.srcfile.toChars()));
1182                 m.genobjfile(global.params.multiobj);
1183                 obj_end(library, m.objfile);
1184                 obj_write_deferred(library);
1185             }
1186             if (global.errors)
1187             {
1188                 if (!global.params.lib)
1189                     m.deleteObjFile();
1190             }
1191             else
1192             {
1193                 if (global.params.doDocComments)
1194                     m.gendocfile();
1195             }
1196         }
1197     }       
1198
1199     if (global.params.lib && !global.errors)
1200         library.write();
1201
1202     backend_term();
1203     if (global.errors)
1204         fatal();
1205
1206     if (!global.params.objfiles.dim)
1207     {
1208         if (global.params.link)
1209             error("no object files to link");
1210     }
1211     else
1212     {
1213         if (global.params.link)
1214             status = runLINK();
1215
1216         if (global.params.run)
1217         {
1218             if (!status)
1219             {
1220                 status = runProgram();
1221
1222                 /* Delete .obj files and .exe file
1223                  */
1224                 for (int i = 0; i < modules.dim; i++)
1225                 {
1226                     m = cast(Module)modules.data[i];
1227                     m.deleteObjFile();
1228                     if (global.params.oneobj)
1229                         break;
1230                 }
1231                 deleteExeFile();
1232             }
1233         }
1234     }
1235
1236     return status;
1237 }
Note: See TracBrowser for help on using the browser.