Mercurial > projects > ldc
annotate dmd/mars.c @ 1404:11b122f92136
Now that templates instantiations are no longer emitted for all modules that
even blink at them they seem to break due to being linkonce (if compiled with
any optimization level > 0), so let's give them weak linkage instead.
The difference is that unreferenced linkonce symbols can be deleted, while
weak symbols need to be preserved.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Thu, 21 May 2009 15:23:28 +0200 |
parents | dd5dbe7b3923 |
children | def7a1d494fd |
rev | line source |
---|---|
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1133
diff
changeset
|
1 |
159 | 2 // Compiler implementation of the D programming language |
876
27a379f288bf
Merged DMD 1.039
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
875
diff
changeset
|
3 // Copyright (c) 1999-2009 by Digital Mars |
159 | 4 // All Rights Reserved |
5 // written by Walter Bright | |
6 // http://www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <stdio.h> | |
12 #include <stdlib.h> | |
13 #include <ctype.h> | |
14 #include <assert.h> | |
15 #include <limits.h> | |
16 #include <string> | |
17 #include <cstdarg> | |
18 | |
571
cbd6c8073a32
Changed all '#if linux || __APPLE__' to '#if POSIX' so we can support other platforms too, thanx for the suggestion anders.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
568
diff
changeset
|
19 #if POSIX |
159 | 20 #include <errno.h> |
432 | 21 #elif _WIN32 |
22 #include <windows.h> | |
159 | 23 #endif |
24 | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
25 #include "rmem.h" |
159 | 26 #include "root.h" |
27 | |
28 #include "mars.h" | |
29 #include "module.h" | |
30 #include "mtype.h" | |
31 #include "id.h" | |
32 #include "cond.h" | |
33 #include "expression.h" | |
34 #include "lexer.h" | |
35 | |
1064
f0b6549055ab
Make LDC work with LLVM trunk (s/LinkOnceLinkage/LinkOnceOdrLinkage/)
Frits van Bommel <fvbommel wxs.nl>
parents:
988
diff
changeset
|
36 #include "gen/revisions.h" |
788
dce4b4ea2aee
Print llvm package string in version header. See #128.
Christian Kamm <kamm incasoftware de>
parents:
785
diff
changeset
|
37 |
159 | 38 Global global; |
39 | |
40 Global::Global() | |
41 { | |
42 mars_ext = "d"; | |
43 sym_ext = "d"; | |
44 hdr_ext = "di"; | |
45 doc_ext = "html"; | |
46 ddoc_ext = "ddoc"; | |
47 | |
663
6aaa3d3c1183
First part of rename to LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
48 // LDC |
159 | 49 ll_ext = "ll"; |
50 bc_ext = "bc"; | |
675
bfe5229f9d8e
Disable bc output by default. Remove -dis. Add -output-bc, -output-ll, -output-s.
Christian Kamm <kamm incasoftware de>
parents:
663
diff
changeset
|
51 s_ext = "s"; |
708
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
700
diff
changeset
|
52 obj_ext = "o"; |
374
1f20b9f7de1b
Fix nativeobj extension for Windows.
Christian Kamm <kamm incasoftware de>
parents:
366
diff
changeset
|
53 #if _WIN32 |
708
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
700
diff
changeset
|
54 obj_ext_alt = "obj"; |
159 | 55 #endif |
56 | |
876
27a379f288bf
Merged DMD 1.039
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
875
diff
changeset
|
57 copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen"; |
159 | 58 written = "written by Walter Bright and Tomas Lindquist Olsen"; |
1369
dd5dbe7b3923
Updated DMDFE version id from 1.042 to 1.045 ...
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1195
diff
changeset
|
59 version = "v1.045"; |
853
82ad6c0c601c
Add Elrood's patch to output LDC and LLVM source revs.
Christian Kamm <kamm incasoftware de>
parents:
849
diff
changeset
|
60 ldc_version = LDC_REV; |
1064
f0b6549055ab
Make LDC work with LLVM trunk (s/LinkOnceLinkage/LinkOnceOdrLinkage/)
Frits van Bommel <fvbommel wxs.nl>
parents:
988
diff
changeset
|
61 llvm_version = LLVM_REV_STR; |
159 | 62 global.structalign = 8; |
63 | |
986
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
64 // This should only be used as a global, so the other fields are |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
65 // automatically initialized to zero when the program is loaded. |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
66 // In particular, DO NOT zero-initialize .params here (like DMD |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
67 // does) because command-line options initialize some of those |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
68 // fields to non-zero defaults, and do so from constructors that |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
69 // may run before this one. |
159 | 70 } |
71 | |
72 char *Loc::toChars() const | |
73 { | |
74 OutBuffer buf; | |
75 | |
76 if (filename) | |
77 { | |
78 buf.printf("%s", filename); | |
79 } | |
80 | |
81 if (linnum) | |
82 buf.printf("(%d)", linnum); | |
83 buf.writeByte(0); | |
84 return (char *)buf.extractData(); | |
85 } | |
86 | |
87 Loc::Loc(Module *mod, unsigned linnum) | |
88 { | |
89 this->linnum = linnum; | |
90 this->filename = mod ? mod->srcfile->toChars() : NULL; | |
91 } | |
92 | |
93 /************************************** | |
94 * Print error message and exit. | |
95 */ | |
96 | |
97 void error(Loc loc, const char *format, ...) | |
98 { | |
99 va_list ap; | |
100 va_start(ap, format); | |
101 verror(loc, format, ap); | |
102 va_end( ap ); | |
103 } | |
104 | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
105 void warning(Loc loc, const char *format, ...) |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
106 { |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
107 if (global.params.warnings && !global.gag) |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
108 { |
1124
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
109 va_list ap; |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
110 va_start(ap, format); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
111 vwarning(loc, format, ap); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
112 va_end( ap ); |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
113 } |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
114 } |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1064
diff
changeset
|
115 |
159 | 116 void verror(Loc loc, const char *format, va_list ap) |
117 { | |
118 if (!global.gag) | |
119 { | |
120 char *p = loc.toChars(); | |
121 | |
122 if (*p) | |
123 fprintf(stdmsg, "%s: ", p); | |
124 mem.free(p); | |
125 | |
126 fprintf(stdmsg, "Error: "); | |
127 vfprintf(stdmsg, format, ap); | |
128 fprintf(stdmsg, "\n"); | |
129 fflush(stdmsg); | |
130 } | |
131 global.errors++; | |
132 } | |
133 | |
1124
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
134 void vwarning(Loc loc, const char *format, va_list ap) |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
135 { |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
136 if (global.params.warnings && !global.gag) |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
137 { |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
138 char *p = loc.toChars(); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
139 |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
140 if (*p) |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
141 fprintf(stdmsg, "%s: ", p); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
142 mem.free(p); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
143 |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
144 fprintf(stdmsg, "Warning: "); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
145 vfprintf(stdmsg, format, ap); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
146 fprintf(stdmsg, "\n"); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
147 fflush(stdmsg); |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
148 } |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
149 } |
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
150 |
159 | 151 /*************************************** |
152 * Call this after printing out fatal error messages to clean up and exit | |
153 * the compiler. | |
154 */ | |
155 | |
156 void fatal() | |
157 { | |
158 #if 0 | |
159 halt(); | |
160 #endif | |
161 exit(EXIT_FAILURE); | |
162 } | |
163 | |
164 /************************************** | |
165 * Try to stop forgetting to remove the breakpoints from | |
166 * release builds. | |
167 */ | |
168 void halt() | |
169 { | |
170 #ifdef DEBUG | |
171 *(char*)0=0; | |
172 #endif | |
173 } | |
174 | |
175 /*********************************** | |
176 * Parse and append contents of environment variable envvar | |
177 * to argc and argv[]. | |
178 * The string is separated into arguments, processing \ and ". | |
179 */ | |
180 | |
181 void getenv_setargv(const char *envvar, int *pargc, char** *pargv) | |
182 { | |
183 char *env; | |
184 char *p; | |
185 Array *argv; | |
186 int argc; | |
187 | |
188 int wildcard; // do wildcard expansion | |
189 int instring; | |
190 int slash; | |
191 char c; | |
192 int j; | |
193 | |
194 env = getenv(envvar); | |
195 if (!env) | |
196 return; | |
197 | |
198 env = mem.strdup(env); // create our own writable copy | |
199 | |
200 argc = *pargc; | |
201 argv = new Array(); | |
202 argv->setDim(argc); | |
203 | |
986
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
204 int argc_left = 0; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
205 for (int i = 0; i < argc; i++) { |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
206 if (!strcmp((*pargv)[i], "-run") || !strcmp((*pargv)[i], "--run")) { |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
207 // HACK: set flag to indicate we saw '-run' here |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
208 global.params.run = true; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
209 // Don't eat -run yet so the program arguments don't get changed |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
210 argc_left = argc - i; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
211 argc = i; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
212 *pargv = &(*pargv)[i]; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
213 argv->setDim(i); |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
214 break; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
215 } else { |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
216 argv->data[i] = (void *)(*pargv)[i]; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
217 } |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
218 } |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
219 // HACK to stop required values from command line being drawn from DFLAGS |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
220 argv->push((char*)""); |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
221 argc++; |
159 | 222 |
223 j = 1; // leave argv[0] alone | |
224 while (1) | |
225 { | |
226 wildcard = 1; | |
227 switch (*env) | |
228 { | |
229 case ' ': | |
230 case '\t': | |
231 env++; | |
232 break; | |
233 | |
234 case 0: | |
235 goto Ldone; | |
236 | |
237 case '"': | |
238 wildcard = 0; | |
239 default: | |
240 argv->push(env); // append | |
241 //argv->insert(j, env); // insert at position j | |
242 j++; | |
243 argc++; | |
244 p = env; | |
245 slash = 0; | |
246 instring = 0; | |
247 c = 0; | |
248 | |
249 while (1) | |
250 { | |
251 c = *env++; | |
252 switch (c) | |
253 { | |
254 case '"': | |
255 p -= (slash >> 1); | |
256 if (slash & 1) | |
257 { p--; | |
258 goto Laddc; | |
259 } | |
260 instring ^= 1; | |
261 slash = 0; | |
262 continue; | |
263 | |
264 case ' ': | |
265 case '\t': | |
266 if (instring) | |
267 goto Laddc; | |
268 *p = 0; | |
269 //if (wildcard) | |
270 //wildcardexpand(); // not implemented | |
271 break; | |
272 | |
273 case '\\': | |
274 slash++; | |
275 *p++ = c; | |
276 continue; | |
277 | |
278 case 0: | |
279 *p = 0; | |
280 //if (wildcard) | |
281 //wildcardexpand(); // not implemented | |
282 goto Ldone; | |
283 | |
284 default: | |
285 Laddc: | |
286 slash = 0; | |
287 *p++ = c; | |
288 continue; | |
289 } | |
290 break; | |
291 } | |
292 } | |
293 } | |
294 | |
295 Ldone: | |
986
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
296 assert(argc == argv->dim); |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
297 argv->reserve(argc_left); |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
298 for (int i = 0; i < argc_left; i++) |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
299 argv->data[argc++] = (void *)(*pargv)[i]; |
a8cb25d478c4
Use LLVM-style command line (instead of DMD-style)
Frits van Bommel <fvbommel wxs.nl>
parents:
960
diff
changeset
|
300 |
159 | 301 *pargc = argc; |
302 *pargv = (char **)argv->data; | |
303 } |