Merge remote-tracking branch 'origin/4.8'

Change-Id: I8acb6582890fb2e103996cc4987f7543d22d7108
This commit is contained in:
Eike Ziller
2018-10-11 10:41:25 +02:00
93 changed files with 1072 additions and 802 deletions

View File

@@ -281,6 +281,17 @@
\li Set the current branch to track the selected one. \li Set the current branch to track the selected one.
\endtable \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 \section2 Applying Patches
Patches are rewriting instructions that can be applied to a set of files. Patches are rewriting instructions that can be applied to a set of files.

View File

@@ -685,7 +685,7 @@ static inline QString fixComponentPathForIncompatibleQt(const QString &component
if (componentPath.contains(importString)) { if (componentPath.contains(importString)) {
int index = componentPath.indexOf(importString) + 8; int index = componentPath.indexOf(importString) + 8;
const QString relativeImportPath = componentPath.right(componentPath.length() - index); 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('/')); fixedComponentPath.replace(QLatin1Char('\\'), QLatin1Char('/'));
if (QFileInfo::exists(fixedComponentPath)) if (QFileInfo::exists(fixedComponentPath))
return fixedComponentPath; return fixedComponentPath;

View File

@@ -1834,7 +1834,11 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
error(cursor(), "expected identifier before '%s'", tok().spell()); error(cursor(), "expected identifier before '%s'", tok().spell());
return false; return false;
} }
if (LA() == T_IDENTIFIER)
parseName(ast->name); parseName(ast->name);
else
return false;
if (_languageFeatures.cxx11Enabled && LA() == T_COLON) { if (_languageFeatures.cxx11Enabled && LA() == T_COLON) {
ast->colon_token = consumeToken(); ast->colon_token = consumeToken();

View File

@@ -36,6 +36,13 @@ namespace ClangBackEnd {
using namespace std::chrono_literals; using namespace std::chrono_literals;
static QProcess::ProcessChannelMode kProcessChannelMode
#ifdef Q_OS_WIN
= QProcess::MergedChannels;
#else
= QProcess::ForwardedChannels;
#endif
ProcessCreator::ProcessCreator() ProcessCreator::ProcessCreator()
{ {
} }
@@ -66,7 +73,7 @@ std::future<QProcessUniquePointer> ProcessCreator::createProcess() const
return std::async(std::launch::async, [&] { return std::async(std::launch::async, [&] {
checkIfProcessPathExists(); checkIfProcessPathExists();
auto process = QProcessUniquePointer(new QProcess); auto process = QProcessUniquePointer(new QProcess);
process->setProcessChannelMode(QProcess::QProcess::ForwardedChannels); process->setProcessChannelMode(kProcessChannelMode);
process->setProcessEnvironment(processEnvironment()); process->setProcessEnvironment(processEnvironment());
process->start(m_processPath, m_arguments); process->start(m_processPath, m_arguments);
process->waitForStarted(5000); process->waitForStarted(5000);

View File

@@ -276,10 +276,8 @@ void AutotoolsProject::updateCppCodeModel()
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt; CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) { if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder; activeQtVersion = CppTools::ProjectPart::Qt4;
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
activeQtVersion = CppTools::ProjectPart::Qt4Latest;
else else
activeQtVersion = CppTools::ProjectPart::Qt5; activeQtVersion = CppTools::ProjectPart::Qt5;
} }

View File

@@ -210,12 +210,20 @@ void ClangAssistProposalItem::apply(TextDocumentManipulatorInterface &manipulato
if (!abandonParen && ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind) { if (!abandonParen && ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind) {
const CodeCompletionChunk resultType = ccr.chunks.first(); const CodeCompletionChunk resultType = ccr.chunks.first();
QTC_ASSERT(resultType.kind == CodeCompletionChunk::ResultType, return;); if (resultType.kind == CodeCompletionChunk::ResultType) {
if (::Utils::Text::matchPreviousWord(manipulator, cursor, resultType.text.toString())) { if (::Utils::Text::matchPreviousWord(manipulator, cursor, resultType.text.toString())) {
extraCharacters += methodDefinitionParameters(ccr.chunks); extraCharacters += methodDefinitionParameters(ccr.chunks);
// To skip the next block. // To skip the next block.
abandonParen = true; 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::<complete here> }
}
} }
if (!abandonParen) { if (!abandonParen) {
if (completionSettings.m_spaceAfterFunctionName) if (completionSettings.m_spaceAfterFunctionName)

View File

@@ -185,7 +185,7 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeComple
{ {
QTC_CHECK(m_completions.isEmpty()); QTC_CHECK(m_completions.isEmpty());
if (m_sentRequestType == FunctionHintCompletion) { if (m_sentRequestType == FunctionHintCompletion && !completions.isEmpty()) {
const CodeCompletion &firstCompletion = completions.front(); const CodeCompletion &firstCompletion = completions.front();
if (firstCompletion.completionKind == CodeCompletion::FunctionOverloadCompletionKind) { if (firstCompletion.completionKind == CodeCompletion::FunctionOverloadCompletionKind) {
setAsyncProposalAvailable(createFunctionHintProposal(completions)); setAsyncProposalAvailable(createFunctionHintProposal(completions));

View File

@@ -469,7 +469,7 @@ private:
// Determine file kind with respect to ambiguous headers. // Determine file kind with respect to ambiguous headers.
CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(m_filePath); CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(m_filePath);
if (fileKind == CppTools::ProjectFile::AmbiguousHeader) { if (fileKind == CppTools::ProjectFile::AmbiguousHeader) {
fileKind = m_projectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion fileKind = m_projectPart.languageVersion <= ProjectExplorer::LanguageVersion::LatestC
? CppTools::ProjectFile::CHeader ? CppTools::ProjectFile::CHeader
: CppTools::ProjectFile::CXXHeader; : CppTools::ProjectFile::CXXHeader;
} }

View File

@@ -100,10 +100,6 @@ static QFuture<CppTools::ToolTipInfo> editorDocumentHandlesToolTipInfo(
return QFuture<CppTools::ToolTipInfo>(); return QFuture<CppTools::ToolTipInfo>();
} }
ClangHoverHandler::ClangHoverHandler()
{
}
ClangHoverHandler::~ClangHoverHandler() ClangHoverHandler::~ClangHoverHandler()
{ {
abort(); abort();

View File

@@ -37,7 +37,6 @@ class ClangHoverHandler : public TextEditor::BaseHoverHandler
Q_DECLARE_TR_FUNCTIONS(ClangHoverHandler) Q_DECLARE_TR_FUNCTIONS(ClangHoverHandler)
public: public:
ClangHoverHandler();
~ClangHoverHandler() override; ~ClangHoverHandler() override;
void identifyMatch(TextEditor::TextEditorWidget *editorWidget, void identifyMatch(TextEditor::TextEditorWidget *editorWidget,

View File

@@ -70,6 +70,7 @@ public:
: CompilerOptionsBuilder(projectPart, : CompilerOptionsBuilder(projectPart,
UseSystemHeader::No, UseSystemHeader::No,
CppTools::SkipBuiltIn::No, CppTools::SkipBuiltIn::No,
CppTools::SkipLanguageDefines::Yes,
QString(CLANG_VERSION), QString(CLANG_VERSION),
QString(CLANG_RESOURCE_DIR)) QString(CLANG_RESOURCE_DIR))
{ {

View File

@@ -1,5 +1,4 @@
import qbs import qbs
import qbs.FileInfo
QtcPlugin { QtcPlugin {
name: "ClangFormat" name: "ClangFormat"
@@ -8,7 +7,6 @@ QtcPlugin {
Depends { name: "TextEditor" } Depends { name: "TextEditor" }
Depends { name: "CppTools" } Depends { name: "CppTools" }
Depends { name: "ProjectExplorer" } Depends { name: "ProjectExplorer" }
Depends { name: "ExtensionSystem" }
Depends { name: "Utils" } Depends { name: "Utils" }
Depends { name: "libclang"; required: false } Depends { name: "libclang"; required: false }

View File

@@ -194,6 +194,7 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart, CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart,
CppTools::UseSystemHeader::No, CppTools::UseSystemHeader::No,
CppTools::SkipBuiltIn::No, CppTools::SkipBuiltIn::No,
CppTools::SkipLanguageDefines::Yes,
QString(CLANG_VERSION), QString(CLANG_VERSION),
QString(CLANG_RESOURCE_DIR)); QString(CLANG_RESOURCE_DIR));
QStringList arguments = extraClangToolsPrependOptions(); QStringList arguments = extraClangToolsPrependOptions();

View File

@@ -8,7 +8,6 @@ QtcPlugin {
Depends { name: "Core" } Depends { name: "Core" }
Depends { name: "TextEditor" } Depends { name: "TextEditor" }
Depends { name: "CppTools" } Depends { name: "CppTools" }
Depends { name: "ExtensionSystem" }
Depends { name: "ProjectExplorer" } Depends { name: "ProjectExplorer" }
Depends { name: "QtcSsh" } Depends { name: "QtcSsh" }
Depends { name: "Utils" } Depends { name: "Utils" }

View File

@@ -286,10 +286,8 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc)
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt; CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) { if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder; activeQtVersion = CppTools::ProjectPart::Qt4;
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
activeQtVersion = CppTools::ProjectPart::Qt4Latest;
else else
activeQtVersion = CppTools::ProjectPart::Qt5; activeQtVersion = CppTools::ProjectPart::Qt5;
} }

View File

@@ -253,7 +253,7 @@ CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FileName &pr
tcInfo.targetTriple = tc->originalTargetTriple(); tcInfo.targetTriple = tc->originalTargetTriple();
tcInfo.sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); tcInfo.sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
tcInfo.headerPathsRunner = tc->createBuiltInHeaderPathsRunner(); tcInfo.headerPathsRunner = tc->createBuiltInHeaderPathsRunner();
tcInfo.predefinedMacrosRunner = tc->createPredefinedMacrosRunner(); tcInfo.macroInspectionRunner = tc->createMacroInspectionRunner();
m_cppCodeModelUpdater->update({this, tcInfo, tcInfo, rpps}); m_cppCodeModelUpdater->update({this, tcInfo, tcInfo, rpps});

View File

@@ -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",
]
}

View File

@@ -269,7 +269,7 @@ void FindToolWindow::acceptAndGetParameters(QString *term, IFindFilter **filter)
{ {
QTC_ASSERT(filter, return); QTC_ASSERT(filter, return);
*filter = nullptr; *filter = nullptr;
Find::updateFindCompletion(m_ui.searchTerm->text()); Find::updateFindCompletion(m_ui.searchTerm->text(), Find::findFlags());
int index = m_ui.filterList->currentIndex(); int index = m_ui.filterList->currentIndex();
QString searchTerm = m_ui.searchTerm->text(); QString searchTerm = m_ui.searchTerm->text();
if (index >= 0) if (index >= 0)

View File

@@ -190,8 +190,6 @@ void Core::Internal::MenuBarFilter::prepareSearch(const QString &entry)
const QStringList entryPath = normalized.split(separators.at(0), QString::SkipEmptyParts); const QStringList entryPath = normalized.split(separators.at(0), QString::SkipEmptyParts);
m_entries.clear(); m_entries.clear();
QVector<const QMenu *> processedMenus; QVector<const QMenu *> processedMenus;
for (QAction* action : menuBarActions()) { for (QAction* action : menuBarActions())
requestMenuUpdate(action);
m_entries << matchesForAction(action, entryPath, QStringList(), processedMenus); m_entries << matchesForAction(action, entryPath, QStringList(), processedMenus);
} }
}

View File

@@ -5,7 +5,6 @@ QtcPlugin {
Depends { name: "Core" } Depends { name: "Core" }
Depends { name: "CppTools" } Depends { name: "CppTools" }
Depends { name: "ExtensionSystem" }
Depends { name: "ProjectExplorer" } Depends { name: "ProjectExplorer" }
Depends { name: "TextEditor" } Depends { name: "TextEditor" }
Depends { name: "Utils" } Depends { name: "Utils" }

View File

@@ -137,7 +137,7 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
if (!m_options.guessArguments) if (!m_options.guessArguments)
return result; return result;
using Version = CppTools::ProjectPart::LanguageVersion; using Version = ProjectExplorer::LanguageVersion;
switch (part.languageVersion) { switch (part.languageVersion) {
case Version::C89: case Version::C89:
result.push_back("--std=c89 --language=c"); result.push_back("--std=c89 --language=c");
@@ -148,6 +148,9 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
case Version::C11: case Version::C11:
result.push_back("--std=c11 --language=c"); result.push_back("--std=c11 --language=c");
break; break;
case Version::C18:
result.push_back("--language=c");
break;
case Version::CXX03: case Version::CXX03:
result.push_back("--std=c++03 --language=c++"); result.push_back("--std=c++03 --language=c++");
break; break;
@@ -159,6 +162,7 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
break; break;
case Version::CXX98: case Version::CXX98:
case Version::CXX17: case Version::CXX17:
case Version::CXX2a:
result.push_back("--language=c++"); result.push_back("--language=c++");
break; break;
} }

View File

@@ -44,13 +44,15 @@ namespace CppTools {
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart, CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
UseSystemHeader useSystemHeader, UseSystemHeader useSystemHeader,
SkipBuiltIn skipBuiltInHeaderPathsAndDefines, SkipBuiltIn skipBuiltInHeaderPathsAndDefines,
SkipLanguageDefines skipLanguageDefines,
QString clangVersion, QString clangVersion,
QString clangResourceDirectory) QString clangResourceDirectory)
: m_projectPart(projectPart) : m_projectPart(projectPart)
, m_useSystemHeader(useSystemHeader)
, m_clangVersion(clangVersion) , m_clangVersion(clangVersion)
, m_clangResourceDirectory(clangResourceDirectory) , m_clangResourceDirectory(clangResourceDirectory)
, m_useSystemHeader(useSystemHeader)
, m_skipBuiltInHeaderPathsAndDefines(skipBuiltInHeaderPathsAndDefines) , m_skipBuiltInHeaderPathsAndDefines(skipBuiltInHeaderPathsAndDefines)
, m_skipLanguageDefines(skipLanguageDefines)
{ {
} }
@@ -59,7 +61,7 @@ QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind,
m_options.clear(); m_options.clear();
if (fileKind == ProjectFile::CHeader || fileKind == ProjectFile::CSource) { if (fileKind == ProjectFile::CHeader || fileKind == ProjectFile::CSource) {
QTC_ASSERT(m_projectPart.languageVersion <= ProjectPart::LatestCVersion, QTC_ASSERT(m_projectPart.languageVersion <= ProjectExplorer::LanguageVersion::LatestC,
return QStringList();); return QStringList(););
} }
@@ -196,7 +198,7 @@ void CompilerOptionsBuilder::addExtraCodeModelFlags()
void CompilerOptionsBuilder::enableExceptions() void CompilerOptionsBuilder::enableExceptions()
{ {
if (m_projectPart.languageVersion > ProjectPart::LatestCVersion) if (m_projectPart.languageVersion > ProjectExplorer::LanguageVersion::LatestC)
add(QLatin1String("-fcxx-exceptions")); add(QLatin1String("-fcxx-exceptions"));
add(QLatin1String("-fexceptions")); add(QLatin1String("-fexceptions"));
} }
@@ -378,7 +380,8 @@ void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros &macros)
void CompilerOptionsBuilder::updateLanguageOption(ProjectFile::Kind fileKind) 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); const QStringList options = createLanguageOptionGcc(fileKind, objcExt);
if (options.isEmpty()) if (options.isEmpty())
return; return;
@@ -394,41 +397,51 @@ void CompilerOptionsBuilder::updateLanguageOption(ProjectFile::Kind fileKind)
void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions) void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions)
{ {
using ProjectExplorer::LanguageExtension;
using ProjectExplorer::LanguageVersion;
QStringList opts; QStringList opts;
const ProjectPart::LanguageExtensions languageExtensions = m_projectPart.languageExtensions; const ProjectExplorer::LanguageExtensions languageExtensions = m_projectPart.languageExtensions;
const bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions; const bool gnuExtensions = languageExtensions & LanguageExtension::Gnu;
switch (m_projectPart.languageVersion) { switch (m_projectPart.languageVersion) {
case ProjectPart::C89: case LanguageVersion::C89:
opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89")); opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89"));
break; break;
case ProjectPart::C99: case LanguageVersion::C99:
opts << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99")); opts << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99"));
break; break;
case ProjectPart::C11: case LanguageVersion::C11:
opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11")); opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
break; 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")); opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
break; break;
case ProjectPart::CXX98: case LanguageVersion::CXX98:
opts << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98")); opts << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98"));
break; break;
case ProjectPart::CXX03: case LanguageVersion::CXX03:
opts << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03")); opts << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03"));
break; break;
case ProjectPart::CXX14: case LanguageVersion::CXX14:
opts << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14")); opts << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14"));
break; break;
case ProjectPart::CXX17: case LanguageVersion::CXX17:
opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17")); opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
break; 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"); opts << QLatin1String("-fms-extensions");
if (checkForBorlandExtensions && (languageExtensions & ProjectPart::BorlandExtensions)) if (checkForBorlandExtensions && (languageExtensions & LanguageExtension::Borland))
opts << QLatin1String("-fborland-extensions"); opts << QLatin1String("-fborland-extensions");
m_options.append(opts); m_options.append(opts);
@@ -588,6 +601,21 @@ QString CompilerOptionsBuilder::includeOption() const
bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro &macro) const bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro &macro) 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 // Ignore for all compiler toolchains since LLVM has it's own implementation for
// __has_include(STR) and __has_include_next(STR) // __has_include(STR) and __has_include_next(STR)
if (macro.key.startsWith("__has_include")) if (macro.key.startsWith("__has_include"))

View File

@@ -31,13 +31,19 @@
namespace CppTools { namespace CppTools {
enum class UseSystemHeader enum class UseSystemHeader : char
{ {
Yes, Yes,
No No
}; };
enum class SkipBuiltIn enum class SkipBuiltIn : char
{
Yes,
No
};
enum class SkipLanguageDefines : char
{ {
Yes, Yes,
No No
@@ -54,6 +60,7 @@ public:
CompilerOptionsBuilder(const ProjectPart &projectPart, CompilerOptionsBuilder(const ProjectPart &projectPart,
UseSystemHeader useSystemHeader = UseSystemHeader::No, UseSystemHeader useSystemHeader = UseSystemHeader::No,
SkipBuiltIn skipBuiltInHeaderPathsAndDefines = SkipBuiltIn::No, SkipBuiltIn skipBuiltInHeaderPathsAndDefines = SkipBuiltIn::No,
SkipLanguageDefines skipLanguageDefines = SkipLanguageDefines::Yes,
QString clangVersion = QString(), QString clangVersion = QString(),
QString clangResourceDirectory = QString()); QString clangResourceDirectory = QString());
@@ -107,12 +114,13 @@ private:
void addWrappedQtHeadersIncludePath(QStringList &list); void addWrappedQtHeadersIncludePath(QStringList &list);
QStringList m_options; QStringList m_options;
UseSystemHeader m_useSystemHeader;
QString m_clangVersion; QString m_clangVersion;
QString m_clangResourceDirectory; QString m_clangResourceDirectory;
UseSystemHeader m_useSystemHeader;
SkipBuiltIn m_skipBuiltInHeaderPathsAndDefines; SkipBuiltIn m_skipBuiltInHeaderPathsAndDefines;
SkipLanguageDefines m_skipLanguageDefines;
}; };
} // namespace CppTools } // namespace CppTools

View File

@@ -103,37 +103,39 @@ QString Utils::toString(ProjectExplorer::HeaderPathType type)
return QString(); 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) { switch (languageVersion) {
CASE_LANGUAGEVERSION(C89); CASE_LANGUAGEVERSION(C89);
CASE_LANGUAGEVERSION(C99); CASE_LANGUAGEVERSION(C99);
CASE_LANGUAGEVERSION(C11); CASE_LANGUAGEVERSION(C11);
CASE_LANGUAGEVERSION(C18);
CASE_LANGUAGEVERSION(CXX98); CASE_LANGUAGEVERSION(CXX98);
CASE_LANGUAGEVERSION(CXX03); CASE_LANGUAGEVERSION(CXX03);
CASE_LANGUAGEVERSION(CXX11); CASE_LANGUAGEVERSION(CXX11);
CASE_LANGUAGEVERSION(CXX14); CASE_LANGUAGEVERSION(CXX14);
CASE_LANGUAGEVERSION(CXX17); CASE_LANGUAGEVERSION(CXX17);
CASE_LANGUAGEVERSION(CXX2a);
// no default to get a compiler warning if anything is added // no default to get a compiler warning if anything is added
} }
#undef CASE_LANGUAGEVERSION #undef CASE_LANGUAGEVERSION
return QString(); return QString();
} }
QString Utils::toString(ProjectPart::LanguageExtensions languageExtension) QString Utils::toString(ProjectExplorer::LanguageExtensions languageExtension)
{ {
QString result; QString result;
#define CASE_LANGUAGE_EXTENSION(ext) if (languageExtension & ProjectPart::ext) \ #define CASE_LANGUAGE_EXTENSION(ext) if (languageExtension & ProjectExplorer::LanguageExtension::ext) \
result += QLatin1String(#ext ", "); result += QLatin1String(#ext ", ");
CASE_LANGUAGE_EXTENSION(NoExtensions); CASE_LANGUAGE_EXTENSION(None);
CASE_LANGUAGE_EXTENSION(GnuExtensions); CASE_LANGUAGE_EXTENSION(Gnu);
CASE_LANGUAGE_EXTENSION(MicrosoftExtensions); CASE_LANGUAGE_EXTENSION(Microsoft);
CASE_LANGUAGE_EXTENSION(BorlandExtensions); CASE_LANGUAGE_EXTENSION(Borland);
CASE_LANGUAGE_EXTENSION(OpenMPExtensions); CASE_LANGUAGE_EXTENSION(OpenMP);
CASE_LANGUAGE_EXTENSION(ObjectiveCExtensions); CASE_LANGUAGE_EXTENSION(ObjectiveC);
#undef CASE_LANGUAGE_EXTENSION #undef CASE_LANGUAGE_EXTENSION
if (result.endsWith(QLatin1String(", "))) if (result.endsWith(QLatin1String(", ")))
result.chop(2); result.chop(2);
@@ -146,8 +148,7 @@ QString Utils::toString(ProjectPart::QtVersion qtVersion)
switch (qtVersion) { switch (qtVersion) {
CASE_QTVERSION(UnknownQt); CASE_QTVERSION(UnknownQt);
CASE_QTVERSION(NoQt); CASE_QTVERSION(NoQt);
CASE_QTVERSION(Qt4_8_6AndOlder); CASE_QTVERSION(Qt4);
CASE_QTVERSION(Qt4Latest);
CASE_QTVERSION(Qt5); CASE_QTVERSION(Qt5);
// no default to get a compiler warning if anything is added // no default to get a compiler warning if anything is added
} }

View File

@@ -47,8 +47,8 @@ struct CPPTOOLS_EXPORT Utils
static QString toString(CPlusPlus::Document::CheckMode checkMode); static QString toString(CPlusPlus::Document::CheckMode checkMode);
static QString toString(CPlusPlus::Document::DiagnosticMessage::Level level); static QString toString(CPlusPlus::Document::DiagnosticMessage::Level level);
static QString toString(ProjectExplorer::HeaderPathType type); static QString toString(ProjectExplorer::HeaderPathType type);
static QString toString(CppTools::ProjectPart::LanguageVersion languageVersion); static QString toString(ProjectExplorer::LanguageVersion languageVersion);
static QString toString(CppTools::ProjectPart::LanguageExtensions languageExtension); static QString toString(ProjectExplorer::LanguageExtensions languageExtension);
static QString toString(CppTools::ProjectPart::QtVersion qtVersion); static QString toString(CppTools::ProjectPart::QtVersion qtVersion);
static QString toString(CppTools::ProjectPart::BuildTargetType buildTargetType); static QString toString(CppTools::ProjectPart::BuildTargetType buildTargetType);
static QString toString(const QVector<CppTools::ProjectFile> &projectFiles); static QString toString(const QVector<CppTools::ProjectFile> &projectFiles);

View File

@@ -1170,8 +1170,9 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart()
// Do not activate ObjectiveCExtensions since this will lead to the // Do not activate ObjectiveCExtensions since this will lead to the
// "objective-c++" language option for a project-less *.cpp file. // "objective-c++" language option for a project-less *.cpp file.
part->languageExtensions = ProjectPart::AllExtensions; part->languageExtensions = ProjectExplorer::LanguageExtension::All;
part->languageExtensions &= ~ProjectPart::ObjectiveCExtensions; part->languageExtensions &= ~ProjectExplorer::LanguageExtensions(
ProjectExplorer::LanguageExtension::ObjectiveC);
part->qtVersion = ProjectPart::Qt5; part->qtVersion = ProjectPart::Qt5;
part->updateLanguageFeatures(); part->updateLanguageFeatures();

View File

@@ -30,125 +30,11 @@
#include <projectexplorer/headerpath.h> #include <projectexplorer/headerpath.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
namespace CppTools { namespace CppTools {
namespace Internal { 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<void> &futureInterface, ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface<void> &futureInterface,
const ProjectUpdateInfo &projectUpdateInfo) const ProjectUpdateInfo &projectUpdateInfo)
: m_futureInterface(futureInterface) : m_futureInterface(futureInterface)
@@ -196,6 +82,8 @@ static ProjectPart::Ptr projectPartFromRawProjectPart(const RawProjectPart &rawP
QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProjectPart &rawProjectPart) QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProjectPart &rawProjectPart)
{ {
using ProjectExplorer::LanguageExtension;
QVector<ProjectPart::Ptr> result; QVector<ProjectPart::Ptr> result;
ProjectFileCategorizer cat(rawProjectPart.displayName, ProjectFileCategorizer cat(rawProjectPart.displayName,
rawProjectPart.files, rawProjectPart.files,
@@ -205,16 +93,13 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart, const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart,
m_projectUpdateInfo.project); m_projectUpdateInfo.project);
ProjectPart::LanguageVersion defaultVersion = ProjectPart::LatestCxxVersion;
if (rawProjectPart.qtVersion == ProjectPart::Qt4_8_6AndOlder)
defaultVersion = ProjectPart::CXX11;
if (cat.hasCxxSources()) { if (cat.hasCxxSources()) {
result << createProjectPart(rawProjectPart, result << createProjectPart(rawProjectPart,
part, part,
cat.cxxSources(), cat.cxxSources(),
cat.partName("C++"), cat.partName("C++"),
defaultVersion, Language::Cxx,
ProjectPart::NoExtensions); LanguageExtension::None);
} }
if (cat.hasObjcxxSources()) { if (cat.hasObjcxxSources()) {
@@ -222,8 +107,8 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
part, part,
cat.objcxxSources(), cat.objcxxSources(),
cat.partName("Obj-C++"), cat.partName("Obj-C++"),
defaultVersion, Language::Cxx,
ProjectPart::ObjectiveCExtensions); LanguageExtension::ObjectiveC);
} }
if (cat.hasCSources()) { if (cat.hasCSources()) {
@@ -231,8 +116,8 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
part, part,
cat.cSources(), cat.cSources(),
cat.partName("C"), cat.partName("C"),
ProjectPart::LatestCVersion, Language::C,
ProjectPart::NoExtensions); LanguageExtension::None);
} }
if (cat.hasObjcSources()) { if (cat.hasObjcSources()) {
@@ -240,28 +125,24 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
part, part,
cat.objcSources(), cat.objcSources(),
cat.partName("Obj-C"), cat.partName("Obj-C"),
ProjectPart::LatestCVersion, Language::C,
ProjectPart::ObjectiveCExtensions); LanguageExtension::ObjectiveC);
} }
} }
return result; return result;
} }
ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &rawProjectPart, ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
const RawProjectPart &rawProjectPart,
const ProjectPart::Ptr &templateProjectPart, const ProjectPart::Ptr &templateProjectPart,
const ProjectFiles &projectFiles, const ProjectFiles &projectFiles,
const QString &partName, const QString &partName,
ProjectPart::LanguageVersion languageVersion, Language language,
ProjectPart::LanguageExtensions languageExtensions) ProjectExplorer::LanguageExtensions languageExtensions)
{ {
ProjectPart::Ptr part(templateProjectPart->copy());
part->displayName = partName;
part->files = projectFiles;
part->languageVersion = languageVersion;
RawProjectPartFlags flags; RawProjectPartFlags flags;
ToolChainInfo tcInfo; ToolChainInfo tcInfo;
if (languageVersion <= ProjectPart::LatestCVersion) { if (language == Language::C) {
flags = rawProjectPart.flagsForC; flags = rawProjectPart.flagsForC;
tcInfo = m_projectUpdateInfo.cToolChainInfo; tcInfo = m_projectUpdateInfo.cToolChainInfo;
} }
@@ -271,8 +152,46 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &r
tcInfo = m_projectUpdateInfo.cxxToolChainInfo; tcInfo = m_projectUpdateInfo.cxxToolChainInfo;
} }
// TODO: If no toolchain is set, show a warning // 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->languageExtensions |= languageExtensions;
part->updateLanguageFeatures(); part->updateLanguageFeatures();

