diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index beab82f54df013c8c2f3e1c0bbf31f9b8feebb36..a56af5dd4ea521fc09b7b1d6ef264483cb9b84d3 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -1669,7 +1669,11 @@ SemanticHighlighter::Source CPPEditor::currentSource()
 
     const Snapshot snapshot = m_modelManager->snapshot();
     const QString fileName = file()->fileName();
-    const QString code = toPlainText();
+
+    QString code;
+    if (m_lastSemanticInfo.revision != document()->revision())
+        code = toPlainText(); // get the source code only when needed.
+
     const int revision = document()->revision();
     const SemanticHighlighter::Source source(snapshot, fileName, code,
                                              line, column, revision);
@@ -1700,6 +1704,13 @@ void SemanticHighlighter::rehighlight(const Source &source)
     m_condition.wakeOne();
 }
 
+bool SemanticHighlighter::isOutdated()
+{
+    QMutexLocker locker(&m_mutex);
+    const bool outdated = ! m_source.fileName.isEmpty() || m_done;
+    return outdated;
+}
+
 void SemanticHighlighter::run()
 {
     setPriority(QThread::IdlePriority);
@@ -1721,21 +1732,38 @@ void SemanticHighlighter::run()
 
         const SemanticInfo info = semanticInfo(source);
 
-        m_mutex.lock();
-        const bool outdated = ! m_source.fileName.isEmpty() || m_done;
-        m_mutex.unlock();
+        if (! isOutdated()) {
+            m_mutex.lock();
+            m_lastSemanticInfo = info;
+            m_mutex.unlock();
 
-        if (! outdated)
             emit changed(info);
+        }
     }
 }
 
-SemanticInfo SemanticHighlighter::semanticInfo(const Source &source) const
+SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
 {
-    const QByteArray preprocessedCode = source.snapshot.preprocessedCode(source.code, source.fileName);
-    Document::Ptr doc = source.snapshot.documentFromSource(preprocessedCode, source.fileName);
-    const Snapshot snapshot = source.snapshot.simplified(doc);
-    doc->check();
+    m_mutex.lock();
+    const int revision = m_lastSemanticInfo.revision;
+    m_mutex.unlock();
+
+    Snapshot snapshot;
+    Document::Ptr doc;
+
+    if (revision == source.revision) {
+        m_mutex.lock();
+        snapshot = m_lastSemanticInfo.snapshot;
+        doc = m_lastSemanticInfo.doc;
+        m_mutex.unlock();
+    } else {
+        const QByteArray preprocessedCode = source.snapshot.preprocessedCode(source.code, source.fileName);
+
+        doc = source.snapshot.documentFromSource(preprocessedCode, source.fileName);
+        doc->check();
+
+        snapshot = source.snapshot.simplified(doc);
+    }
 
     Control *control = doc->control();
     TranslationUnit *translationUnit = doc->translationUnit();
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 988896977988c96b0523cd97ccc3d5a5af0b986f..6f1c74af94e8b64c51bb2c65db278b6075c19045 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -84,7 +84,7 @@ public:
     typedef QHashIterator<CPlusPlus::Identifier *, QList<Use> > ExternalUseIterator;
 
     SemanticInfo()
-            : revision(0)
+            : revision(-1)
     { }
 
     int revision;
@@ -138,7 +138,7 @@ public:
         }
     };
 
-    SemanticInfo semanticInfo(const Source &source) const;
+    SemanticInfo semanticInfo(const Source &source);
 
     void rehighlight(const Source &source);
 
@@ -148,11 +148,15 @@ Q_SIGNALS:
 protected:
     virtual void run();
 
+private:
+    bool isOutdated();
+
 private:
     QMutex m_mutex;
     QWaitCondition m_condition;
     bool m_done;
     Source m_source;
+    SemanticInfo m_lastSemanticInfo;
 };
 
 class CPPEditorEditable : public TextEditor::BaseTextEditorEditable