Merge remote-tracking branch 'origin/7.0'

Change-Id: I9a7a9a5579f1f4e277e7927eefb1bab9ca60ad4a
This commit is contained in:
Eike Ziller
2022-04-07 09:51:40 +02:00
23 changed files with 168 additions and 41 deletions

View File

@@ -8,7 +8,7 @@ on:
env: env:
QT_VERSION: 6.2.3 QT_VERSION: 6.2.3
CLANG_VERSION: 140 CLANG_VERSION: 14.0.0
ELFUTILS_VERSION: 0.175 ELFUTILS_VERSION: 0.175
CMAKE_VERSION: 3.21.1 CMAKE_VERSION: 3.21.1
NINJA_VERSION: 1.10.2 NINJA_VERSION: 1.10.2

View File

@@ -7,7 +7,7 @@ instructions:
variableValue: "RelWithDebInfo" variableValue: "RelWithDebInfo"
- type: EnvironmentVariable - type: EnvironmentVariable
variableName: LLVM_BASE_URL variableName: LLVM_BASE_URL
variableValue: http://master.qt.io/development_releases/prebuilt/libclang/libclang-release_140-based variableValue: http://master.qt.io/development_releases/prebuilt/libclang/libclang-release_14.0.0-based
- type: Group - type: Group
instructions: instructions:

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
############################################################################ ############################################################################
# #
@@ -102,7 +102,7 @@ def bash_setup(shell):
def main(): def main():
# create temporary file to be sourced into bash that deletes itself # create temporary file to be sourced into bash that deletes itself
with NamedTemporaryFile(delete=False) as shell_script: with NamedTemporaryFile(mode='wt', delete=False) as shell_script:
shell = os.environ.get('SHELL') shell = os.environ.get('SHELL')
shell, system_login_script, login_script, non_interactive_shell, interactive_shell = ( shell, system_login_script, login_script, non_interactive_shell, interactive_shell = (
zsh_setup(shell) if shell is not None and shell.endswith('/zsh') zsh_setup(shell) if shell is not None and shell.endswith('/zsh')

View File

@@ -3,6 +3,8 @@ import qbs 1.0
Product { Product {
name: "Translations" name: "Translations"
type: "qm" type: "qm"
builtByDefault: false
Depends { name: "Qt.core" } Depends { name: "Qt.core" }
Depends { name: "qtc" } Depends { name: "qtc" }

View File

@@ -1393,7 +1393,6 @@ int ForeachStatementAST::lastToken() const
return 1; return 1;
} }
/** \generated */
int FunctionDeclaratorAST::firstToken() const int FunctionDeclaratorAST::firstToken() const
{ {
if (lparen_token) if (lparen_token)
@@ -1403,40 +1402,50 @@ int FunctionDeclaratorAST::firstToken() const
return candidate; return candidate;
if (rparen_token) if (rparen_token)
return rparen_token; return rparen_token;
if (cv_qualifier_list) const int firstQualListToken = cv_qualifier_list ? cv_qualifier_list->firstToken() : 0;
if (int candidate = cv_qualifier_list->firstToken()) const auto isBeforeFirstQualListToken = [firstQualListToken](int token) {
return candidate; return token && (!firstQualListToken || token < firstQualListToken);
if (ref_qualifier_token) };
if (isBeforeFirstQualListToken(ref_qualifier_token))
return ref_qualifier_token; return ref_qualifier_token;
if (exception_specification) if (exception_specification) {
if (int candidate = exception_specification->firstToken()) const int candidate = exception_specification->firstToken();
if (isBeforeFirstQualListToken(candidate))
return candidate; return candidate;
if (trailing_return_type) }
if (int candidate = trailing_return_type->firstToken()) if (trailing_return_type) {
const int candidate = trailing_return_type->firstToken();
if (isBeforeFirstQualListToken(candidate))
return candidate; return candidate;
}
if (firstQualListToken)
return firstQualListToken;
if (as_cpp_initializer) if (as_cpp_initializer)
if (int candidate = as_cpp_initializer->firstToken()) if (int candidate = as_cpp_initializer->firstToken())
return candidate; return candidate;
return 0; return 0;
} }
/** \generated */
int FunctionDeclaratorAST::lastToken() const int FunctionDeclaratorAST::lastToken() const
{ {
if (as_cpp_initializer) if (as_cpp_initializer)
if (int candidate = as_cpp_initializer->lastToken()) if (int candidate = as_cpp_initializer->lastToken())
return candidate; return candidate;
if (trailing_return_type) const int lastQualListToken = cv_qualifier_list ? cv_qualifier_list->lastToken() : 0;
if (int candidate = trailing_return_type->lastToken()) const auto tokenOrLastQualListToken = [lastQualListToken](int token) {
return candidate; return std::max(token ? token + 1 : 0, lastQualListToken);
if (exception_specification) };
if (int candidate = exception_specification->lastToken()) const auto tokenFromAstOrLastQualListToken = [lastQualListToken](const AST *ast) {
return candidate; return std::max(ast ? ast->lastToken() : 0, lastQualListToken);
if (ref_qualifier_token) };
return ref_qualifier_token + 1; if (int candidate = tokenFromAstOrLastQualListToken(trailing_return_type))
if (cv_qualifier_list) return candidate;
if (int candidate = cv_qualifier_list->lastToken()) if (int candidate = tokenFromAstOrLastQualListToken(exception_specification))
return candidate; return candidate;
if (int candidate = tokenOrLastQualListToken(ref_qualifier_token))
return candidate;
if (lastQualListToken)
return lastQualListToken;
if (rparen_token) if (rparen_token)
return rparen_token + 1; return rparen_token + 1;
if (parameter_declaration_clause) if (parameter_declaration_clause)

View File

@@ -86,6 +86,7 @@ Overview::Overview()
showTemplateParameters(false), showTemplateParameters(false),
showEnclosingTemplate(false), showEnclosingTemplate(false),
includeWhiteSpaceInOperatorName(true), includeWhiteSpaceInOperatorName(true),
trailingReturnType(false),
markedArgument(0), markedArgument(0),
markedArgumentBegin(0), markedArgumentBegin(0),
markedArgumentEnd(0) markedArgumentEnd(0)

View File

@@ -69,6 +69,7 @@ public:
bool showTemplateParameters: 1; bool showTemplateParameters: 1;
bool showEnclosingTemplate: 1; bool showEnclosingTemplate: 1;
bool includeWhiteSpaceInOperatorName: 1; /// "operator =()" vs "operator=()" bool includeWhiteSpaceInOperatorName: 1; /// "operator =()" vs "operator=()"
bool trailingReturnType: 1;
int markedArgument; int markedArgument;
int markedArgumentBegin; int markedArgumentBegin;

View File

@@ -435,11 +435,17 @@ void TypePrettyPrinter::visit(Function *type)
retAndArgOverview.showTemplateParameters = true; retAndArgOverview.showTemplateParameters = true;
if (_overview->showReturnTypes) { if (_overview->showReturnTypes) {
const QString returnType = retAndArgOverview.prettyType(type->returnType()); if (_overview->trailingReturnType) {
if (!returnType.isEmpty()) { _text.prepend("auto ");
if (!endsWithPtrOrRef(returnType) || !(_overview->starBindFlags & Overview::BindToIdentifier)) } else {
_text.prepend(QLatin1Char(' ')); const QString returnType = retAndArgOverview.prettyType(type->returnType());
_text.prepend(returnType); if (!returnType.isEmpty()) {
if (!endsWithPtrOrRef(returnType)
|| !(_overview->starBindFlags & Overview::BindToIdentifier)) {
_text.prepend(QLatin1Char(' '));
}
_text.prepend(returnType);
}
} }
} }
@@ -525,10 +531,19 @@ void TypePrettyPrinter::visit(Function *type)
// add exception specifier // add exception specifier
if (const StringLiteral *spec = type->exceptionSpecification()) { if (const StringLiteral *spec = type->exceptionSpecification()) {
appendSpace(); if (type->refQualifier() != Function::NoRefQualifier)
_text.append(' ');
else
appendSpace();
_text += QLatin1String(spec->chars()); _text += QLatin1String(spec->chars());
} }
} }
if (_overview->showReturnTypes && _overview->trailingReturnType) {
const QString returnType = retAndArgOverview.prettyType(type->returnType());
if (!returnType.isEmpty())
_text.append(" -> ").append(returnType);
}
} }
void TypePrettyPrinter::appendSpace() void TypePrettyPrinter::appendSpace()