View File

@@ -25,6 +25,7 @@
#pragma once #pragma once
#include "cpptools_utils.h"
#include "projectinfo.h" #include "projectinfo.h"
#include <QFutureInterface> #include <QFutureInterface>
@@ -46,8 +47,8 @@ private:
const ProjectPart::Ptr &templateProjectPart, const ProjectPart::Ptr &templateProjectPart,
const ProjectFiles &projectFiles, const ProjectFiles &projectFiles,
const QString &partName, const QString &partName,
ProjectPart::LanguageVersion languageVersion, Language language,
ProjectPart::LanguageExtensions languageExtensions); ProjectExplorer::LanguageExtensions languageExtensions);
private: private:
const QFutureInterface<void> m_futureInterface; const QFutureInterface<void> m_futureInterface;

View File

@@ -116,7 +116,8 @@ private:
bool isPreferredLanguage(const ProjectPart &projectPart) const 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) return (m_languagePreference == Language::C && isCProjectPart)
|| (m_languagePreference == Language::Cxx && !isCProjectPart); || (m_languagePreference == Language::Cxx && !isCProjectPart);
} }

View File

@@ -39,7 +39,7 @@ RawProjectPartFlags::RawProjectPartFlags(const ProjectExplorer::ToolChain *toolC
if (toolChain) { if (toolChain) {
this->commandLineFlags = commandLineFlags; this->commandLineFlags = commandLineFlags;
warningFlags = toolChain->warningFlags(commandLineFlags); warningFlags = toolChain->warningFlags(commandLineFlags);
compilerFlags = toolChain->compilerFlags(commandLineFlags); languageExtensions = toolChain->languageExtensions(commandLineFlags);
} }
} }

