diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp
index 46177f1d51448755621ecec9d24be481929612dc..9f2f2b3f2ca19cee68a86b3e729d2d9824d588c6 100644
--- a/src/plugins/cpptools/cppfindreferences.cpp
+++ b/src/plugins/cpptools/cppfindreferences.cpp
@@ -204,71 +204,127 @@ protected:
 
     virtual bool visit(MemberAccessAST *ast)
     {
-        if (! ast->member_name)
-            return false;
-
-        SimpleNameAST *simple = ast->member_name->asSimpleName();
-        if (! simple)
-            return true; // ### TODO handle pseudo-destructors and qualified names.
+        if (ast->member_name) {
+            if (SimpleNameAST *simple = ast->member_name->asSimpleName()) {
+                if (identifier(simple->identifier_token) == _id) {
+                    Q_ASSERT(! _postfixExpressionStack.isEmpty());
 
-        Q_ASSERT(! _postfixExpressionStack.isEmpty());
+                    checkExpression(_postfixExpressionStack.last()->firstToken(),
+                                    simple->identifier_token);
 
-        if (identifier(simple->identifier_token) == _id) {
-            unsigned startOfPostfixExpression = _postfixExpressionStack.last()->firstToken();
+                    return false;
+                }
+            }
+        }
 
-            unsigned begin = tokenAt(startOfPostfixExpression).begin();
-            unsigned end = tokenAt(ast->member_name->lastToken() - 1).end();
+        return true;
+    }
 
-            const QString expression = _source.mid(begin, end - begin);
-            // qDebug() << "*** expression:" << expression;
+    void checkExpression(unsigned startToken, unsigned endToken)
+    {
+        const unsigned begin = tokenAt(startToken).begin();
+        const unsigned end = tokenAt(endToken).end();
 
-            TypeOfExpression typeofExpression;
-            typeofExpression.setSnapshot(_snapshot);
+        const QString expression = _source.mid(begin, end - begin);
+        // qDebug() << "*** expression:" << expression;
 
-            unsigned line, column;
-            getTokenStartPosition(startOfPostfixExpression, &line, &column);
-            Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
+        TypeOfExpression typeofExpression;
+        typeofExpression.setSnapshot(_snapshot);
 
-            const QList<TypeOfExpression::Result> results =
-                    typeofExpression(expression, _doc, lastVisibleSymbol,
-                                     TypeOfExpression::NoPreprocess);
+        unsigned line, column;
+        getTokenStartPosition(startToken, &line, &column);
+        Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
 
-            QList<Symbol *> candidates;
+        const QList<TypeOfExpression::Result> results =
+                typeofExpression(expression, _doc, lastVisibleSymbol,
+                                 TypeOfExpression::NoPreprocess);
 
-            foreach (TypeOfExpression::Result r, results) {
-                FullySpecifiedType ty = r.first;
-                Symbol *lastVisibleSymbol = r.second;
+        QList<Symbol *> candidates;
 
-                candidates.append(lastVisibleSymbol);
-            }
+        foreach (TypeOfExpression::Result r, results) {
+            FullySpecifiedType ty = r.first;
+            Symbol *lastVisibleSymbol = r.second;
 
-            if (checkCandidates(candidates))
-                reportResult(simple->identifier_token);
+            candidates.append(lastVisibleSymbol);
         }
 
-        return false;
+        if (checkCandidates(candidates))
+            reportResult(endToken);
     }
 
     virtual bool visit(QualifiedNameAST *ast)
     {
-        if (! ast->name) {
-            //qWarning() << "invalid AST at" << _doc->fileName() << line << column;
-            ast->name = _sem.check(ast, /*scope */ static_cast<Scope *>(0));
+        for (NestedNameSpecifierAST *nested_name_specifier = ast->nested_name_specifier;
+             nested_name_specifier; nested_name_specifier = nested_name_specifier->next) {
+
+            if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
+                SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName();
+
+                TemplateIdAST *template_id = 0;
+                if (! simple_name) {
+                    template_id = class_or_namespace_name->asTemplateId();
+
+                    if (template_id) {
+                        for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
+                             template_arguments; template_arguments = template_arguments->next) {
+                            accept(template_arguments->template_argument);
+                        }
+                    }
+                }
+
+                if (simple_name || template_id) {
+                    const unsigned identifier_token = simple_name
+                               ? simple_name->identifier_token
+                               : template_id->identifier_token;
+
+                    if (identifier(identifier_token) == _id)
+                        checkExpression(ast->firstToken(), identifier_token);
+                }
+            }
+        }
+
+        if (ast->unqualified_name) {
+            SimpleNameAST *simple_name = ast->unqualified_name->asSimpleName();
+
+            TemplateIdAST *template_id = 0;
+            if (! simple_name) {
+                template_id = ast->unqualified_name->asTemplateId();
+
+                if (template_id) {
+                    for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
+                         template_arguments; template_arguments = template_arguments->next) {
+                        accept(template_arguments->template_argument);
+                    }
+                }
+            }
+
+            if (simple_name || template_id) {
+                const unsigned identifier_token = simple_name
+                        ? simple_name->identifier_token
+                        : template_id->identifier_token;
+
+                if (identifier(identifier_token) == _id)
+                    checkExpression(ast->firstToken(), identifier_token);
+            }
         }
 
-        Q_ASSERT(ast->name != 0);
-        Identifier *id = ast->name->identifier();
-        if (id == _id && ast->unqualified_name) {
+        return false;
+    }
+
+    virtual bool visit(SimpleNameAST *ast)
+    {
+        Identifier *id = identifier(ast->identifier_token);
+        if (id == _id) {
             LookupContext context = currentContext(ast);
             const QList<Symbol *> candidates = context.resolve(ast->name);
             if (checkCandidates(candidates))
-                reportResult(ast->unqualified_name->firstToken());
+                reportResult(ast->identifier_token);
         }
 
         return false;
     }
 
-    virtual bool visit(SimpleNameAST *ast)
+    virtual bool visit(DestructorNameAST *ast)
     {
         Identifier *id = identifier(ast->identifier_token);
         if (id == _id) {
@@ -304,6 +360,7 @@ private:
     Document::Ptr _exprDoc;
     Semantic _sem;
     QList<PostfixExpressionAST *> _postfixExpressionStack;
+    QList<QualifiedNameAST *> _qualifiedNameStack;
 };
 
 } // end of anonymous namespace