Improved support for private classes.

This commit is contained in:
Roberto Raggi
2009-10-12 12:00:40 +02:00
parent eacb27f1fb
commit 99c3327719
3 changed files with 69 additions and 15 deletions

View File

@@ -130,26 +130,66 @@ QList<Symbol *> LookupContext::resolveQualifiedNameId(QualifiedNameId *q,
const QList<Scope *> &visibleScopes, const QList<Scope *> &visibleScopes,
ResolveMode mode) const ResolveMode mode) const
{ {
QList<Scope *> scopes; QList<Symbol *> candidates;
if (q->nameCount() == 1) for (int i = 0; i < visibleScopes.size(); ++i) {
scopes = visibleScopes; // ### handle global scope lookup Scope *scope = visibleScopes.at(i);
else
scopes = resolveNestedNameSpecifier(q, visibleScopes);
QList<Scope *> expanded; for (Symbol *symbol = scope->lookat(q); symbol; symbol = symbol->next()) {
foreach (Scope *scope, scopes) { if (! symbol->name())
expanded.append(scope); continue;
for (unsigned i = 0; i < scope->symbolCount(); ++i) { QualifiedNameId *qq = symbol->name()->asQualifiedNameId();
Symbol *member = scope->symbolAt(i);
if (ScopedSymbol *scopedSymbol = member->asScopedSymbol()) if (! qq)
expandEnumOrAnonymousSymbol(scopedSymbol, &expanded); continue;
else if (! maybeValidSymbol(symbol, mode, candidates))
continue;
if (! q->unqualifiedNameId()->isEqualTo(qq->unqualifiedNameId()))
continue;
else if (qq->nameCount() == q->nameCount()) {
unsigned j = 0;
for (; j < q->nameCount(); ++j) {
Name *classOrNamespaceName1 = q->nameAt(j);
Name *classOrNamespaceName2 = qq->nameAt(j);
if (! classOrNamespaceName1->isEqualTo(classOrNamespaceName2))
break;
}
if (j == q->nameCount())
candidates.append(symbol);
}
} }
} }
return resolve(q->unqualifiedNameId(), expanded, mode); if (candidates.isEmpty()) {
QList<Scope *> scopes;
if (q->nameCount() == 1)
scopes = visibleScopes; // ### handle global scope lookup
else
scopes = resolveNestedNameSpecifier(q, visibleScopes);
QList<Scope *> expanded;
foreach (Scope *scope, scopes) {
expanded.append(scope);
for (unsigned i = 0; i < scope->symbolCount(); ++i) {
Symbol *member = scope->symbolAt(i);
if (ScopedSymbol *scopedSymbol = member->asScopedSymbol())
expandEnumOrAnonymousSymbol(scopedSymbol, &expanded);
}
}
candidates += resolve(q->unqualifiedNameId(), expanded, mode);
}
return candidates;
} }
QList<Symbol *> LookupContext::resolveOperatorNameId(OperatorNameId *opId, QList<Symbol *> LookupContext::resolveOperatorNameId(OperatorNameId *opId,
@@ -198,13 +238,11 @@ QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visible
else if (! maybeValidSymbol(symbol, mode, candidates)) else if (! maybeValidSymbol(symbol, mode, candidates))
continue; // skip it, we're not looking for this kind of symbols continue; // skip it, we're not looking for this kind of symbols
else if (Identifier *symbolId = symbol->identifier()) { else if (Identifier *symbolId = symbol->identifier()) {
if (! symbolId->isEqualTo(id)) if (! symbolId->isEqualTo(id))
continue; // skip it, the symbol's id is not compatible with this lookup. continue; // skip it, the symbol's id is not compatible with this lookup.
} }
if (QualifiedNameId *q = symbol->name()->asQualifiedNameId()) { if (QualifiedNameId *q = symbol->name()->asQualifiedNameId()) {
if (name->isDestructorNameId() != q->unqualifiedNameId()->isDestructorNameId()) if (name->isDestructorNameId() != q->unqualifiedNameId()->isDestructorNameId())

View File

@@ -208,6 +208,21 @@ void Scope::enterSymbol(Symbol *symbol)
} }
} }
Symbol *Scope::lookat(Name *name) const
{
if (! name)
return 0;
else if (OperatorNameId *opId = name->asOperatorNameId())
return lookat(opId->kind());
else if (Identifier *id = name->identifier())
return lookat(id);
else
return 0;
}
Symbol *Scope::lookat(Identifier *id) const Symbol *Scope::lookat(Identifier *id) const
{ {
if (! _hash || ! id) if (! _hash || ! id)

View File

@@ -129,6 +129,7 @@ public:
/// Returns the last Symbol in the scope. /// Returns the last Symbol in the scope.
iterator lastSymbol() const; iterator lastSymbol() const;
Symbol *lookat(Name *name) const;
Symbol *lookat(Identifier *id) const; Symbol *lookat(Identifier *id) const;
Symbol *lookat(int operatorId) const; Symbol *lookat(int operatorId) const;