View File

@@ -28,6 +28,7 @@
#include "cpptools_global.h" #include "cpptools_global.h"
#include "projectpart.h" #include "projectpart.h"
#include <projectexplorer/language.h>
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <functional> #include <functional>
@@ -45,8 +46,7 @@ public:
QStringList commandLineFlags; QStringList commandLineFlags;
// The following are deduced from commandLineFlags. // The following are deduced from commandLineFlags.
ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default; ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default;
ProjectExplorer::ToolChain::CompilerFlags compilerFlags ProjectExplorer::LanguageExtensions languageExtensions = ProjectExplorer::LanguageExtension::None;
= ProjectExplorer::ToolChain::CompilerFlag::NoFlags;
}; };
class CPPTOOLS_EXPORT RawProjectPart class CPPTOOLS_EXPORT RawProjectPart

View File

@@ -48,7 +48,7 @@ ToolChainInfo::ToolChainInfo(const ProjectExplorer::ToolChain *toolChain,
// they can be run from a worker thread. // they can be run from a worker thread.
sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner(); headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner();
predefinedMacrosRunner = toolChain->createPredefinedMacrosRunner(); macroInspectionRunner = toolChain->createMacroInspectionRunner();
} }
} }

View File

@@ -58,7 +58,7 @@ public:
QString sysRootPath; // For headerPathsRunner. QString sysRootPath; // For headerPathsRunner.
ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner; ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner;
ProjectExplorer::ToolChain::PredefinedMacrosRunner predefinedMacrosRunner; ProjectExplorer::ToolChain::MacroInspectionRunner macroInspectionRunner;
}; };
class CPPTOOLS_EXPORT ProjectUpdateInfo class CPPTOOLS_EXPORT ProjectUpdateInfo

View File

