2 // Copyright (c) 1999-2005 by Digital Mars
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
10 /* NOTE: This file has been patched from the original DMD distribution to
11 work with the GDC compiler.
13 Modified by David Friedman, December 2006
23 #include "identifier.h"
27 #include "declaration.h"
28 #include "aggregate.h"
32 Scope
*Scope::freelist
= NULL
;
34 void *Scope::operator new(size_t size
)
39 freelist
= s
->enclosing
;
40 //printf("freelist %p\n", s);
41 assert(s
->flags
& SCOPEfree
);
42 s
->flags
&= ~SCOPEfree
;
46 void *p
= ::operator new(size
);
47 //printf("new %p\n", p);
52 { // Create root scope
54 //printf("Scope::Scope() %p\n", this);
56 this->scopesym
= NULL
;
58 this->enclosing
= NULL
;
63 this->scontinue
= NULL
;
65 this->structalign
= global
.structalign
;
68 this->linkage
= LINKd
;
69 this->protection
= PROTpublic
;
70 this->explicitProtection
= 0;
72 this->attributes
= NULL
;
79 this->noaccesscheck
= 0;
81 this->parameterSpecialization
= 0;
90 Scope::Scope(Scope
*enclosing
)
92 //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
93 assert(!(enclosing
->flags
& SCOPEfree
));
94 this->module
= enclosing
->module
;
95 this->func
= enclosing
->func
;
96 this->parent
= enclosing
->parent
;
97 this->fromDcode
= enclosing
->fromDcode
;
98 this->scopesym
= NULL
;
100 this->sw
= enclosing
->sw
;
101 this->tf
= enclosing
->tf
;
102 this->sbreak
= enclosing
->sbreak
;
103 this->scontinue
= enclosing
->scontinue
;
104 this->fes
= enclosing
->fes
;
105 this->structalign
= enclosing
->structalign
;
106 this->enclosing
= enclosing
;
108 if (enclosing
->enclosing
)
109 assert(!(enclosing
->enclosing
->flags
& SCOPEfree
));
110 if (this == enclosing
->enclosing
)
112 printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing
, enclosing
->enclosing
);
114 assert(this != enclosing
->enclosing
);
117 this->linkage
= enclosing
->linkage
;
118 this->protection
= enclosing
->protection
;
119 this->explicitProtection
= enclosing
->explicitProtection
;
120 this->stc
= enclosing
->stc
;
121 this->attributes
= enclosing
->attributes
;
123 this->inunion
= enclosing
->inunion
;
124 this->incontract
= enclosing
->incontract
;
126 this->noctor
= enclosing
->noctor
;
127 this->noaccesscheck
= enclosing
->noaccesscheck
;
128 this->intypeof
= enclosing
->intypeof
;
129 this->parameterSpecialization
= enclosing
->parameterSpecialization
;
130 this->callSuper
= enclosing
->callSuper
;
132 this->anonAgg
= NULL
;
134 this->lastoffset
= 0;
135 this->docbuf
= enclosing
->docbuf
;
136 assert(this != enclosing
);
139 Scope
*Scope::createGlobal(Module
*module
)
144 sc
->fromDcode
= !module
->isDltFile
;
146 sc
->scopesym
= new ScopeDsymbol();
147 sc
->scopesym
->symtab
= new DsymbolTable();
149 // Add top level package as member of this global scope
153 m
->addMember(NULL
, sc
->scopesym
, 1);
154 m
->parent
= NULL
; // got changed by addMember()
156 // Create the module scope underneath the global scope
157 sc
= sc
->push(module
);
164 //printf("Scope::push()\n");
165 Scope
*s
= new Scope(this);
170 Scope
*Scope::push(ScopeDsymbol
*ss
)
172 //printf("Scope::push(%s)\n", ss->toChars());
180 //printf("Scope::pop() %p nofree = %d\n", this, nofree);
181 Scope
*enc
= enclosing
;
184 enclosing
->callSuper
|= callSuper
;
187 { enclosing
= freelist
;
195 void Scope::mergeCallSuper(Loc loc
, unsigned cs
)
197 // This does a primitive flow analysis to support the restrictions
198 // regarding when and how constructors can appear.
199 // It merges the results of two paths.
200 // The two paths are callSuper and cs; the result is merged into callSuper.
206 callSuper
|= cs
& (CSXany_ctor
| CSXlabel
);
210 else if (callSuper
& CSXreturn
)
212 callSuper
= cs
| (callSuper
& (CSXany_ctor
| CSXlabel
));
216 a
= (cs
& (CSXthis_ctor
| CSXsuper_ctor
)) != 0;
217 b
= (callSuper
& (CSXthis_ctor
| CSXsuper_ctor
)) != 0;
219 error(loc
, "one path skips constructor");
225 Dsymbol
*Scope::search(Loc loc
, Identifier
*ident
, Dsymbol
**pscopesym
)
229 //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
230 if (ident
== Id::empty
)
232 // Look for module scope
233 for (sc
= this; sc
; sc
= sc
->enclosing
)
235 assert(sc
!= sc
->enclosing
);
238 s
= sc
->scopesym
->isModule();
241 //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
243 *pscopesym
= sc
->scopesym
;
251 for (sc
= this; sc
; sc
= sc
->enclosing
)
253 assert(sc
!= sc
->enclosing
);
256 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
257 s
= sc
->scopesym
->search(loc
, ident
, 0);
260 if ((global
.params
.warnings
||
261 global
.params
.Dversion
> 1) &&
262 ident
== Id::length
&&
263 sc
->scopesym
->isArrayScopeSymbol() &&
265 sc
->enclosing
->search(loc
, ident
, NULL
))
267 if (global
.params
.warnings
)
268 fprintf(stdmsg
, "warning - ");
269 error(s
->loc
, "array 'length' hides other 'length' name in outer scope");
272 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
274 *pscopesym
= sc
->scopesym
;
283 Dsymbol
*Scope::insert(Dsymbol
*s
)
286 for (sc
= this; sc
; sc
= sc
->enclosing
)
288 //printf("\tsc = %p\n", sc);
291 //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
292 if (!sc
->scopesym
->symtab
)
293 sc
->scopesym
->symtab
= new DsymbolTable();
294 return sc
->scopesym
->symtab
->insert(s
);
301 /********************************************
302 * Search enclosing scopes for ClassDeclaration.
305 ClassDeclaration
*Scope::getClassScope()
308 for (sc
= this; sc
; sc
= sc
->enclosing
)
310 ClassDeclaration
*cd
;
314 cd
= sc
->scopesym
->isClassDeclaration();
322 /********************************************
323 * Search enclosing scopes for ClassDeclaration.
326 AggregateDeclaration
*Scope::getStructClassScope()
329 for (sc
= this; sc
; sc
= sc
->enclosing
)
331 AggregateDeclaration
*ad
;
335 ad
= sc
->scopesym
->isClassDeclaration();
339 { ad
= sc
->scopesym
->isStructDeclaration();
348 /*******************************************
349 * For TemplateDeclarations, we need to remember the Scope
350 * where it was declared. So mark the Scope as not
354 void Scope::setNoFree()
358 //printf("Scope::setNoFree(this = %p)\n", this);
359 for (sc
= this; sc
; sc
= sc
->enclosing
)
361 //printf("\tsc = %p\n", sc);
364 assert(!(flags
& SCOPEfree
));
365 //assert(sc != sc->enclosing);
366 //assert(!sc->enclosing || sc != sc->enclosing->enclosing);