Skip to content
Snippets Groups Projects
Commit b7820022 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Warn for undefined namespaces in using namespace directives.

parent 19dd2b81
No related branches found
No related tags found
No related merge requests found
......@@ -567,6 +567,32 @@ bool Binder::visit(Block *)
} // end of anonymous namespace
static NamespaceBinding *find_helper(Namespace *symbol, NamespaceBinding *binding,
QSet<QByteArray> *processed)
{
const QByteArray id = binding->qualifiedId();
if (! processed->contains(id)) {
processed->insert(id);
if (binding->symbols.contains(symbol))
return binding;
foreach (NamespaceBinding *nestedBinding, binding->children) {
if (NamespaceBinding *ns = find_helper(symbol, nestedBinding, processed))
return ns;
}
}
return 0;
}
NamespaceBinding *NamespaceBinding::find(Namespace *symbol, NamespaceBinding *binding)
{
QSet<QByteArray> processed;
return find_helper(symbol, binding, &processed);
}
NamespaceBindingPtr CPlusPlus::bind(Document::Ptr doc, Snapshot snapshot)
{
NamespaceBindingPtr global(new NamespaceBinding());
......
......@@ -118,6 +118,8 @@ public:
virtual NamespaceBinding *asNamespaceBinding() { return this; }
static NamespaceBinding *find(Namespace *symbol, NamespaceBinding *binding);
private:
NamespaceBinding *findNamespaceBindingForNameId(NameId *name);
......
......@@ -252,13 +252,16 @@ namespace {
class Process;
class CheckUndefinedBaseClasses: protected ASTVisitor
class CheckUndefinedSymbols: protected ASTVisitor
{
public:
CheckUndefinedBaseClasses(Control *control)
: ASTVisitor(control), _context(0)
CheckUndefinedSymbols(Document::Ptr doc)
: ASTVisitor(doc->control()), _process(0), _doc(doc)
{ }
void setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding)
{ _globalNamespaceBinding = globalNamespaceBinding; }
void operator()(AST *ast, Process *process)
{ _process = process; accept(ast); }
......@@ -290,6 +293,26 @@ protected:
"expected class-name %s token", token);
}
}
return true;
}
virtual bool visit(UsingDirectiveAST *ast)
{
if (ast->name && ast->name->name && _globalNamespaceBinding) {
const Location loc = Location(ast->symbol);
NamespaceBinding *binding = _globalNamespaceBinding.data();
if (Scope *enclosingNamespaceScope = ast->symbol->enclosingNamespaceScope())
binding = NamespaceBinding::find(enclosingNamespaceScope->owner()->asNamespace(), binding);
if (! binding || ! binding->resolveNamespace(loc, ast->name->name)) {
translationUnit()->warning(ast->name->firstToken(),
"expected a namespace after `=' token");
}
}
return true;
}
......@@ -297,7 +320,9 @@ protected:
private:
Process *_process;
Document::Ptr _doc;
LookupContext _context;
NamespaceBindingPtr _globalNamespaceBinding;
};
class Process: public std::unary_function<Document::Ptr, void>
......@@ -334,12 +359,12 @@ public:
if (_workingCopy.contains(doc->fileName())) {
// run the binding pass
NamespaceBindingPtr ns = bind(doc, _snapshot);
Q_UNUSED(ns);
// check for undefined symbols.
CheckUndefinedSymbols checkUndefinedSymbols(doc);
checkUndefinedSymbols.setGlobalNamespaceBinding(ns);
CheckUndefinedBaseClasses checkUndefinedBaseClasses(doc->control());
checkUndefinedBaseClasses(doc->translationUnit()->ast(), this);
checkUndefinedSymbols(doc->translationUnit()->ast(), this);
}
doc->releaseTranslationUnit();
......@@ -349,7 +374,7 @@ public:
}
};
LookupContext CheckUndefinedBaseClasses::lookupContext(unsigned line, unsigned column) const
LookupContext CheckUndefinedSymbols::lookupContext(unsigned line, unsigned column) const
{ return _process->lookupContext(line, column); }
} // end of anonymous namespace
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment