Mercurial > projects > ldc
comparison dmd2/module.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 2667e3a145be |
children | 54b3c1394d62 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2007 by Digital Mars | 3 // Copyright (c) 1999-2009 by Digital Mars |
4 // All Rights Reserved | 4 // All Rights Reserved |
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // http://www.digitalmars.com | 6 // http://www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
10 | 10 |
11 #include <stdio.h> | 11 #include <stdio.h> |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <assert.h> | 13 #include <assert.h> |
14 | 14 |
15 #if _MSC_VER || __MINGW32__ | 15 #if (defined (__SVR4) && defined (__sun)) |
16 #include <alloca.h> | |
17 #endif | |
18 | |
19 #if defined(_MSC_VER) || defined(__MINGW32__) | |
16 #include <malloc.h> | 20 #include <malloc.h> |
17 #endif | 21 #endif |
18 | 22 |
19 #if IN_GCC | 23 #if IN_GCC |
20 #include "gdc_alloca.h" | 24 #include "gdc_alloca.h" |
21 #endif | 25 #endif |
22 | 26 |
23 #include "mem.h" | 27 #include "rmem.h" |
24 | 28 |
25 #include "mars.h" | 29 #include "mars.h" |
26 #include "module.h" | 30 #include "module.h" |
27 #include "parse.h" | 31 #include "parse.h" |
28 #include "scope.h" | 32 #include "scope.h" |
38 | 42 |
39 #ifdef IN_GCC | 43 #ifdef IN_GCC |
40 #include "d-dmd-gcc.h" | 44 #include "d-dmd-gcc.h" |
41 #endif | 45 #endif |
42 | 46 |
43 | 47 #if IN_LLVM |
44 #include "llvm/Support/CommandLine.h" | 48 #include "llvm/Support/CommandLine.h" |
45 | 49 |
46 static llvm::cl::opt<bool> preservePaths("op", | 50 static llvm::cl::opt<bool> preservePaths("op", |
47 llvm::cl::desc("Do not strip paths from source file"), | 51 llvm::cl::desc("Do not strip paths from source file"), |
48 llvm::cl::ZeroOrMore); | 52 llvm::cl::ZeroOrMore); |
49 | 53 |
50 static llvm::cl::opt<bool> fqnNames("oq", | 54 static llvm::cl::opt<bool> fqnNames("oq", |
51 llvm::cl::desc("Write object files with fully qualified names"), | 55 llvm::cl::desc("Write object files with fully qualified names"), |
52 llvm::cl::ZeroOrMore); | 56 llvm::cl::ZeroOrMore); |
53 | 57 #endif |
54 | |
55 | 58 |
56 ClassDeclaration *Module::moduleinfo; | 59 ClassDeclaration *Module::moduleinfo; |
57 | 60 |
58 Module *Module::rootModule; | 61 Module *Module::rootModule; |
59 DsymbolTable *Module::modules; | 62 DsymbolTable *Module::modules; |
69 | 72 |
70 Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen) | 73 Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen) |
71 : Package(ident) | 74 : Package(ident) |
72 { | 75 { |
73 FileName *srcfilename; | 76 FileName *srcfilename; |
77 #if IN_DMD | |
78 FileName *cfilename; | |
79 FileName *hfilename; | |
80 FileName *objfilename; | |
81 FileName *symfilename; | |
82 #endif | |
74 | 83 |
75 // printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); | 84 // printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); |
76 this->arg = filename; | 85 this->arg = filename; |
77 md = NULL; | 86 md = NULL; |
78 errors = 0; | 87 errors = 0; |
82 isDocFile = 0; | 91 isDocFile = 0; |
83 needmoduleinfo = 0; | 92 needmoduleinfo = 0; |
84 #ifdef IN_GCC | 93 #ifdef IN_GCC |
85 strictlyneedmoduleinfo = 0; | 94 strictlyneedmoduleinfo = 0; |
86 #endif | 95 #endif |
96 selfimports = 0; | |
87 insearch = 0; | 97 insearch = 0; |
88 searchCacheIdent = NULL; | 98 searchCacheIdent = NULL; |
89 searchCacheSymbol = NULL; | 99 searchCacheSymbol = NULL; |
90 searchCacheFlags = 0; | 100 searchCacheFlags = 0; |
91 semanticstarted = 0; | 101 semanticstarted = 0; |
92 semanticdone = 0; | 102 semanticdone = 0; |
93 decldefs = NULL; | 103 decldefs = NULL; |
94 vmoduleinfo = NULL; | 104 vmoduleinfo = NULL; |
105 #if IN_DMD | |
95 massert = NULL; | 106 massert = NULL; |
96 marray = NULL; | 107 marray = NULL; |
97 sictor = NULL; | 108 sictor = NULL; |
98 sctor = NULL; | 109 sctor = NULL; |
99 sdtor = NULL; | 110 sdtor = NULL; |
100 stest = NULL; | 111 stest = NULL; |
101 sfilename = NULL; | 112 sfilename = NULL; |
113 #endif | |
102 root = 0; | 114 root = 0; |
103 importedFrom = NULL; | 115 importedFrom = NULL; |
104 srcfile = NULL; | 116 srcfile = NULL; |
105 objfile = NULL; | 117 objfile = NULL; |
106 docfile = NULL; | 118 docfile = NULL; |
114 versionidsNot = NULL; | 126 versionidsNot = NULL; |
115 | 127 |
116 macrotable = NULL; | 128 macrotable = NULL; |
117 escapetable = NULL; | 129 escapetable = NULL; |
118 safe = FALSE; | 130 safe = FALSE; |
131 #if IN-DMD | |
119 doppelganger = 0; | 132 doppelganger = 0; |
120 cov = NULL; | 133 cov = NULL; |
121 covb = NULL; | 134 covb = NULL; |
135 #endif | |
122 | 136 |
123 srcfilename = FileName::defaultExt(filename, global.mars_ext); | 137 srcfilename = FileName::defaultExt(filename, global.mars_ext); |
124 if (!srcfilename->equalsExt(global.mars_ext) && | 138 if (!srcfilename->equalsExt(global.mars_ext) && |
125 !srcfilename->equalsExt(global.hdr_ext) && | 139 !srcfilename->equalsExt(global.hdr_ext) && |
126 !srcfilename->equalsExt("dd")) | 140 !srcfilename->equalsExt("dd")) |
135 else | 149 else |
136 { error("source file name '%s' must have .%s extension", srcfilename->toChars(), global.mars_ext); | 150 { error("source file name '%s' must have .%s extension", srcfilename->toChars(), global.mars_ext); |
137 fatal(); | 151 fatal(); |
138 } | 152 } |
139 } | 153 } |
154 #if !IN_LLVM | |
155 char *argobj; | |
156 if (global.params.objname) | |
157 argobj = global.params.objname; | |
158 else if (global.params.preservePaths) | |
159 argobj = filename; | |
160 else | |
161 argobj = FileName::name(filename); | |
162 if (!FileName::absolute(argobj)) | |
163 { | |
164 argobj = FileName::combine(global.params.objdir, argobj); | |
165 } | |
166 | |
167 if (global.params.objname) | |
168 objfilename = new FileName(argobj, 0); | |
169 else | |
170 objfilename = FileName::forceExt(argobj, global.obj_ext); | |
171 | |
172 symfilename = FileName::forceExt(filename, global.sym_ext); | |
173 #endif | |
174 | |
140 srcfile = new File(srcfilename); | 175 srcfile = new File(srcfilename); |
141 | 176 #if IN_DMD |
177 if (doDocComment) | |
178 { | |
179 setDocfile(); | |
180 } | |
181 | |
182 if (doHdrGen) | |
183 { | |
184 setHdrfile(); | |
185 } | |
186 | |
187 objfile = new File(objfilename); | |
188 symfile = new File(symfilename); | |
189 #endif | |
190 #if IN_LLVM | |
142 // LDC | 191 // LDC |
143 llvmForceLogging = false; | 192 llvmForceLogging = false; |
144 this->doDocComment = doDocComment; | 193 this->doDocComment = doDocComment; |
145 this->doHdrGen = doHdrGen; | 194 this->doHdrGen = doHdrGen; |
146 } | 195 #endif |
147 | 196 } |
148 File* Module::buildFilePath(char* forcename, const char* path, const char* ext) | 197 #if IN_LLVM |
149 { | 198 File* Module::buildFilePath(const char* forcename, const char* path, const char* ext) |
150 char *argobj; | 199 { |
200 const char *argobj; | |
151 if (forcename) | 201 if (forcename) |
152 argobj = forcename; | 202 argobj = forcename; |
153 else | 203 else |
154 { | 204 { |
155 if (preservePaths) | 205 if (preservePaths) |
158 argobj = FileName::name((char*)this->arg); | 208 argobj = FileName::name((char*)this->arg); |
159 | 209 |
160 if (fqnNames) | 210 if (fqnNames) |
161 { | 211 { |
162 if(md) | 212 if(md) |
163 argobj = FileName::replaceName(argobj, md->toChars()); | 213 argobj = FileName::replaceName((char*)argobj, md->toChars()); |
164 else | 214 else |
165 argobj = FileName::replaceName(argobj, toChars()); | 215 argobj = FileName::replaceName((char*)argobj, toChars()); |
166 | 216 |
167 // add ext, otherwise forceExt will make nested.module into nested.bc | 217 // add ext, otherwise forceExt will make nested.module into nested.bc |
168 size_t len = strlen(argobj); | 218 size_t len = strlen(argobj); |
169 size_t extlen = strlen(ext); | 219 size_t extlen = strlen(ext); |
170 char* s = (char *)alloca(len + 1 + extlen + 1); | 220 char* s = (char *)alloca(len + 1 + extlen + 1); |
189 // else | 239 // else |
190 // allow for .o and .obj on windows | 240 // allow for .o and .obj on windows |
191 #if _WIN32 | 241 #if _WIN32 |
192 if (ext == global.params.objdir && FileName::ext(argobj) | 242 if (ext == global.params.objdir && FileName::ext(argobj) |
193 && stricmp(FileName::ext(argobj), global.obj_ext_alt) == 0) | 243 && stricmp(FileName::ext(argobj), global.obj_ext_alt) == 0) |
194 return new File(argobj); | 244 return new File((char*)argobj); |
195 #endif | 245 #endif |
196 return new File(FileName::forceExt(argobj, ext)); | 246 return new File(FileName::forceExt(argobj, ext)); |
197 } | 247 } |
198 | 248 #endif |
249 #if IN_DMD | |
250 void Module::setDocfile() | |
251 { | |
252 FileName *docfilename; | |
253 char *argdoc; | |
254 | |
255 if (global.params.docname) | |
256 argdoc = global.params.docname; | |
257 else if (global.params.preservePaths) | |
258 argdoc = (char *)arg; | |
259 else | |
260 argdoc = FileName::name((char *)arg); | |
261 if (!FileName::absolute(argdoc)) | |
262 { //FileName::ensurePathExists(global.params.docdir); | |
263 argdoc = FileName::combine(global.params.docdir, argdoc); | |
264 } | |
265 if (global.params.docname) | |
266 docfilename = new FileName(argdoc, 0); | |
267 else | |
268 docfilename = FileName::forceExt(argdoc, global.doc_ext); | |
269 | |
270 if (docfilename->equals(srcfile->name)) | |
271 { error("Source file and documentation file have same name '%s'", srcfile->name->str); | |
272 fatal(); | |
273 } | |
274 | |
275 docfile = new File(docfilename); | |
276 } | |
277 | |
278 void Module::setHdrfile() | |
279 { | |
280 FileName *hdrfilename; | |
281 char *arghdr; | |
282 | |
283 if (global.params.hdrname) | |
284 arghdr = global.params.hdrname; | |
285 else if (global.params.preservePaths) | |
286 arghdr = (char *)arg; | |
287 else | |
288 arghdr = FileName::name((char *)arg); | |
289 if (!FileName::absolute(arghdr)) | |
290 { //FileName::ensurePathExists(global.params.hdrdir); | |
291 arghdr = FileName::combine(global.params.hdrdir, arghdr); | |
292 } | |
293 if (global.params.hdrname) | |
294 hdrfilename = new FileName(arghdr, 0); | |
295 else | |
296 hdrfilename = FileName::forceExt(arghdr, global.hdr_ext); | |
297 | |
298 if (hdrfilename->equals(srcfile->name)) | |
299 { error("Source file and 'header' file have same name '%s'", srcfile->name->str); | |
300 fatal(); | |
301 } | |
302 | |
303 hdrfile = new File(hdrfilename); | |
304 } | |
305 #endif | |
306 | |
307 #if IN_LLVM | |
199 void Module::buildTargetFiles() | 308 void Module::buildTargetFiles() |
200 { | 309 { |
201 if(objfile && | 310 if(objfile && |
202 (!doDocComment || docfile) && | 311 (!doDocComment || docfile) && |
203 (!doHdrGen || hdrfile)) | 312 (!doHdrGen || hdrfile)) |
225 { | 334 { |
226 error("Output header files with the same name as the source file are forbidden"); | 335 error("Output header files with the same name as the source file are forbidden"); |
227 fatal(); | 336 fatal(); |
228 } | 337 } |
229 } | 338 } |
230 | 339 #endif |
231 void Module::deleteObjFile() | 340 void Module::deleteObjFile() |
232 { | 341 { |
233 if (global.params.obj) | 342 if (global.params.obj) |
234 objfile->remove(); | 343 objfile->remove(); |
235 //if (global.params.llvmBC) | 344 //if (global.params.llvmBC) |
563 } | 672 } |
564 } | 673 } |
565 } | 674 } |
566 | 675 |
567 #ifdef IN_GCC | 676 #ifdef IN_GCC |
568 // dump utf-8 encoded source | 677 // dump utf-8 encoded source |
569 if (dump_source) | 678 if (dump_source) |
570 { // %% srcname could contain a path ... | 679 { // %% srcname could contain a path ... |
571 d_gcc_dump_source(srcname, "utf-8", buf, buflen); | 680 d_gcc_dump_source(srcname, "utf-8", buf, buflen); |
572 } | 681 } |
573 #endif | 682 #endif |
577 */ | 686 */ |
578 if (buflen >= 4 && memcmp(buf, "Ddoc", 4) == 0) | 687 if (buflen >= 4 && memcmp(buf, "Ddoc", 4) == 0) |
579 { | 688 { |
580 comment = buf + 4; | 689 comment = buf + 4; |
581 isDocFile = 1; | 690 isDocFile = 1; |
691 #if IN_DMD | |
692 if (!docfile) | |
693 setDocfile(); | |
694 #endif | |
582 return; | 695 return; |
583 } | 696 } |
584 if (isHtml) | 697 if (isHtml) |
585 { | 698 { |
586 OutBuffer *dbuf = new OutBuffer(); | 699 OutBuffer *dbuf = new OutBuffer(); |
900 //printf("\tdeferred.dim = %d, len = %d, dprogress = %d\n", deferred.dim, len, dprogress); | 1013 //printf("\tdeferred.dim = %d, len = %d, dprogress = %d\n", deferred.dim, len, dprogress); |
901 } while (deferred.dim < len || dprogress); // while making progress | 1014 } while (deferred.dim < len || dprogress); // while making progress |
902 nested--; | 1015 nested--; |
903 //printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim); | 1016 //printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim); |
904 } | 1017 } |
1018 | |
1019 /************************************ | |
1020 * Recursively look at every module this module imports, | |
1021 * return TRUE if it imports m. | |
1022 * Can be used to detect circular imports. | |
1023 */ | |
1024 | |
1025 int Module::imports(Module *m) | |
1026 { | |
1027 //printf("%s Module::imports(%s)\n", toChars(), m->toChars()); | |
1028 int aimports_dim = aimports.dim; | |
1029 #if 0 | |
1030 for (int i = 0; i < aimports.dim; i++) | |
1031 { Module *mi = (Module *)aimports.data[i]; | |
1032 printf("\t[%d] %s\n", i, mi->toChars()); | |
1033 } | |
1034 #endif | |
1035 for (int i = 0; i < aimports.dim; i++) | |
1036 { Module *mi = (Module *)aimports.data[i]; | |
1037 if (mi == m) | |
1038 return TRUE; | |
1039 if (!mi->insearch) | |
1040 { | |
1041 mi->insearch = 1; | |
1042 int r = mi->imports(m); | |
1043 if (r) | |
1044 return r; | |
1045 } | |
1046 } | |
1047 return FALSE; | |
1048 } | |
1049 | |
1050 /************************************* | |
1051 * Return !=0 if module imports itself. | |
1052 */ | |
1053 | |
1054 int Module::selfImports() | |
1055 { | |
1056 //printf("Module::selfImports() %s\n", toChars()); | |
1057 if (!selfimports) | |
1058 { | |
1059 for (int i = 0; i < amodules.dim; i++) | |
1060 { Module *mi = (Module *)amodules.data[i]; | |
1061 //printf("\t[%d] %s\n", i, mi->toChars()); | |
1062 mi->insearch = 0; | |
1063 } | |
1064 | |
1065 selfimports = imports(this) + 1; | |
1066 | |
1067 for (int i = 0; i < amodules.dim; i++) | |
1068 { Module *mi = (Module *)amodules.data[i]; | |
1069 //printf("\t[%d] %s\n", i, mi->toChars()); | |
1070 mi->insearch = 0; | |
1071 } | |
1072 } | |
1073 return selfimports - 1; | |
1074 } | |
1075 | |
905 | 1076 |
906 /* =========================== ModuleDeclaration ===================== */ | 1077 /* =========================== ModuleDeclaration ===================== */ |
907 | 1078 |
908 ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id, bool safe) | 1079 ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id, bool safe) |
909 { | 1080 { |