From 1601f53542027017b43531dc58f202d1ba2635cb Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Fri, 17 Nov 2017 14:13:55 +0100 Subject: [PATCH] Clang: StaticAnalyzer: use the default compiler options builder Analyzer has clang path and can generate necessary header paths to be able to use default options builder. Change-Id: I9bb1fc158f045f6e099817c5557ee7d9e38416fb Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzerruncontrol.cpp | 60 +++++++------------ .../clangstaticanalyzerruncontrol.h | 2 +- .../cpptools/compileroptionsbuilder.cpp | 19 ++++-- src/plugins/cpptools/compileroptionsbuilder.h | 7 +++ 4 files changed, 43 insertions(+), 45 deletions(-) diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index 1e26c408a24..679e06b99fe 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -191,37 +191,9 @@ QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStri return newArguments; } -class ClangStaticAnalyzerOptionsBuilder final : public CompilerOptionsBuilder -{ -public: - ClangStaticAnalyzerOptionsBuilder(const CppTools::ProjectPart &projectPart) - : CompilerOptionsBuilder(projectPart) - { - } - - bool excludeHeaderPath(const QString &headerPath) const final - { - if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID - && headerPath.contains(m_projectPart.toolChainTargetTriple)) { - return true; - } - return CompilerOptionsBuilder::excludeHeaderPath(headerPath); - } - - void addPredefinedHeaderPathsOptions() final - { - add("-undef"); - if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { - // exclude default clang path to use msvc includes - add("-nostdinc"); - add("-nostdlibinc"); - } - } -}; - static QStringList createMsCompatibilityVersionOption(const ProjectPart &projectPart) { - ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart); + CompilerOptionsBuilder optionsBuilder(projectPart); optionsBuilder.addMsvcCompatibilityVersion(); const QStringList option = optionsBuilder.options(); @@ -231,7 +203,7 @@ static QStringList createMsCompatibilityVersionOption(const ProjectPart &project static QStringList createOptionsToUndefineCppLanguageFeatureMacrosForMsvc2015( const ProjectPart &projectPart) { - ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart); + CompilerOptionsBuilder optionsBuilder(projectPart); optionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015(); return optionsBuilder.options(); @@ -239,7 +211,7 @@ static QStringList createOptionsToUndefineCppLanguageFeatureMacrosForMsvc2015( static QStringList createOptionsToUndefineClangVersionMacrosForMsvc(const ProjectPart &projectPart) { - ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart); + CompilerOptionsBuilder optionsBuilder(projectPart); optionsBuilder.undefineClangVersionMacrosForMsvc(); return optionsBuilder.options(); @@ -251,7 +223,7 @@ static QStringList createHeaderPathsOptionsForClangOnMac(const ProjectPart &proj if (Utils::HostOsInfo::isMacHost() && projectPart.toolchainType == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) { - ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart); + CompilerOptionsBuilder optionsBuilder(projectPart); optionsBuilder.addHeaderPathOptions(); options = optionsBuilder.options(); } @@ -310,7 +282,9 @@ static AnalyzeUnits unitsToAnalyzeFromCompilerCallData( return unitsToAnalyze; } -static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector projectParts) +static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector projectParts, + const QString &clangVersion, + const QString &clangResourceDirectory) { qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts."; @@ -327,8 +301,9 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector generateCallGroupToProjectPartMapping( return mapping; } -AnalyzeUnits ClangStaticAnalyzerToolRunner::sortedUnitsToAnalyze() +static QString clangResourceDir(const QString &clangExecutable, const QString &clangVersion) +{ + QDir llvmDir = QFileInfo(clangExecutable).dir(); + llvmDir.cdUp(); + return llvmDir.absolutePath() + clangIncludePath(clangVersion); +} + +AnalyzeUnits ClangStaticAnalyzerToolRunner::sortedUnitsToAnalyze(const QString &clangVersion) { QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits()); AnalyzeUnits units; const ProjectInfo::CompilerCallData compilerCallData = m_projectInfo.compilerCallData(); if (compilerCallData.isEmpty()) { - units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts()); + const QString clangResourceDirectory = clangResourceDir(m_clangExecutable, clangVersion); + units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(), clangVersion, + clangResourceDirectory); } else { const QHash callGroupToProjectPart = generateCallGroupToProjectPartMapping(m_projectInfo.projectParts()); @@ -480,7 +464,7 @@ void ClangStaticAnalyzerToolRunner::start() m_clangLogFileDir = temporaryDir.path(); // Collect files - const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(); + const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(version.toString()); qCDebug(LOG) << "Files to process:" << unitsToProcess; m_unitsToProcess = unitsToProcess; m_initialFilesToProcessSize = m_unitsToProcess.count(); diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h index 16d50f085cd..e5425d0c4be 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h @@ -62,7 +62,7 @@ private: void start() final; void stop() final; - AnalyzeUnits sortedUnitsToAnalyze(); + AnalyzeUnits sortedUnitsToAnalyze(const QString &clangVersion); void analyzeNextFile(); ClangStaticAnalyzerRunner *createRunner(); diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 100c39bfc21..8f1ed2c4166 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -29,6 +29,7 @@ #include +#include #include #include @@ -499,14 +500,20 @@ bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions() { - add("-undef"); add("-nostdinc"); add("-nostdlibinc"); - if (!m_clangVersion.isEmpty() - && m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { - add(includeDirOption() + clangIncludeDirectory()); - } + // In case of MSVC we need builtin clang defines to correctly handle clang includes + if (m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) + add("-undef"); + + addClangIncludeFolder(); +} + +void CompilerOptionsBuilder::addClangIncludeFolder() +{ + QTC_CHECK(!m_clangVersion.isEmpty()); + add(includeDirOption() + clangIncludeDirectory()); } void CompilerOptionsBuilder::addProjectConfigFileInclude() @@ -528,7 +535,7 @@ static QString creatorLibexecPath() QString CompilerOptionsBuilder::clangIncludeDirectory() const { - QDir dir(creatorLibexecPath() + "/clang/lib/clang/" + m_clangVersion + "/include"); + QDir dir(creatorLibexecPath() + "/clang" + clangIncludePath(m_clangVersion)); if (!dir.exists() || !QFileInfo(dir, "stdint.h").exists()) dir = QDir(m_clangResourceDirectory); return QDir::toNativeSeparators(dir.canonicalPath()); diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h index 1f91bafcb18..d27f19ba483 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.h +++ b/src/plugins/cpptools/compileroptionsbuilder.h @@ -90,10 +90,17 @@ private: QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const; QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const; QString clangIncludeDirectory() const; + void addClangIncludeFolder(); QStringList m_options; QString m_clangVersion; QString m_clangResourceDirectory; }; +template +T clangIncludePath(const T &clangVersion) +{ + return "/lib/clang/" + clangVersion + "/include"; +} + } // namespace CppTools