forked from qt-creator/qt-creator
We need to look at the symbol's location to implement the qualified name lookup.
This commit is contained in:
@@ -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,13 +277,15 @@ 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()) {
|
||||||
break;
|
ignoreUsingDirectives = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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");
|
||||||
|
Reference in New Issue
Block a user