View File

@@ -2835,9 +2835,15 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
if (path.rbegin()->hasConstType()) if (path.rbegin()->hasConstType())
return false; return false;
for (auto it = path.rbegin() + 1; it != path.rend(); ++it) { for (auto it = path.rbegin() + 1; it != path.rend(); ++it) {
if (it->kind() == "Call" || it->kind() == "CXXConstruct" if (it->kind() == "CXXConstruct" || it->kind() == "MemberInitializer")
|| it->kind() == "MemberInitializer") {
return true; return true;
if (it->kind() == "Call") {
// In class templates, member calls can result in "Call" nodes rather than
// "CXXMemberCall". We try to detect this by checking for a certain kind of
// child node.
const QList<AstNode> children = it->children().value_or(QList<AstNode>());
return children.isEmpty() || children.first().kind() != "CXXDependentScopeMember";
} }
// The token should get marked for e.g. lambdas, but not for assignment operators, // The token should get marked for e.g. lambdas, but not for assignment operators,

View File

@@ -1315,6 +1315,12 @@ void ClangdTestHighlighting::test_data()
QTest::newRow("deref operator (object)") << 960 << 10 << 960 << 11 << QList<int>{C_LOCAL} << 0; QTest::newRow("deref operator (object)") << 960 << 10 << 960 << 11 << QList<int>{C_LOCAL} << 0;
QTest::newRow("deref operator (member)") << 960 << 12 << 960 << 13 << QList<int>{C_FIELD} << 0; QTest::newRow("deref operator (member)") << 960 << 12 << 960 << 13 << QList<int>{C_FIELD} << 0;
QTest::newRow("nested call") << 979 << 20 << 979 << 21 << QList<int>{C_LOCAL} << 0; QTest::newRow("nested call") << 979 << 20 << 979 << 21 << QList<int>{C_LOCAL} << 0;
QTest::newRow("member call on dependent (1)") << 996 << 19 << 996 << 22
<< QList<int>{C_FIELD} << 0;
QTest::newRow("member call on dependent (2)") << 996 << 38 << 996 << 41
<< QList<int>{C_FIELD} << 0;
QTest::newRow("member call on dependent (3)") << 999 << 9 << 999 << 12
<< QList<int>{C_LOCAL} << 0;
} }
void ClangdTestHighlighting::test() void ClangdTestHighlighting::test()

