Skip to content

Commit

Permalink
Apply fixed fix for bug 314 (pull 190).
Browse files Browse the repository at this point in the history
Fixes fea1aee
  • Loading branch information
Christian Kamm committed Dec 31, 2011
1 parent c50eb5f commit dc5ab5c
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 105 deletions.
2 changes: 1 addition & 1 deletion src/dsymbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
//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);
s2 = ss->search(loc, ident, ss->isImport() ? 1 : 0);
if (!s)
s = s2;
else if (s2 && s != s2)
Expand Down
6 changes: 6 additions & 0 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -6610,6 +6610,12 @@ Expression *DotIdExp::semantic(Scope *sc, int flag)
(ie->sds->isModule() && ie->sds != sc->module) ? 1 : 0);
if (s)
{
/* Check for access before resolving aliases because public
* aliases to private symbols are public.
*/
if (Declaration *d = s->isDeclaration())
accessCheck(loc, sc, 0, d);

s = s->toAlias();
checkDeprecated(sc, s);

Expand Down
155 changes: 63 additions & 92 deletions src/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *aliasId,
int isstatic)
: Dsymbol(id)
: Dsymbol()
{
assert(id);
this->loc = loc;
Expand All @@ -37,22 +37,13 @@ Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *alias
this->isstatic = isstatic;
pkg = NULL;
mod = NULL;

if (aliasId)
this->ident = aliasId;
// Kludge to change Import identifier to first package
else if (packages && packages->dim)
this->ident = packages->tdata()[0];
}

void Import::addAlias(Identifier *name, Identifier *alias)
{
if (isstatic)
error("cannot have an import bind list");

if (!aliasId)
this->ident = NULL; // make it an anonymous import

names.push(name);
aliases.push(alias);
}
Expand Down Expand Up @@ -141,15 +132,12 @@ void Import::importAll(Scope *sc)
load(sc);
mod->importAll(0);

if (!isstatic && !aliasId && !names.dim)
{
/* Default to private importing
*/
enum PROT prot = sc->protection;
if (!sc->explicitProtection)
prot = PROTprivate;
sc->scopesym->importScope(mod, prot);
}
/* Default to private importing
*/
enum PROT prot = sc->protection;
if (!sc->explicitProtection)
prot = PROTprivate;
sc->scopesym->importScope(this, prot);
}
}

Expand Down Expand Up @@ -179,20 +167,17 @@ void Import::semantic(Scope *sc)
//printf("%s imports %s\n", sc->module->toChars(), mod->toChars());
sc->module->aimports.push(mod);

if (!isstatic && !aliasId && !names.dim)
/* Default to private importing
*/
enum PROT prot = sc->protection;
if (!sc->explicitProtection)
prot = PROTprivate;
for (Scope *scd = sc; scd; scd = scd->enclosing)
{
/* Default to private importing
*/
enum PROT prot = sc->protection;
if (!sc->explicitProtection)
prot = PROTprivate;
for (Scope *scd = sc; scd; scd = scd->enclosing)
if (scd->scopesym)
{
if (scd->scopesym)
{
scd->scopesym->importScope(mod, prot);
break;
}
scd->scopesym->importScope(this, prot);
break;
}
}

Expand All @@ -202,18 +187,6 @@ void Import::semantic(Scope *sc)
{ //printf("module4 %s because of %s\n", sc->module->toChars(), mod->toChars());
sc->module->needmoduleinfo = 1;
}

sc = sc->push(mod);
for (size_t i = 0; i < aliasdecls.dim; i++)
{ Dsymbol *s = aliasdecls.tdata()[i];

//printf("\tImport alias semantic('%s')\n", s->toChars());
if (!mod->search(loc, names.tdata()[i], 0))
error("%s not found", (names.tdata()[i])->toChars());

s->semantic(sc);
}
sc = sc->pop();
}

if (global.params.moduleDeps != NULL)
Expand Down Expand Up @@ -298,48 +271,6 @@ void Import::semantic2(Scope *sc)
}
}

Dsymbol *Import::toAlias()
{
if (aliasId)
return mod;
return this;
}

/*****************************
* Add import to sd's symbol table.
*/

int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
int result = 0;

if (names.dim == 0)
return Dsymbol::addMember(sc, sd, memnum);

if (aliasId)
result = Dsymbol::addMember(sc, sd, memnum);

/* Instead of adding the import to sd's symbol table,
* add each of the alias=name pairs
*/
for (size_t i = 0; i < names.dim; i++)
{
Identifier *name = names.tdata()[i];
Identifier *alias = aliases.tdata()[i];

if (!alias)
alias = name;

TypeIdentifier *tname = new TypeIdentifier(loc, name);
AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
result |= ad->addMember(sc, sd, memnum);

aliasdecls.push(ad);
}

return result;
}

Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
{
//printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
Expand All @@ -349,14 +280,50 @@ Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
mod->semantic();
}

// Forward it to the package/module
return pkg->search(loc, ident, flags);
}
if (names.dim) // selective import
{
for (size_t i = 0; i < names.dim; i++)
{
Identifier *name = (Identifier *)names.data[i];
Identifier *alias = (Identifier *)aliases.data[i];

int Import::overloadInsert(Dsymbol *s)
{
// Allow multiple imports of the same name
return s->isImport() != NULL;
if (!alias)
alias = name;

if (alias->equals(ident))
return mod->search(loc, name, flags);
}

// What should happen when renamed and selective imports are mixed?
// This makes the whole module available with the renamed id.
if (aliasId && aliasId->equals(ident))
return mod;
}
else // non-selective import
{
// For renamed imports, only the alias name is visible.
if (aliasId)
{
if (aliasId->equals(ident))
return mod;
return 0;
}

// For non-static imports, prefer symbols in the module over the module name.
if (!isstatic)
{
Dsymbol *s = mod->search(loc, ident, flags);
if (s)
return s;
}

// Make the start of the package name available.
if (pkg->ident->equals(ident))
{
return pkg;
}
}
return 0;
}

void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
Expand All @@ -383,3 +350,7 @@ void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
}

char *Import::toChars()
{
return id->toChars();
}
6 changes: 1 addition & 5 deletions src/import.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ struct Import : Dsymbol
Identifiers names;
Identifiers aliases;

AliasDeclarations aliasdecls; // AliasDeclarations for names/aliases

Module *mod;
Package *pkg; // leftmost package/module

Expand All @@ -52,11 +50,9 @@ struct Import : Dsymbol
void importAll(Scope *sc);
void semantic(Scope *sc);
void semantic2(Scope *sc);
Dsymbol *toAlias();
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
int overloadInsert(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *toChars();

Import *isImport() { return this; }
};
Expand Down
14 changes: 7 additions & 7 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,14 +685,14 @@ void Module::importAll(Scope *prevsc)
*/
Scope *sc = Scope::createGlobal(this); // create root scope

// Add import of "object" if this module isn't "object"
if (ident != Id::object)
// Add import of "object", even for the "object" module.
// If it isn't there, some compiler rewrites, like
// classinst == classinst -> .object.opEquals(classinst, classinst)
// would fail inside object.d.
if (members->dim == 0 || ((*members)[0])->ident != Id::object)
{
if (members->dim == 0 || ((*members)[0])->ident != Id::object)
{
Import *im = new Import(0, NULL, Id::object, NULL, 0);
members->shift(im);
}
Import *im = new Import(0, NULL, Id::object, NULL, 0);
members->shift(im);
}

if (!symtab)
Expand Down

0 comments on commit dc5ab5c

Please sign in to comment.