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 <nikolai.kosjar@qt.io>
This commit is contained in:
Ivan Donchevskii
2017-11-17 14:13:55 +01:00
parent 0269503dd8
commit 1601f53542
4 changed files with 43 additions and 45 deletions

View File

@@ -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<ProjectPart::Ptr> projectParts)
static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Ptr> projectParts,
const QString &clangVersion,
const QString &clangResourceDirectory)
{
qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts.";
@@ -327,8 +301,9 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
QTC_CHECK(file.kind != ProjectFile::Unsupported);
if (ProjectFile::isSource(file.kind)) {
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
const QStringList arguments
= ClangStaticAnalyzerOptionsBuilder(*projectPart).build(file.kind, pchUsage);
CompilerOptionsBuilder optionsBuilder(*projectPart, clangVersion,
clangResourceDirectory);
const QStringList arguments = optionsBuilder.build(file.kind, pchUsage);
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
}
}
@@ -350,14 +325,23 @@ static QHash<QString, ProjectPart::Ptr> 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<QString, ProjectPart::Ptr> 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();

View File

@@ -62,7 +62,7 @@ private:
void start() final;
void stop() final;
AnalyzeUnits sortedUnitsToAnalyze();
AnalyzeUnits sortedUnitsToAnalyze(const QString &clangVersion);
void analyzeNextFile();
ClangStaticAnalyzerRunner *createRunner();

View File

@@ -29,6 +29,7 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
#include <utils/qtcfallthrough.h>
#include <QDir>
@@ -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) {
// 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());

View File

@@ -90,10 +90,17 @@ private:
QByteArray toDefineOption(const ProjectExplorer::Macro &macro) const;
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
QString clangIncludeDirectory() const;
void addClangIncludeFolder();
QStringList m_options;
QString m_clangVersion;
QString m_clangResourceDirectory;
};
template<class T>
T clangIncludePath(const T &clangVersion)
{
return "/lib/clang/" + clangVersion + "/include";
}
} // namespace CppTools