Mercurial > projects > ldc
annotate dmd/module.c @ 948:780530d1cad3
Revert templates to old behavior.
While emitting a template instantiation only once is good for compile times
and binary sizes, it doesn't work with linkonce linkage as inlined function
bodies could be discarded. Since we don't want to inhibit inlining, templates
are reverted to the previous behavior, where an instantiation is emitted for
each module using it.
In the future, a custom inlining pass may allow us to switch back to
common/weak linkage and reenable smart template instance emission.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 08 Feb 2009 21:44:46 +0100 |
parents | 330f999ade44 |
children | 369996c08420 |
rev | line source |
---|---|
336 | 1 |
2 // Compiler implementation of the D programming language | |
3 // Copyright (c) 1999-2007 by Digital Mars | |
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 <assert.h> | |
14 | |
872
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
751
diff
changeset
|
15 #if (defined (__SVR4) && defined (__sun)) |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
751
diff
changeset
|
16 #include <alloca.h> |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
751
diff
changeset
|
17 #endif |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
751
diff
changeset
|
18 |
336 | 19 #if _MSC_VER || __MINGW32__ |
20 #include <malloc.h> | |
21 #endif | |
22 | |
23 #if IN_GCC | |
24 #include "gdc_alloca.h" | |
25 #endif | |
26 | |
27 #include "mem.h" | |
28 | |
29 #include "mars.h" | |
30 #include "module.h" | |
31 #include "parse.h" | |
32 #include "scope.h" | |
33 #include "identifier.h" | |
34 #include "id.h" | |
35 #include "import.h" | |
36 #include "dsymbol.h" | |
37 #include "hdrgen.h" | |
38 #include "lexer.h" | |
39 | |
40 #define MARS 1 | |
41 #include "html.h" | |
42 | |
43 #ifdef IN_GCC | |
44 #include "d-dmd-gcc.h" | |
45 #endif | |
46 | |
47 ClassDeclaration *Module::moduleinfo; | |
48 | |
49 Module *Module::rootModule; | |
50 DsymbolTable *Module::modules; | |
51 Array Module::amodules; | |
52 | |
53 Array Module::deferred; // deferred Dsymbol's needing semantic() run on them | |
54 unsigned Module::dprogress; | |
55 | |
56 void Module::init() | |
57 { | |
58 modules = new DsymbolTable(); | |
59 } | |
60 | |
61 Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen) | |
62 : Package(ident) | |
63 { | |
64 FileName *srcfilename; | |
65 | |
66 // printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); | |
67 this->arg = filename; | |
68 md = NULL; | |
69 errors = 0; | |
70 numlines = 0; | |
71 members = NULL; | |
72 isHtml = 0; | |
73 isDocFile = 0; | |
74 needmoduleinfo = 0; | |
75 #ifdef IN_GCC | |
76 strictlyneedmoduleinfo = 0; | |
77 #endif | |
78 insearch = 0; | |
79 searchCacheIdent = NULL; | |
80 searchCacheSymbol = NULL; | |
81 searchCacheFlags = 0; | |
82 semanticstarted = 0; | |
83 semanticdone = 0; | |
84 decldefs = NULL; | |
85 vmoduleinfo = NULL; | |
86 massert = NULL; | |
87 marray = NULL; | |
88 sictor = NULL; | |
89 sctor = NULL; | |
90 sdtor = NULL; | |
91 stest = NULL; | |
92 sfilename = NULL; | |
93 root = 0; | |
94 importedFrom = NULL; | |
95 srcfile = NULL; | |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
96 objfile = NULL; |
336 | 97 docfile = NULL; |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
98 hdrfile = NULL; |
336 | 99 |
100 debuglevel = 0; | |
101 debugids = NULL; | |
102 debugidsNot = NULL; | |
103 versionlevel = 0; | |
104 versionids = NULL; | |
105 versionidsNot = NULL; | |
106 | |
107 macrotable = NULL; | |
108 escapetable = NULL; | |
109 doppelganger = 0; | |
110 cov = NULL; | |
111 covb = NULL; | |
112 | |
113 srcfilename = FileName::defaultExt(filename, global.mars_ext); | |
114 if (!srcfilename->equalsExt(global.mars_ext) && | |
510
6aee82889553
Merged DMD 1.034, array operations are not yet implemented ;)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
486
diff
changeset
|
115 !srcfilename->equalsExt(global.hdr_ext) && |
336 | 116 !srcfilename->equalsExt("dd")) |
117 { | |
118 if (srcfilename->equalsExt("html") || | |
119 srcfilename->equalsExt("htm") || | |
120 srcfilename->equalsExt("xhtml")) | |
121 isHtml = 1; | |
122 else | |
123 { error("source file name '%s' must have .%s extension", srcfilename->toChars(), global.mars_ext); | |
124 fatal(); | |
125 } | |
126 } | |
127 srcfile = new File(srcfilename); | |
128 | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
643
diff
changeset
|
129 // LDC |
486
a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
336
diff
changeset
|
130 llvmForceLogging = false; |
604
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
131 this->doDocComment = doDocComment; |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
132 this->doHdrGen = doHdrGen; |
336 | 133 } |
134 | |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
135 File* Module::buildFilePath(char* forcename, char* path, char* ext) |
336 | 136 { |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
137 char *argobj; |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
138 if (forcename) |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
139 argobj = forcename; |
336 | 140 else |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
141 { |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
142 if (global.params.preservePaths) |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
143 argobj = (char*)this->arg; |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
144 else |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
145 argobj = FileName::name((char*)this->arg); |
336 | 146 |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
147 if (global.params.fqnNames) |
643 | 148 { |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
149 if(md) |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
150 argobj = FileName::replaceName(argobj, md->toChars()); |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
151 else |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
152 argobj = FileName::replaceName(argobj, toChars()); |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
153 |
643 | 154 // add ext, otherwise forceExt will make nested.module into nested.bc |
155 size_t len = strlen(argobj); | |
156 size_t extlen = strlen(ext); | |
157 char* s = (char *)alloca(len + 1 + extlen + 1); | |
158 memcpy(s, argobj, len); | |
159 s[len] = '.'; | |
160 memcpy(s + len + 1, ext, extlen + 1); | |
161 s[len+1+extlen] = 0; | |
162 argobj = s; | |
163 } | |
336 | 164 } |
165 | |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
166 if (!FileName::absolute(argobj)) |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
167 { |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
168 argobj = FileName::combine(path, argobj); |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
169 } |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
170 |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
171 FileName::ensurePathExists(FileName::path(argobj)); |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
172 |
708
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
173 // always append the extension! otherwise hard to make output switches consistent |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
174 // if (forcename) |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
175 // return new File(argobj); |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
176 // else |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
177 // allow for .o and .obj on windows |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
178 #if _WIN32 |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
179 if (ext == global.params.objdir && FileName::ext(argobj) |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
180 && stricmp(FileName::ext(argobj), global.obj_ext_alt) == 0) |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
181 return new File(argobj); |
708
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
182 #endif |
fd5665da3a27
Hopefully sensible command switch handling. Changed default ext to .o on Windows.
Christian Kamm <kamm incasoftware de>
parents:
675
diff
changeset
|
183 return new File(FileName::forceExt(argobj, ext)); |
336 | 184 } |
185 | |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
186 void Module::buildTargetFiles() |
336 | 187 { |
604
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
188 if(objfile && |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
189 (!doDocComment || docfile) && |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
190 (!doHdrGen || hdrfile)) |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
191 return; |
336 | 192 |
604
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
193 if(!objfile) |
675
bfe5229f9d8e
Disable bc output by default. Remove -dis. Add -output-bc, -output-ll, -output-s.
Christian Kamm <kamm incasoftware de>
parents:
664
diff
changeset
|
194 objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.obj_ext); |
604
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
195 if(doDocComment && !docfile) |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
196 docfile = Module::buildFilePath(global.params.docname, global.params.docdir, global.doc_ext); |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
197 if(doHdrGen && !hdrfile) |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
198 hdrfile = Module::buildFilePath(global.params.hdrname, global.params.hdrdir, global.hdr_ext); |
598
13ff06605226
To prevert source-overwriting in the future, forbit output files with the same
Christian Kamm <kamm incasoftware de>
parents:
597
diff
changeset
|
199 |
13ff06605226
To prevert source-overwriting in the future, forbit output files with the same
Christian Kamm <kamm incasoftware de>
parents:
597
diff
changeset
|
200 // safety check: never allow obj, doc or hdr file to have the source file's name |
604
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
201 if(stricmp(FileName::name(objfile->name->str), FileName::name((char*)this->arg)) == 0) |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
202 { |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
203 error("Output object files with the same name as the source file are forbidden"); |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
204 fatal(); |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
205 } |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
206 if(docfile && stricmp(FileName::name(docfile->name->str), FileName::name((char*)this->arg)) == 0) |
598
13ff06605226
To prevert source-overwriting in the future, forbit output files with the same
Christian Kamm <kamm incasoftware de>
parents:
597
diff
changeset
|
207 { |
604
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
208 error("Output doc files with the same name as the source file are forbidden"); |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
209 fatal(); |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
210 } |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
211 if(hdrfile && stricmp(FileName::name(hdrfile->name->str), FileName::name((char*)this->arg)) == 0) |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
212 { |
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
213 error("Output header files with the same name as the source file are forbidden"); |
598
13ff06605226
To prevert source-overwriting in the future, forbit output files with the same
Christian Kamm <kamm incasoftware de>
parents:
597
diff
changeset
|
214 fatal(); |
13ff06605226
To prevert source-overwriting in the future, forbit output files with the same
Christian Kamm <kamm incasoftware de>
parents:
597
diff
changeset
|
215 } |
336 | 216 } |
217 | |
218 void Module::deleteObjFile() | |
219 { | |
220 if (global.params.obj) | |
221 objfile->remove(); | |
222 //if (global.params.llvmBC) | |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
223 //bcfile->remove(); |
604
a30fc28e8f23
Make creating and deleting of doc and hdr files dependent on whether doc and
Christian Kamm <kamm incasoftware de>
parents:
598
diff
changeset
|
224 if (doDocComment && docfile) |
336 | 225 docfile->remove(); |
226 } | |
227 | |
228 Module::~Module() | |
229 { | |
230 } | |
231 | |
232 const char *Module::kind() | |
233 { | |
234 return "module"; | |
235 } | |
236 | |
237 Module *Module::load(Loc loc, Array *packages, Identifier *ident) | |
238 { Module *m; | |
239 char *filename; | |
240 | |
241 //printf("Module::load(ident = '%s')\n", ident->toChars()); | |
242 | |
243 // Build module filename by turning: | |
244 // foo.bar.baz | |
245 // into: | |
246 // foo\bar\baz | |
247 filename = ident->toChars(); | |
248 if (packages && packages->dim) | |
249 { | |
250 OutBuffer buf; | |
251 int i; | |
252 | |
253 for (i = 0; i < packages->dim; i++) | |
254 { Identifier *pid = (Identifier *)packages->data[i]; | |
255 | |
256 buf.writestring(pid->toChars()); | |
257 #if _WIN32 | |
258 buf.writeByte('\\'); | |
259 #else | |
260 buf.writeByte('/'); | |
261 #endif | |
262 } | |
263 buf.writestring(filename); | |
264 buf.writeByte(0); | |
265 filename = (char *)buf.extractData(); | |
266 } | |
267 | |
268 m = new Module(filename, ident, 0, 0); | |
269 m->loc = loc; | |
270 | |
271 /* Search along global.path for .di file, then .d file. | |
272 */ | |
273 char *result = NULL; | |
274 FileName *fdi = FileName::forceExt(filename, global.hdr_ext); | |
275 FileName *fd = FileName::forceExt(filename, global.mars_ext); | |
276 char *sdi = fdi->toChars(); | |
277 char *sd = fd->toChars(); | |
278 | |
279 if (FileName::exists(sdi)) | |
280 result = sdi; | |
281 else if (FileName::exists(sd)) | |
282 result = sd; | |
283 else if (FileName::absolute(filename)) | |
284 ; | |
285 else if (!global.path) | |
286 ; | |
287 else | |
288 { | |
289 for (size_t i = 0; i < global.path->dim; i++) | |
290 { | |
291 char *p = (char *)global.path->data[i]; | |
292 char *n = FileName::combine(p, sdi); | |
293 if (FileName::exists(n)) | |
294 { result = n; | |
295 break; | |
296 } | |
297 mem.free(n); | |
298 n = FileName::combine(p, sd); | |
299 if (FileName::exists(n)) | |
300 { result = n; | |
301 break; | |
302 } | |
303 mem.free(n); | |
304 } | |
305 } | |
306 if (result) | |
307 m->srcfile = new File(result); | |
308 | |
309 if (global.params.verbose) | |
310 { | |
311 printf("import "); | |
312 if (packages) | |
313 { | |
314 for (size_t i = 0; i < packages->dim; i++) | |
315 { Identifier *pid = (Identifier *)packages->data[i]; | |
316 printf("%s.", pid->toChars()); | |
317 } | |
318 } | |
319 printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars()); | |
320 } | |
321 | |
322 m->read(loc); | |
323 m->parse(); | |
324 | |
325 #ifdef IN_GCC | |
326 d_gcc_magic_module(m); | |
327 #endif | |
328 | |
329 return m; | |
330 } | |
331 | |
332 void Module::read(Loc loc) | |
333 { | |
334 //printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars()); | |
335 if (srcfile->read()) | |
336 { error(loc, "cannot read file '%s'", srcfile->toChars()); | |
337 fatal(); | |
338 } | |
339 } | |
340 | |
341 inline unsigned readwordLE(unsigned short *p) | |
342 { | |
343 #if __I86__ | |
344 return *p; | |
345 #else | |
346 return (((unsigned char *)p)[1] << 8) | ((unsigned char *)p)[0]; | |
347 #endif | |
348 } | |
349 | |
350 inline unsigned readwordBE(unsigned short *p) | |
351 { | |
352 return (((unsigned char *)p)[0] << 8) | ((unsigned char *)p)[1]; | |
353 } | |
354 | |
355 inline unsigned readlongLE(unsigned *p) | |
356 { | |
357 #if __I86__ | |
358 return *p; | |
359 #else | |
360 return ((unsigned char *)p)[0] | | |
361 (((unsigned char *)p)[1] << 8) | | |
362 (((unsigned char *)p)[2] << 16) | | |
363 (((unsigned char *)p)[3] << 24); | |
364 #endif | |
365 } | |
366 | |
367 inline unsigned readlongBE(unsigned *p) | |
368 { | |
369 return ((unsigned char *)p)[3] | | |
370 (((unsigned char *)p)[2] << 8) | | |
371 (((unsigned char *)p)[1] << 16) | | |
372 (((unsigned char *)p)[0] << 24); | |
373 } | |
374 | |
375 #if IN_GCC | |
376 void Module::parse(bool dump_source) | |
377 #else | |
378 void Module::parse() | |
379 #endif | |
380 { char *srcname; | |
381 unsigned char *buf; | |
382 unsigned buflen; | |
383 unsigned le; | |
384 unsigned bom; | |
385 | |
386 //printf("Module::parse()\n"); | |
387 | |
388 srcname = srcfile->name->toChars(); | |
389 //printf("Module::parse(srcname = '%s')\n", srcname); | |
390 | |
391 buf = srcfile->buffer; | |
392 buflen = srcfile->len; | |
393 | |
394 if (buflen >= 2) | |
395 { | |
396 /* Convert all non-UTF-8 formats to UTF-8. | |
397 * BOM : http://www.unicode.org/faq/utf_bom.html | |
398 * 00 00 FE FF UTF-32BE, big-endian | |
399 * FF FE 00 00 UTF-32LE, little-endian | |
400 * FE FF UTF-16BE, big-endian | |
401 * FF FE UTF-16LE, little-endian | |
402 * EF BB BF UTF-8 | |
403 */ | |
404 | |
405 bom = 1; // assume there's a BOM | |
406 if (buf[0] == 0xFF && buf[1] == 0xFE) | |
407 { | |
408 if (buflen >= 4 && buf[2] == 0 && buf[3] == 0) | |
409 { // UTF-32LE | |
410 le = 1; | |
411 | |
412 Lutf32: | |
413 OutBuffer dbuf; | |
414 unsigned *pu = (unsigned *)(buf); | |
415 unsigned *pumax = &pu[buflen / 4]; | |
416 | |
417 if (buflen & 3) | |
418 { error("odd length of UTF-32 char source %u", buflen); | |
419 fatal(); | |
420 } | |
421 | |
422 dbuf.reserve(buflen / 4); | |
423 for (pu += bom; pu < pumax; pu++) | |
424 { unsigned u; | |
425 | |
426 u = le ? readlongLE(pu) : readlongBE(pu); | |
427 if (u & ~0x7F) | |
428 { | |
429 if (u > 0x10FFFF) | |
430 { error("UTF-32 value %08x greater than 0x10FFFF", u); | |
431 fatal(); | |
432 } | |
433 dbuf.writeUTF8(u); | |
434 } | |
435 else | |
436 dbuf.writeByte(u); | |
437 } | |
438 dbuf.writeByte(0); // add 0 as sentinel for scanner | |
439 buflen = dbuf.offset - 1; // don't include sentinel in count | |
440 buf = (unsigned char *) dbuf.extractData(); | |
441 } | |
442 else | |
443 { // UTF-16LE (X86) | |
444 // Convert it to UTF-8 | |
445 le = 1; | |
446 | |
447 Lutf16: | |
448 OutBuffer dbuf; | |
449 unsigned short *pu = (unsigned short *)(buf); | |
450 unsigned short *pumax = &pu[buflen / 2]; | |
451 | |
452 if (buflen & 1) | |
453 { error("odd length of UTF-16 char source %u", buflen); | |
454 fatal(); | |
455 } | |
456 | |
457 dbuf.reserve(buflen / 2); | |
458 for (pu += bom; pu < pumax; pu++) | |
459 { unsigned u; | |
460 | |
461 u = le ? readwordLE(pu) : readwordBE(pu); | |
462 if (u & ~0x7F) | |
463 { if (u >= 0xD800 && u <= 0xDBFF) | |
464 { unsigned u2; | |
465 | |
466 if (++pu > pumax) | |
467 { error("surrogate UTF-16 high value %04x at EOF", u); | |
468 fatal(); | |
469 } | |
470 u2 = le ? readwordLE(pu) : readwordBE(pu); | |
471 if (u2 < 0xDC00 || u2 > 0xDFFF) | |
472 { error("surrogate UTF-16 low value %04x out of range", u2); | |
473 fatal(); | |
474 } | |
475 u = (u - 0xD7C0) << 10; | |
476 u |= (u2 - 0xDC00); | |
477 } | |
478 else if (u >= 0xDC00 && u <= 0xDFFF) | |
479 { error("unpaired surrogate UTF-16 value %04x", u); | |
480 fatal(); | |
481 } | |
482 else if (u == 0xFFFE || u == 0xFFFF) | |
483 { error("illegal UTF-16 value %04x", u); | |
484 fatal(); | |
485 } | |
486 dbuf.writeUTF8(u); | |
487 } | |
488 else | |
489 dbuf.writeByte(u); | |
490 } | |
491 dbuf.writeByte(0); // add 0 as sentinel for scanner | |
492 buflen = dbuf.offset - 1; // don't include sentinel in count | |
493 buf = (unsigned char *) dbuf.extractData(); | |
494 } | |
495 } | |
496 else if (buf[0] == 0xFE && buf[1] == 0xFF) | |
497 { // UTF-16BE | |
498 le = 0; | |
499 goto Lutf16; | |
500 } | |
501 else if (buflen >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF) | |
502 { // UTF-32BE | |
503 le = 0; | |
504 goto Lutf32; | |
505 } | |
506 else if (buflen >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF) | |
507 { // UTF-8 | |
508 | |
509 buf += 3; | |
510 buflen -= 3; | |
511 } | |
512 else | |
513 { | |
514 /* There is no BOM. Make use of Arcane Jill's insight that | |
515 * the first char of D source must be ASCII to | |
516 * figure out the encoding. | |
517 */ | |
518 | |
519 bom = 0; | |
520 if (buflen >= 4) | |
521 { if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0) | |
522 { // UTF-32LE | |
523 le = 1; | |
524 goto Lutf32; | |
525 } | |
526 else if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) | |
527 { // UTF-32BE | |
528 le = 0; | |
529 goto Lutf32; | |
530 } | |
531 } | |
532 if (buflen >= 2) | |
533 { | |
534 if (buf[1] == 0) | |
535 { // UTF-16LE | |
536 le = 1; | |
537 goto Lutf16; | |
538 } | |
539 else if (buf[0] == 0) | |
540 { // UTF-16BE | |
541 le = 0; | |
542 goto Lutf16; | |
543 } | |
544 } | |
545 | |
546 // It's UTF-8 | |
547 if (buf[0] >= 0x80) | |
548 { error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]); | |
549 fatal(); | |
550 } | |
551 } | |
552 } | |
553 | |
554 #ifdef IN_GCC | |
555 // dump utf-8 encoded source | |
556 if (dump_source) | |
557 { // %% srcname could contain a path ... | |
558 d_gcc_dump_source(srcname, "utf-8", buf, buflen); | |
559 } | |
560 #endif | |
561 | |
562 /* If it starts with the string "Ddoc", then it's a documentation | |
563 * source file. | |
564 */ | |
565 if (buflen >= 4 && memcmp(buf, "Ddoc", 4) == 0) | |
566 { | |
567 comment = buf + 4; | |
568 isDocFile = 1; | |
569 return; | |
570 } | |
571 if (isHtml) | |
572 { | |
573 OutBuffer *dbuf = new OutBuffer(); | |
574 Html h(srcname, buf, buflen); | |
575 h.extractCode(dbuf); | |
576 buf = dbuf->data; | |
577 buflen = dbuf->offset; | |
578 #ifdef IN_GCC | |
579 // dump extracted source | |
580 if (dump_source) | |
581 d_gcc_dump_source(srcname, "d.utf-8", buf, buflen); | |
582 #endif | |
583 } | |
584 Parser p(this, buf, buflen, docfile != NULL); | |
585 p.nextToken(); | |
586 members = p.parseModule(); | |
587 md = p.md; | |
588 numlines = p.loc.linnum; | |
589 | |
590 DsymbolTable *dst; | |
591 | |
592 if (md) | |
593 { this->ident = md->id; | |
594 dst = Package::resolve(md->packages, &this->parent, NULL); | |
595 } | |
596 else | |
597 { | |
598 dst = modules; | |
599 | |
600 /* Check to see if module name is a valid identifier | |
601 */ | |
602 if (!Lexer::isValidIdentifier(this->ident->toChars())) | |
603 error("has non-identifier characters in filename, use module declaration instead"); | |
604 } | |
605 | |
606 // Update global list of modules | |
607 if (!dst->insert(this)) | |
608 { | |
609 if (md) | |
610 error(loc, "is in multiple packages %s", md->toChars()); | |
611 else | |
612 error(loc, "is in multiple defined"); | |
613 } | |
614 else | |
615 { | |
616 amodules.push(this); | |
617 } | |
618 } | |
619 | |
751
dc8b8b7ea0c1
Fix compile-time warnings. Adjust include in d-asm-i386.
Christian Kamm <kamm incasoftware de>
parents:
708
diff
changeset
|
620 void Module::semantic(Scope* unused_sc) |
336 | 621 { int i; |
622 | |
623 if (semanticstarted) | |
624 return; | |
625 | |
626 //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); | |
627 semanticstarted = 1; | |
628 | |
629 // Note that modules get their own scope, from scratch. | |
630 // This is so regardless of where in the syntax a module | |
631 // gets imported, it is unaffected by context. | |
632 Scope *sc = Scope::createGlobal(this); // create root scope | |
633 | |
634 //printf("Module = %p, linkage = %d\n", sc->scopesym, sc->linkage); | |
635 | |
636 // Add import of "object" if this module isn't "object" | |
637 if (ident != Id::object) | |
638 { | |
639 Import *im = new Import(0, NULL, Id::object, NULL, 0); | |
640 members->shift(im); | |
641 } | |
642 | |
643 // Add all symbols into module's symbol table | |
644 symtab = new DsymbolTable(); | |
645 for (i = 0; i < members->dim; i++) | |
646 { Dsymbol *s; | |
647 | |
648 s = (Dsymbol *)members->data[i]; | |
649 s->addMember(NULL, sc->scopesym, 1); | |
650 } | |
651 | |
652 // Pass 1 semantic routines: do public side of the definition | |
653 for (i = 0; i < members->dim; i++) | |
654 { Dsymbol *s; | |
655 | |
656 s = (Dsymbol *)members->data[i]; | |
657 //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars()); | |
658 s->semantic(sc); | |
659 runDeferredSemantic(); | |
660 } | |
661 | |
662 sc = sc->pop(); | |
663 sc->pop(); | |
664 semanticdone = semanticstarted; | |
665 //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); | |
666 } | |
667 | |
751
dc8b8b7ea0c1
Fix compile-time warnings. Adjust include in d-asm-i386.
Christian Kamm <kamm incasoftware de>
parents:
708
diff
changeset
|
668 void Module::semantic2(Scope* unused_sc) |
336 | 669 { int i; |
670 | |
671 if (deferred.dim) | |
672 { | |
673 for (int i = 0; i < deferred.dim; i++) | |
674 { | |
675 Dsymbol *sd = (Dsymbol *)deferred.data[i]; | |
676 | |
677 sd->error("unable to resolve forward reference in definition"); | |
678 } | |
679 return; | |
680 } | |
681 //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent); | |
682 if (semanticstarted >= 2) | |
683 return; | |
684 assert(semanticstarted == 1); | |
685 semanticstarted = 2; | |
686 | |
687 // Note that modules get their own scope, from scratch. | |
688 // This is so regardless of where in the syntax a module | |
689 // gets imported, it is unaffected by context. | |
690 Scope *sc = Scope::createGlobal(this); // create root scope | |
691 //printf("Module = %p\n", sc.scopesym); | |
692 | |
693 // Pass 2 semantic routines: do initializers and function bodies | |
694 for (i = 0; i < members->dim; i++) | |
695 { Dsymbol *s; | |
696 | |
697 s = (Dsymbol *)members->data[i]; | |
698 s->semantic2(sc); | |
699 } | |
700 | |
701 sc = sc->pop(); | |
702 sc->pop(); | |
703 semanticdone = semanticstarted; | |
704 //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent); | |
705 } | |
706 | |
751
dc8b8b7ea0c1
Fix compile-time warnings. Adjust include in d-asm-i386.
Christian Kamm <kamm incasoftware de>
parents:
708
diff
changeset
|
707 void Module::semantic3(Scope* unused_sc) |
336 | 708 { int i; |
709 | |
710 //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent); | |
711 if (semanticstarted >= 3) | |
712 return; | |
713 assert(semanticstarted == 2); | |
714 semanticstarted = 3; | |
715 | |
716 // Note that modules get their own scope, from scratch. | |
717 // This is so regardless of where in the syntax a module | |
718 // gets imported, it is unaffected by context. | |
719 Scope *sc = Scope::createGlobal(this); // create root scope | |
720 //printf("Module = %p\n", sc.scopesym); | |
721 | |
722 // Pass 3 semantic routines: do initializers and function bodies | |
723 for (i = 0; i < members->dim; i++) | |
724 { Dsymbol *s; | |
725 | |
726 s = (Dsymbol *)members->data[i]; | |
727 //printf("Module %s: %s.semantic3()\n", toChars(), s->toChars()); | |
728 s->semantic3(sc); | |
729 } | |
730 | |
731 sc = sc->pop(); | |
732 sc->pop(); | |
733 semanticdone = semanticstarted; | |
734 } | |
735 | |
736 void Module::inlineScan() | |
737 { int i; | |
738 | |
739 if (semanticstarted >= 4) | |
740 return; | |
741 assert(semanticstarted == 3); | |
742 semanticstarted = 4; | |
743 | |
744 // Note that modules get their own scope, from scratch. | |
745 // This is so regardless of where in the syntax a module | |
746 // gets imported, it is unaffected by context. | |
747 //printf("Module = %p\n", sc.scopesym); | |
748 | |
749 for (i = 0; i < members->dim; i++) | |
750 { Dsymbol *s; | |
751 | |
752 s = (Dsymbol *)members->data[i]; | |
753 //if (global.params.verbose) | |
754 //printf("inline scan symbol %s\n", s->toChars()); | |
755 | |
756 s->inlineScan(); | |
757 } | |
758 semanticdone = semanticstarted; | |
759 } | |
760 | |
761 /**************************************************** | |
762 */ | |
763 | |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
764 // is this used anywhere? |
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
765 /* |
336 | 766 void Module::gensymfile() |
767 { | |
768 OutBuffer buf; | |
769 HdrGenState hgs; | |
770 | |
771 //printf("Module::gensymfile()\n"); | |
772 | |
773 buf.printf("// Sym file generated from '%s'", srcfile->toChars()); | |
774 buf.writenl(); | |
775 | |
776 for (int i = 0; i < members->dim; i++) | |
777 { Dsymbol *s = (Dsymbol *)members->data[i]; | |
778 | |
779 s->toCBuffer(&buf, &hgs); | |
780 } | |
781 | |
782 // Transfer image to file | |
783 symfile->setbuffer(buf.data, buf.offset); | |
784 buf.data = NULL; | |
785 | |
786 symfile->writev(); | |
580
7824c21a58e3
Restructure path handling a bit. Fixes #66.
Christian Kamm <kamm incasoftware de>
parents:
550
diff
changeset
|
787 }*/ |
336 | 788 |
789 /********************************** | |
790 * Determine if we need to generate an instance of ModuleInfo | |
791 * for this Module. | |
792 */ | |
793 | |
794 int Module::needModuleInfo() | |
795 { | |
550
cbe08531430f
Removed unimplemented switches.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
510
diff
changeset
|
796 return needmoduleinfo; |
336 | 797 } |
798 | |
799 Dsymbol *Module::search(Loc loc, Identifier *ident, int flags) | |
800 { | |
801 /* Since modules can be circularly referenced, | |
802 * need to stop infinite recursive searches. | |
803 */ | |
804 | |
805 //printf("%s Module::search('%s', flags = %d) insearch = %d\n", toChars(), ident->toChars(), flags, insearch); | |
806 Dsymbol *s; | |
807 if (insearch) | |
808 s = NULL; | |
809 else if (searchCacheIdent == ident && searchCacheFlags == flags) | |
810 s = searchCacheSymbol; | |
811 else | |
812 { | |
813 insearch = 1; | |
814 s = ScopeDsymbol::search(loc, ident, flags); | |
815 insearch = 0; | |
816 | |
817 searchCacheIdent = ident; | |
818 searchCacheSymbol = s; | |
819 searchCacheFlags = flags; | |
820 } | |
821 return s; | |
822 } | |
823 | |
824 /******************************************* | |
825 * Can't run semantic on s now, try again later. | |
826 */ | |
827 | |
828 void Module::addDeferredSemantic(Dsymbol *s) | |
829 { | |
830 // Don't add it if it is already there | |
831 for (int i = 0; i < deferred.dim; i++) | |
832 { | |
833 Dsymbol *sd = (Dsymbol *)deferred.data[i]; | |
834 | |
835 if (sd == s) | |
836 return; | |
837 } | |
838 | |
839 //printf("Module::addDeferredSemantic('%s')\n", s->toChars()); | |
840 deferred.push(s); | |
841 } | |
842 | |
843 | |
844 /****************************************** | |
845 * Run semantic() on deferred symbols. | |
846 */ | |
847 | |
848 void Module::runDeferredSemantic() | |
849 { | |
850 size_t len; | |
851 | |
852 static int nested; | |
853 if (nested) | |
854 return; | |
855 //if (deferred.dim) printf("+Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim); | |
856 nested++; | |
857 | |
858 do | |
859 { | |
860 dprogress = 0; | |
861 len = deferred.dim; | |
862 if (!len) | |
863 break; | |
864 | |
865 Dsymbol **todo; | |
866 Dsymbol *tmp; | |
867 if (len == 1) | |
868 { | |
869 todo = &tmp; | |
870 } | |
871 else | |
872 { | |
873 todo = (Dsymbol **)alloca(len * sizeof(Dsymbol *)); | |
874 assert(todo); | |
875 } | |
876 memcpy(todo, deferred.data, len * sizeof(Dsymbol *)); | |
877 deferred.setDim(0); | |
878 | |
879 for (int i = 0; i < len; i++) | |
880 { | |
881 Dsymbol *s = todo[i]; | |
882 | |
883 s->semantic(NULL); | |
884 //printf("deferred: %s, parent = %s\n", s->toChars(), s->parent->toChars()); | |
885 } | |
886 //printf("\tdeferred.dim = %d, len = %d, dprogress = %d\n", deferred.dim, len, dprogress); | |
887 } while (deferred.dim < len || dprogress); // while making progress | |
888 nested--; | |
889 //printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim); | |
890 } | |
891 | |
875
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
892 /************************************ |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
893 * Recursively look at every module this module imports, |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
894 * return TRUE if it imports m. |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
895 * Can be used to detect circular imports. |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
896 */ |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
897 |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
898 int Module::imports(Module *m) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
899 { |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
900 //printf("%s Module::imports(%s)\n", toChars(), m->toChars()); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
901 int aimports_dim = aimports.dim; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
902 #if 0 |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
903 for (int i = 0; i < aimports.dim; i++) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
904 { Module *mi = (Module *)aimports.data[i]; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
905 printf("\t[%d] %s\n", i, mi->toChars()); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
906 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
907 #endif |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
908 for (int i = 0; i < aimports.dim; i++) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
909 { Module *mi = (Module *)aimports.data[i]; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
910 if (mi == m) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
911 return TRUE; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
912 if (!mi->insearch) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
913 { |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
914 mi->insearch = 1; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
915 int r = mi->imports(m); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
916 mi->insearch = 0; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
917 if (r) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
918 return r; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
919 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
920 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
921 return FALSE; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
922 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
923 |
336 | 924 /* =========================== ModuleDeclaration ===================== */ |
925 | |
926 ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id) | |
927 { | |
928 this->packages = packages; | |
929 this->id = id; | |
930 } | |
931 | |
932 char *ModuleDeclaration::toChars() | |
933 { | |
934 OutBuffer buf; | |
935 int i; | |
936 | |
937 if (packages && packages->dim) | |
938 { | |
939 for (i = 0; i < packages->dim; i++) | |
940 { Identifier *pid = (Identifier *)packages->data[i]; | |
941 | |
942 buf.writestring(pid->toChars()); | |
943 buf.writeByte('.'); | |
944 } | |
945 } | |
946 buf.writestring(id->toChars()); | |
947 buf.writeByte(0); | |
948 return (char *)buf.extractData(); | |
949 } | |
950 | |
951 /* =========================== Package ===================== */ | |
952 | |
953 Package::Package(Identifier *ident) | |
954 : ScopeDsymbol(ident) | |
955 { | |
956 } | |
957 | |
958 | |
959 const char *Package::kind() | |
960 { | |
961 return "package"; | |
962 } | |
963 | |
964 | |
965 DsymbolTable *Package::resolve(Array *packages, Dsymbol **pparent, Package **ppkg) | |
966 { | |
967 DsymbolTable *dst = Module::modules; | |
968 Dsymbol *parent = NULL; | |
969 | |
970 //printf("Package::resolve()\n"); | |
971 if (ppkg) | |
972 *ppkg = NULL; | |
973 | |
974 if (packages) | |
975 { int i; | |
976 | |
977 for (i = 0; i < packages->dim; i++) | |
978 { Identifier *pid = (Identifier *)packages->data[i]; | |
979 Dsymbol *p; | |
980 | |
981 p = dst->lookup(pid); | |
982 if (!p) | |
983 { | |
984 p = new Package(pid); | |
985 dst->insert(p); | |
986 p->parent = parent; | |
987 ((ScopeDsymbol *)p)->symtab = new DsymbolTable(); | |
988 } | |
989 else | |
990 { | |
991 assert(p->isPackage()); | |
992 if (p->isModule()) | |
993 { p->error("module and package have the same name"); | |
994 fatal(); | |
995 break; | |
996 } | |
997 } | |
998 parent = p; | |
999 dst = ((Package *)p)->symtab; | |
1000 if (ppkg && !*ppkg) | |
1001 *ppkg = (Package *)p; | |
1002 } | |
1003 if (pparent) | |
1004 { | |
1005 *pparent = parent; | |
1006 } | |
1007 } | |
1008 return dst; | |
1009 } |