diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 7ce0e42c69df9f16ca6f23b346c78bf98620e9b5..1f4dc9c51af0b2d947e5b3dd8d181f859486c5a7 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -792,3 +792,69 @@ bool ResolveExpression::visit(PostIncrDecrAST *)
 {
     return false;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+QList<Symbol *> SymbolsForDotAccess::operator()(NamedType *namedTy,
+                                                ResolveExpression::Result p,
+                                                const LookupContext &context)
+{
+    QList<Symbol *> resolvedSymbols;
+
+    if (_blackList.contains(p))
+        return resolvedSymbols;
+
+    _blackList.append(p);
+
+    const QList<Symbol *> candidates =
+            context.resolve(namedTy->name(), context.visibleScopes(p));
+
+    foreach (Symbol *candidate, candidates) {
+        if (Class *klass = candidate->asClass()) {
+            if (resolvedSymbols.contains(klass))
+                continue; // we already know about `klass'
+            resolvedSymbols.append(klass);
+        } else if (candidate->isTypedef()) {
+            if (Declaration *decl = candidate->asDeclaration()) {
+                if (Class *asClass = decl->type()->asClass()) {
+                    // typedef struct { } Point;
+                    // Point pt;
+                    // pt.
+                    resolvedSymbols.append(asClass);
+                } else {
+                    // typedef Point Boh;
+                    // Boh b;
+                    // b.
+                    const ResolveExpression::Result r(decl->type(), decl);
+                    resolvedSymbols += operator()(r, context);
+                }
+            }
+        } else if (Declaration *decl = candidate->asDeclaration()) {
+            if (Function *funTy = decl->type()->asFunction()) {
+                // QString foo("ciao");
+                // foo.
+                if (funTy->scope()->isBlockScope() || funTy->scope()->isNamespaceScope()) {
+                    const ResolveExpression::Result r(funTy->returnType(), decl);
+                    resolvedSymbols += operator()(r, context);
+                }
+            }
+        }
+    }
+
+    return resolvedSymbols;
+}
+
+QList<Symbol *> SymbolsForDotAccess::operator()(ResolveExpression::Result p,
+                                                const LookupContext &context)
+{
+    FullySpecifiedType ty = p.first;
+
+    if (NamedType *namedTy = ty->asNamedType()) {
+        return operator()(namedTy, p, context);
+    } else if (ReferenceType *refTy = ty->asReferenceType()) {
+        const ResolveExpression::Result e(refTy->elementType(), p.second);
+        return operator()(e, context);
+    }
+
+    return QList<Symbol *>();
+}
+
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index ac4a675b459818e493a4b95be0a25be2b8c41a84..35a32c84655e604503d8ba53657353a81fa26e09 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -128,6 +128,20 @@ private:
     QList<Result> _results;
 };
 
+class CPLUSPLUS_EXPORT SymbolsForDotAccess
+{
+    QList<ResolveExpression::Result> _blackList;
+
+public:
+    QList<Symbol *> operator()(NamedType *namedTy,
+                               ResolveExpression::Result p,
+                               const LookupContext &context);
+
+    QList<Symbol *> operator()(ResolveExpression::Result p,
+                               const LookupContext &context);
+};
+
+
 } // end of namespace CPlusPlus
 
 #endif // CPLUSPLUS_RESOLVEEXPRESSION_H
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index f8c5fe9b48ad3493c9e9728e79720ac6df5f57f1..075a55b96e96008767490956b909c33345f911f4 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -180,8 +180,6 @@ protected:
 } // namespace Internal
 } // namespace CppTools
 
-
-
 using namespace CppTools::Internal;
 
 FunctionArgumentWidget::FunctionArgumentWidget(Core::ICore *core)
@@ -581,12 +579,12 @@ bool CppCodeCompletion::completeMember(FullySpecifiedType,
                                        const QList<TypeOfExpression::Result> &results,
                                        const LookupContext &context)
 {
-    QTC_ASSERT(!results.isEmpty(), return false);
+    if (results.isEmpty())
+        return false;
 
+    const TypeOfExpression::Result p = results.first();
     QList<Symbol *> classObjectCandidates;
 
-    TypeOfExpression::Result p = results.first();
-
     if (m_completionOperator == T_ARROW)  {
         FullySpecifiedType ty = p.first;
 
@@ -666,13 +664,13 @@ bool CppCodeCompletion::completeMember(FullySpecifiedType,
         }
 
         if (namedTy) {
-            const QList<Symbol *> classes =
-                    context.resolveClass(namedTy->name(),
-                                         context.visibleScopes(p));
-
-            foreach (Symbol *c, classes) {
-                if (! classObjectCandidates.contains(c))
-                    classObjectCandidates.append(c);
+            SymbolsForDotAccess symbolsForDotAccess;
+            const QList<Symbol *> symbols = symbolsForDotAccess(namedTy, p, context);
+            foreach (Symbol *symbol, symbols) {
+                if (classObjectCandidates.contains(symbol))
+                    continue;
+                if (Class *klass = symbol->asClass())
+                    classObjectCandidates.append(klass);
             }
         }
     }