ProjectExplorer: extended Toolchain::CompilerFlags

Now it provides information about C language standard and C++
extensions. No new behavior added to project managers.

Change-Id: Ib7c19641f452a75c9b14cd7e33d104dcd1603720
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
Sergey Shambir
2013-04-28 13:11:48 +04:00
parent 6ab892f067
commit 6faf45a465
8 changed files with 127 additions and 22 deletions

View File

@@ -406,7 +406,7 @@ bool CMakeProject::parseCMakeLists()
part->frameworkPaths = allFrameworkPaths;
part->cVersion = CppTools::ProjectPart::C99;
if (tc)
part->cxxVersion = tc->compilerFlags(cxxflags) == ToolChain::STD_CXX11
part->cxxVersion = (tc->compilerFlags(cxxflags) | ToolChain::StandardCxx11)
? CppTools::ProjectPart::CXX11
: CppTools::ProjectPart::CXX98;
else

View File

@@ -90,15 +90,19 @@ QByteArray AbstractMsvcToolChain::predefinedMacros(const QStringList &cxxflags)
ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList &cxxflags) const
{
Q_UNUSED(cxxflags);
CompilerFlags flags(MicrosoftExtensions);
if (cxxflags.contains(QLatin1String("/openmp")))
flags |= OpenMP;
switch (m_abi.osFlavor()) {
case ProjectExplorer::Abi::WindowsMsvc2010Flavor:
case ProjectExplorer::Abi::WindowsMsvc2012Flavor:
return STD_CXX11;
default:
return NO_FLAGS;
}
// see http://msdn.microsoft.com/en-us/library/0k0w269d%28v=vs.71%29.aspx
if (cxxflags.contains(QLatin1String("/Za")))
flags &= ~MicrosoftExtensions;
if (m_abi.osFlavor() == Abi::WindowsMsvc2010Flavor
|| m_abi.osFlavor() == Abi::WindowsMsvc2012Flavor)
flags |= StandardCxx11;
return flags;
}
/**

View File

@@ -141,8 +141,8 @@ ToolChain::CompilerFlags CustomToolChain::compilerFlags(const QStringList &cxxfl
{
foreach (const QString &cxx11Flag, m_cxx11Flags)
if (cxxflags.contains(cxx11Flag))
return STD_CXX11;
return NO_FLAGS;
return StandardCxx11;
return NoFlags;
}
ToolChain::WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const

View File

@@ -350,6 +350,11 @@ QString GccToolChain::defaultDisplayName() const
compilerCommand().parentDir().toUserOutput());
}
ToolChain::CompilerFlags GccToolChain::defaultCompilerFlags() const
{
return CompilerFlags(GnuExtensions);
}
QString GccToolChain::type() const
{
return QLatin1String("gcc");
@@ -434,14 +439,57 @@ QByteArray GccToolChain::predefinedMacros(const QStringList &cxxflags) const
return runResults.second;
}
/**
* @brief Parses gcc flags -std=*, -fopenmp, -fms-extensions, -ansi.
* @see http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
*/
ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags) const
{
QStringList allCxxflags = m_platformCodeGenFlags + cxxflags; // add only cxxflags is empty?
if (allCxxflags.contains(QLatin1String("-std=c++0x")) || allCxxflags.contains(QLatin1String("-std=gnu++0x")) ||
allCxxflags.contains(QLatin1String("-std=c++11")) || allCxxflags.contains(QLatin1String("-std=gnu++11")) ||
allCxxflags.contains(QLatin1String("-std=c++1y")) || allCxxflags.contains(QLatin1String("-std=gnu++1y")))
return STD_CXX11;
return NO_FLAGS;
CompilerFlags flags = defaultCompilerFlags();
const QStringList allCxxflags = m_platformCodeGenFlags + cxxflags; // add only cxxflags is empty?
foreach (const QString &flag, allCxxflags) {
if (flag.startsWith(QLatin1String("-std="))) {
const QByteArray std = flag.mid(5).toAscii();
if (std == "c++98" || std == "c++03") {
flags &= ~CompilerFlags(StandardCxx11 | GnuExtensions);
} else if (std == "gnu++98" || std == "gnu++03") {
flags &= ~StandardCxx11;
flags |= GnuExtensions;
} else if (std == "c++0x" || std == "c++11" || std== "c++1y") {
flags |= StandardCxx11;
flags &= ~GnuExtensions;
} else if (std == "gnu++0x" || std == "gnu++11" || std== "gnu++1y") {
flags |= CompilerFlags(StandardCxx11 | GnuExtensions);
} else if (std == "c89" || std == "c90"
|| std == "iso9899:1990" | std == "iso9899:199409") {
flags &= ~CompilerFlags(StandardC99 | StandardC11);
} else if (std == "gnu89" || std == "gnu90") {
flags &= ~CompilerFlags(StandardC99 | StandardC11);
flags |= GnuExtensions;
} else if (std == "c99" || std == "c9x"
|| std == "iso9899:1999" || std == "iso9899:199x") {
flags |= StandardC99;
flags &= ~StandardC11;
} else if (std == "gnu99" || std == "gnu9x") {
flags |= CompilerFlags(StandardC99 | GnuExtensions);
flags &= ~StandardC11;
} else if (std == "c11" || std == "c1x" || std == "iso9899:2011") {
flags |= CompilerFlags(StandardC99 | StandardC11);
} else if (std == "gnu11" || std == "gnu1x") {
flags |= CompilerFlags(StandardC99 | StandardC11 | GnuExtensions);
}
} else if (flag == QLatin1String("-fopenmp")) {
flags |= OpenMP;
} else if (flag == QLatin1String("-fms-extensions")) {
flags |= MicrosoftExtensions;
} else if (flag == QLatin1String("-ansi")) {
flags &= ~CompilerFlags(StandardCxx11 | GnuExtensions
| StandardC99 | StandardC11);
}
}
return flags;
}
GccToolChain::WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const
@@ -973,6 +1021,18 @@ QString ClangToolChain::makeCommand(const Utils::Environment &environment) const
return makes.first();
}
/**
* @brief Similar to \a GccToolchain::compilerFlags, but recognizes
* "-fborland-extensions".
*/
ToolChain::CompilerFlags ClangToolChain::compilerFlags(const QStringList &cxxflags) const
{
CompilerFlags flags = GccToolChain::compilerFlags(cxxflags);
if (cxxflags.contains(QLatin1String("-fborland-extensions")))
flags |= BorlandExtensions;
return flags;
}
ToolChain::WarningFlags ClangToolChain::warningFlags(const QStringList &cflags) const
{
WarningFlags flags = GccToolChain::warningFlags(cflags);;
@@ -999,6 +1059,11 @@ QList<FileName> ClangToolChain::suggestedMkspecList() const
return QList<FileName>(); // Note: Not supported by Qt yet, so default to the mkspec the Qt was build with
}
ToolChain::CompilerFlags ClangToolChain::defaultCompilerFlags() const
{
return CompilerFlags(GnuExtensions | StandardC99 | StandardCxx11);
}
IOutputParser *ClangToolChain::outputParser() const
{
return new ClangParser;
@@ -1187,6 +1252,28 @@ QString LinuxIccToolChain::typeDisplayName() const
return Internal::LinuxIccToolChainFactory::tr("Linux ICC");
}
/**
* Similar to \a GccToolchain::compilerFlags, but uses "-openmp" instead of
* "-fopenmp" and "-fms-dialect[=ver]" instead of "-fms-extensions".
* @see UNIX manual for "icc"
*/
ToolChain::CompilerFlags LinuxIccToolChain::compilerFlags(const QStringList &cxxflags) const
{
QStringList copy = cxxflags;
copy.removeAll(QLatin1String("-fopenmp"));
copy.removeAll(QLatin1String("-fms-extensions"));
CompilerFlags flags = GccToolChain::compilerFlags(cxxflags);
if (cxxflags.contains(QLatin1String("-openmp")))
flags |= OpenMP;
if (cxxflags.contains(QLatin1String("-fms-dialect"))
|| cxxflags.contains(QLatin1String("-fms-dialect=8"))
|| cxxflags.contains(QLatin1String("-fms-dialect=9"))
|| cxxflags.contains(QLatin1String("-fms-dialect=10")))
flags |= MicrosoftExtensions;
return flags;
}
IOutputParser *LinuxIccToolChain::outputParser() const
{
return new LinuxIccParser;

View File

@@ -97,6 +97,7 @@ protected:
GccToolChain(const GccToolChain &);
virtual QString defaultDisplayName() const;
virtual CompilerFlags defaultCompilerFlags() const;
virtual QList<Abi> detectSupportedAbis() const;
virtual QString detectVersion() const;
@@ -149,6 +150,7 @@ public:
QString typeDisplayName() const;
QString makeCommand(const Utils::Environment &environment) const;
CompilerFlags compilerFlags(const QStringList &cxxflags) const;
WarningFlags warningFlags(const QStringList &cflags) const;
IOutputParser *outputParser() const;
@@ -157,6 +159,9 @@ public:
QList<Utils::FileName> suggestedMkspecList() const;
protected:
virtual CompilerFlags defaultCompilerFlags() const;
private:
ClangToolChain(bool autodetect);
@@ -196,6 +201,7 @@ public:
QString type() const;
QString typeDisplayName() const;
CompilerFlags compilerFlags(const QStringList &cxxflags) const;
IOutputParser *outputParser() const;
ToolChain *clone() const;

View File

@@ -82,10 +82,18 @@ public:
virtual QByteArray predefinedMacros(const QStringList &cxxflags) const = 0;
enum CompilerFlags {
NO_FLAGS = 0,
STD_CXX11 = 1
enum CompilerFlag {
NoFlags = 0,
StandardCxx11 = 0x1,
StandardC99 = 0x2,
StandardC11 = 0x4,
GnuExtensions = 0x8,
MicrosoftExtensions = 0x10,
BorlandExtensions = 0x20,
OpenMP = 0x40
};
Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag)
virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0;
enum WarningFlag {

View File

@@ -483,7 +483,7 @@ void QbsProject::updateCppCodeModel(const qbs::ProjectData *prj)
if (tc) {
includePaths = tc->systemHeaderPaths(cxxFlags, ProjectExplorer::SysRootKitInformation::sysRoot(k));
grpDefines += tc->predefinedMacros(cxxFlags);
if (tc->compilerFlags(cxxFlags) == ProjectExplorer::ToolChain::STD_CXX11)
if (tc->compilerFlags(cxxFlags) | ProjectExplorer::ToolChain::StandardCxx11)
isCxx11 = true;
}
foreach (const ProjectExplorer::HeaderPath &headerPath, includePaths) {

View File

@@ -587,7 +587,7 @@ void Qt4Project::updateCppCodeModel()
// part->language
if (tc)
part->cxxVersion = (tc->compilerFlags(cxxflags) == ToolChain::STD_CXX11)
part->cxxVersion = (tc->compilerFlags(cxxflags) | ToolChain::StandardCxx11)
? ProjectPart::CXX11 : ProjectPart::CXX98;
else
part->cxxVersion = ProjectPart::CXX11;