@@ -35,12 +35,13 @@ namespace CppTools {
void ProjectPart::updateLanguageFeatures() void ProjectPart::updateLanguageFeatures()
{ {
const bool hasCxx = languageVersion >= CXX98; const bool hasCxx = languageVersion >= ProjectExplorer::LanguageVersion::CXX98;
const bool hasQt = hasCxx && qtVersion != NoQt; const bool hasQt = hasCxx && qtVersion != NoQt;
languageFeatures.cxx11Enabled = languageVersion >= CXX11; languageFeatures.cxx11Enabled = languageVersion >= ProjectExplorer::LanguageVersion::CXX11;
languageFeatures.cxxEnabled = hasCxx; languageFeatures.cxxEnabled = hasCxx;
languageFeatures.c99Enabled = languageVersion >= C99; languageFeatures.c99Enabled = languageVersion >= ProjectExplorer::LanguageVersion::C99;
languageFeatures.objCEnabled = languageExtensions.testFlag(ObjectiveCExtensions); languageFeatures.objCEnabled = languageExtensions.testFlag(
ProjectExplorer::LanguageExtension::ObjectiveC);
languageFeatures.qtEnabled = hasQt; languageFeatures.qtEnabled = hasQt;
languageFeatures.qtMocRunEnabled = hasQt; languageFeatures.qtMocRunEnabled = hasQt;
if (!hasQt) { if (!hasQt) {

View File

@@ -30,6 +30,7 @@
#include "cppprojectfile.h" #include "cppprojectfile.h"
#include <projectexplorer/headerpath.h> #include <projectexplorer/headerpath.h>
#include <projectexplorer/language.h>
#include <projectexplorer/projectexplorer_global.h> #include <projectexplorer/projectexplorer_global.h>
#include <projectexplorer/projectmacro.h> #include <projectexplorer/projectmacro.h>
@@ -49,40 +50,10 @@ namespace CppTools {
class CPPTOOLS_EXPORT ProjectPart class CPPTOOLS_EXPORT ProjectPart
{ {
public: 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 { enum QtVersion {
UnknownQt = -1, UnknownQt = -1,
NoQt, NoQt,
Qt4_8_6AndOlder, Qt4,
Qt4Latest,
Qt5 Qt5
}; };
@@ -127,8 +98,8 @@ public:
ProjectExplorer::Macros projectMacros; ProjectExplorer::Macros projectMacros;
LanguageVersion languageVersion = LatestCxxVersion; ProjectExplorer::LanguageVersion languageVersion = ProjectExplorer::LanguageVersion::LatestCxx;
LanguageExtensions languageExtensions = NoExtensions; ProjectExplorer::LanguageExtensions languageExtensions = ProjectExplorer::LanguageExtension::None;
ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default; ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default;
QtVersion qtVersion = UnknownQt; QtVersion qtVersion = UnknownQt;
CPlusPlus::LanguageFeatures languageFeatures; CPlusPlus::LanguageFeatures languageFeatures;

View File

@@ -191,18 +191,20 @@ QWidget *SymbolsFindFilter::createConfigWidget()
void SymbolsFindFilter::writeSettings(QSettings *settings) void SymbolsFindFilter::writeSettings(QSettings *settings)
{ {
settings->beginGroup(QLatin1String(SETTINGS_GROUP)); settings->beginGroup(QLatin1String(SETTINGS_GROUP));
settings->setValue(QLatin1String(SETTINGS_SYMBOLTYPES), (int)m_symbolsToSearch); settings->setValue(QLatin1String(SETTINGS_SYMBOLTYPES), int(m_symbolsToSearch));
settings->setValue(QLatin1String(SETTINGS_SEARCHSCOPE), (int)m_scope); settings->setValue(QLatin1String(SETTINGS_SEARCHSCOPE), int(m_scope));
settings->endGroup(); settings->endGroup();
} }
void SymbolsFindFilter::readSettings(QSettings *settings) void SymbolsFindFilter::readSettings(QSettings *settings)
{ {
settings->beginGroup(QLatin1String(SETTINGS_GROUP)); settings->beginGroup(QLatin1String(SETTINGS_GROUP));
m_symbolsToSearch = (SearchSymbols::SymbolTypes)settings->value(QLatin1String(SETTINGS_SYMBOLTYPES), m_symbolsToSearch = static_cast<SearchSymbols::SymbolTypes>(
(int)SearchSymbols::AllTypes).toInt(); settings->value(QLatin1String(SETTINGS_SYMBOLTYPES),
m_scope = (SearchScope)settings->value(QLatin1String(SETTINGS_SEARCHSCOPE), int(SearchSymbols::AllTypes)).toInt());
(int)SymbolSearcher::SearchProjectsOnly).toInt(); m_scope = static_cast<SearchScope>(
settings->value(QLatin1String(SETTINGS_SEARCHSCOPE),
int(SymbolSearcher::SearchProjectsOnly)).toInt());
settings->endGroup(); settings->endGroup();
emit symbolsToSearchChanged(); emit symbolsToSearchChanged();
} }

View File

@@ -201,8 +201,6 @@ CdbEngine::CdbEngine() :
wh->addTypeFormats("QImage", imageFormats); wh->addTypeFormats("QImage", imageFormats);
wh->addTypeFormats("QImage *", imageFormats); wh->addTypeFormats("QImage *", imageFormats);
connect(action(OperateByInstruction), &QAction::triggered,
this, &CdbEngine::operateByInstructionTriggered);
connect(action(CreateFullBacktrace), &QAction::triggered, connect(action(CreateFullBacktrace), &QAction::triggered,
this, &CdbEngine::createFullBacktrace); this, &CdbEngine::createFullBacktrace);
connect(&m_process, static_cast<void(QProcess::*)(int)>(&QProcess::finished), connect(&m_process, static_cast<void(QProcess::*)(int)>(&QProcess::finished),
@@ -270,6 +268,7 @@ CdbEngine::~CdbEngine() = default;
void CdbEngine::operateByInstructionTriggered(bool operateByInstruction) void CdbEngine::operateByInstructionTriggered(bool operateByInstruction)
{ {
DebuggerEngine::operateByInstructionTriggered(operateByInstruction);
if (m_operateByInstruction == operateByInstruction) if (m_operateByInstruction == operateByInstruction)
return; return;
m_operateByInstruction = operateByInstruction; m_operateByInstruction = operateByInstruction;
@@ -522,7 +521,7 @@ void CdbEngine::handleInitialSessionIdle()
const DebuggerRunParameters &rp = runParameters(); const DebuggerRunParameters &rp = runParameters();
if (!rp.commandsAfterConnect.isEmpty()) if (!rp.commandsAfterConnect.isEmpty())
runCommand({rp.commandsAfterConnect, NoFlags}); runCommand({rp.commandsAfterConnect, NoFlags});
operateByInstructionTriggered(action(OperateByInstruction)->isChecked()); operateByInstructionTriggered(operatesByInstruction());
// QmlCppEngine expects the QML engine to be connected before any breakpoints are hit // QmlCppEngine expects the QML engine to be connected before any breakpoints are hit
// (attemptBreakpointSynchronization() will be directly called then) // (attemptBreakpointSynchronization() will be directly called then)
if (rp.breakOnMain) { if (rp.breakOnMain) {

View File

@@ -113,7 +113,7 @@ private:
void processError(); void processError();
void processFinished(); void processFinished();
void runCommand(const DebuggerCommand &cmd) override; void runCommand(const DebuggerCommand &cmd) override;
void operateByInstructionTriggered(bool); void operateByInstructionTriggered(bool) override;
void createFullBacktrace(); void createFullBacktrace();

View File

@@ -165,18 +165,6 @@ DebuggerSettings::DebuggerSettings()
item->setDefaultValue(false); item->setDefaultValue(false);
insertItem(LogTimeStamps, item); 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("<p>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 = new SavedAction(this);
item->setText(tr("Dereference Pointers Automatically")); item->setText(tr("Dereference Pointers Automatically"));
item->setCheckable(true); item->setCheckable(true);

View File

@@ -82,7 +82,6 @@ enum DebuggerActionCode
AutoQuit, AutoQuit,
LockView, LockView,
LogTimeStamps, LogTimeStamps,
OperateByInstruction,
CloseSourceBuffersOnExit, CloseSourceBuffersOnExit,
CloseMemoryBuffersOnExit, CloseMemoryBuffersOnExit,
SwitchModeOnExit, SwitchModeOnExit,

View File

@@ -393,23 +393,6 @@ public:
m_toolTipManager.resetLocation(); 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: public:
void setInitialActionStates(); void setInitialActionStates();
void setBusyCursor(bool on); void setBusyCursor(bool on);
@@ -542,9 +525,15 @@ void DebuggerEnginePrivate::setupViews()
m_operateByInstructionAction.setVisible(m_engine->hasCapability(DisassemblerCapability)); m_operateByInstructionAction.setVisible(m_engine->hasCapability(DisassemblerCapability));
m_operateByInstructionAction.setIcon(Debugger::Icons::SINGLE_INSTRUCTION_MODE.icon()); m_operateByInstructionAction.setIcon(Debugger::Icons::SINGLE_INSTRUCTION_MODE.icon());
m_operateByInstructionAction.setCheckable(true); m_operateByInstructionAction.setCheckable(true);
m_operateByInstructionAction.setChecked(boolSetting(OperateByInstruction)); m_operateByInstructionAction.setChecked(false);
m_operateByInstructionAction.setToolTip("<p>" + 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, connect(&m_operateByInstructionAction, &QAction::triggered,
this, &DebuggerEnginePrivate::handleOperateByInstructionTriggered); m_engine, &DebuggerEngine::operateByInstructionTriggered);
QTC_ASSERT(m_state == DebuggerNotReady || m_state == DebuggerFinished, qDebug() << m_state); QTC_ASSERT(m_state == DebuggerNotReady || m_state == DebuggerFinished, qDebug() << m_state);
m_progress.setProgressValue(200); m_progress.setProgressValue(200);
@@ -977,7 +966,7 @@ void DebuggerEngine::gotoLocation(const Location &loc)
d->resetLocation(); d->resetLocation();
if (loc.canBeDisassembled() if (loc.canBeDisassembled()
&& ((hasCapability(OperateByInstructionCapability) && d->operatesByInstruction()) && ((hasCapability(OperateByInstructionCapability) && operatesByInstruction())
|| !loc.hasDebugInfo()) ) || !loc.hasDebugInfo()) )
{ {
d->m_disassemblerAgent.setLocation(loc); d->m_disassemblerAgent.setLocation(loc);
@@ -1803,6 +1792,24 @@ bool DebuggerEngine::debuggerActionsEnabled() const
return debuggerActionsEnabledHelper(d->m_state); 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 bool DebuggerEngine::companionPreventsActions() const
{ {
return false; return false;
@@ -2291,7 +2298,7 @@ void DebuggerEngine::handleExecStep()
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE);
} else { } else {
resetLocation(); resetLocation();
if (d->operatesByInstruction()) if (operatesByInstruction())
executeStepI(); executeStepI();
else else
executeStep(); executeStep();
@@ -2305,7 +2312,7 @@ void DebuggerEngine::handleExecNext()
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE);
} else { } else {
resetLocation(); resetLocation();
if (d->operatesByInstruction()) if (operatesByInstruction())
executeNextI(); executeNextI();
else else
executeNext(); executeNext();

View File

@@ -338,6 +338,9 @@ public:
bool debuggerActionsEnabled() const; bool debuggerActionsEnabled() const;
virtual bool companionPreventsActions() const; virtual bool companionPreventsActions() const;
bool operatesByInstruction() const;
virtual void operateByInstructionTriggered(bool on); // FIXME: Remove.
DebuggerState state() const; DebuggerState state() const;
bool isDying() const; bool isDying() const;

View File

@@ -1233,7 +1233,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
m_nextAction.setIcon(Icons::STEP_OVER.icon()); m_nextAction.setIcon(Icons::STEP_OVER.icon());
connect(&m_nextAction, &QAction::triggered, this, [] { connect(&m_nextAction, &QAction::triggered, this, [] {
if (DebuggerEngine *engine = EngineManager::currentEngine()) { if (DebuggerEngine *engine = EngineManager::currentEngine()) {
engine->executeNext(); engine->handleExecNext();
} else { } else {
DebuggerRunTool::setBreakOnMainNextTime(); DebuggerRunTool::setBreakOnMainNextTime();
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, false); 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()); m_stepAction.setIcon(Icons::STEP_OVER.icon());
connect(&m_stepAction, &QAction::triggered, this, [] { connect(&m_stepAction, &QAction::triggered, this, [] {
if (DebuggerEngine *engine = EngineManager::currentEngine()) { if (DebuggerEngine *engine = EngineManager::currentEngine()) {
engine->executeStep(); engine->handleExecStep();
} else { } else {
DebuggerRunTool::setBreakOnMainNextTime(); DebuggerRunTool::setBreakOnMainNextTime();
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, false); ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, false);
@@ -1298,10 +1298,10 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
ActionManager::registerAction(&m_frameUpAction, ActionManager::registerAction(&m_frameUpAction,
"Debugger.FrameUp", cppDebuggercontext); "Debugger.FrameUp", cppDebuggercontext);
cmd = ActionManager::registerAction(action(OperateByInstruction), // cmd = ActionManager::registerAction(action(OperateByInstruction),
Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext); // Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
cmd->setAttribute(Command::CA_Hide); // cmd->setAttribute(Command::CA_Hide);
debugMenu->addAction(cmd); // debugMenu->addAction(cmd);
cmd = ActionManager::registerAction(&m_breakAction, "Debugger.ToggleBreak"); cmd = ActionManager::registerAction(&m_breakAction, "Debugger.ToggleBreak");
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("F8") : tr("F9"))); cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("F8") : tr("F9")));
@@ -2056,7 +2056,6 @@ void DebuggerPluginPrivate::setInitialState()
m_watchAction.setEnabled(false); m_watchAction.setEnabled(false);
m_breakAction.setEnabled(false); m_breakAction.setEnabled(false);
//m_snapshotAction.setEnabled(false); //m_snapshotAction.setEnabled(false);
action(OperateByInstruction)->setChecked(false);
m_exitAction.setEnabled(false); m_exitAction.setEnabled(false);
m_abortAction.setEnabled(false); m_abortAction.setEnabled(false);

View File

@@ -134,7 +134,7 @@ SourcePathMap SourcePathMappingModel::sourcePathMap() const
bool SourcePathMappingModel::isNewPlaceHolder(const Mapping &m) const bool SourcePathMappingModel::isNewPlaceHolder(const Mapping &m) const
{ {
const QLatin1Char lessThan('<'); const QLatin1Char lessThan('<');
const QLatin1Char greaterThan('<'); const QLatin1Char greaterThan('>');
return m.first.isEmpty() || m.first.startsWith(lessThan) return m.first.isEmpty() || m.first.startsWith(lessThan)
|| m.first.endsWith(greaterThan) || m.first.endsWith(greaterThan)
|| m.first == m_newSourcePlaceHolder || m.first == m_newSourcePlaceHolder

View File

@@ -1233,7 +1233,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
//qDebug() << "BP " << rid << data.toString(); //qDebug() << "BP " << rid << data.toString();
// Quickly set the location marker. // Quickly set the location marker.
if (lineNumber && !boolSetting(OperateByInstruction) if (lineNumber && !operatesByInstruction()
&& QFileInfo::exists(fullName) && QFileInfo::exists(fullName)
&& function != "qt_v4TriggeredBreakpointHook" && function != "qt_v4TriggeredBreakpointHook"
&& function != "qt_qmlDebugMessageAvailable" && function != "qt_qmlDebugMessageAvailable"

View File

@@ -891,7 +891,7 @@ void LldbEngine::handleLocationNotification(const GdbMi &reportedLocation)
QString function = reportedLocation["function"].data(); QString function = reportedLocation["function"].data();
int lineNumber = reportedLocation["line"].toInt(); int lineNumber = reportedLocation["line"].toInt();
Location loc = Location(fileName, lineNumber); Location loc = Location(fileName, lineNumber);
if (boolSetting(OperateByInstruction) || !QFileInfo::exists(fileName) || lineNumber <= 0) { if (operatesByInstruction() || !QFileInfo::exists(fileName) || lineNumber <= 0) {
loc = Location(address); loc = Location(address);
loc.setNeedsMarker(true); loc.setNeedsMarker(true);
loc.setUseAssembler(true); loc.setUseAssembler(true);

View File

@@ -69,8 +69,6 @@ StackHandler::StackHandler(DebuggerEngine *engine)
{ {
setObjectName("StackModel"); setObjectName("StackModel");
connect(action(OperateByInstruction), &QAction::triggered,
this, &StackHandler::resetModel);
connect(action(ExpandStack), &QAction::triggered, connect(action(ExpandStack), &QAction::triggered,
this, &StackHandler::reloadFullStack); this, &StackHandler::reloadFullStack);
connect(action(MaximalStackDepth), &QAction::triggered, connect(action(MaximalStackDepth), &QAction::triggered,
@@ -159,7 +157,7 @@ Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
if (index.row() == m_stackFrames.size()) if (index.row() == m_stackFrames.size())
return QAbstractTableModel::flags(index); return QAbstractTableModel::flags(index);
const StackFrame &frame = m_stackFrames.at(index.row()); 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 return isValid && m_contentsValid
? QAbstractTableModel::flags(index) : Qt::ItemFlags(); ? QAbstractTableModel::flags(index) : Qt::ItemFlags();
} }
@@ -258,7 +256,7 @@ void StackHandler::setFramesAndCurrentIndex(const GdbMi &frames, bool isFull)
// a few exceptions: // a few exceptions:
// Always jump to frame #0 when stepping by instruction. // Always jump to frame #0 when stepping by instruction.
if (boolSetting(OperateByInstruction)) if (m_engine->operatesByInstruction())
targetFrame = 0; targetFrame = 0;
// If there is no frame with source, jump to frame #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 int StackHandler::firstUsableIndex() const
{ {
if (!boolSetting(OperateByInstruction)) { if (!m_engine->operatesByInstruction()) {
for (int i = 0, n = m_stackFrames.size(); i != n; ++i) for (int i = 0, n = m_stackFrames.size(); i != n; ++i)
if (m_stackFrames.at(i).isUsable()) if (m_stackFrames.at(i).isUsable())
return i; return i;

View File

@@ -73,6 +73,7 @@ public:
bool isContentsValid() const { return m_contentsValid; } bool isContentsValid() const { return m_contentsValid; }
void scheduleResetLocation(); void scheduleResetLocation();
void resetLocation(); void resetLocation();
void resetModel() { beginResetModel(); endResetModel(); }
signals: signals:
void stackChanged(); void stackChanged();
@@ -87,7 +88,6 @@ private:
bool setData(const QModelIndex &idx, const QVariant &data, int role) override; bool setData(const QModelIndex &idx, const QVariant &data, int role) override;
bool contextMenuEvent(const Utils::ItemViewEvent &event); bool contextMenuEvent(const Utils::ItemViewEvent &event);
void resetModel() { beginResetModel(); endResetModel(); }
void reloadFullStack(); void reloadFullStack();
void copyContentsToClipboard(); void copyContentsToClipboard();
void saveTaskFile(); void saveTaskFile();

View File

@@ -239,6 +239,9 @@ bool GenericProject::saveRawList(const QStringList &rawList, const QString &file
static void insertSorted(QStringList *list, const QString &value) static void insertSorted(QStringList *list, const QString &value)
{ {
int pos = Utils::indexOf(*list, [value](const QString &s) { return s > value; }); int pos = Utils::indexOf(*list, [value](const QString &s) { return s > value; });
if (pos == -1)
list->append(value);
else
list->insert(pos, value); list->insert(pos, value);
} }
@@ -433,10 +436,8 @@ void GenericProject::refreshCppCodeModel()
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt; CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
if (QtSupport::BaseQtVersion *qtVersion = if (QtSupport::BaseQtVersion *qtVersion =
QtSupport::QtKitInformation::qtVersion(activeTarget()->kit())) { QtSupport::QtKitInformation::qtVersion(activeTarget()->kit())) {
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder; activeQtVersion = CppTools::ProjectPart::Qt4;
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
activeQtVersion = CppTools::ProjectPart::Qt4Latest;
else else
activeQtVersion = CppTools::ProjectPart::Qt5; activeQtVersion = CppTools::ProjectPart::Qt5;
} }

View File

@@ -529,7 +529,7 @@ void BranchModel::checkoutBranch(const QModelIndex &idx)
// No StashGuard since this function for now is only used with clean working dir. // 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 // 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) bool BranchModel::branchIsMerged(const QModelIndex &idx)

View File

@@ -254,7 +254,7 @@ void FetchContext::cherryPick()
void FetchContext::checkout() void FetchContext::checkout()
{ {
GitPlugin::client()->stashAndCheckout(m_repository, "FETCH_HEAD"); GitPlugin::client()->checkout(m_repository, "FETCH_HEAD");
} }
void FetchContext::terminate() void FetchContext::terminate()

View File

@@ -1113,21 +1113,22 @@ VcsBaseEditorWidget *GitClient::annotate(
return editor; return editor;
} }
bool GitClient::synchronousCheckout(const QString &workingDirectory, void GitClient::checkout(const QString &workingDirectory, const QString &ref,
const QString &ref, StashMode stashMode)
QString *errorMessage)
{ {
if (stashMode == StashMode::TryStash && !beginStashScope(workingDirectory, "Checkout"))
return;
QStringList arguments = setupCheckoutArguments(workingDirectory, ref); QStringList arguments = setupCheckoutArguments(workingDirectory, ref);
const SynchronousProcessResponse resp = vcsFullySynchronousExec( VcsCommand *command = vcsExec(
workingDirectory, arguments, VcsCommand::ExpectRepoChanges); workingDirectory, arguments, nullptr, true,
VcsOutputWindow::append(resp.stdOut()); VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage);
if (resp.result == SynchronousProcessResponse::Finished) { connect(command, &VcsCommand::finished,
this, [this, workingDirectory, stashMode](bool success) {
if (stashMode == StashMode::TryStash)
endStashScope(workingDirectory);
if (success)
updateSubmodulesIfNeeded(workingDirectory, true); updateSubmodulesIfNeeded(workingDirectory, true);
return true; });
} else {
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
return false;
}
} }
/* method used to setup arguments for checkout, in case user wants to create local branch */ /* 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; 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, static inline QString msgParentRevisionFailed(const QString &workingDirectory,
const QString &revision, const QString &revision,
const QString &why) const QString &why)
@@ -3378,7 +3369,7 @@ GitRemote::GitRemote(const QString &url)
{ {
static const QRegularExpression remotePattern( static const QRegularExpression remotePattern(
"^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)" "^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)"
"(?::(?<port>\\d+))?:?(?<path>/.*)$"); "(?::(?<port>\\d+))?:?(?<path>.*)$");
if (url.isEmpty()) if (url.isEmpty())
return; return;
@@ -3403,12 +3394,13 @@ GitRemote::GitRemote(const QString &url)
if (!match.hasMatch()) if (!match.hasMatch())
return; return;
bool ok = false;
protocol = match.captured("protocol"); protocol = match.captured("protocol");
userName = match.captured("user"); userName = match.captured("user");
host = match.captured("host"); host = match.captured("host");
port = match.captured("port").toUShort(); port = match.captured("port").toUShort(&ok);
path = match.captured("path"); path = match.captured("path");
isValid = true; isValid = ok || match.captured("port").isEmpty();
} }
} // namespace Internal } // namespace Internal

View File

@@ -173,10 +173,9 @@ public:
bool synchronousCheckoutFiles(const QString &workingDirectory, QStringList files = QStringList(), bool synchronousCheckoutFiles(const QString &workingDirectory, QStringList files = QStringList(),
QString revision = QString(), QString *errorMessage = nullptr, QString revision = QString(), QString *errorMessage = nullptr,
bool revertStaging = true); bool revertStaging = true);
// Checkout ref enum class StashMode { NoStash, TryStash };
bool stashAndCheckout(const QString &workingDirectory, const QString &ref); void checkout(const QString &workingDirectory, const QString &ref,
bool synchronousCheckout(const QString &workingDirectory, const QString &ref, StashMode stashMode = StashMode::TryStash);
QString *errorMessage = nullptr);
QStringList setupCheckoutArguments(const QString &workingDirectory, const QString &ref); QStringList setupCheckoutArguments(const QString &workingDirectory, const QString &ref);
void updateSubmodulesIfNeeded(const QString &workingDirectory, bool prompt); void updateSubmodulesIfNeeded(const QString &workingDirectory, bool prompt);

View File

@@ -191,7 +191,7 @@ void GitEditorWidget::setPlainText(const QString &text)
void GitEditorWidget::checkoutChange() void GitEditorWidget::checkoutChange()
{ {
GitPlugin::client()->stashAndCheckout(sourceWorkingDirectory(), m_currentChange); GitPlugin::client()->checkout(sourceWorkingDirectory(), m_currentChange);
} }
void GitEditorWidget::resetChange(const QByteArray &resetType) void GitEditorWidget::resetChange(const QByteArray &resetType)

View File

@@ -82,6 +82,17 @@ public:
m_directory = parameters.additionalParameters.toString(); 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 void processLine(const QString &line, FileSearchResultList *resultList) const
{ {
if (line.isEmpty()) if (line.isEmpty())
@@ -97,7 +108,15 @@ public:
const int textSeparator = line.indexOf(QChar::Null, lineSeparator + 1); const int textSeparator = line.indexOf(QChar::Null, lineSeparator + 1);
single.lineNumber = line.mid(lineSeparator + 1, textSeparator - lineSeparator - 1).toInt(); single.lineNumber = line.mid(lineSeparator + 1, textSeparator - lineSeparator - 1).toInt();
QString text = line.mid(textSeparator + 1); QString text = line.mid(textSeparator + 1);
QVector<QPair<int, int>> matches; QRegularExpression regexp;
QVector<Match> 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 (;;) { for (;;) {
const int matchStart = text.indexOf(boldRed); const int matchStart = text.indexOf(boldRed);
if (matchStart == -1) if (matchStart == -1)
@@ -106,23 +125,19 @@ public:
const int matchEnd = text.indexOf(resetColor, matchTextStart); const int matchEnd = text.indexOf(resetColor, matchTextStart);
QTC_ASSERT(matchEnd != -1, break); QTC_ASSERT(matchEnd != -1, break);
const int matchLength = matchEnd - matchTextStart; const int matchLength = matchEnd - matchTextStart;
matches.append(qMakePair(matchStart, matchLength)); Match match(matchStart, matchLength);
text = text.left(matchStart) + text.mid(matchTextStart, matchLength) const QStringRef matchText = text.midRef(matchTextStart, matchLength);
+ text.mid(matchEnd + resetColor.size()); 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; 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)) { for (auto match : qAsConst(matches)) {
single.matchStart = match.first; single.matchStart = match.matchStart;
single.matchLength = match.second; single.matchLength = match.matchLength;
single.regexpCapturedTexts = match.regexpCapturedTexts;
resultList->append(single); resultList->append(single);
} }
} }

View File

@@ -861,7 +861,7 @@ void GitPlugin::startChangeRelatedAction(const Id &id)
m_gitClient->synchronousRevert(workingDirectory, change); m_gitClient->synchronousRevert(workingDirectory, change);
break; break;
case Checkout: case Checkout:
m_gitClient->stashAndCheckout(workingDirectory, change); m_gitClient->checkout(workingDirectory, change);
break; break;
default: default:
return; return;
@@ -1552,6 +1552,118 @@ void GitPlugin::testLogResolving()
"50a6b54c - Merge branch 'for-junio' of git://bogomips.org/git-svn", "50a6b54c - Merge branch 'for-junio' of git://bogomips.org/git-svn",
"3587b513 - Update draft release notes to 1.8.2"); "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<RemoteTest>("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 #endif
} // namespace Internal } // namespace Internal

View File

@@ -106,6 +106,8 @@ private slots:
void testDiffFileResolving_data(); void testDiffFileResolving_data();
void testDiffFileResolving(); void testDiffFileResolving();
void testLogResolving(); void testLogResolving();
void testGitRemote_data();
void testGitRemote();
#endif #endif
private: private:

View File

@@ -18,6 +18,7 @@ QtcPlugin {
"baseclient.h", "baseclient.h",
"dynamiccapabilities.cpp", "dynamiccapabilities.cpp",
"dynamiccapabilities.h", "dynamiccapabilities.h",
"languageclient.qrc",
"languageclient_global.h", "languageclient_global.h",
"languageclientcodeassist.cpp", "languageclientcodeassist.cpp",
"languageclientcodeassist.h", "languageclientcodeassist.h",

View File

@@ -77,9 +77,9 @@ bool NimToolChain::isValid() const
return fi.isExecutable(); 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 Macros NimToolChain::predefinedMacros(const QStringList &) const
@@ -87,9 +87,9 @@ Macros NimToolChain::predefinedMacros(const QStringList &) const
return Macros(); 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 WarningFlags NimToolChain::warningFlags(const QStringList &) const

View File

@@ -40,9 +40,9 @@ public:
ProjectExplorer::Abi targetAbi() const override; ProjectExplorer::Abi targetAbi() const override;
bool isValid() const override; bool isValid() const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override; MacroInspectionRunner createMacroInspectionRunner() const override;
ProjectExplorer::Macros predefinedMacros(const QStringList &flags) const final; 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; ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final;
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;

View File

@@ -20,6 +20,7 @@ Project {
"classview/classview.qbs", "classview/classview.qbs",
"clearcase/clearcase.qbs", "clearcase/clearcase.qbs",
"cmakeprojectmanager/cmakeprojectmanager.qbs", "cmakeprojectmanager/cmakeprojectmanager.qbs",
"compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs",
"coreplugin/coreplugin.qbs", "coreplugin/coreplugin.qbs",
"coreplugin/images/logo/logo.qbs", "coreplugin/images/logo/logo.qbs",
"cpaster/cpaster.qbs", "cpaster/cpaster.qbs",

View File

@@ -29,6 +29,7 @@
#include "projectexplorer.h" #include "projectexplorer.h"
#include "projectexplorersettings.h" #include "projectexplorersettings.h"
#include "taskhub.h" #include "taskhub.h"
#include "toolchaincache.h"
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
@@ -46,7 +47,7 @@ namespace Internal {
AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Core::Id l, Detection d, AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Core::Id l, Detection d,
const Abi &abi, const Abi &abi,
const QString& vcvarsBat) : ToolChain(typeId, d), const QString& vcvarsBat) : ToolChain(typeId, d),
m_predefinedMacrosMutex(new QMutex), m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>()),
m_lastEnvironment(Utils::Environment::systemEnvironment()), m_lastEnvironment(Utils::Environment::systemEnvironment()),
m_headerPathsMutex(new QMutex), m_headerPathsMutex(new QMutex),
m_abi(abi), m_abi(abi),
@@ -57,20 +58,18 @@ AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Core::Id l, Detect
AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Detection d) : AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Detection d) :
ToolChain(typeId, d), ToolChain(typeId, d),
m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>()),
m_lastEnvironment(Utils::Environment::systemEnvironment()) m_lastEnvironment(Utils::Environment::systemEnvironment())
{ } { }
AbstractMsvcToolChain::~AbstractMsvcToolChain() AbstractMsvcToolChain::~AbstractMsvcToolChain()
{ {
delete m_predefinedMacrosMutex;
delete m_headerPathsMutex; delete m_headerPathsMutex;
} }
AbstractMsvcToolChain::AbstractMsvcToolChain(const AbstractMsvcToolChain &other) AbstractMsvcToolChain::AbstractMsvcToolChain(const AbstractMsvcToolChain &other)
: ToolChain(other), : ToolChain(other),
m_debuggerCommand(other.m_debuggerCommand), m_debuggerCommand(other.m_debuggerCommand),
m_predefinedMacrosMutex(new QMutex),
m_predefinedMacros(other.m_predefinedMacros),
m_lastEnvironment(other.m_lastEnvironment), m_lastEnvironment(other.m_lastEnvironment),
m_resultEnvironment(other.m_resultEnvironment), m_resultEnvironment(other.m_resultEnvironment),
m_headerPathsMutex(new QMutex), m_headerPathsMutex(new QMutex),
@@ -99,65 +98,109 @@ QString AbstractMsvcToolChain::originalTargetTriple() const
: QLatin1String("i686-pc-windows-msvc"); : 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 &macros)
{
int mscVer = -1;
QByteArray msvcLang;
for (const ProjectExplorer::Macro &macro : 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); Utils::Environment env(m_lastEnvironment);
addToEnvironment(env); addToEnvironment(env);
std::shared_ptr<Cache<MacroInspectionReport, 64>> macroCache = m_predefinedMacrosCache;
const Core::Id lang = language();
// This runner must be thread-safe! // This runner must be thread-safe!
return [this, env](const QStringList &cxxflags) { return [this, env, macroCache, lang](const QStringList &cxxflags) {
QMutexLocker locker(m_predefinedMacrosMutex); const QStringList filteredFlags = Utils::filtered(cxxflags, [](const QString &arg) {
if (m_predefinedMacros.isEmpty()) return hasFlagEffectOnMacros(arg);
m_predefinedMacros = msvcPredefinedMacros(cxxflags, env); });
return m_predefinedMacros;
const Utils::optional<MacroInspectionReport> 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 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"))) if (cxxflags.contains(QLatin1String("/openmp")))
flags |= OpenMP; extensions |= LanguageExtension::OpenMP;
// see http://msdn.microsoft.com/en-us/library/0k0w269d%28v=vs.71%29.aspx // see http://msdn.microsoft.com/en-us/library/0k0w269d%28v=vs.71%29.aspx
if (cxxflags.contains(QLatin1String("/Za"))) if (cxxflags.contains(QLatin1String("/Za")))
flags &= ~MicrosoftExtensions; extensions &= ~LanguageExtensions(LanguageExtension::Microsoft);
bool cLanguage = (language() == ProjectExplorer::Constants::C_LANGUAGE_ID); return extensions;
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;
} }
/** /**
@@ -427,6 +470,11 @@ void AbstractMsvcToolChain::inferWarningsForLevel(int warningLevel, WarningFlags
flags |= WarningFlags::UnusedParams; flags |= WarningFlags::UnusedParams;
} }
void Internal::AbstractMsvcToolChain::toolChainUpdated()
{
m_predefinedMacrosCache->invalidate();
}
bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const
{ {
if (!ToolChain::operator ==(other)) if (!ToolChain::operator ==(other))

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include "toolchain.h" #include "toolchain.h"
#include "toolchaincache.h"
#include "abi.h" #include "abi.h"
#include "headerpath.h" #include "headerpath.h"
@@ -53,9 +54,9 @@ public:
QString originalTargetTriple() const override; QString originalTargetTriple() const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override; MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) 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; WarningFlags warningFlags(const QStringList &cflags) const override;
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, HeaderPaths builtInHeaderPaths(const QStringList &cxxflags,
@@ -92,6 +93,7 @@ protected:
}; };
static void inferWarningsForLevel(int warningLevel, WarningFlags &flags); static void inferWarningsForLevel(int warningLevel, WarningFlags &flags);
void toolChainUpdated() override;
virtual Utils::Environment readEnvironmentSetting(const Utils::Environment& env) const = 0; virtual Utils::Environment readEnvironmentSetting(const Utils::Environment& env) const = 0;
// Function must be thread-safe! // Function must be thread-safe!
virtual Macros msvcPredefinedMacros(const QStringList cxxflags, virtual Macros msvcPredefinedMacros(const QStringList cxxflags,
@@ -99,8 +101,9 @@ protected:
Utils::FileName m_debuggerCommand; Utils::FileName m_debuggerCommand;
mutable QMutex *m_predefinedMacrosMutex = nullptr;
mutable Macros m_predefinedMacros; mutable std::shared_ptr<Cache<MacroInspectionReport, 64>> m_predefinedMacrosCache;
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment. mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
mutable QMutex *m_headerPathsMutex = nullptr; mutable QMutex *m_headerPathsMutex = nullptr;

View File

@@ -116,12 +116,13 @@ bool CustomToolChain::isValid() const
return true; return true;
} }
ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner() const ToolChain::MacroInspectionRunner CustomToolChain::createMacroInspectionRunner() const
{ {
const Macros theMacros = m_predefinedMacros; const Macros theMacros = m_predefinedMacros;
const Core::Id lang = language();
// This runner must be thread-safe! // This runner must be thread-safe!
return [theMacros](const QStringList &cxxflags){ return [theMacros, lang](const QStringList &cxxflags){
Macros macros = theMacros; Macros macros = theMacros;
for (const QString &cxxFlag : cxxflags) { for (const QString &cxxFlag : cxxflags) {
if (cxxFlag.startsWith(QLatin1String("-D"))) if (cxxFlag.startsWith(QLatin1String("-D")))
@@ -130,21 +131,18 @@ ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner(
macros.append({cxxFlag.mid(2).trimmed().toUtf8(), MacroType::Undefine}); 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 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) return LanguageExtension::None;
if (cxxflags.contains(cxx11Flag))
return StandardCxx11;
return NoFlags;
} }
WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const

View File

@@ -71,9 +71,9 @@ public:
bool isValid() const override; bool isValid() const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override; MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) 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; WarningFlags warningFlags(const QStringList &cxxflags) const override;
const Macros &rawPredefinedMacros() const; const Macros &rawPredefinedMacros() const;
void setPredefinedMacros(const Macros &macros); void setPredefinedMacros(const Macros &macros);

View File

@@ -254,7 +254,7 @@ GccToolChain::GccToolChain(Detection d) :
GccToolChain::GccToolChain(Core::Id typeId, Detection d) : GccToolChain::GccToolChain(Core::Id typeId, Detection d) :
ToolChain(typeId, d), ToolChain(typeId, d),
m_predefinedMacrosCache(std::make_shared<Cache<QVector<Macro>, 64>>()), m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>()),
m_headerPathsCache(std::make_shared<Cache<HeaderPaths>>()) m_headerPathsCache(std::make_shared<Cache<HeaderPaths>>())
{ } { }
@@ -302,9 +302,9 @@ QString GccToolChain::defaultDisplayName() const
compilerCommand().parentDir().toUserOutput()); compilerCommand().parentDir().toUserOutput());
} }
ToolChain::CompilerFlags GccToolChain::defaultCompilerFlags() const LanguageExtensions GccToolChain::defaultLanguageExtensions() const
{ {
return CompilerFlags(GnuExtensions); return LanguageExtension::Gnu;
} }
QString GccToolChain::typeDisplayName() const QString GccToolChain::typeDisplayName() const
@@ -385,9 +385,7 @@ static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath,
return path.isEmpty() ? compilerPath : path; return path.isEmpty() ? compilerPath : path;
} }
Q_GLOBAL_STATIC_WITH_ARGS(const QVector<QByteArray>, unwantedMacros, ({"__cplusplus"})) ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() const
ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() const
{ {
// Using a clean environment breaks ccache/distcc/etc. // Using a clean environment breaks ccache/distcc/etc.
Environment env = Environment::systemEnvironment(); Environment env = Environment::systemEnvironment();
@@ -396,7 +394,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
const QStringList platformCodeGenFlags = m_platformCodeGenFlags; const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter; OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
QTC_CHECK(reinterpretOptions); QTC_CHECK(reinterpretOptions);
std::shared_ptr<Cache<QVector<Macro>, 64>> macroCache = m_predefinedMacrosCache; std::shared_ptr<Cache<MacroInspectionReport, 64>> macroCache = m_predefinedMacrosCache;
Core::Id lang = language(); Core::Id lang = language();
// This runner must be thread-safe! // This runner must be thread-safe!
@@ -436,28 +434,27 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
} }
arguments = reinterpretOptions(arguments); arguments = reinterpretOptions(arguments);
const Utils::optional<QVector<Macro>> cachedMacros = macroCache->check(arguments); const Utils::optional<MacroInspectionReport> cachedMacros = macroCache->check(arguments);
if (cachedMacros) if (cachedMacros)
return cachedMacros.value(); return cachedMacros.value();
const QVector<Macro> macros const Macros macros = gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
= gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
arguments, arguments,
env.toStringList()); env.toStringList());
const QVector<Macro> filteredMacros = Utils::filtered(macros, [](const Macro &m) {
return !unwantedMacros->contains(m.key);
});
macroCache->insert(arguments, filteredMacros);
qCDebug(gccLog) << "Reporting macros to code model:"; const auto report = MacroInspectionReport{macros, languageVersion(lang, macros)};
for (const Macro &m : filteredMacros) { macroCache->insert(arguments, report);
qCDebug(gccLog) << "MacroInspectionReport for code model:";
qCDebug(gccLog) << "Language version:" << static_cast<int>(report.languageVersion);
for (const Macro &m : macros) {
qCDebug(gccLog) << compilerCommand.toUserOutput() qCDebug(gccLog) << compilerCommand.toUserOutput()
<< (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [") << (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
<< arguments.join(", ") << "]" << arguments.join(", ") << "]"
<< QString::fromUtf8(m.toByteArray()); << 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 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 * @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? const QStringList allCxxflags = m_platformCodeGenFlags + cxxflags; // add only cxxflags is empty?
foreach (const QString &flag, allCxxflags) { foreach (const QString &flag, allCxxflags) {
if (flag.startsWith("-std=")) { if (flag.startsWith("-std=")) {
const QByteArray std = flag.mid(5).toLatin1(); const QByteArray std = flag.mid(5).toLatin1();
if (std == "c++98" || std == "c++03") { if (std.startsWith("gnu"))
flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | StandardCxx17 | GnuExtensions); extensions |= LanguageExtension::Gnu;
flags |= StandardCxx98; else
} else if (std == "gnu++98" || std == "gnu++03") { extensions &= ~LanguageExtensions(LanguageExtension::Gnu);
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);
}
} else if (flag == "-fopenmp") { } else if (flag == "-fopenmp") {
flags |= OpenMP; extensions |= LanguageExtension::Gnu;
} else if (flag == "-fms-extensions") { } else if (flag == "-fms-extensions") {
flags |= MicrosoftExtensions; extensions |= LanguageExtension::Microsoft;
} else if (flag == "-ansi") {
flags &= ~CompilerFlags(StandardCxx11 | GnuExtensions
| StandardC99 | StandardC11);
} }
} }
return flags; return extensions;
} }
WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const
@@ -1069,7 +1025,10 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const FileName &comp
return result; return result;
tc->setLanguage(language); 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->setCompilerCommand(compilerPath);
tc->setSupportedAbis(detectedAbis.supportedAbis); tc->setSupportedAbis(detectedAbis.supportedAbis);
tc->setTargetAbi(abi); tc->setTargetAbi(abi);
@@ -1134,7 +1093,11 @@ void GccToolChainConfigWidget::applyImpl()
tc->setDisplayName(displayName); // reset display name tc->setDisplayName(displayName); // reset display name
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text())); tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));
tc->setPlatformLinkerFlags(splitString(m_platformLinkerFlagsLineEdit->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() 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". * "-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")) if (cxxflags.contains("-fborland-extensions"))
flags |= BorlandExtensions; extensions |= LanguageExtension::Borland;
return flags; return extensions;
} }
WarningFlags ClangToolChain::warningFlags(const QStringList &cflags) const WarningFlags ClangToolChain::warningFlags(const QStringList &cflags) const
@@ -1317,9 +1280,9 @@ void ClangToolChain::addToEnvironment(Environment &env) const
env.unset("PWD"); env.unset("PWD");
} }
ToolChain::CompilerFlags ClangToolChain::defaultCompilerFlags() const LanguageExtensions ClangToolChain::defaultLanguageExtensions() const
{ {
return CompilerFlags(GnuExtensions | StandardCxx11); return LanguageExtension::Gnu;
} }
IOutputParser *ClangToolChain::outputParser() const IOutputParser *ClangToolChain::outputParser() const
@@ -1365,12 +1328,12 @@ QList<ToolChain *> ClangToolChainFactory::autoDetect(const QList<ToolChain *> &a
const FileName compilerPath = FileName::fromString(Core::ICore::clangExecutable(CLANG_BINDIR)); const FileName compilerPath = FileName::fromString(Core::ICore::clangExecutable(CLANG_BINDIR));
if (!compilerPath.isEmpty()) { if (!compilerPath.isEmpty()) {
tcs.append(autoDetectToolchains(compilerPath.parentDir().appendPath( const FileName clang = compilerPath.parentDir().appendPath(
HostOsInfo::withExecutableSuffix("clang++")), HostOsInfo::withExecutableSuffix("clang"));
tcs.append(autoDetectToolchains(clang,
hostAbi, Constants::CXX_LANGUAGE_ID, hostAbi, Constants::CXX_LANGUAGE_ID,
Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown)); Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown));
tcs.append(autoDetectToolchains(compilerPath.parentDir().appendPath( tcs.append(autoDetectToolchains(clang,
HostOsInfo::withExecutableSuffix("clang")),
hostAbi, Constants::C_LANGUAGE_ID, hostAbi, Constants::C_LANGUAGE_ID,
Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown)); 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". * "-fopenmp" and "-fms-dialect[=ver]" instead of "-fms-extensions".
* @see UNIX manual for "icc" * @see UNIX manual for "icc"
*/ */
ToolChain::CompilerFlags LinuxIccToolChain::compilerFlags(const QStringList &cxxflags) const LanguageExtensions LinuxIccToolChain::languageExtensions(const QStringList &cxxflags) const
{ {
QStringList copy = cxxflags; QStringList copy = cxxflags;
copy.removeAll("-fopenmp"); copy.removeAll("-fopenmp");
copy.removeAll("-fms-extensions"); copy.removeAll("-fms-extensions");
CompilerFlags flags = GccToolChain::compilerFlags(cxxflags); LanguageExtensions extensions = GccToolChain::languageExtensions(cxxflags);
if (cxxflags.contains("-openmp")) if (cxxflags.contains("-openmp"))
flags |= OpenMP; extensions |= LanguageExtension::OpenMP;
if (cxxflags.contains("-fms-dialect") if (cxxflags.contains("-fms-dialect")
|| cxxflags.contains("-fms-dialect=8") || cxxflags.contains("-fms-dialect=8")
|| cxxflags.contains("-fms-dialect=9") || cxxflags.contains("-fms-dialect=9")
|| cxxflags.contains("-fms-dialect=10")) || cxxflags.contains("-fms-dialect=10"))
flags |= MicrosoftExtensions; extensions |= LanguageExtension::Microsoft;
return flags; return extensions;
} }
IOutputParser *LinuxIccToolChain::outputParser() const IOutputParser *LinuxIccToolChain::outputParser() const

View File

@@ -28,14 +28,11 @@
#include "projectexplorer_export.h" #include "projectexplorer_export.h"
#include "toolchain.h" #include "toolchain.h"
#include "toolchaincache.h"
#include "abi.h" #include "abi.h"
#include "headerpath.h" #include "headerpath.h"
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/optional.h>
#include <QMutex>
#include <QStringList>
#include <functional> #include <functional>
#include <memory> #include <memory>
@@ -54,79 +51,6 @@ class LinuxIccToolChainFactory;
// GccToolChain // GccToolChain
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
template<class T, int Size = 16>
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<T> check(const QStringList &compilerArguments)
{
QMutexLocker locker(&m_mutex);
return checkImpl(compilerArguments);
}
void invalidate()
{
QMutexLocker locker(&m_mutex);
m_cache.clear();
}
private:
Utils::optional<T> 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<QStringList, T>;
QMutex m_mutex;
QVector<CacheItem> m_cache;
};
class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain
{ {
public: public:
@@ -140,10 +64,10 @@ public:
bool isValid() const override; 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; WarningFlags warningFlags(const QStringList &cflags) const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override; MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) const override; Macros predefinedMacros(const QStringList &cxxflags) const override;
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
@@ -200,7 +124,7 @@ protected:
Macros macroCache(const QStringList &allCxxflags) const; Macros macroCache(const QStringList &allCxxflags) const;
virtual QString defaultDisplayName() const; virtual QString defaultDisplayName() const;
virtual CompilerFlags defaultCompilerFlags() const; virtual LanguageExtensions defaultLanguageExtensions() const;
virtual DetectedAbisResult detectSupportedAbis() const; virtual DetectedAbisResult detectSupportedAbis() const;
virtual QString detectVersion() const; virtual QString detectVersion() const;
@@ -253,7 +177,7 @@ private:
mutable HeaderPaths m_headerPaths; mutable HeaderPaths m_headerPaths;
mutable QString m_version; mutable QString m_version;
mutable std::shared_ptr<Cache<QVector<Macro>, 64>> m_predefinedMacrosCache; mutable std::shared_ptr<Cache<MacroInspectionReport, 64>> m_predefinedMacrosCache;
mutable std::shared_ptr<Cache<HeaderPaths>> m_headerPathsCache; mutable std::shared_ptr<Cache<HeaderPaths>> m_headerPathsCache;
mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {}; mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {};
@@ -273,7 +197,7 @@ public:
QString typeDisplayName() const override; QString typeDisplayName() const override;
QString makeCommand(const Utils::Environment &environment) 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; WarningFlags warningFlags(const QStringList &cflags) const override;
IOutputParser *outputParser() const override; IOutputParser *outputParser() const override;
@@ -284,7 +208,7 @@ public:
void addToEnvironment(Utils::Environment &env) const override; void addToEnvironment(Utils::Environment &env) const override;
protected: protected:
CompilerFlags defaultCompilerFlags() const override; LanguageExtensions defaultLanguageExtensions() const override;
private: private:
friend class Internal::ClangToolChainFactory; friend class Internal::ClangToolChainFactory;
@@ -321,7 +245,7 @@ class PROJECTEXPLORER_EXPORT LinuxIccToolChain : public GccToolChain
public: public:
QString typeDisplayName() const override; QString typeDisplayName() const override;
CompilerFlags compilerFlags(const QStringList &cxxflags) const override; LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
IOutputParser *outputParser() const override; IOutputParser *outputParser() const override;
ToolChain *clone() const override; ToolChain *clone() const override;

View File

@@ -314,6 +314,24 @@ JsonWizardFactory *JsonWizardFactory::createWizardFactory(const QVariantMap &dat
return factory; 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() Utils::FileNameList &JsonWizardFactory::searchPaths()
{ {
static Utils::FileNameList m_searchPaths = Utils::FileNameList() static Utils::FileNameList m_searchPaths = Utils::FileNameList()
@@ -321,6 +339,9 @@ Utils::FileNameList &JsonWizardFactory::searchPaths()
QLatin1String(WIZARD_PATH)) QLatin1String(WIZARD_PATH))
<< Utils::FileName::fromString(Core::ICore::resourcePath() + QLatin1Char('/') + << Utils::FileName::fromString(Core::ICore::resourcePath() + QLatin1Char('/') +
QLatin1String(WIZARD_PATH)); QLatin1String(WIZARD_PATH));
for (const QString &environmentTemplateDirName : environmentTemplatesPaths())
m_searchPaths << Utils::FileName::fromString(environmentTemplateDirName);
return m_searchPaths; return m_searchPaths;
} }

View File

@@ -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 <QFlags>
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

View File

@@ -334,6 +334,7 @@ static QByteArray msvcCompilationFile()
"__CLR_VER", "__CLR_VER",
"_CMMN_INTRIN_FUNC", "_CMMN_INTRIN_FUNC",
"_CONTROL_FLOW_GUARD", "_CONTROL_FLOW_GUARD",
"__cplusplus",
"__cplusplus_cli", "__cplusplus_cli",
"__cplusplus_winrt", "__cplusplus_winrt",
"_CPPLIB_VER", "_CPPLIB_VER",
@@ -469,8 +470,6 @@ Macros MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags,
predefinedMacros.append(Macro::fromKeyValue(define)); predefinedMacros.append(Macro::fromKeyValue(define));
} else if (arg.startsWith(QLatin1String("/U"))) { } else if (arg.startsWith(QLatin1String("/U"))) {
predefinedMacros.append({arg.mid(2).toLocal8Bit(), ProjectExplorer::MacroType::Undefine}); 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 { } else {
toProcess.append(arg); toProcess.append(arg);
} }

View File

@@ -210,8 +210,6 @@ const char OPENFILE[] = "ProjectExplorer.OpenFile";
const char SEARCHONFILESYSTEM[] = "ProjectExplorer.SearchOnFileSystem"; const char SEARCHONFILESYSTEM[] = "ProjectExplorer.SearchOnFileSystem";
const char SHOWINGRAPHICALSHELL[] = "ProjectExplorer.ShowInGraphicalShell"; const char SHOWINGRAPHICALSHELL[] = "ProjectExplorer.ShowInGraphicalShell";
const char OPENTERMINALHERE[] = "ProjectExplorer.OpenTerminalHere"; const char OPENTERMINALHERE[] = "ProjectExplorer.OpenTerminalHere";
const char OPENTERMINALHEREBUILD[]= "ProjectExplorer.OpenTerminalHereBuildEnv";
const char OPENTERMINALHERERUN[] = "ProjectExplorer.OpenTerminalHereRunEnv";
const char DUPLICATEFILE[] = "ProjectExplorer.DuplicateFile"; const char DUPLICATEFILE[] = "ProjectExplorer.DuplicateFile";
const char DELETEFILE[] = "ProjectExplorer.DeleteFile"; const char DELETEFILE[] = "ProjectExplorer.DeleteFile";
const char DIFFFILE[] = "ProjectExplorer.DiffFile"; 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_openTerminalHereBuildEnv = new QAction(tr("Build Environment"), this);
dd->m_openTerminalHereRunEnv = new QAction(tr("Run Environment"), this); dd->m_openTerminalHereRunEnv = new QAction(tr("Run Environment"), this);
#if !defined(Q_OS_UNIX) || QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) #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); projecTreeContext);
dd->m_openTerminalMenu->addAction(dd->m_openTerminalHereBuildEnv); dd->m_openTerminalMenu->addAction(dd->m_openTerminalHereBuildEnv);
cmd = ActionManager::registerAction(dd->m_openTerminalHereRunEnv, Constants::OPENTERMINALHERERUN, cmd = ActionManager::registerAction(dd->m_openTerminalHereRunEnv,
"ProjectExplorer.OpenTerminalHereRunEnv",
projecTreeContext); projecTreeContext);
dd->m_openTerminalMenu->addAction(dd->m_openTerminalHereRunEnv); dd->m_openTerminalMenu->addAction(dd->m_openTerminalHereRunEnv);
#endif #endif

View File

@@ -89,6 +89,7 @@ HEADERS += projectexplorer.h \
projectmodels.h \ projectmodels.h \
currentprojectfind.h \ currentprojectfind.h \
toolchain.h \ toolchain.h \
toolchaincache.h \
toolchainconfigwidget.h \ toolchainconfigwidget.h \
toolchainmanager.h \ toolchainmanager.h \
toolchainoptionspage.h \ toolchainoptionspage.h \

View File

@@ -145,6 +145,7 @@ Project {
"taskmodel.cpp", "taskmodel.h", "taskmodel.cpp", "taskmodel.h",
"taskwindow.cpp", "taskwindow.h", "taskwindow.cpp", "taskwindow.h",
"toolchain.cpp", "toolchain.h", "toolchain.cpp", "toolchain.h",
"toolchaincache.h",
"toolchainconfigwidget.cpp", "toolchainconfigwidget.h", "toolchainconfigwidget.cpp", "toolchainconfigwidget.h",
"toolchainmanager.cpp", "toolchainmanager.h", "toolchainmanager.cpp", "toolchainmanager.h",
"toolchainoptionspage.cpp", "toolchainoptionspage.h", "toolchainoptionspage.cpp", "toolchainoptionspage.h",

View File

@@ -286,6 +286,65 @@ bool ToolChain::fromMap(const QVariantMap &data)
return true; 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 &macros)
{
if (language == Constants::CXX_LANGUAGE_ID) {
for (const ProjectExplorer::Macro &macro : 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 &macro : 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. Used by the tool chain kit information to validate the kit.
*/ */

View File

@@ -29,6 +29,7 @@
#include "projectexplorer_global.h" #include "projectexplorer_global.h"
#include "headerpath.h" #include "headerpath.h"
#include "language.h"
#include "projectmacro.h" #include "projectmacro.h"
#include <coreplugin/id.h> #include <coreplugin/id.h>
@@ -107,28 +108,19 @@ public:
virtual bool isValid() const = 0; virtual bool isValid() const = 0;
enum CompilerFlag { virtual LanguageExtensions languageExtensions(const QStringList &cxxflags) const = 0;
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 WarningFlags warningFlags(const QStringList &cflags) const = 0; virtual WarningFlags warningFlags(const QStringList &cflags) const = 0;
// A PredefinedMacrosRunner is created in the ui thread and runs in another thread. class MacroInspectionReport
using PredefinedMacrosRunner = std::function<Macros(const QStringList &cxxflags)>; {
virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const = 0; public:
Macros macros;
LanguageVersion languageVersion;
};
// A MacroInspectionRunner is created in the ui thread and runs in another thread.
using MacroInspectionRunner = std::function<MacroInspectionReport(const QStringList &cxxflags)>;
virtual MacroInspectionRunner createMacroInspectionRunner() const = 0;
virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0; virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0;
// A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread. // A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread.
@@ -157,6 +149,8 @@ public:
virtual QList<Task> validateKit(const Kit *k) const; virtual QList<Task> validateKit(const Kit *k) const;
void setLanguage(Core::Id language); void setLanguage(Core::Id language);
static LanguageVersion cxxLanguageVersion(const QByteArray &cplusplusMacroValue);
static LanguageVersion languageVersion(const Core::Id &language, const Macros &macros);
protected: protected:
explicit ToolChain(Core::Id typeId, Detection d); explicit ToolChain(Core::Id typeId, Detection d);

View File

@@ -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 <QMutex>
#include <QMutexLocker>
#include <QStringList>
#include <QVector>
#include <utils/optional.h>
namespace ProjectExplorer {
template<class T, int Size = 16>
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<T> check(const QStringList &compilerArguments)
{
QMutexLocker locker(&m_mutex);
return checkImpl(compilerArguments);
}
void invalidate()
{
QMutexLocker locker(&m_mutex);
m_cache.clear();
}
private:
Utils::optional<T> 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<QStringList, T>;
QMutex m_mutex;
QVector<CacheItem> m_cache;
};
} // namespace ProjectExplorer

View File

@@ -308,9 +308,9 @@ public:
QString typeDisplayName() const override { return QString("Test Tool Chain"); } QString typeDisplayName() const override { return QString("Test Tool Chain"); }
Abi targetAbi() const override { return Abi::hostAbi(); } Abi targetAbi() const override { return Abi::hostAbi(); }
bool isValid() const override { return m_valid; } 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(); } 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; } WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags); return WarningFlags::NoWarnings; }
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override { return BuiltInHeaderPathsRunner(); } BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override { return BuiltInHeaderPathsRunner(); }
HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, const FileName &sysRoot) const override HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, const FileName &sysRoot) const override

View File

@@ -152,47 +152,6 @@ Q_DECLARE_TYPEINFO(HandlerNode, Q_MOVABLE_TYPE);
QT_END_NAMESPACE 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<QString, QVariant> 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<QString, HandlerNode>::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: // Helpers:
// -------------------------------------------------------------------- // --------------------------------------------------------------------

View File

@@ -915,10 +915,8 @@ void QbsProject::updateCppCodeModel()
CppTools::ProjectPart::QtVersion qtVersionFromKit = CppTools::ProjectPart::NoQt; CppTools::ProjectPart::QtVersion qtVersionFromKit = CppTools::ProjectPart::NoQt;
if (qtVersion) { if (qtVersion) {
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
qtVersionFromKit = CppTools::ProjectPart::Qt4_8_6AndOlder; qtVersionFromKit = CppTools::ProjectPart::Qt4;
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
qtVersionFromKit = CppTools::ProjectPart::Qt4Latest;
else else
qtVersionFromKit = CppTools::ProjectPart::Qt5; qtVersionFromKit = CppTools::ProjectPart::Qt5;
} }

View File

@@ -277,10 +277,8 @@ void QmakeProject::updateCppCodeModel()
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k); QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt; ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt;
if (qtVersion) { if (qtVersion) {
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6)) if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
qtVersionForPart = ProjectPart::Qt4_8_6AndOlder; qtVersionForPart = ProjectPart::Qt4;
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
qtVersionForPart = ProjectPart::Qt4Latest;
else else
qtVersionForPart = ProjectPart::Qt5; qtVersionForPart = ProjectPart::Qt5;
} }

View File

@@ -38,7 +38,7 @@ using namespace ProjectExplorer;
namespace QtSupport { namespace QtSupport {
static QLoggingCategory log("qtc.qsxmlcgenerator"); static QLoggingCategory log("qtc.qscxmlcgenerator");
static const char TaskCategory[] = "Task.Category.ExtraCompiler.QScxmlc"; static const char TaskCategory[] = "Task.Category.ExtraCompiler.QScxmlc";
QScxmlcGenerator::QScxmlcGenerator(const Project *project, QScxmlcGenerator::QScxmlcGenerator(const Project *project,

View File

@@ -119,7 +119,15 @@ void runSilverSeacher(FutureInterfaceType &fi, FileFindParameters parameters)
process.start("ag", arguments); process.start("ag", arguments);
if (process.waitForFinished()) { if (process.waitForFinished()) {
typedef QList<FileSearchResult> FileSearchResultList; typedef QList<FileSearchResult> 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(); FileSearchResultList items = parser.parse();
if (!items.isEmpty()) if (!items.isEmpty())
fi.reportResult(items); fi.reportResult(items);
@@ -134,7 +142,6 @@ namespace SilverSearcher {
FindInFilesSilverSearcher::FindInFilesSilverSearcher(QObject *parent) FindInFilesSilverSearcher::FindInFilesSilverSearcher(QObject *parent)
: SearchEngine(parent), : SearchEngine(parent),
m_widget(0),
m_path("ag"), m_path("ag"),
m_toolName("SilverSearcher") m_toolName("SilverSearcher")
{ {
@@ -190,7 +197,7 @@ QFuture<FileSearchResultList> FindInFilesSilverSearcher::executeSearch(
IEditor *FindInFilesSilverSearcher::openEditor(const SearchResultItem & /*item*/, IEditor *FindInFilesSilverSearcher::openEditor(const SearchResultItem & /*item*/,
const FileFindParameters & /*parameters*/) const FileFindParameters & /*parameters*/)
{ {
return 0; return nullptr;
} }
void FindInFilesSilverSearcher::readSettings(QSettings * /*settings*/) void FindInFilesSilverSearcher::readSettings(QSettings * /*settings*/)

View File

@@ -30,10 +30,12 @@
namespace SilverSearcher { namespace SilverSearcher {
SilverSearcherOutputParser::SilverSearcherOutputParser( SilverSearcherOutputParser::SilverSearcherOutputParser(
const QByteArray &output) const QByteArray &output, const QRegularExpression &regexp)
: output(output) : output(output)
, regexp(regexp)
, outputSize(output.size()) , outputSize(output.size())
{ {
hasRegexp = !regexp.pattern().isEmpty();
} }
QList<Utils::FileSearchResult> SilverSearcherOutputParser::parse() QList<Utils::FileSearchResult> SilverSearcherOutputParser::parse()
@@ -102,6 +104,13 @@ bool SilverSearcherOutputParser::parseMatchLength()
int SilverSearcherOutputParser::parseMatches() int SilverSearcherOutputParser::parseMatches()
{ {
int matches = 1; 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] != ':') { while (index < outputSize && output[index] != ':') {
if (output[index] == ',') { if (output[index] == ',') {
++matches; ++matches;
@@ -109,6 +118,10 @@ int SilverSearcherOutputParser::parseMatches()
} }
parseMatchIndex(); parseMatchIndex();
parseMatchLength(); parseMatchLength();
if (hasRegexp) {
const QString part = QString::fromUtf8(text.mid(item.matchStart, item.matchLength));
item.regexpCapturedTexts = regexp.match(part).capturedTexts();
}
items << item; items << item;
} }

View File

@@ -28,15 +28,18 @@
#include <coreplugin/find/searchresultwindow.h> #include <coreplugin/find/searchresultwindow.h>
#include <utils/filesearch.h> #include <utils/filesearch.h>
#include <QList>
#include <QByteArray> #include <QByteArray>
#include <QList>
#include <QRegularExpression>
namespace SilverSearcher { namespace SilverSearcher {
class SilverSearcherOutputParser class SilverSearcherOutputParser
{ {
public: public:
SilverSearcherOutputParser(const QByteArray &output); SilverSearcherOutputParser(
const QByteArray &output,
const QRegularExpression &regexp = QRegularExpression());
QList<Utils::FileSearchResult> parse(); QList<Utils::FileSearchResult> parse();
private: private:
@@ -48,6 +51,8 @@ private:
bool parseText(); bool parseText();
QByteArray output; QByteArray output;
QRegularExpression regexp;
bool hasRegexp = false;
int outputSize = 0; int outputSize = 0;
int index = 0; int index = 0;
Utils::FileSearchResult item; Utils::FileSearchResult item;

View File

@@ -142,7 +142,8 @@ bool DisplaySettings::equals(const DisplaySettings &ds) const
QLabel *DisplaySettings::createAnnotationSettingsLink() QLabel *DisplaySettings::createAnnotationSettingsLink()
{ {
auto label = new QLabel("<i><a href>Annotation Settings</a></i>", Core::ICore::mainWindow()); auto label = new QLabel("<small><i><a href>Annotation Settings</a></i></small>",
Core::ICore::mainWindow());
QObject::connect(label, &QLabel::linkActivated, []() { QObject::connect(label, &QLabel::linkActivated, []() {
Utils::ToolTip::hideImmediately(); Utils::ToolTip::hideImmediately();
Core::ICore::showOptionsDialog(Constants::TEXT_EDITOR_DISPLAY_SETTINGS); Core::ICore::showOptionsDialog(Constants::TEXT_EDITOR_DISPLAY_SETTINGS);

View File

@@ -290,6 +290,7 @@ bool TextMark::addToolTipContent(QLayout *target) const
} }
auto textLabel = new QLabel; auto textLabel = new QLabel;
textLabel->setOpenExternalLinks(true);
textLabel->setText(text); textLabel->setText(text);
// Differentiate between tool tips that where explicitly set and default tool tips. // Differentiate between tool tips that where explicitly set and default tool tips.
textLabel->setEnabled(!m_toolTip.isEmpty()); textLabel->setEnabled(!m_toolTip.isEmpty());

View File

@@ -305,9 +305,7 @@ void VcsBaseEditorConfig::updateMappedSettings()
void VcsBaseEditorConfig::addAction(QAction *action) void VcsBaseEditorConfig::addAction(QAction *action)
{ {
const QList<QAction *> actions = d->m_toolBar->actions(); d->m_toolBar->addAction(action);
// Insert the action before line/column and split actions.
d->m_toolBar->insertAction(actions.at(qMax(actions.count() - 2, 0)), action);
} }
} // namespace VcsBase } // namespace VcsBase

View File

@@ -1049,21 +1049,8 @@ void QMakeEvaluator::loadDefaults()
if (GetComputerName(name, &name_length)) if (GetComputerName(name, &name_length))
vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromWCharArray(name)); vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromWCharArray(name));
QSysInfo::WinVersion ver = QSysInfo::WindowsVersion; vars[ProKey("QMAKE_HOST.version")] << ProString(QSysInfo::kernelVersion());
vars[ProKey("QMAKE_HOST.version")] << ProString(QString::number(ver)); vars[ProKey("QMAKE_HOST.version_string")] << ProString(QSysInfo::productVersion());
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;
SYSTEM_INFO info; SYSTEM_INFO info;
GetSystemInfo(&info); GetSystemInfo(&info);

View File

@@ -77,9 +77,12 @@ for id in svgIDs:
# The shell mode of Inkscape is used to execute several export commands # The shell mode of Inkscape is used to execute several export commands
# with one launch of Inkscape. # with one launch of Inkscape.
inkscapeShellCommands = "" inkscapeShellCommands = ""
pngFiles = []
for id in svgIDs: for id in svgIDs:
inkscapeShellCommands += "qtcreatoricons.svg --export-id=" + id + " --export-id-only --export-png=" + qtcSourceRoot + id + ".png --export-dpi=96\n" for scale in [1, 2]:
inkscapeShellCommands += "qtcreatoricons.svg --export-id=" + id + " --export-id-only --export-png=" + qtcSourceRoot + id + "@2x.png --export-dpi=192\n" 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" inkscapeShellCommands += "quit\n"
inkscapeProcess = subprocess.Popen(['inkscape', '--shell'], stdin=subprocess.PIPE, shell=True, cwd=scriptDir) inkscapeProcess = subprocess.Popen(['inkscape', '--shell'], stdin=subprocess.PIPE, shell=True, cwd=scriptDir)
inkscapeProcess.communicate(input=inkscapeShellCommands.encode()) inkscapeProcess.communicate(input=inkscapeShellCommands.encode())
@@ -89,6 +92,5 @@ optipngExecutable = spawn.find_executable("optipng")
if not optipngExecutable: if not optipngExecutable:
sys.stderr.write("optipng was not found in PATH. Please do not push the unoptimized .pngs to the main repository.\n") sys.stderr.write("optipng was not found in PATH. Please do not push the unoptimized .pngs to the main repository.\n")
else: else:
for id in svgIDs: for pngFile in pngFiles:
subprocess.call(["optipng", "-o7", "-strip", "all", qtcSourceRoot + id + ".png"]) subprocess.call(["optipng", "-o7", "-strip", "all", pngFile])
subprocess.call(["optipng", "-o7", "-strip", "all", qtcSourceRoot + id + "@2x.png"])

View File

@@ -25,8 +25,9 @@
#pragma once #pragma once
#include <projectexplorer/headerpath.h>
#include <projectexplorer/abi.h> #include <projectexplorer/abi.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/language.h>
#include <projectexplorer/projectmacro.h> #include <projectexplorer/projectmacro.h>
#include <coreplugin/id.h> #include <coreplugin/id.h>
@@ -39,29 +40,19 @@ class ToolChain
public: public:
Core::Id typeId() const { return Core::Id(); } 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(); } Abi targetAbi() const { return Abi(); }
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(const QStringList &cxxflags, const QString &sysRoot)>; using BuiltInHeaderPathsRunner = std::function<HeaderPaths(const QStringList &cxxflags, const QString &sysRoot)>;
virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const { return BuiltInHeaderPathsRunner(); } virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const { return BuiltInHeaderPathsRunner(); }
using PredefinedMacrosRunner = std::function<Macros(const QStringList &cxxflags)>; class MacroInspectionReport
virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const { return PredefinedMacrosRunner(); } {
public:
Macros macros;
LanguageVersion languageVersion; // Derived from macros.
};
using MacroInspectionRunner = std::function<MacroInspectionReport(const QStringList &cxxflags)>;
virtual MacroInspectionRunner createMacroInspectionRunner() const = 0;
virtual QString originalTargetTriple() const { return QString(); } virtual QString originalTargetTriple() const { return QString(); }
virtual QStringList extraCodeModelFlags() const { return QStringList(); } virtual QStringList extraCodeModelFlags() const { return QStringList(); }

View File

@@ -41,23 +41,30 @@ using ProjectExplorer::Project;
MATCHER_P(IsPartOfHeader, headerPart, std::string(negation ? "isn't " : "is ") + headerPart) 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: protected:
void SetUp() final void SetUp() final
{ {
projectPart.project = project.get(); projectPart.project = project.get();
projectPart.toolchainType = ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID; projectPart.toolchainType = ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID;
projectPart.languageVersion = CppTools::ProjectPart::CXX17; projectPart.languageVersion = ProjectExplorer::LanguageVersion::CXX17;
projectPart.toolChainWordWidth = CppTools::ProjectPart::WordWidth64Bit; projectPart.toolChainWordWidth = CppTools::ProjectPart::WordWidth64Bit;
projectPart.toolChainTargetTriple = "x86_64-apple-darwin10"; projectPart.toolChainTargetTriple = "x86_64-apple-darwin10";
projectPart.extraCodeModelFlags = QStringList{"-arch", "x86_64"}; projectPart.extraCodeModelFlags = QStringList{"-arch", "x86_64"};
projectPart.precompiledHeaders = QStringList{TESTDATA_DIR "/compileroptionsbuilder.pch"}; 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.projectMacros = {ProjectExplorer::Macro{"projectFoo", "projectBar"}};
projectPart.qtVersion = ProjectPart::Qt5; projectPart.qtVersion = ProjectPart::Qt5;
@@ -68,31 +75,51 @@ protected:
std::unique_ptr<Project> project{std::make_unique<ProjectExplorer::Project>()}; std::unique_ptr<Project> project{std::make_unique<ProjectExplorer::Project>()};
ProjectPart projectPart; ProjectPart projectPart;
CompilerOptionsBuilder compilerOptionsBuilder{projectPart}; CppTools::CompilerOptionsBuilder compilerOptionsBuilder{projectPart};
}; };
TEST_F(CompilerOptionsBuilderTest, AddToolchainAndProjectMacros) TEST_F(CompilerOptionsBuilder, AddToolchainAndProjectMacros)
{ {
compilerOptionsBuilder.addToolchainAndProjectMacros(); compilerOptionsBuilder.addToolchainAndProjectMacros();
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-Dfoo=bar", "-DprojectFoo=projectBar")); 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(); compilerOptionsBuilder.addWordWidth();
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-m64")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-m64"));
} }
TEST_F(CompilerOptionsBuilderTest, AddToolchainFlags) TEST_F(CompilerOptionsBuilder, AddToolchainFlags)
{ {
compilerOptionsBuilder.addToolchainFlags(); compilerOptionsBuilder.addToolchainFlags();
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-undef")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-undef"));
} }
TEST_F(CompilerOptionsBuilderTest, HeaderPathOptionsOrder) TEST_F(CompilerOptionsBuilder, HeaderPathOptionsOrder)
{ {
compilerOptionsBuilder.addHeaderPathOptions(); compilerOptionsBuilder.addHeaderPathOptions();
@@ -103,9 +130,9 @@ TEST_F(CompilerOptionsBuilderTest, HeaderPathOptionsOrder)
"-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); "-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(); compilerOptionsBuilder.addHeaderPathOptions();
@@ -116,11 +143,12 @@ TEST_F(CompilerOptionsBuilderTest, UseSystemHeader)
"-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); "-isystem", QDir::toNativeSeparators("/tmp/builtin_path")));
} }
TEST_F(CompilerOptionsBuilderTest, ClangHeadersPath) TEST_F(CompilerOptionsBuilder, ClangHeadersPath)
{ {
CompilerOptionsBuilder compilerOptionsBuilder(projectPart, CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
CppTools::UseSystemHeader::No, CppTools::UseSystemHeader::No,
CppTools::SkipBuiltIn::No, CppTools::SkipBuiltIn::No,
CppTools::SkipLanguageDefines::Yes,
"7.0.0", "7.0.0",
""); "");
@@ -135,7 +163,7 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersPath)
"-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); "-isystem", QDir::toNativeSeparators("/tmp/builtin_path")));
} }
TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderMacOs) TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderMacOs)
{ {
auto defaultPaths = projectPart.headerPaths; auto defaultPaths = projectPart.headerPaths;
projectPart.headerPaths = {HeaderPath{"/usr/include/c++/4.2.1", HeaderPathType::BuiltIn}, projectPart.headerPaths = {HeaderPath{"/usr/include/c++/4.2.1", HeaderPathType::BuiltIn},
@@ -146,9 +174,10 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderMacOs)
HeaderPath{"/usr/include", HeaderPathType::BuiltIn} HeaderPath{"/usr/include", HeaderPathType::BuiltIn}
}; };
projectPart.headerPaths.append(defaultPaths); projectPart.headerPaths.append(defaultPaths);
CompilerOptionsBuilder compilerOptionsBuilder(projectPart, CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
CppTools::UseSystemHeader::No, CppTools::UseSystemHeader::No,
CppTools::SkipBuiltIn::No, CppTools::SkipBuiltIn::No,
CppTools::SkipLanguageDefines::Yes,
"7.0.0", "7.0.0",
""); "");
@@ -168,7 +197,7 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderMacOs)
"-isystem", QDir::toNativeSeparators("/tmp/builtin_path"))); "-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}, 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}, HeaderPath{"/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward", HeaderPathType::BuiltIn},
@@ -179,9 +208,10 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderLinux)
HeaderPath{"/usr/include", HeaderPathType::BuiltIn} HeaderPath{"/usr/include", HeaderPathType::BuiltIn}
}; };
projectPart.toolChainTargetTriple = "x86_64-linux-gnu"; projectPart.toolChainTargetTriple = "x86_64-linux-gnu";
CompilerOptionsBuilder compilerOptionsBuilder(projectPart, CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
CppTools::UseSystemHeader::No, CppTools::UseSystemHeader::No,
CppTools::SkipBuiltIn::No, CppTools::SkipBuiltIn::No,
CppTools::SkipLanguageDefines::Yes,
"7.0.0", "7.0.0",
""); "");
@@ -200,75 +230,75 @@ TEST_F(CompilerOptionsBuilderTest, ClangHeadersAndCppIncludesPathsOrderLinux)
"-isystem", QDir::toNativeSeparators("/usr/include"))); "-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); 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(), ASSERT_THAT(compilerOptionsBuilder.options(),
ElementsAre("-include", QDir::toNativeSeparators(TESTDATA_DIR "/compileroptionsbuilder.pch"))); ElementsAre("-include", QDir::toNativeSeparators(TESTDATA_DIR "/compileroptionsbuilder.pch")));
} }
TEST_F(CompilerOptionsBuilderTest, AddMacros) TEST_F(CompilerOptionsBuilder, AddMacros)
{ {
compilerOptionsBuilder.addMacros(ProjectExplorer::Macros{ProjectExplorer::Macro{"key", "value"}}); compilerOptionsBuilder.addMacros(ProjectExplorer::Macros{ProjectExplorer::Macro{"key", "value"}});
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-Dkey=value")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-Dkey=value"));
} }
TEST_F(CompilerOptionsBuilderTest, AddTargetTriple) TEST_F(CompilerOptionsBuilder, AddTargetTriple)
{ {
compilerOptionsBuilder.addTargetTriple(); compilerOptionsBuilder.addTargetTriple();
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-target", "x86_64-apple-darwin10")); 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(); compilerOptionsBuilder.enableExceptions();
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-fexceptions")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-fexceptions"));
} }
TEST_F(CompilerOptionsBuilderTest, EnableCXXExceptions) TEST_F(CompilerOptionsBuilder, EnableCXXExceptions)
{ {
compilerOptionsBuilder.enableExceptions(); compilerOptionsBuilder.enableExceptions();
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-fcxx-exceptions", "-fexceptions")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-fcxx-exceptions", "-fexceptions"));
} }
TEST_F(CompilerOptionsBuilderTest, InsertWrappedQtHeaders) TEST_F(CompilerOptionsBuilder, InsertWrappedQtHeaders)
{ {
compilerOptionsBuilder.insertWrappedQtHeaders(); compilerOptionsBuilder.insertWrappedQtHeaders();
ASSERT_THAT(compilerOptionsBuilder.options(), Contains(IsPartOfHeader("wrappedQtHeaders"))); ASSERT_THAT(compilerOptionsBuilder.options(), Contains(IsPartOfHeader("wrappedQtHeaders")));
} }
TEST_F(CompilerOptionsBuilderTest, SetLanguageVersion) TEST_F(CompilerOptionsBuilder, SetLanguageVersion)
{ {
compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource); compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource);
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "c++")); 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); compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource);
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "objective-c++")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "objective-c++"));
} }
TEST_F(CompilerOptionsBuilderTest, UpdateLanguageVersion) TEST_F(CompilerOptionsBuilder, UpdateLanguageVersion)
{ {
compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource); compilerOptionsBuilder.updateLanguageOption(ProjectFile::CXXSource);
@@ -277,7 +307,7 @@ TEST_F(CompilerOptionsBuilderTest, UpdateLanguageVersion)
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "c++-header")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-x", "c++-header"));
} }
TEST_F(CompilerOptionsBuilderTest, AddMsvcCompatibilityVersion) TEST_F(CompilerOptionsBuilder, AddMsvcCompatibilityVersion)
{ {
projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID;
projectPart.toolChainMacros.append(ProjectExplorer::Macro{"_MSC_FULL_VER", "190000000"}); 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")); 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.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID;
projectPart.isMsvc2015Toolchain = true; projectPart.isMsvc2015Toolchain = true;
@@ -297,7 +327,7 @@ TEST_F(CompilerOptionsBuilderTest, UndefineCppLanguageFeatureMacrosForMsvc2015)
ASSERT_THAT(compilerOptionsBuilder.options(), Contains(QString{"-U__cpp_aggregate_bases"})); 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; projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID;
@@ -306,7 +336,7 @@ TEST_F(CompilerOptionsBuilderTest, AddDefineFunctionMacrosMsvc)
ASSERT_THAT(compilerOptionsBuilder.options(), Contains(QString{"-D__FUNCTION__=\"\""})); ASSERT_THAT(compilerOptionsBuilder.options(), Contains(QString{"-D__FUNCTION__=\"\""}));
} }
TEST_F(CompilerOptionsBuilderTest, AddProjectConfigFileInclude) TEST_F(CompilerOptionsBuilder, AddProjectConfigFileInclude)
{ {
projectPart.projectConfigFile = "dummy_file.h"; projectPart.projectConfigFile = "dummy_file.h";
@@ -315,7 +345,7 @@ TEST_F(CompilerOptionsBuilderTest, AddProjectConfigFileInclude)
ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-include", "dummy_file.h")); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-include", "dummy_file.h"));
} }
TEST_F(CompilerOptionsBuilderTest, UndefineClangVersionMacrosForMsvc) TEST_F(CompilerOptionsBuilder, UndefineClangVersionMacrosForMsvc)
{ {
projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID;
@@ -324,20 +354,21 @@ TEST_F(CompilerOptionsBuilderTest, UndefineClangVersionMacrosForMsvc)
ASSERT_THAT(compilerOptionsBuilder.options(), Contains(QString{"-U__clang__"})); 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(), ASSERT_THAT(compilerOptionsBuilder.options(),
ElementsAre( ElementsAre(
"-nostdlibinc", "-c", "-m64", "-target", "x86_64-apple-darwin10", "-nostdlibinc", "-c", "-m64", "-target", "x86_64-apple-darwin10",
"-arch", "x86_64", "-x", "c++", "-std=c++17", "-fcxx-exceptions", "-arch", "x86_64", "-x", "c++", "-std=c++17", "-fcxx-exceptions",
"-fexceptions", "-Dfoo=bar", "-DprojectFoo=projectBar", "-undef", "-fexceptions", "-Dfoo=bar", "-DprojectFoo=projectBar", "-undef",
"-I", QDir::toNativeSeparators("D:/code/qt-creator/tests/unit/unittest/../../../share/qtcreator/cplusplus/wrappedQtHeaders"), "-I", IsPartOfHeader("wrappedQtHeaders"),
"-I", QDir::toNativeSeparators("D:/code/qt-creator/tests/unit/unittest/../../../share/qtcreator/cplusplus/wrappedQtHeaders/QtCore"), "-I", IsPartOfHeader(QDir::toNativeSeparators("wrappedQtHeaders/QtCore").toStdString()),
"-I", QDir::toNativeSeparators("/tmp/path"), "-I", QDir::toNativeSeparators("/tmp/path"),
"-I", QDir::toNativeSeparators("/tmp/system_path"), "-I", QDir::toNativeSeparators("/tmp/system_path"),
"-isystem", QDir::toNativeSeparators("/tmp/builtin_path") "-isystem", QDir::toNativeSeparators("/tmp/builtin_path")
)); ));
} }
}

