forked from qt-creator/qt-creator
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:
@@ -191,37 +191,9 @@ QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStri
|
|||||||
return newArguments;
|
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)
|
static QStringList createMsCompatibilityVersionOption(const ProjectPart &projectPart)
|
||||||
{
|
{
|
||||||
ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
|
CompilerOptionsBuilder optionsBuilder(projectPart);
|
||||||
optionsBuilder.addMsvcCompatibilityVersion();
|
optionsBuilder.addMsvcCompatibilityVersion();
|
||||||
const QStringList option = optionsBuilder.options();
|
const QStringList option = optionsBuilder.options();
|
||||||
|
|
||||||
@@ -231,7 +203,7 @@ static QStringList createMsCompatibilityVersionOption(const ProjectPart &project
|
|||||||
static QStringList createOptionsToUndefineCppLanguageFeatureMacrosForMsvc2015(
|
static QStringList createOptionsToUndefineCppLanguageFeatureMacrosForMsvc2015(
|
||||||
const ProjectPart &projectPart)
|
const ProjectPart &projectPart)
|
||||||
{
|
{
|
||||||
ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
|
CompilerOptionsBuilder optionsBuilder(projectPart);
|
||||||
optionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015();
|
optionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||||
|
|
||||||
return optionsBuilder.options();
|
return optionsBuilder.options();
|
||||||
@@ -239,7 +211,7 @@ static QStringList createOptionsToUndefineCppLanguageFeatureMacrosForMsvc2015(
|
|||||||
|
|
||||||
static QStringList createOptionsToUndefineClangVersionMacrosForMsvc(const ProjectPart &projectPart)
|
static QStringList createOptionsToUndefineClangVersionMacrosForMsvc(const ProjectPart &projectPart)
|
||||||
{
|
{
|
||||||
ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
|
CompilerOptionsBuilder optionsBuilder(projectPart);
|
||||||
optionsBuilder.undefineClangVersionMacrosForMsvc();
|
optionsBuilder.undefineClangVersionMacrosForMsvc();
|
||||||
|
|
||||||
return optionsBuilder.options();
|
return optionsBuilder.options();
|
||||||
@@ -251,7 +223,7 @@ static QStringList createHeaderPathsOptionsForClangOnMac(const ProjectPart &proj
|
|||||||
|
|
||||||
if (Utils::HostOsInfo::isMacHost()
|
if (Utils::HostOsInfo::isMacHost()
|
||||||
&& projectPart.toolchainType == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) {
|
&& projectPart.toolchainType == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) {
|
||||||
ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
|
CompilerOptionsBuilder optionsBuilder(projectPart);
|
||||||
optionsBuilder.addHeaderPathOptions();
|
optionsBuilder.addHeaderPathOptions();
|
||||||
options = optionsBuilder.options();
|
options = optionsBuilder.options();
|
||||||
}
|
}
|
||||||
@@ -310,7 +282,9 @@ static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
|
|||||||
return unitsToAnalyze;
|
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.";
|
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);
|
QTC_CHECK(file.kind != ProjectFile::Unsupported);
|
||||||
if (ProjectFile::isSource(file.kind)) {
|
if (ProjectFile::isSource(file.kind)) {
|
||||||
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
||||||
const QStringList arguments
|
CompilerOptionsBuilder optionsBuilder(*projectPart, clangVersion,
|
||||||
= ClangStaticAnalyzerOptionsBuilder(*projectPart).build(file.kind, pchUsage);
|
clangResourceDirectory);
|
||||||
|
const QStringList arguments = optionsBuilder.build(file.kind, pchUsage);
|
||||||
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
|
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,14 +325,23 @@ static QHash<QString, ProjectPart::Ptr> generateCallGroupToProjectPartMapping(
|
|||||||
return mapping;
|
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());
|
QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits());
|
||||||
|
|
||||||
AnalyzeUnits units;
|
AnalyzeUnits units;
|
||||||
const ProjectInfo::CompilerCallData compilerCallData = m_projectInfo.compilerCallData();
|
const ProjectInfo::CompilerCallData compilerCallData = m_projectInfo.compilerCallData();
|
||||||
if (compilerCallData.isEmpty()) {
|
if (compilerCallData.isEmpty()) {
|
||||||
units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts());
|
const QString clangResourceDirectory = clangResourceDir(m_clangExecutable, clangVersion);
|
||||||
|
units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(), clangVersion,
|
||||||
|
clangResourceDirectory);
|
||||||
} else {
|
} else {
|
||||||
const QHash<QString, ProjectPart::Ptr> callGroupToProjectPart
|
const QHash<QString, ProjectPart::Ptr> callGroupToProjectPart
|
||||||
= generateCallGroupToProjectPartMapping(m_projectInfo.projectParts());
|
= generateCallGroupToProjectPartMapping(m_projectInfo.projectParts());
|
||||||
@@ -480,7 +464,7 @@ void ClangStaticAnalyzerToolRunner::start()
|
|||||||
m_clangLogFileDir = temporaryDir.path();
|
m_clangLogFileDir = temporaryDir.path();
|
||||||
|
|
||||||
// Collect files
|
// Collect files
|
||||||
const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze();
|
const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(version.toString());
|
||||||
qCDebug(LOG) << "Files to process:" << unitsToProcess;
|
qCDebug(LOG) << "Files to process:" << unitsToProcess;
|
||||||
m_unitsToProcess = unitsToProcess;
|
m_unitsToProcess = unitsToProcess;
|
||||||
m_initialFilesToProcessSize = m_unitsToProcess.count();
|
m_initialFilesToProcessSize = m_unitsToProcess.count();
|
||||||
|
@@ -62,7 +62,7 @@ private:
|
|||||||
void start() final;
|
void start() final;
|
||||||
void stop() final;
|
void stop() final;
|
||||||
|
|
||||||
AnalyzeUnits sortedUnitsToAnalyze();
|
AnalyzeUnits sortedUnitsToAnalyze(const QString &clangVersion);
|
||||||
void analyzeNextFile();
|
void analyzeNextFile();
|
||||||
ClangStaticAnalyzerRunner *createRunner();
|
ClangStaticAnalyzerRunner *createRunner();
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcfallthrough.h>
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -499,14 +500,20 @@ bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const
|
|||||||
|
|
||||||
void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions()
|
void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions()
|
||||||
{
|
{
|
||||||
add("-undef");
|
|
||||||
add("-nostdinc");
|
add("-nostdinc");
|
||||||
add("-nostdlibinc");
|
add("-nostdlibinc");
|
||||||
|
|
||||||
if (!m_clangVersion.isEmpty()
|
// In case of MSVC we need builtin clang defines to correctly handle clang includes
|
||||||
&& m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
if (m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||||
add(includeDirOption() + clangIncludeDirectory());
|
add("-undef");
|
||||||
|
|
||||||
|
addClangIncludeFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompilerOptionsBuilder::addClangIncludeFolder()
|
||||||
|
{
|
||||||
|
QTC_CHECK(!m_clangVersion.isEmpty());
|
||||||
|
add(includeDirOption() + clangIncludeDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerOptionsBuilder::addProjectConfigFileInclude()
|
void CompilerOptionsBuilder::addProjectConfigFileInclude()
|
||||||
@@ -528,7 +535,7 @@ static QString creatorLibexecPath()
|
|||||||
|
|
||||||
QString CompilerOptionsBuilder::clangIncludeDirectory() const
|
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())
|
if (!dir.exists() || !QFileInfo(dir, "stdint.h").exists())
|
||||||
dir = QDir(m_clangResourceDirectory);
|
dir = QDir(m_clangResourceDirectory);
|
||||||
return QDir::toNativeSeparators(dir.canonicalPath());
|
return QDir::toNativeSeparators(dir.canonicalPath());
|
||||||
|
@@ -90,10 +90,17 @@ private:
|
|||||||
QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const;
|
QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const;
|
||||||
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
|
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
|
||||||
QString clangIncludeDirectory() const;
|
QString clangIncludeDirectory() const;
|
||||||
|
void addClangIncludeFolder();
|
||||||
|
|
||||||
QStringList m_options;
|
QStringList m_options;
|
||||||
QString m_clangVersion;
|
QString m_clangVersion;
|
||||||
QString m_clangResourceDirectory;
|
QString m_clangResourceDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T clangIncludePath(const T &clangVersion)
|
||||||
|
{
|
||||||
|
return "/lib/clang/" + clangVersion + "/include";
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
Reference in New Issue
Block a user