diff options
author | Nikolai Kosjar <[email protected]> | 2020-05-13 14:47:35 +0200 |
---|---|---|
committer | Nikolai Kosjar <[email protected]> | 2020-05-19 12:28:49 +0000 |
commit | 9fc2fda07e0e777dd911ed424fb52b9ed4ab09e5 (patch) | |
tree | 54e574b09bf24b7fb7fe4c2711a2bc1c47ed5294 /src/plugins/clangtools/clangtoolslogfilereader.cpp | |
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 <[email protected]>
Reviewed-by: hjk <[email protected]>
Diffstat (limited to 'src/plugins/clangtools/clangtoolslogfilereader.cpp')
-rw-r--r-- | src/plugins/clangtools/clangtoolslogfilereader.cpp | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/src/plugins/clangtools/clangtoolslogfilereader.cpp b/src/plugins/clangtools/clangtoolslogfilereader.cpp index fc80a1b8299..9acfe6c00ed 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) |