diff --git a/plugins/custom-definesandincludes/compilerprovider/compilerprovider.cpp b/plugins/custom-definesandincludes/compilerprovider/compilerprovider.cpp --- a/plugins/custom-definesandincludes/compilerprovider/compilerprovider.cpp +++ b/plugins/custom-definesandincludes/compilerprovider/compilerprovider.cpp @@ -48,12 +48,12 @@ ICompiler(i18n("None"), QString(), QString(), false) {} - QHash< QString, QString > defines(const QString&) const override + QHash< QString, QString > defines(Utils::LanguageType, const QString&) const override { return {}; } - Path::List includes(const QString&) const override + Path::List includes(Utils::LanguageType, const QString&) const override { return {}; } @@ -139,7 +139,8 @@ languageType = Utils::languageType(item->path(), config.parserArguments.parseAmbiguousAsCPP); } - return config.compiler->defines(languageType == Utils::C ? config.parserArguments.cArguments : config.parserArguments.cppArguments); + return config.compiler->defines(languageType, + languageType == Utils::C ? config.parserArguments.cArguments : config.parserArguments.cppArguments); } Path::List CompilerProvider::includes( ProjectBaseItem* item ) const @@ -150,7 +151,8 @@ languageType = Utils::languageType(item->path(), config.parserArguments.parseAmbiguousAsCPP); } - return config.compiler->includes(languageType == Utils::C ? config.parserArguments.cArguments : config.parserArguments.cppArguments); + return config.compiler->includes(languageType, + languageType == Utils::C ? config.parserArguments.cArguments : config.parserArguments.cppArguments); } Path::List CompilerProvider::frameworkDirectories( ProjectBaseItem* /* item */ ) const diff --git a/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.h b/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.h --- a/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.h +++ b/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.h @@ -32,9 +32,9 @@ public: GccLikeCompiler( const QString& name, const QString& path, bool editable, const QString& factoryName ); - KDevelop::Defines defines(const QString& arguments) const override; + KDevelop::Defines defines(Utils::LanguageType type, const QString& arguments) const override; - KDevelop::Path::List includes(const QString& arguments) const override; + KDevelop::Path::List includes(Utils::LanguageType type, const QString& arguments) const override; private: void invalidateCache(); diff --git a/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.cpp b/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.cpp --- a/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.cpp +++ b/plugins/custom-definesandincludes/compilerprovider/gcclikecompiler.cpp @@ -36,48 +36,40 @@ namespace { -// compilers don't deduplicate QStringLiteral -QString minusXC() { return QStringLiteral("-xc"); } -QString minusXCPlusPlus() { return QStringLiteral("-xc++"); } -QStringList languageOptions(const QString& arguments) +QString languageOption(Utils::LanguageType type) { + switch (type) { + case Utils::C: + return QStringLiteral("-xc"); + case Utils::Cpp: + return QStringLiteral("-xc++"); + case Utils::OpenCl: + return QStringLiteral("-xcl"); + case Utils::Cuda: + return QStringLiteral("-xcuda"); + case Utils::ObjC: + return QStringLiteral("-xobjective-c"); + default: + Q_UNREACHABLE(); + } +} +QString languageStandard(const QString& arguments) +{ // TODO: handle -ansi flag: In C mode, this is equivalent to -std=c90. In C++ mode, it is equivalent to -std=c++98. - // TODO: check for -x flag on command line const QRegularExpression regexp(QStringLiteral("-std=(\\S+)")); - // see gcc manpage or llvm/tools/clang/include/clang/Frontend/LangStandards.def for list of valid language options auto result = regexp.match(arguments); - if(result.hasMatch()){ - const auto standard = result.captured(0); - const auto mode = result.capturedRef(1); - QString language; - if (mode.startsWith(QLatin1String("c++")) || mode.startsWith(QLatin1String("gnu++"))) { - language = minusXCPlusPlus(); - } else if (mode.startsWith(QLatin1String("iso9899:"))) { - // all iso9899:xxxxx modes are C standards - language = minusXC(); - } else { - // check for c11, gnu99, etc: all of them have a digit after the c/gnu - const QRegularExpression cRegexp(QStringLiteral("(c|gnu)\\d.*")); - if (cRegexp.match(mode).hasMatch()) { - language = minusXC(); - } - } - if (language.isEmpty()) { - qCWarning(DEFINESANDINCLUDES) << "Failed to determine language from -std= flag:" << arguments; - language = minusXCPlusPlus(); - } - return {standard, language}; + if (result.hasMatch()) + return result.captured(0); - } // no -std= flag passed -> assume c++11 - return {QStringLiteral("-std=c++11"), minusXCPlusPlus()}; + return QStringLiteral("-std=c++11"); } } -Defines GccLikeCompiler::defines(const QString& arguments) const +Defines GccLikeCompiler::defines(Utils::LanguageType type, const QString& arguments) const { auto& data = m_definesIncludes[arguments]; if (!data.definedMacros.isEmpty() ) { @@ -93,7 +85,7 @@ proc.setProcessChannelMode( QProcess::MergedChannels ); // TODO: what about -mXXX or -target= flags, some of these change search paths/defines - auto compilerArguments = languageOptions(arguments); + QStringList compilerArguments{languageOption(type), languageStandard(arguments)}; compilerArguments.append(QStringLiteral("-dM")); compilerArguments.append(QStringLiteral("-E")); compilerArguments.append(QProcess::nullDevice()); @@ -123,7 +115,7 @@ return data.definedMacros; } -Path::List GccLikeCompiler::includes(const QString& arguments) const +Path::List GccLikeCompiler::includes(Utils::LanguageType type, const QString& arguments) const { auto& data = m_definesIncludes[arguments]; if ( !data.includePaths.isEmpty() ) { @@ -147,7 +139,7 @@ // /usr/include // End of search list. - auto compilerArguments = languageOptions(arguments); + QStringList compilerArguments{languageOption(type), languageStandard(arguments)}; compilerArguments.append(QStringLiteral("-E")); compilerArguments.append(QStringLiteral("-v")); compilerArguments.append(QProcess::nullDevice()); diff --git a/plugins/custom-definesandincludes/compilerprovider/icompiler.h b/plugins/custom-definesandincludes/compilerprovider/icompiler.h --- a/plugins/custom-definesandincludes/compilerprovider/icompiler.h +++ b/plugins/custom-definesandincludes/compilerprovider/icompiler.h @@ -29,6 +29,20 @@ #include "../idefinesandincludesmanager.h" +namespace Utils +{ +enum LanguageType +{ + C, + Cpp, + OpenCl, + Cuda, + ObjC, + + Other = 100 +}; +} + /// An interface that represents a compiler. Compiler provides standard include directories and standard defined macros. class ICompiler { @@ -45,13 +59,13 @@ * @param arguments compiler command-line arguments * @return list of defined macros for the compiler */ - virtual KDevelop::Defines defines(const QString& arguments) const = 0; + virtual KDevelop::Defines defines(Utils::LanguageType type, const QString& arguments) const = 0; /** * @param arguments compiler command-line arguments * @return list of include directories for the compiler */ - virtual KDevelop::Path::List includes(const QString& arguments) const = 0; + virtual KDevelop::Path::List includes(Utils::LanguageType type, const QString& arguments) const = 0; void setPath( const QString &path ); diff --git a/plugins/custom-definesandincludes/compilerprovider/msvccompiler.h b/plugins/custom-definesandincludes/compilerprovider/msvccompiler.h --- a/plugins/custom-definesandincludes/compilerprovider/msvccompiler.h +++ b/plugins/custom-definesandincludes/compilerprovider/msvccompiler.h @@ -31,9 +31,9 @@ public: MsvcCompiler(const QString& name, const QString& path, bool editable, const QString& factoryName); - KDevelop::Defines defines(const QString& arguments) const override; + KDevelop::Defines defines(Utils::LanguageType type, const QString& arguments) const override; - KDevelop::Path::List includes(const QString& arguments) const override; + KDevelop::Path::List includes(Utils::LanguageType type, const QString& arguments) const override; }; #endif // MSVCCOMPILER_H diff --git a/plugins/custom-definesandincludes/compilerprovider/msvccompiler.cpp b/plugins/custom-definesandincludes/compilerprovider/msvccompiler.cpp --- a/plugins/custom-definesandincludes/compilerprovider/msvccompiler.cpp +++ b/plugins/custom-definesandincludes/compilerprovider/msvccompiler.cpp @@ -34,7 +34,7 @@ using namespace KDevelop; -Defines MsvcCompiler::defines(const QString&) const +Defines MsvcCompiler::defines(Utils::LanguageType, const QString&) const { Defines ret; //Get standard macros from kdevmsvcdefinehelpers @@ -115,7 +115,7 @@ return ret; } -Path::List MsvcCompiler::includes(const QString&) const +Path::List MsvcCompiler::includes(Utils::LanguageType, const QString&) const { QStringList _includePaths = QProcessEnvironment::systemEnvironment().value( QStringLiteral("INCLUDE") ).split( QStringLiteral(";"), QString::SkipEmptyParts ); Path::List includePaths; diff --git a/plugins/custom-definesandincludes/compilerprovider/settingsmanager.h b/plugins/custom-definesandincludes/compilerprovider/settingsmanager.h --- a/plugins/custom-definesandincludes/compilerprovider/settingsmanager.h +++ b/plugins/custom-definesandincludes/compilerprovider/settingsmanager.h @@ -63,17 +63,6 @@ namespace Utils { -enum LanguageType -{ - C, - Cpp, - OpenCl, - Cuda, - ObjC, - - Other = 100 -}; - LanguageType languageType(const KDevelop::Path& path, bool treatAmbiguousAsCPP = true); } diff --git a/plugins/custom-definesandincludes/compilerprovider/tests/test_compilerprovider.cpp b/plugins/custom-definesandincludes/compilerprovider/tests/test_compilerprovider.cpp --- a/plugins/custom-definesandincludes/compilerprovider/tests/test_compilerprovider.cpp +++ b/plugins/custom-definesandincludes/compilerprovider/tests/test_compilerprovider.cpp @@ -113,18 +113,18 @@ auto provider = settings->provider(); for (auto c : provider->compilers()) { if (!c->editable() && !c->path().isEmpty()) { - QVERIFY(!c->defines({}).isEmpty()); - QVERIFY(!c->includes({}).isEmpty()); + QVERIFY(!c->defines(Utils::Cpp, {}).isEmpty()); + QVERIFY(!c->includes(Utils::Cpp, {}).isEmpty()); } } QVERIFY(!provider->defines(nullptr).isEmpty()); QVERIFY(!provider->includes(nullptr).isEmpty()); auto compiler = provider->compilerForItem(nullptr); QVERIFY(compiler); - QVERIFY(!compiler->defines(QStringLiteral("--std=c++11")).isEmpty()); - QVERIFY(!compiler->includes(QStringLiteral("--std=c++11")).isEmpty()); + QVERIFY(!compiler->defines(Utils::Cpp, QStringLiteral("-std=c++11")).isEmpty()); + QVERIFY(!compiler->includes(Utils::Cpp, QStringLiteral("-std=c++11")).isEmpty()); } void TestCompilerProvider::testStorageBackwardsCompatible()