diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2020-05-13 14:47:35 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2020-05-19 12:28:49 +0000 |
commit | 9fc2fda07e0e777dd911ed424fb52b9ed4ab09e5 (patch) | |
tree | 54e574b09bf24b7fb7fe4c2711a2bc1c47ed5294 /src/plugins/clangtools | |
parent | e2a68edbc18242b2766d15a7d851ad9d49d4b6e7 (diff) |
ClangTools: Remove dependency to libclang and custom clang binary
Before this change, we've invoked a custom clang binary that had clazy
statically compiled into it. The invocation also ensured that the
diagnostics were serialized to a file, so that libclang could be used
afterwards to read them.
As the clazy-standalone executable supports exporting diagnostics to a
YAML file now (just as clang-tidy) and Qt Creator ships it already, rely
on that executable alone instead of the clang/libclang combo.
While we do not depend on any clang header or library at build-time now,
the CompilerOptionsBuilder constructor still needs the CLANG_VERSION and
CLANG_RESOURCE_DIR pieces from llvm-config. This dependency should be
removed as next.
Change-Id: I4fa5753ab09008fd24bc5247b28c4836b5e8ca45
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins/clangtools')
-rw-r--r-- | src/plugins/clangtools/clangtidyclazyrunner.cpp | 36 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtidyclazyrunner.h | 8 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtool.cpp | 7 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtool.h | 1 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtoolruncontrol.cpp | 9 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtools.pro | 3 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtools.qbs | 8 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtoolslogfilereader.cpp | 192 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtoolslogfilereader.h | 8 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtoolsutils.cpp | 1 | ||||
-rw-r--r-- | src/plugins/clangtools/settingswidget.cpp | 23 |
11 files changed, 14 insertions, 282 deletions
diff --git a/src/plugins/clangtools/clangtidyclazyrunner.cpp b/src/plugins/clangtools/clangtidyclazyrunner.cpp index 166d1c94e0..5bab62b474 100644 --- a/src/plugins/clangtools/clangtidyclazyrunner.cpp +++ b/src/plugins/clangtools/clangtidyclazyrunner.cpp @@ -53,28 +53,6 @@ static bool isClMode(const QStringList &options) return options.contains("--driver-mode=cl"); } -static QStringList serializeDiagnosticsArguments(const QStringList &baseOptions, - const QString &outputFilePath) -{ - const QStringList serializeArgs{"-serialize-diagnostics", outputFilePath}; - if (isClMode(baseOptions)) - return clangArgsForCl(serializeArgs); - return serializeArgs; -} - -static QStringList clazyPluginArguments(const ClangDiagnosticConfig diagnosticConfig) -{ - QStringList arguments; - - if (diagnosticConfig.isClazyEnabled()) { - arguments << XclangArgs({"-add-plugin", "clazy"}); - if (!diagnosticConfig.clazyChecks().isEmpty()) - arguments << XclangArgs({"-plugin-arg-clazy", diagnosticConfig.clazyChecks()}); - } - - return arguments; -} - static QStringList tidyChecksArguments(const ClangDiagnosticConfig diagnosticConfig) { const ClangDiagnosticConfig::TidyMode tidyMode = diagnosticConfig.clangTidyMode(); @@ -147,19 +125,5 @@ ClazyStandaloneRunner::ClazyStandaloneRunner(const ClangDiagnosticConfig &config }); } -ClazyPluginRunner::ClazyPluginRunner(const ClangDiagnosticConfig &config, QObject *parent) - : ClangToolRunner(parent) -{ - setName(tr("Clazy")); - setOutputFileFormat(OutputFileFormat::Serialized); - setExecutable(Core::ICore::clangExecutable(CLANG_BINDIR)); - setArgsCreator([this, config](const QStringList &baseOptions) { - return serializeDiagnosticsArguments(baseOptions, outputFilePath()) - << clazyPluginArguments(config) - << clangArguments(config, baseOptions) - << QDir::toNativeSeparators(fileToAnalyze()); - }); -} - } // namespace Internal } // namespace ClangTools diff --git a/src/plugins/clangtools/clangtidyclazyrunner.h b/src/plugins/clangtools/clangtidyclazyrunner.h index 72cd7a155c..ec9b940a18 100644 --- a/src/plugins/clangtools/clangtidyclazyrunner.h +++ b/src/plugins/clangtools/clangtidyclazyrunner.h @@ -48,13 +48,5 @@ public: ClazyStandaloneRunner(const CppTools::ClangDiagnosticConfig &config, QObject *parent = nullptr); }; -class ClazyPluginRunner final : public ClangToolRunner -{ - Q_OBJECT - -public: - ClazyPluginRunner(const CppTools::ClangDiagnosticConfig &config, QObject *parent = nullptr); -}; - } // namespace Internal } // namespace ClangTools diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index f23a088889..d96bdfd40f 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -717,7 +717,6 @@ void ClangTool::startTool(ClangTool::FileSelection fileSelection, Diagnostics ClangTool::read(OutputFileFormat outputFileFormat, const QString &logFilePath, - const QString &mainFilePath, const QSet<FilePath> &projectFiles, QString *errorMessage) const { @@ -730,10 +729,8 @@ Diagnostics ClangTool::read(OutputFileFormat outputFileFormat, acceptFromFilePath, errorMessage); } - return readSerializedDiagnostics(Utils::FilePath::fromString(logFilePath), - Utils::FilePath::fromString(mainFilePath), - acceptFromFilePath, - errorMessage); + + return {}; } FileInfos ClangTool::collectFileInfos(Project *project, FileSelection fileSelection) diff --git a/src/plugins/clangtools/clangtool.h b/src/plugins/clangtools/clangtool.h index b867cf1845..7882245e91 100644 --- a/src/plugins/clangtools/clangtool.h +++ b/src/plugins/clangtools/clangtool.h @@ -96,7 +96,6 @@ public: Diagnostics read(OutputFileFormat outputFileFormat, const QString &logFilePath, - const QString &mainFilePath, const QSet<Utils::FilePath> &projectFiles, QString *errorMessage) const; diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index 3932d5b440..2d077a1502 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -236,12 +236,8 @@ QList<RunnerCreator> ClangToolRunWorker::runnerCreators() if (m_diagnosticConfig.isClangTidyEnabled()) creators << [this]() { return createRunner<ClangTidyRunner>(); }; - if (m_diagnosticConfig.isClazyEnabled()) { - if (!qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH").isEmpty()) - creators << [this]() { return createRunner<ClazyStandaloneRunner>(); }; - else - creators << [this]() { return createRunner<ClazyPluginRunner>(); }; - } + if (m_diagnosticConfig.isClazyEnabled()) + creators << [this]() { return createRunner<ClazyStandaloneRunner>(); }; return creators; } @@ -388,7 +384,6 @@ void ClangToolRunWorker::onRunnerFinishedWithSuccess(const QString &filePath) QString errorMessage; const Diagnostics diagnostics = tool()->read(runner->outputFileFormat(), outputFilePath, - filePath, m_projectFiles, &errorMessage); diff --git a/src/plugins/clangtools/clangtools.pro b/src/plugins/clangtools/clangtools.pro index 9b1076fbda..7abb6bc53b 100644 --- a/src/plugins/clangtools/clangtools.pro +++ b/src/plugins/clangtools/clangtools.pro @@ -4,9 +4,6 @@ include(../../shared/clang/clang_defines.pri) requires(!isEmpty(LLVM_VERSION)) -LIBS += $$LIBCLANG_LIBS -INCLUDEPATH += $$LLVM_INCLUDEPATH - include(../../shared/yaml-cpp/yaml-cpp_installation.pri) isEmpty(EXTERNAL_YAML_CPP_FOUND) { DEFINES += YAML_CPP_DLL diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs index 07ec6201b1..e3d93e34f5 100644 --- a/src/plugins/clangtools/clangtools.qbs +++ b/src/plugins/clangtools/clangtools.qbs @@ -12,7 +12,6 @@ QtcPlugin { Depends { name: "QtcSsh" } Depends { name: "Utils" } - Depends { name: "libclang"; required: false } Depends { name: "yaml-cpp" } Depends { name: "clang_defines" } @@ -27,13 +26,6 @@ QtcPlugin { "QmakeProjectManager", ] - condition: libclang.present - - cpp.includePaths: base.concat(libclang.llvmIncludeDir) - cpp.libraryPaths: base.concat(libclang.llvmLibDir) - cpp.dynamicLibraries: base.concat(libclang.llvmLibs) - cpp.rpaths: base.concat(libclang.llvmLibDir) - files: [ "clangfileinfo.h", "clangfixitsrefactoringchanges.cpp", diff --git a/src/plugins/clangtools/clangtoolslogfilereader.cpp b/src/plugins/clangtools/clangtoolslogfilereader.cpp index fc80a1b829..9acfe6c00e 100644 --- a/src/plugins/clangtools/clangtoolslogfilereader.cpp +++ b/src/plugins/clangtools/clangtoolslogfilereader.cpp @@ -27,198 +27,17 @@ #include <cpptools/cppprojectfile.h> -#include <QDebug> #include <QDir> -#include <QFile> #include <QFileInfo> -#include <QObject> -#include <QRegularExpression> -#include <QXmlStreamReader> -#include <utils/executeondestruction.h> #include <utils/fileutils.h> -#include <utils/hostosinfo.h> -#include <utils/qtcassert.h> #include <utils/textutils.h> -#include <clang-c/Index.h> - #include <yaml-cpp/yaml.h> namespace ClangTools { namespace Internal { -static QString fromCXString(CXString &&cxString) -{ - QString result = QString::fromUtf8(clang_getCString(cxString)); - clang_disposeString(cxString); - return result; -} - -static Debugger::DiagnosticLocation diagLocationFromSourceLocation(CXSourceLocation cxLocation) -{ - CXFile file; - unsigned line; - unsigned column; - clang_getSpellingLocation(cxLocation, &file, &line, &column, nullptr); - - Debugger::DiagnosticLocation location; - location.filePath = fromCXString(clang_getFileName(file)); - location.filePath = QDir::cleanPath(location.filePath); // Normalize to find duplicates later - location.line = line; - location.column = column; - return location; -} - -static QString cxDiagnosticType(const CXDiagnostic cxDiagnostic) -{ - const CXDiagnosticSeverity severity = clang_getDiagnosticSeverity(cxDiagnostic); - switch (severity) { - case CXDiagnostic_Note: - return QString("note"); - case CXDiagnostic_Warning: - return QString("warning"); - case CXDiagnostic_Error: - return QString("error"); - case CXDiagnostic_Fatal: - return QString("fatal"); - case CXDiagnostic_Ignored: - return QString("ignored"); - } - return QString("ignored"); -} - -static ExplainingStep buildChildDiagnostic(const CXDiagnostic cxDiagnostic) -{ - ExplainingStep diagnosticStep; - QString type = cxDiagnosticType(cxDiagnostic); - if (type == QStringLiteral("ignored")) - return diagnosticStep; - - const CXSourceLocation cxLocation = clang_getDiagnosticLocation(cxDiagnostic); - diagnosticStep.location = diagLocationFromSourceLocation(cxLocation); - diagnosticStep.message = fromCXString(clang_getDiagnosticSpelling(cxDiagnostic)); - return diagnosticStep; -} - -static bool isInvalidDiagnosticLocation(const Diagnostic &diagnostic, const ExplainingStep &child, - const QString &nativeFilePath) -{ - // When main file is considered included by itself - this diagnostic has invalid location. - // This case usually happens when original diagnostic comes from system header but - // has main file name set in the source location instead (which is incorrect). - return child.message.indexOf(nativeFilePath) >= 0 - && child.message.indexOf("in file included from") >= 0 - && diagnostic.location.filePath == nativeFilePath; -} - -static ExplainingStep buildFixIt(const CXDiagnostic cxDiagnostic, unsigned index) -{ - ExplainingStep fixItStep; - CXSourceRange cxFixItRange; - fixItStep.isFixIt = true; - fixItStep.message = fromCXString(clang_getDiagnosticFixIt(cxDiagnostic, index, &cxFixItRange)); - fixItStep.location = diagLocationFromSourceLocation(clang_getRangeStart(cxFixItRange)); - fixItStep.ranges.push_back(fixItStep.location); - fixItStep.ranges.push_back(diagLocationFromSourceLocation(clang_getRangeEnd(cxFixItRange))); - return fixItStep; -} - -static Diagnostic buildDiagnostic(const CXDiagnostic cxDiagnostic, - const AcceptDiagsFromFilePath &acceptFromFilePath, - const QString &nativeFilePath) -{ - Diagnostic diagnostic; - diagnostic.type = cxDiagnosticType(cxDiagnostic); - if (diagnostic.type == QStringLiteral("ignored")) - return diagnostic; - - const CXSourceLocation cxLocation = clang_getDiagnosticLocation(cxDiagnostic); - if (clang_Location_isInSystemHeader(cxLocation)) - return diagnostic; - - diagnostic.location = diagLocationFromSourceLocation(cxLocation); - const auto diagnosticFilePath = Utils::FilePath::fromString(diagnostic.location.filePath); - if (acceptFromFilePath && !acceptFromFilePath(diagnosticFilePath)) - return diagnostic; - - // TODO: Introduce CppTools::ProjectFile::isGenerated to filter these out properly - const QString fileName = diagnosticFilePath.fileName(); - if ((fileName.startsWith("ui_") && fileName.endsWith(".h")) || fileName.endsWith(".moc")) - return diagnostic; - - CXDiagnosticSet cxChildDiagnostics = clang_getChildDiagnostics(cxDiagnostic); - Utils::ExecuteOnDestruction onBuildExit([&]() { - clang_disposeDiagnosticSet(cxChildDiagnostics); - }); - - using CppTools::ProjectFile; - const bool isHeaderFile = ProjectFile::isHeader( - ProjectFile::classify(diagnostic.location.filePath)); - - for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(cxChildDiagnostics); ++i) { - CXDiagnostic cxDiagnostic = clang_getDiagnosticInSet(cxChildDiagnostics, i); - Utils::ExecuteOnDestruction cleanUpDiagnostic([&]() { - clang_disposeDiagnostic(cxDiagnostic); - }); - const ExplainingStep diagnosticStep = buildChildDiagnostic(cxDiagnostic); - if (diagnosticStep.isValid()) - continue; - - if (isHeaderFile && diagnosticStep.message.contains("in file included from")) - continue; - - if (isInvalidDiagnosticLocation(diagnostic, diagnosticStep, nativeFilePath)) - return diagnostic; - - diagnostic.explainingSteps.push_back(diagnosticStep); - } - - const unsigned fixItCount = clang_getDiagnosticNumFixIts(cxDiagnostic); - diagnostic.hasFixits = fixItCount != 0; - for (unsigned i = 0; i < fixItCount; ++i) - diagnostic.explainingSteps.push_back(buildFixIt(cxDiagnostic, i)); - - diagnostic.description = fromCXString(clang_getDiagnosticSpelling(cxDiagnostic)); - diagnostic.category = fromCXString(clang_getDiagnosticCategoryText(cxDiagnostic)); - - return diagnostic; -} - -static Diagnostics readSerializedDiagnostics_helper(const Utils::FilePath &logFilePath, - const Utils::FilePath &mainFilePath, - const AcceptDiagsFromFilePath &acceptFromFilePath) -{ - Diagnostics list; - CXLoadDiag_Error error; - CXString errorString; - - CXDiagnosticSet diagnostics = clang_loadDiagnostics(logFilePath.toString().toStdString().c_str(), - &error, - &errorString); - if (error != CXLoadDiag_None || !diagnostics) - return list; - - Utils::ExecuteOnDestruction onReadExit([&]() { - clang_disposeDiagnosticSet(diagnostics); - }); - - const QString nativeFilePath = QDir::toNativeSeparators(mainFilePath.toString()); - for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) { - CXDiagnostic cxDiagnostic = clang_getDiagnosticInSet(diagnostics, i); - Utils::ExecuteOnDestruction cleanUpDiagnostic([&]() { - clang_disposeDiagnostic(cxDiagnostic); - }); - const Diagnostic diagnostic = buildDiagnostic(cxDiagnostic, acceptFromFilePath, nativeFilePath); - if (!diagnostic.isValid()) - continue; - - list.push_back(diagnostic); - } - - return list; -} - static bool checkFilePath(const Utils::FilePath &filePath, QString *errorMessage) { QFileInfo fi(filePath.toFileInfo()); @@ -234,17 +53,6 @@ static bool checkFilePath(const Utils::FilePath &filePath, QString *errorMessage return true; } -Diagnostics readSerializedDiagnostics(const Utils::FilePath &logFilePath, - const Utils::FilePath &mainFilePath, - const AcceptDiagsFromFilePath &acceptFromFilePath, - QString *errorMessage) -{ - if (!checkFilePath(logFilePath, errorMessage)) - return {}; - - return readSerializedDiagnostics_helper(logFilePath, mainFilePath, acceptFromFilePath); -} - Utils::optional<LineColumnInfo> byteOffsetInUtf8TextToLineColumn(const char *text, int offset, int startLine) diff --git a/src/plugins/clangtools/clangtoolslogfilereader.h b/src/plugins/clangtools/clangtoolslogfilereader.h index 996f7ffbeb..8d06eb853f 100644 --- a/src/plugins/clangtools/clangtoolslogfilereader.h +++ b/src/plugins/clangtools/clangtoolslogfilereader.h @@ -34,16 +34,10 @@ namespace Utils { class FilePath; } namespace ClangTools { namespace Internal { -enum class OutputFileFormat { Serialized, Yaml }; +enum class OutputFileFormat { Yaml }; using AcceptDiagsFromFilePath = std::function<bool(const Utils::FilePath &)>; -// Reads diagnostics generated by "clang -serialize-diagnostics path/to/file" -Diagnostics readSerializedDiagnostics(const Utils::FilePath &logFilePath, - const Utils::FilePath &mainFilePath, - const AcceptDiagsFromFilePath &acceptFromFilePath, - QString *errorMessage); - // Reads diagnostics generated by "clang-tidy/clazy-standalone -export-fixes=path/to/file" Diagnostics readExportedDiagnostics(const Utils::FilePath &logFilePath, const AcceptDiagsFromFilePath &acceptFromFilePath, diff --git a/src/plugins/clangtools/clangtoolsutils.cpp b/src/plugins/clangtools/clangtoolsutils.cpp index 7fbcc35889..661a2165d0 100644 --- a/src/plugins/clangtools/clangtoolsutils.cpp +++ b/src/plugins/clangtools/clangtoolsutils.cpp @@ -153,7 +153,6 @@ QString clazyStandaloneFallbackExecutable() { return findValidExecutable({ shippedClazyStandaloneExecutable(), - qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH"), Constants::CLAZY_STANDALONE_EXECUTABLE_NAME, }); } diff --git a/src/plugins/clangtools/settingswidget.cpp b/src/plugins/clangtools/settingswidget.cpp index a095450d26..b2ef284641 100644 --- a/src/plugins/clangtools/settingswidget.cpp +++ b/src/plugins/clangtools/settingswidget.cpp @@ -95,20 +95,15 @@ SettingsWidget::SettingsWidget() path, "ClangTools.ClangTidyExecutable.History"); - if (qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH").isEmpty()) { - m_ui->clazyStandalonePathChooser->setVisible(false); - m_ui->clazyStandaloneLabel->setVisible(false); - } else { - placeHolderText = shippedClazyStandaloneExecutable(); - path = m_settings->clazyStandaloneExecutable(); - if (path.isEmpty() && placeHolderText.isEmpty()) - path = Constants::CLAZY_STANDALONE_EXECUTABLE_NAME; - setupPathChooser(m_ui->clazyStandalonePathChooser, - tr("Clazy Executable"), - placeHolderText, - path, - "ClangTools.ClazyStandaloneExecutable.History"); - } + placeHolderText = shippedClazyStandaloneExecutable(); + path = m_settings->clazyStandaloneExecutable(); + if (path.isEmpty() && placeHolderText.isEmpty()) + path = Constants::CLAZY_STANDALONE_EXECUTABLE_NAME; + setupPathChooser(m_ui->clazyStandalonePathChooser, + tr("Clazy Executable"), + placeHolderText, + path, + "ClangTools.ClazyStandaloneExecutable.History"); // // Group box "Run Options" |