Mercurial > projects > ldc
annotate dmd/mars.c @ 339:385a18242485 trunk
[svn r360] Another mostly rewrite of DtoArrayInit. Should be much more robust now, and probably faster code generated for the most common cases too!
Fixed issues with slice initialization (!!!) of multidimensional static arrays.
Attempt to fix issue with referencing nested 'this' pointers introduced in DMD 1.033 merge.
author | lindquist |
---|---|
date | Sun, 13 Jul 2008 01:29:49 +0200 |
parents | aaade6ded589 |
children | 1d3026702f65 |
rev | line source |
---|---|
159 | 1 // Compiler implementation of the D programming language |
2 // Copyright (c) 1999-2008 by Digital Mars | |
3 // All Rights Reserved | |
4 // written by Walter Bright | |
5 // http://www.digitalmars.com | |
6 // License for redistribution is by either the Artistic License | |
7 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
8 // See the included readme.txt for details. | |
9 | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <ctype.h> | |
13 #include <assert.h> | |
14 #include <limits.h> | |
15 #include <string> | |
16 #include <cstdarg> | |
17 | |
18 #if __DMC__ | |
19 #include <dos.h> | |
20 #endif | |
21 | |
22 #if linux | |
23 #include <errno.h> | |
24 #endif | |
25 | |
26 #include "mem.h" | |
27 #include "root.h" | |
28 | |
29 #include "mars.h" | |
30 #include "module.h" | |
31 #include "mtype.h" | |
32 #include "id.h" | |
33 #include "cond.h" | |
34 #include "expression.h" | |
35 #include "lexer.h" | |
36 | |
37 #include "gen/logger.h" | |
277
90a8c798b0db
[svn r298] Eliminated the dmd/link.c source file entirely in favor of a llvm::sys based approach to the same functionality.
lindquist
parents:
276
diff
changeset
|
38 #include "gen/linker.h" |
159 | 39 |
40 void getenv_setargv(const char *envvar, int *pargc, char** *pargv); | |
41 | |
284
70c370e97944
[svn r305] Started support for custom class allocators/deallocators. Allocators with more than one argument still need to be fixed.
lindquist
parents:
279
diff
changeset
|
42 // llvmdc |
70c370e97944
[svn r305] Started support for custom class allocators/deallocators. Allocators with more than one argument still need to be fixed.
lindquist
parents:
279
diff
changeset
|
43 void findDefaultTarget(); |
70c370e97944
[svn r305] Started support for custom class allocators/deallocators. Allocators with more than one argument still need to be fixed.
lindquist
parents:
279
diff
changeset
|
44 |
159 | 45 Global global; |
46 | |
47 Global::Global() | |
48 { | |
49 mars_ext = "d"; | |
50 sym_ext = "d"; | |
51 hdr_ext = "di"; | |
52 doc_ext = "html"; | |
53 ddoc_ext = "ddoc"; | |
54 | |
55 #if IN_LLVM | |
56 obj_ext = "bc"; | |
57 ll_ext = "ll"; | |
58 bc_ext = "bc"; | |
59 nativeobj_ext = "o"; | |
60 #elif _WIN32 | |
61 obj_ext = "obj"; | |
62 #elif linux | |
63 obj_ext = "o"; | |
64 #else | |
65 #error "fix this" | |
66 #endif | |
67 | |
68 copyright = "Copyright (c) 1999-2008 by Digital Mars and Tomas Lindquist Olsen"; | |
69 written = "written by Walter Bright and Tomas Lindquist Olsen"; | |
70 version = "v1.029"; | |
71 llvmdc_version = "0.1"; | |
72 global.structalign = 8; | |
73 | |
74 memset(¶ms, 0, sizeof(Param)); | |
75 } | |
76 | |
77 char *Loc::toChars() const | |
78 { | |
79 OutBuffer buf; | |
80 char *p; | |
81 | |
82 if (filename) | |
83 { | |
84 buf.printf("%s", filename); | |
85 } | |
86 | |
87 if (linnum) | |
88 buf.printf("(%d)", linnum); | |
89 buf.writeByte(0); | |
90 return (char *)buf.extractData(); | |
91 } | |
92 | |
93 Loc::Loc(Module *mod, unsigned linnum) | |
94 { | |
95 this->linnum = linnum; | |
96 this->filename = mod ? mod->srcfile->toChars() : NULL; | |
97 } | |
98 | |
99 /************************************** | |
100 * Print error message and exit. | |
101 */ | |
102 | |
103 void error(Loc loc, const char *format, ...) | |
104 { | |
105 va_list ap; | |
106 va_start(ap, format); | |
107 verror(loc, format, ap); | |
108 va_end( ap ); | |
109 } | |
110 | |
111 void verror(Loc loc, const char *format, va_list ap) | |
112 { | |
113 if (!global.gag) | |
114 { | |
115 char *p = loc.toChars(); | |
116 | |
117 if (*p) | |
118 fprintf(stdmsg, "%s: ", p); | |
119 mem.free(p); | |
120 | |
121 fprintf(stdmsg, "Error: "); | |
122 vfprintf(stdmsg, format, ap); | |
123 fprintf(stdmsg, "\n"); | |
124 fflush(stdmsg); | |
125 } | |
126 global.errors++; | |
127 } | |
128 | |
129 /*************************************** | |
130 * Call this after printing out fatal error messages to clean up and exit | |
131 * the compiler. | |
132 */ | |
133 | |
134 void fatal() | |
135 { | |
136 #if 0 | |
137 halt(); | |
138 #endif | |
139 exit(EXIT_FAILURE); | |
140 } | |
141 | |
142 /************************************** | |
143 * Try to stop forgetting to remove the breakpoints from | |
144 * release builds. | |
145 */ | |
146 void halt() | |
147 { | |
148 #ifdef DEBUG | |
149 *(char*)0=0; | |
150 #endif | |
151 } | |
152 | |
153 extern void backend_init(); | |
154 extern void backend_term(); | |
155 | |
156 void usage() | |
157 { | |
205
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
159
diff
changeset
|
158 printf("LLVM D Compiler %s (based on DMD %s and LLVM 2.3)\n%s\n%s\n", |
159 | 159 global.llvmdc_version, global.version, global.copyright, global.written); |
160 printf("\ | |
161 D Language Documentation: http://www.digitalmars.com/d/1.0/index.html\n\ | |
162 LLVMDC Homepage: http://www.dsource.org/projects/llvmdc\n\ | |
163 Usage:\n\ | |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
306
diff
changeset
|
164 llvmdc files.d ... { -switch }\n\ |
159 | 165 \n\ |
166 files.d D source files\n%s\ | |
167 -annotate annotate the bitcode with human readable source code\n\ | |
168 -c do not link\n\ | |
169 -cov do code coverage analysis\n\ | |
170 -D generate documentation\n\ | |
171 -Dd<docdir> write documentation file to <docdir> directory\n\ | |
172 -Df<filename> write documentation file to <filename>\n\ | |
173 -d allow deprecated features\n\ | |
174 -debug compile in debug code\n\ | |
175 -debug=level compile in debug code <= level\n\ | |
176 -debug=ident compile in debug code identified by ident\n\ | |
177 -debuglib=name set symbolic debug library to name\n\ | |
178 -defaultlib=name set default library to name\n\ | |
179 -dis disassemble module after compiling\n\ | |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
180 -fp80 enable 80bit reals on x86 32bit (EXPERIMENTAL)\n\ |
159 | 181 -g add symbolic debug info\n\ |
182 -gc add symbolic debug info, pretend to be C\n\ | |
183 -H generate 'header' file\n\ | |
184 -Hd<hdrdir> write 'header' file to <hdrdir> directory\n\ | |
185 -Hf<filename> write 'header' file to <filename>\n\ | |
186 --help print help\n\ | |
187 -I<path> where to look for imports\n\ | |
188 -J<path> where to look for string imports\n\ | |
189 -ignore ignore unsupported pragmas\n\ | |
190 -inline do function inlining\n\ | |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
306
diff
changeset
|
191 -L<linkerflag> pass <linkerflag> to llvm-ld\n\ |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
306
diff
changeset
|
192 -m<arch> emit code specific to <arch> being one of:\n\ |
159 | 193 x86 x86-64 ppc32 ppc64\n\ |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
194 -noasm do not allow use of inline asm\n\ |
159 | 195 -nofloat do not emit reference to floating point\n\ |
196 -noruntime do not allow code that generates implicit runtime calls\n\ | |
197 -noverify do not run the validation pass before writing bitcode\n\ | |
198 -O optimize, same as -O2\n\ | |
199 -O<n> optimize at level <n> (0-5)\n\ | |
200 -o- do not write object file\n\ | |
201 -od<objdir> write object files to directory <objdir>\n\ | |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
306
diff
changeset
|
202 -of<filename> name output file to <filename>\n\ |
159 | 203 -op do not strip paths from source file\n\ |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
204 -oq write object files with fully qualified names\n\ |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
306
diff
changeset
|
205 -profile profile runtime performance of generated code\n\ |
159 | 206 -quiet suppress unnecessary messages\n\ |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
306
diff
changeset
|
207 -release compile release version\n\ |
159 | 208 -run srcfile args... run resulting program, passing args\n\ |
209 -R<path> provide path to the directory containing the runtime library\n\ | |
210 -unittest compile in unit tests\n\ | |
211 -v verbose\n\ | |
212 -vv very verbose (does not include -v)\n\ | |
213 -v1 D language version 1\n\ | |
214 -version=level compile in version code >= level\n\ | |
215 -version=ident compile in version code identified by ident\n\ | |
216 -w enable warnings\n\ | |
217 ", | |
218 #if WIN32 | |
219 " @cmdfile read arguments from cmdfile\n" | |
220 #else | |
221 "" | |
222 #endif | |
223 ); | |
224 } | |
225 | |
226 int main(int argc, char *argv[]) | |
227 { | |
228 int i; | |
229 Array files; | |
230 char *p; | |
231 Module *m; | |
232 int status = EXIT_SUCCESS; | |
233 int argcstart = argc; | |
234 char* tt_arch = 0; | |
235 char* tt_os = 0; | |
236 char* data_layout = 0; | |
237 bool very_verbose = false; | |
238 | |
239 // Check for malformed input | |
240 if (argc < 1 || !argv) | |
241 { | |
242 Largs: | |
243 error("missing or null command line arguments"); | |
244 fatal(); | |
245 } | |
246 for (i = 0; i < argc; i++) | |
247 { | |
248 if (!argv[i]) | |
249 goto Largs; | |
250 } | |
251 | |
252 #if __DMC__ // DMC unique support for response files | |
253 if (response_expand(&argc,&argv)) // expand response files | |
254 error("can't open response file"); | |
255 #endif | |
256 | |
257 files.reserve(argc - 1); | |
258 | |
259 // Set default values | |
260 global.params.argv0 = argv[0]; | |
261 global.params.link = 1; | |
262 global.params.useAssert = 0; | |
327
781af50846b2
[svn r348] Switch on class invariants (except in release mode).
ChristianK
parents:
323
diff
changeset
|
263 global.params.useInvariants = 1; |
159 | 264 global.params.useIn = 1; |
265 global.params.useOut = 1; | |
266 global.params.useArrayBounds = 0; | |
331
04e1b4930975
[svn r352] Implement SwitchErrorStatement. Fixes #52.
ChristianK
parents:
327
diff
changeset
|
267 global.params.useSwitchError = 1; |
159 | 268 global.params.useInline = 0; // this one messes things up to a point where codegen breaks |
269 global.params.llvmInline = 0; // use this one instead to know if inline passes should be run | |
270 global.params.obj = 1; | |
271 global.params.Dversion = 2; | |
272 global.params.quiet = 1; | |
273 | |
274 global.params.linkswitches = new Array(); | |
275 global.params.libfiles = new Array(); | |
276 global.params.objfiles = new Array(); | |
277 global.params.ddocfiles = new Array(); | |
278 | |
279 global.params.is64bit = sizeof(void*) == 8 ? 1 : 0; | |
280 | |
281 uint16_t endiantest = 0xFF00; | |
282 uint8_t endianres = ((uint8_t*)&endiantest)[0]; | |
283 if (endianres == 0x00) | |
284 global.params.isLE = true; | |
285 else if (endianres == 0xFF) | |
286 global.params.isLE = false; | |
287 else { | |
288 error("Endian test is broken"); | |
289 fatal(); | |
290 } | |
291 | |
292 global.params.llvmArch = 0; | |
293 global.params.forceBE = 0; | |
294 global.params.noruntime = 0; | |
295 global.params.novalidate = 0; | |
296 global.params.optimizeLevel = -1; | |
297 global.params.runtimeImppath = 0; | |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
298 global.params.useInlineAsm = 1; |
159 | 299 |
300 global.params.defaultlibname = "phobos"; | |
301 global.params.debuglibname = global.params.defaultlibname; | |
302 | |
303 // Predefine version identifiers | |
304 #if IN_LLVM | |
305 VersionCondition::addPredefinedGlobalIdent("LLVM"); | |
306 VersionCondition::addPredefinedGlobalIdent("LLVMDC"); | |
307 #endif | |
308 #if _WIN32 | |
309 VersionCondition::addPredefinedGlobalIdent("Windows"); | |
310 VersionCondition::addPredefinedGlobalIdent("Win32"); | |
279
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
311 VersionCondition::addPredefinedGlobalIdent("mingw32"); |
159 | 312 global.params.isWindows = 1; |
250
fc9c1a0eabbd
[svn r267] Fixed debug info for global variables.
lindquist
parents:
237
diff
changeset
|
313 tt_os = "-pc-mingw32"; |
159 | 314 #elif linux |
315 VersionCondition::addPredefinedGlobalIdent("linux"); | |
316 global.params.isLinux = 1; | |
279
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
317 tt_os = "-pc-linux-gnu"; |
159 | 318 #else |
319 #error | |
320 #endif /* linux */ | |
321 | |
279
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
322 // !win32 == posix for now |
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
323 if (!global.params.isWindows) |
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
324 VersionCondition::addPredefinedGlobalIdent("Posix"); |
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
325 |
159 | 326 //VersionCondition::addPredefinedGlobalIdent("D_Bits"); |
327 VersionCondition::addPredefinedGlobalIdent("all"); | |
328 | |
329 #if _WIN32 | |
330 inifile(argv[0], "llvmdc.ini"); | |
285
297690b5d4a5
[svn r306] Fixed: it's now possible to compile and link llvmdc with MinGW32 and msys on Win32 :D I tried it myself ;) Building the runtime still needs some work, but it's a step in the right direction.
lindquist
parents:
284
diff
changeset
|
331 #elif linux |
159 | 332 inifile(argv[0], "llvmdc.conf"); |
333 #else | |
334 #error | |
335 #endif | |
336 getenv_setargv("DFLAGS", &argc, &argv); | |
337 | |
338 #if 0 | |
339 for (i = 0; i < argc; i++) | |
340 { | |
341 printf("argv[%d] = '%s'\n", i, argv[i]); | |
342 } | |
343 #endif | |
344 | |
345 for (i = 1; i < argc; i++) | |
346 { | |
347 p = argv[i]; | |
348 if (*p == '-') | |
349 { | |
350 if (strcmp(p + 1, "d") == 0) | |
351 global.params.useDeprecated = 1; | |
352 else if (strcmp(p + 1, "c") == 0) | |
353 global.params.link = 0; | |
354 else if (strcmp(p + 1, "cov") == 0) | |
355 global.params.cov = 1; | |
356 else if (strcmp(p + 1, "fPIC") == 0) | |
357 global.params.pic = 1; | |
358 else if (strcmp(p + 1, "g") == 0) | |
359 global.params.symdebug = 1; | |
360 else if (strcmp(p + 1, "gc") == 0) | |
361 global.params.symdebug = 2; | |
362 else if (strcmp(p + 1, "gt") == 0) | |
363 { error("use -profile instead of -gt\n"); | |
364 global.params.trace = 1; | |
365 } | |
366 else if (strcmp(p + 1, "profile") == 0) | |
367 global.params.trace = 1; | |
368 else if (strcmp(p + 1, "v") == 0) | |
369 global.params.verbose = 1; | |
370 else if (strcmp(p + 1, "vv") == 0) { | |
371 Logger::enable(); | |
372 very_verbose = true; | |
373 } | |
374 else if (strcmp(p + 1, "v1") == 0) | |
375 global.params.Dversion = 1; | |
376 else if (strcmp(p + 1, "w") == 0) | |
377 global.params.warnings = 1; | |
378 else if (p[1] == 'O') | |
379 { | |
380 global.params.optimize = 1; | |
381 global.params.optimizeLevel = 2; | |
382 if (p[2] != 0) { | |
383 int optlevel = atoi(p+2); | |
384 if (optlevel < 0 || optlevel > 5) { | |
385 error("Optimization level must be between 0 and 5. Using default (%d)", | |
386 global.params.optimizeLevel); | |
387 } | |
388 else { | |
389 global.params.optimizeLevel = optlevel; | |
390 } | |
391 } | |
392 } | |
393 else if (strcmp(p + 1, "forcebe") == 0) | |
394 global.params.forceBE = 1; | |
395 else if (strcmp(p + 1, "noruntime") == 0) | |
396 global.params.noruntime = 1; | |
397 else if (strcmp(p + 1, "noverify") == 0) | |
398 global.params.novalidate = 1; | |
399 else if (strcmp(p + 1, "dis") == 0) | |
400 global.params.disassemble = 1; | |
401 else if (strcmp(p + 1, "annotate") == 0) | |
402 global.params.llvmAnnotate = 1; | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
403 else if (strcmp(p + 1, "fp80") == 0) |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
404 global.params.useFP80 = 1; |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
405 else if (strcmp(p + 1, "noasm") == 0) |
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
406 global.params.useInlineAsm = 0; |
159 | 407 else if (p[1] == 'o') |
408 { | |
409 switch (p[2]) | |
410 { | |
411 case '-': | |
412 global.params.obj = 0; | |
413 break; | |
414 | |
415 case 'd': | |
416 if (!p[3]) | |
417 goto Lnoarg; | |
418 global.params.objdir = p + 3; | |
419 break; | |
420 | |
421 case 'f': | |
422 if (!p[3]) | |
423 goto Lnoarg; | |
424 global.params.objname = p + 3; | |
425 break; | |
426 | |
427 case 'p': | |
428 if (p[3]) | |
429 goto Lerror; | |
430 global.params.preservePaths = 1; | |
431 break; | |
432 | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
433 case 'q': |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
434 if (p[3]) |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
435 goto Lerror; |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
436 global.params.fqnPaths = 1; |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
437 break; |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
438 |
159 | 439 case 0: |
440 error("-o no longer supported, use -of or -od"); | |
441 break; | |
442 | |
443 default: | |
444 goto Lerror; | |
445 } | |
446 } | |
447 else if (p[1] == 'D') | |
448 { global.params.doDocComments = 1; | |
449 switch (p[2]) | |
450 { | |
451 case 'd': | |
452 if (!p[3]) | |
453 goto Lnoarg; | |
454 global.params.docdir = p + 3; | |
455 break; | |
456 case 'f': | |
457 if (!p[3]) | |
458 goto Lnoarg; | |
459 global.params.docname = p + 3; | |
460 break; | |
461 | |
462 case 0: | |
463 break; | |
464 | |
465 default: | |
466 goto Lerror; | |
467 } | |
468 } | |
469 #ifdef _DH | |
470 else if (p[1] == 'H') | |
471 { global.params.doHdrGeneration = 1; | |
472 switch (p[2]) | |
473 { | |
474 case 'd': | |
475 if (!p[3]) | |
476 goto Lnoarg; | |
477 global.params.hdrdir = p + 3; | |
478 break; | |
479 | |
480 case 'f': | |
481 if (!p[3]) | |
482 goto Lnoarg; | |
483 global.params.hdrname = p + 3; | |
484 break; | |
485 | |
486 case 0: | |
487 break; | |
488 | |
489 default: | |
490 goto Lerror; | |
491 } | |
492 } | |
493 #endif | |
494 else if (strcmp(p + 1, "ignore") == 0) | |
495 global.params.ignoreUnsupportedPragmas = 1; | |
496 else if (strcmp(p + 1, "inline") == 0) { | |
497 // TODO | |
498 // the ast rewrites dmd does for inlining messes up the ast. | |
499 // someday maybe we can support it, for now llvm does an excellent job at inlining | |
500 global.params.useInline = 0; //1 | |
501 global.params.llvmInline = 1; | |
502 } | |
503 else if (strcmp(p + 1, "nofloat") == 0) | |
504 global.params.nofloat = 1; | |
505 else if (strcmp(p + 1, "quiet") == 0) | |
506 global.params.quiet = 1; | |
507 else if (strcmp(p + 1, "release") == 0) | |
508 global.params.release = 1; | |
509 else if (strcmp(p + 1, "unittest") == 0) | |
510 global.params.useUnitTests = 1; | |
511 else if (p[1] == 'I') | |
512 { | |
513 if (!global.params.imppath) | |
514 global.params.imppath = new Array(); | |
515 global.params.imppath->push(p + 2); | |
516 } | |
517 else if (p[1] == 'J') | |
518 { | |
519 if (!global.params.fileImppath) | |
520 global.params.fileImppath = new Array(); | |
521 global.params.fileImppath->push(p + 2); | |
522 } | |
523 else if (p[1] == 'R') | |
524 { | |
525 global.params.runtimePath = p+2; | |
526 } | |
527 else if (memcmp(p + 1, "debug", 5) == 0 && p[6] != 'l') | |
528 { | |
529 // Parse: | |
530 // -debug | |
531 // -debug=number | |
532 // -debug=identifier | |
533 if (p[6] == '=') | |
534 { | |
535 if (isdigit(p[7])) | |
536 { long level; | |
537 | |
538 errno = 0; | |
539 level = strtol(p + 7, &p, 10); | |
540 if (*p || errno || level > INT_MAX) | |
541 goto Lerror; | |
542 DebugCondition::setGlobalLevel((int)level); | |
543 } | |
544 else if (Lexer::isValidIdentifier(p + 7)) | |
545 DebugCondition::addGlobalIdent(p + 7); | |
546 else | |
547 goto Lerror; | |
548 } | |
549 else if (p[6]) | |
550 goto Lerror; | |
551 else | |
552 global.params.debuglevel = 1; | |
553 } | |
554 else if (memcmp(p + 1, "version", 5) == 0) | |
555 { | |
556 // Parse: | |
557 // -version=number | |
558 // -version=identifier | |
559 if (p[8] == '=') | |
560 { | |
561 if (isdigit(p[9])) | |
562 { long level; | |
563 | |
564 errno = 0; | |
565 level = strtol(p + 9, &p, 10); | |
566 if (*p || errno || level > INT_MAX) | |
567 goto Lerror; | |
568 VersionCondition::setGlobalLevel((int)level); | |
569 } | |
570 else if (Lexer::isValidIdentifier(p + 9)) | |
571 VersionCondition::addGlobalIdent(p + 9); | |
572 else | |
573 goto Lerror; | |
574 } | |
575 else | |
576 goto Lerror; | |
577 } | |
578 else if (strcmp(p + 1, "-b") == 0) | |
579 global.params.debugb = 1; | |
580 else if (strcmp(p + 1, "-c") == 0) | |
581 global.params.debugc = 1; | |
582 else if (strcmp(p + 1, "-f") == 0) | |
583 global.params.debugf = 1; | |
584 else if (strcmp(p + 1, "-help") == 0) | |
585 { usage(); | |
586 exit(EXIT_SUCCESS); | |
587 } | |
588 else if (strcmp(p + 1, "-r") == 0) | |
589 global.params.debugr = 1; | |
590 else if (strcmp(p + 1, "-x") == 0) | |
591 global.params.debugx = 1; | |
592 else if (strcmp(p + 1, "-y") == 0) | |
593 global.params.debugy = 1; | |
594 else if (p[1] == 'L') | |
595 { | |
596 global.params.linkswitches->push(p + 2); | |
597 } | |
598 else if (memcmp(p + 1, "defaultlib=", 11) == 0) | |
599 { | |
600 global.params.defaultlibname = p + 1 + 11; | |
601 } | |
602 else if (memcmp(p + 1, "debuglib=", 9) == 0) | |
603 { | |
604 global.params.debuglibname = p + 1 + 9; | |
605 } | |
606 else if (strcmp(p + 1, "run") == 0) | |
607 { global.params.run = 1; | |
608 global.params.runargs_length = ((i >= argcstart) ? argc : argcstart) - i - 1; | |
609 if (global.params.runargs_length) | |
610 { | |
611 files.push(argv[i + 1]); | |
612 global.params.runargs = &argv[i + 2]; | |
613 i += global.params.runargs_length; | |
614 global.params.runargs_length--; | |
615 } | |
616 else | |
617 { global.params.run = 0; | |
618 goto Lnoarg; | |
619 } | |
620 } | |
621 else if (p[1] == 'm') | |
622 { | |
623 global.params.llvmArch = p+2; | |
624 } | |
625 else | |
626 { | |
627 Lerror: | |
628 error("unrecognized switch '%s'", argv[i]); | |
629 continue; | |
630 | |
631 Lnoarg: | |
632 error("argument expected for switch '%s'", argv[i]); | |
633 continue; | |
634 } | |
635 } | |
636 else | |
637 files.push(p); | |
638 } | |
639 if (global.errors) | |
640 { | |
641 fatal(); | |
642 } | |
643 if (files.dim == 0) | |
644 { usage(); | |
645 return EXIT_FAILURE; | |
646 } | |
647 | |
648 if (global.params.release) | |
649 { global.params.useInvariants = 0; | |
650 global.params.useIn = 0; | |
651 global.params.useOut = 0; | |
652 global.params.useAssert = 0; | |
653 global.params.useArrayBounds = 0; | |
654 global.params.useSwitchError = 0; | |
655 } | |
656 | |
657 if (global.params.run) | |
658 global.params.quiet = 1; | |
659 | |
660 if (global.params.useUnitTests) | |
661 global.params.useAssert = 1; | |
662 | |
663 if (!global.params.obj) | |
664 global.params.link = 0; | |
665 | |
666 if (global.params.link) | |
667 { | |
668 global.params.exefile = global.params.objname; | |
669 global.params.objname = NULL; | |
670 } | |
671 else if (global.params.run) | |
672 { | |
673 error("flags conflict with -run"); | |
674 fatal(); | |
675 } | |
676 else | |
677 { | |
678 if (global.params.objname && files.dim > 1) | |
679 { | |
680 error("multiple source files, but only one .obj name"); | |
681 fatal(); | |
682 } | |
683 } | |
684 if (global.params.cov) | |
685 VersionCondition::addPredefinedGlobalIdent("D_Coverage"); | |
686 | |
687 bool allowForceEndianness = false; | |
688 | |
689 if (global.params.llvmArch == 0) { | |
284
70c370e97944
[svn r305] Started support for custom class allocators/deallocators. Allocators with more than one argument still need to be fixed.
lindquist
parents:
279
diff
changeset
|
690 findDefaultTarget(); |
159 | 691 } |
692 | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
693 bool is_x86 = false; |
159 | 694 if (strcmp(global.params.llvmArch,"x86")==0) { |
695 VersionCondition::addPredefinedGlobalIdent("X86"); | |
696 //VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86"); | |
697 global.params.isLE = true; | |
698 global.params.is64bit = false; | |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
699 global.params.cpu = ARCHx86; |
159 | 700 tt_arch = "i686"; |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
701 data_layout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-f80:32:32-v64:64:64-v128:128:128-a0:0:64"; |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
702 is_x86 = true; |
159 | 703 } |
704 else if (strcmp(global.params.llvmArch,"x86-64")==0) { | |
705 VersionCondition::addPredefinedGlobalIdent("X86_64"); | |
706 //VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86_64"); | |
707 global.params.isLE = true; | |
708 global.params.is64bit = true; | |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
709 global.params.cpu = ARCHx86_64; |
159 | 710 tt_arch = "x86_64"; |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
711 data_layout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"; |
159 | 712 } |
713 else if (strcmp(global.params.llvmArch,"ppc32")==0) { | |
714 VersionCondition::addPredefinedGlobalIdent("PPC"); | |
715 global.params.isLE = false; | |
716 global.params.is64bit = false; | |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
717 global.params.cpu = ARCHppc; |
159 | 718 tt_arch = "powerpc"; |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
719 data_layout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"; |
159 | 720 } |
721 else if (strcmp(global.params.llvmArch,"ppc64")==0) { | |
722 VersionCondition::addPredefinedGlobalIdent("PPC64"); | |
723 global.params.isLE = false; | |
724 global.params.is64bit = true; | |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
725 global.params.cpu = ARCHppc_64; |
159 | 726 tt_arch = "powerpc64"; |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
727 data_layout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"; |
159 | 728 } |
729 else { | |
730 assert(0 && "Invalid arch"); | |
731 } | |
732 | |
733 if (allowForceEndianness && global.params.forceBE) { | |
734 VersionCondition::addPredefinedGlobalIdent("BigEndian"); | |
735 global.params.isLE = false; | |
736 } | |
737 else if (global.params.isLE) { | |
738 VersionCondition::addPredefinedGlobalIdent("LittleEndian"); | |
739 } | |
740 else { | |
741 VersionCondition::addPredefinedGlobalIdent("BigEndian"); | |
742 } | |
743 | |
744 if (global.params.is64bit) { | |
745 VersionCondition::addPredefinedGlobalIdent("LLVM64"); | |
746 } | |
747 | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
748 if (global.params.useFP80) { |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
749 if (!is_x86) { |
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
750 error("the -fp80 option is only valid for the x86 32bit architecture"); |
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
751 fatal(); |
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
752 } |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
753 VersionCondition::addPredefinedGlobalIdent("LLVM_X86_FP80"); |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
754 } |
237
a168a2c3ea48
[svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents:
220
diff
changeset
|
755 if (is_x86 && global.params.useInlineAsm) { |
220
ccc2e6898a78
[svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents:
219
diff
changeset
|
756 VersionCondition::addPredefinedGlobalIdent("D_InlineAsm"); |
ccc2e6898a78
[svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents:
219
diff
changeset
|
757 VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86"); |
ccc2e6898a78
[svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents:
219
diff
changeset
|
758 } |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
205
diff
changeset
|
759 |
159 | 760 assert(tt_arch != 0); |
761 assert(tt_os != 0); | |
762 assert(data_layout != 0); | |
763 global.params.tt_arch = tt_arch; | |
764 global.params.tt_os = tt_os; | |
765 global.params.data_layout = data_layout; | |
766 | |
767 // Initialization | |
768 Type::init(); | |
769 Id::initialize(); | |
770 Module::init(); | |
771 initPrecedence(); | |
772 | |
773 backend_init(); | |
774 | |
775 //printf("%d source files\n",files.dim); | |
776 | |
777 // Build import search path | |
778 if (global.params.imppath) | |
779 { | |
780 for (i = 0; i < global.params.imppath->dim; i++) | |
781 { | |
782 char *path = (char *)global.params.imppath->data[i]; | |
783 Array *a = FileName::splitPath(path); | |
784 | |
785 if (a) | |
786 { | |
787 if (!global.path) | |
788 global.path = new Array(); | |
789 global.path->append(a); | |
790 } | |
791 } | |
792 } | |
793 | |
794 // Build string import search path | |
795 if (global.params.fileImppath) | |
796 { | |
797 for (i = 0; i < global.params.fileImppath->dim; i++) | |
798 { | |
799 char *path = (char *)global.params.fileImppath->data[i]; | |
800 Array *a = FileName::splitPath(path); | |
801 | |
802 if (a) | |
803 { | |
804 if (!global.filePath) | |
805 global.filePath = new Array(); | |
806 global.filePath->append(a); | |
807 } | |
808 } | |
809 } | |
810 | |
811 // Create Modules | |
812 Array modules; | |
813 modules.reserve(files.dim); | |
814 for (i = 0; i < files.dim; i++) | |
815 { Identifier *id; | |
816 char *ext; | |
817 char *name; | |
818 | |
819 p = (char *) files.data[i]; | |
820 | |
821 p = FileName::name(p); // strip path | |
822 ext = FileName::ext(p); | |
823 if (ext) | |
824 { | |
825 #if IN_LLVM | |
826 if (strcmp(ext, global.nativeobj_ext) == 0 || | |
827 strcmp(ext, global.obj_ext) == 0) | |
828 #elif TARGET_LINUX | |
829 if (strcmp(ext, global.obj_ext) == 0) | |
830 #else | |
831 if (stricmp(ext, global.obj_ext) == 0) | |
832 #endif | |
833 { | |
834 global.params.objfiles->push(files.data[i]); | |
835 continue; | |
836 } | |
837 | |
279
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
838 #if TARGET_LINUX || __MINGW32__ |
159 | 839 if (strcmp(ext, "a") == 0) |
840 #else | |
841 if (stricmp(ext, "lib") == 0) | |
842 #endif | |
843 { | |
844 global.params.libfiles->push(files.data[i]); | |
845 continue; | |
846 } | |
847 | |
848 if (strcmp(ext, global.ddoc_ext) == 0) | |
849 { | |
850 global.params.ddocfiles->push(files.data[i]); | |
851 continue; | |
852 } | |
853 | |
854 #if !TARGET_LINUX | |
855 if (stricmp(ext, "res") == 0) | |
856 { | |
857 global.params.resfile = (char *)files.data[i]; | |
858 continue; | |
859 } | |
860 | |
861 if (stricmp(ext, "def") == 0) | |
862 { | |
863 global.params.deffile = (char *)files.data[i]; | |
864 continue; | |
865 } | |
866 | |
867 if (stricmp(ext, "exe") == 0) | |
868 { | |
869 global.params.exefile = (char *)files.data[i]; | |
870 continue; | |
871 } | |
872 #endif | |
873 | |
874 if (stricmp(ext, global.mars_ext) == 0 || | |
875 stricmp(ext, "htm") == 0 || | |
876 stricmp(ext, "html") == 0 || | |
877 stricmp(ext, "xhtml") == 0) | |
878 { | |
879 ext--; // skip onto '.' | |
880 assert(*ext == '.'); | |
881 name = (char *)mem.malloc((ext - p) + 1); | |
882 memcpy(name, p, ext - p); | |
883 name[ext - p] = 0; // strip extension | |
884 | |
885 if (name[0] == 0 || | |
886 strcmp(name, "..") == 0 || | |
887 strcmp(name, ".") == 0) | |
888 { | |
889 Linvalid: | |
890 error("invalid file name '%s'", (char *)files.data[i]); | |
891 fatal(); | |
892 } | |
893 } | |
894 else | |
895 { error("unrecognized file extension %s\n", ext); | |
896 fatal(); | |
897 } | |
898 } | |
899 else | |
900 { name = p; | |
901 if (!*name) | |
902 goto Linvalid; | |
903 } | |
904 | |
905 id = new Identifier(name, 0); | |
906 m = new Module((char *) files.data[i], id, global.params.doDocComments, global.params.doHdrGeneration); | |
907 modules.push(m); | |
908 | |
909 global.params.objfiles->push(m->objfile->name->str); | |
910 } | |
911 | |
912 // Read files, parse them | |
913 for (i = 0; i < modules.dim; i++) | |
914 { | |
915 m = (Module *)modules.data[i]; | |
916 if (global.params.verbose) | |
917 printf("parse %s\n", m->toChars()); | |
918 if (!Module::rootModule) | |
919 Module::rootModule = m; | |
920 m->importedFrom = m; | |
921 m->deleteObjFile(); | |
922 m->read(0); | |
923 m->parse(); | |
924 if (m->isDocFile) | |
925 { | |
926 m->gendocfile(); | |
927 | |
928 // Remove m from list of modules | |
929 modules.remove(i); | |
930 i--; | |
931 | |
932 // Remove m's object file from list of object files | |
933 for (int j = 0; j < global.params.objfiles->dim; j++) | |
934 { | |
935 if (m->objfile->name->str == global.params.objfiles->data[j]) | |
936 { | |
937 global.params.objfiles->remove(j); | |
938 break; | |
939 } | |
940 } | |
941 | |
942 if (global.params.objfiles->dim == 0) | |
943 global.params.link = 0; | |
944 } | |
945 } | |
946 if (global.errors) | |
947 fatal(); | |
948 #ifdef _DH | |
949 if (global.params.doHdrGeneration) | |
950 { | |
951 /* Generate 'header' import files. | |
952 * Since 'header' import files must be independent of command | |
953 * line switches and what else is imported, they are generated | |
954 * before any semantic analysis. | |
955 */ | |
956 for (i = 0; i < modules.dim; i++) | |
957 { | |
958 m = (Module *)modules.data[i]; | |
959 if (global.params.verbose) | |
960 printf("import %s\n", m->toChars()); | |
961 m->genhdrfile(); | |
962 } | |
963 } | |
964 if (global.errors) | |
965 fatal(); | |
966 #endif | |
967 | |
968 // Do semantic analysis | |
969 for (i = 0; i < modules.dim; i++) | |
970 { | |
971 m = (Module *)modules.data[i]; | |
972 if (global.params.verbose) | |
973 printf("semantic %s\n", m->toChars()); | |
974 m->semantic(); | |
975 } | |
976 if (global.errors) | |
977 fatal(); | |
978 | |
979 // Do pass 2 semantic analysis | |
980 for (i = 0; i < modules.dim; i++) | |
981 { | |
982 m = (Module *)modules.data[i]; | |
983 if (global.params.verbose) | |
984 printf("semantic2 %s\n", m->toChars()); | |
985 m->semantic2(); | |
986 } | |
987 if (global.errors) | |
988 fatal(); | |
989 | |
990 // Do pass 3 semantic analysis | |
991 for (i = 0; i < modules.dim; i++) | |
992 { | |
993 m = (Module *)modules.data[i]; | |
994 if (global.params.verbose) | |
995 printf("semantic3 %s\n", m->toChars()); | |
996 m->semantic3(); | |
997 } | |
998 if (global.errors) | |
999 fatal(); | |
1000 | |
1001 #if !IN_LLVM | |
1002 // Scan for functions to inline | |
1003 if (global.params.useInline) | |
1004 { | |
1005 /* The problem with useArrayBounds and useAssert is that the | |
1006 * module being linked to may not have generated them, so if | |
1007 * we inline functions from those modules, the symbols for them will | |
1008 * not be found at link time. | |
1009 */ | |
1010 if (!global.params.useArrayBounds && !global.params.useAssert) | |
1011 { | |
1012 #endif | |
1013 // Do pass 3 semantic analysis on all imported modules, | |
1014 // since otherwise functions in them cannot be inlined | |
1015 for (i = 0; i < Module::amodules.dim; i++) | |
1016 { | |
1017 m = (Module *)Module::amodules.data[i]; | |
1018 if (global.params.verbose) | |
1019 printf("semantic3 %s\n", m->toChars()); | |
1020 m->semantic3(); | |
1021 } | |
1022 if (global.errors) | |
1023 fatal(); | |
1024 #if !IN_LLVM | |
1025 } | |
1026 | |
1027 for (i = 0; i < modules.dim; i++) | |
1028 { | |
1029 m = (Module *)modules.data[i]; | |
1030 if (global.params.verbose) | |
1031 printf("inline scan %s\n", m->toChars()); | |
1032 m->inlineScan(); | |
1033 } | |
1034 } | |
1035 if (global.errors) | |
1036 fatal(); | |
1037 #endif | |
1038 | |
1039 // Generate output files | |
1040 for (i = 0; i < modules.dim; i++) | |
1041 { | |
1042 m = (Module *)modules.data[i]; | |
1043 if (global.params.verbose) | |
1044 printf("code %s\n", m->toChars()); | |
1045 if (global.params.obj) | |
336 | 1046 m->genobjfile(0); |
159 | 1047 if (global.errors) |
1048 m->deleteObjFile(); | |
1049 else | |
1050 { | |
1051 if (global.params.doDocComments) | |
1052 m->gendocfile(); | |
1053 } | |
1054 } | |
279
a137ed004205
[svn r300] Removed some win32 stuff that was causing problems on mingw32.
lindquist
parents:
277
diff
changeset
|
1055 |
159 | 1056 backend_term(); |
1057 if (global.errors) | |
1058 fatal(); | |
1059 | |
1060 if (!global.params.objfiles->dim) | |
1061 { | |
1062 if (global.params.link) | |
1063 error("no object files to link"); | |
1064 } | |
1065 else | |
1066 { | |
1067 if (global.params.link) | |
276
21f85bac0b1a
[svn r297] Fixed: rewrote linker code to use LLVM's Program facilities instead of DMD's oldschool broken "native" approach.
lindquist
parents:
262
diff
changeset
|
1068 //status = runLINK(); |
306
0baca2feb554
[svn r327] Fixed some more MinGW32 issues. It's now very close to working.
lindquist
parents:
285
diff
changeset
|
1069 linkExecutable(argv[0]); |
159 | 1070 |
1071 if (global.params.run) | |
1072 { | |
1073 if (!status) | |
1074 { | |
277
90a8c798b0db
[svn r298] Eliminated the dmd/link.c source file entirely in favor of a llvm::sys based approach to the same functionality.
lindquist
parents:
276
diff
changeset
|
1075 status = runExectuable(); |
159 | 1076 |
1077 /* Delete .obj files and .exe file | |
1078 */ | |
1079 for (i = 0; i < modules.dim; i++) | |
1080 { | |
1081 m = (Module *)modules.data[i]; | |
1082 m->deleteObjFile(); | |
1083 } | |
277
90a8c798b0db
[svn r298] Eliminated the dmd/link.c source file entirely in favor of a llvm::sys based approach to the same functionality.
lindquist
parents:
276
diff
changeset
|
1084 deleteExecutable(); |
159 | 1085 } |
1086 } | |
1087 } | |
1088 | |
1089 return status; | |
1090 } | |
1091 | |
1092 | |
1093 | |
1094 /*********************************** | |
1095 * Parse and append contents of environment variable envvar | |
1096 * to argc and argv[]. | |
1097 * The string is separated into arguments, processing \ and ". | |
1098 */ | |
1099 | |
1100 void getenv_setargv(const char *envvar, int *pargc, char** *pargv) | |
1101 { | |
1102 char *env; | |
1103 char *p; | |
1104 Array *argv; | |
1105 int argc; | |
1106 | |
1107 int wildcard; // do wildcard expansion | |
1108 int instring; | |
1109 int slash; | |
1110 char c; | |
1111 int j; | |
1112 | |
1113 env = getenv(envvar); | |
1114 if (!env) | |
1115 return; | |
1116 | |
1117 env = mem.strdup(env); // create our own writable copy | |
1118 | |
1119 argc = *pargc; | |
1120 argv = new Array(); | |
1121 argv->setDim(argc); | |
1122 | |
1123 for (int i = 0; i < argc; i++) | |
1124 argv->data[i] = (void *)(*pargv)[i]; | |
1125 | |
1126 j = 1; // leave argv[0] alone | |
1127 while (1) | |
1128 { | |
1129 wildcard = 1; | |
1130 switch (*env) | |
1131 { | |
1132 case ' ': | |
1133 case '\t': | |
1134 env++; | |
1135 break; | |
1136 | |
1137 case 0: | |
1138 goto Ldone; | |
1139 | |
1140 case '"': | |
1141 wildcard = 0; | |
1142 default: | |
1143 argv->push(env); // append | |
1144 //argv->insert(j, env); // insert at position j | |
1145 j++; | |
1146 argc++; | |
1147 p = env; | |
1148 slash = 0; | |
1149 instring = 0; | |
1150 c = 0; | |
1151 | |
1152 while (1) | |
1153 { | |
1154 c = *env++; | |
1155 switch (c) | |
1156 { | |
1157 case '"': | |
1158 p -= (slash >> 1); | |
1159 if (slash & 1) | |
1160 { p--; | |
1161 goto Laddc; | |
1162 } | |
1163 instring ^= 1; | |
1164 slash = 0; | |
1165 continue; | |
1166 | |
1167 case ' ': | |
1168 case '\t': | |
1169 if (instring) | |
1170 goto Laddc; | |
1171 *p = 0; | |
1172 //if (wildcard) | |
1173 //wildcardexpand(); // not implemented | |
1174 break; | |
1175 | |
1176 case '\\': | |
1177 slash++; | |
1178 *p++ = c; | |
1179 continue; | |
1180 | |
1181 case 0: | |
1182 *p = 0; | |
1183 //if (wildcard) | |
1184 //wildcardexpand(); // not implemented | |
1185 goto Ldone; | |
1186 | |
1187 default: | |
1188 Laddc: | |
1189 slash = 0; | |
1190 *p++ = c; | |
1191 continue; | |
1192 } | |
1193 break; | |
1194 } | |
1195 } | |
1196 } | |
1197 | |
1198 Ldone: | |
1199 *pargc = argc; | |
1200 *pargv = (char **)argv->data; | |
1201 } |