View File

@@ -978,3 +978,24 @@ void nestedCall()
my_struct* s = get_my_struct(); my_struct* s = get_my_struct();
new my_struct2(s->method(0)); new my_struct2(s->method(0));
} }
template<typename T>
class my_class
{
private:
struct my_int
{
int n;
};
std::vector<my_int> vec;
public:
void foo()
{
auto it = vec.begin(), end = vec.end();
T* ptr = nullptr;
ptr->bar();
}
};

View File

@@ -268,7 +268,18 @@ QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
// CMake sometimes mixes several shell-escaped pieces into one fragment. Disentangle that again: // CMake sometimes mixes several shell-escaped pieces into one fragment. Disentangle that again:
const QStringList parts = ProcessArgs::splitArgs(f.fragment); const QStringList parts = ProcessArgs::splitArgs(f.fragment);
for (const QString &part : parts) { for (QString part : parts) {
// Library search paths that are added with target_link_directories are added as
// -LIBPATH:... (Windows/MSVC), or
// -L... (Unix/GCC)
// with role "libraryPath"
if (f.role == "libraryPath") {
if (part.startsWith("-LIBPATH:"))
part = part.mid(9);
else if (part.startsWith("-L"))
part = part.mid(2);
}
// Some projects abuse linking to libraries to pass random flags to the linker, so ignore // Some projects abuse linking to libraries to pass random flags to the linker, so ignore
// flags mixed into a fragment // flags mixed into a fragment
if (part.startsWith("-")) if (part.startsWith("-"))

View File

@@ -33,6 +33,7 @@
#include <QCheckBox> #include <QCheckBox>
#include <QEvent> #include <QEvent>
#include <QKeyEvent> #include <QKeyEvent>
#include <QScreen>
#include <QVBoxLayout> #include <QVBoxLayout>
using namespace Utils; using namespace Utils;
@@ -64,7 +65,8 @@ OptionsPopup::OptionsPopup(QWidget *parent, const QVector<Id> &commands)
layout->addWidget(checkBox); layout->addWidget(checkBox);
} }
const QPoint globalPos = parent->mapToGlobal(QPoint(0, -sizeHint().height())); const QPoint globalPos = parent->mapToGlobal(QPoint(0, -sizeHint().height()));
move(globalPos.x(), std::max(globalPos.y(), 0)); const QRect screenGeometry = parent->screen()->availableGeometry();
move(globalPos.x(), std::max(globalPos.y(), screenGeometry.y()));
} }
bool OptionsPopup::event(QEvent *ev) bool OptionsPopup::event(QEvent *ev)

