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 {