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