View File

@@ -204,7 +204,7 @@ bool ListModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceP
if (!m_filterTags.isEmpty()) { if (!m_filterTags.isEmpty()) {
return Utils::allOf(m_filterTags, [&item](const QString &filterTag) { return Utils::allOf(m_filterTags, [&item](const QString &filterTag) {
return item->tags.contains(filterTag); return item->tags.contains(filterTag, Qt::CaseInsensitive);
}); });
} }
@@ -214,7 +214,9 @@ bool ListModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceP
wordMatch |= bool(item->name.contains(subString, Qt::CaseInsensitive)); wordMatch |= bool(item->name.contains(subString, Qt::CaseInsensitive));
if (wordMatch) if (wordMatch)
continue; continue;
const auto subMatch = [&subString](const QString &elem) { return elem.contains(subString); }; const auto subMatch = [&subString](const QString &elem) {
return elem.contains(subString, Qt::CaseInsensitive);
};
wordMatch |= Utils::contains(item->tags, subMatch); wordMatch |= Utils::contains(item->tags, subMatch);
if (wordMatch) if (wordMatch)
continue; continue;

View File

@@ -6110,6 +6110,41 @@ void QuickfixTest::testMoveFuncDefOutsideMemberFuncToCppWithInlinePartOfName()
QuickFixOperationTest(testDocuments, &factory); QuickFixOperationTest(testDocuments, &factory);
} }
void QuickfixTest::testMoveFuncDefOutsideMixedQualifiers()
{
QList<TestDocumentPtr> testDocuments;
QByteArray original;
QByteArray expected;
// Header File
original = R"(
struct Base {
virtual auto func() const && noexcept -> void = 0;
};
struct Derived : public Base {
auto @func() const && noexcept -> void override {}
};)";
expected = R"(
struct Base {
virtual auto func() const && noexcept -> void = 0;
};
struct Derived : public Base {
auto func() const && noexcept -> void override;
};)";
testDocuments << CppTestDocument::create("file.h", original, expected);
// Source File
original = "#include \"file.h\"\n";
expected = R"DELIM(#include "file.h"
auto Derived::func() const && noexcept -> void {}
)DELIM";
testDocuments << CppTestDocument::create("file.cpp", original, expected);
MoveFuncDefOutside factory;
QuickFixOperationTest(testDocuments, &factory);
}
void QuickfixTest::testMoveFuncDefOutsideMemberFuncToCppInsideNS() void QuickfixTest::testMoveFuncDefOutsideMemberFuncToCppInsideNS()
{ {
QList<TestDocumentPtr> testDocuments; QList<TestDocumentPtr> testDocuments;

View File

@@ -192,6 +192,7 @@ private slots:
void testMoveFuncDefOutsideUnnamedTemplate(); void testMoveFuncDefOutsideUnnamedTemplate();
void testMoveFuncDefOutsideMemberFuncToCppStatic(); void testMoveFuncDefOutsideMemberFuncToCppStatic();
void testMoveFuncDefOutsideMemberFuncToCppWithInlinePartOfName(); void testMoveFuncDefOutsideMemberFuncToCppWithInlinePartOfName();
void testMoveFuncDefOutsideMixedQualifiers();
void testMoveAllFuncDefOutsideMemberFuncToCpp(); void testMoveAllFuncDefOutsideMemberFuncToCpp();
void testMoveAllFuncDefOutsideMemberFuncOutside(); void testMoveAllFuncDefOutsideMemberFuncOutside();

View File

@@ -6234,6 +6234,13 @@ QString definitionSignature(const CppQuickFixInterface *assist,
oo.showArgumentNames = true; oo.showArgumentNames = true;
oo.showEnclosingTemplate = true; oo.showEnclosingTemplate = true;
oo.showTemplateParameters = true; oo.showTemplateParameters = true;
oo.trailingReturnType = functionDefinitionAST->declarator
&& functionDefinitionAST->declarator->postfix_declarator_list
&& functionDefinitionAST->declarator->postfix_declarator_list->value
&& functionDefinitionAST->declarator->postfix_declarator_list
->value->asFunctionDeclarator()
&& functionDefinitionAST->declarator->postfix_declarator_list
->value->asFunctionDeclarator()->trailing_return_type;
const Name *name = func->name(); const Name *name = func->name();
if (name && nameIncludesOperatorName(name)) { if (name && nameIncludesOperatorName(name)) {
CoreDeclaratorAST *coreDeclarator = functionDefinitionAST->declarator->core_declarator; CoreDeclaratorAST *coreDeclarator = functionDefinitionAST->declarator->core_declarator;

View File

@@ -724,11 +724,13 @@ void ItemLibraryAssetImportDialog::setCloseButtonState(bool importing)
void ItemLibraryAssetImportDialog::addError(const QString &error, const QString &srcPath) void ItemLibraryAssetImportDialog::addError(const QString &error, const QString &srcPath)
{ {
m_closeOnFinish = false;
addFormattedMessage(m_outputFormatter, error, srcPath, Utils::StdErrFormat); addFormattedMessage(m_outputFormatter, error, srcPath, Utils::StdErrFormat);
} }
void ItemLibraryAssetImportDialog::addWarning(const QString &warning, const QString &srcPath) void ItemLibraryAssetImportDialog::addWarning(const QString &warning, const QString &srcPath)
{ {
m_closeOnFinish = false;
addFormattedMessage(m_outputFormatter, warning, srcPath, Utils::StdOutFormat); addFormattedMessage(m_outputFormatter, warning, srcPath, Utils::StdOutFormat);
} }
@@ -777,6 +779,10 @@ void ItemLibraryAssetImportDialog::onImportFinished()
QString doneStr = tr("Import done."); QString doneStr = tr("Import done.");
addInfo(doneStr); addInfo(doneStr);
setImportProgress(100, doneStr); setImportProgress(100, doneStr);
if (m_closeOnFinish) {
// Add small delay to allow user to visually confirm import finishing
QTimer::singleShot(1000, this, &ItemLibraryAssetImportDialog::onClose);
}
} }
} }
@@ -785,7 +791,7 @@ void ItemLibraryAssetImportDialog::onClose()
if (m_importer.isImporting()) { if (m_importer.isImporting()) {
addInfo(tr("Canceling import.")); addInfo(tr("Canceling import."));
m_importer.cancelImport(); m_importer.cancelImport();
} else { } else if (isVisible()) {
if (ui->progressBar->value() == 100) // import done successfully if (ui->progressBar->value() == 100) // import done successfully
accept(); accept();
else else

View File

@@ -91,5 +91,6 @@ private:
int m_optionsHeight = 0; int m_optionsHeight = 0;
int m_optionsRows = 0; int m_optionsRows = 0;
QSet<QString> m_preselectedFilesForOverwrite; QSet<QString> m_preselectedFilesForOverwrite;
bool m_closeOnFinish = true;
}; };
} }

