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