summaryrefslogtreecommitdiff
path: root/src/plugins/compilationdatabaseprojectmanager
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-10-30 10:31:34 +0100
committerIvan Donchevskii <ivan.donchevskii@qt.io>2018-11-01 14:52:05 +0000
commitf604c8a77cf86663fc751bcf23c94697088cfda1 (patch)
treec98bc2ff2e694f3d93650260f8144e1e8c522f2f /src/plugins/compilationdatabaseprojectmanager
parentcb75aa3e58987ed3cd8ac5e1dde089b855f731b2 (diff)
downloadqt-creator-f604c8a77cf86663fc751bcf23c94697088cfda1.tar.gz
CompilationDatabase: Support both code models
Extract headers, defines and fileKind from flags in order to have complete project parts. Side-effect: better support for MSVC-specific flags. Change-Id: Iaa1413c91c96c3cf89ddbe76a7a1f0f46c5289c0 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
Diffstat (limited to 'src/plugins/compilationdatabaseprojectmanager')
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp407
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h7
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.pro16
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs19
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp10
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h2
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp105
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.h54
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.qrc6
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri7
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp216
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h50
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/database_samples/llvm/compile_commands.json7
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/database_samples/qtc/compile_commands.json62
14 files changed, 790 insertions, 178 deletions
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
index 106d0926b9..522a8356ab 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
@@ -26,158 +26,286 @@
#include "compilationdatabaseproject.h"
#include "compilationdatabaseconstants.h"
+#include "compilationdatabaseutils.h"
#include <coreplugin/icontext.h>
#include <cpptools/projectinfo.h>
#include <cpptools/cppprojectupdater.h>
#include <projectexplorer/gcctoolchain.h>
+#include <projectexplorer/headerpath.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectnodes.h>
-#include <projectexplorer/target.h>
#include <projectexplorer/toolchainconfigwidget.h>
+#include <projectexplorer/toolchainmanager.h>
#include <texteditor/textdocument.h>
+
+#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
-#include <QRegularExpression>
+#ifdef Q_OS_WIN
+#include <Windows.h>
+#endif
+
+using namespace ProjectExplorer;
namespace CompilationDatabaseProjectManager {
namespace Internal {
-class DBProjectNode : public ProjectExplorer::ProjectNode
+namespace {
+class DBProjectNode : public ProjectNode
{
public:
explicit DBProjectNode(const Utils::FileName &projectFilePath)
- : ProjectExplorer::ProjectNode(projectFilePath)
+ : ProjectNode(projectFilePath)
{}
};
-static QStringList splitCommandLine(QString commandLine)
+QStringList jsonObjectFlags(const QJsonObject &object)
{
- QStringList result;
- bool insideQuotes = false;
-
- // Remove escaped quotes.
- commandLine.replace("\\\"", "'");
- for (const QString &part : commandLine.split(QRegularExpression("\""))) {
- if (insideQuotes) {
- const QString quotedPart = "\"" + part + "\"";
- if (result.last().endsWith("="))
- result.last().append(quotedPart);
- else
- result.append(quotedPart);
- } else { // If 's' is outside quotes ...
- result.append(part.split(QRegularExpression("\\s+"), QString::SkipEmptyParts));
- }
- insideQuotes = !insideQuotes;
+ QStringList flags;
+ const QJsonArray arguments = object["arguments"].toArray();
+ if (arguments.isEmpty()) {
+ flags = splitCommandLine(object["command"].toString());
+ } else {
+ for (const QJsonValue &arg : arguments)
+ flags.append(arg.toString());
}
- return result;
+
+ return flags;
}
-static QString updatedPathFlag(const QString &pathStr, const QString &workingDir,
- const QString &originalFlag)
+bool isGccCompiler(const QString &compilerName)
{
- QString result = pathStr;
- if (!QDir(pathStr).exists()
- && QDir(workingDir + "/" + pathStr).exists()) {
- result = workingDir + "/" + pathStr;
- }
-
- if (originalFlag.startsWith("-I"))
- return "-I" + result;
-
- if (originalFlag.startsWith("-isystem"))
- return "-isystem" + result;
-
- return result;
+ return compilerName.contains("gcc") || compilerName.contains("g++");
}
-static QStringList filteredFlags(const QStringList &flags, const QString &fileName,
- const QString &workingDir)
+Core::Id getCompilerId(QString compilerName)
{
- QStringList filtered;
- // Skip compiler call if present.
- bool skipNext = !flags.first().startsWith('-');
- bool includePath = false;
-
- for (const QString &flag : flags) {
- if (skipNext) {
- skipNext = false;
- continue;
- }
+ if (Utils::HostOsInfo::isWindowsHost()) {
+ if (compilerName.endsWith(".exe"))
+ compilerName.chop(4);
+ if (isGccCompiler(compilerName))
+ return ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID;
+
+ // Default is clang-cl
+ return ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID;
+ }
+ if (isGccCompiler(compilerName))
+ return ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
- QString pathStr;
- if (includePath) {
- includePath = false;
- pathStr = flag;
- } else if ((flag.startsWith("-I") || flag.startsWith("-isystem"))
- && flag != "-I" && flag != "-isystem") {
- pathStr = flag.mid(flag.startsWith("-I") ? 2 : 8);
- }
+ // Default is clang
+ return ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID;
+}
- if (!pathStr.isEmpty()) {
- filtered.push_back(updatedPathFlag(pathStr, workingDir, flag));
- continue;
- }
+ToolChain *toolchainFromCompilerId(const Core::Id &compilerId, const Core::Id &language)
+{
+ return ToolChainManager::toolChain([&compilerId, &language](const ToolChain *tc) {
+ if (!tc->isValid() || tc->language() != language)
+ return false;
+ return tc->typeId() == compilerId;
+ });
+}
- if (flag == "-c" || flag == "-pedantic" || flag.startsWith("/") || flag.startsWith("-m")
- || flag.startsWith("-O") || flag.startsWith("-W") || flag.startsWith("-w")
- || flag.startsWith("--sysroot=")) {
- continue;
- }
+QString compilerPath(QString pathFlag)
+{
+ if (pathFlag.isEmpty())
+ return pathFlag;
+#ifdef Q_OS_WIN
+ // Handle short DOS style file names (cmake can generate them).
+ const DWORD pathLength = GetLongPathNameW((LPCWSTR)pathFlag.utf16(), 0, 0);
+ wchar_t* buffer = new wchar_t[pathLength];
+ GetLongPathNameW((LPCWSTR)pathFlag.utf16(), buffer, pathLength);
+ pathFlag = QString::fromUtf16((ushort *)buffer, pathLength - 1);
+ delete[] buffer;
+#endif
+ return QDir::fromNativeSeparators(pathFlag);
+}
- if (flag == "-target" || flag == "-triple" || flag == "-isysroot" || flag == "-isystem"
- || flag == "--sysroot") {
- skipNext = true;
- continue;
- }
+ToolChain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Core::Id &language)
+{
+ if (flags.empty())
+ return ToolChainKitInformation::toolChain(kit, language);
- if (flag.endsWith(fileName))
- continue;
+ // Try exact compiler match.
+ const Utils::FileName compiler = Utils::FileName::fromString(compilerPath(flags.front()));
+ ToolChain *toolchain = ToolChainManager::toolChain([&compiler, &language](const ToolChain *tc) {
+ return tc->isValid() && tc->language() == language && tc->compilerCommand() == compiler;
+ });
+ if (toolchain)
+ return toolchain;
+
+ Core::Id compilerId = getCompilerId(compiler.fileName());
+ if ((toolchain = toolchainFromCompilerId(compilerId, language)))
+ return toolchain;
+
+ if (compilerId != ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID &&
+ compilerId != ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
+ compilerId = Utils::HostOsInfo::isWindowsHost()
+ ? ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID
+ : ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID;
+ if ((toolchain = toolchainFromCompilerId(compilerId, language)))
+ return toolchain;
+ }
- if (flag == "-I" || flag == "-isystem")
- includePath = true;
+ toolchain = ToolChainKitInformation::toolChain(kit, language);
+ qWarning() << QCoreApplication::translate("CompilationDatabaseProject",
+ "No matching toolchain found, use the default.");
+ return toolchain;
+}
- filtered.push_back(flag);
+Utils::FileName jsonObjectFilename(const QJsonObject &object)
+{
+ const QString workingDir = object["directory"].toString();
+ Utils::FileName fileName = Utils::FileName::fromString(
+ QDir::fromNativeSeparators(object["file"].toString()));
+ if (fileName.toFileInfo().isRelative()) {
+ fileName = Utils::FileUtils::canonicalPath(
+ Utils::FileName::fromString(workingDir + "/" + fileName.toString()));
}
-
- return filtered;
+ return fileName;
}
-static CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile,
- const QJsonObject &object,
- const QString &workingDir,
- const Utils::FileName &fileName)
+void addDriverModeFlagIfNeeded(const ToolChain *toolchain, QStringList &flags)
{
- QStringList flags;
- const QJsonArray arguments = object["arguments"].toArray();
- if (arguments.isEmpty()) {
- flags = splitCommandLine(object["command"].toString());
- } else {
- for (const QJsonValue &arg : arguments)
- flags.append(arg.toString());
+ if (toolchain->typeId() == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID
+ && !flags.empty() && !flags.front().endsWith("cl")
+ && !flags.front().endsWith("cl.exe")) {
+ flags.insert(1, "--driver-mode=g++");
}
+}
- flags = filteredFlags(flags, fileName.fileName(), workingDir);
+CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile,
+ Kit *kit,
+ ToolChain *&cToolchain,
+ ToolChain *&cxxToolchain,
+ const QString &workingDir,
+ const Utils::FileName &fileName,
+ QStringList flags)
+{
+ HeaderPaths headerPaths;
+ Macros macros;
+ CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::Unclassified;
+
+ const QStringList originalFlags = flags;
+ filteredFlags(fileName.fileName(),
+ workingDir,
+ flags,
+ headerPaths,
+ macros,
+ fileKind);
CppTools::RawProjectPart rpp;
rpp.setProjectFileLocation(projectFile.toString());
rpp.setBuildSystemTarget(workingDir);
rpp.setDisplayName(fileName.fileName());
rpp.setFiles({fileName.toString()});
-
- CppTools::RawProjectPartFlags cxxProjectFlags;
- cxxProjectFlags.commandLineFlags = flags;
- rpp.setFlagsForCxx(cxxProjectFlags);
+ rpp.setHeaderPaths(headerPaths);
+ rpp.setMacros(macros);
+
+ if (fileKind == CppTools::ProjectFile::Kind::CHeader
+ || fileKind == CppTools::ProjectFile::Kind::CSource) {
+ if (!cToolchain) {
+ cToolchain = toolchainFromFlags(kit, originalFlags,
+ ProjectExplorer::Constants::C_LANGUAGE_ID);
+ ToolChainKitInformation::setToolChain(kit, cToolchain);
+ }
+ addDriverModeFlagIfNeeded(cToolchain, flags);
+ rpp.setFlagsForC({cToolchain, flags});
+ } else {
+ if (!cxxToolchain) {
+ cxxToolchain = toolchainFromFlags(kit, originalFlags,
+ ProjectExplorer::Constants::CXX_LANGUAGE_ID);
+ ToolChainKitInformation::setToolChain(kit, cxxToolchain);
+ }
+ addDriverModeFlagIfNeeded(cxxToolchain, flags);
+ rpp.setFlagsForCxx({cxxToolchain, flags});
+ }
return rpp;
}
+} // anonymous namespace
+
+void CompilationDatabaseProject::buildTreeAndProjectParts(const Utils::FileName &projectFile)
+{
+ QFile file(projectFilePath().toString());
+ if (!file.open(QIODevice::ReadOnly)) {
+ emitParsingFinished(false);
+ return;
+ }
+
+ const QJsonArray array = QJsonDocument::fromJson(file.readAll()).array();
+
+ auto root = std::make_unique<DBProjectNode>(projectDirectory());
+ root->addNode(std::make_unique<FileNode>(
+ projectFile,
+ FileType::Project,
+ false));
+ auto headers = std::make_unique<VirtualFolderNode>(
+ Utils::FileName::fromString("Headers"), 0);
+ auto sources = std::make_unique<VirtualFolderNode>(
+ Utils::FileName::fromString("Sources"), 0);
+
+ CppTools::RawProjectParts rpps;
+ ToolChain *cToolchain = nullptr;
+ ToolChain *cxxToolchain = nullptr;
+ for (const QJsonValue &element : array) {
+ const QJsonObject object = element.toObject();
+
+ Utils::FileName fileName = jsonObjectFilename(object);
+ const QStringList flags = jsonObjectFlags(object);
+ const QString filePath = fileName.toString();
+
+ const CppTools::ProjectFile::Kind kind = CppTools::ProjectFile::classify(filePath);
+ FolderNode *parent = nullptr;
+ FileType type = FileType::Unknown;
+ if (CppTools::ProjectFile::isHeader(kind)) {
+ parent = headers.get();
+ type = FileType::Header;
+ } else if (CppTools::ProjectFile::isSource(kind)) {
+ parent = sources.get();
+ type = FileType::Source;
+ } else {
+ parent = root.get();
+ }
+ parent->addNode(std::make_unique<FileNode>(fileName, type, false));
+
+ CppTools::RawProjectPart rpp = makeRawProjectPart(projectFile,
+ m_kit.get(),
+ cToolchain,
+ cxxToolchain,
+ object["directory"].toString(),
+ fileName,
+ flags);
+ int rppIndex = Utils::indexOf(rpps, [&rpp](const CppTools::RawProjectPart &currentRpp) {
+ return rpp.buildSystemTarget == currentRpp.buildSystemTarget
+ && rpp.headerPaths == currentRpp.headerPaths
+ && rpp.projectMacros == currentRpp.projectMacros
+ && rpp.flagsForCxx.commandLineFlags == currentRpp.flagsForCxx.commandLineFlags;
+ });
+ if (rppIndex == -1)
+ rpps.append(rpp);
+ else
+ rpps[rppIndex].files.append(rpp.files);
+ }
+
+ root->addNode(std::move(headers));
+ root->addNode(std::move(sources));
+
+ setRootProjectNode(std::move(root));
+
+ m_cppCodeModelUpdater->update({this, cToolchain, cxxToolchain, m_kit.get(), rpps});
+
+ emitParsingFinished(true);
+}
+
CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FileName &projectFile)
: Project(Constants::COMPILATIONDATABASEMIMETYPE, projectFile)
, m_cppCodeModelUpdater(std::make_unique<CppTools::CppProjectUpdater>(this))
@@ -185,90 +313,17 @@ CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FileName &pr
setId(Constants::COMPILATIONDATABASEPROJECT_ID);
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(projectDirectory().fileName());
+ setRequiredKitPredicate([](const Kit *) { return false; });
+ setPreferredKitPredicate([](const Kit *) { return false; });
- connect(this, &Project::activeTargetChanged, [this, projectFile](ProjectExplorer::Target *target) {
- if (!target)
- return;
-
- ProjectExplorer::Kit *kit = target->kit();
- if (!kit)
- return;
-
- auto toolchains = ProjectExplorer::ToolChainKitInformation::toolChains(kit);
- if (toolchains.isEmpty())
- return;
-
- emitParsingStarted();
-
- const QFuture<void> future = ::Utils::runAsync([this, projectFile, kit,
- tc = toolchains.first()](){
- QFile file(projectFilePath().toString());
- if (!file.open(QIODevice::ReadOnly)) {
- emitParsingFinished(false);
- return;
- }
-
- const QJsonArray array = QJsonDocument::fromJson(file.readAll()).array();
-
- auto root = std::make_unique<DBProjectNode>(projectDirectory());
- root->addNode(std::make_unique<ProjectExplorer::FileNode>(
- projectFile,
- ProjectExplorer::FileType::Project,
- false));
- auto headers = std::make_unique<ProjectExplorer::VirtualFolderNode>(
- Utils::FileName::fromString("Headers"), 0);
- auto sources = std::make_unique<ProjectExplorer::VirtualFolderNode>(
- Utils::FileName::fromString("Sources"), 0);
- CppTools::RawProjectParts rpps;
- for (const QJsonValue &element : array) {
- const QJsonObject object = element.toObject();
- const QString workingDir = object["directory"].toString();
- Utils::FileName fileName = Utils::FileName::fromString(
- QDir::fromNativeSeparators(object["file"].toString()));
- if (!fileName.exists()) {
- fileName = Utils::FileUtils::canonicalPath(
- Utils::FileName::fromString(workingDir + "/" + fileName.toString()));
- }
- const QString filePath = fileName.toString();
- const CppTools::ProjectFile::Kind kind = CppTools::ProjectFile::classify(filePath);
- ProjectExplorer::FolderNode *parent = nullptr;
- ProjectExplorer::FileType type = ProjectExplorer::FileType::Unknown;
- if (CppTools::ProjectFile::isHeader(kind)) {
- parent = headers.get();
- type = ProjectExplorer::FileType::Header;
- } else if (CppTools::ProjectFile::isSource(kind)) {
- parent = sources.get();
- type = ProjectExplorer::FileType::Source;
- } else {
- parent = root.get();
- }
- parent->addNode(std::make_unique<ProjectExplorer::FileNode>(
- fileName, type, false));
-
- rpps.append(makeRawProjectPart(projectFile, object, workingDir, fileName));
- }
-
- root->addNode(std::move(headers));
- root->addNode(std::move(sources));
-
- setRootProjectNode(std::move(root));
-
- CppTools::ToolChainInfo tcInfo;
- tcInfo.type = ProjectExplorer::Constants::COMPILATION_DATABASE_TOOLCHAIN_TYPEID;
- tcInfo.isMsvc2015ToolChain
- = tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMsvc2015Flavor;
- tcInfo.wordWidth = tc->targetAbi().wordWidth();
- tcInfo.targetTriple = tc->originalTargetTriple();
- tcInfo.sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
- tcInfo.headerPathsRunner = tc->createBuiltInHeaderPathsRunner();
- tcInfo.macroInspectionRunner = tc->createMacroInspectionRunner();
-
- m_cppCodeModelUpdater->update({this, tcInfo, tcInfo, rpps});
-
- emitParsingFinished(true);
- });
- m_parserWatcher.setFuture(future);
+ m_kit.reset(KitManager::defaultKit()->clone());
+
+ emitParsingStarted();
+
+ const QFuture<void> future = ::Utils::runAsync([this, projectFile](){
+ buildTreeAndProjectParts(projectFile);
});
+ m_parserWatcher.setFuture(future);
}
CompilationDatabaseProject::~CompilationDatabaseProject()
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
index 2ba01adbaa..26fabebe47 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
@@ -35,6 +35,8 @@ namespace CppTools {
class CppProjectUpdater;
}
+namespace ProjectExplorer { class Kit; }
+
namespace CompilationDatabaseProjectManager {
namespace Internal {
@@ -45,10 +47,15 @@ class CompilationDatabaseProject : public ProjectExplorer::Project
public:
explicit CompilationDatabaseProject(const Utils::FileName &filename);
~CompilationDatabaseProject() override;
+ bool needsConfiguration() const override { return false; }
+ bool needsBuildConfigurations() const override { return false; }
private:
+ void buildTreeAndProjectParts(const Utils::FileName &projectFile);
+
QFutureWatcher<void> m_parserWatcher;
std::unique_ptr<CppTools::CppProjectUpdater> m_cppCodeModelUpdater;
+ std::unique_ptr<ProjectExplorer::Kit> m_kit;
};
class CompilationDatabaseEditorFactory : public TextEditor::TextEditorFactory
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.pro b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.pro
index a815c0db8e..e7efefb47e 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.pro
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.pro
@@ -2,9 +2,21 @@ include(../../qtcreatorplugin.pri)
SOURCES = \
compilationdatabaseproject.cpp \
- compilationdatabaseprojectmanagerplugin.cpp
+ compilationdatabaseprojectmanagerplugin.cpp \
+ compilationdatabaseutils.cpp
HEADERS = \
compilationdatabaseproject.h \
compilationdatabaseprojectmanagerplugin.h \
- compilationdatabaseconstants.h
+ compilationdatabaseconstants.h \
+ compilationdatabaseutils.h
+
+equals(TEST, 1) {
+ HEADERS += \
+ compilationdatabasetests.h
+
+ SOURCES += \
+ compilationdatabasetests.cpp
+
+ RESOURCES += compilationdatabasetests.qrc
+}
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs
index e21dc9e123..4cbe2af284 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs
@@ -13,7 +13,26 @@ QtcPlugin {
"compilationdatabaseconstants.h",
"compilationdatabaseproject.cpp",
"compilationdatabaseproject.h",
+ "compilationdatabaseutils.cpp",
+ "compilationdatabaseutils.h",
"compilationdatabaseprojectmanagerplugin.cpp",
"compilationdatabaseprojectmanagerplugin.h",
]
+
+ Group {
+ name: "Tests"
+ condition: qtc.testsEnabled
+ files: [
+ "compilationdatabasetests.cpp",
+ "compilationdatabasetests.h",
+ "compilationdatabasetests.qrc",
+ ]
+ }
+
+ Group {
+ name: "Test resources"
+ prefix: "database_samples/"
+ fileTags: []
+ files: ["**/*"]
+ }
}
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
index 1fe0d6d032..77359adc70 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
@@ -27,6 +27,7 @@
#include "compilationdatabaseconstants.h"
#include "compilationdatabaseproject.h"
+#include "compilationdatabasetests.h"
#include <coreplugin/fileiconprovider.h>
#include <projectexplorer/projectmanager.h>
@@ -52,5 +53,14 @@ void CompilationDatabaseProjectManagerPlugin::extensionsInitialized()
{
}
+QList<QObject *> CompilationDatabaseProjectManagerPlugin::createTestObjects() const
+{
+ QList<QObject *> tests;
+#ifdef WITH_TESTS
+ tests << new CompilationDatabaseTests;
+#endif
+ return tests;
+}
+
} // namespace Internal
} // namespace CompilationDatabaseProjectManager
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h
index a89db25e37..37c9c1db1d 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h
@@ -43,6 +43,8 @@ public:
bool initialize(const QStringList &arguments, QString *errorMessage) final;
void extensionsInitialized() final;
private:
+ QList<QObject *> createTestObjects() const final;
+
CompilationDatabaseEditorFactory factory;
};
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp
new file mode 100644
index 0000000000..72a1b6ac74
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "compilationdatabasetests.h"
+
+#include <coreplugin/icore.h>
+#include <cpptools/cpptoolstestcase.h>
+#include <cpptools/projectinfo.h>
+#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainmanager.h>
+
+#include <QtTest>
+
+using namespace ProjectExplorer;
+
+namespace CompilationDatabaseProjectManager {
+
+CompilationDatabaseTests::CompilationDatabaseTests(QObject *parent)
+ : QObject(parent)
+{}
+
+CompilationDatabaseTests::~CompilationDatabaseTests() = default;
+
+void CompilationDatabaseTests::initTestCase()
+{
+ const QList<Kit *> allKits = KitManager::kits();
+ if (allKits.empty())
+ QSKIP("This test requires at least one kit to be present.");
+
+ ToolChain *toolchain = ToolChainManager::toolChain([](const ToolChain *tc) {
+ return tc->isValid() && tc->language() == Constants::CXX_LANGUAGE_ID;
+ });
+ if (!toolchain)
+ QSKIP("This test requires that there is at least one C++ toolchain present.");
+
+ m_tmpDir = std::make_unique<CppTools::Tests::TemporaryCopiedDir>(":/database_samples");
+ QVERIFY(m_tmpDir->isValid());
+}
+
+void CompilationDatabaseTests::cleanupTestCase()
+{
+ m_tmpDir.reset();
+}
+
+void CompilationDatabaseTests::testProject()
+{
+ QFETCH(QString, projectFilePath);
+
+ CppTools::Tests::ProjectOpenerAndCloser projectManager;
+ const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
+ QVERIFY(projectInfo.isValid());
+
+ projectInfo.projectParts();
+ QVector<CppTools::ProjectPart::Ptr> projectParts = projectInfo.projectParts();
+ QVERIFY(!projectParts.isEmpty());
+
+ CppTools::ProjectPart &projectPart = *projectParts.first();
+ QVERIFY(!projectPart.headerPaths.isEmpty());
+ QVERIFY(!projectPart.projectMacros.isEmpty());
+ QVERIFY(!projectPart.toolChainMacros.isEmpty());
+ QVERIFY(!projectPart.files.isEmpty());
+}
+
+void CompilationDatabaseTests::testProject_data()
+{
+ QTest::addColumn<QString>("projectFilePath");
+
+ addTestRow("qtc/compile_commands.json");
+ addTestRow("llvm/compile_commands.json");
+}
+
+void CompilationDatabaseTests::addTestRow(const QByteArray &relativeFilePath)
+{
+ const QString absoluteFilePath = m_tmpDir->absolutePath(relativeFilePath);
+ const QString fileName = QFileInfo(absoluteFilePath).fileName();
+
+ QTest::newRow(fileName.toUtf8().constData()) << absoluteFilePath;
+}
+
+} // namespace CompilationDatabaseProjectManager
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.h
new file mode 100644
index 0000000000..f508a44013
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QObject>
+#include <memory>
+
+namespace CppTools { namespace Tests { class TemporaryCopiedDir; } }
+
+namespace CompilationDatabaseProjectManager {
+
+class CompilationDatabaseTests : public QObject
+{
+ Q_OBJECT
+public:
+ explicit CompilationDatabaseTests(QObject *parent = nullptr);
+ ~CompilationDatabaseTests();
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void testProject();
+ void testProject_data();
+
+private:
+ void addTestRow(const QByteArray &relativeFilePath);
+
+ std::unique_ptr<CppTools::Tests::TemporaryCopiedDir> m_tmpDir;
+};
+
+} // namespace CompilationDatabaseProjectManager
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.qrc b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.qrc
new file mode 100644
index 0000000000..571437b4c9
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>database_samples/llvm/compile_commands.json</file>
+ <file>database_samples/qtc/compile_commands.json</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri
new file mode 100644
index 0000000000..c1b3188b4c
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri
@@ -0,0 +1,7 @@
+INCLUDEPATH += $$PWD
+
+SOURCES += \
+ $$PWD/compilationdatabaseutils.cpp
+
+HEADERS += \
+ $$PWD/compilationdatabaseutils.h
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp
new file mode 100644
index 0000000000..30ad52160e
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "compilationdatabaseutils.h"
+
+#include <projectexplorer/headerpath.h>
+#include <projectexplorer/projectmacro.h>
+
+#include <utils/hostosinfo.h>
+#include <utils/optional.h>
+
+#include <QDir>
+#include <QRegularExpression>
+
+using namespace ProjectExplorer;
+
+namespace CompilationDatabaseProjectManager {
+
+static QString updatedPathFlag(const QString &pathStr, const QString &workingDir)
+{
+ QString result = pathStr;
+ if (!QDir(pathStr).exists()
+ && QDir(workingDir + "/" + pathStr).exists()) {
+ result = workingDir + "/" + pathStr;
+ }
+
+ return result;
+}
+
+static CppTools::ProjectFile::Kind fileKindFromString(const QString &flag)
+{
+ using namespace CppTools;
+ if (flag == "c++-header")
+ return ProjectFile::CXXHeader;
+ if (flag == "c-header")
+ return ProjectFile::CHeader;
+ if (flag == "c++" || flag == "/TP" || flag.startsWith("/Tp"))
+ return ProjectFile::CXXSource;
+ if (flag == "c" || flag == "/TC" || flag.startsWith("/Tc"))
+ return ProjectFile::CSource;
+
+ if (flag == "objective-c++")
+ return ProjectFile::ObjCXXSource;
+ if (flag == "objective-c++-header")
+ return ProjectFile::ObjCXXHeader;
+ if (flag == "objective-c")
+ return ProjectFile::ObjCSource;
+ if (flag == "objective-c-header")
+ return ProjectFile::ObjCHeader;
+
+ if (flag == "cl")
+ return ProjectFile::OpenCLSource;
+ if (flag == "cuda")
+ return ProjectFile::CudaSource;
+
+ return ProjectFile::Unclassified;
+}
+
+void filteredFlags(const QString &fileName,
+ const QString &workingDir,
+ QStringList &flags,
+ HeaderPaths &headerPaths,
+ Macros &macros,
+ CppTools::ProjectFile::Kind &fileKind)
+{
+ if (flags.isEmpty())
+ return;
+
+ // Skip compiler call if present.
+ bool skipNext = Utils::HostOsInfo::isWindowsHost()
+ ? (!flags.first().startsWith('/') && !flags.first().startsWith('-'))
+ : (!flags.first().startsWith('-'));
+ Utils::optional<HeaderPathType> includePathType;
+ Utils::optional<MacroType> macroType;
+ bool fileKindIsNext = false;
+
+ QStringList filtered;
+ for (const QString &flag : flags) {
+ if (skipNext) {
+ skipNext = false;
+ continue;
+ }
+
+ if (includePathType) {
+ const QString pathStr = updatedPathFlag(flag, workingDir);
+ headerPaths.append({pathStr, includePathType.value()});
+ includePathType.reset();
+ continue;
+ }
+
+ if (macroType) {
+ Macro macro = Macro::fromKeyValue(flag);
+ macro.type = macroType.value();
+ macros.append(macro);
+ macroType.reset();
+ continue;
+ }
+
+ if (fileKindIsNext || flag == "/TC" || flag == "/TP"
+ || flag.startsWith("/Tc") || flag.startsWith("/Tp")) {
+ fileKindIsNext = false;
+ fileKind = fileKindFromString(flag);
+ continue;
+ }
+
+ if (flag == "-x") {
+ fileKindIsNext = true;
+ continue;
+ }
+
+ if (flag == "-c" || flag == "-pedantic"
+ || flag.startsWith("-O") || flag.startsWith("-W") || flag.startsWith("-w")
+ || QString::compare(flag, "-fpic", Qt::CaseInsensitive) == 0
+ || QString::compare(flag, "-fpie", Qt::CaseInsensitive) == 0) {
+ continue;
+ }
+
+ if (flag.endsWith(fileName))
+ continue;
+
+ if ((flag.startsWith("-I") || flag.startsWith("-isystem") || flag.startsWith("/I"))
+ && flag != "-I" && flag != "-isystem" && flag != "/I") {
+ bool userInclude = flag.startsWith("-I");
+ const QString pathStr = updatedPathFlag(flag.mid(userInclude ? 2 : 8),
+ workingDir);
+ headerPaths.append({pathStr, userInclude
+ ? HeaderPathType::User
+ : HeaderPathType::System});
+ continue;
+ }
+
+ if ((flag.startsWith("-D") || flag.startsWith("-U") || flag.startsWith("/D") || flag.startsWith("/U"))
+ && flag != "-D" && flag != "-U" && flag != "/D" && flag != "/U") {
+ Macro macro = Macro::fromKeyValue(flag.mid(2));
+ macro.type = (flag.startsWith("-D") || flag.startsWith("/D")) ? MacroType::Define : MacroType::Undefine;
+ macros.append(macro);
+ continue;
+ }
+
+ if (flag == "-I" || flag == "-isystem" || flag == "/I") {
+ includePathType = (flag != "-isystem") ? HeaderPathType::User : HeaderPathType::System;
+ continue;
+ }
+
+ if (flag == "-D" || flag == "-U" || flag == "/D" || flag == "/U") {
+ macroType = (flag == "-D" || flag == "/D") ? MacroType::Define : MacroType::Undefine;
+ continue;
+ }
+
+ if ((flag.startsWith("-std=") || flag.startsWith("/std:"))
+ && fileKind == CppTools::ProjectFile::Unclassified) {
+ const bool cpp = (flag.contains("c++") || flag.contains("gnu++"));
+ if (CppTools::ProjectFile::isHeader(CppTools::ProjectFile::classify(fileName)))
+ fileKind = cpp ? CppTools::ProjectFile::CXXHeader : CppTools::ProjectFile::CHeader;
+ else
+ fileKind = cpp ? CppTools::ProjectFile::CXXSource : CppTools::ProjectFile::CXXHeader;
+ }
+
+ // Skip all remaining Windows flags except feature flags.
+ if (flag.startsWith("/") && !flag.startsWith("/Z"))
+ continue;
+
+ filtered.push_back(flag);
+ }
+
+ if (fileKind == CppTools::ProjectFile::Unclassified)
+ fileKind = CppTools::ProjectFile::classify(fileName);
+
+ flags = filtered;
+}
+
+QStringList splitCommandLine(QString commandLine)
+{
+ QStringList result;
+ bool insideQuotes = false;
+
+ // Remove escaped quotes.
+ commandLine.replace("\\\"", "'");
+ for (const QString &part : commandLine.split(QRegularExpression("\""))) {
+ if (insideQuotes) {
+ const QString quotedPart = "\"" + part + "\"";
+ if (result.last().endsWith("="))
+ result.last().append(quotedPart);
+ else
+ result.append(quotedPart);
+ } else { // If 's' is outside quotes ...
+ result.append(part.split(QRegularExpression("\\s+"), QString::SkipEmptyParts));
+ }
+ insideQuotes = !insideQuotes;
+ }
+ return result;
+}
+
+} // namespace CompilationDatabaseProjectManager
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h
new file mode 100644
index 0000000000..5e123a8c27
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "compilationdatabaseconstants.h"
+
+#include <cpptools/cppprojectfile.h>
+
+#include <QStringList>
+
+namespace ProjectExplorer {
+class HeaderPath;
+class Macro;
+}
+
+namespace CompilationDatabaseProjectManager {
+
+void filteredFlags(const QString &fileName,
+ const QString &workingDir,
+ QStringList &flags,
+ QVector<ProjectExplorer::HeaderPath> &headerPaths,
+ QVector<ProjectExplorer::Macro> &macros,
+ CppTools::ProjectFile::Kind &fileKind);
+
+QStringList splitCommandLine(QString commandLine);
+
+} // namespace CompilationDatabaseProjectManager
diff --git a/src/plugins/compilationdatabaseprojectmanager/database_samples/llvm/compile_commands.json b/src/plugins/compilationdatabaseprojectmanager/database_samples/llvm/compile_commands.json
new file mode 100644
index 0000000000..051439c960
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/database_samples/llvm/compile_commands.json
@@ -0,0 +1,7 @@
+[
+{
+ "directory": "C:/build-qt_llvm-msvc2017_64bit-Debug",
+ "command": "C:\\PROGRA~2\\MICROS~2\\2017\\COMMUN~1\\VC\\Tools\\MSVC\\1415~1.267\\bin\\HostX64\\x64\\cl.exe /nologo /TP -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_GNU_SOURCE -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Dclang=clang_qtcreator -Dllvm=llvm_qtcreator -Itools\\clang\\lib\\Sema -IC:\\qt_llvm\\tools\\clang\\lib\\Sema -IC:\\qt_llvm\\tools\\clang\\include -Itools\\clang\\include -Iinclude -IC:\\qt_llvm\\include /DWIN32 /D_WINDOWS /Zc:inline /Zc:strictStrings /Oi /Zc:rvalueCast /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324 -w14062 -we4238 /MDd /Zi /Ob0 /Od /RTC1 /EHs-c- /GR /Fotools\\clang\\lib\\Sema\\CMakeFiles\\clangSema.dir\\SemaCodeComplete.cpp.obj /FdTARGET_COMPILE_PDB /FS -c C:\\qt_llvm\\tools\\clang\\lib\\Sema\\SemaCodeComplete.cpp",
+ "file": "C:\\qt_llvm\\tools\\clang\\lib\\Sema\\SemaCodeComplete.cpp"
+}
+] \ No newline at end of file
diff --git a/src/plugins/compilationdatabaseprojectmanager/database_samples/qtc/compile_commands.json b/src/plugins/compilationdatabaseprojectmanager/database_samples/qtc/compile_commands.json
new file mode 100644
index 0000000000..d75e8d9654
--- /dev/null
+++ b/src/plugins/compilationdatabaseprojectmanager/database_samples/qtc/compile_commands.json
@@ -0,0 +1,62 @@
+[
+{
+ "arguments": [
+ "clang++",
+ "-c",
+ "-m32",
+ "-target",
+ "i686-w64-mingw32",
+ "-std=gnu++14",
+ "-fcxx-exceptions",
+ "-fexceptions",
+ "-DUNICODE",
+ "-D_UNICODE",
+ "-DCPPTOOLS_LIBRARY",
+ "-DWITH_TESTS",
+ "-DRELATIVE_PLUGIN_PATH=\"../lib/qtcreator/plugins\"",
+ "-DRELATIVE_LIBEXEC_PATH=\".\"",
+ "-DRELATIVE_DATA_PATH=\"../share/qtcreator\"",
+ "-DRELATIVE_DOC_PATH=\"../share/doc/qtcreator\"",
+ "-DIDE_LIBRARY_BASENAME=\"lib\"",
+ "-DQT_CREATOR",
+ "-DQT_NO_CAST_TO_ASCII",
+ "-DQT_RESTRICTED_CAST_FROM_ASCII",
+ "-DQT_DISABLE_DEPRECATED_BEFORE=0x050600",
+ "-DQT_USE_FAST_OPERATOR_PLUS",
+ "-DQT_USE_FAST_CONCATENATION",
+ "-DSRCDIR=\"C:/qt-creator/src/plugins/cpptools\"",
+ "-DQT_QML_DEBUG",
+ "-DQT_PLUGIN",
+ "-DQT_WIDGETS_LIB",
+ "-DQT_GUI_LIB",
+ "-DQT_TESTLIB_LIB",
+ "-DQT_CONCURRENT_LIB",
+ "-DQT_NETWORK_LIB",
+ "-DQT_CORE_LIB",
+ "-fPIC",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtWidgets",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtGui",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtANGLE",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtTest",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtConcurrent",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtNetwork",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtCore",
+ "-I",
+ "C:\\Qt\\5.9.2\\mingw53_32\\mkspecs\\win32-g++",
+ "-x",
+ "c++",
+ "C:\\qt-creator\\src\\plugins\\cpptools\\compileroptionsbuilder.cpp"
+ ],
+ "directory": "C:/build-qtcreator-MinGW_32bit-Debug",
+ "file": "C:/qt-creator/src/plugins/cpptools/compileroptionsbuilder.cpp"
+}
+] \ No newline at end of file