View File

@@ -98,7 +98,6 @@ static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPt
type = componentObjectValue->className().toUtf8(); type = componentObjectValue->className().toUtf8();
dotProperties = getObjectTypes(componentObjectValue, context); dotProperties = getObjectTypes(componentObjectValue, context);
} else if (const ObjectValue * objectValue = value->asObjectValue()) { } else if (const ObjectValue * objectValue = value->asObjectValue()) {
type = objectValue->className().toUtf8();
dotProperties = getObjectTypes(objectValue, context); dotProperties = getObjectTypes(objectValue, context);
} }

View File

@@ -555,6 +555,9 @@ void ExampleSetModel::updateQtVersionList()
newQtVersion = findHighestQtVersion(versions); newQtVersion = findHighestQtVersion(versions);
currentIndex = indexForQtVersion(newQtVersion); currentIndex = indexForQtVersion(newQtVersion);
} // nothing to do for extra example sets } // nothing to do for extra example sets
// Make sure to select something even if the above failed
if (currentIndex < 0 && rowCount() > 0)
currentIndex = 0; // simply select first
selectExampleSet(currentIndex); selectExampleSet(currentIndex);
emit selectedExampleSetChanged(currentIndex); emit selectedExampleSetChanged(currentIndex);
} }

View File

@@ -549,7 +549,6 @@ void ValgrindMemcheckParserTest::testValgrindStartError()
RunnerDumper dumper(&runner); RunnerDumper dumper(&runner);
runner.start(); runner.start();
runner.waitForFinished(); runner.waitForFinished();
QEXPECT_FAIL("", "Error codes of valgrind startup are currently unprocessed", Continue); //FIXME
QVERIFY(dumper.m_errorReceived); QVERIFY(dumper.m_errorReceived);
// just finish without deadlock and we are fine // just finish without deadlock and we are fine
} }