View File

@@ -39,6 +39,7 @@ using CppTools::ProjectUpdateInfo;
using CppTools::ProjectPart; using CppTools::ProjectPart;
using CppTools::RawProjectPart; using CppTools::RawProjectPart;
using ProjectExplorer::Macros;
using ProjectExplorer::ToolChain; using ProjectExplorer::ToolChain;
using testing::Eq; using testing::Eq;
@@ -65,6 +66,7 @@ protected:
ProjectInfo generate(); ProjectInfo generate();
protected: protected:
ProjectUpdateInfo projectUpdateInfo;
RawProjectPart rawProjectPart; RawProjectPart rawProjectPart;
}; };
@@ -101,7 +103,7 @@ TEST_F(ProjectInfoGenerator, ProjectPartIndicatesObjectiveCExtensionsByDefault)
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0); const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::ObjectiveCExtensions); ASSERT_TRUE(projectPart.languageExtensions & ProjectExplorer::LanguageExtension::ObjectiveC);
} }
TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault) TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault)
@@ -112,31 +114,33 @@ TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault)
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0); 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.files = QStringList{ "foo.cpp" };
rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::StandardCxx98;
const ProjectInfo projectInfo = generate(); const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0); 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.files = QStringList{ "foo.cpp" };
rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::MicrosoftExtensions; rawProjectPart.flagsForCxx.languageExtensions = ProjectExplorer::LanguageExtension::Microsoft;
const ProjectInfo projectInfo = generate(); const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0); const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::MicrosoftExtensions); ASSERT_TRUE(projectPart.languageExtensions & ProjectExplorer::LanguageExtension::Microsoft);
} }
TEST_F(ProjectInfoGenerator, ProjectFileKindsMatchProjectPartVersion) TEST_F(ProjectInfoGenerator, ProjectFileKindsMatchProjectPartVersion)
@@ -146,10 +150,10 @@ TEST_F(ProjectInfoGenerator, ProjectFileKindsMatchProjectPartVersion)
const ProjectInfo projectInfo = generate(); const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts(), ASSERT_THAT(projectInfo.projectParts(),
UnorderedElementsAre(IsProjectPart(ProjectPart::LatestCVersion, ProjectFile::CHeader), UnorderedElementsAre(IsProjectPart(ProjectExplorer::LanguageVersion::LatestC, ProjectFile::CHeader),
IsProjectPart(ProjectPart::LatestCVersion, ProjectFile::ObjCHeader), IsProjectPart(ProjectExplorer::LanguageVersion::LatestC, ProjectFile::ObjCHeader),
IsProjectPart(ProjectPart::LatestCxxVersion, ProjectFile::CXXHeader), IsProjectPart(ProjectExplorer::LanguageVersion::LatestCxx, ProjectFile::CXXHeader),
IsProjectPart(ProjectPart::LatestCxxVersion, ProjectFile::ObjCXXHeader))); IsProjectPart(ProjectExplorer::LanguageVersion::LatestCxx, ProjectFile::ObjCXXHeader)));
} }
void ProjectInfoGenerator::SetUp() void ProjectInfoGenerator::SetUp()
@@ -160,7 +164,7 @@ void ProjectInfoGenerator::SetUp()
ProjectInfo ProjectInfoGenerator::generate() ProjectInfo ProjectInfoGenerator::generate()
{ {
QFutureInterface<void> fi; QFutureInterface<void> fi;
ProjectUpdateInfo projectUpdateInfo;
projectUpdateInfo.rawProjectParts += rawProjectPart; projectUpdateInfo.rawProjectParts += rawProjectPart;
::ProjectInfoGenerator generator(fi, projectUpdateInfo); ::ProjectInfoGenerator generator(fi, projectUpdateInfo);

View File

@@ -342,12 +342,12 @@ QList<ProjectPart::Ptr> ProjectPartChooser::createCAndCxxProjectParts()
// Create project part for C // Create project part for C
const ProjectPart::Ptr cprojectpart{new ProjectPart}; const ProjectPart::Ptr cprojectpart{new ProjectPart};
cprojectpart->languageVersion = ProjectPart::C11; cprojectpart->languageVersion = ProjectExplorer::LanguageVersion::C11;
projectParts.append(cprojectpart); projectParts.append(cprojectpart);
// Create project part for CXX // Create project part for CXX
const ProjectPart::Ptr cxxprojectpart{new ProjectPart}; const ProjectPart::Ptr cxxprojectpart{new ProjectPart};
cxxprojectpart->languageVersion = ProjectPart::CXX98; cxxprojectpart->languageVersion = ProjectExplorer::LanguageVersion::CXX98;
projectParts.append(cxxprojectpart); projectParts.append(cxxprojectpart);
return projectParts; return projectParts;