2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
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.
20 #include "gdc_alloca.h"
29 #include "identifier.h"
40 #include "d-dmd-gcc.h"
43 ClassDeclaration
*Module::moduleinfo
;
45 Module
*Module::rootModule
;
46 DsymbolTable
*Module::modules
;
47 Array
Module::amodules
;
49 Array
Module::deferred
; // deferred Dsymbol's needing semantic() run on them
50 unsigned Module::dprogress
;
54 modules
= new DsymbolTable();
57 Module::Module(char *filename
, Identifier
*ident
, int doDocComment
, int doHdrGen
, int isDltFile
)
58 : Package(ident
), isDltFile(isDltFile
)
60 FileName
*srcfilename
;
63 FileName
*objfilename
;
64 FileName
*symfilename
;
66 // printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars());
76 strictlyneedmoduleinfo
= 0;
79 searchCacheIdent
= NULL
;
80 searchCacheSymbol
= NULL
;
103 versionidsNot
= NULL
;
111 srcfilename
= FileName::defaultExt(filename
, global
.dlt_ext
);
112 if (!srcfilename
->equalsExt(global
.mars_ext
) &&
113 !srcfilename
->equalsExt(global
.dlt_ext
) &&
114 !srcfilename
->equalsExt("dd"))
116 if (srcfilename
->equalsExt("html") ||
117 srcfilename
->equalsExt("htm") ||
118 srcfilename
->equalsExt("xhtml"))
121 { error("source file name '%s' must have .%s extension", srcfilename
->toChars(), global
.dlt_ext
);
127 if (global
.params
.objname
)
128 argobj
= global
.params
.objname
;
129 else if (global
.params
.preservePaths
)
132 argobj
= FileName::name(filename
);
133 if (!FileName::absolute(argobj
))
135 argobj
= FileName::combine(global
.params
.objdir
, argobj
);
138 if (global
.params
.objname
)
139 objfilename
= new FileName(argobj
, 0);
141 objfilename
= FileName::forceExt(argobj
, global
.obj_ext
);
143 symfilename
= FileName::forceExt(filename
, global
.sym_ext
);
145 srcfile
= new File(srcfilename
);
157 objfile
= new File(objfilename
);
158 symfile
= new File(symfilename
);
161 void Module::setDocfile()
163 FileName
*docfilename
;
166 if (global
.params
.docname
)
167 argdoc
= global
.params
.docname
;
168 else if (global
.params
.preservePaths
)
169 argdoc
= (char *)arg
;
171 argdoc
= FileName::name((char *)arg
);
172 if (!FileName::absolute(argdoc
))
173 { //FileName::ensurePathExists(global.params.docdir);
174 argdoc
= FileName::combine(global
.params
.docdir
, argdoc
);
176 if (global
.params
.docname
)
177 docfilename
= new FileName(argdoc
, 0);
179 docfilename
= FileName::forceExt(argdoc
, global
.doc_ext
);
181 if (docfilename
->equals(srcfile
->name
))
182 { error("Source file and documentation file have same name '%s'", srcfile
->name
->str
);
186 docfile
= new File(docfilename
);
189 void Module::setHdrfile()
191 FileName
*hdrfilename
;
194 if (global
.params
.hdrname
)
195 arghdr
= global
.params
.hdrname
;
196 else if (global
.params
.preservePaths
)
197 arghdr
= (char *)arg
;
199 arghdr
= FileName::name((char *)arg
);
200 if (!FileName::absolute(arghdr
))
201 { //FileName::ensurePathExists(global.params.hdrdir);
202 arghdr
= FileName::combine(global
.params
.hdrdir
, arghdr
);
204 if (global
.params
.hdrname
)
205 hdrfilename
= new FileName(arghdr
, 0);
207 hdrfilename
= FileName::forceExt(arghdr
, global
.hdr_ext
);
209 if (hdrfilename
->equals(srcfile
->name
))
210 { error("Source file and 'header' file have same name '%s'", srcfile
->name
->str
);
214 hdrfile
= new File(hdrfilename
);
217 void Module::deleteObjFile()
219 if (global
.params
.obj
)
234 Module
*Module::load(Loc loc
, Array
*packages
, Identifier
*ident
)
237 bool dltSyntax
= false;
239 //printf("Module::load(ident = '%s')\n", ident->toChars());
241 // Build module filename by turning:
245 filename
= ident
->toChars();
246 if (packages
&& packages
->dim
)
251 for (i
= 0; i
< packages
->dim
; i
++)
252 { Identifier
*pid
= (Identifier
*)packages
->data
[i
];
254 buf
.writestring(pid
->toChars());
261 buf
.writestring(filename
);
263 filename
= (char *)buf
.extractData();
266 /* Search along global.path for a .dlt file, then a .di file, then a .d file.
269 FileName
*fdlt
= FileName::forceExt(filename
, global
.dlt_ext
);
270 FileName
*fdi
= FileName::forceExt(filename
, global
.hdr_ext
);
271 FileName
*fd
= FileName::forceExt(filename
, global
.mars_ext
);
272 char *sdlt
= fdlt
->toChars();
273 char *sdi
= fdi
->toChars();
274 char *sd
= fd
->toChars();
276 if (FileName::exists(sdlt
))
281 else if (FileName::exists(sdi
))
283 else if (FileName::exists(sd
))
285 else if (FileName::absolute(filename
))
287 else if (!global
.path
)
291 for (size_t i
= 0; i
< global
.path
->dim
; i
++)
293 char *p
= (char *)global
.path
->data
[i
];
296 n
= FileName::combine(p
, sdlt
);
297 if (FileName::exists(n
))
304 n
= FileName::combine(p
, sdi
);
305 if (FileName::exists(n
))
311 n
= FileName::combine(p
, sd
);
312 if (FileName::exists(n
))
320 m
= new Module(filename
, ident
, 0, 0, dltSyntax
);
324 m
->srcfile
= new File(result
);
326 if (global
.params
.verbose
)
331 for (size_t i
= 0; i
< packages
->dim
; i
++)
332 { Identifier
*pid
= (Identifier
*)packages
->data
[i
];
333 printf("%s.", pid
->toChars());
336 printf("%s\t(%s)\n", ident
->toChars(), m
->srcfile
->toChars());
343 d_gcc_magic_module(m
);
349 void Module::read(Loc loc
)
351 //printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars());
353 { error(loc
, "cannot read file '%s'", srcfile
->toChars());
358 inline unsigned readwordLE(unsigned short *p
)
363 return (((unsigned char *)p
)[1] << 8) | ((unsigned char *)p
)[0];
367 inline unsigned readwordBE(unsigned short *p
)
369 return (((unsigned char *)p
)[0] << 8) | ((unsigned char *)p
)[1];
372 inline unsigned readlongLE(unsigned *p
)
377 return ((unsigned char *)p
)[0] |
378 (((unsigned char *)p
)[1] << 8) |
379 (((unsigned char *)p
)[2] << 16) |
380 (((unsigned char *)p
)[3] << 24);
384 inline unsigned readlongBE(unsigned *p
)
386 return ((unsigned char *)p
)[3] |
387 (((unsigned char *)p
)[2] << 8) |
388 (((unsigned char *)p
)[1] << 16) |
389 (((unsigned char *)p
)[0] << 24);
393 void Module::parse(bool dump_source
)
403 //printf("Module::parse()\n");
405 srcname
= srcfile
->name
->toChars();
406 //printf("Module::parse(srcname = '%s')\n", srcname);
408 buf
= srcfile
->buffer
;
409 buflen
= srcfile
->len
;
413 /* Convert all non-UTF-8 formats to UTF-8.
414 * BOM : http://www.unicode.org/faq/utf_bom.html
415 * 00 00 FE FF UTF-32BE, big-endian
416 * FF FE 00 00 UTF-32LE, little-endian
417 * FE FF UTF-16BE, big-endian
418 * FF FE UTF-16LE, little-endian
422 bom
= 1; // assume there's a BOM
423 if (buf
[0] == 0xFF && buf
[1] == 0xFE)
425 if (buflen
>= 4 && buf
[2] == 0 && buf
[3] == 0)
431 unsigned *pu
= (unsigned *)(buf
);
432 unsigned *pumax
= &pu
[buflen
/ 4];
435 { error("odd length of UTF-32 char source %u", buflen
);
439 dbuf
.reserve(buflen
/ 4);
440 for (pu
+= bom
; pu
< pumax
; pu
++)
443 u
= le
? readlongLE(pu
) : readlongBE(pu
);
447 { error("UTF-32 value %08x greater than 0x10FFFF", u
);
455 dbuf
.writeByte(0); // add 0 as sentinel for scanner
456 buflen
= dbuf
.offset
- 1; // don't include sentinel in count
457 buf
= (unsigned char *) dbuf
.extractData();
461 // Convert it to UTF-8
466 unsigned short *pu
= (unsigned short *)(buf
);
467 unsigned short *pumax
= &pu
[buflen
/ 2];
470 { error("odd length of UTF-16 char source %u", buflen
);
474 dbuf
.reserve(buflen
/ 2);
475 for (pu
+= bom
; pu
< pumax
; pu
++)
478 u
= le
? readwordLE(pu
) : readwordBE(pu
);
480 { if (u
>= 0xD800 && u
<= 0xDBFF)
484 { error("surrogate UTF-16 high value %04x at EOF", u
);
487 u2
= le
? readwordLE(pu
) : readwordBE(pu
);
488 if (u2
< 0xDC00 || u2
> 0xDFFF)
489 { error("surrogate UTF-16 low value %04x out of range", u2
);
492 u
= (u
- 0xD7C0) << 10;
495 else if (u
>= 0xDC00 && u
<= 0xDFFF)
496 { error("unpaired surrogate UTF-16 value %04x", u
);
499 else if (u
== 0xFFFE || u
== 0xFFFF)
500 { error("illegal UTF-16 value %04x", u
);
508 dbuf
.writeByte(0); // add 0 as sentinel for scanner
509 buflen
= dbuf
.offset
- 1; // don't include sentinel in count
510 buf
= (unsigned char *) dbuf
.extractData();
513 else if (buf
[0] == 0xFE && buf
[1] == 0xFF)
518 else if (buflen
>= 4 && buf
[0] == 0 && buf
[1] == 0 && buf
[2] == 0xFE && buf
[3] == 0xFF)
523 else if (buflen
>= 3 && buf
[0] == 0xEF && buf
[1] == 0xBB && buf
[2] == 0xBF)
531 /* There is no BOM. Make use of Arcane Jill's insight that
532 * the first char of D source must be ASCII to
533 * figure out the encoding.
538 { if (buf
[1] == 0 && buf
[2] == 0 && buf
[3] == 0)
543 else if (buf
[0] == 0 && buf
[1] == 0 && buf
[2] == 0)
556 else if (buf
[0] == 0)
565 { error("source file must start with BOM or ASCII character, not \\x%02X", buf
[0]);
572 // dump utf-8 encoded source
574 { // %% srcname could contain a path ...
575 d_gcc_dump_source(srcname
, "utf-8", buf
, buflen
);
579 /* If it starts with the string "Ddoc", then it's a documentation
582 if (buflen
>= 4 && memcmp(buf
, "Ddoc", 4) == 0)
592 OutBuffer
*dbuf
= new OutBuffer();
593 Html
h(srcname
, buf
, buflen
);
596 buflen
= dbuf
->offset
;
598 // dump extracted source
600 d_gcc_dump_source(srcname
, "d.utf-8", buf
, buflen
);
606 DltParser
p(this, buf
, buflen
, docfile
!= NULL
);
608 members
= p
.parseModule();
610 numlines
= p
.loc
.linnum
;
614 Parser
p(this, buf
, buflen
, docfile
!= NULL
);
616 members
= p
.parseModule();
618 numlines
= p
.loc
.linnum
;
624 { this->ident
= md
->id
;
625 dst
= Package::resolve(md
->packages
, &this->parent
, NULL
);
631 /* Check to see if module name is a valid identifier
633 if (!Lexer::isValidIdentifier(this->ident
->toChars()))
634 error("has non-identifier characters in filename, use module declaration instead");
637 // Update global list of modules
638 if (!dst
->insert(this))
641 error(loc
, "is in multiple packages %s", md
->toChars());
643 error(loc
, "is in multiple defined");
651 FuncDeclaration
*addMainFunction(Dsymbol
*mainClass
) {
652 ClassDeclaration
*klass
= mainClass
->isClassDeclaration();
654 // Just ignore it then?
655 error("'Main' is not a class!");
658 // Create a main(string[] args) function
659 Arguments
*arguments
= new Arguments();
661 Type
*tstr
= new TypeDArray(Type::tchar
);
662 Type
*targv
= new TypeDArray(tstr
);
664 Argument
*a
= new Argument(STCin
, targv
, Id::args
, NULL
);
667 Loc loc
= mainClass
->loc
;
669 TypeFunction
*ta
= new TypeFunction(arguments
, new Type(Tvoid
, NULL
), 0, LINKc
);
670 FuncDeclaration
*f
= new FuncDeclaration(mainClass
->loc
, 0, Id::main
, STCundefined
, ta
);
672 // Find the constructor
673 CtorDeclaration
*ctor
= NULL
;
674 for (int i
= 0; i
< klass
->members
->dim
; i
++) {
677 s
= (Dsymbol
*)klass
->members
->data
[i
];
678 CtorDeclaration
*thisCtor
= s
->isCtorDeclaration();
681 error(thisCtor
->loc
, "Multiple constructors for Main class!");
689 Expressions
*args
= new Expressions();
692 f
->endloc
= klass
->loc
; // Use default constructor
694 f
->endloc
= ctor
->loc
;
696 Expressions
*builderArgs
= new Expressions();
697 Expression
*externals
= new IdentifierExp(ctor
->loc
, Id::_externals
);
698 // Collect all the objects we need for the constructor's arguments
699 for (int i
= 0; i
< ctor
->arguments
->dim
; i
++) {
700 Argument
*arg
= (Argument
*) ctor
->arguments
->data
[i
];
701 if (arg
->ident
== Id::args
) {
702 // For 'args', just pass through the string[] passed to main()
703 args
->push(new IdentifierExp(ctor
->loc
, arg
->ident
));
705 // For everything else, call a getter in the _externals module
706 Expression
*builder
= new DotIdExp(ctor
->loc
, externals
, arg
->ident
);
707 args
->push(new CallExp(ctor
->loc
, builder
, builderArgs
));
711 "Don't know how to provide a '%s' to the Main constructor",
712 arg->ident->toChars());
718 // Inside main(), create a new Main
720 NewExp
*e
= new NewExp(loc
, NULL
, NULL
, klass
->getType(), args
);
722 // Then invoke the main() method inside it
723 Expressions
*methodArgs
= new Expressions();
724 Expression
*mainMethod
= new DotIdExp(klass
->loc
, e
, Id::main
);
725 Expression
*mainCall
= new CallExp(klass
->loc
, mainMethod
, methodArgs
);
727 Statement
*s
= new ExpStatement(loc
, mainCall
);
733 void Module::semantic()
739 //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
742 // Note that modules get their own scope, from scratch.
743 // This is so regardless of where in the syntax a module
744 // gets imported, it is unaffected by context.
745 Scope
*sc
= Scope::createGlobal(this); // create root scope
747 //printf("Module = %p, linkage = %d\n", sc->scopesym, sc->linkage);
749 // Add import of "object" if this module isn't "object"
750 if (ident
!= Id::object
)
752 Import
*im
= new Import(0, NULL
, Id::object
, NULL
, 0);
758 /* va_list is a pain. If va_list involves a struct, add the
759 struct declaration to the "object" module. This depends on
760 the GCC backend not naming the struct something that will
761 cause a conflict or define "va_list" without going through
763 Type
* t
= d_gcc_builtin_va_list_d_type
;
765 if (t
->ty
== Tstruct
) {
766 StructDeclaration
* sd
= ((TypeStruct
*) t
)->sym
;
777 for (i
= 0; i
< members
->dim
; i
++)
780 s
= (Dsymbol
*)members
->data
[i
];
782 if (s
->ident
&& s
->ident
== Id::Main
) {
783 Dsymbol
*mainFn
= addMainFunction(s
);
786 members
->push(mainFn
);
788 Import
*im
= new Import(0, NULL
, Id::_externals
, NULL
, true);
794 // Add all symbols into module's symbol table
795 symtab
= new DsymbolTable();
796 for (i
= 0; i
< members
->dim
; i
++)
799 s
= (Dsymbol
*)members
->data
[i
];
800 s
->addMember(NULL
, sc
->scopesym
, 1);
803 // Pass 1 semantic routines: do public side of the definition
804 for (i
= 0; i
< members
->dim
; i
++)
807 s
= (Dsymbol
*)members
->data
[i
];
808 //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars());
810 runDeferredSemantic();
815 semanticdone
= semanticstarted
;
816 //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
819 void Module::semantic2()
824 for (int i
= 0; i
< deferred
.dim
; i
++)
826 Dsymbol
*sd
= (Dsymbol
*)deferred
.data
[i
];
828 sd
->error("unable to resolve forward reference in definition");
832 //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent);
833 if (semanticstarted
>= 2)
835 assert(semanticstarted
== 1);
838 // Note that modules get their own scope, from scratch.
839 // This is so regardless of where in the syntax a module
840 // gets imported, it is unaffected by context.
841 Scope
*sc
= Scope::createGlobal(this); // create root scope
842 //printf("Module = %p\n", sc.scopesym);
844 // Pass 2 semantic routines: do initializers and function bodies
845 for (i
= 0; i
< members
->dim
; i
++)
848 s
= (Dsymbol
*)members
->data
[i
];
854 semanticdone
= semanticstarted
;
855 //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent);
858 void Module::semantic3()
861 //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent);
862 if (semanticstarted
>= 3)
864 assert(semanticstarted
== 2);
867 // Note that modules get their own scope, from scratch.
868 // This is so regardless of where in the syntax a module
869 // gets imported, it is unaffected by context.
870 Scope
*sc
= Scope::createGlobal(this); // create root scope
871 //printf("Module = %p\n", sc.scopesym);
873 // Pass 3 semantic routines: do initializers and function bodies
874 for (i
= 0; i
< members
->dim
; i
++)
877 s
= (Dsymbol
*)members
->data
[i
];
878 //printf("Module %s: %s.semantic3()\n", toChars(), s->toChars());
884 semanticdone
= semanticstarted
;
887 void Module::inlineScan()
890 if (semanticstarted
>= 4)
892 assert(semanticstarted
== 3);
895 // Note that modules get their own scope, from scratch.
896 // This is so regardless of where in the syntax a module
897 // gets imported, it is unaffected by context.
898 //printf("Module = %p\n", sc.scopesym);
900 for (i
= 0; i
< members
->dim
; i
++)
903 s
= (Dsymbol
*)members
->data
[i
];
904 //if (global.params.verbose)
905 //printf("inline scan symbol %s\n", s->toChars());
909 semanticdone
= semanticstarted
;
912 /****************************************************
915 void Module::gensymfile()
920 //printf("Module::gensymfile()\n");
922 buf
.printf("// Sym file generated from '%s'", srcfile
->toChars());
925 for (int i
= 0; i
< members
->dim
; i
++)
926 { Dsymbol
*s
= (Dsymbol
*)members
->data
[i
];
928 s
->toCBuffer(&buf
, &hgs
);
931 // Transfer image to file
932 symfile
->setbuffer(buf
.data
, buf
.offset
);
938 /**********************************
939 * Determine if we need to generate an instance of ModuleInfo
943 int Module::needModuleInfo()
945 return needmoduleinfo
|| global
.params
.cov
;
948 Dsymbol
*Module::search(Loc loc
, Identifier
*ident
, int flags
)
950 /* Since modules can be circularly referenced,
951 * need to stop infinite recursive searches.
954 //printf("%s Module::search('%s', flags = %d) insearch = %d\n", toChars(), ident->toChars(), flags, insearch);
958 else if (searchCacheIdent
== ident
&& searchCacheFlags
== flags
)
959 s
= searchCacheSymbol
;
963 s
= ScopeDsymbol::search(loc
, ident
, flags
);
966 searchCacheIdent
= ident
;
967 searchCacheSymbol
= s
;
968 searchCacheFlags
= flags
;
973 /*******************************************
974 * Can't run semantic on s now, try again later.
977 void Module::addDeferredSemantic(Dsymbol
*s
)
979 // Don't add it if it is already there
980 for (int i
= 0; i
< deferred
.dim
; i
++)
982 Dsymbol
*sd
= (Dsymbol
*)deferred
.data
[i
];
988 //printf("Module::addDeferredSemantic('%s')\n", s->toChars());
993 /******************************************
994 * Run semantic() on deferred symbols.
997 void Module::runDeferredSemantic()
1004 //if (deferred.dim) printf("+Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim);
1022 todo
= (Dsymbol
**)alloca(len
* sizeof(Dsymbol
*));
1025 memcpy(todo
, deferred
.data
, len
* sizeof(Dsymbol
*));
1028 for (int i
= 0; i
< len
; i
++)
1030 Dsymbol
*s
= todo
[i
];
1033 //printf("deferred: %s, parent = %s\n", s->toChars(), s->parent->toChars());
1035 //printf("\tdeferred.dim = %d, len = %d, dprogress = %d\n", deferred.dim, len, dprogress);
1036 } while (deferred
.dim
< len
|| dprogress
); // while making progress
1038 //printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim);
1041 /* =========================== ModuleDeclaration ===================== */
1043 ModuleDeclaration::ModuleDeclaration(Array
*packages
, Identifier
*id
)
1045 this->packages
= packages
;
1049 char *ModuleDeclaration::toChars()
1054 if (packages
&& packages
->dim
)
1056 for (i
= 0; i
< packages
->dim
; i
++)
1057 { Identifier
*pid
= (Identifier
*)packages
->data
[i
];
1059 buf
.writestring(pid
->toChars());
1063 buf
.writestring(id
->toChars());
1065 return (char *)buf
.extractData();
1068 /* =========================== Package ===================== */
1070 Package::Package(Identifier
*ident
)
1071 : ScopeDsymbol(ident
)
1076 char *Package::kind()
1082 DsymbolTable
*Package::resolve(Array
*packages
, Dsymbol
**pparent
, Package
**ppkg
)
1084 DsymbolTable
*dst
= Module::modules
;
1085 Dsymbol
*parent
= NULL
;
1087 //printf("Package::resolve()\n");
1094 for (i
= 0; i
< packages
->dim
; i
++)
1095 { Identifier
*pid
= (Identifier
*)packages
->data
[i
];
1098 p
= dst
->lookup(pid
);
1101 p
= new Package(pid
);
1104 ((ScopeDsymbol
*)p
)->symtab
= new DsymbolTable();
1108 assert(p
->isPackage());
1110 { p
->error("module and package have the same name");
1116 dst
= ((Package
*)p
)->symtab
;
1118 *ppkg
= (Package
*)p
;