diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index c45f86834c2bc75a20c45bdbde869fa7b06faff8..8702f9e4960ab89e047ff55dbf8179bba58d5094 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -861,11 +861,30 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
     return canonicalSymbol;
 }
 
+const Macro *CPPEditor::findCanonicalMacro(const QTextCursor &cursor,
+                                                  Document::Ptr doc) const
+{
+    if (! doc)
+        return 0;
+
+    int line, col;
+    convertPosition(cursor.position(), &line, &col);
+
+    if (const Macro *macro = doc->findMacroDefinitionAt(line))
+        return macro;
+
+    if (const Document::MacroUse *use = doc->findMacroUseAt(cursor.position()))
+        return &use->macro();
+
+    return 0;
+}
 
 void CPPEditor::findUsages()
 {    
     if (Symbol *canonicalSymbol = markSymbols()) {
         m_modelManager->findUsages(canonicalSymbol);
+    } else if (const Macro *macro = findCanonicalMacro(textCursor(), m_lastSemanticInfo.doc)) {
+        m_modelManager->findMacroUsages(*macro);
     }
 }
 
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index b7ac5512cf657a3a604f1e8aca40c0510ca2c870..38f14c141a919df23f8cdb66e73bd471f3b194f8 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -227,6 +227,8 @@ protected:
     CPlusPlus::Symbol *findCanonicalSymbol(const QTextCursor &cursor,
                                            CPlusPlus::Document::Ptr doc,
                                            const CPlusPlus::Snapshot &snapshot) const;
+    const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
+                                               CPlusPlus::Document::Ptr doc) const;
 
 private Q_SLOTS:
     void updateFileName();
diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp
index 60efaf7784ad8d773dc0c053261b2afb80330a6b..699e7b72c3912cd3a1aee9ab77575ac07aaf844e 100644
--- a/src/plugins/cpptools/cppfindreferences.cpp
+++ b/src/plugins/cpptools/cppfindreferences.cpp
@@ -65,6 +65,20 @@
 using namespace CppTools::Internal;
 using namespace CPlusPlus;
 
+static QString getSource(const QString &fileName,
+                         const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy)
+{
+    if (workingCopy.contains(fileName)) {
+        return workingCopy.source(fileName);
+    } else {
+        QFile file(fileName);
+        if (! file.open(QFile::ReadOnly))
+            return QString();
+
+        return QTextStream(&file).readAll(); // ### FIXME
+    }
+}
+
 namespace {
 
 class ProcessFile: public std::unary_function<QString, QList<Usage> >
@@ -91,18 +105,8 @@ public:
                 return usages; // skip this document, it's not using symbolId.
         }
 
-        QByteArray source;
-
-        if (workingCopy.contains(fileName))
-            source = snapshot.preprocessedCode(workingCopy.source(fileName), fileName);
-        else {
-            QFile file(fileName);
-            if (! file.open(QFile::ReadOnly))
-                return usages;
-
-            const QString contents = QTextStream(&file).readAll(); // ### FIXME
-            source = snapshot.preprocessedCode(contents, fileName);
-        }
+        QByteArray source = snapshot.preprocessedCode(
+                getSource(fileName, workingCopy), fileName);
 
         Document::Ptr doc = snapshot.documentFromSource(source, fileName);
         doc->tokenize();
@@ -294,3 +298,123 @@ void CppFindReferences::openEditor(const Find::SearchResultItem &item)
     TextEditor::BaseTextEditor::openEditorAt(item.fileName, item.lineNumber, item.searchTermStart);
 }
 
+
+namespace {
+
+class FindMacroUsesInFile: public std::unary_function<QString, QList<Usage> >
+{
+    const CppTools::CppModelManagerInterface::WorkingCopy workingCopy;
+    const Snapshot snapshot;
+    const Macro &macro;
+
+public:
+    FindMacroUsesInFile(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy,
+                        const Snapshot snapshot,
+                        const Macro &macro)
+        : workingCopy(workingCopy), snapshot(snapshot), macro(macro)
+    { }
+
+    QList<Usage> operator()(const QString &fileName)
+    {
+        QList<Usage> usages;
+
+        const Document::Ptr &doc = snapshot.document(fileName);
+        QByteArray source;
+
+        foreach (const Document::MacroUse &use, doc->macroUses()) {
+            const Macro &useMacro = use.macro();
+            if (useMacro.line() == macro.line()
+                && useMacro.fileName() == macro.fileName())
+                {
+                if (source.isEmpty())
+                    source = getSource(fileName, workingCopy).toLatin1(); // ### FIXME: Encoding?
+
+                unsigned lineStart;
+                const QString &lineSource = matchingLine(use.begin(), source, &lineStart);
+                usages.append(Usage(fileName, lineSource, use.beginLine(),
+                                    use.begin() - lineStart, use.length()));
+            }
+        }
+
+        return usages;
+    }
+
+    // ### FIXME: Pretty close to FindUsages::matchingLine.
+    static QString matchingLine(unsigned position, const QByteArray &source,
+                                unsigned *lineStart = 0)
+    {
+        const char *beg = source.constData();
+        const char *start = beg + position;
+        for (; start != beg - 1; --start) {
+            if (*start == '\n')
+                break;
+        }
+
+        ++start;
+
+        const char *end = start + 1;
+        for (; *end; ++end) {
+            if (*end == '\n')
+                break;
+        }
+
+        if (lineStart)
+            *lineStart = start - beg;
+
+        // ### FIXME: Encoding?
+        const QString matchingLine = QString::fromUtf8(start, end - start);
+        return matchingLine;
+    }
+};
+
+} // end of anonymous namespace
+
+static void findMacroUses_helper(QFutureInterface<Usage> &future,
+                        const CppTools::CppModelManagerInterface::WorkingCopy workingCopy,
+                        const Snapshot snapshot,
+                        const Macro macro)
+{
+    const QString& sourceFile = macro.fileName();
+    QStringList files(sourceFile);
+    files += snapshot.filesDependingOn(sourceFile);
+    files.removeDuplicates();
+
+    future.setProgressRange(0, files.size());
+
+    FindMacroUsesInFile process(workingCopy, snapshot, macro);
+    UpdateUI reduce(&future);
+    QtConcurrent::blockingMappedReduced<QList<Usage> > (files, process, reduce);
+
+    future.setProgressValue(files.size());
+}
+
+void CppFindReferences::findMacroUses(const Macro &macro)
+{
+    Find::SearchResult *search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchOnly);
+
+    _resultWindow->popup(true);
+
+    connect(search, SIGNAL(activated(Find::SearchResultItem)),
+            this, SLOT(openEditor(Find::SearchResultItem)));
+
+    const Snapshot snapshot = _modelManager->snapshot();
+    const CppTools::CppModelManagerInterface::WorkingCopy workingCopy = _modelManager->workingCopy();
+
+    // add the macro definition itself
+    {
+        // ### FIXME: Encoding?
+        const QByteArray &source = getSource(macro.fileName(), workingCopy).toLatin1();
+        _resultWindow->addResult(macro.fileName(), macro.line(),
+                                 source.mid(macro.offset(), macro.length()), 0, macro.length());
+    }
+
+    QFuture<Usage> result;
+    result = QtConcurrent::run(&findMacroUses_helper, workingCopy, snapshot, macro);
+    m_watcher.setFuture(result);
+
+    Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
+    Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
+                                                              CppTools::Constants::TASK_SEARCH);
+    connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup()));
+}
+
diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h
index 5425e4988d626c00a74dcbc48df53bd96ddff9f0..a97810389855592b3ea27ee8f73ca3bd6984a60c 100644
--- a/src/plugins/cpptools/cppfindreferences.h
+++ b/src/plugins/cpptools/cppfindreferences.h
@@ -67,6 +67,8 @@ public:
     void findUsages(CPlusPlus::Symbol *symbol);
     void renameUsages(CPlusPlus::Symbol *symbol);
 
+    void findMacroUses(const CPlusPlus::Macro &macro);
+
 private Q_SLOTS:
     void displayResults(int first, int last);
     void searchFinished();
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index a31ed64df5c65d57d842cee3919200554c979194..6f7245072f21ee02772f7ef58f67ef6399d6b53a 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -792,6 +792,11 @@ void CppModelManager::renameUsages(CPlusPlus::Symbol *symbol)
         m_findReferences->renameUsages(symbol);
 }
 
+void CppModelManager::findMacroUsages(const CPlusPlus::Macro &macro)
+{
+    m_findReferences->findMacroUses(macro);
+}
+
 CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList()
 {
     WorkingCopy workingCopy;
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index f5f445d605198f7cdfc519a0fe4452e4a3eb3013..bd5b7c0768f240b3aa82e651aa1abecd3633adeb 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -108,6 +108,8 @@ public:
     virtual void findUsages(CPlusPlus::Symbol *symbol);
     virtual void renameUsages(CPlusPlus::Symbol *symbol);
 
+    virtual void findMacroUsages(const CPlusPlus::Macro &macro);
+
     void setHeaderSuffixes(const QStringList &suffixes)
     { m_headerSuffixes = suffixes; }
 
diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h
index 8db6b02b717e9107f1f64f35bf33b95dc58356b8..9b9e3dd3cd553945193d8c219d3f2a431e09f8e4 100644
--- a/src/plugins/cpptools/cppmodelmanagerinterface.h
+++ b/src/plugins/cpptools/cppmodelmanagerinterface.h
@@ -123,6 +123,8 @@ public:
     virtual void renameUsages(CPlusPlus::Symbol *symbol) = 0;
     virtual void findUsages(CPlusPlus::Symbol *symbol) = 0;
 
+    virtual void findMacroUsages(const CPlusPlus::Macro &macro) = 0;
+
 public Q_SLOTS:
     void updateModifiedSourceFiles();
     virtual void updateSourceFiles(const QStringList &sourceFiles) = 0;