1
2 // Compiler implementation of the D programming language
3 // Copyright: Copyright (C) 2014-2019 by The D Language Foundation, All Rights Reserved
4 // Authors: Walter Bright, http://www.digitalmars.com
5 // License: http://boost.org/LICENSE_1_0.txt
6 // Source: https://github.com/D-Programming-Language/dmd/blob/master/src/nspace.c
7
8
9 #include "root/dsystem.h"
10
11 #include "mars.h"
12 #include "dsymbol.h"
13 #include "nspace.h"
14 #include "identifier.h"
15 #include "scope.h"
16
17 /* This implements namespaces.
18 */
19
Nspace(Loc loc,Identifier * ident,Dsymbols * members,bool mangleOnly)20 Nspace::Nspace(Loc loc, Identifier *ident, Dsymbols *members, bool mangleOnly)
21 : ScopeDsymbol(ident)
22 {
23 //printf("Nspace::Nspace(ident = %s)\n", ident->toChars());
24 this->loc = loc;
25 this->members = members;
26 // Determines whether the symbol for this namespace should be included in
27 // the symbol table.
28 this->mangleOnly = mangleOnly;
29 }
30
syntaxCopy(Dsymbol *)31 Dsymbol *Nspace::syntaxCopy(Dsymbol *)
32 {
33 Nspace *ns = new Nspace(loc, ident, NULL, mangleOnly);
34 return ScopeDsymbol::syntaxCopy(ns);
35 }
36
addMember(Scope * sc,ScopeDsymbol * sds)37 void Nspace::addMember(Scope *sc, ScopeDsymbol *sds)
38 {
39 if (mangleOnly)
40 parent = sds;
41 else
42 ScopeDsymbol::addMember(sc, sds);
43 if (members)
44 {
45 if (!symtab)
46 symtab = new DsymbolTable();
47 // The namespace becomes 'imported' into the enclosing scope
48 for (Scope *sce = sc; 1; sce = sce->enclosing)
49 {
50 ScopeDsymbol *sds2 = sce->scopesym;
51 if (sds2)
52 {
53 sds2->importScope(this, Prot(PROTpublic));
54 break;
55 }
56 }
57 assert(sc);
58 sc = sc->push(this);
59 sc->linkage = LINKcpp; // namespaces default to C++ linkage
60 sc->parent = this;
61 for (size_t i = 0; i < members->dim; i++)
62 {
63 Dsymbol *s = (*members)[i];
64 //printf("add %s to scope %s\n", s->toChars(), toChars());
65 s->addMember(sc, this);
66 }
67 sc->pop();
68 }
69 }
70
setScope(Scope * sc)71 void Nspace::setScope(Scope *sc)
72 {
73 ScopeDsymbol::setScope(sc);
74 if (members)
75 {
76 assert(sc);
77 sc = sc->push(this);
78 sc->linkage = LINKcpp; // namespaces default to C++ linkage
79 sc->parent = this;
80 for (size_t i = 0; i < members->dim; i++)
81 {
82 Dsymbol *s = (*members)[i];
83 s->setScope(sc);
84 }
85 sc->pop();
86 }
87 }
88
semantic(Scope * sc)89 void Nspace::semantic(Scope *sc)
90 {
91 if (semanticRun != PASSinit)
92 return;
93 if (_scope)
94 {
95 sc = _scope;
96 _scope = NULL;
97 }
98 if (!sc)
99 return;
100
101 semanticRun = PASSsemantic;
102 parent = sc->parent;
103 if (members)
104 {
105 assert(sc);
106 sc = sc->push(this);
107 sc->linkage = LINKcpp; // note that namespaces imply C++ linkage
108 sc->parent = this;
109
110 for (size_t i = 0; i < members->dim; i++)
111 {
112 Dsymbol *s = (*members)[i];
113 s->importAll(sc);
114 }
115
116 for (size_t i = 0; i < members->dim; i++)
117 {
118 Dsymbol *s = (*members)[i];
119 s->semantic(sc);
120 }
121 sc->pop();
122 }
123 semanticRun = PASSsemanticdone;
124 }
125
semantic2(Scope * sc)126 void Nspace::semantic2(Scope *sc)
127 {
128 if (semanticRun >= PASSsemantic2)
129 return;
130 semanticRun = PASSsemantic2;
131 if (members)
132 {
133 assert(sc);
134 sc = sc->push(this);
135 sc->linkage = LINKcpp;
136 for (size_t i = 0; i < members->dim; i++)
137 {
138 Dsymbol *s = (*members)[i];
139 s->semantic2(sc);
140 }
141 sc->pop();
142 }
143 }
144
semantic3(Scope * sc)145 void Nspace::semantic3(Scope *sc)
146 {
147 if (semanticRun >= PASSsemantic3)
148 return;
149 semanticRun = PASSsemantic3;
150 if (members)
151 {
152 sc = sc->push(this);
153 sc->linkage = LINKcpp;
154 for (size_t i = 0; i < members->dim; i++)
155 {
156 Dsymbol *s = (*members)[i];
157 s->semantic3(sc);
158 }
159 sc->pop();
160 }
161 }
162
kind()163 const char *Nspace::kind() const
164 {
165 return "namespace";
166 }
167
oneMember(Dsymbol ** ps,Identifier * ident)168 bool Nspace::oneMember(Dsymbol **ps, Identifier *ident)
169 {
170 return Dsymbol::oneMember(ps, ident);
171 }
172
search(const Loc & loc,Identifier * ident,int flags)173 Dsymbol *Nspace::search(const Loc &loc, Identifier *ident, int flags)
174 {
175 //printf("%s::Nspace::search('%s')\n", toChars(), ident->toChars());
176 if (_scope && !symtab)
177 semantic(_scope);
178
179 if (!members || !symtab) // opaque or semantic() is not yet called
180 {
181 error("is forward referenced when looking for '%s'", ident->toChars());
182 return NULL;
183 }
184
185 return ScopeDsymbol::search(loc, ident, flags);
186 }
187
apply(Dsymbol_apply_ft_t fp,void * param)188 int Nspace::apply(Dsymbol_apply_ft_t fp, void *param)
189 {
190 if (members)
191 {
192 for (size_t i = 0; i < members->dim; i++)
193 {
194 Dsymbol *s = (*members)[i];
195 if (s)
196 {
197 if (s->apply(fp, param))
198 return 1;
199 }
200 }
201 }
202 return 0;
203 }
204
hasPointers()205 bool Nspace::hasPointers()
206 {
207 //printf("Nspace::hasPointers() %s\n", toChars());
208
209 if (members)
210 {
211 for (size_t i = 0; i < members->dim; i++)
212 {
213 Dsymbol *s = (*members)[i];
214 //printf(" s = %s %s\n", s->kind(), s->toChars());
215 if (s->hasPointers())
216 {
217 return true;
218 }
219 }
220 }
221 return false;
222 }
223
setFieldOffset(AggregateDeclaration * ad,unsigned * poffset,bool isunion)224 void Nspace::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
225 {
226 //printf("Nspace::setFieldOffset() %s\n", toChars());
227 if (_scope) // if fwd reference
228 semantic(NULL); // try to resolve it
229 if (members)
230 {
231 for (size_t i = 0; i < members->dim; i++)
232 {
233 Dsymbol *s = (*members)[i];
234 //printf("\t%s\n", s->toChars());
235 s->setFieldOffset(ad, poffset, isunion);
236 }
237 }
238 }
239