ToolChain: added warningFlags() method

Converts toolchain-specific flags in QFlags.
Will be useful for ClangCodeModel.

Change-Id: I2cff650c952f7c41d3a27535a27fa52b932a0b92
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Sergey Shambir
2013-03-03 21:53:38 +04:00
committed by Erik Verbruggen
parent e0314eb4f3
commit 20b5c3b2c8
8 changed files with 292 additions and 0 deletions

View File

@@ -101,6 +101,55 @@ ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList
} }
} }
/**
* Converts MSVC warning flags to clang flags.
* @see http://msdn.microsoft.com/en-us/library/thxezb7y.aspx
*/
AbstractMsvcToolChain::WarningFlags AbstractMsvcToolChain::warningFlags(const QStringList &cflags) const
{
WarningFlags flags;
foreach (QString flag, cflags) {
if (!flag.isEmpty() && flag[0] == QLatin1Char('-'))
flag[0] = QLatin1Char('/');
if (flag == QLatin1String("/WX"))
flags |= WarningsAsErrors;
else if (flag == QLatin1String("/W0") || flag == QLatin1String("/w"))
inferWarningsForLevel(0, flags);
else if (flag == QLatin1String("/W1"))
inferWarningsForLevel(1, flags);
else if (flag == QLatin1String("/W2"))
inferWarningsForLevel(2, flags);
else if (flag == QLatin1String("/W3") || flag == QLatin1String("/W4") || flag == QLatin1String("/Wall"))
inferWarningsForLevel(3, flags);
WarningFlagAdder add(flag, flags);
if (add.triggered())
continue;
// http://msdn.microsoft.com/en-us/library/ay4h0tc9.aspx
add(4263, WarnOverloadedVirtual);
// http://msdn.microsoft.com/en-us/library/ytxde1x7.aspx
add(4230, WarnIgnoredQualfiers);
// not exact match, http://msdn.microsoft.com/en-us/library/0hx5ckb0.aspx
add(4258, WarnHiddenLocals);
// http://msdn.microsoft.com/en-us/library/wzxffy8c.aspx
add(4265, WarnNonVirtualDestructor);
// http://msdn.microsoft.com/en-us/library/y92ktdf2%28v=vs.90%29.aspx
add(4018, WarnSignedComparison);
// http://msdn.microsoft.com/en-us/library/w099eeey%28v=vs.90%29.aspx
add(4068, WarnUnknownPragma);
// http://msdn.microsoft.com/en-us/library/26kb9fy0%28v=vs.80%29.aspx
add(4100, WarnUnusedParams);
// http://msdn.microsoft.com/en-us/library/c733d5h9%28v=vs.90%29.aspx
add(4101, WarnUnusedLocals);
// http://msdn.microsoft.com/en-us/library/xb1db44s%28v=vs.90%29.aspx
add(4189, WarnUnusedLocals);
// http://msdn.microsoft.com/en-us/library/ttcz0bys%28v=vs.90%29.aspx
add(4996, WarnDeprecated);
}
return flags;
}
QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const
{ {
Q_UNUSED(cxxflags); Q_UNUSED(cxxflags);
@@ -276,6 +325,30 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env,
return true; return true;
} }
/**
* Infers warnings settings on warning level set
* @see http://msdn.microsoft.com/en-us/library/23k5d385.aspx
*/
void AbstractMsvcToolChain::inferWarningsForLevel(int warningLevel, WarningFlags &flags)
{
// reset all except unrelated flag
flags = flags & WarningsAsErrors;
if (warningLevel >= 1) {
flags |= WarningFlags(WarningsDefault | WarnIgnoredQualfiers | WarnHiddenLocals | WarnUnknownPragma);
}
if (warningLevel >= 2) {
flags |= WarningsAll;
}
if (warningLevel >= 3) {
flags |= WarningFlags(WarningsExtra | WarnNonVirtualDestructor | WarnSignedComparison
| WarnUnusedLocals | WarnDeprecated);
}
if (warningLevel >= 4) {
flags |= WarnUnusedParams;
}
}
bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const
{ {
if (!ToolChain::operator ==(other)) if (!ToolChain::operator ==(other))
@@ -286,6 +359,52 @@ bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const
&& m_vcvarsBat == msvcTc->m_vcvarsBat; && m_vcvarsBat == msvcTc->m_vcvarsBat;
} }
AbstractMsvcToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag,
ToolChain::WarningFlags &flags) :
m_flags(flags),
m_triggered(false)
{
if (flag.startsWith(QLatin1String("-wd"))) {
m_doesEnable = false;
} else if (flag.startsWith(QLatin1String("-w"))) {
m_doesEnable = true;
} else {
m_triggered = true;
return;
}
bool ok = false;
if (m_doesEnable)
m_warningCode = flag.mid(2).toInt(&ok);
else
m_warningCode = flag.mid(3).toInt(&ok);
if (!ok)
m_triggered = true;
}
void AbstractMsvcToolChain::WarningFlagAdder::operator ()(int warningCode, ToolChain::WarningFlags flagsSet)
{
if (m_triggered)
return;
if (warningCode == m_warningCode)
{
m_triggered = true;
if (m_doesEnable)
m_flags |= flagsSet;
else
m_flags &= ~flagsSet;
}
}
void AbstractMsvcToolChain::WarningFlagAdder::operator ()(int warningCode, ToolChain::WarningFlag flag)
{
(*this)(warningCode, WarningFlags(flag));
}
bool AbstractMsvcToolChain::WarningFlagAdder::triggered() const
{
return m_triggered;
}
} // namespace Internal } // namespace Internal
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -52,6 +52,7 @@ public:
QByteArray predefinedMacros(const QStringList &cxxflags) const; QByteArray predefinedMacros(const QStringList &cxxflags) const;
CompilerFlags compilerFlags(const QStringList &cxxflags) const; CompilerFlags compilerFlags(const QStringList &cxxflags) const;
WarningFlags warningFlags(const QStringList &cflags) const;
QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const; QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const;
void addToEnvironment(Utils::Environment &env) const; void addToEnvironment(Utils::Environment &env) const;
@@ -71,6 +72,21 @@ public:
QMap<QString, QString> &envPairs); QMap<QString, QString> &envPairs);
protected: protected:
class WarningFlagAdder
{
int m_warningCode;
WarningFlags &m_flags;
bool m_doesEnable;
bool m_triggered;
public:
WarningFlagAdder(const QString &flag, WarningFlags &flags);
void operator ()(int warningCode, WarningFlags flagsSet);
void operator ()(int warningCode, WarningFlag flag);
bool triggered() const;
};
static void inferWarningsForLevel(int warningLevel, WarningFlags &flags);
virtual Utils::Environment readEnvironmentSetting(Utils::Environment& env) const = 0; virtual Utils::Environment readEnvironmentSetting(Utils::Environment& env) const = 0;
virtual QByteArray msvcPredefinedMacros(const QStringList cxxflags, virtual QByteArray msvcPredefinedMacros(const QStringList cxxflags,
const Utils::Environment& env) const; const Utils::Environment& env) const;

