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) const ProjectInfo &projectInfo)
: AnalyzerRunControl(startParams, runConfiguration) : AnalyzerRunControl(startParams, runConfiguration)
, m_projectInfo(projectInfo) , m_projectInfo(projectInfo)
, m_toolchainType(ProjectExplorer::ToolChainKitInformation
::toolChain(runConfiguration->target()->kit())->type())
, m_wordWidth(runConfiguration->abi().wordWidth()) , m_wordWidth(runConfiguration->abi().wordWidth())
, m_initialFilesToProcessSize(0) , m_initialFilesToProcessSize(0)
, m_filesAnalyzed(0) , m_filesAnalyzed(0)
@@ -113,27 +111,113 @@ static QStringList tweakedArguments(const QString &filePath,
return newArguments; return newArguments;
} }
static QStringList argumentsFromProjectPart(const CppTools::ProjectPart::Ptr &projectPart, static QString createLanguageOptionMsvc(ProjectFile::Kind fileKind)
CppTools::ProjectFile::Kind fileKind,
const QString &toolchainType,
unsigned char wordWidth)
{ {
CompilerOptionsBuilder optionsBuilder(projectPart); switch (fileKind) {
optionsBuilder.addLanguageOption(fileKind, toolchainType); case ProjectFile::CHeader:
optionsBuilder.addOptionsForLanguage(false, toolchainType); case ProjectFile::CSource:
optionsBuilder.addToolchainAndProjectDefines(toolchainType); return QLatin1String("/TC");
optionsBuilder.addHeaderPathOptions(CompilerOptionsBuilder::IsBlackListed(), toolchainType); break;
case ProjectFile::CXXHeader:
if (toolchainType == QLatin1String("msvc")) case ProjectFile::CXXSource:
optionsBuilder.add(QLatin1String("/EHsc")); // clang-cl does not understand exceptions return QLatin1String("/TP");
else break;
optionsBuilder.add(QLatin1String("-fPIC")); // TODO: Remove? default:
break;
QStringList options = optionsBuilder.options(); }
prependWordWidthArgumentIfNotIncluded(&options, wordWidth); return QString();
return options;
} }
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( static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
const ProjectInfo::CompilerCallData &compilerCallData, const ProjectInfo::CompilerCallData &compilerCallData,
unsigned char wordWidth) unsigned char wordWidth)
@@ -157,7 +241,6 @@ static AnalyzeUnits unitsToAnalyzeFromCompilerCallData(
} }
static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr> projectParts, static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr> projectParts,
const QString &toolchainType,
unsigned char wordWidth) unsigned char wordWidth)
{ {
qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts."; qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts.";
@@ -173,10 +256,8 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr>
continue; continue;
QTC_CHECK(file.kind != ProjectFile::Unclassified); QTC_CHECK(file.kind != ProjectFile::Unclassified);
if (ProjectFile::isSource(file.kind)) { if (ProjectFile::isSource(file.kind)) {
const QStringList arguments = argumentsFromProjectPart(projectPart, const QStringList arguments
file.kind, = ClangStaticAnalyzerOptionsBuilder::build(projectPart, file.kind, wordWidth);
toolchainType,
wordWidth);
unitsToAnalyze << AnalyzeUnit(file.path, arguments); unitsToAnalyze << AnalyzeUnit(file.path, arguments);
} }
} }
@@ -193,7 +274,6 @@ 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_toolchainType,
m_wordWidth); m_wordWidth);
} else { } else {
units = unitsToAnalyzeFromCompilerCallData(compilerCallData, m_wordWidth); units = unitsToAnalyzeFromCompilerCallData(compilerCallData, m_wordWidth);
@@ -219,6 +299,12 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
return debug; return debug;
} }
static QString toolchainType(ProjectExplorer::RunConfiguration *runConfiguration)
{
QTC_ASSERT(runConfiguration, return QString());
return ToolChainKitInformation::toolChain(runConfiguration->target()->kit())->type();
}
bool ClangStaticAnalyzerRunControl::startEngine() bool ClangStaticAnalyzerRunControl::startEngine()
{ {
m_success = false; m_success = false;
@@ -231,8 +317,8 @@ bool ClangStaticAnalyzerRunControl::startEngine()
// Check clang executable // Check clang executable
bool isValidClangExecutable; bool isValidClangExecutable;
const QString executable const QString executable = clangExecutableFromSettings(toolchainType(runConfiguration()),
= clangExecutableFromSettings(m_toolchainType, &isValidClangExecutable); &isValidClangExecutable);
if (!isValidClangExecutable) { if (!isValidClangExecutable) {
const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.") const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.")
.arg(executable); .arg(executable);

View File

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