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: