bool Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident) { //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); Dsymbol *s = NULL; if (members) { for (size_t i = 0; i < members->dim; i++) { Dsymbol *sx = (*members)[i]; bool x = sx->oneMember(ps, ident); //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); if (!x) { //printf("\tfalse 1\n"); assert(*ps == NULL); return false; } if (*ps) { assert(ident); if (!(*ps)->ident || !(*ps)->ident->equals(ident)) continue; if (!s) s = *ps; else if (s->isOverloadable() && (*ps)->isOverloadable()) { // keep head of overload set FuncDeclaration *f1 = s->isFuncDeclaration(); FuncDeclaration *f2 = (*ps)->isFuncDeclaration(); if (f1 && f2) { assert(!f1->isFuncAliasDeclaration()); assert(!f2->isFuncAliasDeclaration()); for (; f1 != f2; f1 = f1->overnext0) { if (f1->overnext0 == NULL) { f1->overnext0 = f2; break; } } } } else // more than one symbol { *ps = NULL; //printf("\tfalse 2\n"); return false; } } } } *ps = s; // s is the one symbol, NULL if none //printf("\ttrue\n"); return true; }
int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident) { //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); Dsymbol *s = NULL; if (members) { for (size_t i = 0; i < members->dim; i++) { Dsymbol *sx = (*members)[i]; int x = sx->oneMember(ps, ident); //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); if (!x) { //printf("\tfalse 1\n"); assert(*ps == NULL); return FALSE; } if (*ps) { if (ident) { if (!(*ps)->ident || !(*ps)->ident->equals(ident)) continue; } if (!s) s = *ps; else if (s->isOverloadable() && (*ps)->isOverloadable()) ; // keep head of overload set else // more than one symbol { *ps = NULL; //printf("\tfalse 2\n"); return FALSE; } } } } *ps = s; // s is the one symbol, NULL if none //printf("\ttrue\n"); return TRUE; }
Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) { //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; // Look in symbols declared in this module Dsymbol *s1 = symtab ? symtab->lookup(ident) : NULL; //printf("\ts1 = %p, imports = %p, %d\n", s1, imports, imports ? imports->dim : 0); if (s1) { //printf("\ts = '%s.%s'\n",toChars(),s1->toChars()); return s1; } else if (!imports) return NULL; else { Dsymbol *s = NULL; OverloadSet *a = NULL; // Look in imported modules for (size_t i = 0; i < imports->dim; i++) { // If private import, don't search it if (flags & 1 && prots[i] == PROTprivate) continue; Dsymbol *ss = (*imports)[i]; //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport()); /* Don't find private members if ss is a module */ Dsymbol *s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); if (!s) s = s2; else if (s2 && s != s2) { if (s->toAlias() == s2->toAlias() || s->getType() == s2->getType() && s->getType()) { /* After following aliases, we found the same * symbol, so it's not an ambiguity. But if one * alias is deprecated or less accessible, prefer * the other. */ if (s->isDeprecated() || s2->prot() > s->prot() && s2->prot() != PROTnone) s = s2; } else { /* Two imports of the same module should be regarded as * the same. */ Import *i1 = s->isImport(); Import *i2 = s2->isImport(); if (!(i1 && i2 && (i1->mod == i2->mod || (!i1->parent->isImport() && !i2->parent->isImport() && i1->ident->equals(i2->ident)) ) ) ) { /* Bugzilla 8668: * Public selective import adds AliasDeclaration in module. * To make an overload set, resolve aliases in here and * get actual overload roots which accessible via s and s2. */ s = s->toAlias(); s2 = s2->toAlias(); /* If both s2 and s are overloadable (though we only * need to check s once) */ if (s2->isOverloadable() && (a || s->isOverloadable())) { if (!a) { a = new OverloadSet(s->ident); a->parent = this; } /* Don't add to a[] if s2 is alias of previous sym */ for (size_t j = 0; j < a->a.dim; j++) { Dsymbol *s3 = a->a[j]; if (s2->toAlias() == s3->toAlias()) { if (s3->isDeprecated() || s2->prot() > s3->prot() && s2->prot() != PROTnone) a->a[j] = s2; goto Lcontinue; } } a->push(s2); Lcontinue: continue; } if (flags & 4) // if return NULL on ambiguity return NULL; if (!(flags & 2)) ScopeDsymbol::multiplyDefined(loc, s, s2); break; } } } } /* Build special symbol if we had multiple finds */ if (a) { assert(s); a->push(s); s = a; } if (s) { if (!(flags & 2) && s->prot() == PROTprivate && !s->parent->isTemplateMixin()) { if (!s->isImport()) error(loc, "%s %s is private", s->kind(), s->toPrettyChars()); } } return s; } }
Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) { //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); // Look in symbols declared in this module Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; if (s) { //printf("\ts = '%s.%s'\n",toChars(),s->toChars()); } else if (imports) { OverloadSet *a = NULL; // Look in imported modules for (int i = 0; i < imports->dim; i++) { ScopeDsymbol *ss = (ScopeDsymbol *)imports->data[i]; Dsymbol *s2; // If private import, don't search it if (flags & 1 && prots[i] == PROTprivate) continue; //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport()); /* Don't find private members if ss is a module */ s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); if (!s) s = s2; else if (s2 && s != s2) { if (s->toAlias() == s2->toAlias()) { /* After following aliases, we found the same symbol, * so it's not an ambiguity. * But if one alias is deprecated, prefer the other. */ if (s->isDeprecated()) s = s2; } else { /* Two imports of the same module should be regarded as * the same. */ Import *i1 = s->isImport(); Import *i2 = s2->isImport(); if (!(i1 && i2 && (i1->mod == i2->mod || (!i1->parent->isImport() && !i2->parent->isImport() && i1->ident->equals(i2->ident)) ) ) ) { /* If both s2 and s are overloadable (though we only * need to check s once) */ if (s2->isOverloadable() && (a || s->isOverloadable())) { if (!a) a = new OverloadSet(); /* Don't add to a[] if s2 is alias of previous sym */ for (int j = 0; j < a->a.dim; j++) { Dsymbol *s3 = (Dsymbol *)a->a.data[j]; if (s2->toAlias() == s3->toAlias()) { if (s3->isDeprecated()) a->a.data[j] = (void *)s2; goto Lcontinue; } } a->push(s2); Lcontinue: continue; } if (flags & 4) // if return NULL on ambiguity return NULL; if (!(flags & 2)) ss->multiplyDefined(loc, s, s2); break; } } } } /* Build special symbol if we had multiple finds */ if (a) { assert(s); a->push(s); s = a; } if (s) { Declaration *d = s->isDeclaration(); /* if (d && d->protection == PROTprivate && !d->parent->isTemplateMixin() && !(flags & 2)) error("%s is private", d->toPrettyChars()); */ } } return s; }