Commit 20b5c3b2 authored by Sergey Shambir's avatar Sergey Shambir Committed by Erik Verbruggen
Browse files

ToolChain: added warningFlags() method



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

Change-Id: I2cff650c952f7c41d3a27535a27fa52b932a0b92
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent e0314eb4
......@@ -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
{
Q_UNUSED(cxxflags);
......@@ -276,6 +325,30 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env,
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
{
if (!ToolChain::operator ==(other))
......@@ -286,6 +359,52 @@ bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const
&& 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 ProjectExplorer
......
......@@ -52,6 +52,7 @@ public:
QByteArray predefinedMacros(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;
void addToEnvironment(Utils::Environment &env) const;
......@@ -71,6 +72,21 @@ public:
QMap<QString, QString> &envPairs);
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 QByteArray msvcPredefinedMacros(const QStringList cxxflags,
const Utils::Environment& env) const;
......
......@@ -145,6 +145,12 @@ ToolChain::CompilerFlags CustomToolChain::compilerFlags(const QStringList &cxxfl
return NO_FLAGS;
}
ToolChain::WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const
{
Q_UNUSED(cxxflags);
return WarningFlags(WarningsDefault);
}
const QStringList &CustomToolChain::rawPredefinedMacros() const
{
return m_predefinedMacros;
......
......@@ -67,6 +67,7 @@ public:
QByteArray predefinedMacros(const QStringList &cxxflags) const;
CompilerFlags compilerFlags(const QStringList &cxxflags) const;
WarningFlags warningFlags(const QStringList &cxxflags) const;
const QStringList &rawPredefinedMacros() const;
void setPredefinedMacros(const QStringList &list);
......
......@@ -436,6 +436,51 @@ ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags
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
{
if (m_headerPaths.isEmpty()) {
......@@ -827,6 +872,18 @@ QString ClangToolChain::makeCommand(const Utils::Environment &environment) const
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
{
Abi abi = targetAbi();
......@@ -1089,6 +1146,46 @@ GccToolChain *Internal::LinuxIccToolChainFactory::createToolChain(bool autoDetec
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
// Unit tests:
......
......@@ -66,6 +66,7 @@ public:
QByteArray predefinedMacros(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;
void addToEnvironment(Utils::Environment &env) const;
......@@ -100,6 +101,20 @@ protected:
static const int PREDEFINED_MACROS_CACHE_SIZE;
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:
GccToolChain(bool autodetect);
......@@ -127,6 +142,8 @@ public:
QString typeDisplayName() const;
QString makeCommand(const Utils::Environment &environment) const;
WarningFlags warningFlags(const QStringList &cflags) const;
IOutputParser *outputParser() const;
ToolChain *clone() const;
......
......@@ -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.
*/
/*!
\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)
\brief Used by the ToolChainManager to restore user-generated tool chains.
......
......@@ -87,6 +87,37 @@ public:
STD_CXX11 = 1
};
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,
const Utils::FileName &sysRoot) const = 0;
virtual void addToEnvironment(Utils::Environment &env) const = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment