Adapt to upstream API change in CompilerOptionsBuilder II

Change-Id: I196b69846e22136773cf3cbf463a413d840dc4d2
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-06-26 13:53:50 +02:00
parent c26e6e398b
commit fafb0cb8d4
2 changed files with 114 additions and 29 deletions

View File

@@ -61,8 +61,6 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl(
const ProjectInfo &projectInfo)
: AnalyzerRunControl(startParams, runConfiguration)
, m_projectInfo(projectInfo)
, m_toolchainType(ProjectExplorer::ToolChainKitInformation
::toolChain(runConfiguration->target()->kit())->type())
, m_wordWidth(runConfiguration->abi().wordWidth())
, m_initialFilesToProcessSize(0)
, m_filesAnalyzed(0)
@@ -113,27 +111,113 @@ static QStringList tweakedArguments(const QString &filePath,
return newArguments;
}
static QStringList argumentsFromProjectPart(const CppTools::ProjectPart::Ptr &projectPart,
CppTools::ProjectFile::Kind fileKind,
const QString &toolchainType,
unsigned char wordWidth)
static QString createLanguageOptionMsvc(ProjectFile::Kind fileKind)
{
CompilerOptionsBuilder optionsBuilder(projectPart);
optionsBuilder.addLanguageOption(fileKind, toolchainType);
optionsBuilder.addOptionsForLanguage(false, toolchainType);
optionsBuilder.addToolchainAndProjectDefines(toolchainType);
optionsBuilder.addHeaderPathOptions(CompilerOptionsBuilder::IsBlackListed(), toolchainType);
if (toolchainType == QLatin1String("msvc"))
optionsBuilder.add(QLatin1String("/EHsc")); // clang-cl does not understand exceptions
else
optionsBuilder.add(QLatin1String("-fPIC")); // TODO: Remove?
QStringList options = optionsBuilder.options();
prependWordWidthArgumentIfNotIncluded(&options, wordWidth);
return options;
switch (fileKind) {
case ProjectFile::CHeader:
case ProjectFile::CSource:
return QLatin1String("/TC");
break;
case ProjectFile::CXXHeader:
case ProjectFile::CXXSource:
return QLatin1String("/TP");
break;
default:
break;
}
return QString();
}
class ClangStaticAnalyzerOptionsBuilder : public CompilerOptionsBuilder
{
public:
static QStringList build(const CppTools::ProjectPart::Ptr &projectPart,
CppTools::ProjectFile::Kind fileKind,
unsigned char wordWidth)
{
ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
optionsBuilder.addLanguageOption(fileKind);
optionsBuilder.addOptionsForLanguage(false);
// In gcc headers, lots of built-ins are referenced that clang does not understand.
// Therefore, prevent the inclusion of the header that references them. Of course, this
// will break if code actually requires stuff from there, but that should be the less common
// case.
const QString type = projectPart->toolchainType;
if (type == QLatin1String("mingw") || type == QLatin1String("gcc"))
optionsBuilder.addDefine("#define _X86INTRIN_H_INCLUDED\n");
optionsBuilder.addToolchainAndProjectDefines();
optionsBuilder.addHeaderPathOptions();
if (projectPart->toolchainType == QLatin1String("msvc"))
optionsBuilder.add(QLatin1String("/EHsc")); // clang-cl does not understand exceptions
else
optionsBuilder.add(QLatin1String("-fPIC")); // TODO: Remove?
QStringList options = optionsBuilder.options();
prependWordWidthArgumentIfNotIncluded(&options, wordWidth);
return options;
}
private:
ClangStaticAnalyzerOptionsBuilder(const CppTools::ProjectPart::Ptr &projectPart)
: CompilerOptionsBuilder(projectPart)
, m_isMsvcToolchain(m_projectPart->toolchainType == QLatin1String("msvc"))
{
}
void addLanguageOption(ProjectFile::Kind fileKind) override
{
if (m_isMsvcToolchain)
add(createLanguageOptionMsvc(fileKind));
else
CompilerOptionsBuilder::addLanguageOption(fileKind);
}
void addOptionsForLanguage(bool checkForBorlandExtensions) override
{
if (m_isMsvcToolchain)
return;
CompilerOptionsBuilder::addOptionsForLanguage(checkForBorlandExtensions);
}
QString includeOption() const override
{
if (m_isMsvcToolchain)
return QLatin1String("/I");
return CompilerOptionsBuilder::includeOption();
}
QString defineOption() const override
{
if (m_isMsvcToolchain)
return QLatin1String("/D");
return CompilerOptionsBuilder::defineOption();
}
bool excludeDefineLine(const QByteArray &defineLine) const override
{
if (CompilerOptionsBuilder::excludeDefineLine(defineLine))
return true;
// gcc 4.9 has:
// #define __has_include(STR) __has_include__(STR)
// #define __has_include_next(STR) __has_include_next__(STR)
// The right-hand sides are gcc built-ins that clang does not understand, and they'd
// override clang's own (non-macro, it seems) definitions of the symbols on the left-hand
// side.
const bool isGccToolchain = m_projectPart->toolchainType == QLatin1String("gcc");
if (isGccToolchain && defineLine.contains("has_include"))
return true;
return false;
}
private:
bool m_isMsvcToolchain;
};
static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
const ProjectInfo::CompilerCallData &compilerCallData,
unsigned char wordWidth)
@@ -157,7 +241,6 @@ static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
}
static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr> projectParts,
const QString &toolchainType,
unsigned char wordWidth)
{
qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts.";
@@ -173,10 +256,8 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr>
continue;
QTC_CHECK(file.kind != ProjectFile::Unclassified);
if (ProjectFile::isSource(file.kind)) {
const QStringList arguments = argumentsFromProjectPart(projectPart,
file.kind,
toolchainType,
wordWidth);
const QStringList arguments
= ClangStaticAnalyzerOptionsBuilder::build(projectPart, file.kind, wordWidth);
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
}
}
@@ -193,7 +274,6 @@ AnalyzeUnits ClangStaticAnalyzerRunControl::sortedUnitsToAnalyze()
const ProjectInfo::CompilerCallData compilerCallData = m_projectInfo.compilerCallData();
if (compilerCallData.isEmpty()) {
units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(),
m_toolchainType,
m_wordWidth);
} else {
units = unitsToAnalyzeFromCompilerCallData(compilerCallData, m_wordWidth);
@@ -219,6 +299,12 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
return debug;
}
static QString toolchainType(ProjectExplorer::RunConfiguration *runConfiguration)
{
QTC_ASSERT(runConfiguration, return QString());
return ToolChainKitInformation::toolChain(runConfiguration->target()->kit())->type();
}
bool ClangStaticAnalyzerRunControl::startEngine()
{
m_success = false;
@@ -231,8 +317,8 @@ bool ClangStaticAnalyzerRunControl::startEngine()
// Check clang executable
bool isValidClangExecutable;
const QString executable
= clangExecutableFromSettings(m_toolchainType, &isValidClangExecutable);
const QString executable = clangExecutableFromSettings(toolchainType(runConfiguration()),
&isValidClangExecutable);
if (!isValidClangExecutable) {
const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.")
.arg(executable);

View File

@@ -71,7 +71,6 @@ private:
private:
const CppTools::ProjectInfo m_projectInfo;
const QString m_toolchainType;
const unsigned char m_wordWidth;
QString m_clangExecutable;