forked from qt-creator/qt-creator
C++: moved the CppPreprocessor into its own file.
Change-Id: I399d667a1fccb376fadbd6ab8fbba243e86d8f4b Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
516116c5a5
commit
09ea0d235a
@@ -1,6 +1,7 @@
|
||||
#include "builtinindexingsupport.h"
|
||||
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpppreprocessor.h"
|
||||
#include "searchsymbols.h"
|
||||
#include "cpptoolsconstants.h"
|
||||
#include "cppprojectfile.h"
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "cppcompletionassist.h"
|
||||
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpptoolsconstants.h"
|
||||
#include "cppdoxygen.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpppreprocessor.h"
|
||||
#include "cpptoolsconstants.h"
|
||||
|
||||
#include "builtinindexingsupport.h"
|
||||
#include "cppcompletionassist.h"
|
||||
@@ -44,7 +46,6 @@
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
@@ -53,9 +54,11 @@
|
||||
#include <QTimer>
|
||||
#include <QTextBlock>
|
||||
|
||||
#include <functional>
|
||||
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
|
||||
#define WITH_AST_DUMP
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
@@ -96,7 +99,7 @@ using namespace CppTools;
|
||||
using namespace CppTools::Internal;
|
||||
using namespace CPlusPlus;
|
||||
|
||||
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
|
||||
#ifdef WITH_AST_DUMP
|
||||
|
||||
#include <cxxabi.h>
|
||||
|
||||
@@ -169,421 +172,6 @@ static const char pp_configuration[] =
|
||||
"#define __inline inline\n"
|
||||
"#define __forceinline inline\n";
|
||||
|
||||
CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager, bool dumpFileNameWhileParsing)
|
||||
: m_snapshot(modelManager->snapshot()),
|
||||
m_modelManager(modelManager),
|
||||
m_dumpFileNameWhileParsing(dumpFileNameWhileParsing),
|
||||
m_preprocess(this, &m_env),
|
||||
m_revision(0)
|
||||
{
|
||||
m_preprocess.setKeepComments(true);
|
||||
}
|
||||
|
||||
CppPreprocessor::~CppPreprocessor()
|
||||
{ }
|
||||
|
||||
void CppPreprocessor::setRevision(unsigned revision)
|
||||
{ m_revision = revision; }
|
||||
|
||||
void CppPreprocessor::setWorkingCopy(const CppModelManagerInterface::WorkingCopy &workingCopy)
|
||||
{ m_workingCopy = workingCopy; }
|
||||
|
||||
void CppPreprocessor::setIncludePaths(const QStringList &includePaths)
|
||||
{
|
||||
m_includePaths.clear();
|
||||
|
||||
for (int i = 0; i < includePaths.size(); ++i) {
|
||||
const QString &path = includePaths.at(i);
|
||||
|
||||
if (Utils::HostOsInfo::isMacHost()) {
|
||||
if (i + 1 < includePaths.size() && path.endsWith(QLatin1String(".framework/Headers"))) {
|
||||
const QFileInfo pathInfo(path);
|
||||
const QFileInfo frameworkFileInfo(pathInfo.path());
|
||||
const QString frameworkName = frameworkFileInfo.baseName();
|
||||
|
||||
const QFileInfo nextIncludePath = includePaths.at(i + 1);
|
||||
if (nextIncludePath.fileName() == frameworkName) {
|
||||
// We got a QtXXX.framework/Headers followed by $QTDIR/include/QtXXX.
|
||||
// In this case we prefer to include files from $QTDIR/include/QtXXX.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_includePaths.append(cleanPath(path));
|
||||
}
|
||||
}
|
||||
|
||||
void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
|
||||
{
|
||||
m_frameworkPaths.clear();
|
||||
|
||||
foreach (const QString &frameworkPath, frameworkPaths) {
|
||||
addFrameworkPath(frameworkPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the given framework path, and expand private frameworks.
|
||||
//
|
||||
// Example:
|
||||
// <framework-path>/ApplicationServices.framework
|
||||
// has private frameworks in:
|
||||
// <framework-path>/ApplicationServices.framework/Frameworks
|
||||
// if the "Frameworks" folder exists inside the top level framework.
|
||||
void CppPreprocessor::addFrameworkPath(const QString &frameworkPath)
|
||||
{
|
||||
// The algorithm below is a bit too eager, but that's because we're not getting
|
||||
// in the frameworks we're linking against. If we would have that, then we could
|
||||
// add only those private frameworks.
|
||||
QString cleanFrameworkPath = cleanPath(frameworkPath);
|
||||
if (!m_frameworkPaths.contains(cleanFrameworkPath))
|
||||
m_frameworkPaths.append(cleanFrameworkPath);
|
||||
|
||||
const QDir frameworkDir(cleanFrameworkPath);
|
||||
const QStringList filter = QStringList() << QLatin1String("*.framework");
|
||||
foreach (const QFileInfo &framework, frameworkDir.entryInfoList(filter)) {
|
||||
if (!framework.isDir())
|
||||
continue;
|
||||
const QFileInfo privateFrameworks(framework.absoluteFilePath(), QLatin1String("Frameworks"));
|
||||
if (privateFrameworks.exists() && privateFrameworks.isDir())
|
||||
addFrameworkPath(privateFrameworks.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
void CppPreprocessor::setTodo(const QStringList &files)
|
||||
{ m_todo = QSet<QString>::fromList(files); }
|
||||
|
||||
namespace {
|
||||
class Process: public std::unary_function<Document::Ptr, void>
|
||||
{
|
||||
QPointer<CppModelManager> _modelManager;
|
||||
Document::Ptr _doc;
|
||||
Document::CheckMode _mode;
|
||||
|
||||
public:
|
||||
Process(QPointer<CppModelManager> modelManager,
|
||||
Document::Ptr doc,
|
||||
const CppModelManager::WorkingCopy &workingCopy)
|
||||
: _modelManager(modelManager),
|
||||
_doc(doc),
|
||||
_mode(Document::FastCheck)
|
||||
{
|
||||
|
||||
if (workingCopy.contains(_doc->fileName()))
|
||||
_mode = Document::FullCheck;
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
_doc->check(_mode);
|
||||
|
||||
if (_modelManager)
|
||||
_modelManager->emitDocumentUpdated(_doc);
|
||||
|
||||
_doc->releaseSourceAndAST();
|
||||
}
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
void CppPreprocessor::run(const QString &fileName)
|
||||
{
|
||||
sourceNeeded(0, fileName, IncludeGlobal);
|
||||
}
|
||||
|
||||
void CppPreprocessor::removeFromCache(const QString &fileName)
|
||||
{
|
||||
m_snapshot.remove(fileName);
|
||||
}
|
||||
|
||||
void CppPreprocessor::resetEnvironment()
|
||||
{
|
||||
m_env.reset();
|
||||
m_processed.clear();
|
||||
}
|
||||
|
||||
void CppPreprocessor::getFileContents(const QString &absoluteFilePath,
|
||||
QString *contents,
|
||||
unsigned *revision) const
|
||||
{
|
||||
if (absoluteFilePath.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_workingCopy.contains(absoluteFilePath)) {
|
||||
QPair<QString, unsigned> entry = m_workingCopy.get(absoluteFilePath);
|
||||
if (contents)
|
||||
*contents = entry.first;
|
||||
if (revision)
|
||||
*revision = entry.second;
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(absoluteFilePath);
|
||||
if (file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QTextCodec *defaultCodec = Core::EditorManager::instance()->defaultTextCodec();
|
||||
QTextStream stream(&file);
|
||||
stream.setCodec(defaultCodec);
|
||||
if (contents)
|
||||
*contents = stream.readAll();
|
||||
if (revision)
|
||||
*revision = 0;
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
bool CppPreprocessor::checkFile(const QString &absoluteFilePath) const
|
||||
{
|
||||
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath))
|
||||
return true;
|
||||
|
||||
QFileInfo fileInfo(absoluteFilePath);
|
||||
return fileInfo.isFile() && fileInfo.isReadable();
|
||||
}
|
||||
|
||||
/// Resolve the given file name to its absolute path w.r.t. the include type.
|
||||
QString CppPreprocessor::resolveFile(const QString &fileName, IncludeType type)
|
||||
{
|
||||
if (type == IncludeGlobal) {
|
||||
QHash<QString, QString>::ConstIterator it = m_fileNameCache.find(fileName);
|
||||
if (it != m_fileNameCache.end())
|
||||
return it.value();
|
||||
const QString fn = resolveFile_helper(fileName, type);
|
||||
m_fileNameCache.insert(fileName, fn);
|
||||
return fn;
|
||||
}
|
||||
|
||||
// IncludeLocal, IncludeNext
|
||||
return resolveFile_helper(fileName, type);
|
||||
}
|
||||
|
||||
QString CppPreprocessor::cleanPath(const QString &path)
|
||||
{
|
||||
QString result = QDir::cleanPath(path);
|
||||
const QChar slash(QLatin1Char('/'));
|
||||
if (!result.endsWith(slash))
|
||||
result.append(slash);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CppPreprocessor::resolveFile_helper(const QString &fileName, IncludeType type)
|
||||
{
|
||||
QFileInfo fileInfo(fileName);
|
||||
if (fileName == Preprocessor::configurationFileName || fileInfo.isAbsolute())
|
||||
return fileName;
|
||||
|
||||
if (type == IncludeLocal && m_currentDoc) {
|
||||
QFileInfo currentFileInfo(m_currentDoc->fileName());
|
||||
QString path = cleanPath(currentFileInfo.absolutePath()) + fileName;
|
||||
if (checkFile(path))
|
||||
return path;
|
||||
}
|
||||
|
||||
foreach (const QString &includePath, m_includePaths) {
|
||||
QString path = includePath + fileName;
|
||||
if (checkFile(path))
|
||||
return path;
|
||||
}
|
||||
|
||||
int index = fileName.indexOf(QLatin1Char('/'));
|
||||
if (index != -1) {
|
||||
QString frameworkName = fileName.left(index);
|
||||
QString name = frameworkName + QLatin1String(".framework/Headers/") + fileName.mid(index + 1);
|
||||
|
||||
foreach (const QString &frameworkPath, m_frameworkPaths) {
|
||||
QString path = frameworkPath + name;
|
||||
if (checkFile(path))
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << "**** file" << fileName << "not found!";
|
||||
return QString();
|
||||
}
|
||||
|
||||
void CppPreprocessor::macroAdded(const Macro ¯o)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->appendMacro(macro);
|
||||
}
|
||||
|
||||
static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s, const Macro ¯o)
|
||||
{
|
||||
Macro newMacro(macro);
|
||||
newMacro.setFileRevision(s.get(macro.fileName()).second);
|
||||
return newMacro;
|
||||
}
|
||||
|
||||
void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, unsigned line, const Macro ¯o)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line,
|
||||
QVector<MacroArgumentReference>());
|
||||
}
|
||||
|
||||
void CppPreprocessor::failedMacroDefinitionCheck(unsigned offset, const ByteArrayRef &name)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addUndefinedMacroUse(QByteArray(name.start(), name.size()), offset);
|
||||
}
|
||||
|
||||
void CppPreprocessor::notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line,
|
||||
QVector<MacroArgumentReference>());
|
||||
}
|
||||
|
||||
void CppPreprocessor::startExpandingMacro(unsigned offset, unsigned line,
|
||||
const Macro ¯o,
|
||||
const QVector<MacroArgumentReference> &actuals)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, actuals);
|
||||
}
|
||||
|
||||
void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
//qDebug() << "stop expanding:" << macro.name;
|
||||
}
|
||||
|
||||
void CppPreprocessor::markAsIncludeGuard(const QByteArray ¯oName)
|
||||
{
|
||||
if (!m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->setIncludeGuardMacroName(macroName);
|
||||
}
|
||||
|
||||
void CppPreprocessor::mergeEnvironment(Document::Ptr doc)
|
||||
{
|
||||
if (! doc)
|
||||
return;
|
||||
|
||||
const QString fn = doc->fileName();
|
||||
|
||||
if (m_processed.contains(fn))
|
||||
return;
|
||||
|
||||
m_processed.insert(fn);
|
||||
|
||||
foreach (const Document::Include &incl, doc->includes()) {
|
||||
QString includedFile = incl.fileName();
|
||||
|
||||
if (Document::Ptr includedDoc = m_snapshot.document(includedFile))
|
||||
mergeEnvironment(includedDoc);
|
||||
else
|
||||
run(includedFile);
|
||||
}
|
||||
|
||||
m_env.addMacros(doc->definedMacros());
|
||||
}
|
||||
|
||||
void CppPreprocessor::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);
|
||||
}
|
||||
|
||||
void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
|
||||
QString absoluteFileName = resolveFile(fileName, type);
|
||||
absoluteFileName = QDir::cleanPath(absoluteFileName);
|
||||
if (m_currentDoc && !absoluteFileName.isEmpty())
|
||||
m_currentDoc->addIncludeFile(absoluteFileName, line);
|
||||
if (m_included.contains(absoluteFileName))
|
||||
return; // we've already seen this file.
|
||||
if (absoluteFileName != modelManager()->configurationFileName())
|
||||
m_included.insert(absoluteFileName);
|
||||
|
||||
unsigned editorRevision = 0;
|
||||
QString contents;
|
||||
getFileContents(absoluteFileName, &contents, &editorRevision);
|
||||
if (m_currentDoc) {
|
||||
if (contents.isEmpty() && ! QFileInfo(absoluteFileName).isAbsolute()) {
|
||||
QString msg = QCoreApplication::translate(
|
||||
"CppPreprocessor", "%1: No such file or directory").arg(fileName);
|
||||
|
||||
Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
|
||||
m_currentDoc->fileName(),
|
||||
line, /*column = */ 0,
|
||||
msg);
|
||||
|
||||
m_currentDoc->addDiagnosticMessage(d);
|
||||
|
||||
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_dumpFileNameWhileParsing) {
|
||||
qDebug() << "Parsing file:" << absoluteFileName
|
||||
// << "contents:" << contents.size()
|
||||
;
|
||||
}
|
||||
|
||||
Document::Ptr doc = m_snapshot.document(absoluteFileName);
|
||||
if (doc) {
|
||||
mergeEnvironment(doc);
|
||||
return;
|
||||
}
|
||||
|
||||
doc = Document::create(absoluteFileName);
|
||||
doc->setRevision(m_revision);
|
||||
doc->setEditorRevision(editorRevision);
|
||||
|
||||
QFileInfo info(absoluteFileName);
|
||||
if (info.exists())
|
||||
doc->setLastModified(info.lastModified());
|
||||
|
||||
Document::Ptr previousDoc = switchDocument(doc);
|
||||
|
||||
const QByteArray preprocessedCode = m_preprocess.run(absoluteFileName, contents);
|
||||
|
||||
// { QByteArray b(preprocessedCode); b.replace("\n", "<<<\n"); qDebug("Preprocessed code for \"%s\": [[%s]]", fileName.toUtf8().constData(), b.constData()); }
|
||||
|
||||
doc->setUtf8Source(preprocessedCode);
|
||||
doc->keepSourceAndAST();
|
||||
doc->tokenize();
|
||||
|
||||
m_snapshot.insert(doc);
|
||||
m_todo.remove(absoluteFileName);
|
||||
|
||||
Process process(m_modelManager, doc, m_workingCopy);
|
||||
process();
|
||||
|
||||
(void) switchDocument(previousDoc);
|
||||
}
|
||||
|
||||
Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
|
||||
{
|
||||
Document::Ptr previousDoc = m_currentDoc;
|
||||
m_currentDoc = doc;
|
||||
return previousDoc;
|
||||
}
|
||||
|
||||
void CppModelManager::updateModifiedSourceFiles()
|
||||
{
|
||||
const Snapshot snapshot = this->snapshot();
|
||||
|
||||
@@ -31,15 +31,11 @@
|
||||
#define CPPMODELMANAGER_H
|
||||
|
||||
#include "cpptools_global.h"
|
||||
#include "cpptoolsconstants.h"
|
||||
#include "cppmodelmanagerinterface.h"
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <texteditor/basetexteditor.h>
|
||||
|
||||
#include <cplusplus/PreprocessorEnvironment.h>
|
||||
#include <cplusplus/pp-engine.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QMutex>
|
||||
|
||||
@@ -51,7 +47,6 @@ class BaseTextEditorWidget;
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
class CppCompletionSupportFactory;
|
||||
class CppEditorSupport;
|
||||
class CppHighlightingSupportFactory;
|
||||
|
||||
@@ -205,77 +200,6 @@ private:
|
||||
CppIndexingSupport *m_internalIndexingSupport;
|
||||
};
|
||||
|
||||
class CPPTOOLS_EXPORT CppPreprocessor: public CPlusPlus::Client
|
||||
{
|
||||
Q_DISABLE_COPY(CppPreprocessor)
|
||||
|
||||
public:
|
||||
CppPreprocessor(QPointer<CppModelManager> modelManager, bool dumpFileNameWhileParsing = false);
|
||||
virtual ~CppPreprocessor();
|
||||
|
||||
void setRevision(unsigned revision);
|
||||
void setWorkingCopy(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy);
|
||||
void setIncludePaths(const QStringList &includePaths);
|
||||
void setFrameworkPaths(const QStringList &frameworkPaths);
|
||||
void addFrameworkPath(const QString &frameworkPath);
|
||||
void setProjectFiles(const QStringList &files);
|
||||
void setTodo(const QStringList &files);
|
||||
|
||||
void run(const QString &fileName);
|
||||
void removeFromCache(const QString &fileName);
|
||||
|
||||
void resetEnvironment();
|
||||
static QString cleanPath(const QString &path);
|
||||
|
||||
const QSet<QString> &todo() const
|
||||
{ return m_todo; }
|
||||
|
||||
CppModelManager *modelManager() const
|
||||
{ return m_modelManager.data(); }
|
||||
|
||||
protected:
|
||||
CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
void getFileContents(const QString &absoluteFilePath, QString *contents, unsigned *revision) const;
|
||||
bool checkFile(const QString &absoluteFilePath) const;
|
||||
QString resolveFile(const QString &fileName, IncludeType type);
|
||||
QString resolveFile_helper(const QString &fileName, IncludeType type);
|
||||
|
||||
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
virtual void macroAdded(const CPlusPlus::Macro ¯o);
|
||||
virtual void passedMacroDefinitionCheck(unsigned offset, unsigned line,
|
||||
const CPlusPlus::Macro ¯o);
|
||||
virtual void failedMacroDefinitionCheck(unsigned offset, const CPlusPlus::ByteArrayRef &name);
|
||||
virtual void notifyMacroReference(unsigned offset, unsigned line,
|
||||
const CPlusPlus::Macro ¯o);
|
||||
virtual void startExpandingMacro(unsigned offset,
|
||||
unsigned line,
|
||||
const CPlusPlus::Macro ¯o,
|
||||
const QVector<CPlusPlus::MacroArgumentReference> &actuals);
|
||||
virtual void stopExpandingMacro(unsigned offset, const CPlusPlus::Macro ¯o);
|
||||
virtual void markAsIncludeGuard(const QByteArray ¯oName);
|
||||
virtual void startSkippingBlocks(unsigned offset);
|
||||
virtual void stopSkippingBlocks(unsigned offset);
|
||||
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType type);
|
||||
|
||||
private:
|
||||
CPlusPlus::Snapshot m_snapshot;
|
||||
QPointer<CppModelManager> m_modelManager;
|
||||
bool m_dumpFileNameWhileParsing;
|
||||
CPlusPlus::Environment m_env;
|
||||
CPlusPlus::Preprocessor m_preprocess;
|
||||
QStringList m_includePaths;
|
||||
CppTools::CppModelManagerInterface::WorkingCopy m_workingCopy;
|
||||
QStringList m_frameworkPaths;
|
||||
QSet<QString> m_included;
|
||||
CPlusPlus::Document::Ptr m_currentDoc;
|
||||
QSet<QString> m_todo;
|
||||
QSet<QString> m_processed;
|
||||
unsigned m_revision;
|
||||
QHash<QString, QString> m_fileNameCache;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CppTools
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "cpptoolsplugin.h"
|
||||
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpppreprocessor.h"
|
||||
#include "modelmanagertesthelper.h"
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
425
src/plugins/cpptools/cpppreprocessor.cpp
Normal file
425
src/plugins/cpptools/cpppreprocessor.cpp
Normal file
@@ -0,0 +1,425 @@
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpppreprocessor.h"
|
||||
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace CPlusPlus;
|
||||
using namespace CppTools;
|
||||
using namespace CppTools::Internal;
|
||||
|
||||
CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager, bool dumpFileNameWhileParsing)
|
||||
: m_snapshot(modelManager->snapshot()),
|
||||
m_modelManager(modelManager),
|
||||
m_dumpFileNameWhileParsing(dumpFileNameWhileParsing),
|
||||
m_preprocess(this, &m_env),
|
||||
m_revision(0)
|
||||
{
|
||||
m_preprocess.setKeepComments(true);
|
||||
}
|
||||
|
||||
CppPreprocessor::~CppPreprocessor()
|
||||
{ }
|
||||
|
||||
void CppPreprocessor::setRevision(unsigned revision)
|
||||
{ m_revision = revision; }
|
||||
|
||||
void CppPreprocessor::setWorkingCopy(const CppModelManagerInterface::WorkingCopy &workingCopy)
|
||||
{ m_workingCopy = workingCopy; }
|
||||
|
||||
void CppPreprocessor::setIncludePaths(const QStringList &includePaths)
|
||||
{
|
||||
m_includePaths.clear();
|
||||
|
||||
for (int i = 0; i < includePaths.size(); ++i) {
|
||||
const QString &path = includePaths.at(i);
|
||||
|
||||
if (Utils::HostOsInfo::isMacHost()) {
|
||||
if (i + 1 < includePaths.size() && path.endsWith(QLatin1String(".framework/Headers"))) {
|
||||
const QFileInfo pathInfo(path);
|
||||
const QFileInfo frameworkFileInfo(pathInfo.path());
|
||||
const QString frameworkName = frameworkFileInfo.baseName();
|
||||
|
||||
const QFileInfo nextIncludePath = includePaths.at(i + 1);
|
||||
if (nextIncludePath.fileName() == frameworkName) {
|
||||
// We got a QtXXX.framework/Headers followed by $QTDIR/include/QtXXX.
|
||||
// In this case we prefer to include files from $QTDIR/include/QtXXX.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_includePaths.append(cleanPath(path));
|
||||
}
|
||||
}
|
||||
|
||||
void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
|
||||
{
|
||||
m_frameworkPaths.clear();
|
||||
|
||||
foreach (const QString &frameworkPath, frameworkPaths) {
|
||||
addFrameworkPath(frameworkPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the given framework path, and expand private frameworks.
|
||||
//
|
||||
// Example:
|
||||
// <framework-path>/ApplicationServices.framework
|
||||
// has private frameworks in:
|
||||
// <framework-path>/ApplicationServices.framework/Frameworks
|
||||
// if the "Frameworks" folder exists inside the top level framework.
|
||||
void CppPreprocessor::addFrameworkPath(const QString &frameworkPath)
|
||||
{
|
||||
// The algorithm below is a bit too eager, but that's because we're not getting
|
||||
// in the frameworks we're linking against. If we would have that, then we could
|
||||
// add only those private frameworks.
|
||||
QString cleanFrameworkPath = cleanPath(frameworkPath);
|
||||
if (!m_frameworkPaths.contains(cleanFrameworkPath))
|
||||
m_frameworkPaths.append(cleanFrameworkPath);
|
||||
|
||||
const QDir frameworkDir(cleanFrameworkPath);
|
||||
const QStringList filter = QStringList() << QLatin1String("*.framework");
|
||||
foreach (const QFileInfo &framework, frameworkDir.entryInfoList(filter)) {
|
||||
if (!framework.isDir())
|
||||
continue;
|
||||
const QFileInfo privateFrameworks(framework.absoluteFilePath(), QLatin1String("Frameworks"));
|
||||
if (privateFrameworks.exists() && privateFrameworks.isDir())
|
||||
addFrameworkPath(privateFrameworks.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
void CppPreprocessor::setTodo(const QStringList &files)
|
||||
{ m_todo = QSet<QString>::fromList(files); }
|
||||
|
||||
namespace {
|
||||
class Process: public std::unary_function<Document::Ptr, void>
|
||||
{
|
||||
QPointer<CppModelManager> _modelManager;
|
||||
Document::Ptr _doc;
|
||||
Document::CheckMode _mode;
|
||||
|
||||
public:
|
||||
Process(QPointer<CppModelManager> modelManager,
|
||||
Document::Ptr doc,
|
||||
const CppModelManager::WorkingCopy &workingCopy)
|
||||
: _modelManager(modelManager),
|
||||
_doc(doc),
|
||||
_mode(Document::FastCheck)
|
||||
{
|
||||
|
||||
if (workingCopy.contains(_doc->fileName()))
|
||||
_mode = Document::FullCheck;
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
_doc->check(_mode);
|
||||
|
||||
if (_modelManager)
|
||||
_modelManager->emitDocumentUpdated(_doc);
|
||||
|
||||
_doc->releaseSourceAndAST();
|
||||
}
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
void CppPreprocessor::run(const QString &fileName)
|
||||
{
|
||||
sourceNeeded(0, fileName, IncludeGlobal);
|
||||
}
|
||||
|
||||
void CppPreprocessor::removeFromCache(const QString &fileName)
|
||||
{
|
||||
m_snapshot.remove(fileName);
|
||||
}
|
||||
|
||||
void CppPreprocessor::resetEnvironment()
|
||||
{
|
||||
m_env.reset();
|
||||
m_processed.clear();
|
||||
}
|
||||
|
||||
void CppPreprocessor::getFileContents(const QString &absoluteFilePath,
|
||||
QString *contents,
|
||||
unsigned *revision) const
|
||||
{
|
||||
if (absoluteFilePath.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_workingCopy.contains(absoluteFilePath)) {
|
||||
QPair<QString, unsigned> entry = m_workingCopy.get(absoluteFilePath);
|
||||
if (contents)
|
||||
*contents = entry.first;
|
||||
if (revision)
|
||||
*revision = entry.second;
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(absoluteFilePath);
|
||||
if (file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QTextCodec *defaultCodec = Core::EditorManager::instance()->defaultTextCodec();
|
||||
QTextStream stream(&file);
|
||||
stream.setCodec(defaultCodec);
|
||||
if (contents)
|
||||
*contents = stream.readAll();
|
||||
if (revision)
|
||||
*revision = 0;
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
bool CppPreprocessor::checkFile(const QString &absoluteFilePath) const
|
||||
{
|
||||
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath))
|
||||
return true;
|
||||
|
||||
QFileInfo fileInfo(absoluteFilePath);
|
||||
return fileInfo.isFile() && fileInfo.isReadable();
|
||||
}
|
||||
|
||||
/// Resolve the given file name to its absolute path w.r.t. the include type.
|
||||
QString CppPreprocessor::resolveFile(const QString &fileName, IncludeType type)
|
||||
{
|
||||
if (type == IncludeGlobal) {
|
||||
QHash<QString, QString>::ConstIterator it = m_fileNameCache.find(fileName);
|
||||
if (it != m_fileNameCache.end())
|
||||
return it.value();
|
||||
const QString fn = resolveFile_helper(fileName, type);
|
||||
m_fileNameCache.insert(fileName, fn);
|
||||
return fn;
|
||||
}
|
||||
|
||||
// IncludeLocal, IncludeNext
|
||||
return resolveFile_helper(fileName, type);
|
||||
}
|
||||
|
||||
QString CppPreprocessor::cleanPath(const QString &path)
|
||||
{
|
||||
QString result = QDir::cleanPath(path);
|
||||
const QChar slash(QLatin1Char('/'));
|
||||
if (!result.endsWith(slash))
|
||||
result.append(slash);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CppPreprocessor::resolveFile_helper(const QString &fileName, IncludeType type)
|
||||
{
|
||||
QFileInfo fileInfo(fileName);
|
||||
if (fileName == Preprocessor::configurationFileName || fileInfo.isAbsolute())
|
||||
return fileName;
|
||||
|
||||
if (type == IncludeLocal && m_currentDoc) {
|
||||
QFileInfo currentFileInfo(m_currentDoc->fileName());
|
||||
QString path = cleanPath(currentFileInfo.absolutePath()) + fileName;
|
||||
if (checkFile(path))
|
||||
return path;
|
||||
}
|
||||
|
||||
foreach (const QString &includePath, m_includePaths) {
|
||||
QString path = includePath + fileName;
|
||||
if (checkFile(path))
|
||||
return path;
|
||||
}
|
||||
|
||||
int index = fileName.indexOf(QLatin1Char('/'));
|
||||
if (index != -1) {
|
||||
QString frameworkName = fileName.left(index);
|
||||
QString name = frameworkName + QLatin1String(".framework/Headers/") + fileName.mid(index + 1);
|
||||
|
||||
foreach (const QString &frameworkPath, m_frameworkPaths) {
|
||||
QString path = frameworkPath + name;
|
||||
if (checkFile(path))
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << "**** file" << fileName << "not found!";
|
||||
return QString();
|
||||
}
|
||||
|
||||
void CppPreprocessor::macroAdded(const Macro ¯o)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->appendMacro(macro);
|
||||
}
|
||||
|
||||
static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s, const Macro ¯o)
|
||||
{
|
||||
Macro newMacro(macro);
|
||||
newMacro.setFileRevision(s.get(macro.fileName()).second);
|
||||
return newMacro;
|
||||
}
|
||||
|
||||
void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, unsigned line, const Macro ¯o)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line,
|
||||
QVector<MacroArgumentReference>());
|
||||
}
|
||||
|
||||
void CppPreprocessor::failedMacroDefinitionCheck(unsigned offset, const ByteArrayRef &name)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addUndefinedMacroUse(QByteArray(name.start(), name.size()), offset);
|
||||
}
|
||||
|
||||
void CppPreprocessor::notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line,
|
||||
QVector<MacroArgumentReference>());
|
||||
}
|
||||
|
||||
void CppPreprocessor::startExpandingMacro(unsigned offset, unsigned line,
|
||||
const Macro ¯o,
|
||||
const QVector<MacroArgumentReference> &actuals)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, actuals);
|
||||
}
|
||||
|
||||
void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
//qDebug() << "stop expanding:" << macro.name;
|
||||
}
|
||||
|
||||
void CppPreprocessor::markAsIncludeGuard(const QByteArray ¯oName)
|
||||
{
|
||||
if (!m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->setIncludeGuardMacroName(macroName);
|
||||
}
|
||||
|
||||
void CppPreprocessor::mergeEnvironment(Document::Ptr doc)
|
||||
{
|
||||
if (! doc)
|
||||
return;
|
||||
|
||||
const QString fn = doc->fileName();
|
||||
|
||||
if (m_processed.contains(fn))
|
||||
return;
|
||||
|
||||
m_processed.insert(fn);
|
||||
|
||||
foreach (const Document::Include &incl, doc->includes()) {
|
||||
QString includedFile = incl.fileName();
|
||||
|
||||
if (Document::Ptr includedDoc = m_snapshot.document(includedFile))
|
||||
mergeEnvironment(includedDoc);
|
||||
else
|
||||
run(includedFile);
|
||||
}
|
||||
|
||||
m_env.addMacros(doc->definedMacros());
|
||||
}
|
||||
|
||||
void CppPreprocessor::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);
|
||||
}
|
||||
|
||||
void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
|
||||
QString absoluteFileName = resolveFile(fileName, type);
|
||||
absoluteFileName = QDir::cleanPath(absoluteFileName);
|
||||
if (m_currentDoc && !absoluteFileName.isEmpty())
|
||||
m_currentDoc->addIncludeFile(absoluteFileName, line);
|
||||
if (m_included.contains(absoluteFileName))
|
||||
return; // we've already seen this file.
|
||||
if (absoluteFileName != modelManager()->configurationFileName())
|
||||
m_included.insert(absoluteFileName);
|
||||
|
||||
unsigned editorRevision = 0;
|
||||
QString contents;
|
||||
getFileContents(absoluteFileName, &contents, &editorRevision);
|
||||
if (m_currentDoc) {
|
||||
if (contents.isEmpty() && ! QFileInfo(absoluteFileName).isAbsolute()) {
|
||||
QString msg = QCoreApplication::translate(
|
||||
"CppPreprocessor", "%1: No such file or directory").arg(fileName);
|
||||
|
||||
Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
|
||||
m_currentDoc->fileName(),
|
||||
line, /*column = */ 0,
|
||||
msg);
|
||||
|
||||
m_currentDoc->addDiagnosticMessage(d);
|
||||
|
||||
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_dumpFileNameWhileParsing) {
|
||||
qDebug() << "Parsing file:" << absoluteFileName
|
||||
// << "contents:" << contents.size()
|
||||
;
|
||||
}
|
||||
|
||||
Document::Ptr doc = m_snapshot.document(absoluteFileName);
|
||||
if (doc) {
|
||||
mergeEnvironment(doc);
|
||||
return;
|
||||
}
|
||||
|
||||
doc = Document::create(absoluteFileName);
|
||||
doc->setRevision(m_revision);
|
||||
doc->setEditorRevision(editorRevision);
|
||||
|
||||
QFileInfo info(absoluteFileName);
|
||||
if (info.exists())
|
||||
doc->setLastModified(info.lastModified());
|
||||
|
||||
Document::Ptr previousDoc = switchDocument(doc);
|
||||
|
||||
const QByteArray preprocessedCode = m_preprocess.run(absoluteFileName, contents);
|
||||
|
||||
// { QByteArray b(preprocessedCode); b.replace("\n", "<<<\n"); qDebug("Preprocessed code for \"%s\": [[%s]]", fileName.toUtf8().constData(), b.constData()); }
|
||||
|
||||
doc->setUtf8Source(preprocessedCode);
|
||||
doc->keepSourceAndAST();
|
||||
doc->tokenize();
|
||||
|
||||
m_snapshot.insert(doc);
|
||||
m_todo.remove(absoluteFileName);
|
||||
|
||||
Process process(m_modelManager, doc, m_workingCopy);
|
||||
process();
|
||||
|
||||
(void) switchDocument(previousDoc);
|
||||
}
|
||||
|
||||
Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
|
||||
{
|
||||
Document::Ptr previousDoc = m_currentDoc;
|
||||
m_currentDoc = doc;
|
||||
return previousDoc;
|
||||
}
|
||||
91
src/plugins/cpptools/cpppreprocessor.h
Normal file
91
src/plugins/cpptools/cpppreprocessor.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef CPPPREPROCESSOR_H
|
||||
#define CPPPREPROCESSOR_H
|
||||
|
||||
#include "cppmodelmanagerinterface.h"
|
||||
|
||||
#include <cplusplus/PreprocessorEnvironment.h>
|
||||
#include <cplusplus/pp-engine.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QPointer>
|
||||
|
||||
namespace CppTools {
|
||||
namespace Internal {
|
||||
|
||||
class CppModelManager;
|
||||
|
||||
class CPPTOOLS_EXPORT CppPreprocessor: public CPlusPlus::Client
|
||||
{
|
||||
Q_DISABLE_COPY(CppPreprocessor)
|
||||
|
||||
public:
|
||||
CppPreprocessor(QPointer<CppModelManager> modelManager, bool dumpFileNameWhileParsing = false);
|
||||
virtual ~CppPreprocessor();
|
||||
|
||||
void setRevision(unsigned revision);
|
||||
void setWorkingCopy(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy);
|
||||
void setIncludePaths(const QStringList &includePaths);
|
||||
void setFrameworkPaths(const QStringList &frameworkPaths);
|
||||
void addFrameworkPath(const QString &frameworkPath);
|
||||
void setProjectFiles(const QStringList &files);
|
||||
void setTodo(const QStringList &files);
|
||||
|
||||
void run(const QString &fileName);
|
||||
void removeFromCache(const QString &fileName);
|
||||
|
||||
void resetEnvironment();
|
||||
static QString cleanPath(const QString &path);
|
||||
|
||||
const QSet<QString> &todo() const
|
||||
{ return m_todo; }
|
||||
|
||||
CppModelManager *modelManager() const
|
||||
{ return m_modelManager.data(); }
|
||||
|
||||
protected:
|
||||
CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
void getFileContents(const QString &absoluteFilePath, QString *contents, unsigned *revision) const;
|
||||
bool checkFile(const QString &absoluteFilePath) const;
|
||||
QString resolveFile(const QString &fileName, IncludeType type);
|
||||
QString resolveFile_helper(const QString &fileName, IncludeType type);
|
||||
|
||||
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
virtual void macroAdded(const CPlusPlus::Macro ¯o);
|
||||
virtual void passedMacroDefinitionCheck(unsigned offset, unsigned line,
|
||||
const CPlusPlus::Macro ¯o);
|
||||
virtual void failedMacroDefinitionCheck(unsigned offset, const CPlusPlus::ByteArrayRef &name);
|
||||
virtual void notifyMacroReference(unsigned offset, unsigned line,
|
||||
const CPlusPlus::Macro ¯o);
|
||||
virtual void startExpandingMacro(unsigned offset,
|
||||
unsigned line,
|
||||
const CPlusPlus::Macro ¯o,
|
||||
const QVector<CPlusPlus::MacroArgumentReference> &actuals);
|
||||
virtual void stopExpandingMacro(unsigned offset, const CPlusPlus::Macro ¯o);
|
||||
virtual void markAsIncludeGuard(const QByteArray ¯oName);
|
||||
virtual void startSkippingBlocks(unsigned offset);
|
||||
virtual void stopSkippingBlocks(unsigned offset);
|
||||
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType type);
|
||||
|
||||
private:
|
||||
CPlusPlus::Snapshot m_snapshot;
|
||||
QPointer<CppModelManager> m_modelManager;
|
||||
bool m_dumpFileNameWhileParsing;
|
||||
CPlusPlus::Environment m_env;
|
||||
CPlusPlus::Preprocessor m_preprocess;
|
||||
QStringList m_includePaths;
|
||||
CppTools::CppModelManagerInterface::WorkingCopy m_workingCopy;
|
||||
QStringList m_frameworkPaths;
|
||||
QSet<QString> m_included;
|
||||
CPlusPlus::Document::Ptr m_currentDoc;
|
||||
QSet<QString> m_todo;
|
||||
QSet<QString> m_processed;
|
||||
unsigned m_revision;
|
||||
QHash<QString, QString> m_fileNameCache;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CppTools
|
||||
|
||||
#endif // CPPPREPROCESSOR_H
|
||||
@@ -44,7 +44,8 @@ HEADERS += completionsettingspage.h \
|
||||
cppindexingsupport.h \
|
||||
builtinindexingsupport.h \
|
||||
cpppointerdeclarationformatter.h \
|
||||
cppprojectfile.h
|
||||
cppprojectfile.h \
|
||||
cpppreprocessor.h
|
||||
|
||||
SOURCES += completionsettingspage.cpp \
|
||||
cppclassesfilter.cpp \
|
||||
@@ -87,7 +88,8 @@ SOURCES += completionsettingspage.cpp \
|
||||
cppindexingsupport.cpp \
|
||||
builtinindexingsupport.cpp \
|
||||
cpppointerdeclarationformatter.cpp \
|
||||
cppprojectfile.cpp
|
||||
cppprojectfile.cpp \
|
||||
cpppreprocessor.cpp
|
||||
|
||||
FORMS += completionsettingspage.ui \
|
||||
cppfilesettingspage.ui \
|
||||
|
||||
@@ -105,7 +105,9 @@ QtcPlugin {
|
||||
"uicodecompletionsupport.cpp",
|
||||
"uicodecompletionsupport.h",
|
||||
"builtinindexingsupport.cpp",
|
||||
"builtinindexingsupport.h"
|
||||
"builtinindexingsupport.h",
|
||||
"cpppreprocessor.cpp",
|
||||
"cpppreprocessor.h"
|
||||
]
|
||||
|
||||
Group {
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "cpptoolsconstants.h"
|
||||
#include "cpptoolsplugin.h"
|
||||
|
||||
#include "cppfilesettingspage.h"
|
||||
#include "cppcodestylesettingspage.h"
|
||||
#include "cppclassesfilter.h"
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "symbolsfindfilter.h"
|
||||
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpptoolsconstants.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/progressmanager/futureprogress.h>
|
||||
|
||||
Reference in New Issue
Block a user