From 1f8ce02d06b63c58b7e1a91bb13f9e778d60a5b1 Mon Sep 17 00:00:00 2001 From: Roberto Raggi <qtc-committer@nokia.com> Date: Mon, 8 Dec 2008 11:08:48 +0100 Subject: [PATCH] Some cleanup in CppPreprocessor. --- src/plugins/cpptools/cppmodelmanager.cpp | 491 ++++++++++++----------- 1 file changed, 259 insertions(+), 232 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index dbc324013c6..6be28d36252 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -31,7 +31,6 @@ ** ***************************************************************************/ -#define _SCL_SECURE_NO_WARNINGS 1 #include "pp.h" #include "cppmodelmanager.h" @@ -70,11 +69,10 @@ #include <QTime> #include <QDebug> +using namespace CppTools; +using namespace CppTools::Internal; using namespace CPlusPlus; -namespace CppTools { -namespace Internal { - static const char pp_configuration_file[] = "<configuration>"; static const char pp_configuration[] = @@ -106,299 +104,328 @@ static const char pp_configuration[] = "#define __declspec(a)\n" "#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method\n"; +namespace CppTools { +namespace Internal { + class CppPreprocessor: public rpp::Client { public: - CppPreprocessor(QPointer<CppModelManager> modelManager) - : m_modelManager(modelManager), - m_documents(modelManager->documents()), - m_proc(this, env) - { } + CppPreprocessor(QPointer<CppModelManager> modelManager); + + void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy); + void setIncludePaths(const QStringList &includePaths); + void setFrameworkPaths(const QStringList &frameworkPaths); + void addIncludePath(const QString &path); + void setProjectFiles(const QStringList &files); + void run(QString &fileName); + void operator()(QString &fileName); - void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy) - { m_workingCopy = workingCopy; } +protected: + CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc); + + bool includeFile(const QString &absoluteFilePath, QByteArray *result); + QByteArray tryIncludeFile(QString &fileName, IncludeType type); + + void mergeEnvironment(CPlusPlus::Document::Ptr doc); + void mergeEnvironment(CPlusPlus::Document::Ptr doc, QSet<QString> *processed); + + virtual void macroAdded(const QByteArray ¯oName, + const QByteArray ¯oText); + virtual void startExpandingMacro(unsigned offset, + const rpp::Macro ¯o, + const QByteArray &originalText); + virtual void stopExpandingMacro(unsigned offset, const rpp::Macro ¯o); + virtual void startSkippingBlocks(unsigned offset); + virtual void stopSkippingBlocks(unsigned offset); + virtual void sourceNeeded(QString &fileName, IncludeType type); + +private: + QPointer<CppModelManager> m_modelManager; + CppModelManager::DocumentTable m_documents; + rpp::Environment env; + rpp::pp m_proc; + QStringList m_includePaths; + QStringList m_systemIncludePaths; + QMap<QString, QByteArray> m_workingCopy; + QStringList m_projectFiles; + QStringList m_frameworkPaths; + QSet<QString> m_included; + CPlusPlus::Document::Ptr m_currentDoc; +}; - void setIncludePaths(const QStringList &includePaths) - { m_includePaths = includePaths; } +} // namespace Internal +} // namespace CppTools - void setFrameworkPaths(const QStringList &frameworkPaths) - { m_frameworkPaths = frameworkPaths; } +CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager) + : m_modelManager(modelManager), + m_documents(modelManager->documents()), + m_proc(this, env) +{ } - void addIncludePath(const QString &path) - { m_includePaths.append(path); } +void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy) +{ m_workingCopy = workingCopy; } - void setProjectFiles(const QStringList &files) - { m_projectFiles = files; } +void CppPreprocessor::setIncludePaths(const QStringList &includePaths) +{ m_includePaths = includePaths; } - void run(QString &fileName) - { sourceNeeded(fileName, IncludeGlobal); } +void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths) +{ m_frameworkPaths = frameworkPaths; } - void operator()(QString &fileName) - { run(fileName); } +void CppPreprocessor::addIncludePath(const QString &path) +{ m_includePaths.append(path); } -protected: - bool includeFile(const QString &absoluteFilePath, QByteArray *result) - { - if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) { - return true; - } +void CppPreprocessor::setProjectFiles(const QStringList &files) +{ m_projectFiles = files; } - if (m_workingCopy.contains(absoluteFilePath)) { - m_included.insert(absoluteFilePath); - *result = m_workingCopy.value(absoluteFilePath); - return true; - } +void CppPreprocessor::run(QString &fileName) +{ sourceNeeded(fileName, IncludeGlobal); } - QFileInfo fileInfo(absoluteFilePath); - if (! fileInfo.isFile()) - return false; - - QFile file(absoluteFilePath); - if (file.open(QFile::ReadOnly)) { - m_included.insert(absoluteFilePath); - QTextStream stream(&file); - const QString contents = stream.readAll(); - *result = contents.toUtf8(); - file.close(); - return true; - } +void CppPreprocessor::operator()(QString &fileName) +{ run(fileName); } +bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QByteArray *result) +{ + if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) { + return true; + } + + if (m_workingCopy.contains(absoluteFilePath)) { + m_included.insert(absoluteFilePath); + *result = m_workingCopy.value(absoluteFilePath); + return true; + } + + QFileInfo fileInfo(absoluteFilePath); + if (! fileInfo.isFile()) return false; + + QFile file(absoluteFilePath); + if (file.open(QFile::ReadOnly)) { + m_included.insert(absoluteFilePath); + QTextStream stream(&file); + const QString contents = stream.readAll(); + *result = contents.toUtf8(); + file.close(); + return true; } - QByteArray tryIncludeFile(QString &fileName, IncludeType type) - { - QFileInfo fileInfo(fileName); - if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) { - QByteArray contents; - includeFile(fileName, &contents); + return false; +} + +QByteArray CppPreprocessor::tryIncludeFile(QString &fileName, IncludeType type) +{ + QFileInfo fileInfo(fileName); + if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) { + QByteArray contents; + includeFile(fileName, &contents); + return contents; + } + + if (type == IncludeLocal && m_currentDoc) { + QFileInfo currentFileInfo(m_currentDoc->fileName()); + QString path = currentFileInfo.absolutePath(); + path += QLatin1Char('/'); + path += fileName; + path = QDir::cleanPath(path); + QByteArray contents; + if (includeFile(path, &contents)) { + fileName = path; return contents; } + } - if (type == IncludeLocal && m_currentDoc) { - QFileInfo currentFileInfo(m_currentDoc->fileName()); - QString path = currentFileInfo.absolutePath(); - path += QLatin1Char('/'); - path += fileName; - path = QDir::cleanPath(path); - QByteArray contents; - if (includeFile(path, &contents)) { - fileName = path; - return contents; - } + foreach (const QString &includePath, m_includePaths) { + QString path = includePath; + path += QLatin1Char('/'); + path += fileName; + path = QDir::cleanPath(path); + QByteArray contents; + if (includeFile(path, &contents)) { + fileName = path; + return contents; } + } - foreach (const QString &includePath, m_includePaths) { - QString path = includePath; - path += QLatin1Char('/'); - path += fileName; - path = QDir::cleanPath(path); - QByteArray contents; - if (includeFile(path, &contents)) { - fileName = path; - return contents; - } + // look in the system include paths + foreach (const QString &includePath, m_systemIncludePaths) { + QString path = includePath; + path += QLatin1Char('/'); + path += fileName; + path = QDir::cleanPath(path); + QByteArray contents; + if (includeFile(path, &contents)) { + fileName = path; + return contents; } + } + + int index = fileName.indexOf(QLatin1Char('/')); + if (index != -1) { + QString frameworkName = fileName.left(index); + QString name = fileName.mid(index + 1); - // look in the system include paths - foreach (const QString &includePath, m_systemIncludePaths) { - QString path = includePath; + foreach (const QString &frameworkPath, m_frameworkPaths) { + QString path = frameworkPath; path += QLatin1Char('/'); - path += fileName; - path = QDir::cleanPath(path); + path += frameworkName; + path += QLatin1String(".framework/Headers/"); + path += name; QByteArray contents; if (includeFile(path, &contents)) { fileName = path; return contents; } } + } - int index = fileName.indexOf(QLatin1Char('/')); - if (index != -1) { - QString frameworkName = fileName.left(index); - QString name = fileName.mid(index + 1); - - foreach (const QString &frameworkPath, m_frameworkPaths) { - QString path = frameworkPath; - path += QLatin1Char('/'); - path += frameworkName; - path += QLatin1String(".framework/Headers/"); - path += name; - QByteArray contents; - if (includeFile(path, &contents)) { - fileName = path; - return contents; - } - } + QString path = fileName; + if (path.at(0) != QLatin1Char('/')) + path.prepend(QLatin1Char('/')); + + foreach (const QString &projectFile, m_projectFiles) { + if (projectFile.endsWith(path)) { + fileName = projectFile; + QByteArray contents; + includeFile(fileName, &contents); + return contents; } + } - QString path = fileName; - if (path.at(0) != QLatin1Char('/')) - path.prepend(QLatin1Char('/')); + //qDebug() << "**** file" << fileName << "not found!"; + return QByteArray(); +} - foreach (const QString &projectFile, m_projectFiles) { - if (projectFile.endsWith(path)) { - fileName = projectFile; - QByteArray contents; - includeFile(fileName, &contents); - return contents; - } - } +void CppPreprocessor::macroAdded(const QByteArray ¯oName, const QByteArray ¯oText) +{ + if (! m_currentDoc) + return; - //qDebug() << "**** file" << fileName << "not found!"; - return QByteArray(); - } + m_currentDoc->appendMacro(macroName, macroText); +} - virtual void macroAdded(const QByteArray ¯oName, const QByteArray ¯oText) - { - if (! m_currentDoc) - return; +void CppPreprocessor::startExpandingMacro(unsigned offset, + const rpp::Macro &, + const QByteArray &originalText) +{ + if (! m_currentDoc) + return; - m_currentDoc->appendMacro(macroName, macroText); - } + //qDebug() << "start expanding:" << macro.name << "text:" << originalText; + m_currentDoc->addMacroUse(offset, originalText.length()); +} - virtual void startExpandingMacro(unsigned offset, - const rpp::Macro &, - const QByteArray &originalText) - { - if (! m_currentDoc) - return; - - //qDebug() << "start expanding:" << macro.name << "text:" << originalText; - m_currentDoc->addMacroUse(offset, originalText.length()); - } +void CppPreprocessor::stopExpandingMacro(unsigned, const rpp::Macro &) +{ + if (! m_currentDoc) + return; - virtual void stopExpandingMacro(unsigned, const rpp::Macro &) - { - if (! m_currentDoc) - return; + //qDebug() << "stop expanding:" << macro.name; +} - //qDebug() << "stop expanding:" << macro.name; - } +void CppPreprocessor::mergeEnvironment(Document::Ptr doc) +{ + QSet<QString> processed; + mergeEnvironment(doc, &processed); +} - void mergeEnvironment(Document::Ptr doc) - { - QSet<QString> processed; - mergeEnvironment(doc, &processed); - } +void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *processed) +{ + if (! doc) + return; - void mergeEnvironment(Document::Ptr doc, QSet<QString> *processed) - { - if (! doc) - return; + const QString fn = doc->fileName(); - const QString fn = doc->fileName(); + if (processed->contains(fn)) + return; - if (processed->contains(fn)) - return; + processed->insert(fn); - processed->insert(fn); + foreach (QString includedFile, doc->includedFiles()) + mergeEnvironment(m_documents.value(includedFile), processed); - foreach (QString includedFile, doc->includedFiles()) - mergeEnvironment(m_documents.value(includedFile), processed); + const QByteArray macros = doc->definedMacros(); + QByteArray localFileName = doc->fileName().toUtf8(); - const QByteArray macros = doc->definedMacros(); - QByteArray localFileName = doc->fileName().toUtf8(); + QByteArray dummy; + m_proc(localFileName, macros, &dummy); +} - QByteArray dummy; - m_proc(localFileName, macros, &dummy); - } +void CppPreprocessor::startSkippingBlocks(unsigned offset) +{ + //qDebug() << "start skipping blocks:" << offset; + if (m_currentDoc) + m_currentDoc->startSkippingBlocks(offset); +} - virtual void startSkippingBlocks(unsigned offset) - { - //qDebug() << "start skipping blocks:" << offset; - if (m_currentDoc) - m_currentDoc->startSkippingBlocks(offset); - } +void CppPreprocessor::stopSkippingBlocks(unsigned offset) +{ + //qDebug() << "stop skipping blocks:" << offset; + if (m_currentDoc) + m_currentDoc->stopSkippingBlocks(offset); +} - virtual void stopSkippingBlocks(unsigned offset) - { - //qDebug() << "stop skipping blocks:" << offset; - if (m_currentDoc) - m_currentDoc->stopSkippingBlocks(offset); - } +void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type) +{ + if (fileName.isEmpty()) + return; - virtual void sourceNeeded(QString &fileName, IncludeType type) - { - if (fileName.isEmpty()) - return; - - QByteArray contents = tryIncludeFile(fileName, type); - - if (m_currentDoc) { - m_currentDoc->addIncludeFile(fileName); - if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) { - QString msg; - msg += fileName; - msg += QLatin1String(": No such file or directory"); - Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning, - m_currentDoc->fileName(), - env.currentLine, /*column = */ 0, - msg); - m_currentDoc->addDiagnosticMessage(d); - //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line; - } + QByteArray contents = tryIncludeFile(fileName, type); + + if (m_currentDoc) { + m_currentDoc->addIncludeFile(fileName); + if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) { + QString msg; + msg += fileName; + msg += QLatin1String(": No such file or directory"); + Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning, + m_currentDoc->fileName(), + env.currentLine, /*column = */ 0, + msg); + m_currentDoc->addDiagnosticMessage(d); + //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line; } + } - if (! contents.isEmpty()) { - Document::Ptr cachedDoc = m_documents.value(fileName); - if (cachedDoc && m_currentDoc) { - mergeEnvironment(cachedDoc); - } else { - Document::Ptr previousDoc = switchDocument(Document::create(fileName)); + if (! contents.isEmpty()) { + Document::Ptr cachedDoc = m_documents.value(fileName); + if (cachedDoc && m_currentDoc) { + mergeEnvironment(cachedDoc); + } else { + Document::Ptr previousDoc = switchDocument(Document::create(fileName)); - const QByteArray previousFile = env.current_file; - const unsigned previousLine = env.currentLine; + const QByteArray previousFile = env.current_file; + const unsigned previousLine = env.currentLine; - env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(), - m_currentDoc->translationUnit()->fileNameLength()); + env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(), + m_currentDoc->translationUnit()->fileNameLength()); - QByteArray preprocessedCode; - m_proc(contents, &preprocessedCode); - //qDebug() << preprocessedCode; + QByteArray preprocessedCode; + m_proc(contents, &preprocessedCode); + //qDebug() << preprocessedCode; - env.current_file = previousFile; - env.currentLine = previousLine; + env.current_file = previousFile; + env.currentLine = previousLine; - m_currentDoc->setSource(preprocessedCode); - m_currentDoc->parse(); - m_currentDoc->check(); - m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream. + m_currentDoc->setSource(preprocessedCode); + m_currentDoc->parse(); + m_currentDoc->check(); + m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream. - if (m_modelManager) - m_modelManager->emitDocumentUpdated(m_currentDoc); - (void) switchDocument(previousDoc); - } + if (m_modelManager) + m_modelManager->emitDocumentUpdated(m_currentDoc); + (void) switchDocument(previousDoc); } } +} - Document::Ptr switchDocument(Document::Ptr doc) - { - Document::Ptr previousDoc = m_currentDoc; - m_currentDoc = doc; - return previousDoc; - } - -private: - QPointer<CppModelManager> m_modelManager; - CppModelManager::DocumentTable m_documents; - rpp::Environment env; - rpp::pp m_proc; - QStringList m_includePaths; - QStringList m_systemIncludePaths; - QMap<QString, QByteArray> m_workingCopy; - QStringList m_projectFiles; - QStringList m_frameworkPaths; - QSet<QString> m_included; - Document::Ptr m_currentDoc; -}; - -} // namespace Internal -} // namespace CppTools +Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc) +{ + Document::Ptr previousDoc = m_currentDoc; + m_currentDoc = doc; + return previousDoc; +} -using namespace CppTools; -using namespace CppTools::Internal; /*! \class CppTools::CppModelManager -- GitLab