C++: Better resolution for typedef when resolving expr.

Example:
struct Bar { int m; };
typedef Bar *pBar;
pBar b;
b-> // completes correctly now

Change-Id: I97cc67579b955fe47c68ab6c35be9a054b6d1be9
Done-by: ckamm
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
This commit is contained in:
Leandro Melo
2011-11-17 12:42:02 +01:00
parent 38d90e58d0
commit cb45971778
2 changed files with 41 additions and 5 deletions

View File

@@ -485,8 +485,6 @@ void CreateBindings::lookupInScope(const Name *name, Scope *scope,
const TemplateNameId *templateId, const TemplateNameId *templateId,
ClassOrNamespace *binding) ClassOrNamespace *binding)
{ {
Q_UNUSED(templateId);
if (! name) { if (! name) {
return; return;

View File

@@ -48,6 +48,7 @@
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QtDebug> #include <QtCore/QtDebug>
#include <QtCore/QSet>
using namespace CPlusPlus; using namespace CPlusPlus;
@@ -679,6 +680,38 @@ ClassOrNamespace *ResolveExpression::findClass(const FullySpecifiedType &origina
return binding; return binding;
} }
static void resolveTypedefs(const LookupContext &context,
FullySpecifiedType *type,
Scope **scope)
{
QSet<Symbol *> visited;
while (NamedType *namedTy = (*type)->asNamedType()) {
ClassOrNamespace *scopeCoN = context.lookupType(*scope);
if (!scopeCoN)
break;
// check if namedTy->name() resolves to a typedef
QList<LookupItem> namedTypeItems = scopeCoN->lookup(namedTy->name());
bool foundTypedef = false;
foreach (const LookupItem &it, namedTypeItems) {
if (it.declaration() && it.declaration()->isTypedef()) {
if (visited.contains(it.declaration()))
break;
visited.insert(it.declaration());
// continue working with the typedefed type and scope
*type = it.declaration()->type();
*scope = it.scope();
foundTypedef = true;
break;
}
}
if (!foundTypedef)
break;
}
}
ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &baseResults, ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &baseResults,
int accessOp, int accessOp,
bool *replacedDotOperator) const bool *replacedDotOperator) const
@@ -687,6 +720,8 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
FullySpecifiedType ty = r.type().simplified(); FullySpecifiedType ty = r.type().simplified();
Scope *scope = r.scope(); Scope *scope = r.scope();
resolveTypedefs(_context, &ty, &scope);
if (accessOp == T_ARROW) { if (accessOp == T_ARROW) {
if (PointerType *ptrTy = ty->asPointerType()) { if (PointerType *ptrTy = ty->asPointerType()) {
if (ClassOrNamespace *binding = findClass(ptrTy->elementType(), scope)) if (ClassOrNamespace *binding = findClass(ptrTy->elementType(), scope))
@@ -700,6 +735,7 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
Symbol *overload = r.declaration(); Symbol *overload = r.declaration();
if (! overload) if (! overload)
continue; continue;
Scope *functionScope = overload->enclosingScope();
if (overload->type()->isFunctionType()) { if (overload->type()->isFunctionType()) {
FullySpecifiedType overloadTy = instantiate(binding->templateId(), overload); FullySpecifiedType overloadTy = instantiate(binding->templateId(), overload);
@@ -708,11 +744,13 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
FullySpecifiedType retTy = instantiatedFunction->returnType().simplified(); FullySpecifiedType retTy = instantiatedFunction->returnType().simplified();
resolveTypedefs(_context, &retTy, &functionScope);
if (PointerType *ptrTy = retTy->asPointerType()) { if (PointerType *ptrTy = retTy->asPointerType()) {
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), overload->enclosingScope())) if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), functionScope))
return retBinding; return retBinding;
if (scope != overload->enclosingScope()) { if (scope != functionScope) {
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), scope)) if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), scope))
return retBinding; return retBinding;
} }
@@ -720,7 +758,7 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
if (ClassOrNamespace *origin = binding->instantiationOrigin()) { if (ClassOrNamespace *origin = binding->instantiationOrigin()) {
foreach (Symbol *originSymbol, origin->symbols()) { foreach (Symbol *originSymbol, origin->symbols()) {
Scope *originScope = originSymbol->asScope(); Scope *originScope = originSymbol->asScope();
if (originScope && originScope != scope && originScope != overload->enclosingScope()) { if (originScope && originScope != scope && originScope != functionScope) {
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), originScope)) if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), originScope))
return retBinding; return retBinding;
} }