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
;
76 this->inDtemplate
= 0;
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->inDtemplate
= enclosing
->inDtemplate
;
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
)
145 sc
->scopesym
= new ScopeDsymbol();
146 sc
->scopesym
->symtab
= new DsymbolTable();
148 // Add top level package as member of this global scope
152 m
->addMember(NULL
, sc
->scopesym
, 1);
153 m
->parent
= NULL
; // got changed by addMember()
155 // Create the module scope underneath the global scope
156 sc
= sc
->push(module
);
163 //printf("Scope::push()\n");
164 Scope
*s
= new Scope(this);
169 Scope
*Scope::push(ScopeDsymbol
*ss
)
171 //printf("Scope::push(%s)\n", ss->toChars());
179 //printf("Scope::pop() %p nofree = %d\n", this, nofree);
180 Scope
*enc
= enclosing
;
183 enclosing
->callSuper
|= callSuper
;
186 { enclosing
= freelist
;
194 void Scope::mergeCallSuper(Loc loc
, unsigned cs
)
196 // This does a primitive flow analysis to support the restrictions
197 // regarding when and how constructors can appear.
198 // It merges the results of two paths.
199 // The two paths are callSuper and cs; the result is merged into callSuper.
205 callSuper
|= cs
& (CSXany_ctor
| CSXlabel
);
209 else if (callSuper
& CSXreturn
)
211 callSuper
= cs
| (callSuper
& (CSXany_ctor
| CSXlabel
));
215 a
= (cs
& (CSXthis_ctor
| CSXsuper_ctor
)) != 0;
216 b
= (callSuper
& (CSXthis_ctor
| CSXsuper_ctor
)) != 0;
218 error(loc
, "one path skips constructor");
224 Dsymbol
*Scope::search(Loc loc
, Identifier
*ident
, Dsymbol
**pscopesym
)
228 //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
229 if (ident
== Id::empty
)
231 // Look for module scope
232 for (sc
= this; sc
; sc
= sc
->enclosing
)
234 assert(sc
!= sc
->enclosing
);
237 s
= sc
->scopesym
->isModule();
240 //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
242 *pscopesym
= sc
->scopesym
;
250 for (sc
= this; sc
; sc
= sc
->enclosing
)
252 assert(sc
!= sc
->enclosing
);
255 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
256 s
= sc
->scopesym
->search(loc
, ident
, 0);
259 if ((global
.params
.warnings
||
260 global
.params
.Dversion
> 1) &&
261 ident
== Id::length
&&
262 sc
->scopesym
->isArrayScopeSymbol() &&
264 sc
->enclosing
->search(loc
, ident
, NULL
))
266 if (global
.params
.warnings
)
267 fprintf(stdmsg
, "warning - ");
268 error(s
->loc
, "array 'length' hides other 'length' name in outer scope");
271 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
273 *pscopesym
= sc
->scopesym
;
282 Dsymbol
*Scope::insert(Dsymbol
*s
)
285 for (sc
= this; sc
; sc
= sc
->enclosing
)
287 //printf("\tsc = %p\n", sc);
290 //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
291 if (!sc
->scopesym
->symtab
)
292 sc
->scopesym
->symtab
= new DsymbolTable();
293 return sc
->scopesym
->symtab
->insert(s
);
300 /********************************************
301 * Search enclosing scopes for ClassDeclaration.
304 ClassDeclaration
*Scope::getClassScope()
307 for (sc
= this; sc
; sc
= sc
->enclosing
)
309 ClassDeclaration
*cd
;
313 cd
= sc
->scopesym
->isClassDeclaration();
321 /********************************************
322 * Search enclosing scopes for ClassDeclaration.
325 AggregateDeclaration
*Scope::getStructClassScope()
328 for (sc
= this; sc
; sc
= sc
->enclosing
)
330 AggregateDeclaration
*ad
;
334 ad
= sc
->scopesym
->isClassDeclaration();
338 { ad
= sc
->scopesym
->isStructDeclaration();
347 /*******************************************
348 * For TemplateDeclarations, we need to remember the Scope
349 * where it was declared. So mark the Scope as not
353 void Scope::setNoFree()
357 //printf("Scope::setNoFree(this = %p)\n", this);
358 for (sc
= this; sc
; sc
= sc
->enclosing
)
360 //printf("\tsc = %p\n", sc);
363 assert(!(flags
& SCOPEfree
));
364 //assert(sc != sc->enclosing);
365 //assert(!sc->enclosing || sc != sc->enclosing->enclosing);