ClangStaticAnalyzer: Set target explicitly for gcc toolchains

The default target of clang.exe might be unfavorable since it depends on
e.g. the tool chain used to build clang.exe:

                            default target
     clang build with msvc: i686-pc-windows-msvc
    clang build with mingw: i686-pc-windows-gnu

The correct target is important since it not only has implications on
the built-in macros and include paths, but also on parsing options. For
example, the msvc target silently adds the following parsing options

    -fms-extensions
    -fms-compatibility
    -fms-compatibility-version=17.00
    -fdelayed-template-parsing

...as can be seen by the output of

    $ clang.exe -### empty.cpp

Change-Id: Icd8aaf11016e59f37025cbf1c97da81511ff249b
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2016-03-04 15:33:33 +01:00
parent 5c030a4336
commit 768c900990
2 changed files with 39 additions and 9 deletions

View File

@@ -80,6 +80,7 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl(
BuildConfiguration *buildConfiguration = target->activeBuildConfiguration(); BuildConfiguration *buildConfiguration = target->activeBuildConfiguration();
QTC_ASSERT(buildConfiguration, return); QTC_ASSERT(buildConfiguration, return);
m_environment = buildConfiguration->environment(); m_environment = buildConfiguration->environment();
m_targetTriple = ToolChainKitInformation::toolChain(target->kit())->originalTargetTriple();
} }
static void prependWordWidthArgumentIfNotIncluded(QStringList *arguments, unsigned char wordWidth) static void prependWordWidthArgumentIfNotIncluded(QStringList *arguments, unsigned char wordWidth)
@@ -96,11 +97,29 @@ static void prependWordWidthArgumentIfNotIncluded(QStringList *arguments, unsign
QTC_CHECK(!arguments->contains(m32Argument) || !arguments->contains(m64Argument)); QTC_CHECK(!arguments->contains(m32Argument) || !arguments->contains(m64Argument));
} }
static void prependTargetTripleIfNotIncludedAndNotEmpty(QStringList *arguments,
const QString &targetTriple)
{
QTC_ASSERT(arguments, return);
if (targetTriple.isEmpty())
return;
const QString targetOption = QLatin1String("-target");
if (!arguments->contains(targetOption)) {
arguments->prepend(targetTriple);
arguments->prepend(targetOption);
}
}
// Removes (1) filePath (2) -o <somePath>. // Removes (1) filePath (2) -o <somePath>.
// Adds -m64/-m32 argument if not already included. // Prepends -m64/-m32 argument if not already included.
// Prepends -target if not already included.
static QStringList tweakedArguments(const QString &filePath, static QStringList tweakedArguments(const QString &filePath,
const QStringList &arguments, const QStringList &arguments,
unsigned char wordWidth) unsigned char wordWidth,
const QString &targetTriple)
{ {
QStringList newArguments; QStringList newArguments;
@@ -121,6 +140,7 @@ static QStringList tweakedArguments(const QString &filePath,
QTC_CHECK(skip == false); QTC_CHECK(skip == false);
prependWordWidthArgumentIfNotIncluded(&newArguments, wordWidth); prependWordWidthArgumentIfNotIncluded(&newArguments, wordWidth);
prependTargetTripleIfNotIncludedAndNotEmpty(&newArguments, targetTriple);
return newArguments; return newArguments;
} }
@@ -147,7 +167,8 @@ class ClangStaticAnalyzerOptionsBuilder : public CompilerOptionsBuilder
public: public:
static QStringList build(const CppTools::ProjectPart &projectPart, static QStringList build(const CppTools::ProjectPart &projectPart,
CppTools::ProjectFile::Kind fileKind, CppTools::ProjectFile::Kind fileKind,
unsigned char wordWidth) unsigned char wordWidth,
const QString &targetTriple)
{ {
ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart); ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
optionsBuilder.addLanguageOption(fileKind); optionsBuilder.addLanguageOption(fileKind);
@@ -172,6 +193,8 @@ public:
QStringList options = optionsBuilder.options(); QStringList options = optionsBuilder.options();
prependWordWidthArgumentIfNotIncluded(&options, wordWidth); prependWordWidthArgumentIfNotIncluded(&options, wordWidth);
prependTargetTripleIfNotIncludedAndNotEmpty(&options, targetTriple);
return options; return options;
} }
@@ -217,7 +240,8 @@ private:
static AnalyzeUnits unitsToAnalyzeFromCompilerCallData( static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
const ProjectInfo::CompilerCallData &compilerCallData, const ProjectInfo::CompilerCallData &compilerCallData,
unsigned char wordWidth) unsigned char wordWidth,
const QString &targetTriple)
{ {
qCDebug(LOG) << "Taking arguments for analyzing from CompilerCallData."; qCDebug(LOG) << "Taking arguments for analyzing from CompilerCallData.";
@@ -229,7 +253,7 @@ static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
const QString file = it.key(); const QString file = it.key();
const QList<QStringList> compilerCalls = it.value(); const QList<QStringList> compilerCalls = it.value();
foreach (const QStringList &options, compilerCalls) { foreach (const QStringList &options, compilerCalls) {
const QStringList arguments = tweakedArguments(file, options, wordWidth); const QStringList arguments = tweakedArguments(file, options, wordWidth, targetTriple);
unitsToAnalyze << AnalyzeUnit(file, arguments); unitsToAnalyze << AnalyzeUnit(file, arguments);
} }
} }
@@ -238,7 +262,8 @@ static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
} }
static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr> projectParts, static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr> projectParts,
unsigned char wordWidth) unsigned char wordWidth,
const QString &targetTriple)
{ {
qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts."; qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts.";
@@ -256,7 +281,8 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr>
const QStringList arguments const QStringList arguments
= ClangStaticAnalyzerOptionsBuilder::build(*projectPart.data(), = ClangStaticAnalyzerOptionsBuilder::build(*projectPart.data(),
file.kind, file.kind,
wordWidth); wordWidth,
targetTriple);
unitsToAnalyze << AnalyzeUnit(file.path, arguments); unitsToAnalyze << AnalyzeUnit(file.path, arguments);
} }
} }
@@ -273,9 +299,12 @@ AnalyzeUnits ClangStaticAnalyzerRunControl::sortedUnitsToAnalyze()
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(), units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(),
m_wordWidth); m_wordWidth,
m_targetTriple);
} else { } else {
units = unitsToAnalyzeFromCompilerCallData(compilerCallData, m_wordWidth); units = unitsToAnalyzeFromCompilerCallData(compilerCallData,
m_wordWidth,
m_targetTriple);
} }
Utils::sort(units, [](const AnalyzeUnit &a1, const AnalyzeUnit &a2) -> bool { Utils::sort(units, [](const AnalyzeUnit &a1, const AnalyzeUnit &a2) -> bool {

View File

@@ -83,6 +83,7 @@ private:
private: private:
const CppTools::ProjectInfo m_projectInfo; const CppTools::ProjectInfo m_projectInfo;
const unsigned char m_wordWidth; const unsigned char m_wordWidth;
QString m_targetTriple;
Utils::Environment m_environment; Utils::Environment m_environment;
QString m_clangExecutable; QString m_clangExecutable;