diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 83082853176b5c917ea8a5cd26b1b247e56ce588..31ff8a00865e3fe28fab0bb526b0bb35180d4db8 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -623,141 +623,175 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
         memberName = ast->member_name->name;
 
     // Remember the access operator.
-    const unsigned accessOp = tokenKind(ast->access_token);
+    const int accessOp = tokenKind(ast->access_token);
 
     _results = resolveMemberExpression(baseResults, accessOp, memberName);
 
     return false;
 }
 
-QList<ResolveExpression::Result>
-ResolveExpression::resolveMemberExpression(const QList<Result> &baseResults,
-                                           unsigned accessOp,
-                                           Name *memberName) const
+QList<Symbol *> ResolveExpression::resolveBaseExpression(const QList<Result> &baseResults, int accessOp) const
 {
-    ResolveClass resolveClass;
-    QList<Result> results;
+    QList<Symbol *> classObjectCandidates;
 
-    if (accessOp == T_ARROW) {
-        foreach (Result p, baseResults) {
-            FullySpecifiedType ty = p.first;
+    if (baseResults.isEmpty())
+        return classObjectCandidates;
 
-            if (ReferenceType *refTy = ty->asReferenceType())
-                ty = refTy->elementType();
+    Result result = baseResults.first();
 
-            if (NamedType *namedTy = ty->asNamedType()) {
-                resolveClass.setPointerAccess(true);
-                QList<Symbol *> classObjectCandidates = resolveClass(namedTy, p, _context);
+    if (accessOp == T_ARROW)  {
+        FullySpecifiedType ty = result.first.simplified();
 
-                foreach (Symbol *classObject, classObjectCandidates) {
-                    results += resolveMember(p, memberName,
-                                             control()->namedType(classObject->name()), // ### remove the call to namedType
-                                             classObject->asClass());
+        if (Class *classTy = ty->asClassType()) {
+            Symbol *symbol = result.second;
+            if (symbol && ! symbol->isClass())
+                classObjectCandidates.append(classTy);
+        } else if (NamedType *namedTy = ty->asNamedType()) {
+            // ### This code is pretty slow.
+            const QList<Symbol *> candidates = _context.resolve(namedTy->name());
+            foreach (Symbol *candidate, candidates) {
+                if (candidate->isTypedef()) {
+                    ty = candidate->type();
+                    const ResolveExpression::Result r(ty, candidate);
+                    result = r;
+                    break;
                 }
+            }
+        }
+
+        if (NamedType *namedTy = ty->asNamedType()) {
+            ResolveClass resolveClass;
 
-                if (classObjectCandidates.isEmpty()) {
-                    resolveClass.setPointerAccess(false);
-                    classObjectCandidates = resolveClass(namedTy, p, _context);
+            const QList<Symbol *> candidates = resolveClass(result, _context);
+            foreach (Symbol *classObject, candidates) {
+                const QList<Result> overloads = resolveArrowOperator(result, namedTy,
+                                                                     classObject->asClass());
 
-                    foreach (Symbol *classObject, classObjectCandidates) {
-                        const QList<Result> overloads = resolveArrowOperator(p, namedTy,
-                                                                             classObject->asClass());
-                        foreach (Result r, overloads) {
-                            FullySpecifiedType ty = r.first;
-                            Function *funTy = ty->asFunctionType();
-                            if (! funTy)
-                                continue;
+                foreach (Result r, overloads) {
+                    FullySpecifiedType ty = r.first;
+                    Function *funTy = ty->asFunctionType();
+                    if (! funTy)
+                        continue;
 
-                            ty = funTy->returnType();
+                    ty = funTy->returnType().simplified();
 
-                            if (ReferenceType *refTy = ty->asReferenceType())
-                                ty = refTy->elementType();
+                    if (PointerType *ptrTy = ty->asPointerType()) {
+                        if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
+                            const QList<Symbol *> classes =
+                                    resolveClass(namedTy, result, _context);
 
-                            if (PointerType *ptrTy = ty->asPointerType()) {
-                                if (NamedType *namedTy = ptrTy->elementType()->asNamedType())
-                                    results += resolveMember(r, memberName, namedTy);
+                            foreach (Symbol *c, classes) {
+                                if (! classObjectCandidates.contains(c))
+                                    classObjectCandidates.append(c);
                             }
                         }
                     }
                 }
-            } else if (PointerType *ptrTy = ty->asPointerType()) {
-                if (NamedType *namedTy = ptrTy->elementType()->asNamedType())
-                    results += resolveMember(p, memberName, namedTy);
             }
-        }
-    } else if (accessOp == T_DOT) {
-        // The base expression shall be a "class object" of a complete type.
-        foreach (Result p, baseResults) {
-            FullySpecifiedType ty = p.first;
+        } else if (PointerType *ptrTy = ty->asPointerType()) {
+            if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
+                ResolveClass resolveClass;
 
-            if (ReferenceType *refTy = ty->asReferenceType())
-                ty = refTy->elementType();
+                const QList<Symbol *> classes = resolveClass(namedTy, result,
+                                                             _context);
 
-            if (NamedType *namedTy = ty->asNamedType())
-                results += resolveMember(p, memberName, namedTy);
-            else if (Function *fun = ty->asFunctionType()) {
-                if (fun->scope() && (fun->scope()->isBlockScope() || fun->scope()->isNamespaceScope())) {
-                    ty = fun->returnType();
-
-                    if (ReferenceType *refTy = ty->asReferenceType())
-                        ty = refTy->elementType();
-
-                    if (NamedType *namedTy = ty->asNamedType())
-                        results += resolveMember(p, memberName, namedTy);
+                foreach (Symbol *c, classes) {
+                    if (! classObjectCandidates.contains(c))
+                        classObjectCandidates.append(c);
                 }
+            } else if (Class *classTy = ptrTy->elementType()->asClassType()) {
+                // typedef struct { int x } *Ptr;
+                // Ptr p;
+                // p->
+                classObjectCandidates.append(classTy);
+            }
+        }
+    } else if (accessOp == T_DOT) {
+        FullySpecifiedType ty = result.first.simplified();
+
+        NamedType *namedTy = 0;
+
+        if (Class *classTy = ty->asClassType()) {
+            Symbol *symbol = result.second;
+            if (symbol && ! symbol->isClass())
+                classObjectCandidates.append(classTy);
+        } else {
+            namedTy = ty->asNamedType();
+            if (! namedTy) {
+                Function *fun = ty->asFunctionType();
+                if (fun && fun->scope() && (fun->scope()->isBlockScope() || fun->scope()->isNamespaceScope()))
+                    namedTy = fun->returnType()->asNamedType();
             }
+        }
 
+        if (namedTy) {
+            ResolveClass resolveClass;
+            const QList<Symbol *> symbols = resolveClass(namedTy, result,
+                                                         _context);
+            foreach (Symbol *symbol, symbols) {
+                if (classObjectCandidates.contains(symbol))
+                    continue;
+                if (Class *klass = symbol->asClass())
+                    classObjectCandidates.append(klass);
+            }
         }
     }
 
-    return results;
+    return classObjectCandidates;
 }
 
 QList<ResolveExpression::Result>
-ResolveExpression::resolveMember(const Result &p,
-                                 Name *memberName,
-                                 NamedType *namedTy) const
+ResolveExpression::resolveMemberExpression(const QList<Result> &baseResults,
+                                           unsigned accessOp,
+                                           Name *memberName) const
 {
-    ResolveClass resolveClass;
+    QList<Result> results;
 
-    const QList<Symbol *> classObjectCandidates =
-            resolveClass(namedTy, p, _context);
+    const QList<Symbol *> classObjectCandidates = resolveBaseExpression(baseResults, accessOp);
+    foreach (Symbol *candidate, classObjectCandidates) {
+        Class *klass = candidate->asClass();
+        if (! klass)
+            continue;
 
-    QList<Result> results;
-    foreach (Symbol *classObject, classObjectCandidates) {
-        results += resolveMember(p, memberName, namedTy,
-                                 classObject->asClass());
+        results += resolveMember(memberName, klass);
     }
+
     return results;
 }
 
 QList<ResolveExpression::Result>
-ResolveExpression::resolveMember(const Result &,
-                                 Name *memberName,
-                                 NamedType *namedTy,
-                                 Class *klass) const
+ResolveExpression::resolveMember(Name *memberName, Class *klass) const
 {
+    QList<Result> results;
+
     QList<Scope *> scopes;
     _context.expand(klass->members(), _context.visibleScopes(), &scopes);
-    QList<Result> results;
 
     QList<Symbol *> candidates = _context.resolve(memberName, scopes);
+
     foreach (Symbol *candidate, candidates) {
         FullySpecifiedType ty = candidate->type();
-        Name *unqualifiedNameId = namedTy->name();
-        if (QualifiedNameId *q = namedTy->name()->asQualifiedNameId())
-            unqualifiedNameId = q->unqualifiedNameId();
-        if (TemplateNameId *templId = unqualifiedNameId->asTemplateNameId()) {
-            Substitution subst;
-            for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
-                FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
-                if (i < klass->templateParameterCount()) {
-                    subst.append(qMakePair(klass->templateParameterAt(i)->name(),
-                                           templArgTy));
+
+        if (Name *className = klass->name()) {
+            Name *unqualifiedNameId = className;
+
+            if (QualifiedNameId *q = className->asQualifiedNameId())
+                unqualifiedNameId = q->unqualifiedNameId();
+
+            if (TemplateNameId *templId = unqualifiedNameId->asTemplateNameId()) {
+                Substitution subst;
+
+                for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
+                    FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
+
+                    if (i < klass->templateParameterCount())
+                        subst.append(qMakePair(klass->templateParameterAt(i)->name(),
+                                               templArgTy));
                 }
+
+                Instantiation inst(control(), subst);
+                ty = inst(ty);
             }
-            Instantiation inst(control(), subst);
-            ty = inst(ty);
         }
 
         const Result result(ty, candidate);
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index f548e9a15c5f976f5886c088200a5ce661876f84..71289ef34320fec21ff59e56867daa8ff9a1d106 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -53,14 +53,7 @@ public:
                                           unsigned accessOp,
                                           Name *memberName) const;
 
-    QList<Result> resolveMember(const Result &result,
-                                Name *memberName,
-                                NamedType *namedTy) const;
-
-    QList<Result> resolveMember(const Result &result,
-                                Name *memberName,
-                                NamedType *namedTy,
-                                Class *klass) const;
+    QList<Result> resolveMember(Name *memberName, Class *klass) const;
 
     QList<Result> resolveArrowOperator(const Result &result,
                                        NamedType *namedTy,
@@ -70,6 +63,10 @@ public:
                                        NamedType *namedTy,
                                        Class *klass) const;
 
+
+    QList<Symbol *> resolveBaseExpression(const QList<Result> &baseResults,
+                                          int accessOp) const;
+
 protected:
     QList<Result> switchResults(const QList<Result> &symbols);