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