View File

@@ -145,6 +145,12 @@ ToolChain::CompilerFlags CustomToolChain::compilerFlags(const QStringList &cxxfl
return NO_FLAGS; return NO_FLAGS;
} }
ToolChain::WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const
{
Q_UNUSED(cxxflags);
return WarningFlags(WarningsDefault);
}
const QStringList &CustomToolChain::rawPredefinedMacros() const const QStringList &CustomToolChain::rawPredefinedMacros() const
{ {
return m_predefinedMacros; return m_predefinedMacros;

View File

@@ -67,6 +67,7 @@ public:
QByteArray predefinedMacros(const QStringList &cxxflags) const; QByteArray predefinedMacros(const QStringList &cxxflags) const;
CompilerFlags compilerFlags(const QStringList &cxxflags) const; CompilerFlags compilerFlags(const QStringList &cxxflags) const;
WarningFlags warningFlags(const QStringList &cxxflags) const;
const QStringList &rawPredefinedMacros() const; const QStringList &rawPredefinedMacros() const;
void setPredefinedMacros(const QStringList &list); void setPredefinedMacros(const QStringList &list);

View File

@@ -436,6 +436,51 @@ ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags
return NO_FLAGS; return NO_FLAGS;
} }
GccToolChain::WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const
{
// based on 'LC_ALL="en" gcc -Q --help=warnings | grep enabled'
WarningFlags flags(WarnDeprecated | WarnIgnoredQualfiers
| WarnSignedComparison | WarnUninitializedVars);
WarningFlags groupWall(WarningsAll | WarnUnknownPragma |WarnUnusedFunctions
| WarnUnusedLocals | WarnUnusedResult | WarnUnusedValue
| WarnSignedComparison | WarnUninitializedVars);
WarningFlags groupWextra(WarningsExtra | WarnIgnoredQualfiers | WarnUnusedParams);
foreach (const QString &flag, cflags) {
if (flag == QLatin1String("--all-warnings"))
flags |= groupWall;
else if (flag == QLatin1String("--extra-warnings"))
flags |= groupWextra;
WarningFlagAdder add(flag, flags);
if (add.triggered())
continue;
// supported by clang too
add("error", WarningsAsErrors);
add("all", groupWall);
add("extra", groupWextra);
add("deprecated", WarnDeprecated);
add("effc++", WarnEffectiveCxx);
add("ignored-qualifiers", WarnIgnoredQualfiers);
add("non-virtual-dtor", WarnNonVirtualDestructor);
add("overloaded-virtual", WarnOverloadedVirtual);
add("shadow", WarnHiddenLocals);
add("sign-compare", WarnSignedComparison);
add("unknown-pragmas", WarnUnknownPragma);
add("unused", ToolChain::WarningFlag(
WarnUnusedFunctions | WarnUnusedLocals | WarnUnusedParams
| WarnUnusedResult | WarnUnusedValue));
add("unused-function", WarnUnusedFunctions);
add("unused-variable", WarnUnusedLocals);
add("unused-parameter", WarnUnusedParams);
add("unused-result", WarnUnusedResult);
add("unused-value", WarnUnusedValue);
add("uninitialized", WarnUninitializedVars);
}
return flags;
}
QList<HeaderPath> GccToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const QList<HeaderPath> GccToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const
{ {
if (m_headerPaths.isEmpty()) { if (m_headerPaths.isEmpty()) {
@@ -827,6 +872,18 @@ QString ClangToolChain::makeCommand(const Utils::Environment &environment) const
return makes.first(); return makes.first();
} }
ToolChain::WarningFlags ClangToolChain::warningFlags(const QStringList &cflags) const
{
WarningFlags flags = GccToolChain::warningFlags(cflags);;
foreach (const QString &flag, cflags) {
if (flag == QLatin1String("-Wdocumentation"))
flags |= WarnDocumentation;
if (flag == QLatin1String("-Wno-documentation"))
flags &= ~WarnDocumentation;
}
return flags;
}
QList<FileName> ClangToolChain::suggestedMkspecList() const QList<FileName> ClangToolChain::suggestedMkspecList() const
{ {
Abi abi = targetAbi(); Abi abi = targetAbi();
@@ -1089,6 +1146,46 @@ GccToolChain *Internal::LinuxIccToolChainFactory::createToolChain(bool autoDetec
return new LinuxIccToolChain(autoDetect); return new LinuxIccToolChain(autoDetect);
} }
GccToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag, ToolChain::WarningFlags &flags) :
m_flags(flags),
m_triggered(false)
{
if (!flag.startsWith(QLatin1String("-W"))) {
m_triggered = true;
return;
}
m_doesEnable = !flag.startsWith(QLatin1String("-Wno-"));
if (m_doesEnable)
m_flagUtf8 = flag.mid(2).toUtf8();
else
m_flagUtf8 = flag.mid(5).toUtf8();
}
void GccToolChain::WarningFlagAdder::operator ()(const char name[], ToolChain::WarningFlags flagsSet)
{
if (m_triggered)
return;
if (0 == strcmp(m_flagUtf8.data(), name))
{
m_triggered = true;
if (m_doesEnable)
m_flags |= flagsSet;
else
m_flags &= ~flagsSet;
}
}
void GccToolChain::WarningFlagAdder::operator ()(const char name[], ToolChain::WarningFlag flag)
{
(*this)(name, WarningFlags(flag));
}
bool GccToolChain::WarningFlagAdder::triggered() const
{
return m_triggered;
}
} // namespace ProjectExplorer } // namespace ProjectExplorer
// Unit tests: // Unit tests:

View File

@@ -66,6 +66,7 @@ public:
QByteArray predefinedMacros(const QStringList &cxxflags) const; QByteArray predefinedMacros(const QStringList &cxxflags) const;
CompilerFlags compilerFlags(const QStringList &cxxflags) const; CompilerFlags compilerFlags(const QStringList &cxxflags) const;
WarningFlags warningFlags(const QStringList &cflags) const;
QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const; QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const;
void addToEnvironment(Utils::Environment &env) const; void addToEnvironment(Utils::Environment &env) const;
@@ -100,6 +101,20 @@ protected:
static const int PREDEFINED_MACROS_CACHE_SIZE; static const int PREDEFINED_MACROS_CACHE_SIZE;
mutable GccCache m_predefinedMacros; mutable GccCache m_predefinedMacros;
class WarningFlagAdder
{
QByteArray m_flagUtf8;
WarningFlags &m_flags;
bool m_doesEnable;
bool m_triggered;
public:
WarningFlagAdder(const QString &flag, WarningFlags &flags);
void operator ()(const char name[], WarningFlags flagsSet);
void operator ()(const char name[], WarningFlag flag);
bool triggered() const;
};
private: private:
GccToolChain(bool autodetect); GccToolChain(bool autodetect);
@@ -127,6 +142,8 @@ public:
QString typeDisplayName() const; QString typeDisplayName() const;
QString makeCommand(const Utils::Environment &environment) const; QString makeCommand(const Utils::Environment &environment) const;
WarningFlags warningFlags(const QStringList &cflags) const;
IOutputParser *outputParser() const; IOutputParser *outputParser() const;
ToolChain *clone() const; ToolChain *clone() const;

View File

@@ -215,6 +215,11 @@ QList<Task> ToolChain::validateKit(const Kit *) const
\brief Name used to display the name of the tool chain that will be created. \brief Name used to display the name of the tool chain that will be created.
*/ */
/*!
\fn QStringList ProjectExplorer::ToolChain::clangParserFlags(const QStringList &cxxflags) const = 0
\brief Converts toolchain-specific flags to list flags that tunes libclang parser
*/
/*! /*!
\fn bool ProjectExplorer::ToolChainFactory::canRestore(const QVariantMap &data) \fn bool ProjectExplorer::ToolChainFactory::canRestore(const QVariantMap &data)
\brief Used by the ToolChainManager to restore user-generated tool chains. \brief Used by the ToolChainManager to restore user-generated tool chains.

View File

@@ -87,6 +87,37 @@ public:
STD_CXX11 = 1 STD_CXX11 = 1
}; };
virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0; virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0;
enum WarningFlag {
// General settings
WarningsAsErrors,
WarningsDefault,
WarningsAll,
WarningsExtra,
WarningsPedantic,
// Any language
WarnUnusedLocals,
WarnUnusedParams,
WarnUnusedFunctions,
WarnUnusedResult,
WarnUnusedValue,
WarnDocumentation,
WarnUninitializedVars,
WarnHiddenLocals,
WarnUnknownPragma,
WarnDeprecated,
WarnSignedComparison,
WarnIgnoredQualfiers,
// C++
WarnOverloadedVirtual,
WarnEffectiveCxx,
WarnNonVirtualDestructor
};
Q_DECLARE_FLAGS(WarningFlags, WarningFlag)
virtual WarningFlags warningFlags(const QStringList &cflags) const = 0;
virtual QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, virtual QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags,
const Utils::FileName &sysRoot) const = 0; const Utils::FileName &sysRoot) const = 0;
virtual void addToEnvironment(Utils::Environment &env) const = 0; virtual void addToEnvironment(Utils::Environment &env) const = 0;