Merge dmd upstream 6243fa6d2
[official-gcc.git] / gcc / d / dmd / dscope.c
blob27412b53d1335bd737e911e85401090f6a4f402a
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/scope.c
9 */
11 #include "root/dsystem.h" // strlen()
12 #include "root/root.h"
13 #include "root/rmem.h"
14 #include "root/speller.h"
16 #include "mars.h"
17 #include "init.h"
18 #include "identifier.h"
19 #include "scope.h"
20 #include "attrib.h"
21 #include "dsymbol.h"
22 #include "declaration.h"
23 #include "statement.h"
24 #include "aggregate.h"
25 #include "module.h"
26 #include "id.h"
27 #include "template.h"
29 Scope *Scope::freelist = NULL;
31 void allocFieldinit(Scope *sc, size_t dim)
33 sc->fieldinit = (unsigned *)mem.xcalloc(sizeof(unsigned), dim);
34 sc->fieldinit_dim = dim;
37 void freeFieldinit(Scope *sc)
39 if (sc->fieldinit)
40 mem.xfree(sc->fieldinit);
41 sc->fieldinit = NULL;
42 sc->fieldinit_dim = 0;
45 Scope *Scope::alloc()
47 if (freelist)
49 Scope *s = freelist;
50 freelist = s->enclosing;
51 //printf("freelist %p\n", s);
52 assert(s->flags & SCOPEfree);
53 s->flags &= ~SCOPEfree;
54 return s;
57 return new Scope();
60 Scope::Scope()
62 // Create root scope
64 //printf("Scope::Scope() %p\n", this);
65 this->_module = NULL;
66 this->scopesym = NULL;
67 this->sds = NULL;
68 this->enclosing = NULL;
69 this->parent = NULL;
70 this->sw = NULL;
71 this->tf = NULL;
72 this->os = NULL;
73 this->tinst = NULL;
74 this->minst = NULL;
75 this->sbreak = NULL;
76 this->scontinue = NULL;
77 this->fes = NULL;
78 this->callsc = NULL;
79 this->aligndecl = NULL;
80 this->func = NULL;
81 this->slabel = NULL;
82 this->linkage = LINKd;
83 this->cppmangle = CPPMANGLEdefault;
84 this->inlining = PINLINEdefault;
85 this->protection = Prot(PROTpublic);
86 this->explicitProtection = 0;
87 this->stc = 0;
88 this->depdecl = NULL;
89 this->inunion = 0;
90 this->nofree = 0;
91 this->noctor = 0;
92 this->intypeof = 0;
93 this->lastVar = NULL;
94 this->callSuper = 0;
95 this->fieldinit = NULL;
96 this->fieldinit_dim = 0;
97 this->flags = 0;
98 this->lastdc = NULL;
99 this->anchorCounts = NULL;
100 this->prevAnchor = NULL;
101 this->userAttribDecl = NULL;
104 Scope *Scope::copy()
106 Scope *sc = Scope::alloc();
107 *sc = *this; // memcpy
109 /* Bugzilla 11777: The copied scope should not inherit fieldinit.
111 sc->fieldinit = NULL;
113 return sc;
116 Scope *Scope::createGlobal(Module *_module)
118 Scope *sc = Scope::alloc();
119 *sc = Scope(); // memset
121 sc->aligndecl = NULL;
122 sc->linkage = LINKd;
123 sc->inlining = PINLINEdefault;
124 sc->protection = Prot(PROTpublic);
126 sc->_module = _module;
128 sc->tinst = NULL;
129 sc->minst = _module;
131 sc->scopesym = new ScopeDsymbol();
132 sc->scopesym->symtab = new DsymbolTable();
134 // Add top level package as member of this global scope
135 Dsymbol *m = _module;
136 while (m->parent)
137 m = m->parent;
138 m->addMember(NULL, sc->scopesym);
139 m->parent = NULL; // got changed by addMember()
141 // Create the module scope underneath the global scope
142 sc = sc->push(_module);
143 sc->parent = _module;
144 return sc;
147 Scope *Scope::push()
149 Scope *s = copy();
151 //printf("Scope::push(this = %p) new = %p\n", this, s);
152 assert(!(flags & SCOPEfree));
153 s->scopesym = NULL;
154 s->sds = NULL;
155 s->enclosing = this;
156 s->slabel = NULL;
157 s->nofree = 0;
158 s->fieldinit = saveFieldInit();
159 s->flags = (flags & (SCOPEcontract | SCOPEdebug | SCOPEctfe | SCOPEcompile | SCOPEconstraint |
160 SCOPEnoaccesscheck | SCOPEignoresymbolvisibility));
161 s->lastdc = NULL;
163 assert(this != s);
164 return s;
167 Scope *Scope::push(ScopeDsymbol *ss)
169 //printf("Scope::push(%s)\n", ss->toChars());
170 Scope *s = push();
171 s->scopesym = ss;
172 return s;
175 Scope *Scope::pop()
177 //printf("Scope::pop() %p nofree = %d\n", this, nofree);
178 Scope *enc = enclosing;
180 if (enclosing)
182 enclosing->callSuper |= callSuper;
183 if (fieldinit)
185 if (enclosing->fieldinit)
187 assert(fieldinit != enclosing->fieldinit);
188 size_t dim = fieldinit_dim;
189 for (size_t i = 0; i < dim; i++)
190 enclosing->fieldinit[i] |= fieldinit[i];
192 freeFieldinit(this);
196 if (!nofree)
198 enclosing = freelist;
199 freelist = this;
200 flags |= SCOPEfree;
203 return enc;
206 Scope *Scope::startCTFE()
208 Scope *sc = this->push();
209 sc->flags = this->flags | SCOPEctfe;
210 return sc;
213 Scope *Scope::endCTFE()
215 assert(flags & SCOPEctfe);
216 return pop();
219 void Scope::mergeCallSuper(Loc loc, unsigned cs)
221 // This does a primitive flow analysis to support the restrictions
222 // regarding when and how constructors can appear.
223 // It merges the results of two paths.
224 // The two paths are callSuper and cs; the result is merged into callSuper.
226 if (cs != callSuper)
228 // Have ALL branches called a constructor?
229 int aAll = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
230 int bAll = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
232 // Have ANY branches called a constructor?
233 bool aAny = (cs & CSXany_ctor) != 0;
234 bool bAny = (callSuper & CSXany_ctor) != 0;
236 // Have any branches returned?
237 bool aRet = (cs & CSXreturn) != 0;
238 bool bRet = (callSuper & CSXreturn) != 0;
240 // Have any branches halted?
241 bool aHalt = (cs & CSXhalt) != 0;
242 bool bHalt = (callSuper & CSXhalt) != 0;
244 bool ok = true;
246 if (aHalt && bHalt)
248 callSuper = CSXhalt;
250 else if ((!aHalt && aRet && !aAny && bAny) ||
251 (!bHalt && bRet && !bAny && aAny))
253 // If one has returned without a constructor call, there must be never
254 // have been ctor calls in the other.
255 ok = false;
257 else if (aHalt || (aRet && aAll))
259 // If one branch has called a ctor and then exited, anything the
260 // other branch has done is OK (except returning without a
261 // ctor call, but we already checked that).
262 callSuper |= cs & (CSXany_ctor | CSXlabel);
264 else if (bHalt || (bRet && bAll))
266 callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
268 else
270 // Both branches must have called ctors, or both not.
271 ok = (aAll == bAll);
272 // If one returned without a ctor, we must remember that
273 // (Don't bother if we've already found an error)
274 if (ok && aRet && !aAny)
275 callSuper |= CSXreturn;
276 callSuper |= cs & (CSXany_ctor | CSXlabel);
278 if (!ok)
279 error(loc, "one path skips constructor");
283 unsigned *Scope::saveFieldInit()
285 unsigned *fi = NULL;
286 if (fieldinit) // copy
288 size_t dim = fieldinit_dim;
289 fi = (unsigned *)mem.xmalloc(sizeof(unsigned) * dim);
290 for (size_t i = 0; i < dim; i++)
291 fi[i] = fieldinit[i];
293 return fi;
296 static bool mergeFieldInit(unsigned &fieldInit, unsigned fi, bool mustInit)
298 if (fi != fieldInit)
300 // Have any branches returned?
301 bool aRet = (fi & CSXreturn) != 0;
302 bool bRet = (fieldInit & CSXreturn) != 0;
304 // Have any branches halted?
305 bool aHalt = (fi & CSXhalt) != 0;
306 bool bHalt = (fieldInit & CSXhalt) != 0;
308 bool ok;
310 if (aHalt && bHalt)
312 ok = true;
313 fieldInit = CSXhalt;
315 else if (!aHalt && aRet)
317 ok = !mustInit || (fi & CSXthis_ctor);
318 fieldInit = fieldInit;
320 else if (!bHalt && bRet)
322 ok = !mustInit || (fieldInit & CSXthis_ctor);
323 fieldInit = fi;
325 else if (aHalt)
327 ok = !mustInit || (fieldInit & CSXthis_ctor);
328 fieldInit = fieldInit;
330 else if (bHalt)
332 ok = !mustInit || (fi & CSXthis_ctor);
333 fieldInit = fi;
335 else
337 ok = !mustInit || !((fieldInit ^ fi) & CSXthis_ctor);
338 fieldInit |= fi;
341 return ok;
343 return true;
346 void Scope::mergeFieldInit(Loc loc, unsigned *fies)
348 if (fieldinit && fies)
350 FuncDeclaration *f = func;
351 if (fes) f = fes->func;
352 AggregateDeclaration *ad = f->isMember2();
353 assert(ad);
355 for (size_t i = 0; i < ad->fields.dim; i++)
357 VarDeclaration *v = ad->fields[i];
358 bool mustInit = (v->storage_class & STCnodefaultctor ||
359 v->type->needsNested());
361 if (!::mergeFieldInit(fieldinit[i], fies[i], mustInit))
363 ::error(loc, "one path skips field %s", ad->fields[i]->toChars());
369 Module *Scope::instantiatingModule()
371 // TODO: in speculative context, returning 'module' is correct?
372 return minst ? minst : _module;
375 static Dsymbol *searchScopes(Scope *scope, Loc loc, Identifier *ident, Dsymbol **pscopesym, int flags)
377 for (Scope *sc = scope; sc; sc = sc->enclosing)
379 assert(sc != sc->enclosing);
380 if (!sc->scopesym)
381 continue;
382 //printf("\tlooking in scopesym '%s', kind = '%s', flags = x%x\n", sc->scopesym->toChars(), sc->scopesym->kind(), flags);
384 if (sc->scopesym->isModule())
385 flags |= SearchUnqualifiedModule; // tell Module.search() that SearchLocalsOnly is to be obeyed
387 if (Dsymbol *s = sc->scopesym->search(loc, ident, flags))
389 if (!(flags & (SearchImportsOnly | IgnoreErrors)) &&
390 ident == Id::length && sc->scopesym->isArrayScopeSymbol() &&
391 sc->enclosing && sc->enclosing->search(loc, ident, NULL, flags))
393 warning(s->loc, "array 'length' hides other 'length' name in outer scope");
395 if (pscopesym)
396 *pscopesym = sc->scopesym;
397 return s;
399 // Stop when we hit a module, but keep going if that is not just under the global scope
400 if (sc->scopesym->isModule() && !(sc->enclosing && !sc->enclosing->enclosing))
401 break;
403 return NULL;
406 /************************************
407 * Perform unqualified name lookup by following the chain of scopes up
408 * until found.
410 * Params:
411 * loc = location to use for error messages
412 * ident = name to look up
413 * pscopesym = if supplied and name is found, set to scope that ident was found in
414 * flags = modify search based on flags
416 * Returns:
417 * symbol if found, null if not
419 Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym, int flags)
421 // This function is called only for unqualified lookup
422 assert(!(flags & (SearchLocalsOnly | SearchImportsOnly)));
424 /* If ident is "start at module scope", only look at module scope
426 if (ident == Id::empty)
428 // Look for module scope
429 for (Scope *sc = this; sc; sc = sc->enclosing)
431 assert(sc != sc->enclosing);
432 if (!sc->scopesym)
433 continue;
435 if (Dsymbol *s = sc->scopesym->isModule())
437 if (pscopesym)
438 *pscopesym = sc->scopesym;
439 return s;
442 return NULL;
445 if (this->flags & SCOPEignoresymbolvisibility)
446 flags |= IgnoreSymbolVisibility;
448 Dsymbol *sold = NULL;
449 if (global.params.bug10378 || global.params.check10378)
451 sold = searchScopes(this, loc, ident, pscopesym, flags | IgnoreSymbolVisibility);
452 if (!global.params.check10378)
453 return sold;
455 if (ident == Id::dollar) // Bugzilla 15825
456 return sold;
458 // Search both ways
461 // First look in local scopes
462 Dsymbol *s = searchScopes(this, loc, ident, pscopesym, flags | SearchLocalsOnly);
463 if (!s)
465 // Second look in imported modules
466 s = searchScopes(this, loc, ident, pscopesym, flags | SearchImportsOnly);
467 /** Still find private symbols, so that symbols that weren't access
468 * checked by the compiler remain usable. Once the deprecation is over,
469 * this should be moved to search_correct instead.
471 if (!s && !(flags & IgnoreSymbolVisibility))
473 s = searchScopes(this, loc, ident, pscopesym, flags | SearchLocalsOnly | IgnoreSymbolVisibility);
474 if (!s)
475 s = searchScopes(this, loc, ident, pscopesym, flags | SearchImportsOnly | IgnoreSymbolVisibility);
477 if (s && !(flags & IgnoreErrors))
478 ::deprecation(loc, "%s is not visible from module %s", s->toPrettyChars(), _module->toChars());
482 if (global.params.check10378)
484 Dsymbol *snew = s;
485 if (sold != snew)
486 deprecation10378(loc, sold, snew);
487 if (global.params.bug10378)
488 s = sold;
490 return s;
493 Dsymbol *Scope::insert(Dsymbol *s)
495 if (VarDeclaration *vd = s->isVarDeclaration())
497 if (lastVar)
498 vd->lastVar = lastVar;
499 lastVar = vd;
501 else if (WithScopeSymbol *ss = s->isWithScopeSymbol())
503 if (VarDeclaration *vd = ss->withstate->wthis)
505 if (lastVar)
506 vd->lastVar = lastVar;
507 lastVar = vd;
509 return NULL;
511 for (Scope *sc = this; sc; sc = sc->enclosing)
513 //printf("\tsc = %p\n", sc);
514 if (sc->scopesym)
516 //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
517 if (!sc->scopesym->symtab)
518 sc->scopesym->symtab = new DsymbolTable();
519 return sc->scopesym->symtabInsert(s);
522 assert(0);
523 return NULL;
526 /********************************************
527 * Search enclosing scopes for ClassDeclaration.
530 ClassDeclaration *Scope::getClassScope()
532 for (Scope *sc = this; sc; sc = sc->enclosing)
534 if (!sc->scopesym)
535 continue;
537 ClassDeclaration *cd = sc->scopesym->isClassDeclaration();
538 if (cd)
539 return cd;
541 return NULL;
544 /********************************************
545 * Search enclosing scopes for ClassDeclaration.
548 AggregateDeclaration *Scope::getStructClassScope()
550 for (Scope *sc = this; sc; sc = sc->enclosing)
552 if (!sc->scopesym)
553 continue;
555 AggregateDeclaration *ad = sc->scopesym->isClassDeclaration();
556 if (ad)
557 return ad;
558 ad = sc->scopesym->isStructDeclaration();
559 if (ad)
560 return ad;
562 return NULL;
565 /*******************************************
566 * For TemplateDeclarations, we need to remember the Scope
567 * where it was declared. So mark the Scope as not
568 * to be free'd.
571 void Scope::setNoFree()
573 //int i = 0;
575 //printf("Scope::setNoFree(this = %p)\n", this);
576 for (Scope *sc = this; sc; sc = sc->enclosing)
578 //printf("\tsc = %p\n", sc);
579 sc->nofree = 1;
581 assert(!(flags & SCOPEfree));
582 //assert(sc != sc->enclosing);
583 //assert(!sc->enclosing || sc != sc->enclosing->enclosing);
584 //if (++i == 10)
585 //assert(0);
589 structalign_t Scope::alignment()
591 if (aligndecl)
592 return aligndecl->getAlignment(this);
593 else
594 return STRUCTALIGN_DEFAULT;
597 /************************************************
598 * Given the failed search attempt, try to find
599 * one with a close spelling.
602 void *scope_search_fp(void *arg, const char *seed, int* cost)
604 //printf("scope_search_fp('%s')\n", seed);
606 /* If not in the lexer's string table, it certainly isn't in the symbol table.
607 * Doing this first is a lot faster.
609 size_t len = strlen(seed);
610 if (!len)
611 return NULL;
612 Identifier *id = Identifier::lookup(seed, len);
613 if (!id)
614 return NULL;
616 Scope *sc = (Scope *)arg;
617 Module::clearCache();
618 Dsymbol *scopesym = NULL;
619 Dsymbol *s = sc->search(Loc(), id, &scopesym, IgnoreErrors);
620 if (s)
622 for (*cost = 0; sc; sc = sc->enclosing, (*cost)++)
623 if (sc->scopesym == scopesym)
624 break;
625 if (scopesym != s->parent)
627 (*cost)++; // got to the symbol through an import
628 if (s->prot().kind == PROTprivate)
629 return NULL;
632 return (void*)s;
635 void Scope::deprecation10378(Loc loc, Dsymbol *sold, Dsymbol *snew)
637 // Bugzilla 15857
639 // The overloadset found via the new lookup rules is either
640 // equal or a subset of the overloadset found via the old
641 // lookup rules, so it suffices to compare the dimension to
642 // check for equality.
643 OverloadSet *osold = NULL;
644 OverloadSet *osnew = NULL;
645 if (sold && (osold = sold->isOverloadSet()) != NULL &&
646 snew && (osnew = snew->isOverloadSet()) != NULL &&
647 osold->a.dim == osnew->a.dim)
648 return;
650 OutBuffer buf;
651 buf.writestring("local import search method found ");
652 if (osold)
653 buf.printf("%s %s (%d overloads)", sold->kind(), sold->toPrettyChars(), (int)osold->a.dim);
654 else if (sold)
655 buf.printf("%s %s", sold->kind(), sold->toPrettyChars());
656 else
657 buf.writestring("nothing");
658 buf.writestring(" instead of ");
659 if (osnew)
660 buf.printf("%s %s (%d overloads)", snew->kind(), snew->toPrettyChars(), (int)osnew->a.dim);
661 else if (snew)
662 buf.printf("%s %s", snew->kind(), snew->toPrettyChars());
663 else
664 buf.writestring("nothing");
666 deprecation(loc, "%s", buf.peekString());
669 Dsymbol *Scope::search_correct(Identifier *ident)
671 if (global.gag)
672 return NULL; // don't do it for speculative compiles; too time consuming
674 return (Dsymbol *)speller(ident->toChars(), &scope_search_fp, this, idchars);
677 /************************************
678 * Maybe `ident` was a C or C++ name. Check for that,
679 * and suggest the D equivalent.
680 * Params:
681 * ident = unknown identifier
682 * Returns:
683 * D identifier string if found, null if not
685 const char *Scope::search_correct_C(Identifier *ident)
687 TOK tok;
688 if (ident == Id::_NULL)
689 tok = TOKnull;
690 else if (ident == Id::_TRUE)
691 tok = TOKtrue;
692 else if (ident == Id::_FALSE)
693 tok = TOKfalse;
694 else if (ident == Id::_unsigned)
695 tok = TOKuns32;
696 else
697 return NULL;
698 return Token::toChars(tok);