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