1
2 // Compiler implementation of the D programming language
3 // Copyright: Copyright (C) 2014-2021 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(Prot::public_));
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->length; 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->length; i++)
81 {
82 Dsymbol *s = (*members)[i];
83 s->setScope(sc);
84 }
85 sc->pop();
86 }
87 }
88
kind()89 const char *Nspace::kind() const
90 {
91 return "namespace";
92 }
93
oneMember(Dsymbol ** ps,Identifier * ident)94 bool Nspace::oneMember(Dsymbol **ps, Identifier *ident)
95 {
96 return Dsymbol::oneMember(ps, ident);
97 }
98
search(const Loc & loc,Identifier * ident,int flags)99 Dsymbol *Nspace::search(const Loc &loc, Identifier *ident, int flags)
100 {
101 //printf("%s::Nspace::search('%s')\n", toChars(), ident->toChars());
102 if (_scope && !symtab)
103 dsymbolSemantic(this, _scope);
104
105 if (!members || !symtab) // opaque or semantic() is not yet called
106 {
107 error("is forward referenced when looking for `%s`", ident->toChars());
108 return NULL;
109 }
110
111 return ScopeDsymbol::search(loc, ident, flags);
112 }
113
apply(Dsymbol_apply_ft_t fp,void * param)114 int Nspace::apply(Dsymbol_apply_ft_t fp, void *param)
115 {
116 if (members)
117 {
118 for (size_t i = 0; i < members->length; i++)
119 {
120 Dsymbol *s = (*members)[i];
121 if (s)
122 {
123 if (s->apply(fp, param))
124 return 1;
125 }
126 }
127 }
128 return 0;
129 }
130
hasPointers()131 bool Nspace::hasPointers()
132 {
133 //printf("Nspace::hasPointers() %s\n", toChars());
134
135 if (members)
136 {
137 for (size_t i = 0; i < members->length; i++)
138 {
139 Dsymbol *s = (*members)[i];
140 //printf(" s = %s %s\n", s->kind(), s->toChars());
141 if (s->hasPointers())
142 {
143 return true;
144 }
145 }
146 }
147 return false;
148 }
149
setFieldOffset(AggregateDeclaration * ad,unsigned * poffset,bool isunion)150 void Nspace::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
151 {
152 //printf("Nspace::setFieldOffset() %s\n", toChars());
153 if (_scope) // if fwd reference
154 dsymbolSemantic(this, NULL); // try to resolve it
155 if (members)
156 {
157 for (size_t i = 0; i < members->length; i++)
158 {
159 Dsymbol *s = (*members)[i];
160 //printf("\t%s\n", s->toChars());
161 s->setFieldOffset(ad, poffset, isunion);
162 }
163 }
164 }
165