We need to look at the symbol's location to implement the qualified name lookup.

This commit is contained in:
Roberto Raggi
2009-02-19 18:26:10 +01:00
parent b7507d7e3d
commit 47f27ee7f5

View File

@@ -57,6 +57,40 @@
// NamespaceBinding // NamespaceBinding
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class Location
{
public:
Location()
: _fileId(0),
_sourceLocation(0)
{ }
Location(Symbol *symbol)
: _fileId(symbol->fileId()),
_sourceLocation(symbol->sourceLocation())
{ }
Location(StringLiteral *fileId, unsigned sourceLocation)
: _fileId(fileId), _sourceLocation(sourceLocation)
{ }
inline bool isValid() const
{ return _fileId != 0; }
inline operator bool() const
{ return _fileId != 0; }
inline StringLiteral *fileId() const
{ return _fileId; }
inline unsigned sourceLocation() const
{ return _sourceLocation; }
private:
StringLiteral *_fileId;
unsigned _sourceLocation;
};
class NamespaceBinding class NamespaceBinding
{ {
public: public:
@@ -81,10 +115,9 @@ public:
/// Returns the binding associated with the given symbol. /// Returns the binding associated with the given symbol.
NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol); NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol);
NamespaceBinding *resolveNamespace(QualifiedNameId *q, unsigned index, NamespaceBinding *resolveNamespace(const Location &loc,
unsigned count); Name *name,
bool lookAtParent = true);
NamespaceBinding *resolveNamespace(Name *name, bool lookAtParent = true);
/// Helpers. /// Helpers.
std::string qualifiedId() const; std::string qualifiedId() const;
@@ -103,7 +136,7 @@ public: // attributes
/// This binding's connections. /// This binding's connections.
Array<NamespaceBinding *> children; Array<NamespaceBinding *> children;
/// This binding's usings /// This binding's list of using namespaces.
Array<NamespaceBinding *> usings; Array<NamespaceBinding *> usings;
/// This binding's namespace symbols. /// This binding's namespace symbols.
@@ -221,7 +254,8 @@ NamespaceBinding *NamespaceBinding::findOrCreateNamespaceBinding(Namespace *symb
return binding; return binding;
} }
static void closure(NamespaceBinding *binding, Name *name, static void closure(const Location &loc,
NamespaceBinding *binding, Name *name,
Array<NamespaceBinding *> *bindings) Array<NamespaceBinding *> *bindings)
{ {
for (unsigned i = 0; i < bindings->size(); ++i) { for (unsigned i = 0; i < bindings->size(); ++i) {
@@ -243,15 +277,17 @@ static void closure(NamespaceBinding *binding, Name *name,
Scope *scope = symbol->members(); Scope *scope = symbol->members();
for (Symbol *symbol = scope->lookat(id); symbol; symbol = symbol->next()) { for (Symbol *symbol = scope->lookat(id); symbol; symbol = symbol->next()) {
if (symbol->isUsingDeclaration() || symbol->isUsingNamespaceDirective()) if (! symbol->isNamespace())
continue; continue;
//printf("found declaration at %s:%d\n", symbol->fileName(), symbol->line()); const Location l(symbol);
// ### FIXME: ignoreUsingDirectives = true; if (l.fileId() == loc.fileId() && l.sourceLocation() < loc.sourceLocation()) {
ignoreUsingDirectives = true;
break; break;
} }
} }
}
if (ignoreUsingDirectives) if (ignoreUsingDirectives)
return; return;
@@ -259,19 +295,21 @@ static void closure(NamespaceBinding *binding, Name *name,
for (unsigned i = 0; i < binding->usings.size(); ++i) { for (unsigned i = 0; i < binding->usings.size(); ++i) {
NamespaceBinding *u = binding->usings.at(i); NamespaceBinding *u = binding->usings.at(i);
closure(u, name, bindings); closure(loc, u, name, bindings);
} }
} }
NamespaceBinding *NamespaceBinding::resolveNamespace(Name *name, bool lookAtParent) NamespaceBinding *NamespaceBinding::resolveNamespace(const Location &loc,
Name *name,
bool lookAtParent)
{ {
if (! name) if (! name)
return 0; return 0;
else if (NameId *nameId = name->asNameId()) { else if (NameId *nameId = name->asNameId()) {
Array<NamespaceBinding *> bindings; Array<NamespaceBinding *> bindings;
closure(this, nameId, &bindings); closure(loc, this, nameId, &bindings);
Array<NamespaceBinding *> results; Array<NamespaceBinding *> results;
@@ -291,22 +329,22 @@ NamespaceBinding *NamespaceBinding::resolveNamespace(Name *name, bool lookAtPare
} }
else if (parent && lookAtParent) else if (parent && lookAtParent)
return parent->resolveNamespace(name); return parent->resolveNamespace(loc, name);
} else if (QualifiedNameId *q = name->asQualifiedNameId()) { } else if (QualifiedNameId *q = name->asQualifiedNameId()) {
if (q->nameCount() == 1) { if (q->nameCount() == 1) {
assert(q->isGlobal()); assert(q->isGlobal());
return globalNamespaceBinding()->resolveNamespace(q->nameAt(0)); return globalNamespaceBinding()->resolveNamespace(loc, q->nameAt(0));
} }
NamespaceBinding *current = this; NamespaceBinding *current = this;
if (q->isGlobal()) if (q->isGlobal())
current = globalNamespaceBinding(); current = globalNamespaceBinding();
current = current->resolveNamespace(q->nameAt(0)); current = current->resolveNamespace(loc, q->nameAt(0));
for (unsigned i = 1; current && i < q->nameCount(); ++i) for (unsigned i = 1; current && i < q->nameCount(); ++i)
current = current->resolveNamespace(q->nameAt(i), false); current = current->resolveNamespace(loc, q->nameAt(i), false);
return current; return current;
} }
@@ -370,7 +408,7 @@ public:
protected: protected:
NamespaceBinding *bind(Symbol *symbol, NamespaceBinding *binding); NamespaceBinding *bind(Symbol *symbol, NamespaceBinding *binding);
NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol); NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol);
NamespaceBinding *resolveNamespace(Name *name); NamespaceBinding *resolveNamespace(const Location &loc, Name *name);
NamespaceBinding *switchNamespaceBinding(NamespaceBinding *binding); NamespaceBinding *switchNamespaceBinding(NamespaceBinding *binding);
@@ -412,12 +450,12 @@ NamespaceBinding *Binder::findOrCreateNamespaceBinding(Namespace *symbol)
return namespaceBinding; return namespaceBinding;
} }
NamespaceBinding *Binder::resolveNamespace(Name *name) NamespaceBinding *Binder::resolveNamespace(const Location &loc, Name *name)
{ {
if (! namespaceBinding) if (! namespaceBinding)
return 0; return 0;
return namespaceBinding->resolveNamespace(name); return namespaceBinding->resolveNamespace(loc, name);
} }
@@ -443,7 +481,7 @@ bool Binder::visit(Namespace *symbol)
bool Binder::visit(UsingNamespaceDirective *u) bool Binder::visit(UsingNamespaceDirective *u)
{ {
NamespaceBinding *resolved = resolveNamespace(u->name()); NamespaceBinding *resolved = resolveNamespace(Location(u), u->name());
if (! resolved) { if (! resolved) {
unit->error(u->sourceLocation(), "expected namespace-name"); unit->error(u->sourceLocation(), "expected namespace-name");