Allow returning something of type void in a function that returns void
[delight/core.git] / dmd2 / import.c
blob7d8d1f41b808db9a7998b992cd1ea56477343c3c
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2006 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.
11 #include <stdio.h>
12 #include <assert.h>
14 #include "root.h"
15 #include "dsymbol.h"
16 #include "import.h"
17 #include "identifier.h"
18 #include "module.h"
19 #include "scope.h"
20 #include "hdrgen.h"
21 #include "mtype.h"
22 #include "declaration.h"
23 #include "id.h"
25 /********************************* Import ****************************/
27 Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
28 int isstatic)
29 : Dsymbol(id)
31 this->loc = loc;
32 this->packages = packages;
33 this->id = id;
34 this->aliasId = aliasId;
35 this->isstatic = isstatic;
36 pkg = NULL;
37 mod = NULL;
39 if (aliasId)
40 this->ident = aliasId;
41 // Kludge to change Import identifier to first package
42 else if (packages && packages->dim)
43 this->ident = (Identifier *)packages->data[0];
46 void Import::addAlias(Identifier *name, Identifier *alias)
48 if (isstatic)
49 error("cannot have an import bind list");
51 if (!aliasId)
52 this->ident = NULL; // make it an anonymous import
54 names.push(name);
55 aliases.push(alias);
58 char *Import::kind()
60 return isstatic ? (char *)"static import" : (char *)"import";
63 enum PROT Import::prot()
65 return protection;
68 Dsymbol *Import::syntaxCopy(Dsymbol *s)
70 assert(!s);
72 Import *si;
74 si = new Import(loc, packages, id, aliasId, isstatic);
76 for (size_t i = 0; i < names.dim; i++)
78 si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]);
81 return si;
84 void Import::load(Scope *sc)
86 DsymbolTable *dst;
87 Dsymbol *s;
89 //printf("Import::load('%s')\n", toChars());
91 // See if existing module
92 dst = Package::resolve(packages, NULL, &pkg);
94 s = dst->lookup(id);
95 if (s)
97 if (s->isModule())
98 mod = (Module *)s;
99 else
100 error("package and module have the same name");
103 if (!mod)
105 // Load module
106 mod = Module::load(loc, packages, id);
107 dst->insert(id, mod); // id may be different from mod->ident,
108 // if so then insert alias
109 if (!mod->importedFrom)
110 mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
112 if (!pkg)
113 pkg = mod;
114 mod->semantic();
116 //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
120 void Import::semantic(Scope *sc)
122 //printf("Import::semantic('%s')\n", toChars());
124 load(sc);
126 /* Default to private importing
128 protection = sc->protection;
129 if (!sc->explicitProtection)
130 protection = PROTprivate;
132 if (mod)
134 #if 0
135 if (mod->loc.linnum != 0)
136 { /* If the line number is not 0, then this is not
137 * a 'root' module, i.e. it was not specified on the command line.
139 mod->importedFrom = sc->module->importedFrom;
140 assert(mod->importedFrom);
142 #endif
144 if (!isstatic && !aliasId && !names.dim)
146 sc->scopesym->importScope(mod, protection);
149 // Modules need a list of each imported module
150 sc->module->aimports.push(mod);
152 if (mod->needmoduleinfo)
153 sc->module->needmoduleinfo = 1;
155 sc = sc->push(mod);
156 for (size_t i = 0; i < aliasdecls.dim; i++)
157 { AliasDeclaration *ad = (AliasDeclaration *)aliasdecls.data[i];
159 //printf("\tImport alias semantic('%s')\n", s->toChars());
160 if (!mod->search(loc, (Identifier *)names.data[i], 0))
161 error("%s not found", ((Identifier *)names.data[i])->toChars());
163 ad->semantic(sc);
164 ad->protection = protection;
166 sc = sc->pop();
168 //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
171 void Import::semantic2(Scope *sc)
173 //printf("Import::semantic2('%s')\n", toChars());
174 mod->semantic2();
175 if (mod->needmoduleinfo)
176 sc->module->needmoduleinfo = 1;
179 Dsymbol *Import::toAlias()
181 if (aliasId)
182 return mod;
183 return this;
186 int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
188 int result = 0;
190 if (names.dim == 0)
191 return Dsymbol::addMember(sc, sd, memnum);
193 if (aliasId)
194 result = Dsymbol::addMember(sc, sd, memnum);
196 for (size_t i = 0; i < names.dim; i++)
198 Identifier *name = (Identifier *)names.data[i];
199 Identifier *alias = (Identifier *)aliases.data[i];
201 if (!alias)
202 alias = name;
204 #if 1
205 TypeIdentifier *tname = new TypeIdentifier(loc, name);
206 #else
207 TypeIdentifier *tname = new TypeIdentifier(loc, NULL);
208 if (packages)
210 for (size_t j = 0; j < packages->dim; j++)
211 { Identifier *pid = (Identifier *)packages->data[j];
213 if (!tname->ident)
214 tname->ident = pid;
215 else
216 tname->addIdent(pid);
219 if (!tname->ident)
220 tname->ident = id;
221 else
222 tname->addIdent(id);
223 tname->addIdent(name);
224 #endif
225 AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
226 result |= ad->addMember(sc, sd, memnum);
228 aliasdecls.push(ad);
231 return result;
234 Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
236 //printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
238 if (!pkg)
239 load(NULL);
241 // Forward it to the package/module
242 return pkg->search(loc, ident, flags);
245 int Import::overloadInsert(Dsymbol *s)
247 // Allow multiple imports of the same name
248 return s->isImport() != NULL;
251 void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
253 if (hgs->hdrgen && id == Id::object)
254 return; // object is imported by default
256 if (isstatic)
257 buf->writestring("static ");
258 buf->writestring("import ");
259 if (aliasId)
261 buf->printf("%s = ", aliasId->toChars());
263 if (packages && packages->dim)
265 for (size_t i = 0; i < packages->dim; i++)
266 { Identifier *pid = (Identifier *)packages->data[i];
268 buf->printf("%s.", pid->toChars());
271 buf->printf("%s;", id->toChars());
272 buf->writenl();