C++: Only parse with appropriate defines for open editors.

If two files from different (sub-)projects include the same header file,
and the defined macros differ for both files, the header file will be
parsed with only the appropriate macros for the including file.

Task-number: QTCREATORBUG-9802
Task-number: QTCREATORBUG-1249

Change-Id: I560490afa287b3bb1e863bce1bb4f57af36ad56e
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
Erik Verbruggen
2013-08-19 16:05:29 +02:00
parent 447c4ed37f
commit ba2d7a4fa7
22 changed files with 570 additions and 48 deletions

View File

@@ -6,6 +6,7 @@
#include <utils/textfileformat.h>
#include <QCoreApplication>
#include <QCryptographicHash>
/*!
* \class CppTools::Internal::CppPreprocessor
@@ -34,6 +35,17 @@ CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager,
m_preprocess.setKeepComments(true);
}
CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager, const Snapshot &snapshot,
bool dumpFileNameWhileParsing)
: m_snapshot(snapshot),
m_modelManager(modelManager),
m_dumpFileNameWhileParsing(dumpFileNameWhileParsing),
m_preprocess(this, &m_env),
m_revision(0)
{
m_preprocess.setKeepComments(true);
}
CppPreprocessor::~CppPreprocessor()
{ }
@@ -129,10 +141,10 @@ public:
{
_doc->check(_mode);
if (_modelManager)
if (_modelManager) {
_modelManager->emitDocumentUpdated(_doc);
_doc->releaseSourceAndAST();
_doc->releaseSourceAndAST();
}
}
};
} // end of anonymous namespace
@@ -398,7 +410,7 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu
if (m_dumpFileNameWhileParsing) {
qDebug() << "Parsing file:" << absoluteFileName
<< "contents:" << contents.size()
<< "contents:" << contents.size() << "bytes";
;
}
@@ -426,6 +438,33 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu
// b.constData());
// }
QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData(preprocessedCode);
foreach (const Macro &macro, doc->definedMacros()) {
if (macro.isHidden()) {
static const QByteArray undef("#undef ");
hash.addData(undef);
hash.addData(macro.name());
} else {
static const QByteArray def("#define ");
hash.addData(macro.name());
hash.addData(" ", 1);
hash.addData(def);
hash.addData(macro.definitionText());
}
hash.addData("\n", 1);
}
doc->setFingerprint(hash.result());
Document::Ptr anotherDoc = m_globalSnapshot.document(absoluteFileName);
if (anotherDoc && anotherDoc->fingerprint() == doc->fingerprint()) {
switchDocument(previousDoc);
mergeEnvironment(anotherDoc);
m_snapshot.insert(anotherDoc);
m_todo.remove(absoluteFileName);
return;
}
doc->setUtf8Source(preprocessedCode);
doc->keepSourceAndAST();
doc->tokenize();