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
;
78 this->noaccesscheck
= 0;
80 this->parameterSpecialization
= 0;
89 Scope::Scope(Scope
*enclosing
)
91 //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
92 assert(!(enclosing
->flags
& SCOPEfree
));
93 this->module
= enclosing
->module
;
94 this->func
= enclosing
->func
;
95 this->parent
= enclosing
->parent
;
96 this->scopesym
= NULL
;
98 this->sw
= enclosing
->sw
;
99 this->tf
= enclosing
->tf
;
100 this->sbreak
= enclosing
->sbreak
;
101 this->scontinue
= enclosing
->scontinue
;
102 this->fes
= enclosing
->fes
;
103 this->structalign
= enclosing
->structalign
;
104 this->enclosing
= enclosing
;
106 if (enclosing
->enclosing
)
107 assert(!(enclosing
->enclosing
->flags
& SCOPEfree
));
108 if (this == enclosing
->enclosing
)
110 printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing
, enclosing
->enclosing
);
112 assert(this != enclosing
->enclosing
);
115 this->linkage
= enclosing
->linkage
;
116 this->protection
= enclosing
->protection
;
117 this->explicitProtection
= enclosing
->explicitProtection
;
118 this->stc
= enclosing
->stc
;
119 this->attributes
= enclosing
->attributes
;
121 this->inunion
= enclosing
->inunion
;
122 this->incontract
= enclosing
->incontract
;
124 this->noctor
= enclosing
->noctor
;
125 this->noaccesscheck
= enclosing
->noaccesscheck
;
126 this->intypeof
= enclosing
->intypeof
;
127 this->parameterSpecialization
= enclosing
->parameterSpecialization
;
128 this->callSuper
= enclosing
->callSuper
;
130 this->anonAgg
= NULL
;
132 this->lastoffset
= 0;
133 this->docbuf
= enclosing
->docbuf
;
134 assert(this != enclosing
);
137 Scope
*Scope::createGlobal(Module
*module
)
143 sc
->scopesym
= new ScopeDsymbol();
144 sc
->scopesym
->symtab
= new DsymbolTable();
146 // Add top level package as member of this global scope
150 m
->addMember(NULL
, sc
->scopesym
, 1);
151 m
->parent
= NULL
; // got changed by addMember()
153 // Create the module scope underneath the global scope
154 sc
= sc
->push(module
);
161 //printf("Scope::push()\n");
162 Scope
*s
= new Scope(this);
167 Scope
*Scope::push(ScopeDsymbol
*ss
)
169 //printf("Scope::push(%s)\n", ss->toChars());
177 //printf("Scope::pop() %p nofree = %d\n", this, nofree);
178 Scope
*enc
= enclosing
;
181 enclosing
->callSuper
|= callSuper
;
184 { enclosing
= freelist
;
192 void Scope::mergeCallSuper(Loc loc
, unsigned cs
)
194 // This does a primitive flow analysis to support the restrictions
195 // regarding when and how constructors can appear.
196 // It merges the results of two paths.
197 // The two paths are callSuper and cs; the result is merged into callSuper.
203 callSuper
|= cs
& (CSXany_ctor
| CSXlabel
);
207 else if (callSuper
& CSXreturn
)
209 callSuper
= cs
| (callSuper
& (CSXany_ctor
| CSXlabel
));
213 a
= (cs
& (CSXthis_ctor
| CSXsuper_ctor
)) != 0;
214 b
= (callSuper
& (CSXthis_ctor
| CSXsuper_ctor
)) != 0;
216 error(loc
, "one path skips constructor");
222 Dsymbol
*Scope::search(Loc loc
, Identifier
*ident
, Dsymbol
**pscopesym
)
226 //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
227 if (ident
== Id::empty
)
229 // Look for module scope
230 for (sc
= this; sc
; sc
= sc
->enclosing
)
232 assert(sc
!= sc
->enclosing
);
235 s
= sc
->scopesym
->isModule();
238 //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
240 *pscopesym
= sc
->scopesym
;
248 for (sc
= this; sc
; sc
= sc
->enclosing
)
250 assert(sc
!= sc
->enclosing
);
253 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
254 s
= sc
->scopesym
->search(loc
, ident
, 0);
257 if ((global
.params
.warnings
||
258 global
.params
.Dversion
> 1) &&
259 ident
== Id::length
&&
260 sc
->scopesym
->isArrayScopeSymbol() &&
262 sc
->enclosing
->search(loc
, ident
, NULL
))
264 if (global
.params
.warnings
)
265 fprintf(stdmsg
, "warning - ");
266 error(s
->loc
, "array 'length' hides other 'length' name in outer scope");
269 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
271 *pscopesym
= sc
->scopesym
;
280 Dsymbol
*Scope::insert(Dsymbol
*s
)
283 for (sc
= this; sc
; sc
= sc
->enclosing
)
285 //printf("\tsc = %p\n", sc);
288 //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
289 if (!sc
->scopesym
->symtab
)
290 sc
->scopesym
->symtab
= new DsymbolTable();
291 return sc
->scopesym
->symtab
->insert(s
);
298 /********************************************
299 * Search enclosing scopes for ClassDeclaration.
302 ClassDeclaration
*Scope::getClassScope()
305 for (sc
= this; sc
; sc
= sc
->enclosing
)
307 ClassDeclaration
*cd
;
311 cd
= sc
->scopesym
->isClassDeclaration();
319 /********************************************
320 * Search enclosing scopes for ClassDeclaration.
323 AggregateDeclaration
*Scope::getStructClassScope()
326 for (sc
= this; sc
; sc
= sc
->enclosing
)
328 AggregateDeclaration
*ad
;
332 ad
= sc
->scopesym
->isClassDeclaration();
336 { ad
= sc
->scopesym
->isStructDeclaration();
345 /*******************************************
346 * For TemplateDeclarations, we need to remember the Scope
347 * where it was declared. So mark the Scope as not
351 void Scope::setNoFree()
355 //printf("Scope::setNoFree(this = %p)\n", this);
356 for (sc
= this; sc
; sc
= sc
->enclosing
)
358 //printf("\tsc = %p\n", sc);
361 assert(!(flags
& SCOPEfree
));
362 //assert(sc != sc->enclosing);
363 //assert(!sc->enclosing || sc != sc->enclosing->enclosing);