Commit 19e03b18 authored by Christian Kamm's avatar Christian Kamm Committed by hjk

C++11: Correct scoping for scoped enums.

Fixes completion, highlighting and find usages.

Change-Id: I1ea12c6a9c7a4f8ba0f9d55e31d6b7986233e7d8
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent c5562000
......@@ -2965,6 +2965,8 @@ bool Bind::visit(EnumSpecifierAST *ast)
Enum *e = control()->newEnum(sourceLocation, enumName);
e->setStartOffset(tokenAt(sourceLocation).end()); // at the end of the enum or identifier token.
e->setEndOffset(tokenAt(ast->lastToken() - 1).end());
if (ast->key_token)
e->setScoped(true);
ast->symbol = e;
_scope->addMember(e);
......
......@@ -421,10 +421,12 @@ void Block::visitSymbol0(SymbolVisitor *visitor)
Enum::Enum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name)
, _isScoped(false)
{ }
Enum::Enum(Clone *clone, Subst *subst, Enum *original)
: Scope(clone, subst, original)
, _isScoped(original->isScoped())
{ }
Enum::~Enum()
......@@ -447,6 +449,16 @@ bool Enum::isEqualTo(const Type *other) const
return l->isEqualTo(r);
}
bool Enum::isScoped() const
{
return _isScoped;
}
void Enum::setScoped(bool scoped)
{
_isScoped = scoped;
}
void Enum::accept0(TypeVisitor *visitor)
{ visitor->visit(this); }
......
......@@ -279,10 +279,16 @@ public:
virtual Enum *asEnumType()
{ return this; }
bool isScoped() const;
void setScoped(bool scoped);
protected:
virtual void visitSymbol0(SymbolVisitor *visitor);
virtual void accept0(TypeVisitor *visitor);
virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const;
private:
bool _isScoped;
};
class CPLUSPLUS_EXPORT Function: public Scope, public Type
......
......@@ -83,6 +83,9 @@ static void path_helper(Symbol *symbol, QList<const Name *> *names)
} else if (symbol->isFunction()) {
if (const QualifiedNameId *q = symbol->name()->asQualifiedNameId())
addNames(q->base(), names);
} else if (Enum *e = symbol->asEnum()) {
if (e->isScoped())
addNames(symbol->name(), names);
}
}
}
......@@ -349,17 +352,10 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
if (! candidates.isEmpty())
return candidates; // it's a template parameter.
} else if (Class *klass = scope->asClass()) {
if (ClassOrNamespace *binding = bindings()->lookupType(klass)) {
candidates = binding->find(name);
if (! candidates.isEmpty())
return candidates;
}
} else if (Namespace *ns = scope->asNamespace()) {
if (ClassOrNamespace *binding = bindings()->lookupType(ns))
} else if (scope->asNamespace()
|| scope->asClass()
|| (scope->asEnum() && scope->asEnum()->isScoped())) {
if (ClassOrNamespace *binding = bindings()->lookupType(scope))
candidates = binding->find(name);
if (! candidates.isEmpty())
......@@ -419,7 +415,7 @@ QList<ClassOrNamespace *> ClassOrNamespace::usings() const
return _usings;
}
QList<Enum *> ClassOrNamespace::enums() const
QList<Enum *> ClassOrNamespace::unscopedEnums() const
{
const_cast<ClassOrNamespace *>(this)->flush();
return _enums;
......@@ -547,7 +543,7 @@ void ClassOrNamespace::lookup_helper(const Name *name, ClassOrNamespace *binding
}
}
foreach (Enum *e, binding->enums())
foreach (Enum *e, binding->unscopedEnums())
_factory->lookupInScope(name, e, result, templateId, binding);
foreach (ClassOrNamespace *u, binding->usings())
......@@ -753,7 +749,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
instantiation->_instantiationOrigin = origin;
// The instantiation should have all symbols, enums, and usings from the reference.
instantiation->_enums.append(reference->enums());
instantiation->_enums.append(reference->unscopedEnums());
instantiation->_usings.append(reference->usings());
// It gets a bit complicated if the reference is actually a class template because we
......@@ -917,7 +913,7 @@ void ClassOrNamespace::addTodo(Symbol *symbol)
_todo.append(symbol);
}
void ClassOrNamespace::addEnum(Enum *e)
void ClassOrNamespace::addUnscopedEnum(Enum *e)
{
_enums.append(e);
}
......@@ -1126,7 +1122,12 @@ bool CreateBindings::visit(ForwardClassDeclaration *klass)
bool CreateBindings::visit(Enum *e)
{
_currentClassOrNamespace->addEnum(e);
if (e->isScoped()) {
ClassOrNamespace *previous = enterClassOrNamespaceBinding(e);
_currentClassOrNamespace = previous;
} else {
_currentClassOrNamespace->addUnscopedEnum(e);
}
return false;
}
......
......@@ -90,7 +90,7 @@ public:
ClassOrNamespace *parent() const;
QList<ClassOrNamespace *> usings() const;
QList<Enum *> enums() const;
QList<Enum *> unscopedEnums() const;
QList<Symbol *> symbols() const;
ClassOrNamespace *globalNamespace() const;
......@@ -110,7 +110,7 @@ private:
void addTodo(Symbol *symbol);
void addSymbol(Symbol *symbol);
void addEnum(Enum *e);
void addUnscopedEnum(Enum *e);
void addUsing(ClassOrNamespace *u);
void addNestedType(const Name *alias, ClassOrNamespace *e);
......
......@@ -1407,10 +1407,10 @@ void CppCompletionAssistProcessor::globalCompletion(CPlusPlus::Scope *currentSco
const QList<Symbol *> symbols = currentBinding->symbols();
if (! symbols.isEmpty()) {
if (symbols.first()->isNamespace())
completeNamespace(currentBinding);
else
if (symbols.first()->isClass())
completeClass(currentBinding);
else
completeNamespace(currentBinding);
}
}
......@@ -1480,6 +1480,12 @@ bool CppCompletionAssistProcessor::completeScope(const QList<CPlusPlus::LookupIt
completeClass(b);
break;
}
} else if (Enum *e = ty->asEnumType()) {
if (ClassOrNamespace *b = context.lookupType(e)) {
completeNamespace(b);
break;
}
}
}
......@@ -1504,11 +1510,11 @@ void CppCompletionAssistProcessor::completeNamespace(CPlusPlus::ClassOrNamespace
QSet<Scope *> scopesVisited;
foreach (Symbol *bb, binding->symbols()) {
if (Namespace *ns = bb->asNamespace())
scopesToVisit.append(ns);
if (Scope *scope = bb->asScope())
scopesToVisit.append(scope);
}
foreach (Enum *e, binding->enums()) {
foreach (Enum *e, binding->unscopedEnums()) {
scopesToVisit.append(e);
}
......@@ -1549,7 +1555,7 @@ void CppCompletionAssistProcessor::completeClass(CPlusPlus::ClassOrNamespace *b,
scopesToVisit.append(k);
}
foreach (Enum *e, binding->enums())
foreach (Enum *e, binding->unscopedEnums())
scopesToVisit.append(e);
while (! scopesToVisit.isEmpty()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment