diff --git a/doc/src/vcs/creator-vcs-git.qdoc b/doc/src/vcs/creator-vcs-git.qdoc index f5cd4a2e922..54d58e96710 100644 --- a/doc/src/vcs/creator-vcs-git.qdoc +++ b/doc/src/vcs/creator-vcs-git.qdoc @@ -281,6 +281,17 @@ \li Set the current branch to track the selected one. \endtable + \section3 Configuring Merge Tools + + Only graphical merge tools are supported. You can configure the + merge tool to use on the command line. For example, to use the + \l{http://kdiff3.sourceforge.net/}{KDiff3} merge tool, enter the + following command: + + \badcode + git config --global merge.tool kdiff3 + \endcode + \section2 Applying Patches Patches are rewriting instructions that can be applied to a set of files. diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index 3ee177a3872..18e36270ce5 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -685,7 +685,7 @@ static inline QString fixComponentPathForIncompatibleQt(const QString &component if (componentPath.contains(importString)) { int index = componentPath.indexOf(importString) + 8; const QString relativeImportPath = componentPath.right(componentPath.length() - index); - QString fixedComponentPath = QLibraryInfo::location(QLibraryInfo::ImportsPath) + relativeImportPath; + QString fixedComponentPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath) + relativeImportPath; fixedComponentPath.replace(QLatin1Char('\\'), QLatin1Char('/')); if (QFileInfo::exists(fixedComponentPath)) return fixedComponentPath; diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 05ac1102452..c2198b65783 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -1834,7 +1834,11 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node) error(cursor(), "expected identifier before '%s'", tok().spell()); return false; } - parseName(ast->name); + + if (LA() == T_IDENTIFIER) + parseName(ast->name); + else + return false; if (_languageFeatures.cxx11Enabled && LA() == T_COLON) { ast->colon_token = consumeToken(); diff --git a/src/libs/clangsupport/processcreator.cpp b/src/libs/clangsupport/processcreator.cpp index 22b52793e30..aa9ba9641a5 100644 --- a/src/libs/clangsupport/processcreator.cpp +++ b/src/libs/clangsupport/processcreator.cpp @@ -36,6 +36,13 @@ namespace ClangBackEnd { using namespace std::chrono_literals; +static QProcess::ProcessChannelMode kProcessChannelMode +#ifdef Q_OS_WIN + = QProcess::MergedChannels; +#else + = QProcess::ForwardedChannels; +#endif + ProcessCreator::ProcessCreator() { } @@ -66,7 +73,7 @@ std::future ProcessCreator::createProcess() const return std::async(std::launch::async, [&] { checkIfProcessPathExists(); auto process = QProcessUniquePointer(new QProcess); - process->setProcessChannelMode(QProcess::QProcess::ForwardedChannels); + process->setProcessChannelMode(kProcessChannelMode); process->setProcessEnvironment(processEnvironment()); process->start(m_processPath, m_arguments); process->waitForStarted(5000); diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index c211fcc471b..fc4850b84fc 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -276,10 +276,8 @@ void AutotoolsProject::updateCppCodeModel() CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt; if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) { - if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) - activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder; - else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) - activeQtVersion = CppTools::ProjectPart::Qt4Latest; + if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) + activeQtVersion = CppTools::ProjectPart::Qt4; else activeQtVersion = CppTools::ProjectPart::Qt5; } diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.cpp b/src/plugins/clangcodemodel/clangassistproposalitem.cpp index 6b4d0b81629..ed15a006f66 100644 --- a/src/plugins/clangcodemodel/clangassistproposalitem.cpp +++ b/src/plugins/clangcodemodel/clangassistproposalitem.cpp @@ -210,11 +210,19 @@ void ClangAssistProposalItem::apply(TextDocumentManipulatorInterface &manipulato if (!abandonParen && ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind) { const CodeCompletionChunk resultType = ccr.chunks.first(); - QTC_ASSERT(resultType.kind == CodeCompletionChunk::ResultType, return;); - if (::Utils::Text::matchPreviousWord(manipulator, cursor, resultType.text.toString())) { - extraCharacters += methodDefinitionParameters(ccr.chunks); - // To skip the next block. - abandonParen = true; + if (resultType.kind == CodeCompletionChunk::ResultType) { + if (::Utils::Text::matchPreviousWord(manipulator, cursor, resultType.text.toString())) { + extraCharacters += methodDefinitionParameters(ccr.chunks); + // To skip the next block. + abandonParen = true; + } + } else { + // Do nothing becasue it's not a function definition. + + // It's a clang bug that the function might miss a ResultType chunk + // when the base class method is called from the overriding method + // of the derived class. For example: + // void Derived::foo() override { Base:: } } } if (!abandonParen) { diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index e87135351db..e8d7086662c 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -185,7 +185,7 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeComple { QTC_CHECK(m_completions.isEmpty()); - if (m_sentRequestType == FunctionHintCompletion) { + if (m_sentRequestType == FunctionHintCompletion && !completions.isEmpty()) { const CodeCompletion &firstCompletion = completions.front(); if (firstCompletion.completionKind == CodeCompletion::FunctionOverloadCompletionKind) { setAsyncProposalAvailable(createFunctionHintProposal(completions)); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 706677d87ee..7a185bb8213 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -469,7 +469,7 @@ private: // Determine file kind with respect to ambiguous headers. CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(m_filePath); if (fileKind == CppTools::ProjectFile::AmbiguousHeader) { - fileKind = m_projectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion + fileKind = m_projectPart.languageVersion <= ProjectExplorer::LanguageVersion::LatestC ? CppTools::ProjectFile::CHeader : CppTools::ProjectFile::CXXHeader; } diff --git a/src/plugins/clangcodemodel/clanghoverhandler.cpp b/src/plugins/clangcodemodel/clanghoverhandler.cpp index 158bb9db64f..3817f82f0ad 100644 --- a/src/plugins/clangcodemodel/clanghoverhandler.cpp +++ b/src/plugins/clangcodemodel/clanghoverhandler.cpp @@ -100,10 +100,6 @@ static QFuture editorDocumentHandlesToolTipInfo( return QFuture(); } -ClangHoverHandler::ClangHoverHandler() -{ -} - ClangHoverHandler::~ClangHoverHandler() { abort(); diff --git a/src/plugins/clangcodemodel/clanghoverhandler.h b/src/plugins/clangcodemodel/clanghoverhandler.h index e6e262ecd01..7f7bdbb18dd 100644 --- a/src/plugins/clangcodemodel/clanghoverhandler.h +++ b/src/plugins/clangcodemodel/clanghoverhandler.h @@ -37,7 +37,6 @@ class ClangHoverHandler : public TextEditor::BaseHoverHandler Q_DECLARE_TR_FUNCTIONS(ClangHoverHandler) public: - ClangHoverHandler(); ~ClangHoverHandler() override; void identifyMatch(TextEditor::TextEditorWidget *editorWidget, diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 971c0551749..62c78f8c6d0 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -70,6 +70,7 @@ public: : CompilerOptionsBuilder(projectPart, UseSystemHeader::No, CppTools::SkipBuiltIn::No, + CppTools::SkipLanguageDefines::Yes, QString(CLANG_VERSION), QString(CLANG_RESOURCE_DIR)) { diff --git a/src/plugins/clangformat/clangformat.qbs b/src/plugins/clangformat/clangformat.qbs index 9b575fc73ca..f470951e9d1 100644 --- a/src/plugins/clangformat/clangformat.qbs +++ b/src/plugins/clangformat/clangformat.qbs @@ -1,5 +1,4 @@ import qbs -import qbs.FileInfo QtcPlugin { name: "ClangFormat" @@ -8,7 +7,6 @@ QtcPlugin { Depends { name: "TextEditor" } Depends { name: "CppTools" } Depends { name: "ProjectExplorer" } - Depends { name: "ExtensionSystem" } Depends { name: "Utils" } Depends { name: "libclang"; required: false } diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index 67d8c013e63..8423d6771cf 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -194,6 +194,7 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos) CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart, CppTools::UseSystemHeader::No, CppTools::SkipBuiltIn::No, + CppTools::SkipLanguageDefines::Yes, QString(CLANG_VERSION), QString(CLANG_RESOURCE_DIR)); QStringList arguments = extraClangToolsPrependOptions(); diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs index 97759e54c5c..7eb7e6c7c70 100644 --- a/src/plugins/clangtools/clangtools.qbs +++ b/src/plugins/clangtools/clangtools.qbs @@ -8,7 +8,6 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "TextEditor" } Depends { name: "CppTools" } - Depends { name: "ExtensionSystem" } Depends { name: "ProjectExplorer" } Depends { name: "QtcSsh" } Depends { name: "Utils" } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index ddf9ba6d896..598a0f7b4a8 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -286,10 +286,8 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt; if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) { - if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) - activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder; - else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) - activeQtVersion = CppTools::ProjectPart::Qt4Latest; + if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) + activeQtVersion = CppTools::ProjectPart::Qt4; else activeQtVersion = CppTools::ProjectPart::Qt5; } diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index 487652aeb94..47c66df91a5 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -253,7 +253,7 @@ CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FileName &pr tcInfo.targetTriple = tc->originalTargetTriple(); tcInfo.sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); tcInfo.headerPathsRunner = tc->createBuiltInHeaderPathsRunner(); - tcInfo.predefinedMacrosRunner = tc->createPredefinedMacrosRunner(); + tcInfo.macroInspectionRunner = tc->createMacroInspectionRunner(); m_cppCodeModelUpdater->update({this, tcInfo, tcInfo, rpps}); diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs new file mode 100644 index 00000000000..e21dc9e1230 --- /dev/null +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs @@ -0,0 +1,19 @@ +import qbs + +QtcPlugin { + name: "CompilationDatabaseProjectManager" + + Depends { name: "Core" } + Depends { name: "CppTools" } + Depends { name: "ProjectExplorer" } + Depends { name: "TextEditor" } + Depends { name: "Utils" } + + files: [ + "compilationdatabaseconstants.h", + "compilationdatabaseproject.cpp", + "compilationdatabaseproject.h", + "compilationdatabaseprojectmanagerplugin.cpp", + "compilationdatabaseprojectmanagerplugin.h", + ] +} diff --git a/src/plugins/coreplugin/find/findtoolwindow.cpp b/src/plugins/coreplugin/find/findtoolwindow.cpp index 85897fb8ae8..04f138a1515 100644 --- a/src/plugins/coreplugin/find/findtoolwindow.cpp +++ b/src/plugins/coreplugin/find/findtoolwindow.cpp @@ -269,7 +269,7 @@ void FindToolWindow::acceptAndGetParameters(QString *term, IFindFilter **filter) { QTC_ASSERT(filter, return); *filter = nullptr; - Find::updateFindCompletion(m_ui.searchTerm->text()); + Find::updateFindCompletion(m_ui.searchTerm->text(), Find::findFlags()); int index = m_ui.filterList->currentIndex(); QString searchTerm = m_ui.searchTerm->text(); if (index >= 0) diff --git a/src/plugins/coreplugin/menubarfilter.cpp b/src/plugins/coreplugin/menubarfilter.cpp index 69c178ae94c..7791bb1f1ef 100644 --- a/src/plugins/coreplugin/menubarfilter.cpp +++ b/src/plugins/coreplugin/menubarfilter.cpp @@ -190,8 +190,6 @@ void Core::Internal::MenuBarFilter::prepareSearch(const QString &entry) const QStringList entryPath = normalized.split(separators.at(0), QString::SkipEmptyParts); m_entries.clear(); QVector processedMenus; - for (QAction* action : menuBarActions()) { - requestMenuUpdate(action); + for (QAction* action : menuBarActions()) m_entries << matchesForAction(action, entryPath, QStringList(), processedMenus); - } } diff --git a/src/plugins/cppcheck/cppcheck.qbs b/src/plugins/cppcheck/cppcheck.qbs index 56f6d737c10..9a113c2cf30 100644 --- a/src/plugins/cppcheck/cppcheck.qbs +++ b/src/plugins/cppcheck/cppcheck.qbs @@ -5,7 +5,6 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "CppTools" } - Depends { name: "ExtensionSystem" } Depends { name: "ProjectExplorer" } Depends { name: "TextEditor" } Depends { name: "Utils" } diff --git a/src/plugins/cppcheck/cppchecktool.cpp b/src/plugins/cppcheck/cppchecktool.cpp index 28111cd3f6e..38d70be0894 100644 --- a/src/plugins/cppcheck/cppchecktool.cpp +++ b/src/plugins/cppcheck/cppchecktool.cpp @@ -137,7 +137,7 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part) if (!m_options.guessArguments) return result; - using Version = CppTools::ProjectPart::LanguageVersion; + using Version = ProjectExplorer::LanguageVersion; switch (part.languageVersion) { case Version::C89: result.push_back("--std=c89 --language=c"); @@ -148,6 +148,9 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part) case Version::C11: result.push_back("--std=c11 --language=c"); break; + case Version::C18: + result.push_back("--language=c"); + break; case Version::CXX03: result.push_back("--std=c++03 --language=c++"); break; @@ -159,6 +162,7 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part) break; case Version::CXX98: case Version::CXX17: + case Version::CXX2a: result.push_back("--language=c++"); break; } diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index e722722e252..1dbcff2e030 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -44,13 +44,15 @@ namespace CppTools { CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart, UseSystemHeader useSystemHeader, SkipBuiltIn skipBuiltInHeaderPathsAndDefines, + SkipLanguageDefines skipLanguageDefines, QString clangVersion, QString clangResourceDirectory) : m_projectPart(projectPart) - , m_useSystemHeader(useSystemHeader) , m_clangVersion(clangVersion) , m_clangResourceDirectory(clangResourceDirectory) + , m_useSystemHeader(useSystemHeader) , m_skipBuiltInHeaderPathsAndDefines(skipBuiltInHeaderPathsAndDefines) + , m_skipLanguageDefines(skipLanguageDefines) { } @@ -59,7 +61,7 @@ QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind, m_options.clear(); if (fileKind == ProjectFile::CHeader || fileKind == ProjectFile::CSource) { - QTC_ASSERT(m_projectPart.languageVersion <= ProjectPart::LatestCVersion, + QTC_ASSERT(m_projectPart.languageVersion <= ProjectExplorer::LanguageVersion::LatestC, return QStringList();); } @@ -196,7 +198,7 @@ void CompilerOptionsBuilder::addExtraCodeModelFlags() void CompilerOptionsBuilder::enableExceptions() { - if (m_projectPart.languageVersion > ProjectPart::LatestCVersion) + if (m_projectPart.languageVersion > ProjectExplorer::LanguageVersion::LatestC) add(QLatin1String("-fcxx-exceptions")); add(QLatin1String("-fexceptions")); } @@ -378,7 +380,8 @@ void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros ¯os) void CompilerOptionsBuilder::updateLanguageOption(ProjectFile::Kind fileKind) { - const bool objcExt = m_projectPart.languageExtensions & ProjectPart::ObjectiveCExtensions; + const bool objcExt = m_projectPart.languageExtensions + & ProjectExplorer::LanguageExtension::ObjectiveC; const QStringList options = createLanguageOptionGcc(fileKind, objcExt); if (options.isEmpty()) return; @@ -394,41 +397,51 @@ void CompilerOptionsBuilder::updateLanguageOption(ProjectFile::Kind fileKind) void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions) { + using ProjectExplorer::LanguageExtension; + using ProjectExplorer::LanguageVersion; + QStringList opts; - const ProjectPart::LanguageExtensions languageExtensions = m_projectPart.languageExtensions; - const bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions; + const ProjectExplorer::LanguageExtensions languageExtensions = m_projectPart.languageExtensions; + const bool gnuExtensions = languageExtensions & LanguageExtension::Gnu; switch (m_projectPart.languageVersion) { - case ProjectPart::C89: + case LanguageVersion::C89: opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89")); break; - case ProjectPart::C99: + case LanguageVersion::C99: opts << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99")); break; - case ProjectPart::C11: + case LanguageVersion::C11: opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11")); break; - case ProjectPart::CXX11: + case LanguageVersion::C18: + // Clang 6, 7 and current trunk do not accept "gnu18"/"c18", so use the "*17" variants. + opts << (gnuExtensions ? QLatin1String("-std=gnu17") : QLatin1String("-std=c17")); + break; + case LanguageVersion::CXX11: opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11")); break; - case ProjectPart::CXX98: + case LanguageVersion::CXX98: opts << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98")); break; - case ProjectPart::CXX03: + case LanguageVersion::CXX03: opts << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03")); break; - case ProjectPart::CXX14: + case LanguageVersion::CXX14: opts << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14")); break; - case ProjectPart::CXX17: + case LanguageVersion::CXX17: opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17")); break; + case LanguageVersion::CXX2a: + opts << (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a")); + break; } - if (languageExtensions & ProjectPart::MicrosoftExtensions) + if (languageExtensions & LanguageExtension::Microsoft) opts << QLatin1String("-fms-extensions"); - if (checkForBorlandExtensions && (languageExtensions & ProjectPart::BorlandExtensions)) + if (checkForBorlandExtensions && (languageExtensions & LanguageExtension::Borland)) opts << QLatin1String("-fborland-extensions"); m_options.append(opts); @@ -588,6 +601,21 @@ QString CompilerOptionsBuilder::includeOption() const bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const { + // Avoid setting __cplusplus & co as this might conflict with other command line flags. + // Clang should set __cplusplus based on -std= and -fms-compatibility-version version. + static const auto languageDefines = {"__cplusplus", + "__STDC_VERSION__", + "_MSC_BUILD", + "_MSVC_LANG", + "_MSC_FULL_VER", + "_MSC_VER"}; + if (m_skipLanguageDefines == SkipLanguageDefines::Yes + && std::find(languageDefines.begin(), + languageDefines.end(), + macro.key) != languageDefines.end()) { + return true; + } + // Ignore for all compiler toolchains since LLVM has it's own implementation for // __has_include(STR) and __has_include_next(STR) if (macro.key.startsWith("__has_include")) diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h index 1274c1b860c..67a7345a306 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.h +++ b/src/plugins/cpptools/compileroptionsbuilder.h @@ -31,13 +31,19 @@ namespace CppTools { -enum class UseSystemHeader +enum class UseSystemHeader : char { Yes, No }; -enum class SkipBuiltIn +enum class SkipBuiltIn : char +{ + Yes, + No +}; + +enum class SkipLanguageDefines : char { Yes, No @@ -54,6 +60,7 @@ public: CompilerOptionsBuilder(const ProjectPart &projectPart, UseSystemHeader useSystemHeader = UseSystemHeader::No, SkipBuiltIn skipBuiltInHeaderPathsAndDefines = SkipBuiltIn::No, + SkipLanguageDefines skipLanguageDefines = SkipLanguageDefines::Yes, QString clangVersion = QString(), QString clangResourceDirectory = QString()); @@ -107,12 +114,13 @@ private: void addWrappedQtHeadersIncludePath(QStringList &list); QStringList m_options; - UseSystemHeader m_useSystemHeader; QString m_clangVersion; QString m_clangResourceDirectory; + UseSystemHeader m_useSystemHeader; SkipBuiltIn m_skipBuiltInHeaderPathsAndDefines; + SkipLanguageDefines m_skipLanguageDefines; }; } // namespace CppTools diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp index 6a0c1fe1240..e359f71a05d 100644 --- a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp +++ b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp @@ -103,37 +103,39 @@ QString Utils::toString(ProjectExplorer::HeaderPathType type) return QString(); } -QString Utils::toString(ProjectPart::LanguageVersion languageVersion) +QString Utils::toString(ProjectExplorer::LanguageVersion languageVersion) { -#define CASE_LANGUAGEVERSION(x) case ProjectPart::x: return QLatin1String(#x) +#define CASE_LANGUAGEVERSION(x) case ProjectExplorer::LanguageVersion::x: return QLatin1String(#x) switch (languageVersion) { CASE_LANGUAGEVERSION(C89); CASE_LANGUAGEVERSION(C99); CASE_LANGUAGEVERSION(C11); + CASE_LANGUAGEVERSION(C18); CASE_LANGUAGEVERSION(CXX98); CASE_LANGUAGEVERSION(CXX03); CASE_LANGUAGEVERSION(CXX11); CASE_LANGUAGEVERSION(CXX14); CASE_LANGUAGEVERSION(CXX17); + CASE_LANGUAGEVERSION(CXX2a); // no default to get a compiler warning if anything is added } #undef CASE_LANGUAGEVERSION return QString(); } -QString Utils::toString(ProjectPart::LanguageExtensions languageExtension) +QString Utils::toString(ProjectExplorer::LanguageExtensions languageExtension) { QString result; -#define CASE_LANGUAGE_EXTENSION(ext) if (languageExtension & ProjectPart::ext) \ +#define CASE_LANGUAGE_EXTENSION(ext) if (languageExtension & ProjectExplorer::LanguageExtension::ext) \ result += QLatin1String(#ext ", "); - CASE_LANGUAGE_EXTENSION(NoExtensions); - CASE_LANGUAGE_EXTENSION(GnuExtensions); - CASE_LANGUAGE_EXTENSION(MicrosoftExtensions); - CASE_LANGUAGE_EXTENSION(BorlandExtensions); - CASE_LANGUAGE_EXTENSION(OpenMPExtensions); - CASE_LANGUAGE_EXTENSION(ObjectiveCExtensions); + CASE_LANGUAGE_EXTENSION(None); + CASE_LANGUAGE_EXTENSION(Gnu); + CASE_LANGUAGE_EXTENSION(Microsoft); + CASE_LANGUAGE_EXTENSION(Borland); + CASE_LANGUAGE_EXTENSION(OpenMP); + CASE_LANGUAGE_EXTENSION(ObjectiveC); #undef CASE_LANGUAGE_EXTENSION if (result.endsWith(QLatin1String(", "))) result.chop(2); @@ -146,8 +148,7 @@ QString Utils::toString(ProjectPart::QtVersion qtVersion) switch (qtVersion) { CASE_QTVERSION(UnknownQt); CASE_QTVERSION(NoQt); - CASE_QTVERSION(Qt4_8_6AndOlder); - CASE_QTVERSION(Qt4Latest); + CASE_QTVERSION(Qt4); CASE_QTVERSION(Qt5); // no default to get a compiler warning if anything is added } diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.h b/src/plugins/cpptools/cppcodemodelinspectordumper.h index d460acf4965..b0f7a18a011 100644 --- a/src/plugins/cpptools/cppcodemodelinspectordumper.h +++ b/src/plugins/cpptools/cppcodemodelinspectordumper.h @@ -47,8 +47,8 @@ struct CPPTOOLS_EXPORT Utils static QString toString(CPlusPlus::Document::CheckMode checkMode); static QString toString(CPlusPlus::Document::DiagnosticMessage::Level level); static QString toString(ProjectExplorer::HeaderPathType type); - static QString toString(CppTools::ProjectPart::LanguageVersion languageVersion); - static QString toString(CppTools::ProjectPart::LanguageExtensions languageExtension); + static QString toString(ProjectExplorer::LanguageVersion languageVersion); + static QString toString(ProjectExplorer::LanguageExtensions languageExtension); static QString toString(CppTools::ProjectPart::QtVersion qtVersion); static QString toString(CppTools::ProjectPart::BuildTargetType buildTargetType); static QString toString(const QVector &projectFiles); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 9303d663388..5db9dd601d1 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -1170,8 +1170,9 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart() // Do not activate ObjectiveCExtensions since this will lead to the // "objective-c++" language option for a project-less *.cpp file. - part->languageExtensions = ProjectPart::AllExtensions; - part->languageExtensions &= ~ProjectPart::ObjectiveCExtensions; + part->languageExtensions = ProjectExplorer::LanguageExtension::All; + part->languageExtensions &= ~ProjectExplorer::LanguageExtensions( + ProjectExplorer::LanguageExtension::ObjectiveC); part->qtVersion = ProjectPart::Qt5; part->updateLanguageFeatures(); diff --git a/src/plugins/cpptools/cppprojectinfogenerator.cpp b/src/plugins/cpptools/cppprojectinfogenerator.cpp index fd1c9280902..0eb1af9c6e7 100644 --- a/src/plugins/cpptools/cppprojectinfogenerator.cpp +++ b/src/plugins/cpptools/cppprojectinfogenerator.cpp @@ -30,125 +30,11 @@ #include #include +#include + namespace CppTools { namespace Internal { -namespace { - -class ToolChainEvaluator -{ -public: - ToolChainEvaluator(ProjectPart &projectPart, - const RawProjectPartFlags &flags, - const ToolChainInfo &tcInfo) - : m_projectPart(projectPart) - , m_flags(flags) - , m_tcInfo(tcInfo) - { - } - - void evaluate() - { - m_projectPart.toolchainType = m_tcInfo.type; - m_projectPart.isMsvc2015Toolchain = m_tcInfo.isMsvc2015ToolChain; - m_projectPart.toolChainWordWidth = mapWordWith(m_tcInfo.wordWidth); - m_projectPart.toolChainTargetTriple = m_tcInfo.targetTriple; - m_projectPart.extraCodeModelFlags = m_tcInfo.extraCodeModelFlags; - - m_projectPart.warningFlags = m_flags.warningFlags; - - // For compilation database pass the command line flags directly. - if (m_projectPart.toolchainType == ProjectExplorer::Constants::COMPILATION_DATABASE_TOOLCHAIN_TYPEID) - m_projectPart.extraCodeModelFlags = m_flags.commandLineFlags; - - mapLanguageVersion(); - mapLanguageExtensions(); - - addHeaderPaths(); - addDefines(); - } - -private: - static ProjectPart::ToolChainWordWidth mapWordWith(unsigned wordWidth) - { - return wordWidth == 64 - ? ProjectPart::WordWidth64Bit - : ProjectPart::WordWidth32Bit; - } - - void mapLanguageVersion() - { - using namespace ProjectExplorer; - - const ToolChain::CompilerFlags &compilerFlags = m_flags.compilerFlags; - ProjectPart::LanguageVersion &languageVersion = m_projectPart.languageVersion; - - if (compilerFlags & ToolChain::StandardC11) - languageVersion = ProjectPart::C11; - else if (compilerFlags & ToolChain::StandardC99) - languageVersion = ProjectPart::C99; - else if (compilerFlags & ToolChain::StandardCxx17) - languageVersion = ProjectPart::CXX17; - else if (compilerFlags & ToolChain::StandardCxx14) - languageVersion = ProjectPart::CXX14; - else if (compilerFlags & ToolChain::StandardCxx11) - languageVersion = ProjectPart::CXX11; - else if (compilerFlags & ToolChain::StandardCxx98) - languageVersion = ProjectPart::CXX98; - } - - void mapLanguageExtensions() - { - using namespace ProjectExplorer; - - const ToolChain::CompilerFlags &compilerFlags = m_flags.compilerFlags; - ProjectPart::LanguageExtensions &languageExtensions = m_projectPart.languageExtensions; - - if (compilerFlags & ToolChain::BorlandExtensions) - languageExtensions |= ProjectPart::BorlandExtensions; - if (compilerFlags & ToolChain::GnuExtensions) - languageExtensions |= ProjectPart::GnuExtensions; - if (compilerFlags & ToolChain::MicrosoftExtensions) - languageExtensions |= ProjectPart::MicrosoftExtensions; - if (compilerFlags & ToolChain::OpenMP) - languageExtensions |= ProjectPart::OpenMPExtensions; - if (compilerFlags & ToolChain::ObjectiveC) - languageExtensions |= ProjectPart::ObjectiveCExtensions; - } - - void addHeaderPaths() - { - if (!m_tcInfo.headerPathsRunner) - return; // No compiler set in kit. - - const ProjectExplorer::HeaderPaths builtInHeaderPaths - = m_tcInfo.headerPathsRunner(m_flags.commandLineFlags, - m_tcInfo.sysRootPath); - - ProjectExplorer::HeaderPaths &headerPaths = m_projectPart.headerPaths; - for (const ProjectExplorer::HeaderPath &header : builtInHeaderPaths) { - const ProjectExplorer::HeaderPath headerPath{header.path, header.type}; - if (!headerPaths.contains(headerPath)) - headerPaths.push_back(headerPath); - } - } - - void addDefines() - { - if (!m_tcInfo.predefinedMacrosRunner) - return; // No compiler set in kit. - - m_projectPart.toolChainMacros = m_tcInfo.predefinedMacrosRunner(m_flags.commandLineFlags); - } - -private: - ProjectPart &m_projectPart; - const RawProjectPartFlags &m_flags; - const ToolChainInfo &m_tcInfo; -}; - -} // anonymous namespace - ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface &futureInterface, const ProjectUpdateInfo &projectUpdateInfo) : m_futureInterface(futureInterface) @@ -196,6 +82,8 @@ static ProjectPart::Ptr projectPartFromRawProjectPart(const RawProjectPart &rawP QVector ProjectInfoGenerator::createProjectParts(const RawProjectPart &rawProjectPart) { + using ProjectExplorer::LanguageExtension; + QVector result; ProjectFileCategorizer cat(rawProjectPart.displayName, rawProjectPart.files, @@ -205,16 +93,13 @@ QVector ProjectInfoGenerator::createProjectParts(const RawProj const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart, m_projectUpdateInfo.project); - ProjectPart::LanguageVersion defaultVersion = ProjectPart::LatestCxxVersion; - if (rawProjectPart.qtVersion == ProjectPart::Qt4_8_6AndOlder) - defaultVersion = ProjectPart::CXX11; if (cat.hasCxxSources()) { result << createProjectPart(rawProjectPart, part, cat.cxxSources(), cat.partName("C++"), - defaultVersion, - ProjectPart::NoExtensions); + Language::Cxx, + LanguageExtension::None); } if (cat.hasObjcxxSources()) { @@ -222,8 +107,8 @@ QVector ProjectInfoGenerator::createProjectParts(const RawProj part, cat.objcxxSources(), cat.partName("Obj-C++"), - defaultVersion, - ProjectPart::ObjectiveCExtensions); + Language::Cxx, + LanguageExtension::ObjectiveC); } if (cat.hasCSources()) { @@ -231,8 +116,8 @@ QVector ProjectInfoGenerator::createProjectParts(const RawProj part, cat.cSources(), cat.partName("C"), - ProjectPart::LatestCVersion, - ProjectPart::NoExtensions); + Language::C, + LanguageExtension::None); } if (cat.hasObjcSources()) { @@ -240,28 +125,24 @@ QVector ProjectInfoGenerator::createProjectParts(const RawProj part, cat.objcSources(), cat.partName("Obj-C"), - ProjectPart::LatestCVersion, - ProjectPart::ObjectiveCExtensions); + Language::C, + LanguageExtension::ObjectiveC); } } return result; } -ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &rawProjectPart, - const ProjectPart::Ptr &templateProjectPart, - const ProjectFiles &projectFiles, - const QString &partName, - ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions) +ProjectPart::Ptr ProjectInfoGenerator::createProjectPart( + const RawProjectPart &rawProjectPart, + const ProjectPart::Ptr &templateProjectPart, + const ProjectFiles &projectFiles, + const QString &partName, + Language language, + ProjectExplorer::LanguageExtensions languageExtensions) { - ProjectPart::Ptr part(templateProjectPart->copy()); - part->displayName = partName; - part->files = projectFiles; - part->languageVersion = languageVersion; - RawProjectPartFlags flags; ToolChainInfo tcInfo; - if (languageVersion <= ProjectPart::LatestCVersion) { + if (language == Language::C) { flags = rawProjectPart.flagsForC; tcInfo = m_projectUpdateInfo.cToolChainInfo; } @@ -271,8 +152,46 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &r tcInfo = m_projectUpdateInfo.cxxToolChainInfo; } // TODO: If no toolchain is set, show a warning - ToolChainEvaluator evaluator(*part.data(), flags, tcInfo); - evaluator.evaluate(); + + ProjectPart::Ptr part(templateProjectPart->copy()); + part->displayName = partName; + part->files = projectFiles; + part->toolchainType = tcInfo.type; + part->isMsvc2015Toolchain = tcInfo.isMsvc2015ToolChain; + part->toolChainWordWidth = tcInfo.wordWidth == 64 ? ProjectPart::WordWidth64Bit + : ProjectPart::WordWidth32Bit; + part->toolChainTargetTriple = tcInfo.targetTriple; + part->extraCodeModelFlags = tcInfo.extraCodeModelFlags; + part->warningFlags = flags.warningFlags; + part->languageExtensions = flags.languageExtensions; + + if (part->toolchainType == ProjectExplorer::Constants::COMPILATION_DATABASE_TOOLCHAIN_TYPEID) + part->extraCodeModelFlags = flags.commandLineFlags; + + // Toolchain macros and language version + if (tcInfo.macroInspectionRunner) { + auto macroInspectionReport = tcInfo.macroInspectionRunner(flags.commandLineFlags); + part->toolChainMacros = macroInspectionReport.macros; + part->languageVersion = macroInspectionReport.languageVersion; + // No compiler set in kit. + } else if (language == Language::C) { + part->languageVersion = ProjectExplorer::LanguageVersion::LatestC; + } else { + part->languageVersion = ProjectExplorer::LanguageVersion::LatestCxx; + } + + // Header paths + if (tcInfo.headerPathsRunner) { + const ProjectExplorer::HeaderPaths builtInHeaderPaths + = tcInfo.headerPathsRunner(flags.commandLineFlags, tcInfo.sysRootPath); + + ProjectExplorer::HeaderPaths &headerPaths = part->headerPaths; + for (const ProjectExplorer::HeaderPath &header : builtInHeaderPaths) { + const ProjectExplorer::HeaderPath headerPath{header.path, header.type}; + if (!headerPaths.contains(headerPath)) + headerPaths.push_back(headerPath); + } + } part->languageExtensions |= languageExtensions; part->updateLanguageFeatures(); diff --git a/src/plugins/cpptools/cppprojectinfogenerator.h b/src/plugins/cpptools/cppprojectinfogenerator.h index 6f81eaf85f5..6f97faf9cbf 100644 --- a/src/plugins/cpptools/cppprojectinfogenerator.h +++ b/src/plugins/cpptools/cppprojectinfogenerator.h @@ -25,6 +25,7 @@ #pragma once +#include "cpptools_utils.h" #include "projectinfo.h" #include @@ -46,8 +47,8 @@ private: const ProjectPart::Ptr &templateProjectPart, const ProjectFiles &projectFiles, const QString &partName, - ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions); + Language language, + ProjectExplorer::LanguageExtensions languageExtensions); private: const QFutureInterface m_futureInterface; diff --git a/src/plugins/cpptools/cppprojectpartchooser.cpp b/src/plugins/cpptools/cppprojectpartchooser.cpp index bbf9ca35594..a7bb56beb04 100644 --- a/src/plugins/cpptools/cppprojectpartchooser.cpp +++ b/src/plugins/cpptools/cppprojectpartchooser.cpp @@ -116,7 +116,8 @@ private: bool isPreferredLanguage(const ProjectPart &projectPart) const { - const bool isCProjectPart = projectPart.languageVersion <= ProjectPart::LatestCVersion; + const bool isCProjectPart = projectPart.languageVersion + <= ProjectExplorer::LanguageVersion::LatestC; return (m_languagePreference == Language::C && isCProjectPart) || (m_languagePreference == Language::Cxx && !isCProjectPart); } diff --git a/src/plugins/cpptools/cpprawprojectpart.cpp b/src/plugins/cpptools/cpprawprojectpart.cpp index 6f60d9cf46f..9675be52919 100644 --- a/src/plugins/cpptools/cpprawprojectpart.cpp +++ b/src/plugins/cpptools/cpprawprojectpart.cpp @@ -39,7 +39,7 @@ RawProjectPartFlags::RawProjectPartFlags(const ProjectExplorer::ToolChain *toolC if (toolChain) { this->commandLineFlags = commandLineFlags; warningFlags = toolChain->warningFlags(commandLineFlags); - compilerFlags = toolChain->compilerFlags(commandLineFlags); + languageExtensions = toolChain->languageExtensions(commandLineFlags); } } diff --git a/src/plugins/cpptools/cpprawprojectpart.h b/src/plugins/cpptools/cpprawprojectpart.h index 4aa17a3a47d..e238fa1d818 100644 --- a/src/plugins/cpptools/cpprawprojectpart.h +++ b/src/plugins/cpptools/cpprawprojectpart.h @@ -28,6 +28,7 @@ #include "cpptools_global.h" #include "projectpart.h" +#include #include #include @@ -45,8 +46,7 @@ public: QStringList commandLineFlags; // The following are deduced from commandLineFlags. ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default; - ProjectExplorer::ToolChain::CompilerFlags compilerFlags - = ProjectExplorer::ToolChain::CompilerFlag::NoFlags; + ProjectExplorer::LanguageExtensions languageExtensions = ProjectExplorer::LanguageExtension::None; }; class CPPTOOLS_EXPORT RawProjectPart diff --git a/src/plugins/cpptools/projectinfo.cpp b/src/plugins/cpptools/projectinfo.cpp index a51caebe111..c39449fef7a 100644 --- a/src/plugins/cpptools/projectinfo.cpp +++ b/src/plugins/cpptools/projectinfo.cpp @@ -48,7 +48,7 @@ ToolChainInfo::ToolChainInfo(const ProjectExplorer::ToolChain *toolChain, // they can be run from a worker thread. sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner(); - predefinedMacrosRunner = toolChain->createPredefinedMacrosRunner(); + macroInspectionRunner = toolChain->createMacroInspectionRunner(); } } diff --git a/src/plugins/cpptools/projectinfo.h b/src/plugins/cpptools/projectinfo.h index 38bf509cba2..a69ffd8fdfe 100644 --- a/src/plugins/cpptools/projectinfo.h +++ b/src/plugins/cpptools/projectinfo.h @@ -58,7 +58,7 @@ public: QString sysRootPath; // For headerPathsRunner. ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner; - ProjectExplorer::ToolChain::PredefinedMacrosRunner predefinedMacrosRunner; + ProjectExplorer::ToolChain::MacroInspectionRunner macroInspectionRunner; }; class CPPTOOLS_EXPORT ProjectUpdateInfo diff --git a/src/plugins/cpptools/projectpart.cpp b/src/plugins/cpptools/projectpart.cpp index 4dc871e87ea..bcfe4b3e52d 100644 --- a/src/plugins/cpptools/projectpart.cpp +++ b/src/plugins/cpptools/projectpart.cpp @@ -35,12 +35,13 @@ namespace CppTools { void ProjectPart::updateLanguageFeatures() { - const bool hasCxx = languageVersion >= CXX98; + const bool hasCxx = languageVersion >= ProjectExplorer::LanguageVersion::CXX98; const bool hasQt = hasCxx && qtVersion != NoQt; - languageFeatures.cxx11Enabled = languageVersion >= CXX11; + languageFeatures.cxx11Enabled = languageVersion >= ProjectExplorer::LanguageVersion::CXX11; languageFeatures.cxxEnabled = hasCxx; - languageFeatures.c99Enabled = languageVersion >= C99; - languageFeatures.objCEnabled = languageExtensions.testFlag(ObjectiveCExtensions); + languageFeatures.c99Enabled = languageVersion >= ProjectExplorer::LanguageVersion::C99; + languageFeatures.objCEnabled = languageExtensions.testFlag( + ProjectExplorer::LanguageExtension::ObjectiveC); languageFeatures.qtEnabled = hasQt; languageFeatures.qtMocRunEnabled = hasQt; if (!hasQt) { diff --git a/src/plugins/cpptools/projectpart.h b/src/plugins/cpptools/projectpart.h index ce017abc79d..77a08128bfb 100644 --- a/src/plugins/cpptools/projectpart.h +++ b/src/plugins/cpptools/projectpart.h @@ -30,6 +30,7 @@ #include "cppprojectfile.h" #include +#include #include #include @@ -49,40 +50,10 @@ namespace CppTools { class CPPTOOLS_EXPORT ProjectPart { public: - enum LanguageVersion { - C89, - C99, - C11, - LatestCVersion = C11, - CXX98, - CXX03, - CXX11, - CXX14, - CXX17, - LatestCxxVersion = CXX17, - }; - - enum LanguageExtension { - NoExtensions = 0, - GnuExtensions = 1 << 0, - MicrosoftExtensions = 1 << 1, - BorlandExtensions = 1 << 2, - OpenMPExtensions = 1 << 3, - ObjectiveCExtensions = 1 << 4, - - AllExtensions = GnuExtensions - | MicrosoftExtensions - | BorlandExtensions - | OpenMPExtensions - | ObjectiveCExtensions - }; - Q_DECLARE_FLAGS(LanguageExtensions, LanguageExtension) - enum QtVersion { UnknownQt = -1, NoQt, - Qt4_8_6AndOlder, - Qt4Latest, + Qt4, Qt5 }; @@ -127,8 +98,8 @@ public: ProjectExplorer::Macros projectMacros; - LanguageVersion languageVersion = LatestCxxVersion; - LanguageExtensions languageExtensions = NoExtensions; + ProjectExplorer::LanguageVersion languageVersion = ProjectExplorer::LanguageVersion::LatestCxx; + ProjectExplorer::LanguageExtensions languageExtensions = ProjectExplorer::LanguageExtension::None; ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default; QtVersion qtVersion = UnknownQt; CPlusPlus::LanguageFeatures languageFeatures; diff --git a/src/plugins/cpptools/symbolsfindfilter.cpp b/src/plugins/cpptools/symbolsfindfilter.cpp index 0afd65db18c..58e0ba11d3e 100644 --- a/src/plugins/cpptools/symbolsfindfilter.cpp +++ b/src/plugins/cpptools/symbolsfindfilter.cpp @@ -191,18 +191,20 @@ QWidget *SymbolsFindFilter::createConfigWidget() void SymbolsFindFilter::writeSettings(QSettings *settings) { settings->beginGroup(QLatin1String(SETTINGS_GROUP)); - settings->setValue(QLatin1String(SETTINGS_SYMBOLTYPES), (int)m_symbolsToSearch); - settings->setValue(QLatin1String(SETTINGS_SEARCHSCOPE), (int)m_scope); + settings->setValue(QLatin1String(SETTINGS_SYMBOLTYPES), int(m_symbolsToSearch)); + settings->setValue(QLatin1String(SETTINGS_SEARCHSCOPE), int(m_scope)); settings->endGroup(); } void SymbolsFindFilter::readSettings(QSettings *settings) { settings->beginGroup(QLatin1String(SETTINGS_GROUP)); - m_symbolsToSearch = (SearchSymbols::SymbolTypes)settings->value(QLatin1String(SETTINGS_SYMBOLTYPES), - (int)SearchSymbols::AllTypes).toInt(); - m_scope = (SearchScope)settings->value(QLatin1String(SETTINGS_SEARCHSCOPE), - (int)SymbolSearcher::SearchProjectsOnly).toInt(); + m_symbolsToSearch = static_cast( + settings->value(QLatin1String(SETTINGS_SYMBOLTYPES), + int(SearchSymbols::AllTypes)).toInt()); + m_scope = static_cast( + settings->value(QLatin1String(SETTINGS_SEARCHSCOPE), + int(SymbolSearcher::SearchProjectsOnly)).toInt()); settings->endGroup(); emit symbolsToSearchChanged(); } diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 255712aa67e..a047ac1d7c5 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -201,8 +201,6 @@ CdbEngine::CdbEngine() : wh->addTypeFormats("QImage", imageFormats); wh->addTypeFormats("QImage *", imageFormats); - connect(action(OperateByInstruction), &QAction::triggered, - this, &CdbEngine::operateByInstructionTriggered); connect(action(CreateFullBacktrace), &QAction::triggered, this, &CdbEngine::createFullBacktrace); connect(&m_process, static_cast(&QProcess::finished), @@ -270,6 +268,7 @@ CdbEngine::~CdbEngine() = default; void CdbEngine::operateByInstructionTriggered(bool operateByInstruction) { + DebuggerEngine::operateByInstructionTriggered(operateByInstruction); if (m_operateByInstruction == operateByInstruction) return; m_operateByInstruction = operateByInstruction; @@ -522,7 +521,7 @@ void CdbEngine::handleInitialSessionIdle() const DebuggerRunParameters &rp = runParameters(); if (!rp.commandsAfterConnect.isEmpty()) runCommand({rp.commandsAfterConnect, NoFlags}); - operateByInstructionTriggered(action(OperateByInstruction)->isChecked()); + operateByInstructionTriggered(operatesByInstruction()); // QmlCppEngine expects the QML engine to be connected before any breakpoints are hit // (attemptBreakpointSynchronization() will be directly called then) if (rp.breakOnMain) { diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index e5b617eb437..c367925fd3a 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -113,7 +113,7 @@ private: void processError(); void processFinished(); void runCommand(const DebuggerCommand &cmd) override; - void operateByInstructionTriggered(bool); + void operateByInstructionTriggered(bool) override; void createFullBacktrace(); diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index cfb35146834..6d44afdadcd 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -165,18 +165,6 @@ DebuggerSettings::DebuggerSettings() item->setDefaultValue(false); insertItem(LogTimeStamps, item); - item = new SavedAction(this); - item->setText(tr("Operate by Instruction")); - item->setCheckable(true); - item->setDefaultValue(false); - item->setIcon(Debugger::Icons::SINGLE_INSTRUCTION_MODE.icon()); - item->setToolTip(tr("

This switches the debugger to instruction-wise " - "operation mode. In this mode, stepping operates on single " - "instructions and the source location view also shows the " - "disassembled instructions.")); - item->setIconVisibleInMenu(false); - insertItem(OperateByInstruction, item); - item = new SavedAction(this); item->setText(tr("Dereference Pointers Automatically")); item->setCheckable(true); diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 39d3571d45e..6a91a0fc43e 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -82,7 +82,6 @@ enum DebuggerActionCode AutoQuit, LockView, LogTimeStamps, - OperateByInstruction, CloseSourceBuffersOnExit, CloseMemoryBuffersOnExit, SwitchModeOnExit, diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 67a01d026c1..cbc1be8b779 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -393,23 +393,6 @@ public: m_toolTipManager.resetLocation(); } - void handleOperateByInstructionTriggered(bool on) - { - // Go to source only if we have the file. - // if (DebuggerEngine *cppEngine = m_engine->cppEngine()) { - if (m_stackHandler.currentIndex() >= 0) { - const StackFrame frame = m_stackHandler.currentFrame(); - if (on || frame.isUsable()) - m_engine->gotoLocation(Location(frame, true)); - } - // } - } - - bool operatesByInstruction() const - { - return m_operateByInstructionAction.isChecked(); - } - public: void setInitialActionStates(); void setBusyCursor(bool on); @@ -542,9 +525,15 @@ void DebuggerEnginePrivate::setupViews() m_operateByInstructionAction.setVisible(m_engine->hasCapability(DisassemblerCapability)); m_operateByInstructionAction.setIcon(Debugger::Icons::SINGLE_INSTRUCTION_MODE.icon()); m_operateByInstructionAction.setCheckable(true); - m_operateByInstructionAction.setChecked(boolSetting(OperateByInstruction)); + m_operateByInstructionAction.setChecked(false); + m_operateByInstructionAction.setToolTip("

" + tr("This switches the debugger to instruction-wise " + "operation mode. In this mode, stepping operates on single " + "instructions and the source location view also shows the " + "disassembled instructions.")); + m_operateByInstructionAction.setIconVisibleInMenu(false); + connect(&m_operateByInstructionAction, &QAction::triggered, - this, &DebuggerEnginePrivate::handleOperateByInstructionTriggered); + m_engine, &DebuggerEngine::operateByInstructionTriggered); QTC_ASSERT(m_state == DebuggerNotReady || m_state == DebuggerFinished, qDebug() << m_state); m_progress.setProgressValue(200); @@ -977,7 +966,7 @@ void DebuggerEngine::gotoLocation(const Location &loc) d->resetLocation(); if (loc.canBeDisassembled() - && ((hasCapability(OperateByInstructionCapability) && d->operatesByInstruction()) + && ((hasCapability(OperateByInstructionCapability) && operatesByInstruction()) || !loc.hasDebugInfo()) ) { d->m_disassemblerAgent.setLocation(loc); @@ -1803,6 +1792,24 @@ bool DebuggerEngine::debuggerActionsEnabled() const return debuggerActionsEnabledHelper(d->m_state); } +bool DebuggerEngine::operatesByInstruction() const +{ + return d->m_operateByInstructionAction.isChecked(); +} + +void DebuggerEngine::operateByInstructionTriggered(bool on) +{ + // Go to source only if we have the file. + // if (DebuggerEngine *cppEngine = m_engine->cppEngine()) { + d->m_stackHandler.resetModel(); + if (d->m_stackHandler.currentIndex() >= 0) { + const StackFrame frame = d->m_stackHandler.currentFrame(); + if (on || frame.isUsable()) + gotoLocation(Location(frame, true)); + } + // } +} + bool DebuggerEngine::companionPreventsActions() const { return false; @@ -2291,7 +2298,7 @@ void DebuggerEngine::handleExecStep() ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); } else { resetLocation(); - if (d->operatesByInstruction()) + if (operatesByInstruction()) executeStepI(); else executeStep(); @@ -2305,7 +2312,7 @@ void DebuggerEngine::handleExecNext() ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); } else { resetLocation(); - if (d->operatesByInstruction()) + if (operatesByInstruction()) executeNextI(); else executeNext(); diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index b9a31caf512..05c30078d4f 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -338,6 +338,9 @@ public: bool debuggerActionsEnabled() const; virtual bool companionPreventsActions() const; + bool operatesByInstruction() const; + virtual void operateByInstructionTriggered(bool on); // FIXME: Remove. + DebuggerState state() const; bool isDying() const; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 81c657345bc..eb194281d9e 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1233,7 +1233,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, m_nextAction.setIcon(Icons::STEP_OVER.icon()); connect(&m_nextAction, &QAction::triggered, this, [] { if (DebuggerEngine *engine = EngineManager::currentEngine()) { - engine->executeNext(); + engine->handleExecNext(); } else { DebuggerRunTool::setBreakOnMainNextTime(); ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, false); @@ -1248,7 +1248,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, m_stepAction.setIcon(Icons::STEP_OVER.icon()); connect(&m_stepAction, &QAction::triggered, this, [] { if (DebuggerEngine *engine = EngineManager::currentEngine()) { - engine->executeStep(); + engine->handleExecStep(); } else { DebuggerRunTool::setBreakOnMainNextTime(); ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, false); @@ -1298,10 +1298,10 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, ActionManager::registerAction(&m_frameUpAction, "Debugger.FrameUp", cppDebuggercontext); - cmd = ActionManager::registerAction(action(OperateByInstruction), - Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext); - cmd->setAttribute(Command::CA_Hide); - debugMenu->addAction(cmd); +// cmd = ActionManager::registerAction(action(OperateByInstruction), +// Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext); +// cmd->setAttribute(Command::CA_Hide); +// debugMenu->addAction(cmd); cmd = ActionManager::registerAction(&m_breakAction, "Debugger.ToggleBreak"); cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("F8") : tr("F9"))); @@ -2056,7 +2056,6 @@ void DebuggerPluginPrivate::setInitialState() m_watchAction.setEnabled(false); m_breakAction.setEnabled(false); //m_snapshotAction.setEnabled(false); - action(OperateByInstruction)->setChecked(false); m_exitAction.setEnabled(false); m_abortAction.setEnabled(false); diff --git a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp index 67915d8cfad..4d53e55f2d2 100644 --- a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp +++ b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp @@ -134,7 +134,7 @@ SourcePathMap SourcePathMappingModel::sourcePathMap() const bool SourcePathMappingModel::isNewPlaceHolder(const Mapping &m) const { const QLatin1Char lessThan('<'); - const QLatin1Char greaterThan('<'); + const QLatin1Char greaterThan('>'); return m.first.isEmpty() || m.first.startsWith(lessThan) || m.first.endsWith(greaterThan) || m.first == m_newSourcePlaceHolder diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 940909ab41a..d367b548c2a 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1233,7 +1233,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data) //qDebug() << "BP " << rid << data.toString(); // Quickly set the location marker. - if (lineNumber && !boolSetting(OperateByInstruction) + if (lineNumber && !operatesByInstruction() && QFileInfo::exists(fullName) && function != "qt_v4TriggeredBreakpointHook" && function != "qt_qmlDebugMessageAvailable" diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 17338305100..b8d414ad76c 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -891,7 +891,7 @@ void LldbEngine::handleLocationNotification(const GdbMi &reportedLocation) QString function = reportedLocation["function"].data(); int lineNumber = reportedLocation["line"].toInt(); Location loc = Location(fileName, lineNumber); - if (boolSetting(OperateByInstruction) || !QFileInfo::exists(fileName) || lineNumber <= 0) { + if (operatesByInstruction() || !QFileInfo::exists(fileName) || lineNumber <= 0) { loc = Location(address); loc.setNeedsMarker(true); loc.setUseAssembler(true); diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index c4bb6630b0b..e96f457ae6f 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -69,8 +69,6 @@ StackHandler::StackHandler(DebuggerEngine *engine) { setObjectName("StackModel"); - connect(action(OperateByInstruction), &QAction::triggered, - this, &StackHandler::resetModel); connect(action(ExpandStack), &QAction::triggered, this, &StackHandler::reloadFullStack); connect(action(MaximalStackDepth), &QAction::triggered, @@ -159,7 +157,7 @@ Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const if (index.row() == m_stackFrames.size()) return QAbstractTableModel::flags(index); const StackFrame &frame = m_stackFrames.at(index.row()); - const bool isValid = frame.isUsable() || boolSetting(OperateByInstruction); + const bool isValid = frame.isUsable() || m_engine->operatesByInstruction(); return isValid && m_contentsValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(); } @@ -258,7 +256,7 @@ void StackHandler::setFramesAndCurrentIndex(const GdbMi &frames, bool isFull) // a few exceptions: // Always jump to frame #0 when stepping by instruction. - if (boolSetting(OperateByInstruction)) + if (m_engine->operatesByInstruction()) targetFrame = 0; // If there is no frame with source, jump to frame #0. @@ -284,7 +282,7 @@ void StackHandler::prependFrames(const StackFrames &frames) int StackHandler::firstUsableIndex() const { - if (!boolSetting(OperateByInstruction)) { + if (!m_engine->operatesByInstruction()) { for (int i = 0, n = m_stackFrames.size(); i != n; ++i) if (m_stackFrames.at(i).isUsable()) return i; diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h index 0f06b77c755..02268e400af 100644 --- a/src/plugins/debugger/stackhandler.h +++ b/src/plugins/debugger/stackhandler.h @@ -73,6 +73,7 @@ public: bool isContentsValid() const { return m_contentsValid; } void scheduleResetLocation(); void resetLocation(); + void resetModel() { beginResetModel(); endResetModel(); } signals: void stackChanged(); @@ -87,7 +88,6 @@ private: bool setData(const QModelIndex &idx, const QVariant &data, int role) override; bool contextMenuEvent(const Utils::ItemViewEvent &event); - void resetModel() { beginResetModel(); endResetModel(); } void reloadFullStack(); void copyContentsToClipboard(); void saveTaskFile(); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index f1a47947eb3..b99d037e65f 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -239,7 +239,10 @@ bool GenericProject::saveRawList(const QStringList &rawList, const QString &file static void insertSorted(QStringList *list, const QString &value) { int pos = Utils::indexOf(*list, [value](const QString &s) { return s > value; }); - list->insert(pos, value); + if (pos == -1) + list->append(value); + else + list->insert(pos, value); } bool GenericProject::addFiles(const QStringList &filePaths) @@ -433,10 +436,8 @@ void GenericProject::refreshCppCodeModel() CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt; if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(activeTarget()->kit())) { - if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) - activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder; - else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) - activeQtVersion = CppTools::ProjectPart::Qt4Latest; + if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) + activeQtVersion = CppTools::ProjectPart::Qt4; else activeQtVersion = CppTools::ProjectPart::Qt5; } diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index 047b3ebf99d..35340e0731e 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -529,7 +529,7 @@ void BranchModel::checkoutBranch(const QModelIndex &idx) // No StashGuard since this function for now is only used with clean working dir. // If it is ever used from another place, please add StashGuard here - m_client->synchronousCheckout(m_workingDirectory, branch); + m_client->checkout(m_workingDirectory, branch, GitClient::StashMode::NoStash); } bool BranchModel::branchIsMerged(const QModelIndex &idx) diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index d409f939060..13a49c4903a 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -254,7 +254,7 @@ void FetchContext::cherryPick() void FetchContext::checkout() { - GitPlugin::client()->stashAndCheckout(m_repository, "FETCH_HEAD"); + GitPlugin::client()->checkout(m_repository, "FETCH_HEAD"); } void FetchContext::terminate() diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index dbbb45a16a4..eb527339baf 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1113,21 +1113,22 @@ VcsBaseEditorWidget *GitClient::annotate( return editor; } -bool GitClient::synchronousCheckout(const QString &workingDirectory, - const QString &ref, - QString *errorMessage) +void GitClient::checkout(const QString &workingDirectory, const QString &ref, + StashMode stashMode) { + if (stashMode == StashMode::TryStash && !beginStashScope(workingDirectory, "Checkout")) + return; QStringList arguments = setupCheckoutArguments(workingDirectory, ref); - const SynchronousProcessResponse resp = vcsFullySynchronousExec( - workingDirectory, arguments, VcsCommand::ExpectRepoChanges); - VcsOutputWindow::append(resp.stdOut()); - if (resp.result == SynchronousProcessResponse::Finished) { - updateSubmodulesIfNeeded(workingDirectory, true); - return true; - } else { - msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); - return false; - } + VcsCommand *command = vcsExec( + workingDirectory, arguments, nullptr, true, + VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage); + connect(command, &VcsCommand::finished, + this, [this, workingDirectory, stashMode](bool success) { + if (stashMode == StashMode::TryStash) + endStashScope(workingDirectory); + if (success) + updateSubmodulesIfNeeded(workingDirectory, true); + }); } /* method used to setup arguments for checkout, in case user wants to create local branch */ @@ -1358,16 +1359,6 @@ bool GitClient::synchronousCheckoutFiles(const QString &workingDirectory, QStrin return true; } -bool GitClient::stashAndCheckout(const QString &workingDirectory, const QString &ref) -{ - if (!beginStashScope(workingDirectory, "Checkout")) - return false; - if (!synchronousCheckout(workingDirectory, ref)) - return false; - endStashScope(workingDirectory); - return true; -} - static inline QString msgParentRevisionFailed(const QString &workingDirectory, const QString &revision, const QString &why) @@ -3378,7 +3369,7 @@ GitRemote::GitRemote(const QString &url) { static const QRegularExpression remotePattern( "^(?:(?[^:]+)://)?(?:(?[^@]+)@)?(?[^:/]+)" - "(?::(?\\d+))?:?(?/.*)$"); + "(?::(?\\d+))?:?(?.*)$"); if (url.isEmpty()) return; @@ -3403,12 +3394,13 @@ GitRemote::GitRemote(const QString &url) if (!match.hasMatch()) return; + bool ok = false; protocol = match.captured("protocol"); userName = match.captured("user"); host = match.captured("host"); - port = match.captured("port").toUShort(); + port = match.captured("port").toUShort(&ok); path = match.captured("path"); - isValid = true; + isValid = ok || match.captured("port").isEmpty(); } } // namespace Internal diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 30df75fb907..59b64ae2027 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -173,10 +173,9 @@ public: bool synchronousCheckoutFiles(const QString &workingDirectory, QStringList files = QStringList(), QString revision = QString(), QString *errorMessage = nullptr, bool revertStaging = true); - // Checkout ref - bool stashAndCheckout(const QString &workingDirectory, const QString &ref); - bool synchronousCheckout(const QString &workingDirectory, const QString &ref, - QString *errorMessage = nullptr); + enum class StashMode { NoStash, TryStash }; + void checkout(const QString &workingDirectory, const QString &ref, + StashMode stashMode = StashMode::TryStash); QStringList setupCheckoutArguments(const QString &workingDirectory, const QString &ref); void updateSubmodulesIfNeeded(const QString &workingDirectory, bool prompt); diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 2e6746cf646..d4688fa85ff 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -191,7 +191,7 @@ void GitEditorWidget::setPlainText(const QString &text) void GitEditorWidget::checkoutChange() { - GitPlugin::client()->stashAndCheckout(sourceWorkingDirectory(), m_currentChange); + GitPlugin::client()->checkout(sourceWorkingDirectory(), m_currentChange); } void GitEditorWidget::resetChange(const QByteArray &resetType) diff --git a/src/plugins/git/gitgrep.cpp b/src/plugins/git/gitgrep.cpp index 063deb98a25..41f35ea4a80 100644 --- a/src/plugins/git/gitgrep.cpp +++ b/src/plugins/git/gitgrep.cpp @@ -82,6 +82,17 @@ public: m_directory = parameters.additionalParameters.toString(); } + struct Match + { + Match() = default; + Match(int start, int length) : + matchStart(start), matchLength(length) {} + + int matchStart = 0; + int matchLength = 0; + QStringList regexpCapturedTexts; + }; + void processLine(const QString &line, FileSearchResultList *resultList) const { if (line.isEmpty()) @@ -97,7 +108,15 @@ public: const int textSeparator = line.indexOf(QChar::Null, lineSeparator + 1); single.lineNumber = line.mid(lineSeparator + 1, textSeparator - lineSeparator - 1).toInt(); QString text = line.mid(textSeparator + 1); - QVector> matches; + QRegularExpression regexp; + QVector matches; + if (m_parameters.flags & FindRegularExpression) { + const QRegularExpression::PatternOptions patternOptions = + (m_parameters.flags & FindCaseSensitively) + ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption; + regexp.setPattern(m_parameters.text); + regexp.setPatternOptions(patternOptions); + } for (;;) { const int matchStart = text.indexOf(boldRed); if (matchStart == -1) @@ -106,23 +125,19 @@ public: const int matchEnd = text.indexOf(resetColor, matchTextStart); QTC_ASSERT(matchEnd != -1, break); const int matchLength = matchEnd - matchTextStart; - matches.append(qMakePair(matchStart, matchLength)); - text = text.left(matchStart) + text.mid(matchTextStart, matchLength) - + text.mid(matchEnd + resetColor.size()); + Match match(matchStart, matchLength); + const QStringRef matchText = text.midRef(matchTextStart, matchLength); + if (m_parameters.flags & FindRegularExpression) + match.regexpCapturedTexts = regexp.match(matchText).capturedTexts(); + matches.append(match); + text = text.leftRef(matchStart) + matchText + text.midRef(matchEnd + resetColor.size()); } single.matchingLine = text; - if (m_parameters.flags & FindRegularExpression) { - const QRegularExpression::PatternOptions patternOptions = - (m_parameters.flags & QTextDocument::FindCaseSensitively) - ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption; - QRegularExpression regexp(m_parameters.text, patternOptions); - QRegularExpressionMatch regexpMatch = regexp.match(line); - single.regexpCapturedTexts = regexpMatch.capturedTexts(); - } for (auto match : qAsConst(matches)) { - single.matchStart = match.first; - single.matchLength = match.second; + single.matchStart = match.matchStart; + single.matchLength = match.matchLength; + single.regexpCapturedTexts = match.regexpCapturedTexts; resultList->append(single); } } diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 87aac67ef09..35ef47a978c 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -861,7 +861,7 @@ void GitPlugin::startChangeRelatedAction(const Id &id) m_gitClient->synchronousRevert(workingDirectory, change); break; case Checkout: - m_gitClient->stashAndCheckout(workingDirectory, change); + m_gitClient->checkout(workingDirectory, change); break; default: return; @@ -1552,6 +1552,118 @@ void GitPlugin::testLogResolving() "50a6b54c - Merge branch 'for-junio' of git://bogomips.org/git-svn", "3587b513 - Update draft release notes to 1.8.2"); } + +class RemoteTest { +public: + RemoteTest() = default; + explicit RemoteTest(const QString &url): m_url(url) {} + + inline RemoteTest &protocol(const QString &p) { m_protocol = p; return *this; } + inline RemoteTest &userName(const QString &u) { m_userName = u; return *this; } + inline RemoteTest &host(const QString &h) { m_host = h; return *this; } + inline RemoteTest &port(quint16 p) { m_port = p; return *this; } + inline RemoteTest &path(const QString &p) { m_path = p; return *this; } + inline RemoteTest &isLocal(bool l) { m_isLocal = l; return *this; } + inline RemoteTest &isValid(bool v) { m_isValid = v; return *this; } + + const QString m_url; + QString m_protocol; + QString m_userName; + QString m_host; + QString m_path; + quint16 m_port = 0; + bool m_isLocal = false; + bool m_isValid = true; +}; + +} // namespace Internal +} // namespace Git + +Q_DECLARE_METATYPE(Git::Internal::RemoteTest) + +namespace Git { +namespace Internal { + +void GitPlugin::testGitRemote_data() +{ + QTest::addColumn("rt"); + + QTest::newRow("http-no-user") + << RemoteTest("http://code.qt.io/qt-creator/qt-creator.git") + .protocol("http") + .host("code.qt.io") + .path("/qt-creator/qt-creator.git"); + QTest::newRow("https-with-port") + << RemoteTest("https://code.qt.io:80/qt-creator/qt-creator.git") + .protocol("https") + .host("code.qt.io") + .port(80) + .path("/qt-creator/qt-creator.git"); + QTest::newRow("invalid-port") + << RemoteTest("https://code.qt.io:99999/qt-creator/qt-creator.git") + .protocol("https") + .host("code.qt.io") + .path("/qt-creator/qt-creator.git") + .isValid(false); + QTest::newRow("ssh-user-foo") + << RemoteTest("ssh://foo@codereview.qt-project.org:29418/qt-creator/qt-creator.git") + .protocol("ssh") + .userName("foo") + .host("codereview.qt-project.org") + .port(29418) + .path("/qt-creator/qt-creator.git"); + QTest::newRow("ssh-github") + << RemoteTest("git@github.com:qt-creator/qt-creator.git") + .userName("git") + .host("github.com") + .path("qt-creator/qt-creator.git"); + QTest::newRow("local-file-protocol") + << RemoteTest("file:///tmp/myrepo.git") + .protocol("file") + .path("/tmp/myrepo.git") + .isLocal(true); + QTest::newRow("local-absolute-path-unix") + << RemoteTest("/tmp/myrepo.git") + .protocol("file") + .path("/tmp/myrepo.git") + .isLocal(true); + if (Utils::HostOsInfo::isWindowsHost()) { + QTest::newRow("local-absolute-path-unix") + << RemoteTest("c:/git/myrepo.git") + .protocol("file") + .path("c:/git/myrepo.git") + .isLocal(true); + } + QTest::newRow("local-relative-path-children") + << RemoteTest("./git/myrepo.git") + .protocol("file") + .path("./git/myrepo.git") + .isLocal(true); + QTest::newRow("local-relative-path-parent") + << RemoteTest("../myrepo.git") + .protocol("file") + .path("../myrepo.git") + .isLocal(true); +} + +void GitPlugin::testGitRemote() +{ + QFETCH(RemoteTest, rt); + + const GitRemote remote = GitRemote(rt.m_url); + + if (!rt.m_isLocal) { + // local repositories must exist to be valid, so skip the test + QCOMPARE(remote.isValid, rt.m_isValid); + } + + QCOMPARE(remote.protocol, rt.m_protocol); + QCOMPARE(remote.userName, rt.m_userName); + QCOMPARE(remote.host, rt.m_host); + QCOMPARE(remote.port, rt.m_port); + QCOMPARE(remote.path, rt.m_path); +} + #endif } // namespace Internal diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 8722cc058d8..fd334ab89c3 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -106,6 +106,8 @@ private slots: void testDiffFileResolving_data(); void testDiffFileResolving(); void testLogResolving(); + void testGitRemote_data(); + void testGitRemote(); #endif private: diff --git a/src/plugins/languageclient/languageclient.qbs b/src/plugins/languageclient/languageclient.qbs index 3b426ceb496..c808ec78139 100644 --- a/src/plugins/languageclient/languageclient.qbs +++ b/src/plugins/languageclient/languageclient.qbs @@ -18,6 +18,7 @@ QtcPlugin { "baseclient.h", "dynamiccapabilities.cpp", "dynamiccapabilities.h", + "languageclient.qrc", "languageclient_global.h", "languageclientcodeassist.cpp", "languageclientcodeassist.h", diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index 01147f4fa1f..399814db323 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -77,9 +77,9 @@ bool NimToolChain::isValid() const return fi.isExecutable(); } -ToolChain::PredefinedMacrosRunner NimToolChain::createPredefinedMacrosRunner() const +ToolChain::MacroInspectionRunner NimToolChain::createMacroInspectionRunner() const { - return ToolChain::PredefinedMacrosRunner(); + return ToolChain::MacroInspectionRunner(); } Macros NimToolChain::predefinedMacros(const QStringList &) const @@ -87,9 +87,9 @@ Macros NimToolChain::predefinedMacros(const QStringList &) const return Macros(); } -ToolChain::CompilerFlags NimToolChain::compilerFlags(const QStringList &) const +LanguageExtensions NimToolChain::languageExtensions(const QStringList &) const { - return CompilerFlag::NoFlags; + return LanguageExtension::None; } WarningFlags NimToolChain::warningFlags(const QStringList &) const diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h index 7b25e993def..ae3431a55c7 100644 --- a/src/plugins/nim/project/nimtoolchain.h +++ b/src/plugins/nim/project/nimtoolchain.h @@ -40,9 +40,9 @@ public: ProjectExplorer::Abi targetAbi() const override; bool isValid() const override; - PredefinedMacrosRunner createPredefinedMacrosRunner() const override; + MacroInspectionRunner createMacroInspectionRunner() const override; ProjectExplorer::Macros predefinedMacros(const QStringList &flags) const final; - CompilerFlags compilerFlags(const QStringList &flags) const final; + ProjectExplorer::LanguageExtensions languageExtensions(const QStringList &flags) const final; ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final; BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; diff --git a/src/plugins/plugins.qbs b/src/plugins/plugins.qbs index 4962d159056..6d8d6ad1398 100644 --- a/src/plugins/plugins.qbs +++ b/src/plugins/plugins.qbs @@ -20,6 +20,7 @@ Project { "classview/classview.qbs", "clearcase/clearcase.qbs", "cmakeprojectmanager/cmakeprojectmanager.qbs", + "compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs", "coreplugin/coreplugin.qbs", "coreplugin/images/logo/logo.qbs", "cpaster/cpaster.qbs", diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp index 4bd77d14627..74816753ba3 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp @@ -29,6 +29,7 @@ #include "projectexplorer.h" #include "projectexplorersettings.h" #include "taskhub.h" +#include "toolchaincache.h" #include #include @@ -46,7 +47,7 @@ namespace Internal { AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Core::Id l, Detection d, const Abi &abi, const QString& vcvarsBat) : ToolChain(typeId, d), - m_predefinedMacrosMutex(new QMutex), + m_predefinedMacrosCache(std::make_shared>()), m_lastEnvironment(Utils::Environment::systemEnvironment()), m_headerPathsMutex(new QMutex), m_abi(abi), @@ -57,20 +58,18 @@ AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Core::Id l, Detect AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Detection d) : ToolChain(typeId, d), + m_predefinedMacrosCache(std::make_shared>()), m_lastEnvironment(Utils::Environment::systemEnvironment()) { } AbstractMsvcToolChain::~AbstractMsvcToolChain() { - delete m_predefinedMacrosMutex; delete m_headerPathsMutex; } AbstractMsvcToolChain::AbstractMsvcToolChain(const AbstractMsvcToolChain &other) : ToolChain(other), m_debuggerCommand(other.m_debuggerCommand), - m_predefinedMacrosMutex(new QMutex), - m_predefinedMacros(other.m_predefinedMacros), m_lastEnvironment(other.m_lastEnvironment), m_resultEnvironment(other.m_resultEnvironment), m_headerPathsMutex(new QMutex), @@ -99,65 +98,109 @@ QString AbstractMsvcToolChain::originalTargetTriple() const : QLatin1String("i686-pc-windows-msvc"); } -ToolChain::PredefinedMacrosRunner AbstractMsvcToolChain::createPredefinedMacrosRunner() const +// +// We want to detect the language version based on the predefined macros. +// Unfortunately MSVC does not conform to standard when it comes to the predefined +// __cplusplus macro - it reports "199711L", even for newer language versions. +// +// However: +// * For >= Visual Studio 2015 Update 3 predefines _MSVC_LANG which has the proper value +// of __cplusplus. +// See https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2017 +// * For >= Visual Studio 2017 Version 15.7 __cplusplus is correct once /Zc:__cplusplus +// is provided on the command line. Then __cplusplus == _MSVC_LANG. +// See https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus +// +// We rely on _MSVC_LANG if possible, otherwise on some hard coded language versions +// depending on _MSC_VER. +// +// For _MSV_VER values, see https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2017. +// +LanguageVersion static languageVersionForMsvc(const Core::Id &language, const Macros ¯os) +{ + int mscVer = -1; + QByteArray msvcLang; + for (const ProjectExplorer::Macro ¯o : macros) { + if (macro.key == "_MSVC_LANG") + msvcLang = macro.value; + if (macro.key == "_MSC_VER") + mscVer = macro.value.toInt(nullptr); + } + QTC_CHECK(mscVer > 0); + + if (language == Constants::CXX_LANGUAGE_ID) { + if (!msvcLang.isEmpty()) // >= Visual Studio 2015 Update 3 + return ToolChain::cxxLanguageVersion(msvcLang); + if (mscVer >= 1800) // >= Visual Studio 2013 (12.0) + return LanguageVersion::CXX14; + if (mscVer >= 1600) // >= Visual Studio 2010 (10.0) + return LanguageVersion::CXX11; + return LanguageVersion::CXX98; + } else if (language == Constants::C_LANGUAGE_ID) { + if (mscVer >= 1910) // >= Visual Studio 2017 RTW (15.0) + return LanguageVersion::C11; + return LanguageVersion::C99; + } else { + QTC_CHECK(false && "Unexpected toolchain language, assuming latest C++ we support."); + return LanguageVersion::LatestCxx; + } +} + +bool static hasFlagEffectOnMacros(const QString &flag) +{ + if (flag.startsWith("-") || flag.startsWith("/")) { + const QString f = flag.mid(1); + if (f.startsWith("I")) + return false; // Skip include paths + if (f.startsWith("w", Qt::CaseInsensitive)) + return false; // Skip warning options + } + return true; +} + +ToolChain::MacroInspectionRunner AbstractMsvcToolChain::createMacroInspectionRunner() const { Utils::Environment env(m_lastEnvironment); addToEnvironment(env); + std::shared_ptr> macroCache = m_predefinedMacrosCache; + const Core::Id lang = language(); // This runner must be thread-safe! - return [this, env](const QStringList &cxxflags) { - QMutexLocker locker(m_predefinedMacrosMutex); - if (m_predefinedMacros.isEmpty()) - m_predefinedMacros = msvcPredefinedMacros(cxxflags, env); - return m_predefinedMacros; + return [this, env, macroCache, lang](const QStringList &cxxflags) { + const QStringList filteredFlags = Utils::filtered(cxxflags, [](const QString &arg) { + return hasFlagEffectOnMacros(arg); + }); + + const Utils::optional cachedMacros = macroCache->check(filteredFlags); + if (cachedMacros) + return cachedMacros.value(); + + const Macros macros = msvcPredefinedMacros(filteredFlags, env); + + const auto report = MacroInspectionReport{macros, + languageVersionForMsvc(lang, macros)}; + macroCache->insert(filteredFlags, report); + + return report; }; } ProjectExplorer::Macros AbstractMsvcToolChain::predefinedMacros(const QStringList &cxxflags) const { - return createPredefinedMacrosRunner()(cxxflags); + return createMacroInspectionRunner()(cxxflags).macros; } -ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList &cxxflags) const +LanguageExtensions AbstractMsvcToolChain::languageExtensions(const QStringList &cxxflags) const { - CompilerFlags flags(MicrosoftExtensions); + LanguageExtensions extensions(LanguageExtension::Microsoft); if (cxxflags.contains(QLatin1String("/openmp"))) - flags |= OpenMP; + extensions |= LanguageExtension::OpenMP; // see http://msdn.microsoft.com/en-us/library/0k0w269d%28v=vs.71%29.aspx if (cxxflags.contains(QLatin1String("/Za"))) - flags &= ~MicrosoftExtensions; + extensions &= ~LanguageExtensions(LanguageExtension::Microsoft); - bool cLanguage = (language() == ProjectExplorer::Constants::C_LANGUAGE_ID); - - switch (m_abi.osFlavor()) { - case Abi::WindowsMsvc2010Flavor: - case Abi::WindowsMsvc2012Flavor: - if (cLanguage) - flags |= StandardC99; - else - flags |= StandardCxx11; - break; - case Abi::WindowsMsvc2013Flavor: - case Abi::WindowsMsvc2015Flavor: - if (cLanguage) - flags |= StandardC99; - else - flags |= StandardCxx14; - break; - case Abi::WindowsMsvc2017Flavor: - if (cLanguage) - flags |= StandardC11; - else if (cxxflags.contains("/std:c++17") || cxxflags.contains("/std:c++latest")) - flags |= StandardCxx17; - else - flags |= StandardCxx14; - break; - default: - break; - } - - return flags; + return extensions; } /** @@ -427,6 +470,11 @@ void AbstractMsvcToolChain::inferWarningsForLevel(int warningLevel, WarningFlags flags |= WarningFlags::UnusedParams; } +void Internal::AbstractMsvcToolChain::toolChainUpdated() +{ + m_predefinedMacrosCache->invalidate(); +} + bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const { if (!ToolChain::operator ==(other)) diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h index 2979e728cc8..a0836e4dc6c 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.h +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h @@ -26,6 +26,7 @@ #pragma once #include "toolchain.h" +#include "toolchaincache.h" #include "abi.h" #include "headerpath.h" @@ -53,9 +54,9 @@ public: QString originalTargetTriple() const override; - PredefinedMacrosRunner createPredefinedMacrosRunner() const override; + MacroInspectionRunner createMacroInspectionRunner() const override; Macros predefinedMacros(const QStringList &cxxflags) const override; - CompilerFlags compilerFlags(const QStringList &cxxflags) const override; + LanguageExtensions languageExtensions(const QStringList &cxxflags) const override; WarningFlags warningFlags(const QStringList &cflags) const override; BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, @@ -92,6 +93,7 @@ protected: }; static void inferWarningsForLevel(int warningLevel, WarningFlags &flags); + void toolChainUpdated() override; virtual Utils::Environment readEnvironmentSetting(const Utils::Environment& env) const = 0; // Function must be thread-safe! virtual Macros msvcPredefinedMacros(const QStringList cxxflags, @@ -99,8 +101,9 @@ protected: Utils::FileName m_debuggerCommand; - mutable QMutex *m_predefinedMacrosMutex = nullptr; - mutable Macros m_predefinedMacros; + + mutable std::shared_ptr> m_predefinedMacrosCache; + mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment. mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC mutable QMutex *m_headerPathsMutex = nullptr; diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index f9cb0a81a76..d2c6ed8eea0 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -116,12 +116,13 @@ bool CustomToolChain::isValid() const return true; } -ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner() const +ToolChain::MacroInspectionRunner CustomToolChain::createMacroInspectionRunner() const { const Macros theMacros = m_predefinedMacros; + const Core::Id lang = language(); // This runner must be thread-safe! - return [theMacros](const QStringList &cxxflags){ + return [theMacros, lang](const QStringList &cxxflags){ Macros macros = theMacros; for (const QString &cxxFlag : cxxflags) { if (cxxFlag.startsWith(QLatin1String("-D"))) @@ -130,21 +131,18 @@ ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner( macros.append({cxxFlag.mid(2).trimmed().toUtf8(), MacroType::Undefine}); } - return macros; + return MacroInspectionReport{macros, ToolChain::languageVersion(lang, macros)}; }; } Macros CustomToolChain::predefinedMacros(const QStringList &cxxflags) const { - return createPredefinedMacrosRunner()(cxxflags); + return createMacroInspectionRunner()(cxxflags).macros; } -ToolChain::CompilerFlags CustomToolChain::compilerFlags(const QStringList &cxxflags) const +LanguageExtensions CustomToolChain::languageExtensions(const QStringList &) const { - for (const QString &cxx11Flag : m_cxx11Flags) - if (cxxflags.contains(cxx11Flag)) - return StandardCxx11; - return NoFlags; + return LanguageExtension::None; } WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h index 23abb2e7301..e9d672ad33d 100644 --- a/src/plugins/projectexplorer/customtoolchain.h +++ b/src/plugins/projectexplorer/customtoolchain.h @@ -71,9 +71,9 @@ public: bool isValid() const override; - PredefinedMacrosRunner createPredefinedMacrosRunner() const override; + MacroInspectionRunner createMacroInspectionRunner() const override; Macros predefinedMacros(const QStringList &cxxflags) const override; - CompilerFlags compilerFlags(const QStringList &cxxflags) const override; + LanguageExtensions languageExtensions(const QStringList &cxxflags) const override; WarningFlags warningFlags(const QStringList &cxxflags) const override; const Macros &rawPredefinedMacros() const; void setPredefinedMacros(const Macros ¯os); diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 622b477ca21..390ce5706dd 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -254,7 +254,7 @@ GccToolChain::GccToolChain(Detection d) : GccToolChain::GccToolChain(Core::Id typeId, Detection d) : ToolChain(typeId, d), - m_predefinedMacrosCache(std::make_shared, 64>>()), + m_predefinedMacrosCache(std::make_shared>()), m_headerPathsCache(std::make_shared>()) { } @@ -302,9 +302,9 @@ QString GccToolChain::defaultDisplayName() const compilerCommand().parentDir().toUserOutput()); } -ToolChain::CompilerFlags GccToolChain::defaultCompilerFlags() const +LanguageExtensions GccToolChain::defaultLanguageExtensions() const { - return CompilerFlags(GnuExtensions); + return LanguageExtension::Gnu; } QString GccToolChain::typeDisplayName() const @@ -385,9 +385,7 @@ static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath, return path.isEmpty() ? compilerPath : path; } -Q_GLOBAL_STATIC_WITH_ARGS(const QVector, unwantedMacros, ({"__cplusplus"})) - -ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() const +ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() const { // Using a clean environment breaks ccache/distcc/etc. Environment env = Environment::systemEnvironment(); @@ -396,7 +394,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c const QStringList platformCodeGenFlags = m_platformCodeGenFlags; OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter; QTC_CHECK(reinterpretOptions); - std::shared_ptr, 64>> macroCache = m_predefinedMacrosCache; + std::shared_ptr> macroCache = m_predefinedMacrosCache; Core::Id lang = language(); // This runner must be thread-safe! @@ -436,28 +434,27 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c } arguments = reinterpretOptions(arguments); - const Utils::optional> cachedMacros = macroCache->check(arguments); + const Utils::optional cachedMacros = macroCache->check(arguments); if (cachedMacros) return cachedMacros.value(); - const QVector macros - = gccPredefinedMacros(findLocalCompiler(compilerCommand, env), - arguments, - env.toStringList()); - const QVector filteredMacros = Utils::filtered(macros, [](const Macro &m) { - return !unwantedMacros->contains(m.key); - }); - macroCache->insert(arguments, filteredMacros); + const Macros macros = gccPredefinedMacros(findLocalCompiler(compilerCommand, env), + arguments, + env.toStringList()); - qCDebug(gccLog) << "Reporting macros to code model:"; - for (const Macro &m : filteredMacros) { + const auto report = MacroInspectionReport{macros, languageVersion(lang, macros)}; + macroCache->insert(arguments, report); + + qCDebug(gccLog) << "MacroInspectionReport for code model:"; + qCDebug(gccLog) << "Language version:" << static_cast(report.languageVersion); + for (const Macro &m : macros) { qCDebug(gccLog) << compilerCommand.toUserOutput() << (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [") << arguments.join(", ") << "]" << QString::fromUtf8(m.toByteArray()); } - return filteredMacros; + return report; }; } @@ -472,74 +469,33 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c */ ProjectExplorer::Macros GccToolChain::predefinedMacros(const QStringList &cxxflags) const { - return createPredefinedMacrosRunner()(cxxflags); + return createMacroInspectionRunner()(cxxflags).macros; } /** - * @brief Parses gcc flags -std=*, -fopenmp, -fms-extensions, -ansi. + * @brief Parses gcc flags -std=*, -fopenmp, -fms-extensions. * @see http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html */ -ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags) const +LanguageExtensions GccToolChain::languageExtensions(const QStringList &cxxflags) const { - CompilerFlags flags = defaultCompilerFlags(); + LanguageExtensions extensions = defaultLanguageExtensions(); const QStringList allCxxflags = m_platformCodeGenFlags + cxxflags; // add only cxxflags is empty? foreach (const QString &flag, allCxxflags) { if (flag.startsWith("-std=")) { const QByteArray std = flag.mid(5).toLatin1(); - if (std == "c++98" || std == "c++03") { - flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | StandardCxx17 | GnuExtensions); - flags |= StandardCxx98; - } else if (std == "gnu++98" || std == "gnu++03") { - flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | StandardCxx17); - flags |= GnuExtensions; - } else if (std == "c++0x" || std == "c++11") { - flags |= StandardCxx11; - flags &= ~CompilerFlags(StandardCxx14 | StandardCxx17 | GnuExtensions); - } else if (std == "c++14" || std == "c++1y") { - flags |= StandardCxx14; - flags &= ~CompilerFlags(StandardCxx11 | StandardCxx17 | GnuExtensions); - } else if (std == "c++17" || std == "c++1z") { - flags |= StandardCxx17; - flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | GnuExtensions); - } else if (std == "gnu++0x" || std == "gnu++11") { - flags |= CompilerFlags(StandardCxx11 | GnuExtensions); - flags &= ~CompilerFlags(StandardCxx14 | StandardCxx17); - } else if (std== "gnu++14" || std == "gnu++1y") { - flags |= CompilerFlags(StandardCxx14 | GnuExtensions); - flags &= ~CompilerFlags(StandardCxx11 | StandardCxx17); - } else if (std== "gnu++17" || std == "gnu++1z") { - flags |= CompilerFlags(StandardCxx17 | GnuExtensions); - flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14); - } 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); - } + if (std.startsWith("gnu")) + extensions |= LanguageExtension::Gnu; + else + extensions &= ~LanguageExtensions(LanguageExtension::Gnu); } else if (flag == "-fopenmp") { - flags |= OpenMP; + extensions |= LanguageExtension::Gnu; } else if (flag == "-fms-extensions") { - flags |= MicrosoftExtensions; - } else if (flag == "-ansi") { - flags &= ~CompilerFlags(StandardCxx11 | GnuExtensions - | StandardC99 | StandardC11); + extensions |= LanguageExtension::Microsoft; } } - return flags; + return extensions; } WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const @@ -1069,7 +1025,10 @@ QList GccToolChainFactory::autoDetectToolChain(const FileName &comp return result; tc->setLanguage(language); - tc->m_predefinedMacrosCache->insert(QStringList(), macros); + tc->m_predefinedMacrosCache + ->insert(QStringList(), + ToolChain::MacroInspectionReport{macros, + ToolChain::languageVersion(language, macros)}); tc->setCompilerCommand(compilerPath); tc->setSupportedAbis(detectedAbis.supportedAbis); tc->setTargetAbi(abi); @@ -1134,7 +1093,11 @@ void GccToolChainConfigWidget::applyImpl() tc->setDisplayName(displayName); // reset display name tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text())); tc->setPlatformLinkerFlags(splitString(m_platformLinkerFlagsLineEdit->text())); - tc->m_predefinedMacrosCache->insert(tc->platformCodeGenFlags(), m_macros); + tc->m_predefinedMacrosCache + ->insert(tc->platformCodeGenFlags(), + ToolChain::MacroInspectionReport{m_macros, + ToolChain::languageVersion(tc->language(), + m_macros)}); } void GccToolChainConfigWidget::setFromToolchain() @@ -1268,15 +1231,15 @@ QString ClangToolChain::makeCommand(const Environment &environment) const } /** - * @brief Similar to \a GccToolchain::compilerFlags, but recognizes + * @brief Similar to \a GccToolchain::languageExtensions, but recognizes * "-fborland-extensions". */ -ToolChain::CompilerFlags ClangToolChain::compilerFlags(const QStringList &cxxflags) const +LanguageExtensions ClangToolChain::languageExtensions(const QStringList &cxxflags) const { - CompilerFlags flags = GccToolChain::compilerFlags(cxxflags); + LanguageExtensions extensions = GccToolChain::languageExtensions(cxxflags); if (cxxflags.contains("-fborland-extensions")) - flags |= BorlandExtensions; - return flags; + extensions |= LanguageExtension::Borland; + return extensions; } WarningFlags ClangToolChain::warningFlags(const QStringList &cflags) const @@ -1317,9 +1280,9 @@ void ClangToolChain::addToEnvironment(Environment &env) const env.unset("PWD"); } -ToolChain::CompilerFlags ClangToolChain::defaultCompilerFlags() const +LanguageExtensions ClangToolChain::defaultLanguageExtensions() const { - return CompilerFlags(GnuExtensions | StandardCxx11); + return LanguageExtension::Gnu; } IOutputParser *ClangToolChain::outputParser() const @@ -1365,12 +1328,12 @@ QList ClangToolChainFactory::autoDetect(const QList &a const FileName compilerPath = FileName::fromString(Core::ICore::clangExecutable(CLANG_BINDIR)); if (!compilerPath.isEmpty()) { - tcs.append(autoDetectToolchains(compilerPath.parentDir().appendPath( - HostOsInfo::withExecutableSuffix("clang++")), + const FileName clang = compilerPath.parentDir().appendPath( + HostOsInfo::withExecutableSuffix("clang")); + tcs.append(autoDetectToolchains(clang, hostAbi, Constants::CXX_LANGUAGE_ID, Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown)); - tcs.append(autoDetectToolchains(compilerPath.parentDir().appendPath( - HostOsInfo::withExecutableSuffix("clang")), + tcs.append(autoDetectToolchains(clang, hostAbi, Constants::C_LANGUAGE_ID, Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown)); } @@ -1510,25 +1473,25 @@ QString LinuxIccToolChain::typeDisplayName() const } /** - * Similar to \a GccToolchain::compilerFlags, but uses "-openmp" instead of + * Similar to \a GccToolchain::languageExtensions, 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 +LanguageExtensions LinuxIccToolChain::languageExtensions(const QStringList &cxxflags) const { QStringList copy = cxxflags; copy.removeAll("-fopenmp"); copy.removeAll("-fms-extensions"); - CompilerFlags flags = GccToolChain::compilerFlags(cxxflags); + LanguageExtensions extensions = GccToolChain::languageExtensions(cxxflags); if (cxxflags.contains("-openmp")) - flags |= OpenMP; + extensions |= LanguageExtension::OpenMP; if (cxxflags.contains("-fms-dialect") || cxxflags.contains("-fms-dialect=8") || cxxflags.contains("-fms-dialect=9") || cxxflags.contains("-fms-dialect=10")) - flags |= MicrosoftExtensions; - return flags; + extensions |= LanguageExtension::Microsoft; + return extensions; } IOutputParser *LinuxIccToolChain::outputParser() const diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 3458f634140..13685101fdc 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -28,14 +28,11 @@ #include "projectexplorer_export.h" #include "toolchain.h" +#include "toolchaincache.h" #include "abi.h" #include "headerpath.h" #include -#include - -#include -#include #include #include @@ -54,79 +51,6 @@ class LinuxIccToolChainFactory; // GccToolChain // -------------------------------------------------------------------------- -template -class Cache -{ -public: - Cache() { m_cache.reserve(Size); } - Cache(const Cache &other) = delete; - Cache &operator =(const Cache &other) = delete; - - Cache(Cache &&other) - { - using std::swap; - - QMutexLocker otherLocker(&other.m_mutex); - swap(m_cache, other.m_cache); - } - - Cache &operator =(Cache &&other) - { - using std::swap; - - QMutexLocker locker(&m_mutex); - QMutexLocker otherLocker(&other.m_mutex); - auto temporay(std::move(other.m_cache)); // Make sure other.m_cache is empty! - swap(m_cache, temporay); - return *this; - } - - void insert(const QStringList &compilerArguments, const T &values) - { - CacheItem runResults; - runResults.first = compilerArguments; - runResults.second = values; - - QMutexLocker locker(&m_mutex); - if (!checkImpl(compilerArguments)) { - if (m_cache.size() < Size) { - m_cache.push_back(runResults); - } else { - std::rotate(m_cache.begin(), std::next(m_cache.begin()), m_cache.end()); - m_cache.back() = runResults; - } - } - } - - Utils::optional check(const QStringList &compilerArguments) - { - QMutexLocker locker(&m_mutex); - return checkImpl(compilerArguments); - } - - void invalidate() - { - QMutexLocker locker(&m_mutex); - m_cache.clear(); - } - -private: - Utils::optional checkImpl(const QStringList &compilerArguments) - { - auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) { - return ci.first != compilerArguments; - }); - if (it != m_cache.end()) - return m_cache.back().second; - return {}; - } - - using CacheItem = QPair; - - QMutex m_mutex; - QVector m_cache; -}; - class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain { public: @@ -140,10 +64,10 @@ public: bool isValid() const override; - CompilerFlags compilerFlags(const QStringList &cxxflags) const override; + LanguageExtensions languageExtensions(const QStringList &cxxflags) const override; WarningFlags warningFlags(const QStringList &cflags) const override; - PredefinedMacrosRunner createPredefinedMacrosRunner() const override; + MacroInspectionRunner createMacroInspectionRunner() const override; Macros predefinedMacros(const QStringList &cxxflags) const override; BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; @@ -200,7 +124,7 @@ protected: Macros macroCache(const QStringList &allCxxflags) const; virtual QString defaultDisplayName() const; - virtual CompilerFlags defaultCompilerFlags() const; + virtual LanguageExtensions defaultLanguageExtensions() const; virtual DetectedAbisResult detectSupportedAbis() const; virtual QString detectVersion() const; @@ -253,7 +177,7 @@ private: mutable HeaderPaths m_headerPaths; mutable QString m_version; - mutable std::shared_ptr, 64>> m_predefinedMacrosCache; + mutable std::shared_ptr> m_predefinedMacrosCache; mutable std::shared_ptr> m_headerPathsCache; mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {}; @@ -273,7 +197,7 @@ public: QString typeDisplayName() const override; QString makeCommand(const Utils::Environment &environment) const override; - CompilerFlags compilerFlags(const QStringList &cxxflags) const override; + LanguageExtensions languageExtensions(const QStringList &cxxflags) const override; WarningFlags warningFlags(const QStringList &cflags) const override; IOutputParser *outputParser() const override; @@ -284,7 +208,7 @@ public: void addToEnvironment(Utils::Environment &env) const override; protected: - CompilerFlags defaultCompilerFlags() const override; + LanguageExtensions defaultLanguageExtensions() const override; private: friend class Internal::ClangToolChainFactory; @@ -321,7 +245,7 @@ class PROJECTEXPLORER_EXPORT LinuxIccToolChain : public GccToolChain public: QString typeDisplayName() const override; - CompilerFlags compilerFlags(const QStringList &cxxflags) const override; + LanguageExtensions languageExtensions(const QStringList &cxxflags) const override; IOutputParser *outputParser() const override; ToolChain *clone() const override; diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp index 1ef81e7d455..3a01d9e0454 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp @@ -314,6 +314,24 @@ JsonWizardFactory *JsonWizardFactory::createWizardFactory(const QVariantMap &dat return factory; } +static QStringList environmentTemplatesPaths() +{ + QStringList paths; + + QString envTempPath = QString::fromLocal8Bit(qgetenv("QTCREATOR_TEMPLATES_PATH")); + + if (!envTempPath.isEmpty()) { + for (const QString &path : envTempPath + .split(Utils::HostOsInfo::pathListSeparator(), QString::SkipEmptyParts)) { + QString canonicalPath = QDir(path).canonicalPath(); + if (!canonicalPath.isEmpty() && !paths.contains(canonicalPath)) + paths.append(canonicalPath); + } + } + + return paths; +} + Utils::FileNameList &JsonWizardFactory::searchPaths() { static Utils::FileNameList m_searchPaths = Utils::FileNameList() @@ -321,6 +339,9 @@ Utils::FileNameList &JsonWizardFactory::searchPaths() QLatin1String(WIZARD_PATH)) << Utils::FileName::fromString(Core::ICore::resourcePath() + QLatin1Char('/') + QLatin1String(WIZARD_PATH)); + for (const QString &environmentTemplateDirName : environmentTemplatesPaths()) + m_searchPaths << Utils::FileName::fromString(environmentTemplateDirName); + return m_searchPaths; } diff --git a/src/plugins/projectexplorer/language.h b/src/plugins/projectexplorer/language.h new file mode 100644 index 00000000000..5946553a6dd --- /dev/null +++ b/src/plugins/projectexplorer/language.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace ProjectExplorer { + +enum class LanguageVersion { + C89, + C99, + C11, + C18, + LatestC = C18, + CXX98, + CXX03, + CXX11, + CXX14, + CXX17, + CXX2a, + LatestCxx = CXX2a, +}; + +enum class LanguageExtension { + None = 0, + + Gnu = 1 << 0, + Microsoft = 1 << 1, + Borland = 1 << 2, + OpenMP = 1 << 3, + ObjectiveC = 1 << 4, + + All = Gnu + | Microsoft + | Borland + | OpenMP + | ObjectiveC +}; + +Q_DECLARE_FLAGS(LanguageExtensions, LanguageExtension) + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 765dc86d384..50c3a9d369f 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -334,6 +334,7 @@ static QByteArray msvcCompilationFile() "__CLR_VER", "_CMMN_INTRIN_FUNC", "_CONTROL_FLOW_GUARD", + "__cplusplus", "__cplusplus_cli", "__cplusplus_winrt", "_CPPLIB_VER", @@ -469,8 +470,6 @@ Macros MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags, predefinedMacros.append(Macro::fromKeyValue(define)); } else if (arg.startsWith(QLatin1String("/U"))) { predefinedMacros.append({arg.mid(2).toLocal8Bit(), ProjectExplorer::MacroType::Undefine}); - } else if (arg.startsWith(QLatin1String("-I"))) { - // Include paths should not have any effect on defines } else { toProcess.append(arg); } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 34d52e1b782..65981dbe28e 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -210,8 +210,6 @@ const char OPENFILE[] = "ProjectExplorer.OpenFile"; const char SEARCHONFILESYSTEM[] = "ProjectExplorer.SearchOnFileSystem"; const char SHOWINGRAPHICALSHELL[] = "ProjectExplorer.ShowInGraphicalShell"; const char OPENTERMINALHERE[] = "ProjectExplorer.OpenTerminalHere"; -const char OPENTERMINALHEREBUILD[]= "ProjectExplorer.OpenTerminalHereBuildEnv"; -const char OPENTERMINALHERERUN[] = "ProjectExplorer.OpenTerminalHereRunEnv"; const char DUPLICATEFILE[] = "ProjectExplorer.DuplicateFile"; const char DELETEFILE[] = "ProjectExplorer.DeleteFile"; const char DIFFFILE[] = "ProjectExplorer.DiffFile"; @@ -883,11 +881,13 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er dd->m_openTerminalHereBuildEnv = new QAction(tr("Build Environment"), this); dd->m_openTerminalHereRunEnv = new QAction(tr("Run Environment"), this); #if !defined(Q_OS_UNIX) || QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - cmd = ActionManager::registerAction(dd->m_openTerminalHereBuildEnv, Constants::OPENTERMINALHEREBUILD, + cmd = ActionManager::registerAction(dd->m_openTerminalHereBuildEnv, + "ProjectExplorer.OpenTerminalHereBuildEnv", projecTreeContext); dd->m_openTerminalMenu->addAction(dd->m_openTerminalHereBuildEnv); - cmd = ActionManager::registerAction(dd->m_openTerminalHereRunEnv, Constants::OPENTERMINALHERERUN, + cmd = ActionManager::registerAction(dd->m_openTerminalHereRunEnv, + "ProjectExplorer.OpenTerminalHereRunEnv", projecTreeContext); dd->m_openTerminalMenu->addAction(dd->m_openTerminalHereRunEnv); #endif diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index 8e21d9a0dd2..adb2d74e377 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -89,6 +89,7 @@ HEADERS += projectexplorer.h \ projectmodels.h \ currentprojectfind.h \ toolchain.h \ + toolchaincache.h \ toolchainconfigwidget.h \ toolchainmanager.h \ toolchainoptionspage.h \ diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 58646326fab..148d9f3057e 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -145,6 +145,7 @@ Project { "taskmodel.cpp", "taskmodel.h", "taskwindow.cpp", "taskwindow.h", "toolchain.cpp", "toolchain.h", + "toolchaincache.h", "toolchainconfigwidget.cpp", "toolchainconfigwidget.h", "toolchainmanager.cpp", "toolchainmanager.h", "toolchainoptionspage.cpp", "toolchainoptionspage.h", diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index e0c1b113a86..a3f875726ec 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -286,6 +286,65 @@ bool ToolChain::fromMap(const QVariantMap &data) return true; } +static long toLanguageVersionAsLong(QByteArray dateAsByteArray) +{ + dateAsByteArray.chop(1); // Strip 'L'. + return dateAsByteArray.toLong(nullptr); +} + +LanguageVersion ToolChain::cxxLanguageVersion(const QByteArray &cplusplusMacroValue) +{ + const long version = toLanguageVersionAsLong(cplusplusMacroValue); + + if (version > 201703L) + return LanguageVersion::LatestCxx; + if (version > 201402L) + return LanguageVersion::CXX17; + if (version > 201103L) + return LanguageVersion::CXX14; + if (version == 201103L) + return LanguageVersion::CXX11; + + return LanguageVersion::CXX03; +} + +LanguageVersion ToolChain::languageVersion(const Core::Id &language, const Macros ¯os) +{ + if (language == Constants::CXX_LANGUAGE_ID) { + for (const ProjectExplorer::Macro ¯o : macros) { + if (macro.key == "__cplusplus") // Check for the C++ identifying macro + return cxxLanguageVersion(macro.value); + } + + QTC_CHECK(false && "__cplusplus is not predefined, assuming latest C++ we support."); + return LanguageVersion::LatestCxx; + } else if (language == Constants::C_LANGUAGE_ID) { + for (const ProjectExplorer::Macro ¯o : macros) { + if (macro.key == "__STDC_VERSION__") { + const long version = toLanguageVersionAsLong(macro.value); + + if (version > 201710L) + return LanguageVersion::LatestC; + if (version > 201112L) + return LanguageVersion::C18; + if (version > 199901L) + return LanguageVersion::C11; + if (version > 199409L) + return LanguageVersion::C99; + + return LanguageVersion::C89; + } + } + + // The __STDC_VERSION__ macro was introduced after C89. + // We haven't seen it, so it must be C89. + return LanguageVersion::C89; + } else { + QTC_CHECK(false && "Unexpected toolchain language, assuming latest C++ we support."); + return LanguageVersion::LatestCxx; + } +} + /*! Used by the tool chain kit information to validate the kit. */ diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index fcc7e93d062..1976b0925b6 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -29,6 +29,7 @@ #include "projectexplorer_global.h" #include "headerpath.h" +#include "language.h" #include "projectmacro.h" #include @@ -107,28 +108,19 @@ public: virtual bool isValid() const = 0; - enum CompilerFlag { - NoFlags = 0, - StandardCxx11 = 0x1, - StandardC99 = 0x2, - StandardC11 = 0x4, - GnuExtensions = 0x8, - MicrosoftExtensions = 0x10, - BorlandExtensions = 0x20, - OpenMP = 0x40, - ObjectiveC = 0x80, - StandardCxx14 = 0x100, - StandardCxx17 = 0x200, - StandardCxx98 = 0x400, - }; - Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag) - - virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0; + virtual LanguageExtensions languageExtensions(const QStringList &cxxflags) const = 0; virtual WarningFlags warningFlags(const QStringList &cflags) const = 0; - // A PredefinedMacrosRunner is created in the ui thread and runs in another thread. - using PredefinedMacrosRunner = std::function; - virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const = 0; + class MacroInspectionReport + { + public: + Macros macros; + LanguageVersion languageVersion; + }; + + // A MacroInspectionRunner is created in the ui thread and runs in another thread. + using MacroInspectionRunner = std::function; + virtual MacroInspectionRunner createMacroInspectionRunner() const = 0; virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0; // A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread. @@ -157,6 +149,8 @@ public: virtual QList validateKit(const Kit *k) const; void setLanguage(Core::Id language); + static LanguageVersion cxxLanguageVersion(const QByteArray &cplusplusMacroValue); + static LanguageVersion languageVersion(const Core::Id &language, const Macros ¯os); protected: explicit ToolChain(Core::Id typeId, Detection d); diff --git a/src/plugins/projectexplorer/toolchaincache.h b/src/plugins/projectexplorer/toolchaincache.h new file mode 100644 index 00000000000..154c09162f8 --- /dev/null +++ b/src/plugins/projectexplorer/toolchaincache.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace ProjectExplorer { + +template +class Cache +{ +public: + Cache() { m_cache.reserve(Size); } + Cache(const Cache &other) = delete; + Cache &operator =(const Cache &other) = delete; + + Cache(Cache &&other) + { + using std::swap; + + QMutexLocker otherLocker(&other.m_mutex); + swap(m_cache, other.m_cache); + } + + Cache &operator =(Cache &&other) + { + using std::swap; + + QMutexLocker locker(&m_mutex); + QMutexLocker otherLocker(&other.m_mutex); + auto temporay(std::move(other.m_cache)); // Make sure other.m_cache is empty! + swap(m_cache, temporay); + return *this; + } + + void insert(const QStringList &compilerArguments, const T &values) + { + CacheItem runResults; + runResults.first = compilerArguments; + runResults.second = values; + + QMutexLocker locker(&m_mutex); + if (!checkImpl(compilerArguments)) { + if (m_cache.size() < Size) { + m_cache.push_back(runResults); + } else { + std::rotate(m_cache.begin(), std::next(m_cache.begin()), m_cache.end()); + m_cache.back() = runResults; + } + } + } + + Utils::optional check(const QStringList &compilerArguments) + { + QMutexLocker locker(&m_mutex); + return checkImpl(compilerArguments); + } + + void invalidate() + { + QMutexLocker locker(&m_mutex); + m_cache.clear(); + } + +private: + Utils::optional checkImpl(const QStringList &compilerArguments) + { + auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) { + return ci.first != compilerArguments; + }); + if (it != m_cache.end()) + return m_cache.back().second; + return {}; + } + + using CacheItem = QPair; + + QMutex m_mutex; + QVector m_cache; +}; + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp index 409812440f0..80d280a1227 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp @@ -308,9 +308,9 @@ public: QString typeDisplayName() const override { return QString("Test Tool Chain"); } Abi targetAbi() const override { return Abi::hostAbi(); } bool isValid() const override { return m_valid; } - PredefinedMacrosRunner createPredefinedMacrosRunner() const override { return PredefinedMacrosRunner(); } + MacroInspectionRunner createMacroInspectionRunner() const override { return MacroInspectionRunner(); } Macros predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return Macros(); } - CompilerFlags compilerFlags(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return NoFlags; } + LanguageExtensions languageExtensions(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return LanguageExtension::None; } WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags); return WarningFlags::NoWarnings; } BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override { return BuiltInHeaderPathsRunner(); } HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, const FileName &sysRoot) const override diff --git a/src/plugins/projectexplorer/userfileaccessor.cpp b/src/plugins/projectexplorer/userfileaccessor.cpp index a20000ea792..e47e9a2dc7c 100644 --- a/src/plugins/projectexplorer/userfileaccessor.cpp +++ b/src/plugins/projectexplorer/userfileaccessor.cpp @@ -152,47 +152,6 @@ Q_DECLARE_TYPEINFO(HandlerNode, Q_MOVABLE_TYPE); QT_END_NAMESPACE -static HandlerNode buildHandlerNodes(const char * const **keys) -{ - HandlerNode ret; - while (const char *rname = *(*keys)++) { - QString name = QLatin1String(rname); - if (name.endsWith('.')) { - HandlerNode sub = buildHandlerNodes(keys); - foreach (const QString &key, name.split('|')) - ret.children.insert(key, sub); - } else { - ret.strings.insert(name); - } - } - return ret; -} - -static QVariantMap processHandlerNodes(const HandlerNode &node, const QVariantMap &map, - QVariant (*handler)(const QVariant &var)) -{ - QVariantMap result; - QMapIterator it(map); - while (it.hasNext()) { - it.next(); - const QString &key = it.key(); - if (node.strings.contains(key)) { - result.insert(key, handler(it.value())); - goto handled; - } - if (it.value().type() == QVariant::Map) - for (QHash::ConstIterator subit = node.children.constBegin(); - subit != node.children.constEnd(); ++subit) - if (key.startsWith(subit.key())) { - result.insert(key, processHandlerNodes(subit.value(), it.value().toMap(), handler)); - goto handled; - } - result.insert(key, it.value()); - handled: ; - } - return result; -} - // -------------------------------------------------------------------- // Helpers: // -------------------------------------------------------------------- diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 1e07625be3a..7981547ab37 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -915,10 +915,8 @@ void QbsProject::updateCppCodeModel() CppTools::ProjectPart::QtVersion qtVersionFromKit = CppTools::ProjectPart::NoQt; if (qtVersion) { - if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) - qtVersionFromKit = CppTools::ProjectPart::Qt4_8_6AndOlder; - else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) - qtVersionFromKit = CppTools::ProjectPart::Qt4Latest; + if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) + qtVersionFromKit = CppTools::ProjectPart::Qt4; else qtVersionFromKit = CppTools::ProjectPart::Qt5; } diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index e825d600a2a..25477977806 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -277,10 +277,8 @@ void QmakeProject::updateCppCodeModel() QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k); ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt; if (qtVersion) { - if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) - qtVersionForPart = ProjectPart::Qt4_8_6AndOlder; - else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) - qtVersionForPart = ProjectPart::Qt4Latest; + if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) + qtVersionForPart = ProjectPart::Qt4; else qtVersionForPart = ProjectPart::Qt5; } diff --git a/src/plugins/qtsupport/qscxmlcgenerator.cpp b/src/plugins/qtsupport/qscxmlcgenerator.cpp index 309113322a1..d015d9d445f 100644 --- a/src/plugins/qtsupport/qscxmlcgenerator.cpp +++ b/src/plugins/qtsupport/qscxmlcgenerator.cpp @@ -38,7 +38,7 @@ using namespace ProjectExplorer; namespace QtSupport { -static QLoggingCategory log("qtc.qsxmlcgenerator"); +static QLoggingCategory log("qtc.qscxmlcgenerator"); static const char TaskCategory[] = "Task.Category.ExtraCompiler.QScxmlc"; QScxmlcGenerator::QScxmlcGenerator(const Project *project, diff --git a/src/plugins/silversearcher/findinfilessilversearcher.cpp b/src/plugins/silversearcher/findinfilessilversearcher.cpp index a986df14580..3c8f19bc487 100644 --- a/src/plugins/silversearcher/findinfilessilversearcher.cpp +++ b/src/plugins/silversearcher/findinfilessilversearcher.cpp @@ -119,7 +119,15 @@ void runSilverSeacher(FutureInterfaceType &fi, FileFindParameters parameters) process.start("ag", arguments); if (process.waitForFinished()) { typedef QList FileSearchResultList; - SilverSearcher::SilverSearcherOutputParser parser(process.readAll()); + QRegularExpression regexp; + if (parameters.flags & FindRegularExpression) { + const QRegularExpression::PatternOptions patternOptions = + (parameters.flags & FindCaseSensitively) + ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption; + regexp.setPattern(parameters.text); + regexp.setPatternOptions(patternOptions); + } + SilverSearcher::SilverSearcherOutputParser parser(process.readAll(), regexp); FileSearchResultList items = parser.parse(); if (!items.isEmpty()) fi.reportResult(items); @@ -134,7 +142,6 @@ namespace SilverSearcher { FindInFilesSilverSearcher::FindInFilesSilverSearcher(QObject *parent) : SearchEngine(parent), - m_widget(0), m_path("ag"), m_toolName("SilverSearcher") { @@ -190,7 +197,7 @@ QFuture FindInFilesSilverSearcher::executeSearch( IEditor *FindInFilesSilverSearcher::openEditor(const SearchResultItem & /*item*/, const FileFindParameters & /*parameters*/) { - return 0; + return nullptr; } void FindInFilesSilverSearcher::readSettings(QSettings * /*settings*/) diff --git a/src/plugins/silversearcher/silversearcheroutputparser.cpp b/src/plugins/silversearcher/silversearcheroutputparser.cpp index cbc82c5632f..88ec7cdde05 100644 --- a/src/plugins/silversearcher/silversearcheroutputparser.cpp +++ b/src/plugins/silversearcher/silversearcheroutputparser.cpp @@ -30,10 +30,12 @@ namespace SilverSearcher { SilverSearcherOutputParser::SilverSearcherOutputParser( - const QByteArray &output) + const QByteArray &output, const QRegularExpression ®exp) : output(output) + , regexp(regexp) , outputSize(output.size()) { + hasRegexp = !regexp.pattern().isEmpty(); } QList SilverSearcherOutputParser::parse() @@ -102,6 +104,13 @@ bool SilverSearcherOutputParser::parseMatchLength() int SilverSearcherOutputParser::parseMatches() { int matches = 1; + const int colon = output.indexOf(':', index); + QByteArray text; + if (colon != -1) { + const int textStart = colon + 1; + const int newline = output.indexOf('\n', textStart); + text = output.mid(textStart, newline >= 0 ? newline - textStart : -1); + } while (index < outputSize && output[index] != ':') { if (output[index] == ',') { ++matches; @@ -109,6 +118,10 @@ int SilverSearcherOutputParser::parseMatches() } parseMatchIndex(); parseMatchLength(); + if (hasRegexp) { + const QString part = QString::fromUtf8(text.mid(item.matchStart, item.matchLength)); + item.regexpCapturedTexts = regexp.match(part).capturedTexts(); + } items << item; } diff --git a/src/plugins/silversearcher/silversearcheroutputparser.h b/src/plugins/silversearcher/silversearcheroutputparser.h index fd96253427a..1bf0af4685a 100644 --- a/src/plugins/silversearcher/silversearcheroutputparser.h +++ b/src/plugins/silversearcher/silversearcheroutputparser.h @@ -28,15 +28,18 @@ #include #include -#include #include +#include +#include namespace SilverSearcher { class SilverSearcherOutputParser { public: - SilverSearcherOutputParser(const QByteArray &output); + SilverSearcherOutputParser( + const QByteArray &output, + const QRegularExpression ®exp = QRegularExpression()); QList parse(); private: @@ -48,6 +51,8 @@ private: bool parseText(); QByteArray output; + QRegularExpression regexp; + bool hasRegexp = false; int outputSize = 0; int index = 0; Utils::FileSearchResult item; diff --git a/src/plugins/texteditor/displaysettings.cpp b/src/plugins/texteditor/displaysettings.cpp index dd88b770887..7c0eb709664 100644 --- a/src/plugins/texteditor/displaysettings.cpp +++ b/src/plugins/texteditor/displaysettings.cpp @@ -142,7 +142,8 @@ bool DisplaySettings::equals(const DisplaySettings &ds) const QLabel *DisplaySettings::createAnnotationSettingsLink() { - auto label = new QLabel("Annotation Settings", Core::ICore::mainWindow()); + auto label = new QLabel("Annotation Settings", + Core::ICore::mainWindow()); QObject::connect(label, &QLabel::linkActivated, []() { Utils::ToolTip::hideImmediately(); Core::ICore::showOptionsDialog(Constants::TEXT_EDITOR_DISPLAY_SETTINGS); diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp index 425b5773e48..17c6268f85f 100644 --- a/src/plugins/texteditor/textmark.cpp +++ b/src/plugins/texteditor/textmark.cpp @@ -290,6 +290,7 @@ bool TextMark::addToolTipContent(QLayout *target) const } auto textLabel = new QLabel; + textLabel->setOpenExternalLinks(true); textLabel->setText(text); // Differentiate between tool tips that where explicitly set and default tool tips. textLabel->setEnabled(!m_toolTip.isEmpty()); diff --git a/src/plugins/vcsbase/vcsbaseeditorconfig.cpp b/src/plugins/vcsbase/vcsbaseeditorconfig.cpp index 6fd09901bf5..f3f96e3b3fb 100644 --- a/src/plugins/vcsbase/vcsbaseeditorconfig.cpp +++ b/src/plugins/vcsbase/vcsbaseeditorconfig.cpp @@ -305,9 +305,7 @@ void VcsBaseEditorConfig::updateMappedSettings() void VcsBaseEditorConfig::addAction(QAction *action) { - const QList actions = d->m_toolBar->actions(); - // Insert the action before line/column and split actions. - d->m_toolBar->insertAction(actions.at(qMax(actions.count() - 2, 0)), action); + d->m_toolBar->addAction(action); } } // namespace VcsBase diff --git a/src/shared/proparser/qmakeevaluator.cpp b/src/shared/proparser/qmakeevaluator.cpp index 00c87a7a23c..3ed649163d2 100644 --- a/src/shared/proparser/qmakeevaluator.cpp +++ b/src/shared/proparser/qmakeevaluator.cpp @@ -1049,21 +1049,8 @@ void QMakeEvaluator::loadDefaults() if (GetComputerName(name, &name_length)) vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromWCharArray(name)); - QSysInfo::WinVersion ver = QSysInfo::WindowsVersion; - vars[ProKey("QMAKE_HOST.version")] << ProString(QString::number(ver)); - ProString verStr; - switch (ver) { - case QSysInfo::WV_Me: verStr = ProString("WinMe"); break; - case QSysInfo::WV_95: verStr = ProString("Win95"); break; - case QSysInfo::WV_98: verStr = ProString("Win98"); break; - case QSysInfo::WV_NT: verStr = ProString("WinNT"); break; - case QSysInfo::WV_2000: verStr = ProString("Win2000"); break; - case QSysInfo::WV_2003: verStr = ProString("Win2003"); break; - case QSysInfo::WV_XP: verStr = ProString("WinXP"); break; - case QSysInfo::WV_VISTA: verStr = ProString("WinVista"); break; - default: verStr = ProString("Unknown"); break; - } - vars[ProKey("QMAKE_HOST.version_string")] << verStr; + vars[ProKey("QMAKE_HOST.version")] << ProString(QSysInfo::kernelVersion()); + vars[ProKey("QMAKE_HOST.version_string")] << ProString(QSysInfo::productVersion()); SYSTEM_INFO info; GetSystemInfo(&info); diff --git a/src/tools/icons/export.py b/src/tools/icons/export.py index e28b7e6e4e9..6943b18fd74 100644 --- a/src/tools/icons/export.py +++ b/src/tools/icons/export.py @@ -77,9 +77,12 @@ for id in svgIDs: # The shell mode of Inkscape is used to execute several export commands # with one launch of Inkscape. inkscapeShellCommands = "" +pngFiles = [] for id in svgIDs: - inkscapeShellCommands += "qtcreatoricons.svg --export-id=" + id + " --export-id-only --export-png=" + qtcSourceRoot + id + ".png --export-dpi=96\n" - inkscapeShellCommands += "qtcreatoricons.svg --export-id=" + id + " --export-id-only --export-png=" + qtcSourceRoot + id + "@2x.png --export-dpi=192\n" + for scale in [1, 2]: + pngFile = qtcSourceRoot + id + ("" if scale is 1 else "@%dx" % scale) + ".png" + pngFiles.append(pngFile) + inkscapeShellCommands += "qtcreatoricons.svg --export-id=" + id + " --export-id-only --export-png=" + pngFile + " --export-dpi=%d\n" % (scale * 96) inkscapeShellCommands += "quit\n" inkscapeProcess = subprocess.Popen(['inkscape', '--shell'], stdin=subprocess.PIPE, shell=True, cwd=scriptDir) inkscapeProcess.communicate(input=inkscapeShellCommands.encode()) @@ -89,6 +92,5 @@ optipngExecutable = spawn.find_executable("optipng") if not optipngExecutable: sys.stderr.write("optipng was not found in PATH. Please do not push the unoptimized .pngs to the main repository.\n") else: - for id in svgIDs: - subprocess.call(["optipng", "-o7", "-strip", "all", qtcSourceRoot + id + ".png"]) - subprocess.call(["optipng", "-o7", "-strip", "all", qtcSourceRoot + id + "@2x.png"]) + for pngFile in pngFiles: + subprocess.call(["optipng", "-o7", "-strip", "all", pngFile]) diff --git a/tests/unit/mockup/projectexplorer/toolchain.h b/tests/unit/mockup/projectexplorer/toolchain.h index 93cb630c4c6..985184af851 100644 --- a/tests/unit/mockup/projectexplorer/toolchain.h +++ b/tests/unit/mockup/projectexplorer/toolchain.h @@ -25,8 +25,9 @@ #pragma once -#include #include +#include +#include #include #include @@ -39,29 +40,19 @@ class ToolChain public: Core::Id typeId() const { return Core::Id(); } - enum CompilerFlag { - NoFlags = 0, - StandardCxx11 = 0x1, - StandardC99 = 0x2, - StandardC11 = 0x4, - GnuExtensions = 0x8, - MicrosoftExtensions = 0x10, - BorlandExtensions = 0x20, - OpenMP = 0x40, - ObjectiveC = 0x80, - StandardCxx14 = 0x100, - StandardCxx17 = 0x200, - StandardCxx98 = 0x400, - }; - Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag) - Abi targetAbi() const { return Abi(); } using BuiltInHeaderPathsRunner = std::function; virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const { return BuiltInHeaderPathsRunner(); } - using PredefinedMacrosRunner = std::function; - virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const { return PredefinedMacrosRunner(); } + class MacroInspectionReport + { + public: + Macros macros; + LanguageVersion languageVersion; // Derived from macros. + }; + using MacroInspectionRunner = std::function; + virtual MacroInspectionRunner createMacroInspectionRunner() const = 0; virtual QString originalTargetTriple() const { return QString(); } virtual QStringList extraCodeModelFlags() const { return QStringList(); } diff --git a/tests/unit/unittest/compileroptionsbuilder-test.cpp b/tests/unit/unittest/compileroptionsbuilder-test.cpp index ae81f7d0cae..662ff7787f8 100644 --- a/tests/unit/unittest/compileroptionsbuilder-test.cpp +++ b/tests/unit/unittest/compileroptionsbuilder-test.cpp @@ -41,23 +41,30 @@ using ProjectExplorer::Project; MATCHER_P(IsPartOfHeader, headerPart, std::string(negation ? "isn't " : "is ") + headerPart) { - return arg.contains(QString::fromUtf8(headerPart)); + return arg.contains(QString::fromStdString(headerPart)); } +namespace { -class CompilerOptionsBuilderTest : public ::testing::Test +class CompilerOptionsBuilder : public ::testing::Test { protected: void SetUp() final { projectPart.project = project.get(); projectPart.toolchainType = ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID; - projectPart.languageVersion = CppTools::ProjectPart::CXX17; + projectPart.languageVersion = ProjectExplorer::LanguageVersion::CXX17; projectPart.toolChainWordWidth = CppTools::ProjectPart::WordWidth64Bit; projectPart.toolChainTargetTriple = "x86_64-apple-darwin10"; projectPart.extraCodeModelFlags = QStringList{"-arch", "x86_64"}; projectPart.precompiledHeaders = QStringList{TESTDATA_DIR "/compileroptionsbuilder.pch"}; - projectPart.toolChainMacros = {ProjectExplorer::Macro{"foo", "bar"}}; + projectPart.toolChainMacros = {ProjectExplorer::Macro{"foo", "bar"}, + ProjectExplorer::Macro{"__cplusplus", "2"}, + ProjectExplorer::Macro{"__STDC_VERSION__", "2"}, + ProjectExplorer::Macro{"_MSVC_LANG", "2"}, + ProjectExplorer::Macro{"_MSC_BUILD", "2"}, + ProjectExplorer::Macro{"_MSC_FULL_VER", "1900"}, + ProjectExplorer::Macro{"_MSC_VER", "19"}}; projectPart.projectMacros = {ProjectExplorer::Macro{"projectFoo", "projectBar"}}; projectPart.qtVersion = ProjectPart::Qt5; @@ -68,31 +75,51 @@ protected: std::unique_ptr project{std::make_unique()}; ProjectPart projectPart; - CompilerOptionsBuilder compilerOptionsBuilder{projectPart}; + CppTools::CompilerOptionsBuilder compilerOptionsBuilder{projectPart}; }; -TEST_F(CompilerOptionsBuilderTest, AddToolchainAndProjectMacros) +TEST_F(CompilerOptionsBuilder, AddToolchainAndProjectMacros) { compilerOptionsBuilder.addToolchainAndProjectMacros(); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-Dfoo=bar", "-DprojectFoo=projectBar")); } -TEST_F(CompilerOptionsBuilderTest, AddWordWidth) +TEST_F(CompilerOptionsBuilder, AddToolchainAndProjectMacrosWithoutSkipingLanguageDefines) +{ + CppTools::CompilerOptionsBuilder compilerOptionsBuilder{projectPart, + CppTools::UseSystemHeader::No, + CppTools::SkipBuiltIn::No, + CppTools:: SkipLanguageDefines::No}; + + compilerOptionsBuilder.addToolchainAndProjectMacros(); + + ASSERT_THAT(compilerOptionsBuilder.options(), + ElementsAre("-Dfoo=bar", + "-D__cplusplus=2", + "-D__STDC_VERSION__=2", + "-D_MSVC_LANG=2", + "-D_MSC_BUILD=2", + "-D_MSC_FULL_VER=1900", + "-D_MSC_VER=19", + "-DprojectFoo=projectBar")); +} + +TEST_F(CompilerOptionsBuilder, AddWordWidth) { compilerOptionsBuilder.addWordWidth(); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-m64")); } -TEST_F(CompilerOptionsBuilderTest, AddToolchainFlags) +TEST_F(CompilerOptionsBuilder, AddToolchainFlags) { compilerOptionsBuilder.addToolchainFlags(); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-undef")); } -TEST_F(CompilerOptionsBuilderTest, HeaderPathOptionsOrder) +TEST_F(CompilerOptionsBuilder, HeaderPathOptionsOrder) { compilerOptionsBuilder.addHeaderPathOptions(); @@ -103,9 +130,9 @@ TEST_F(CompilerOptionsBuilderTest, HeaderPathOptionsOrder) "-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); } -TEST_F(CompilerOptionsBuilderTest, UseSystemHeader) +TEST_F(CompilerOptionsBuilder, UseSystemHeader) { - CompilerOptionsBuilder compilerOptionsBuilder(projectPart, CppTools::UseSystemHeader::Yes); + CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart, CppTools::UseSystemHeader::Yes); compilerOptionsBuilder.addHeaderPathOptions(); @@ -116,13 +143,14 @@ TEST_F(CompilerOptionsBuilderTest, UseSystemHeader) "-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); } -TEST_F(CompilerOptionsBuilderTest, ClangHeadersPath) +TEST_F(CompilerOptionsBuilder, ClangHeadersPath) { - CompilerOptionsBuilder compilerOptionsBuilder(projectPart, - CppTools::UseSystemHeader::No, - CppTools::SkipBuiltIn::No, - "7.0.0", - ""); + CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart, + CppTools::UseSystemHeader::No, + CppTools::SkipBuiltIn::No, + CppTools::SkipLanguageDefines::Yes, + "7.0.0", + ""); compilerOptionsBuilder.addHeaderPathOptions(); @@ -135,7 +163,7 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersPath) "-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); } -TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderMacOs) +TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderMacOs) { auto defaultPaths = projectPart.headerPaths; projectPart.headerPaths = {HeaderPath{"/usr/include/c++/4.2.1", HeaderPathType::BuiltIn}, @@ -146,11 +174,12 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderMacOs) HeaderPath{"/usr/include", HeaderPathType::BuiltIn} }; projectPart.headerPaths.append(defaultPaths); - CompilerOptionsBuilder compilerOptionsBuilder(projectPart, - CppTools::UseSystemHeader::No, - CppTools::SkipBuiltIn::No, - "7.0.0", - ""); + CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart, + CppTools::UseSystemHeader::No, + CppTools::SkipBuiltIn::No, + CppTools::SkipLanguageDefines::Yes, + "7.0.0", + ""); compilerOptionsBuilder.addHeaderPathOptions(); @@ -168,7 +197,7 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderMacOs) "-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); } -TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderLinux) +TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderLinux) { projectPart.headerPaths = {HeaderPath{"/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8", HeaderPathType::BuiltIn}, HeaderPath{"/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward", HeaderPathType::BuiltIn}, @@ -179,11 +208,12 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderLinux) HeaderPath{"/usr/include", HeaderPathType::BuiltIn} }; projectPart.toolChainTargetTriple = "x86_64-linux-gnu"; - CompilerOptionsBuilder compilerOptionsBuilder(projectPart, - CppTools::UseSystemHeader::No, - CppTools::SkipBuiltIn::No, - "7.0.0", - ""); + CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart, + CppTools::UseSystemHeader::No, + CppTools::SkipBuiltIn::No, + CppTools::SkipLanguageDefines::Yes, + "7.0.0", + ""); compilerOptionsBuilder.addHeaderPathOptions(); @@ -200,75 +230,75 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderLinux) "-isystem", QDir::toNativeSeparators("/usr/include"))); } -TEST_F(CompilerOptionsBuilderTest, NoPrecompiledHeader) +TEST_F(CompilerOptionsBuilder, NoPrecompiledHeader) { - compilerOptionsBuilder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::None); + compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::CompilerOptionsBuilder::PchUsage::None); ASSERT_THAT(compilerOptionsBuilder.options().empty(), true); } -TEST_F(CompilerOptionsBuilderTest, UsePrecompiledHeader) +TEST_F(CompilerOptionsBuilder, UsePrecompiledHeader) { - compilerOptionsBuilder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::Use); + compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::CompilerOptionsBuilder::PchUsage::Use); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-include", QDir::toNativeSeparators(TESTDATA_DIR "/compileroptionsbuilder.pch"))); } -TEST_F(CompilerOptionsBuilderTest, AddMacros) +TEST_F(CompilerOptionsBuilder, AddMacros) { compilerOptionsBuilder.addMacros(ProjectExplorer::Macros{ProjectExplorer::Macro{"key", "value"}}); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-Dkey=value")); } -TEST_F(CompilerOptionsBuilderTest, AddTargetTriple) +TEST_F(CompilerOptionsBuilder, AddTargetTriple) { compilerOptionsBuilder.addTargetTriple(); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-target", "x86_64-apple-darwin10")); } -TEST_F(CompilerOptionsBuilderTest, EnableCExceptions) +TEST_F(CompilerOptionsBuilder, EnableCExceptions) { - projectPart.languageVersion = CppTools::ProjectPart::C99; + projectPart.languageVersion = ProjectExplorer::LanguageVersion::C99; compilerOptionsBuilder.enableExceptions(); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-fexceptions")); } -TEST_F(CompilerOptionsBuilderTest, EnableCXXExceptions) +TEST_F(CompilerOptionsBuilder, EnableCXXExceptions) { compilerOptionsBuilder.enableExceptions(); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-fcxx-exceptions", "-fexceptions")); } -TEST_F(CompilerOptionsBuilderTest, InsertWrappedQtHeaders) +TEST_F(CompilerOptionsBuilder, InsertWrappedQtHeaders) { compilerOptionsBuilder.insertWrappedQtHeaders(); ASSERT_THAT(compilerOptionsBuilder.options(), Contains(IsPartOfHeader("wrappedQtHeaders"))); } -TEST_F(CompilerOptionsBuilderTest, SetLanguageVersion) +TEST_F(CompilerOptionsBuilder, SetLanguageVersion) { compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "c++")); } -TEST_F(CompilerOptionsBuilderTest, HandleLanguageExtension) +TEST_F(CompilerOptionsBuilder, HandleLanguageExtension) { - projectPart.languageExtensions = ProjectPart::ObjectiveCExtensions; + projectPart.languageExtensions = ProjectExplorer::LanguageExtension::ObjectiveC; compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "objective-c++")); } -TEST_F(CompilerOptionsBuilderTest, UpdateLanguageVersion) +TEST_F(CompilerOptionsBuilder, UpdateLanguageVersion) { compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource); @@ -277,7 +307,7 @@ TEST_F(CompilerOptionsBuilderTest, UpdateLanguageVersion) ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "c++-header")); } -TEST_F(CompilerOptionsBuilderTest, AddMsvcCompatibilityVersion) +TEST_F(CompilerOptionsBuilder, AddMsvcCompatibilityVersion) { projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; projectPart.toolChainMacros.append(ProjectExplorer::Macro{"_MSC_FULL_VER", "190000000"}); @@ -287,7 +317,7 @@ TEST_F(CompilerOptionsBuilderTest, AddMsvcCompatibilityVersion) ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-fms-compatibility-version=19.00")); } -TEST_F(CompilerOptionsBuilderTest, UndefineCppLanguageFeatureMacrosForMsvc2015) +TEST_F(CompilerOptionsBuilder, UndefineCppLanguageFeatureMacrosForMsvc2015) { projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; projectPart.isMsvc2015Toolchain = true; @@ -297,7 +327,7 @@ TEST_F(CompilerOptionsBuilderTest, UndefineCppLanguageFeatureMacrosForMsvc2015) ASSERT_THAT(compilerOptionsBuilder.options(), Contains(QString{"-U__cpp_aggregate_bases"})); } -TEST_F(CompilerOptionsBuilderTest, AddDefineFunctionMacrosMsvc) +TEST_F(CompilerOptionsBuilder, AddDefineFunctionMacrosMsvc) { projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; @@ -306,7 +336,7 @@ TEST_F(CompilerOptionsBuilderTest, AddDefineFunctionMacrosMsvc) ASSERT_THAT(compilerOptionsBuilder.options(), Contains(QString{"-D__FUNCTION__=\"\""})); } -TEST_F(CompilerOptionsBuilderTest, AddProjectConfigFileInclude) +TEST_F(CompilerOptionsBuilder, AddProjectConfigFileInclude) { projectPart.projectConfigFile = "dummy_file.h"; @@ -315,7 +345,7 @@ TEST_F(CompilerOptionsBuilderTest, AddProjectConfigFileInclude) ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-include", "dummy_file.h")); } -TEST_F(CompilerOptionsBuilderTest, UndefineClangVersionMacrosForMsvc) +TEST_F(CompilerOptionsBuilder, UndefineClangVersionMacrosForMsvc) { projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; @@ -324,20 +354,21 @@ TEST_F(CompilerOptionsBuilderTest, UndefineClangVersionMacrosForMsvc) ASSERT_THAT(compilerOptionsBuilder.options(), Contains(QString{"-U__clang__"})); } -TEST_F(CompilerOptionsBuilderTest, BuildAllOptions) +TEST_F(CompilerOptionsBuilder, BuildAllOptions) { - compilerOptionsBuilder.build(ProjectFile::CXXSource, CompilerOptionsBuilder::PchUsage::None); + compilerOptionsBuilder.build(ProjectFile::CXXSource, CppTools::CompilerOptionsBuilder::PchUsage::None); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre( "-nostdlibinc", "-c", "-m64", "-target", "x86_64-apple-darwin10", "-arch", "x86_64", "-x", "c++", "-std=c++17", "-fcxx-exceptions", "-fexceptions", "-Dfoo=bar", "-DprojectFoo=projectBar", "-undef", - "-I", QDir::toNativeSeparators("D:/code/qt-creator/tests/unit/unittest/../../../share/qtcreator/cplusplus/wrappedQtHeaders"), - "-I", QDir::toNativeSeparators("D:/code/qt-creator/tests/unit/unittest/../../../share/qtcreator/cplusplus/wrappedQtHeaders/QtCore"), + "-I", IsPartOfHeader("wrappedQtHeaders"), + "-I", IsPartOfHeader(QDir::toNativeSeparators("wrappedQtHeaders/QtCore").toStdString()), "-I", QDir::toNativeSeparators("/tmp/path"), "-I", QDir::toNativeSeparators("/tmp/system_path"), "-isystem", QDir::toNativeSeparators("/tmp/builtin_path") )); } +} diff --git a/tests/unit/unittest/cppprojectinfogenerator-test.cpp b/tests/unit/unittest/cppprojectinfogenerator-test.cpp index 9a991a75204..f1e24b5aee6 100644 --- a/tests/unit/unittest/cppprojectinfogenerator-test.cpp +++ b/tests/unit/unittest/cppprojectinfogenerator-test.cpp @@ -39,6 +39,7 @@ using CppTools::ProjectUpdateInfo; using CppTools::ProjectPart; using CppTools::RawProjectPart; +using ProjectExplorer::Macros; using ProjectExplorer::ToolChain; using testing::Eq; @@ -65,6 +66,7 @@ protected: ProjectInfo generate(); protected: + ProjectUpdateInfo projectUpdateInfo; RawProjectPart rawProjectPart; }; @@ -101,7 +103,7 @@ TEST_F(ProjectInfoGenerator, ProjectPartIndicatesObjectiveCExtensionsByDefault) ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); const ProjectPart &projectPart = *projectInfo.projectParts().at(0); - ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::ObjectiveCExtensions); + ASSERT_TRUE(projectPart.languageExtensions & ProjectExplorer::LanguageExtension::ObjectiveC); } TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault) @@ -112,31 +114,33 @@ TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault) ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); const ProjectPart &projectPart = *projectInfo.projectParts().at(0); - ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::LatestCxxVersion)); + ASSERT_THAT(projectPart.languageVersion, Eq(ProjectExplorer::LanguageVersion::LatestCxx)); } -TEST_F(ProjectInfoGenerator, UseCompilerFlagsForLanguageVersion) +TEST_F(ProjectInfoGenerator, UseMacroInspectionReportForLanguageVersion) { + projectUpdateInfo.cxxToolChainInfo.macroInspectionRunner = [](const QStringList &) { + return ToolChain::MacroInspectionReport{Macros(), ProjectExplorer::LanguageVersion::CXX17}; + }; rawProjectPart.files = QStringList{ "foo.cpp" }; - rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::StandardCxx98; const ProjectInfo projectInfo = generate(); ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); const ProjectPart &projectPart = *projectInfo.projectParts().at(0); - ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::CXX98)); + ASSERT_THAT(projectPart.languageVersion, Eq(ProjectExplorer::LanguageVersion::CXX17)); } -TEST_F(ProjectInfoGenerator, UseCompilerFlagsForLangaugeExtensions) +TEST_F(ProjectInfoGenerator, UseCompilerFlagsForLanguageExtensions) { rawProjectPart.files = QStringList{ "foo.cpp" }; - rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::MicrosoftExtensions; + rawProjectPart.flagsForCxx.languageExtensions = ProjectExplorer::LanguageExtension::Microsoft; const ProjectInfo projectInfo = generate(); ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); const ProjectPart &projectPart = *projectInfo.projectParts().at(0); - ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::MicrosoftExtensions); + ASSERT_TRUE(projectPart.languageExtensions & ProjectExplorer::LanguageExtension::Microsoft); } TEST_F(ProjectInfoGenerator, ProjectFileKindsMatchProjectPartVersion) @@ -146,10 +150,10 @@ TEST_F(ProjectInfoGenerator, ProjectFileKindsMatchProjectPartVersion) const ProjectInfo projectInfo = generate(); ASSERT_THAT(projectInfo.projectParts(), - UnorderedElementsAre(IsProjectPart(ProjectPart::LatestCVersion, ProjectFile::CHeader), - IsProjectPart(ProjectPart::LatestCVersion, ProjectFile::ObjCHeader), - IsProjectPart(ProjectPart::LatestCxxVersion, ProjectFile::CXXHeader), - IsProjectPart(ProjectPart::LatestCxxVersion, ProjectFile::ObjCXXHeader))); + UnorderedElementsAre(IsProjectPart(ProjectExplorer::LanguageVersion::LatestC, ProjectFile::CHeader), + IsProjectPart(ProjectExplorer::LanguageVersion::LatestC, ProjectFile::ObjCHeader), + IsProjectPart(ProjectExplorer::LanguageVersion::LatestCxx, ProjectFile::CXXHeader), + IsProjectPart(ProjectExplorer::LanguageVersion::LatestCxx, ProjectFile::ObjCXXHeader))); } void ProjectInfoGenerator::SetUp() @@ -160,7 +164,7 @@ void ProjectInfoGenerator::SetUp() ProjectInfo ProjectInfoGenerator::generate() { QFutureInterface fi; - ProjectUpdateInfo projectUpdateInfo; + projectUpdateInfo.rawProjectParts += rawProjectPart; ::ProjectInfoGenerator generator(fi, projectUpdateInfo); diff --git a/tests/unit/unittest/cppprojectpartchooser-test.cpp b/tests/unit/unittest/cppprojectpartchooser-test.cpp index 8020d1a35cc..299a888fb76 100644 --- a/tests/unit/unittest/cppprojectpartchooser-test.cpp +++ b/tests/unit/unittest/cppprojectpartchooser-test.cpp @@ -342,12 +342,12 @@ QList ProjectPartChooser::createCAndCxxProjectParts() // Create project part for C const ProjectPart::Ptr cprojectpart{new ProjectPart}; - cprojectpart->languageVersion = ProjectPart::C11; + cprojectpart->languageVersion = ProjectExplorer::LanguageVersion::C11; projectParts.append(cprojectpart); // Create project part for CXX const ProjectPart::Ptr cxxprojectpart{new ProjectPart}; - cxxprojectpart->languageVersion = ProjectPart::CXX98; + cxxprojectpart->languageVersion = ProjectExplorer::LanguageVersion::CXX98; projectParts.append(cxxprojectpart); return projectParts;