1:
2: // Compiler implementation of the D programming language
3: // Copyright (c) 1999-2011 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: static char __file__[] = __FILE__; /* for tassert.h */
14: #include "tassert.h"
15:
16: #if (defined (__SVR4) && defined (__sun))
17: #include <alloca.h>
18: #endif
19:
20: #if defined(_MSC_VER) || defined(__MINGW32__)
21: #include <malloc.h>
22: #endif
23:
24: #if IN_GCC
25: #include "gdc_alloca.h"
26: #endif
27:
28: #include "rmem.h"
29:
30: #include "mars.h"
31: #include "module.h"
32: #include "parse.h"
33: #include "scope.h"
34: #include "identifier.h"
35: #include "id.h"
36: #include "import.h"
37: #include "dsymbol.h"
38: #include "hdrgen.h"
39: #include "lexer.h"
40:
41: #define MARS 1
42: #include "html.h"
43:
44: #ifdef IN_GCC
45: #include "d-dmd-gcc.h"
46: #endif
47:
48: ClassDeclaration *Module::moduleinfo;
49:
50: Module *Module::rootModule;
51: DsymbolTable *Module::modules;
52: Modules Module::amodules;
53:
54: Dsymbols Module::deferred; // deferred Dsymbol's needing semantic() run on them
55: unsigned Module::dprogress;
56:
57: void Module::init()
58: {
59: modules = new DsymbolTable();
60: }
61:
62: Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen)
63: : Package(ident)
64: {
65: FileName *srcfilename;
66: FileName *cfilename;
warning C4101: 'cfilename' : unreferenced local variable
67: FileName *hfilename;
warning C4101: 'hfilename' : unreferenced local variable
68: FileName *objfilename;
69: FileName *symfilename;
70:
71: // printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars());
72: this->arg = filename;
73: md = NULL;
74: errors = 0;
75: numlines = 0;
76: members = NULL;
77: isHtml = 0;
78: isDocFile = 0;
79: needmoduleinfo = 0;
80: #ifdef IN_GCC
81: strictlyneedmoduleinfo = 0;
82: #endif
83: selfimports = 0;
84: insearch = 0;
85: searchCacheIdent = NULL;
86: searchCacheSymbol = NULL;
87: searchCacheFlags = 0;
88: semanticstarted = 0;
89: semanticRun = 0;
90: decldefs = NULL;
91: vmoduleinfo = NULL;
92: massert = NULL;
93: munittest = NULL;
94: marray = NULL;
95: sictor = NULL;
96: sctor = NULL;
97: sdtor = NULL;
98: ssharedctor = NULL;
99: sshareddtor = NULL;
100: stest = NULL;
101: sfilename = NULL;
102: root = 0;
103: importedFrom = NULL;
104: srcfile = NULL;
105: docfile = NULL;
106:
107: debuglevel = 0;
108: debugids = NULL;
109: debugidsNot = NULL;
110: versionlevel = 0;
111: versionids = NULL;
112: versionidsNot = NULL;
113:
114: macrotable = NULL;
115: escapetable = NULL;
116: safe = FALSE;
117: doppelganger = 0;
118: cov = NULL;
119: covb = NULL;
120:
121: nameoffset = 0;
122: namelen = 0;
123:
124: srcfilename = FileName::defaultExt(filename, global.mars_ext);
125: if (!srcfilename->equalsExt(global.mars_ext) &&
126: !srcfilename->equalsExt(global.hdr_ext) &&
127: !srcfilename->equalsExt("dd"))
128: {
129: if (srcfilename->equalsExt("html") ||
130: srcfilename->equalsExt("htm") ||
131: srcfilename->equalsExt("xhtml"))
132: { if (!global.params.useDeprecated)
133: error("html source files is deprecated %s", srcfilename->toChars());
134: isHtml = 1;
135: }
136: else
137: { error("source file name '%s' must have .%s extension", srcfilename->toChars(), global.mars_ext);
138: fatal();
139: }
140: }
141:
142: char *argobj;
143: if (global.params.objname)
144: argobj = global.params.objname;
145: #if 0
146: else if (global.params.preservePaths)
147: argobj = filename;
148: else
149: argobj = FileName::name(filename);
150: if (!FileName::absolute(argobj))
151: {
152: argobj = FileName::combine(global.params.objdir, argobj);
153: }
154: #else // Bugzilla 3547
155: else
156: {
157: if (global.params.preservePaths)
158: argobj = filename;
159: else
160: argobj = FileName::name(filename);
161: if (!FileName::absolute(argobj))
162: {
163: argobj = FileName::combine(global.params.objdir, argobj);
164: }
165: }
166: #endif
167:
168: if (global.params.objname)
169: objfilename = new FileName(argobj, 0);
warning C6211: Leaking memory 'objfilename' due to an exception. Consider using a local catch block to clean up memory: Lines: 63, 64, 65, 66, 67, 68, 69, 72, 73, 74, 75, 76, 77, 78, 79, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 121, 122,124, 126, 130, 137, 138, 142, 143, 144, 168, 169, 173, 175
170: else
171: objfilename = FileName::forceExt(argobj, global.obj_ext);
172:
173: symfilename = FileName::forceExt(filename, global.sym_ext);
174:
175: srcfile = new File(srcfilename);
176:
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: }
190:
191: void Module::setDocfile()
192: {
193: FileName *docfilename;
194: char *argdoc;
195:
196: if (global.params.docname)
197: argdoc = global.params.docname;
198: else if (global.params.preservePaths)
199: argdoc = (char *)arg;
200: else
201: argdoc = FileName::name((char *)arg);
202: if (!FileName::absolute(argdoc))
203: { //FileName::ensurePathExists(global.params.docdir);
204: argdoc = FileName::combine(global.params.docdir, argdoc);
205: }
206: if (global.params.docname)
207: docfilename = new FileName(argdoc, 0);
208: else
209: docfilename = FileName::forceExt(argdoc, global.doc_ext);
210:
211: if (docfilename->equals(srcfile->name))
212: { error("Source file and documentation file have same name '%s'", srcfile->name->str);
213: fatal();
214: }
215:
216: docfile = new File(docfilename);
217: }
218:
219: void Module::setHdrfile()
220: {
221: FileName *hdrfilename;
222: char *arghdr;
223:
224: if (global.params.hdrname)
225: arghdr = global.params.hdrname;
226: else if (global.params.preservePaths)
227: arghdr = (char *)arg;
228: else
229: arghdr = FileName::name((char *)arg);
230: if (!FileName::absolute(arghdr))
231: { //FileName::ensurePathExists(global.params.hdrdir);
232: arghdr = FileName::combine(global.params.hdrdir, arghdr);
233: }
234: if (global.params.hdrname)
235: hdrfilename = new FileName(arghdr, 0);
236: else
237: hdrfilename = FileName::forceExt(arghdr, global.hdr_ext);
238:
239: if (hdrfilename->equals(srcfile->name))
240: { error("Source file and 'header' file have same name '%s'", srcfile->name->str);
241: fatal();
242: }
243:
244: hdrfile = new File(hdrfilename);
245: }
246:
247: void Module::deleteObjFile()
248: {
249: if (global.params.obj)
250: objfile->remove();
251: if (docfile)
252: docfile->remove();
253: }
254:
255: Module::~Module()
256: {
257: }
258:
259: const char *Module::kind()
260: {
261: return "module";
262: }
263:
264: Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
265: { Module *m;
266: char *filename;
267:
268: //printf("Module::load(ident = '%s')\n", ident->toChars());
269:
270: // Build module filename by turning:
271: // foo.bar.baz
272: // into:
273: // foo\bar\baz
274: filename = ident->toChars();
275: if (packages && packages->dim)
276: {
277: OutBuffer buf;
278: int i;
279:
280: for (i = 0; i < packages->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
281: { Identifier *pid = packages->tdata()[i];
282:
283: buf.writestring(pid->toChars());
284: #if _WIN32
285: buf.writeByte('\\');
286: #else
287: buf.writeByte('/');
288: #endif
289: }
290: buf.writestring(filename);
291: buf.writeByte(0);
292: filename = (char *)buf.extractData();
293: }
294:
295: m = new Module(filename, ident, 0, 0);
warning C6211: Leaking memory 'm' due to an exception. Consider using a local catch block to clean up memory: Lines: 265, 266, 274, 275, 295, 296, 300, 301, 302, 303, 304, 306, 307, 333, 334
warning C6211: Leaking memory 'return value' due to an exception. Consider using a local catch block to clean up memory: Lines: 265, 266, 274, 275, 295, 296, 300, 301, 302, 303, 304, 306, 308, 309, 333, 334
296: m->loc = loc;
297:
298: /* Search along global.path for .di file, then .d file.
299: */
300: char *result = NULL;
301: FileName *fdi = FileName::forceExt(filename, global.hdr_ext);
302: FileName *fd = FileName::forceExt(filename, global.mars_ext);
303: char *sdi = fdi->toChars();
304: char *sd = fd->toChars();
305:
306: if (FileName::exists(sdi))
307: result = sdi;
308: else if (FileName::exists(sd))
309: result = sd;
310: else if (FileName::absolute(filename))
311: ;
312: else if (!global.path)
313: ;
314: else
315: {
316: for (size_t i = 0; i < global.path->dim; i++)
317: {
318: char *p = global.path->tdata()[i];
319: char *n = FileName::combine(p, sdi);
320: if (FileName::exists(n))
321: { result = n;
322: break;
323: }
324: mem.free(n);
325: n = FileName::combine(p, sd);
326: if (FileName::exists(n))
327: { result = n;
328: break;
329: }
330: mem.free(n);
331: }
332: }
333: if (result)
334: m->srcfile = new File(result);
335:
336: if (global.params.verbose)
337: {
338: printf("import ");
339: if (packages)
340: {
341: for (size_t i = 0; i < packages->dim; i++)
342: { Identifier *pid = packages->tdata()[i];
343: printf("%s.", pid->toChars());
344: }
345: }
346: printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
347: }
348:
349: m->read(loc);
350: m->parse();
351:
352: #ifdef IN_GCC
353: d_gcc_magic_module(m);
354: #endif
355:
356: return m;
357: }
358:
359: void Module::read(Loc loc)
360: {
361: //printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars());
362: if (srcfile->read())
363: { error(loc, "is in file '%s' which cannot be read", srcfile->toChars());
364: if (!global.gag)
365: { /* Print path
366: */
367: if (global.path)
368: {
369: for (int i = 0; i < global.path->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
370: {
371: char *p = global.path->tdata()[i];
372: fprintf(stdmsg, "import path[%d] = %s\n", i, p);
373: }
374: }
375: else
376: fprintf(stdmsg, "Specify path to file '%s' with -I switch\n", srcfile->toChars());
377: }
378: fatal();
379: }
380: }
381:
382: inline unsigned readwordLE(unsigned short *p)
383: {
384: #if LITTLE_ENDIAN
385: return *p;
386: #else
387: return (((unsigned char *)p)[1] << 8) | ((unsigned char *)p)[0];
388: #endif
389: }
390:
391: inline unsigned readwordBE(unsigned short *p)
392: {
393: return (((unsigned char *)p)[0] << 8) | ((unsigned char *)p)[1];
394: }
395:
396: inline unsigned readlongLE(unsigned *p)
397: {
398: #if LITTLE_ENDIAN
399: return *p;
400: #else
401: return ((unsigned char *)p)[0] |
402: (((unsigned char *)p)[1] << 8) |
403: (((unsigned char *)p)[2] << 16) |
404: (((unsigned char *)p)[3] << 24);
405: #endif
406: }
407:
408: inline unsigned readlongBE(unsigned *p)
409: {
410: return ((unsigned char *)p)[3] |
411: (((unsigned char *)p)[2] << 8) |
412: (((unsigned char *)p)[1] << 16) |
413: (((unsigned char *)p)[0] << 24);
414: }
415:
416: #if IN_GCC
417: void Module::parse(bool dump_source)
418: #else
419: void Module::parse()
420: #endif
421: { char *srcname;
422: unsigned char *buf;
423: unsigned buflen;
424: unsigned le;
425: unsigned bom;
426:
427: //printf("Module::parse()\n");
428:
429: srcname = srcfile->name->toChars();
430: //printf("Module::parse(srcname = '%s')\n", srcname);
431:
432: buf = srcfile->buffer;
433: buflen = srcfile->len;
434:
435: if (buflen >= 2)
436: {
437: /* Convert all non-UTF-8 formats to UTF-8.
438: * BOM : http://www.unicode.org/faq/utf_bom.html
439: * 00 00 FE FF UTF-32BE, big-endian
440: * FF FE 00 00 UTF-32LE, little-endian
441: * FE FF UTF-16BE, big-endian
442: * FF FE UTF-16LE, little-endian
443: * EF BB BF UTF-8
444: */
445:
446: bom = 1; // assume there's a BOM
447: if (buf[0] == 0xFF && buf[1] == 0xFE)
448: {
449: if (buflen >= 4 && buf[2] == 0 && buf[3] == 0)
450: { // UTF-32LE
451: le = 1;
452:
453: Lutf32:
454: OutBuffer dbuf;
455: unsigned *pu = (unsigned *)(buf);
456: unsigned *pumax = &pu[buflen / 4];
457:
458: if (buflen & 3)
459: { error("odd length of UTF-32 char source %u", buflen);
460: fatal();
461: }
462:
463: dbuf.reserve(buflen / 4);
464: for (pu += bom; pu < pumax; pu++)
465: { unsigned u;
466:
467: u = le ? readlongLE(pu) : readlongBE(pu);
468: if (u & ~0x7F)
469: {
470: if (u > 0x10FFFF)
471: { error("UTF-32 value %08x greater than 0x10FFFF", u);
472: fatal();
473: }
474: dbuf.writeUTF8(u);
475: }
476: else
477: dbuf.writeByte(u);
478: }
479: dbuf.writeByte(0); // add 0 as sentinel for scanner
480: buflen = dbuf.offset - 1; // don't include sentinel in count
481: buf = (unsigned char *) dbuf.extractData();
482: }
483: else
484: { // UTF-16LE (X86)
485: // Convert it to UTF-8
486: le = 1;
487:
488: Lutf16:
489: OutBuffer dbuf;
490: unsigned short *pu = (unsigned short *)(buf);
491: unsigned short *pumax = &pu[buflen / 2];
492:
493: if (buflen & 1)
494: { error("odd length of UTF-16 char source %u", buflen);
495: fatal();
496: }
497:
498: dbuf.reserve(buflen / 2);
499: for (pu += bom; pu < pumax; pu++)
500: { unsigned u;
501:
502: u = le ? readwordLE(pu) : readwordBE(pu);
503: if (u & ~0x7F)
504: { if (u >= 0xD800 && u <= 0xDBFF)
505: { unsigned u2;
506:
507: if (++pu > pumax)
508: { error("surrogate UTF-16 high value %04x at EOF", u);
509: fatal();
510: }
511: u2 = le ? readwordLE(pu) : readwordBE(pu);
512: if (u2 < 0xDC00 || u2 > 0xDFFF)
513: { error("surrogate UTF-16 low value %04x out of range", u2);
514: fatal();
515: }
516: u = (u - 0xD7C0) << 10;
517: u |= (u2 - 0xDC00);
518: }
519: else if (u >= 0xDC00 && u <= 0xDFFF)
520: { error("unpaired surrogate UTF-16 value %04x", u);
521: fatal();
522: }
523: else if (u == 0xFFFE || u == 0xFFFF)
524: { error("illegal UTF-16 value %04x", u);
525: fatal();
526: }
527: dbuf.writeUTF8(u);
528: }
529: else
530: dbuf.writeByte(u);
531: }
532: dbuf.writeByte(0); // add 0 as sentinel for scanner
533: buflen = dbuf.offset - 1; // don't include sentinel in count
534: buf = (unsigned char *) dbuf.extractData();
535: }
536: }
537: else if (buf[0] == 0xFE && buf[1] == 0xFF)
538: { // UTF-16BE
539: le = 0;
540: goto Lutf16;
541: }
542: else if (buflen >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF)
543: { // UTF-32BE
544: le = 0;
545: goto Lutf32;
546: }
547: else if (buflen >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)
548: { // UTF-8
549:
550: buf += 3;
551: buflen -= 3;
552: }
553: else
554: {
555: /* There is no BOM. Make use of Arcane Jill's insight that
556: * the first char of D source must be ASCII to
557: * figure out the encoding.
558: */
559:
560: bom = 0;
561: if (buflen >= 4)
562: { if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0)
563: { // UTF-32LE
564: le = 1;
565: goto Lutf32;
566: }
567: else if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0)
568: { // UTF-32BE
569: le = 0;
570: goto Lutf32;
571: }
572: }
573: if (buflen >= 2)
574: {
575: if (buf[1] == 0)
576: { // UTF-16LE
577: le = 1;
578: goto Lutf16;
579: }
580: else if (buf[0] == 0)
581: { // UTF-16BE
582: le = 0;
583: goto Lutf16;
584: }
585: }
586:
587: // It's UTF-8
588: if (buf[0] >= 0x80)
589: { error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]);
590: fatal();
591: }
592: }
593: }
594:
595: #ifdef IN_GCC
596: // dump utf-8 encoded source
597: if (dump_source)
598: { // %% srcname could contain a path ...
599: d_gcc_dump_source(srcname, "utf-8", buf, buflen);
600: }
601: #endif
602:
603: /* If it starts with the string "Ddoc", then it's a documentation
604: * source file.
605: */
606: if (buflen >= 4 && memcmp(buf, "Ddoc", 4) == 0)
607: {
608: comment = buf + 4;
609: isDocFile = 1;
610: if (!docfile)
611: setDocfile();
612: return;
613: }
614: if (isHtml)
615: {
616: OutBuffer *dbuf = new OutBuffer();
617: Html h(srcname, buf, buflen);
618: h.extractCode(dbuf);
619: buf = dbuf->data;
620: buflen = dbuf->offset;
621: #ifdef IN_GCC
622: // dump extracted source
623: if (dump_source)
624: d_gcc_dump_source(srcname, "d.utf-8", buf, buflen);
625: #endif
626: }
627: Parser p(this, buf, buflen, docfile != NULL);
628: p.nextToken();
629: members = p.parseModule();
630: md = p.md;
631: numlines = p.loc.linnum;
632:
633: DsymbolTable *dst;
634:
635: if (md)
636: { this->ident = md->id;
637: this->safe = md->safe;
638: dst = Package::resolve(md->packages, &this->parent, NULL);
639: }
640: else
641: {
642: dst = modules;
643:
644: /* Check to see if module name is a valid identifier
645: */
646: if (!Lexer::isValidIdentifier(this->ident->toChars()))
647: error("has non-identifier characters in filename, use module declaration instead");
648: }
649:
650: // Update global list of modules
651: if (!dst->insert(this))
652: {
653: Dsymbol *prev = dst->lookup(ident);
654: assert(prev);
655: Module *mprev = prev->isModule();
656: if (mprev)
657: error(loc, "from file %s conflicts with another module %s from file %s",
658: srcname, mprev->toChars(), mprev->srcfile->toChars());
659: else
660: {
661: Package *pkg = prev->isPackage();
662: assert(pkg);
663: error(loc, "from file %s conflicts with package name %s",
664: srcname, pkg->toChars());
665: }
666: }
667: else
668: {
669: amodules.push(this);
670: }
671: }
672:
673: void Module::importAll(Scope *prevsc)
674: {
675: //printf("+Module::importAll(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
676:
677: if (scope)
678: return; // already done
679:
680: /* Note that modules get their own scope, from scratch.
681: * This is so regardless of where in the syntax a module
682: * gets imported, it is unaffected by context.
683: * Ignore prevsc.
684: */
685: Scope *sc = Scope::createGlobal(this); // create root scope
686:
687: // Add import of "object" if this module isn't "object"
688: if (ident != Id::object)
689: {
690: if (members->dim == 0 || members->tdata()[0]->ident != Id::object)
691: {
692: Import *im = new Import(0, NULL, Id::object, NULL, 0);
693: members->shift(im);
694: }
695: }
696:
697: if (!symtab)
698: {
699: // Add all symbols into module's symbol table
700: symtab = new DsymbolTable();
701: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
702: {
703: Dsymbol *s = members->tdata()[i];
704: s->addMember(NULL, sc->scopesym, 1);
705: }
706: }
707: // anything else should be run after addMember, so version/debug symbols are defined
708:
709: /* Set scope for the symbols so that if we forward reference
710: * a symbol, it can possibly be resolved on the spot.
711: * If this works out well, it can be extended to all modules
712: * before any semantic() on any of them.
713: */
714: setScope(sc); // remember module scope for semantic
715: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
716: { Dsymbol *s = members->tdata()[i];
717: s->setScope(sc);
718: }
719:
720: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
721: {
722: Dsymbol *s = members->tdata()[i];
723: s->importAll(sc);
724: }
725:
726: sc = sc->pop();
727: sc->pop(); // 2 pops because Scope::createGlobal() created 2
728: }
729:
730: void Module::semantic()
731: {
732: if (semanticstarted)
733: return;
734:
735: //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
736: semanticstarted = 1;
737:
738: // Note that modules get their own scope, from scratch.
739: // This is so regardless of where in the syntax a module
740: // gets imported, it is unaffected by context.
741: Scope *sc = scope; // see if already got one from importAll()
742: if (!sc)
743: { printf("test2\n");
744: Scope::createGlobal(this); // create root scope
745: }
746:
747: //printf("Module = %p, linkage = %d\n", sc->scopesym, sc->linkage);
748:
749: #if 0
750: // Add import of "object" if this module isn't "object"
751: if (ident != Id::object)
752: {
753: Import *im = new Import(0, NULL, Id::object, NULL, 0);
754: members->shift(im);
755: }
756:
757: // Add all symbols into module's symbol table
758: symtab = new DsymbolTable();
759: for (int i = 0; i < members->dim; i++)
760: { Dsymbol *s = (Dsymbol *)members->data[i];
761: s->addMember(NULL, sc->scopesym, 1);
762: }
763:
764: /* Set scope for the symbols so that if we forward reference
765: * a symbol, it can possibly be resolved on the spot.
766: * If this works out well, it can be extended to all modules
767: * before any semantic() on any of them.
768: */
769: for (int i = 0; i < members->dim; i++)
770: { Dsymbol *s = (Dsymbol *)members->data[i];
771: s->setScope(sc);
772: }
773: #endif
774:
775: // Do semantic() on members that don't depend on others
776: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
777: { Dsymbol *s = members->tdata()[i];
778:
779: //printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars());
780: s->semantic0(sc);
781: }
782:
783: // Pass 1 semantic routines: do public side of the definition
784: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
785: { Dsymbol *s = members->tdata()[i];
786:
787: //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars());
788: s->semantic(sc);
789: runDeferredSemantic();
790: }
791:
792: if (!scope)
793: { sc = sc->pop();
warning C6011: Dereferencing NULL pointer 'sc': Lines: 732, 736, 741, 742, 743, 744, 776, 784, 792, 793
794: sc->pop(); // 2 pops because Scope::createGlobal() created 2
795: }
796: semanticRun = semanticstarted;
797: //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
798: }
799:
800: void Module::semantic2()
801: { int i;
802:
803: if (deferred.dim)
804: {
805: for (int i = 0; i < deferred.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
warning C6246: Local declaration of 'i' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '801' of 'c:\projects\extern\d\dmd\src\module.c': Lines: 801
806: {
807: Dsymbol *sd = deferred.tdata()[i];
808:
809: sd->error("unable to resolve forward reference in definition");
810: }
811: return;
812: }
813: //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent);
814: if (semanticstarted >= 2)
815: return;
816: assert(semanticstarted == 1);
817: semanticstarted = 2;
818:
819: // Note that modules get their own scope, from scratch.
820: // This is so regardless of where in the syntax a module
821: // gets imported, it is unaffected by context.
822: Scope *sc = Scope::createGlobal(this); // create root scope
823: //printf("Module = %p\n", sc.scopesym);
824:
825: // Pass 2 semantic routines: do initializers and function bodies
826: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
827: { Dsymbol *s;
828:
829: s = members->tdata()[i];
830: s->semantic2(sc);
831: }
832:
833: sc = sc->pop();
834: sc->pop();
835: semanticRun = semanticstarted;
836: //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent);
837: }
838:
839: void Module::semantic3()
840: { int i;
841:
842: //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent);
843: if (semanticstarted >= 3)
844: return;
845: assert(semanticstarted == 2);
846: semanticstarted = 3;
847:
848: // Note that modules get their own scope, from scratch.
849: // This is so regardless of where in the syntax a module
850: // gets imported, it is unaffected by context.
851: Scope *sc = Scope::createGlobal(this); // create root scope
852: //printf("Module = %p\n", sc.scopesym);
853:
854: // Pass 3 semantic routines: do initializers and function bodies
855: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
856: { Dsymbol *s;
857:
858: s = members->tdata()[i];
859: //printf("Module %s: %s.semantic3()\n", toChars(), s->toChars());
860: s->semantic3(sc);
861: }
862:
863: sc = sc->pop();
864: sc->pop();
865: semanticRun = semanticstarted;
866: }
867:
868: void Module::inlineScan()
869: {
870: if (semanticstarted >= 4)
871: return;
872: assert(semanticstarted == 3);
873: semanticstarted = 4;
874:
875: // Note that modules get their own scope, from scratch.
876: // This is so regardless of where in the syntax a module
877: // gets imported, it is unaffected by context.
878: //printf("Module = %p\n", sc.scopesym);
879:
880: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
881: { Dsymbol *s = members->tdata()[i];
882: //if (global.params.verbose)
883: //printf("inline scan symbol %s\n", s->toChars());
884:
885: s->inlineScan();
886: }
887: semanticRun = semanticstarted;
888: }
889:
890: /****************************************************
891: */
892:
893: void Module::gensymfile()
894: {
895: OutBuffer buf;
896: HdrGenState hgs;
897:
898: //printf("Module::gensymfile()\n");
899:
900: buf.printf("// Sym file generated from '%s'", srcfile->toChars());
901: buf.writenl();
902:
903: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
904: { Dsymbol *s = members->tdata()[i];
905:
906: s->toCBuffer(&buf, &hgs);
907: }
908:
909: // Transfer image to file
910: symfile->setbuffer(buf.data, buf.offset);
911: buf.data = NULL;
912:
913: symfile->writev();
914: }
915:
916: /**********************************
917: * Determine if we need to generate an instance of ModuleInfo
918: * for this Module.
919: */
920:
921: int Module::needModuleInfo()
922: {
923: //printf("needModuleInfo() %s, %d, %d\n", toChars(), needmoduleinfo, global.params.cov);
924: return needmoduleinfo || global.params.cov;
925: }
926:
927: Dsymbol *Module::search(Loc loc, Identifier *ident, int flags)
928: {
929: /* Since modules can be circularly referenced,
930: * need to stop infinite recursive searches.
931: * This is done with the cache.
932: */
933:
934: //printf("%s Module::search('%s', flags = %d) insearch = %d\n", toChars(), ident->toChars(), flags, insearch);
935: Dsymbol *s;
936: if (insearch)
937: s = NULL;
938: else if (searchCacheIdent == ident && searchCacheFlags == flags)
939: {
940: s = searchCacheSymbol;
941: //printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", toChars(), ident->toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol->toChars() : "null");
942: }
943: else
944: {
945: insearch = 1;
946: s = ScopeDsymbol::search(loc, ident, flags);
947: insearch = 0;
948:
949: searchCacheIdent = ident;
950: searchCacheSymbol = s;
951: searchCacheFlags = flags;
952: }
953: return s;
954: }
955:
956: Dsymbol *Module::symtabInsert(Dsymbol *s)
957: {
958: searchCacheIdent = 0; // symbol is inserted, so invalidate cache
959: return Package::symtabInsert(s);
960: }
961:
962: void Module::clearCache()
963: {
964: for (int i = 0; i < amodules.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
965: { Module *m = amodules.tdata()[i];
966: m->searchCacheIdent = NULL;
967: }
968: }
969:
970: /*******************************************
971: * Can't run semantic on s now, try again later.
972: */
973:
974: void Module::addDeferredSemantic(Dsymbol *s)
975: {
976: // Don't add it if it is already there
977: for (int i = 0; i < deferred.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
978: {
979: Dsymbol *sd = deferred.tdata()[i];
980:
981: if (sd == s)
982: return;
983: }
984:
985: //printf("Module::addDeferredSemantic('%s')\n", s->toChars());
986: deferred.push(s);
987: }
988:
989:
990: /******************************************
991: * Run semantic() on deferred symbols.
992: */
993:
994: void Module::runDeferredSemantic()
995: {
996: if (dprogress == 0)
997: return;
998:
999: static int nested;
1000: if (nested)
1001: return;
1002: //if (deferred.dim) printf("+Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim);
1003: nested++;
1004:
1005: size_t len;
1006: do
1007: {
1008: dprogress = 0;
1009: len = deferred.dim;
1010: if (!len)
1011: break;
1012:
1013: Dsymbol **todo;
1014: Dsymbol *tmp;
1015: if (len == 1)
1016: {
1017: todo = &tmp;
1018: }
1019: else
1020: {
1021: todo = (Dsymbol **)alloca(len * sizeof(Dsymbol *));
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
warning C6263: Using _alloca in a loop: this can quickly overflow stack: Lines: 1006
1022: assert(todo);
1023: }
1024: memcpy(todo, deferred.tdata(), len * sizeof(Dsymbol *));
1025: deferred.setDim(0);
1026:
1027: for (int i = 0; i < len; i++)
warning C4018: '<' : signed/unsigned mismatch
1028: {
1029: Dsymbol *s = todo[i];
1030:
1031: s->semantic(NULL);
1032: //printf("deferred: %s, parent = %s\n", s->toChars(), s->parent->toChars());
1033: }
1034: //printf("\tdeferred.dim = %d, len = %d, dprogress = %d\n", deferred.dim, len, dprogress);
1035: } while (deferred.dim < len || dprogress); // while making progress
1036: nested--;
1037: //printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim);
1038: }
1039:
1040: /************************************
1041: * Recursively look at every module this module imports,
1042: * return TRUE if it imports m.
1043: * Can be used to detect circular imports.
1044: */
1045:
1046: int Module::imports(Module *m)
1047: {
1048: //printf("%s Module::imports(%s)\n", toChars(), m->toChars());
1049: int aimports_dim = aimports.dim;
1050: #if 0
1051: for (int i = 0; i < aimports.dim; i++)
1052: { Module *mi = (Module *)aimports.data[i];
1053: printf("\t[%d] %s\n", i, mi->toChars());
1054: }
1055: #endif
1056: for (int i = 0; i < aimports.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1057: { Module *mi = aimports.tdata()[i];
1058: if (mi == m)
1059: return TRUE;
1060: if (!mi->insearch)
1061: {
1062: mi->insearch = 1;
1063: int r = mi->imports(m);
1064: if (r)
1065: return r;
1066: }
1067: }
1068: return FALSE;
1069: }
1070:
1071: /*************************************
1072: * Return !=0 if module imports itself.
1073: */
1074:
1075: int Module::selfImports()
1076: {
1077: //printf("Module::selfImports() %s\n", toChars());
1078: if (!selfimports)
1079: {
1080: for (int i = 0; i < amodules.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1081: { Module *mi = amodules.tdata()[i];
1082: //printf("\t[%d] %s\n", i, mi->toChars());
1083: mi->insearch = 0;
1084: }
1085:
1086: selfimports = imports(this) + 1;
1087:
1088: for (int i = 0; i < amodules.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1089: { Module *mi = amodules.tdata()[i];
1090: //printf("\t[%d] %s\n", i, mi->toChars());
1091: mi->insearch = 0;
1092: }
1093: }
1094: return selfimports - 1;
1095: }
1096:
1097:
1098: /* =========================== ModuleDeclaration ===================== */
1099:
1100: ModuleDeclaration::ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe)
1101: {
1102: this->packages = packages;
1103: this->id = id;
1104: this->safe = safe;
1105: }
1106:
1107: char *ModuleDeclaration::toChars()
1108: {
1109: OutBuffer buf;
1110: int i;
1111:
1112: if (packages && packages->dim)
1113: {
1114: for (i = 0; i < packages->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1115: { Identifier *pid = packages->tdata()[i];
1116:
1117: buf.writestring(pid->toChars());
1118: buf.writeByte('.');
1119: }
1120: }
1121: buf.writestring(id->toChars());
1122: buf.writeByte(0);
1123: return (char *)buf.extractData();
1124: }
1125:
1126: /* =========================== Package ===================== */
1127:
1128: Package::Package(Identifier *ident)
1129: : ScopeDsymbol(ident)
1130: {
1131: }
1132:
1133:
1134: const char *Package::kind()
1135: {
1136: return "package";
1137: }
1138:
1139:
1140: DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg)
1141: {
1142: DsymbolTable *dst = Module::modules;
1143: Dsymbol *parent = NULL;
1144:
1145: //printf("Package::resolve()\n");
1146: if (ppkg)
1147: *ppkg = NULL;
1148:
1149: if (packages)
1150: { int i;
1151:
1152: for (i = 0; i < packages->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1153: { Identifier *pid = packages->tdata()[i];
1154: Dsymbol *p;
1155:
1156: p = dst->lookup(pid);
1157: if (!p)
1158: {
1159: p = new Package(pid);
1160: dst->insert(p);
1161: p->parent = parent;
1162: ((ScopeDsymbol *)p)->symtab = new DsymbolTable();
1163: }
1164: else
1165: {
1166: assert(p->isPackage());
1167: #if TARGET_NET //dot net needs modules and packages with same name
1168: #else
1169: if (p->isModule())
1170: { p->error("module and package have the same name");
1171: fatal();
1172: break;
1173: }
1174: #endif
1175: }
1176: parent = p;
1177: dst = ((Package *)p)->symtab;
1178: if (ppkg && !*ppkg)
1179: *ppkg = (Package *)p;
1180: }
1181: if (pparent)
1182: {
1183: *pparent = parent;
1184: }
1185: }
1186: return dst;
1187: }
1188: