diff --git a/.clang-format b/.clang-format index 25df05eb265..953e0b44cd6 100644 --- a/.clang-format +++ b/.clang-format @@ -53,7 +53,7 @@ BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeComma BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: false +BreakStringLiterals: true ColumnLimit: 100 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false diff --git a/doc/src/android/androiddev.qdoc b/doc/src/android/androiddev.qdoc index e7fd3901be4..ac2a77a3fe6 100644 --- a/doc/src/android/androiddev.qdoc +++ b/doc/src/android/androiddev.qdoc @@ -103,7 +103,15 @@ \endlist - \endlist + \note When using the command line tools instead of Android Studio, + it is recommended to create an empty folder and extract the + downloaded archive into this folder. + The sdkmanager will install downloaded packages next to the + \c tools folder that contains all command line tools. + You must specify the path to the folder where you extracted the + files as Android SDK location inside the Android settings. + + \endlist \section1 Setting Up the Development Environment diff --git a/qbs/modules/libclang/functions.js b/qbs/modules/libclang/functions.js index 99577c3146b..4d384d773e4 100644 --- a/qbs/modules/libclang/functions.js +++ b/qbs/modules/libclang/functions.js @@ -167,6 +167,9 @@ function toolingParameters(llvmConfig) "-Wcovered-switch-default", "-Wnon-virtual-dtor", "-Woverloaded-virtual", + "-Wmissing-field-initializers", + "-Wno-unknown-warning", + "-Wno-unused-command-line-argument", "-fPIC", "-pedantic", "-Wstring-conversion", diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index 0d13dc3f913..9bfcc77a98f 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -4,16 +4,16 @@ import qbs.FileInfo import "qtc.js" as HelperFunctions Module { - property string qtcreator_display_version: '4.8.0-rc1' + property string qtcreator_display_version: '4.8.0' property string ide_version_major: '4' - property string ide_version_minor: '7' - property string ide_version_release: '84' + property string ide_version_minor: '8' + property string ide_version_release: '0' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release property string ide_compat_version_major: '4' - property string ide_compat_version_minor: '7' - property string ide_compat_version_release: '84' + property string ide_compat_version_minor: '8' + property string ide_compat_version_release: '0' property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release diff --git a/qtcreator.pri b/qtcreator.pri index 5af18c1b93d..d65ede07de7 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -1,10 +1,10 @@ !isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included") QTCREATOR_PRI_INCLUDED = 1 -QTCREATOR_VERSION = 4.7.84 -QTCREATOR_COMPAT_VERSION = 4.7.84 +QTCREATOR_VERSION = 4.8.0 +QTCREATOR_COMPAT_VERSION = 4.8.0 VERSION = $$QTCREATOR_VERSION -QTCREATOR_DISPLAY_VERSION = 4.8.0-rc1 +QTCREATOR_DISPLAY_VERSION = 4.8.0 QTCREATOR_COPYRIGHT_YEAR = 2018 BINARY_ARTIFACTS_BRANCH = 4.8 diff --git a/share/qtcreator/cplusplus/examples/tidy_example.cpp b/share/qtcreator/cplusplus/examples/tidy_example.cpp index 2b41a1e83b0..dc921114ea1 100644 --- a/share/qtcreator/cplusplus/examples/tidy_example.cpp +++ b/share/qtcreator/cplusplus/examples/tidy_example.cpp @@ -203,8 +203,6 @@ public: virtual bool check(bool enable = true); }; -bool Derived2:: - // performance-unnecessary-value-param void use(Base b) { diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index a3b46a413e6..6cccd84fba7 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1083,6 +1083,7 @@ class Dumper(DumperBase): addr = frame.GetPCAddress().GetLoadAddress(self.target) functionName = frame.GetFunctionName() + module = frame.GetModule() if isNativeMixed and functionName == '::qt_qmlDebugMessageAvailable()': interpreterStack = self.extractInterpreterStack() @@ -1102,6 +1103,7 @@ class Dumper(DumperBase): result += ',address="0x%x"' % addr result += ',function="%s"' % functionName result += ',line="%d"' % lineNumber + result += ',module="%s"' % module result += ',file="%s"},' % fileName result += ']' result += ',hasmore="%d"' % isLimited @@ -1652,7 +1654,7 @@ class Dumper(DumperBase): def selectThread(self, args): self.reportToken(args) - self.process.SetSelectedThreadByID(args['id']) + self.process.SetSelectedThreadByID(int(args['id'])) self.reportResult('', args) def fetchFullBacktrace(self, _ = None): diff --git a/share/qtcreator/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme index ff7ec91561e..ef19fc9fa63 100644 --- a/share/qtcreator/themes/dark.creatortheme +++ b/share/qtcreator/themes/dark.creatortheme @@ -130,7 +130,7 @@ TreeViewArrowColorSelected=text OutputPanes_DebugTextColor=text OutputPanes_ErrorMessageTextColor=ffff6c6c OutputPanes_MessageOutput=ff008787 -OutputPanes_NormalMessageTextColor=text +OutputPanes_NormalMessageTextColor=ff008787 OutputPanes_StdErrTextColor=ffff6666 OutputPanes_StdOutTextColor=text OutputPanes_WarningMessageTextColor=fff3c300 diff --git a/share/qtcreator/themes/design.creatortheme b/share/qtcreator/themes/design.creatortheme index 60f074f328a..8db109f313f 100644 --- a/share/qtcreator/themes/design.creatortheme +++ b/share/qtcreator/themes/design.creatortheme @@ -190,7 +190,7 @@ TreeViewArrowColorSelected=text OutputPanes_DebugTextColor=text OutputPanes_ErrorMessageTextColor=ffff6c6c OutputPanes_MessageOutput=ff008787 -OutputPanes_NormalMessageTextColor=text +OutputPanes_NormalMessageTextColor=ff008787 OutputPanes_StdErrTextColor=ffff6666 OutputPanes_StdOutTextColor=text OutputPanes_WarningMessageTextColor=fff3c300 diff --git a/share/qtcreator/themes/flat-dark.creatortheme b/share/qtcreator/themes/flat-dark.creatortheme index 5a533b2d678..0c01aa17071 100644 --- a/share/qtcreator/themes/flat-dark.creatortheme +++ b/share/qtcreator/themes/flat-dark.creatortheme @@ -134,7 +134,7 @@ TreeViewArrowColorSelected=text OutputPanes_DebugTextColor=text OutputPanes_ErrorMessageTextColor=ffff6c6c OutputPanes_MessageOutput=ff008787 -OutputPanes_NormalMessageTextColor=text +OutputPanes_NormalMessageTextColor=ff008787 OutputPanes_StdErrTextColor=ffff6666 OutputPanes_StdOutTextColor=text OutputPanes_WarningMessageTextColor=fff3c300 diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 43ae2372c98..005d2e5dbe2 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -13790,25 +13790,25 @@ Soll es noch einmal versucht werden? Record Macro Makroaufnahme - - Ctrl+( - Ctrl+( - - - Alt+( - Alt+( - Stop Recording Macro Makroaufnahme anhalten - Ctrl+) - Ctrl+) + Ctrl+[ + Ctrl+[ - Alt+) - Alt+) + Alt+[ + Alt+[ + + + Ctrl+] + Ctrl+] + + + Alt+] + Alt+] Play Last Macro @@ -20476,20 +20476,6 @@ should a repository require SSH-authentication (see documentation on SSH and the Missing Android SDK packages Fehlende Android-SDK-Pakete - - Cannot create kits for all architectures. - Kits können nicht für alle Architekturen erstellt werden. - - - Qt versions are missing for the following architectures: -%1 - -To add the Qt version, select Options > Build & Run > Qt Versions. - Es fehlen Qt-Versionen für die folgenden Architekturen: -%1 - -Um die Qt-Versionen hinzuzufügen, benutzen Sie Einstellungen > Erstellung und Ausführung > Qt Versionen. - (SDK Version: %1, NDK Version: %2) (SDK-Version: %1, NDK-Version: %2) @@ -20498,15 +20484,8 @@ Um die Qt-Versionen hinzuzufügen, benutzen Sie Einstellungen > Erstellung un Android::Internal::AndroidToolChainFactory - Android GCC - Android GCC - - - - Android::Internal::AndroidToolChainConfigWidget - - NDK Root: - NDK Root: + Android Clang + Android Clang @@ -30364,8 +30343,8 @@ Der vom Kit mindestens benötigte API-Level ist %1. Android-Debugger für %1 - Android for %1 (GCC %2, %3) - Android für %1 (GCC %2, %3) + Android for %1 (Clang %2) + Android für %1 (Clang %2) @@ -46059,6 +46038,10 @@ Die Dateien aus dem Quellverzeichnis des Android-Pakets werden in das Verzeichni Unexpectedly finished. Restarting in %1 seconds. Unerwartet beendet. Neustart in %1 Sekunden. + + Unexpectedly finished. + Unerwartet beendet. + LanguageClient::BaseSettingsWidget diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp index f9ab96eb478..a153e6ac91f 100644 --- a/src/libs/utils/synchronousprocess.cpp +++ b/src/libs/utils/synchronousprocess.cpp @@ -455,7 +455,11 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary, // executable cannot be found in the path. Do not start the // event loop in that case. d->m_binary = binary; - d->m_process.start(binary, args, writeData.isEmpty() ? QIODevice::ReadOnly : QIODevice::ReadWrite); + // using QProcess::start() and passing program, args and OpenMode results in a different + // quoting of arguments than using QProcess::setArguments() beforehand and calling start() + // only with the OpenMode + d->m_process.setProgram(binary); + d->m_process.setArguments(args); connect(&d->m_process, &QProcess::started, this, [this, writeData] { if (!writeData.isEmpty()) { int pos = 0; @@ -469,6 +473,8 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary, } d->m_process.closeWriteChannel(); }); + d->m_process.start(writeData.isEmpty() ? QIODevice::ReadOnly : QIODevice::ReadWrite); + if (!d->m_startFailure) { d->m_timer.start(); if (isGuiThread()) diff --git a/src/libs/utils/tooltip/tips.cpp b/src/libs/utils/tooltip/tips.cpp index d38259518da..2dfbe277526 100644 --- a/src/libs/utils/tooltip/tips.cpp +++ b/src/libs/utils/tooltip/tips.cpp @@ -43,6 +43,8 @@ #include #include +#include + namespace Utils { namespace Internal { diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 1f52d9c2146..59ef8d110b0 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -364,7 +364,7 @@ void AndroidManager::setDeviceApiLevel(ProjectExplorer::Target *target, int leve QPair AndroidManager::apiLevelRange() { - return qMakePair(16, 27); + return qMakePair(16, 28); } QString AndroidManager::androidNameForApiLevel(int x) @@ -418,6 +418,8 @@ QString AndroidManager::androidNameForApiLevel(int x) return QLatin1String("Android 8.0"); case 27: return QLatin1String("Android 8.1"); + case 28: + return QLatin1String("Android 9"); default: return tr("Unknown Android version. API Level: %1").arg(QString::number(x)); } diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index 5ba4ac52b31..7bbe33d0878 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -252,8 +252,9 @@ bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, con if (!f.open(QIODevice::ReadOnly)) return false; runAdb({"shell", "run-as", m_packageName, "rm", to}); - auto res = runAdb({"shell", "run-as", m_packageName, "sh", "-c", QString("'cat > %1'").arg(to)}, - nullptr, f.readAll()); + const QByteArray data = f.readAll(); + const bool res = runAdb({"shell", "run-as", m_packageName, QString("sh -c 'base64 -d > %1'").arg(to)}, + nullptr, data.toBase64()); if (!res) return false; return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to}); diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp index 00f866d47e9..54d9837e2a6 100644 --- a/src/plugins/android/androidsdkmanager.cpp +++ b/src/plugins/android/androidsdkmanager.cpp @@ -261,6 +261,7 @@ public: SdkToolsMarker = 0x100, PlatformToolsMarker = 0x200, EmulatorToolsMarker = 0x400, + ExtrasMarker = 0x800, SectionMarkers = InstalledPackagesMarker | AvailablePackagesMarkers | AvailableUpdatesMarker }; @@ -280,6 +281,7 @@ private: SdkTools *parseSdkToolsPackage(const QStringList &data) const; PlatformTools *parsePlatformToolsPackage(const QStringList &data) const; EmulatorTools *parseEmulatorToolsPackage(const QStringList &data) const; + ExtraTools *parseExtraToolsPackage(const QStringList &data) const; MarkerTag parseMarkers(const QString &line); MarkerTag m_currentSection = MarkerTag::None; @@ -295,7 +297,8 @@ const std::map markerTags { {SdkManagerOutputParser::MarkerTag::BuildToolsMarker, "build-tools"}, {SdkManagerOutputParser::MarkerTag::SdkToolsMarker, "tools"}, {SdkManagerOutputParser::MarkerTag::PlatformToolsMarker, "platform-tools"}, - {SdkManagerOutputParser::MarkerTag::EmulatorToolsMarker, "emulator"} + {SdkManagerOutputParser::MarkerTag::EmulatorToolsMarker, "emulator"}, + {SdkManagerOutputParser::MarkerTag::ExtrasMarker, "extras"} }; AndroidSdkManager::AndroidSdkManager(const AndroidConfig &config, QObject *parent): @@ -562,6 +565,10 @@ void SdkManagerOutputParser::parsePackageData(MarkerTag packageMarker, const QSt } break; + case MarkerTag::ExtrasMarker: + createPackage(&SdkManagerOutputParser::parseExtraToolsPackage); + break; + default: qCDebug(sdkManagerLog) << "Unhandled package: " << markerTags.at(packageMarker); break; @@ -726,6 +733,22 @@ EmulatorTools *SdkManagerOutputParser::parseEmulatorToolsPackage(const QStringLi return emulatorTools; } +ExtraTools *SdkManagerOutputParser::parseExtraToolsPackage(const QStringList &data) const +{ + ExtraTools *extraTools = nullptr; + GenericPackageData packageData; + if (parseAbstractData(packageData, data, 1, "Extras")) { + extraTools = new ExtraTools(packageData.revision, data.at(0)); + extraTools->setDescriptionText(packageData.description); + extraTools->setDisplayText(packageData.description); + extraTools->setInstalledLocation(packageData.installedLocation); + } else { + qCDebug(sdkManagerLog) << "Extra-tools: Parsing failed. Minimum required data " + "unavailable:" << data; + } + return extraTools; +} + SdkManagerOutputParser::MarkerTag SdkManagerOutputParser::parseMarkers(const QString &line) { if (line.isEmpty()) diff --git a/src/plugins/android/androidsdkpackage.cpp b/src/plugins/android/androidsdkpackage.cpp index 7451fef7f00..64de3dcfce5 100644 --- a/src/plugins/android/androidsdkpackage.cpp +++ b/src/plugins/android/androidsdkpackage.cpp @@ -269,4 +269,19 @@ AndroidSdkPackage::PackageType EmulatorTools::type() const return AndroidSdkPackage::EmulatorToolsPackage; } +ExtraTools::ExtraTools(QVersionNumber revision, QString sdkStylePathStr, QObject *parent) : + AndroidSdkPackage(revision, sdkStylePathStr, parent) +{ +} + +bool ExtraTools::isValid() const +{ + return installedLocation().exists(); +} + +AndroidSdkPackage::PackageType ExtraTools::type() const +{ + return AndroidSdkPackage::ExtraToolsPackage; +} + } // namespace Android diff --git a/src/plugins/android/androidsdkpackage.h b/src/plugins/android/androidsdkpackage.h index 0a209c38bf6..09415bd19a6 100644 --- a/src/plugins/android/androidsdkpackage.h +++ b/src/plugins/android/androidsdkpackage.h @@ -53,8 +53,9 @@ public: SdkPlatformPackage = 1 << 4, SystemImagePackage = 1 << 5, EmulatorToolsPackage = 1 << 6, + ExtraToolsPackage = 1 << 7, AnyValidType = SdkToolsPackage | BuildToolsPackage | PlatformToolsPackage | - SdkPlatformPackage | SystemImagePackage | EmulatorToolsPackage + SdkPlatformPackage | SystemImagePackage | EmulatorToolsPackage | ExtraToolsPackage }; enum PackageState { @@ -191,6 +192,16 @@ public: bool isValid() const override; PackageType type() const override; }; + +class ExtraTools : public AndroidSdkPackage +{ +public: + ExtraTools(QVersionNumber revision, QString sdkStylePathStr, QObject *parent = nullptr); + +// AndroidSdkPackage Overrides + bool isValid() const override; + PackageType type() const override; +}; } // namespace Android diff --git a/src/plugins/autotest/autotestplugin.h b/src/plugins/autotest/autotestplugin.h index 97dbcc38d5f..dcbdb5ddde1 100644 --- a/src/plugins/autotest/autotestplugin.h +++ b/src/plugins/autotest/autotestplugin.h @@ -73,7 +73,6 @@ public: static void clearChoiceCache(); private: - bool checkLicense(); void initializeMenuEntries(); void onRunAllTriggered(); void onRunSelectedTriggered(); diff --git a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp index 194d944cf5f..ad48a60685b 100644 --- a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp +++ b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp @@ -157,6 +157,7 @@ void ClangCompletionContextAnalyzer::handleFunctionCall(int afterOperatorPositio setActionAndClangPosition(CompleteSlot, afterOperatorPosition); } else if (m_interface->position() != afterOperatorPosition) { // No function completion if cursor is not after '(' or ',' + m_addSnippets = true; m_positionForProposal = afterOperatorPosition; setActionAndClangPosition(PassThroughToLibClang, afterOperatorPosition); } else { diff --git a/src/plugins/clangformat/clangformat.pro b/src/plugins/clangformat/clangformat.pro index 70eefe17f46..345340f9e6c 100644 --- a/src/plugins/clangformat/clangformat.pro +++ b/src/plugins/clangformat/clangformat.pro @@ -13,7 +13,9 @@ win32 { LIBS += $$CLANGFORMAT_LIBS INCLUDEPATH += $$LLVM_INCLUDEPATH -QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS +QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS +QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS +unix:!macos:QMAKE_LFLAGS += -Wl,--exclude-libs,ALL SOURCES = \ clangformatconfigwidget.cpp \ diff --git a/src/plugins/clangformat/clangformat.qbs b/src/plugins/clangformat/clangformat.qbs index 66e481785e5..abb81d46473 100644 --- a/src/plugins/clangformat/clangformat.qbs +++ b/src/plugins/clangformat/clangformat.qbs @@ -17,6 +17,7 @@ QtcPlugin { condition: libclang.present && (!qbs.targetOS.contains("windows") || libclang.llvmBuildModeMatches) + cpp.cxxFlags: base.concat(libclang.llvmToolingCxxFlags) cpp.defines: base.concat("CLANGPCHMANAGER_LIB") cpp.includePaths: base.concat(libclang.llvmIncludeDir) cpp.libraryPaths: base.concat(libclang.llvmLibDir) diff --git a/src/plugins/clangformat/clangformatindenter.cpp b/src/plugins/clangformat/clangformatindenter.cpp index 718d4526353..18a79889c10 100644 --- a/src/plugins/clangformat/clangformatindenter.cpp +++ b/src/plugins/clangformat/clangformatindenter.cpp @@ -69,6 +69,13 @@ void adjustFormatStyleForLineBreak(format::FormatStyle &style) style.SortUsingDeclarations = false; } +StringRef clearExtraNewline(StringRef text) +{ + while (text.startswith("\n\n")) + text = text.drop_front(); + return text; +} + Replacements filteredReplacements(const Replacements &replacements, int offset, int extraOffsetToAdd, @@ -83,10 +90,13 @@ Replacements filteredReplacements(const Replacements &replacements, if (replacementOffset + 1 >= offset) replacementOffset += extraOffsetToAdd; + StringRef text = onlyIndention ? clearExtraNewline(replacement.getReplacementText()) + : replacement.getReplacementText(); + Error error = filtered.add(Replacement(replacement.getFilePath(), static_cast(replacementOffset), replacement.getLength(), - replacement.getReplacementText())); + text)); // Throws if error is not checked. if (error) break; @@ -123,6 +133,18 @@ void trimFirstNonEmptyBlock(const QTextBlock ¤tBlock) cursor.endEditBlock(); } +void trimCurrentBlock(const QTextBlock ¤tBlock) +{ + if (currentBlock.text().trimmed().isEmpty()) { + // Clear the block containing only spaces + QTextCursor cursor(currentBlock); + cursor.beginEditBlock(); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + cursor.removeSelectedText(); + cursor.endEditBlock(); + } +} + // Returns the total langth of previous lines with pure whitespace. int previousEmptyLinesLength(const QTextBlock ¤tBlock) { @@ -335,10 +357,19 @@ void ClangFormatIndenter::indent(QTextDocument *doc, bool /*autoTriggered*/) { if (cursor.hasSelection()) { - QTextBlock currentBlock = doc->findBlock(cursor.selectionStart()); - while (currentBlock.isValid() && currentBlock.position() < cursor.selectionEnd()) { - indentBlock(doc, currentBlock, typedChar, tabSettings); - currentBlock = currentBlock.next(); + // Calling currentBlock.next() might be unsafe because we change the document. + // Let's operate with block numbers instead. + const int startNumber = doc->findBlock(cursor.selectionStart()).blockNumber(); + const int endNumber = doc->findBlock(cursor.selectionEnd()).blockNumber(); + for (int currentBlockNumber = startNumber; currentBlockNumber <= endNumber; + ++currentBlockNumber) { + const QTextBlock currentBlock = doc->findBlockByNumber(currentBlockNumber); + if (currentBlock.isValid()) { + const int blocksAmount = doc->blockCount(); + indentBlock(doc, currentBlock, typedChar, tabSettings); + QTC_CHECK(blocksAmount == doc->blockCount() + && "ClangFormat plugin indentation changed the amount of blocks."); + } } } else { indentBlock(doc, cursor.block(), typedChar, tabSettings); @@ -399,6 +430,7 @@ void ClangFormatIndenter::indentBlock(QTextDocument *doc, const Utils::FileName fileName = editor->textDocument()->filePath(); trimFirstNonEmptyBlock(block); + trimCurrentBlock(block); const QByteArray buffer = doc->toPlainText().toUtf8(); const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); QTC_ASSERT(utf8Offset >= 0, return;); @@ -417,6 +449,7 @@ int ClangFormatIndenter::indentFor(const QTextBlock &block, const TextEditor::Ta const Utils::FileName fileName = editor->textDocument()->filePath(); trimFirstNonEmptyBlock(block); + trimCurrentBlock(block); const QTextDocument *doc = block.document(); const QByteArray buffer = doc->toPlainText().toUtf8(); const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); diff --git a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp index e181471f66d..f1e00802c70 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp @@ -177,8 +177,10 @@ void DiagnosticView::setModel(QAbstractItemModel *model) m_ignoreSetSelectedFixItsCount = false; }); setHeader(clickableFixItHeader); - header()->setStretchLastSection(false); - header()->setSectionResizeMode(0, QHeaderView::Stretch); + clickableFixItHeader->setStretchLastSection(false); + clickableFixItHeader->setSectionResizeMode(0, QHeaderView::Stretch); + clickableFixItHeader->setSectionResizeMode(1, QHeaderView::ResizeToContents); + clickableFixItHeader->setSectionResizeMode(2, QHeaderView::ResizeToContents); } } // namespace Internal diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp index d5bfa510203..daf7ebf762f 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp +++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp @@ -136,7 +136,7 @@ CppTools::CheckSymbols *createHighlighter(const CPlusPlus::Document::Ptr &doc, int line, column; convertPosition(textDocument, macro.utf16charsBegin(), &line, &column); - ++column; //Highlighting starts at (column-1) --> compensate here + Result use(line, column, name.size(), SemanticHighlighter::MacroUse); macroUses.append(use); } diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index e3f2be6c83a..1529cb445fa 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -235,14 +235,15 @@ static int lastIncludeIndex(const QStringList &options, const QRegularExpression static int includeIndexForResourceDirectory(const QStringList &options, bool isMacOs = false) { - // include/c++/{version}, include/c++/v1 and include/g++ - static const QRegularExpression includeRegExp( - R"(\A.*[\/\\]include[\/\\].*(g\+\+.*\z|c\+\+[\/\\](v1\z|\d+.*\z)))"); + // include/c++, include/g++, libc++\include and libc++abi\include + static const QString cppIncludes = R"((.*[\/\\]include[\/\\].*(g\+\+|c\+\+).*))" + R"(|(.*libc\+\+[\/\\]include))" + R"(|(.*libc\+\+abi[\/\\]include))"; + static const QRegularExpression includeRegExp("\\A(" + cppIncludes + ")\\z"); // The same as includeRegExp but also matches /usr/local/include static const QRegularExpression includeRegExpMac( - R"(\A(.*[\/\\]include[\/\\].*(g\+\+.*\z|c\+\+[\/\\](v1\z|\d+.*\z))))" - R"(|([\/\\]usr[\/\\]local[\/\\]include\z))"); + "\\A(" + cppIncludes + R"(|([\/\\]usr[\/\\]local[\/\\]include))" + ")\\z"); const int cppIncludeIndex = lastIncludeIndex(options, isMacOs ? includeRegExpMac diff --git a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp index a66c357986b..9633bfb6dd0 100644 --- a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp @@ -491,10 +491,13 @@ void FollowSymbolUnderCursor::findLink( { Link link; - int line = 0; - int column = 0; QTextCursor cursor = data.cursor(); QTextDocument *document = cursor.document(); + if (!document) + return processLinkCallback(link); + + int line = 0; + int column = 0; Utils::Text::convertPosition(document, cursor.position(), &line, &column); const int positionInBlock = column - 1; diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 2884f6e87e9..a68ba45c3ec 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -384,7 +384,12 @@ void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective) if (m_currentPerspective) m_currentPerspective->d->restoreLayout(); - const int index = indexInChooser(m_currentPerspective); + int index = indexInChooser(m_currentPerspective); + if (index == -1) { + if (Perspective *parent = Perspective::findPerspective(m_currentPerspective->d->m_parentPerspectiveId)) + index = indexInChooser(parent); + } + if (index != -1) { m_perspectiveChooser->setCurrentIndex(index); diff --git a/src/plugins/debugger/threadshandler.cpp b/src/plugins/debugger/threadshandler.cpp index de58f7b6155..017e1839623 100644 --- a/src/plugins/debugger/threadshandler.cpp +++ b/src/plugins/debugger/threadshandler.cpp @@ -408,6 +408,11 @@ void ThreadsHandler::setThreads(const GdbMi &data) if (!m_currentThread && threads.childCount() > 0) m_currentThread = rootItem()->childAt(0); + + if (!m_currentThread) { + const QModelIndex currentThreadIndex = m_currentThread->index(); + threadSwitcher()->setCurrentIndex(currentThreadIndex.row()); + } } QAbstractItemModel *ThreadsHandler::model() diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index f0469b9c472..10102a794f1 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -396,27 +396,28 @@ ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() con } else if (a == "-arch") { if (++iArg < allFlags.length() && !arguments.contains(a)) arguments << a << allFlags.at(iArg); - } else if (a == "--sysroot" || a == "-isysroot" || a == "-D" ||a == "-U") { + } else if (a == "--sysroot" || a == "-isysroot" || a == "-D" || a == "-U" + || a == "-gcc-toolchain" || a == "-target") { if (++iArg < allFlags.length()) arguments << a << allFlags.at(iArg); - } else if (a == "-m128bit-long-double" || a == "-m32" || a == "-m3dnow" || a == "-m3dnowa" - || a == "-m64" || a == "-m96bit-long-double" || a == "-mabm" || a == "-maes" - || a.startsWith("-march=") || a == "-mavx" || a.startsWith("-masm=") - || a.startsWith("-mfloat-abi") - || a == "-mcx16" || a == "-mfma" || a == "-mfma4" || a == "-mlwp" - || a == "-mpclmul" || a == "-mpopcnt" || a == "-msse" || a == "-msse2" - || a == "-msse2avx" || a == "-msse3" || a == "-msse4" || a == "-msse4.1" - || a == "-msse4.2" || a == "-msse4a" || a == "-mssse3" - || a.startsWith("-mtune=") || a == "-mxop" - || a == "-Os" || a == "-O0" || a == "-O1" || a == "-O2" || a == "-O3" - || a == "-ffinite-math-only" || a == "-fshort-double" || a == "-fshort-wchar" - || a == "-fsignaling-nans" || a == "-fno-inline" || a == "-fno-exceptions" - || a == "-fstack-protector" || a == "-fstack-protector-all" - || a == "-fsanitize=address" || a == "-fno-rtti" - || a.startsWith("-std=") || a.startsWith("-stdlib=") || a.startsWith("-specs=") - || a == "-ansi" || a == "-undef" || a.startsWith("-D") || a.startsWith("-U") - || a == "-fopenmp" || a == "-Wno-deprecated" || a == "-fPIC" || a == "-fpic" - || a == "-fPIE" || a == "-fpie") + } else if (a == "-m128bit-long-double" || a == "-m32" || a == "-m3dnow" + || a == "-m3dnowa" || a == "-m64" || a == "-m96bit-long-double" + || a == "-mabm" || a == "-maes" || a.startsWith("-march=") || a == "-mavx" + || a.startsWith("-masm=") || a.startsWith("-mfloat-abi") || a == "-mcx16" + || a == "-mfma" || a == "-mfma4" || a == "-mlwp" || a == "-mpclmul" + || a == "-mpopcnt" || a == "-msse" || a == "-msse2" || a == "-msse2avx" + || a == "-msse3" || a == "-msse4" || a == "-msse4.1" || a == "-msse4.2" + || a == "-msse4a" || a == "-mssse3" || a.startsWith("-mtune=") + || a == "-mxop" || a == "-Os" || a == "-O0" || a == "-O1" || a == "-O2" + || a == "-O3" || a == "-ffinite-math-only" || a == "-fshort-double" + || a == "-fshort-wchar" || a == "-fsignaling-nans" || a == "-fno-inline" + || a == "-fno-exceptions" || a == "-fstack-protector" + || a == "-fstack-protector-all" || a == "-fsanitize=address" + || a == "-fno-rtti" || a.startsWith("-std=") || a.startsWith("-stdlib=") + || a.startsWith("-specs=") || a == "-ansi" || a == "-undef" + || a.startsWith("-D") || a.startsWith("-U") || a == "-fopenmp" + || a == "-Wno-deprecated" || a == "-fPIC" || a == "-fpic" || a == "-fPIE" + || a == "-fpie") arguments << a; } @@ -545,13 +546,14 @@ QStringList GccToolChain::gccPrepareArguments(const QStringList &flags, for (int i = 0; i < allFlags.size(); ++i) { const QString &flag = allFlags.at(i); if (flag.startsWith("-stdlib=") || flag.startsWith("--gcctoolchain=") - || flag.startsWith("-B")) { + || flag.startsWith("-B") || (flag.startsWith("-isystem") && flag.length() > 8)) { arguments << flag; } else if (!hasKitSysroot) { // pass build system's sysroot to compiler, if we didn't pass one from kit if (flag.startsWith("--sysroot=")) { arguments << flag; - } else if ((flag.startsWith("-isysroot") || flag.startsWith("--sysroot")) + } else if ((flag.startsWith("-isysroot") || flag.startsWith("--sysroot") + || flag == "-target" || flag == "-gcc-toolchain" || flag == "-isystem") && i < flags.size() - 1) { arguments << flag << allFlags.at(i + 1); ++i; diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp index a7ac388487b..dcdf1554c81 100644 --- a/src/plugins/projectexplorer/taskmodel.cpp +++ b/src/plugins/projectexplorer/taskmodel.cpp @@ -437,12 +437,12 @@ void TaskFilterModel::handleRowsAboutToBeRemoved(const QModelIndex &index, int f QTC_ASSERT(!index.isValid(), return); const QPair range = findFilteredRange(first, last, m_mapping); - if (range.first > range.second) // rows to be removed are filtered out - return; - - beginRemoveRows(QModelIndex(), range.first, range.second); - m_beginRemoveRowsSent = true; - m_mapping.erase(m_mapping.begin() + range.first, m_mapping.begin() + range.second + 1); + if (range.first <= range.second) { // remove corresponding rows in filtermodel + beginRemoveRows(QModelIndex(), range.first, range.second); + m_beginRemoveRowsSent = true; + m_mapping.erase(m_mapping.begin() + range.first, m_mapping.begin() + range.second + 1); + } + // adapt existing mapping to removed source indices const int sourceRemovedCount = (last - first) + 1; for (int i = range.first; i < m_mapping.count(); ++i) m_mapping[i] = m_mapping.at(i) - sourceRemovedCount; diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index a3f875726ec..90e9ec147fc 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -289,7 +289,12 @@ bool ToolChain::fromMap(const QVariantMap &data) static long toLanguageVersionAsLong(QByteArray dateAsByteArray) { dateAsByteArray.chop(1); // Strip 'L'. - return dateAsByteArray.toLong(nullptr); + + bool success = false; + const int result = dateAsByteArray.toLong(&success); + QTC_CHECK(success); + + return result; } LanguageVersion ToolChain::cxxLanguageVersion(const QByteArray &cplusplusMacroValue) diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index ad7cf13efc0..745fdc4d00b 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -63,8 +63,7 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant timelineFrames.setValue(value, frame); return; - } else if (timelineIsActive()) { - + } else if (modelNode().hasId() && timelineIsActive()) { QmlTimelineKeyframeGroup timelineFrames(currentTimeline().keyframeGroup(modelNode(), name)); Q_ASSERT(timelineFrames.isValid()); diff --git a/src/plugins/qmljstools/QmlJSTools.json.in b/src/plugins/qmljstools/QmlJSTools.json.in index 0a1d9945806..0902c0ec9ef 100644 --- a/src/plugins/qmljstools/QmlJSTools.json.in +++ b/src/plugins/qmljstools/QmlJSTools.json.in @@ -57,6 +57,11 @@ \" JSON file\", \" \", \" \", + \" \", + \" \", + \" Javascript module\", + \" \", + \" \", \"\" ] } diff --git a/src/plugins/qtsupport/qtcreator_tutorials.xml b/src/plugins/qtsupport/qtcreator_tutorials.xml index 9725c952a96..5984aeeeceb 100644 --- a/src/plugins/qtsupport/qtcreator_tutorials.xml +++ b/src/plugins/qtsupport/qtcreator_tutorials.xml @@ -1,40 +1,40 @@ - + qt creator,build,compile,help - + qt creator,qt designer,widgets,c++,text,help - + qt,qt creator,qt designer,widgets,c++,help - + qt creator,qt quick designer,qt quick,qml,states,transitions,help - + qt creator,qt quick designer,qml,android,ios,controls,help - + qt quick,qml,c++,help - + qt creator,qt quick,automotive,safe renderer,controls,video - + qt creator,embedded,device creation,video - + qt creator,embedded,device creation,video @@ -50,23 +50,23 @@ qt creator,qt quick,video - + qt creator,SCXML,video - + qt creator,qt quick,c++,video - + qt creator,video - + qt creator,video - + qt creator,qt quick,video @@ -74,20 +74,20 @@ qt creator,qt quick,qml,video - + qt creator,qt quick,controls,video - + qt creator,talk,2015 - + qt creator,wizard,talk,2015 - + qt creator,configuration,talk,2013 @@ -95,48 +95,48 @@ qt creator,plugins,talk,2013 - + qt quick,qt creator,qml profiler,talk,2014 - + qt creator,cpu usage analyzer,perf,embedded,device creation,talk,2015 - + qt creator,scxml,talk,2016 - + qt creator,qbs,qemu,talk,2015 - + qt creator,android,talk,2016 - + qt creator,ios,talk,2016 - + qt creator,baremetal,talk,2013 - + uwp,talk,2016 - + ui,qt quick designer,controls,ui,talk,2016 - + qt quick,ui,widgets,talk,2016 - + qt creator,android,talk,2016 @@ -144,40 +144,40 @@ macos,talk,2016 - + qt,qt quick,screen resolution,ui,talk,2016 - + android,ios,talk,2017 - + medical,ui,talk,2017 - + android,ios,talk,2017 - + automotive,application manager,talk,2017 - + embedded,virtual keyboard,talk,2017 - + android,ios,qt quick,controls,talk,2017 - + automotive,ivi,talk,2017 - + talk,2017 diff --git a/src/plugins/texteditor/basehoverhandler.cpp b/src/plugins/texteditor/basehoverhandler.cpp index 3b5edef2ee4..1be518a5cad 100644 --- a/src/plugins/texteditor/basehoverhandler.cpp +++ b/src/plugins/texteditor/basehoverhandler.cpp @@ -76,10 +76,14 @@ void BaseHoverHandler::contextHelpId(TextEditorWidget *widget, { // If the tooltip is visible and there is a help match, this match is used to update // the help id. Otherwise, let the identification process happen. - if (!Utils::ToolTip::isVisible() || !lastHelpItemIdentified().isValid()) - process(widget, pos, [this, widget, callback](int) { propagateHelpId(widget, callback); }); - else + if (!Utils::ToolTip::isVisible() || !lastHelpItemIdentified().isValid()) { + process(widget, pos, [this, widget = QPointer(widget), callback](int) { + if (widget) + propagateHelpId(widget, callback); + }); + } else { propagateHelpId(widget, callback); + } } void BaseHoverHandler::setToolTip(const QString &tooltip) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index c720e196a07..37c2f342483 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -299,6 +299,8 @@ public: { } + ~HoverHandlerRunner() { abortHandlers(); } + void startChecking(const QTextCursor &textCursor, const QPoint &point) { if (m_handlers.empty()) @@ -315,9 +317,7 @@ public: if (isCheckRunning(documentRevision, position)) return; - // Cancel currently running checks - for (BaseHoverHandler *handler : m_handlers) - handler->abort(); + abortHandlers(); // Update invocation data m_documentRevision = documentRevision; @@ -352,8 +352,6 @@ public: void onHandlerFinished(int documentRevision, int position, int priority) { - if (!m_widget) - return; QTC_ASSERT(m_currentHandlerIndex < m_handlers.size(), return); QTC_ASSERT(documentRevision == m_documentRevision, return); QTC_ASSERT(position == m_position, return); @@ -379,7 +377,13 @@ public: } private: - QPointer m_widget; + void abortHandlers() + { + for (BaseHoverHandler *handler : m_handlers) + handler->abort(); + } + + TextEditorWidget *m_widget; const QList &m_handlers; struct LastHandlerInfo { @@ -3025,14 +3029,6 @@ void TextEditorWidget::contextMenuEvent(QContextMenuEvent *e) void TextEditorWidget::inputMethodEvent(QInputMethodEvent *e) { - if (e->commitString().isEmpty() && e->preeditString().isEmpty() && e->attributes().isEmpty()) { - // Avoid doing anything when getting bogus events as it can happen on Gnome desktop. - // Otherwise QPlainTextEdit will report content changes for locations where factually - // nothing changed. - // Workaround for QTCREATORBUG-19571 - e->accept(); - return; - } if (d->m_inBlockSelectionMode) { if (!e->commitString().isEmpty()) d->insertIntoBlockSelection(e->commitString()); diff --git a/src/shared/clang/clang_installation.pri b/src/shared/clang/clang_installation.pri index 3f4b4fde7c4..5ea21874fbb 100644 --- a/src/shared/clang/clang_installation.pri +++ b/src/shared/clang/clang_installation.pri @@ -111,6 +111,17 @@ defineReplace(splitFlags) { return($$result) } +defineReplace(extractWarnings) { + flags = $$1 + result = + for (flag, flags) { + contains(flag, ^[-/][wW].*$) { + result += $$flag + } + } + return($$result) +} + CLANGTOOLING_LIBS=-lclangTooling -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \ -lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \ -lclangASTMatchers -lclangToolingCore -lclangAST -lclangLex -lclangBasic @@ -230,6 +241,9 @@ isEmpty(LLVM_VERSION) { LLVM_CXXFLAGS ~= s,-Wcovered-switch-default, LLVM_CXXFLAGS ~= s,-Wnon-virtual-dtor, LLVM_CXXFLAGS ~= s,-Woverloaded-virtual, + LLVM_CXXFLAGS ~= s,-Wmissing-field-initializers, + LLVM_CXXFLAGS ~= s,-Wno-unknown-warning, + LLVM_CXXFLAGS ~= s,-Wno-unused-command-line-argument, LLVM_CXXFLAGS ~= s,-fPIC, LLVM_CXXFLAGS ~= s,-pedantic, LLVM_CXXFLAGS ~= s,-Wstring-conversion, @@ -238,6 +252,9 @@ isEmpty(LLVM_VERSION) { LLVM_CXXFLAGS = $$splitFlags($$LLVM_CXXFLAGS) + LLVM_CXXFLAGS_WARNINGS = $$extractWarnings($$LLVM_CXXFLAGS) + LLVM_CXXFLAGS -= $$LLVM_CXXFLAGS_WARNINGS + LLVM_IS_COMPILED_WITH_RTTI = $$system($$llvm_config --has-rtti, lines) unix:!disable_external_rpath:!contains(QMAKE_DEFAULT_LIBDIRS, $${LLVM_LIBDIR}) { diff --git a/src/shared/proparser/qmakevfs.cpp b/src/shared/proparser/qmakevfs.cpp index f438978badc..4b0cb7df037 100644 --- a/src/shared/proparser/qmakevfs.cpp +++ b/src/shared/proparser/qmakevfs.cpp @@ -106,10 +106,10 @@ int QMakeVfs::idForFileName(const QString &fn, VfsFlags flags) return id; } #endif - if (!(flags & VfsAccessedOnly)) { #ifdef PROPARSER_THREAD_SAFE - QMutexLocker locker(&s_mutex); + QMutexLocker locker(&s_mutex); #endif + if (!(flags & VfsAccessedOnly)) { int &id = s_fileIdMap[fn]; if (!id) { id = ++s_fileIdCounter; diff --git a/src/tools/clangbackend/clangbackendmain.cpp b/src/tools/clangbackend/clangbackendmain.cpp index d165ebb6dd3..efe5970a4d8 100644 --- a/src/tools/clangbackend/clangbackendmain.cpp +++ b/src/tools/clangbackend/clangbackendmain.cpp @@ -80,7 +80,9 @@ int main(int argc, char *argv[]) const QString connection = processArguments(application); - clang_enableStackTraces(); + // Printing the stack strace might dead lock as clang's stack printer allocates memory. + if (qEnvironmentVariableIntValue("QTC_CLANG_ENABLE_STACKTRACES")) + clang_enableStackTraces(); ClangCodeModelServer clangCodeModelServer; ConnectionServer connectionServer; diff --git a/src/tools/clangbackend/source/tokeninfo.cpp b/src/tools/clangbackend/source/tokeninfo.cpp index dcd631eff82..b7e40d0327b 100644 --- a/src/tools/clangbackend/source/tokeninfo.cpp +++ b/src/tools/clangbackend/source/tokeninfo.cpp @@ -548,9 +548,6 @@ void TokenInfo::punctuationOrOperatorKind() // case CXCursor_CXXDeleteExpr: overloadedOperatorKind(); break; - case CXCursor_Constructor: - collectOutputArguments(m_originalCursor); - break; case CXCursor_UnaryOperator: case CXCursor_BinaryOperator: case CXCursor_CompoundAssignOperator: diff --git a/src/tools/clangbackend/source/unsavedfile.cpp b/src/tools/clangbackend/source/unsavedfile.cpp index efcad4cad47..25925ea3089 100644 --- a/src/tools/clangbackend/source/unsavedfile.cpp +++ b/src/tools/clangbackend/source/unsavedfile.cpp @@ -83,7 +83,8 @@ bool UnsavedFile::hasCharacterAt(uint line, uint column, char character) const Utf8String UnsavedFile::lineRange(uint fromLine, uint toLine) const { - QTC_ASSERT(fromLine <= toLine, return Utf8String()); + if (fromLine > toLine) + return Utf8String(); // Find start of first line bool ok = false; diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro b/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro index dd2592e5ac4..0997b0ec961 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro @@ -18,7 +18,8 @@ QT -= gui LIBS += $$LIBTOOLING_LIBS INCLUDEPATH += $$LLVM_INCLUDEPATH -QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS +QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS +QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS INCLUDEPATH += ../clangrefactoringbackend/source diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp index c3146408f85..7f97599facb 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp @@ -29,6 +29,8 @@ #include "modifiedtimecheckerinterface.h" #include "builddependencygeneratorinterface.h" +#include + #include namespace ClangBackEnd { @@ -51,19 +53,25 @@ OutputContainer setUnion(InputContainer1 &&input1, return results; } -BuildDependency BuildDependenciesProvider::create(const V2::ProjectPartContainer &projectPart) const +BuildDependency BuildDependenciesProvider::create(const V2::ProjectPartContainer &projectPart) { SourceEntries includes = createSourceEntriesFromStorage(projectPart.sourcePathIds, projectPart.projectPartId); - if (!m_modifiedTimeChecker.isUpToDate(includes)) - return m_buildDependenciesGenerator.create(projectPart); + if (!m_modifiedTimeChecker.isUpToDate(includes)) { + BuildDependency buildDependency = m_generator.create(projectPart); + + storeBuildDependency(buildDependency); + + return buildDependency; + } return createBuildDependencyFromStorage(std::move(includes)); } -BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(SourceEntries &&includes) const +BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage( + SourceEntries &&includes) const { BuildDependency buildDependency; @@ -78,14 +86,18 @@ UsedMacros BuildDependenciesProvider::createUsedMacrosFromStorage(const SourceEn UsedMacros usedMacros; usedMacros.reserve(1024); + Sqlite::DeferredTransaction transaction(m_transactionBackend); + for (const SourceEntry &entry : includes) { - UsedMacros macros = m_buildDependenciesStorage.fetchUsedMacros(entry.sourceId); + UsedMacros macros = m_storage.fetchUsedMacros(entry.sourceId); std::sort(macros.begin(), macros.end()); usedMacros.insert(usedMacros.end(), std::make_move_iterator(macros.begin()), std::make_move_iterator(macros.end())); } + transaction.commit(); + return usedMacros; } @@ -94,15 +106,31 @@ SourceEntries BuildDependenciesProvider::createSourceEntriesFromStorage( { SourceEntries includes; + Sqlite::DeferredTransaction transaction(m_transactionBackend); + for (FilePathId sourcePathId : sourcePathIds) { - SourceEntries entries = m_buildDependenciesStorage.fetchDependSources(sourcePathId, + SourceEntries entries = m_storage.fetchDependSources(sourcePathId, projectPartId); SourceEntries mergedEntries = setUnion(includes, entries); includes = std::move(mergedEntries); } + transaction.commit(); + return includes; } +void BuildDependenciesProvider::storeBuildDependency(const BuildDependency &buildDependency) +{ + Sqlite::ImmediateTransaction transaction(m_transactionBackend); + + m_storage.updateSources(buildDependency.includes); + m_storage.insertFileStatuses(buildDependency.fileStatuses); + m_storage.insertOrUpdateSourceDependencies(buildDependency.sourceDependencies); + m_storage.insertOrUpdateUsedMacros(buildDependency.usedMacros); + + transaction.commit(); +} + } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h index 8c22077e816..386eca587ed 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h @@ -27,6 +27,10 @@ #include "builddependenciesproviderinterface.h" +namespace Sqlite { +class TransactionInterface; +} + namespace ClangBackEnd { class BuildDependenciesStorageInterface; @@ -38,25 +42,28 @@ class BuildDependenciesProvider : public BuildDependenciesProviderInterface public: BuildDependenciesProvider(BuildDependenciesStorageInterface &buildDependenciesStorage, ModifiedTimeCheckerInterface &modifiedTimeChecker, - BuildDependencyGeneratorInterface &buildDependenciesGenerator) - : m_buildDependenciesStorage(buildDependenciesStorage), - m_modifiedTimeChecker(modifiedTimeChecker), - m_buildDependenciesGenerator(buildDependenciesGenerator) - { - } + BuildDependencyGeneratorInterface &buildDependenciesGenerator, + Sqlite::TransactionInterface &transactionBackend) + : m_storage(buildDependenciesStorage) + , m_modifiedTimeChecker(modifiedTimeChecker) + , m_generator(buildDependenciesGenerator) + , m_transactionBackend(transactionBackend) + {} - BuildDependency create(const V2::ProjectPartContainer &projectPart) const override; + BuildDependency create(const V2::ProjectPartContainer &projectPart) override; private: BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const; UsedMacros createUsedMacrosFromStorage(const SourceEntries &includes) const; SourceEntries createSourceEntriesFromStorage(const FilePathIds &sourcePathIds, Utils::SmallStringView projectPartId) const; + void storeBuildDependency(const BuildDependency &buildDependency); private: - BuildDependenciesStorageInterface &m_buildDependenciesStorage; + BuildDependenciesStorageInterface &m_storage; ModifiedTimeCheckerInterface &m_modifiedTimeChecker; - BuildDependencyGeneratorInterface &m_buildDependenciesGenerator; + BuildDependencyGeneratorInterface &m_generator; + Sqlite::TransactionInterface &m_transactionBackend; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h index f596b83da9b..0bfaeed06cd 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h @@ -34,7 +34,7 @@ namespace ClangBackEnd { class BuildDependenciesProviderInterface { public: - virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) const = 0; + virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0; protected: ~BuildDependenciesProviderInterface() = default; diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h index ecb2d7cc7dc..f894ed8ecd0 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h @@ -47,25 +47,25 @@ class BuildDependenciesStorage final : public BuildDependenciesStorageInterface using WriteStatement = typename Database::WriteStatement; public: BuildDependenciesStorage(Database &database) - : m_transaction(database), - m_database(database) + : transaction(database), + database(database) { - m_transaction.commit(); + transaction.commit(); } void updateSources(const SourceEntries &sourceEntries) override { for (const SourceEntry &entry : sourceEntries) { - m_updateBuildDependencyTimeStampStatement.write(static_cast(entry.lastModified), + updateBuildDependencyTimeStampStatement.write(static_cast(entry.lastModified), entry.sourceId.filePathId); - m_updateSourceTypeStatement.write(static_cast(entry.sourceType), + updateSourceTypeStatement.write(static_cast(entry.sourceType), entry.sourceId.filePathId); } } void insertFileStatuses(const FileStatuses &fileStatuses) override { - WriteStatement &statement = m_insertFileStatusesStatement; + WriteStatement &statement = insertFileStatusesStatement; for (const FileStatus &fileStatus : fileStatuses) statement.write(fileStatus.filePathId.filePathId, @@ -76,41 +76,41 @@ public: long long fetchLowestLastModifiedTime(FilePathId sourceId) const override { - ReadStatement &statement = m_getLowestLastModifiedTimeOfDependencies; + ReadStatement &statement = getLowestLastModifiedTimeOfDependencies; return statement.template value(sourceId.filePathId).value_or(0); } void insertOrUpdateUsedMacros(const UsedMacros &usedMacros) override { - WriteStatement &insertStatement = m_insertIntoNewUsedMacrosStatement; + WriteStatement &insertStatement = insertIntoNewUsedMacrosStatement; for (const UsedMacro &usedMacro : usedMacros) insertStatement.write(usedMacro.filePathId.filePathId, usedMacro.macroName); - m_syncNewUsedMacrosStatement.execute(); - m_deleteOutdatedUsedMacrosStatement.execute(); - m_deleteNewUsedMacrosTableStatement.execute(); + syncNewUsedMacrosStatement.execute(); + deleteOutdatedUsedMacrosStatement.execute(); + deleteNewUsedMacrosTableStatement.execute(); } void insertOrUpdateSourceDependencies(const SourceDependencies &sourceDependencies) override { - WriteStatement &insertStatement = m_insertIntoNewSourceDependenciesStatement; + WriteStatement &insertStatement = insertIntoNewSourceDependenciesStatement; for (SourceDependency sourceDependency : sourceDependencies) insertStatement.write(sourceDependency.filePathId.filePathId, sourceDependency.dependencyFilePathId.filePathId); - m_syncNewSourceDependenciesStatement.execute(); - m_deleteOutdatedSourceDependenciesStatement.execute(); - m_deleteNewSourceDependenciesStatement.execute(); + syncNewSourceDependenciesStatement.execute(); + deleteOutdatedSourceDependenciesStatement.execute(); + deleteNewSourceDependenciesStatement.execute(); } SourceEntries fetchDependSources(FilePathId sourceId, Utils::SmallStringView projectPartName) const override { - auto projectPartId = m_fetchProjectPartIdStatement.template value(projectPartName); + auto projectPartId = fetchProjectPartIdStatement.template value(projectPartName); if (projectPartId) { - return m_fetchSourceDependenciesStatement.template values( + return fetchSourceDependenciesStatement.template values( 300, sourceId.filePathId, projectPartId.value()); @@ -120,7 +120,7 @@ public: UsedMacros fetchUsedMacros(FilePathId sourceId) const override { - return m_fetchUsedMacrosStatement.template values(128, sourceId.filePathId); + return fetchUsedMacrosStatement.template values(128, sourceId.filePathId); } static Utils::SmallString toJson(const Utils::SmallStringVector &strings) @@ -159,7 +159,7 @@ public: const Sqlite::Column ¯oNameColumn = table.addColumn("macroName", Sqlite::ColumnType::Text); table.addIndex({sourceIdColumn, macroNameColumn}); - table.initialize(m_database); + table.initialize(database); return table; } @@ -173,75 +173,75 @@ public: const Sqlite::Column &dependencySourceIdColumn = table.addColumn("dependencySourceId", Sqlite::ColumnType::Text); table.addIndex({sourceIdColumn, dependencySourceIdColumn}); - table.initialize(m_database); + table.initialize(database); return table; } public: - Sqlite::ImmediateNonThrowingDestructorTransaction m_transaction; - Database &m_database; + Sqlite::ImmediateNonThrowingDestructorTransaction transaction; + Database &database; Sqlite::Table newUsedMacroTable{createNewUsedMacrosTable()}; Sqlite::Table newNewSourceDependenciesTable{createNewSourceDependenciesTable()}; - WriteStatement m_insertIntoNewUsedMacrosStatement{ + WriteStatement insertIntoNewUsedMacrosStatement{ "INSERT INTO newUsedMacros(sourceId, macroName) VALUES (?,?)", - m_database + database }; - WriteStatement m_syncNewUsedMacrosStatement{ + WriteStatement syncNewUsedMacrosStatement{ "INSERT INTO usedMacros(sourceId, macroName) SELECT sourceId, macroName FROM newUsedMacros WHERE NOT EXISTS (SELECT sourceId FROM usedMacros WHERE usedMacros.sourceId == newUsedMacros.sourceId AND usedMacros.macroName == newUsedMacros.macroName)", - m_database + database }; - WriteStatement m_deleteOutdatedUsedMacrosStatement{ + WriteStatement deleteOutdatedUsedMacrosStatement{ "DELETE FROM usedMacros WHERE sourceId IN (SELECT sourceId FROM newUsedMacros) AND NOT EXISTS (SELECT sourceId FROM newUsedMacros WHERE newUsedMacros.sourceId == usedMacros.sourceId AND newUsedMacros.macroName == usedMacros.macroName)", - m_database + database }; - WriteStatement m_deleteNewUsedMacrosTableStatement{ + WriteStatement deleteNewUsedMacrosTableStatement{ "DELETE FROM newUsedMacros", - m_database + database }; - mutable ReadStatement m_getLowestLastModifiedTimeOfDependencies{ + mutable ReadStatement getLowestLastModifiedTimeOfDependencies{ "WITH RECURSIVE sourceIds(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, sourceIds WHERE sourceDependencies.sourceId = sourceIds.sourceId) SELECT min(lastModified) FROM fileStatuses, sourceIds WHERE fileStatuses.sourceId = sourceIds.sourceId", - m_database + database }; - WriteStatement m_insertIntoNewSourceDependenciesStatement{ + WriteStatement insertIntoNewSourceDependenciesStatement{ "INSERT INTO newSourceDependencies(sourceId, dependencySourceId) VALUES (?,?)", - m_database + database }; - WriteStatement m_insertFileStatusesStatement{ + WriteStatement insertFileStatusesStatement{ "INSERT OR REPLACE INTO fileStatuses(sourceId, size, lastModified, isInPrecompiledHeader) VALUES (?,?,?,?)", - m_database + database }; - WriteStatement m_syncNewSourceDependenciesStatement{ + WriteStatement syncNewSourceDependenciesStatement{ "INSERT INTO sourceDependencies(sourceId, dependencySourceId) SELECT sourceId, dependencySourceId FROM newSourceDependencies WHERE NOT EXISTS (SELECT sourceId FROM sourceDependencies WHERE sourceDependencies.sourceId == newSourceDependencies.sourceId AND sourceDependencies.dependencySourceId == newSourceDependencies.dependencySourceId)", - m_database + database }; - WriteStatement m_deleteOutdatedSourceDependenciesStatement{ + WriteStatement deleteOutdatedSourceDependenciesStatement{ "DELETE FROM sourceDependencies WHERE sourceId IN (SELECT sourceId FROM newSourceDependencies) AND NOT EXISTS (SELECT sourceId FROM newSourceDependencies WHERE newSourceDependencies.sourceId == sourceDependencies.sourceId AND newSourceDependencies.dependencySourceId == sourceDependencies.dependencySourceId)", - m_database + database }; - WriteStatement m_deleteNewSourceDependenciesStatement{ + WriteStatement deleteNewSourceDependenciesStatement{ "DELETE FROM newSourceDependencies", - m_database + database }; - WriteStatement m_updateBuildDependencyTimeStampStatement{ + WriteStatement updateBuildDependencyTimeStampStatement{ "UPDATE fileStatuses SET buildDependencyTimeStamp = ? WHERE sourceId == ?", - m_database + database }; - WriteStatement m_updateSourceTypeStatement{ + WriteStatement updateSourceTypeStatement{ "UPDATE projectPartsSources SET sourceType = ? WHERE sourceId == ?", - m_database + database }; - mutable ReadStatement m_fetchSourceDependenciesStatement{ + mutable ReadStatement fetchSourceDependenciesStatement{ "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, collectedDependencies WHERE sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT sourceId, buildDependencyTimeStamp, sourceType FROM collectedDependencies NATURAL JOIN projectPartsSources NATURAL JOIN fileStatuses WHERE projectPartId = ?", - m_database + database }; - mutable ReadStatement m_fetchProjectPartIdStatement{ + mutable ReadStatement fetchProjectPartIdStatement{ "SELECT projectPartId FROM projectParts WHERE projectPartName = ?", - m_database + database }; - mutable ReadStatement m_fetchUsedMacrosStatement{ + mutable ReadStatement fetchUsedMacrosStatement{ "SELECT macroName, sourceId FROM usedMacros WHERE sourceId = ?", - m_database + database }; }; } diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri index 6c45f38ff59..b81b6cd9b5b 100644 --- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri +++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri @@ -1,12 +1,11 @@ INCLUDEPATH += $$PWD SOURCES += \ + $$PWD/builddependenciesprovider.cpp \ $$PWD/pchmanagerserver.cpp \ $$PWD/projectparts.cpp \ $$PWD/projectpartqueue.cpp \ - $$PWD/pchtaskgenerator.cpp \ - $$PWD/builddependenciesprovider.cpp \ - $$PWD/builddependencycollector.cpp + $$PWD/pchtaskgenerator.cpp HEADERS += \ $$PWD/pchmanagerserver.h \ @@ -34,16 +33,13 @@ HEADERS += \ $$PWD/modifiedtimecheckerinterface.h \ $$PWD/sourceentry.h \ $$PWD/builddependenciesstorage.h \ - $$PWD/builddependencycollector.h \ - $$PWD/builddependencygeneratorinterface.h \ - $$PWD/collectbuilddependencytoolaction.h \ - $$PWD/collectbuilddependencyaction.h \ - $$PWD/collectbuilddependencypreprocessorcallbacks.h + $$PWD/builddependencygeneratorinterface.h !isEmpty(LIBTOOLING_LIBS) { SOURCES += \ $$PWD/usedmacrosandsourcescollector.cpp \ - $$PWD/pchcreator.cpp + $$PWD/pchcreator.cpp \ + $$PWD/builddependencycollector.cpp HEADERS += \ $$PWD/collectusedmacroactionfactory.h \ @@ -51,5 +47,9 @@ HEADERS += \ $$PWD/collectusedmacrosandsourcespreprocessorcallbacks.h \ $$PWD/pchcreator.h \ $$PWD/processormanager.h \ - $$PWD/usedmacrosandsourcescollector.h + $$PWD/usedmacrosandsourcescollector.h \ + $$PWD/builddependencycollector.h \ + $$PWD/collectbuilddependencytoolaction.h \ + $$PWD/collectbuilddependencyaction.h \ + $$PWD/collectbuilddependencypreprocessorcallbacks.h } diff --git a/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h index 07c163c92ba..0962129cb61 100644 --- a/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h @@ -44,8 +44,9 @@ namespace ClangBackEnd { -class CollectBuildDependencyPreprocessorCallbacks final : public clang::PPCallbacks, - public CollectUsedMacrosAndSourcesPreprocessorCallbacksBase +class CollectBuildDependencyPreprocessorCallbacks final + : public clang::PPCallbacks, + public CollectUsedMacrosAndSourcesPreprocessorCallbacksBase { public: CollectBuildDependencyPreprocessorCallbacks(BuildDependency &buildDependency, diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro b/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro index ea66a43b61e..630afdf6189 100644 --- a/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro +++ b/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro @@ -19,7 +19,8 @@ LIBS += $$LIBTOOLING_LIBS INCLUDEPATH += $$LLVM_INCLUDEPATH INCLUDEPATH += ../clangpchmanagerbackend/source -QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS +QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS +QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS SOURCES += \ clangrefactoringbackendmain.cpp diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp index 9b5762f3da9..4334e90aa64 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp @@ -8228,6 +8228,8 @@ static void checkNode(QmlJS::SimpleReaderNode::Ptr node, TestRewriterView *view) void tst_TestCore::writeAnnotations() { + QSKIP("We have to improve handling of emtpy lines.", SkipAll); + const QLatin1String qmlCode("\n" "import QtQuick 2.1\n" "\n" diff --git a/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp b/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp index 8c60c1c498d..bca2e8d7a88 100644 --- a/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp +++ b/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp @@ -223,8 +223,9 @@ void tst_FileFormat::testLibraryPaths() project->setSourceDirectory(testDataDir); - QStringList expectedPaths(QStringList() << SRCDIR "/otherLibrary" - << SRCDIR "/data/library"); + const QDir base(testDataDir); + const QStringList expectedPaths({base.relativeFilePath(SRCDIR "/otherLibrary"), + base.relativeFilePath(SRCDIR "/data/library")}); qDebug() << expectedPaths << project->importPaths(); QCOMPARE(project->importPaths().toSet(), expectedPaths.toSet()); delete project; diff --git a/tests/auto/qml/reformatter/tst_reformatter.cpp b/tests/auto/qml/reformatter/tst_reformatter.cpp index f3164f440e3..64506195c4a 100644 --- a/tests/auto/qml/reformatter/tst_reformatter.cpp +++ b/tests/auto/qml/reformatter/tst_reformatter.cpp @@ -93,10 +93,18 @@ void tst_Reformatter::test() // compare line by line int commonLines = qMin(newLines.size(), sourceLines.size()); + bool insideMultiLineComment = false; for (int i = 0; i < commonLines; ++i) { // names intentional to make 'Actual (sourceLine): ...\nExpected (newLinee): ...' line up const QString &sourceLine = sourceLines.at(i); const QString &newLinee = newLines.at(i); + if (!insideMultiLineComment && sourceLine.trimmed().startsWith("/*")) { + insideMultiLineComment = true; + sourceLines.insert(i, "\n"); + continue; + } + if (sourceLine.trimmed().endsWith("*/")) + insideMultiLineComment = false; if (sourceLine.trimmed().isEmpty() && newLinee.trimmed().isEmpty()) continue; bool fail = !QCOMPARE_NOEXIT(newLinee, sourceLine); diff --git a/tests/manual/clang-format-for-qtc/test.cpp b/tests/manual/clang-format-for-qtc/test.cpp index e5afaff1300..b3cf22eaca8 100644 --- a/tests/manual/clang-format-for-qtc/test.cpp +++ b/tests/manual/clang-format-for-qtc/test.cpp @@ -656,7 +656,11 @@ void extremeFunction( ++uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunbelievableLongValue; extremeFunction( - "some super duper super duper super duper super duper super duper super duper super duper long"); + "some super duper super duper super duper super duper super duper super duper long"); + + // BreakStringLiterals splits the string. + extremeFunction("some super duper super duper super duper super duper super duper super duper " + "super duper long"); } void extremeFunction2(int parameter1, diff --git a/tests/unit/unittest/builddependenciesprovider-test.cpp b/tests/unit/unittest/builddependenciesprovider-test.cpp index e829b52d60e..64a92478282 100644 --- a/tests/unit/unittest/builddependenciesprovider-test.cpp +++ b/tests/unit/unittest/builddependenciesprovider-test.cpp @@ -28,6 +28,7 @@ #include "mockbuilddependenciesstorage.h" #include "mockmodifiedtimechecker.h" #include "mockbuilddependencygenerator.h" +#include "mocksqlitetransactionbackend.h" #include @@ -54,38 +55,67 @@ MATCHER_P(HasSourceId, sourceId, std::string(negation ? "hasn't" : "has") class BuildDependenciesProvider : public testing::Test { protected: + NiceMock mockSqliteTransactionBackend; NiceMock mockBuildDependenciesStorage; NiceMock mockModifiedTimeChecker; NiceMock mockBuildDependenciesGenerator; - ClangBackEnd::BuildDependenciesProvider provider{mockBuildDependenciesStorage, mockModifiedTimeChecker, mockBuildDependenciesGenerator}; + ClangBackEnd::BuildDependenciesProvider provider{mockBuildDependenciesStorage, + mockModifiedTimeChecker, + mockBuildDependenciesGenerator, + mockSqliteTransactionBackend}; ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1", {"--yi"}, - {{"YI","1"}}, + {{"YI", "1"}}, {"/yi"}, {1}, {2}}; ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2", {"--er"}, - {{"ER","2"}}, + {{"ER", "2"}}, {"/er"}, {1}, {2, 3, 4}}; - SourceEntries firstSources{{1, SourceType::UserInclude, 1}, {2, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}}; - SourceEntries secondSources{{1, SourceType::UserInclude, 1}, {3, SourceType::UserInclude, 1}, {8, SourceType::UserInclude, 1}}; - SourceEntries thirdSources{{4, SourceType::UserInclude, 1}, {8, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}}; + SourceEntries firstSources{{1, SourceType::UserInclude, 1}, + {2, SourceType::UserInclude, 1}, + {10, SourceType::UserInclude, 1}}; + SourceEntries secondSources{{1, SourceType::UserInclude, 1}, + {3, SourceType::UserInclude, 1}, + {8, SourceType::UserInclude, 1}}; + SourceEntries thirdSources{{4, SourceType::UserInclude, 1}, + {8, SourceType::UserInclude, 1}, + {10, SourceType::UserInclude, 1}}; UsedMacros firstUsedMacros{{"YI", 1}}; UsedMacros secondUsedMacros{{"LIANG", 2}, {"ER", 2}}; UsedMacros thirdUsedMacros{{"SAN", 10}}; - BuildDependency buildDependency{secondSources, {}}; + FilePathIds sourceFiles{1, 3, 8}; + ClangBackEnd::SourceDependencies sourceDependencies{{1, 3}, {1, 8}}; + ClangBackEnd::FileStatuses fileStatuses{{1, 21, 12, false}, + {3, 21, 12, false}, + {8, 21, 12, false}}; + BuildDependency buildDependency{ + secondSources, + secondUsedMacros, + sourceFiles, + sourceDependencies, + fileStatuses + }; }; TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromStorageIfTimeStampsAreUpToDate) { InSequence s; - EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq("ProjectPart1"))).WillRepeatedly(Return(firstSources)); + EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); + EXPECT_CALL(mockBuildDependenciesStorage, + fetchDependSources({2}, TypedEq("ProjectPart1"))) + .WillRepeatedly(Return(firstSources)); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true)); EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); provider.create(projectPart1); } @@ -95,6 +125,7 @@ TEST_F(BuildDependenciesProvider, FetchDependSourcesFromStorage) ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq("ProjectPart2"))).WillByDefault(Return(firstSources)); ON_CALL(mockBuildDependenciesStorage, fetchDependSources({3}, TypedEq("ProjectPart2"))).WillByDefault(Return(secondSources)); ON_CALL(mockBuildDependenciesStorage, fetchDependSources({4}, TypedEq("ProjectPart2"))).WillByDefault(Return(thirdSources)); + ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(true)); auto buildDependency = provider.create(projectPart2); @@ -106,9 +137,20 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromGeneratorIfTi { InSequence s; - EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq("ProjectPart1"))).WillRepeatedly(Return(firstSources)); + EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); + EXPECT_CALL(mockBuildDependenciesStorage, + fetchDependSources({2}, TypedEq("ProjectPart1"))) + .WillRepeatedly(Return(firstSources)); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(false)); - EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)); + EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)) + .WillOnce(Return(buildDependency)); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); + EXPECT_CALL(mockBuildDependenciesStorage, updateSources(Eq(secondSources))); + EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatuses))); + EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies))); + EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(secondUsedMacros))); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); provider.create(projectPart1); } @@ -128,11 +170,15 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeSta { InSequence s; + EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq("ProjectPart1"))).WillRepeatedly(Return(firstSources)); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true)); + EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1})); EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({2})); EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({10})); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); provider.create(projectPart1); } diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp index 1100f1a634f..77feb21bd7f 100644 --- a/tests/unit/unittest/builddependenciesstorage-test.cpp +++ b/tests/unit/unittest/builddependenciesstorage-test.cpp @@ -51,21 +51,21 @@ class BuildDependenciesStorage : public testing::Test protected: NiceMock mockDatabase; Storage storage{mockDatabase}; - MockSqliteWriteStatement &insertIntoNewUsedMacrosStatement = storage.m_insertIntoNewUsedMacrosStatement; - MockSqliteWriteStatement &syncNewUsedMacrosStatement =storage.m_syncNewUsedMacrosStatement; - MockSqliteWriteStatement &deleteOutdatedUsedMacrosStatement = storage.m_deleteOutdatedUsedMacrosStatement; - MockSqliteWriteStatement &deleteNewUsedMacrosTableStatement = storage.m_deleteNewUsedMacrosTableStatement; - MockSqliteWriteStatement &insertFileStatuses = storage.m_insertFileStatusesStatement; - MockSqliteWriteStatement &insertIntoNewSourceDependenciesStatement = storage.m_insertIntoNewSourceDependenciesStatement; - MockSqliteWriteStatement &syncNewSourceDependenciesStatement = storage.m_syncNewSourceDependenciesStatement; - MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = storage.m_deleteOutdatedSourceDependenciesStatement; - MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = storage.m_deleteNewSourceDependenciesStatement; - MockSqliteReadStatement &getLowestLastModifiedTimeOfDependencies = storage.m_getLowestLastModifiedTimeOfDependencies; - MockSqliteWriteStatement &updateBuildDependencyTimeStampStatement = storage.m_updateBuildDependencyTimeStampStatement; - MockSqliteWriteStatement &updateSourceTypeStatement = storage.m_updateSourceTypeStatement; - MockSqliteReadStatement &fetchSourceDependenciesStatement = storage.m_fetchSourceDependenciesStatement; - MockSqliteReadStatement &fetchProjectPartIdStatement = storage.m_fetchProjectPartIdStatement; - MockSqliteReadStatement &fetchUsedMacrosStatement = storage.m_fetchUsedMacrosStatement; + MockSqliteWriteStatement &insertIntoNewUsedMacrosStatement = storage.insertIntoNewUsedMacrosStatement; + MockSqliteWriteStatement &syncNewUsedMacrosStatement =storage.syncNewUsedMacrosStatement; + MockSqliteWriteStatement &deleteOutdatedUsedMacrosStatement = storage.deleteOutdatedUsedMacrosStatement; + MockSqliteWriteStatement &deleteNewUsedMacrosTableStatement = storage.deleteNewUsedMacrosTableStatement; + MockSqliteWriteStatement &insertFileStatuses = storage.insertFileStatusesStatement; + MockSqliteWriteStatement &insertIntoNewSourceDependenciesStatement = storage.insertIntoNewSourceDependenciesStatement; + MockSqliteWriteStatement &syncNewSourceDependenciesStatement = storage.syncNewSourceDependenciesStatement; + MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = storage.deleteOutdatedSourceDependenciesStatement; + MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = storage.deleteNewSourceDependenciesStatement; + MockSqliteReadStatement &getLowestLastModifiedTimeOfDependencies = storage.getLowestLastModifiedTimeOfDependencies; + MockSqliteWriteStatement &updateBuildDependencyTimeStampStatement = storage.updateBuildDependencyTimeStampStatement; + MockSqliteWriteStatement &updateSourceTypeStatement = storage.updateSourceTypeStatement; + MockSqliteReadStatement &fetchSourceDependenciesStatement = storage.fetchSourceDependenciesStatement; + MockSqliteReadStatement &fetchProjectPartIdStatement = storage.fetchProjectPartIdStatement; + MockSqliteReadStatement &fetchUsedMacrosStatement = storage.fetchUsedMacrosStatement; }; TEST_F(BuildDependenciesStorage, ConvertStringsToJson) diff --git a/tests/unit/unittest/clang_dependency.pri b/tests/unit/unittest/clang_dependency.pri index 2c72feadff0..62c798464b1 100644 --- a/tests/unit/unittest/clang_dependency.pri +++ b/tests/unit/unittest/clang_dependency.pri @@ -22,6 +22,7 @@ include(../../../src/shared/clang/clang_defines.pri) !contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): QMAKE_RPATHDIR += $$LLVM_LIBDIR LLVM_CXXFLAGS ~= s,-g\d?, + QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_BINDIR/clang)xxx\\\"\" diff --git a/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp b/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp index 4850c0f9b5e..fb49a4c640b 100644 --- a/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp +++ b/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp @@ -312,6 +312,14 @@ TEST_F(ClangCompletionContextAnalyzer, AfterOpeningParenthesis) ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClang, 0, 0, positionInText, true)); } +TEST_F(ClangCompletionContextAnalyzer, AfterOpeningBraceAndIdentifierOnNewLine) +{ + auto analyzer = runAnalyzer("if (1) {\n" + "cla@"); + + ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClang, -3, -3, positionInText, true)); +} + TEST_F(ClangCompletionContextAnalyzer, ArgumentOneAtSignal) { auto analyzer = runAnalyzer("SIGNAL(@"); diff --git a/tests/unit/unittest/compileroptionsbuilder-test.cpp b/tests/unit/unittest/compileroptionsbuilder-test.cpp index 662ff7787f8..6b2d1af11e3 100644 --- a/tests/unit/unittest/compileroptionsbuilder-test.cpp +++ b/tests/unit/unittest/compileroptionsbuilder-test.cpp @@ -230,6 +230,84 @@ TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderLinux) "-isystem", QDir::toNativeSeparators("/usr/include"))); } +TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderNoVersion) +{ + projectPart.headerPaths = {HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include", HeaderPathType::BuiltIn}, + HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++", HeaderPathType::BuiltIn}, + HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\i686-w64-mingw32", HeaderPathType::BuiltIn}, + HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\backward", HeaderPathType::BuiltIn} + }; + projectPart.toolChainTargetTriple = "x86_64-w64-windows-gnu"; + CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart, + CppTools::UseSystemHeader::No, + CppTools::SkipBuiltIn::No, + CppTools::SkipLanguageDefines::Yes, + "7.0.0", + ""); + + compilerOptionsBuilder.addHeaderPathOptions(); + + ASSERT_THAT(compilerOptionsBuilder.options(), + ElementsAre("-nostdinc", + "-nostdlibinc", + "-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include"), + "-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++"), + "-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\i686-w64-mingw32"), + "-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\backward"), + "-isystem", QDir::toNativeSeparators(CLANG_RESOURCE_DIR ""))); +} + +TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderAndroidClang) +{ + projectPart.headerPaths = { + HeaderPath{ + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include\\i686-linux-android", + HeaderPathType::BuiltIn}, + HeaderPath{ + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++\\include", + HeaderPathType::BuiltIn}, + HeaderPath{ + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\android\\support\\include", + HeaderPathType::BuiltIn}, + HeaderPath{ + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++abi\\include", + HeaderPathType::BuiltIn}, + HeaderPath{"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include", + HeaderPathType::BuiltIn}}; + projectPart.toolChainTargetTriple = "i686-linux-android"; + CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart, + CppTools::UseSystemHeader::No, + CppTools::SkipBuiltIn::No, + CppTools::SkipLanguageDefines::Yes, + "7.0.0", + ""); + + compilerOptionsBuilder.addHeaderPathOptions(); + + ASSERT_THAT( + compilerOptionsBuilder.options(), + ElementsAre( + "-nostdinc", + "-nostdlibinc", + "-isystem", + QDir::toNativeSeparators( + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include\\i686-linux-android"), + "-isystem", + QDir::toNativeSeparators( + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++\\include"), + "-isystem", + QDir::toNativeSeparators( + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\android\\support\\include"), + "-isystem", + QDir::toNativeSeparators( + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++abi\\include"), + "-isystem", + QDir::toNativeSeparators(CLANG_RESOURCE_DIR ""), + "-isystem", + QDir::toNativeSeparators( + "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include"))); +} + TEST_F(CompilerOptionsBuilder, NoPrecompiledHeader) { compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::CompilerOptionsBuilder::PchUsage::None); diff --git a/tests/unit/unittest/data/highlightingmarks.cpp b/tests/unit/unittest/data/highlightingmarks.cpp index a5b6e85872f..e1a48903ca3 100644 --- a/tests/unit/unittest/data/highlightingmarks.cpp +++ b/tests/unit/unittest/data/highlightingmarks.cpp @@ -592,9 +592,9 @@ class WithVirtualFunctionDefined { namespace NFoo { namespace NBar { namespace NTest { class NamespaceTypeSpelling; } } } Undeclared u; - -#include "../../../../share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h" - +#define Q_PROPERTY(arg) static_assert("Q_PROPERTY", #arg); // Keep these in sync with wrappedQtHeaders/QtCore/qobjectdefs.h +#define SIGNAL(arg) #arg +#define SLOT(arg) #arg class Property { Q_PROPERTY(const volatile unsigned long long * prop READ getProp WRITE setProp NOTIFY propChanged) Q_PROPERTY(const QString str READ getStr) @@ -674,3 +674,15 @@ int signalSlotTest() { SIGNAL(something(QString (*func1)(QString))); 1 == 2; } + +class NonConstParameterConstructor +{ + NonConstParameterConstructor() = default; + NonConstParameterConstructor(NonConstParameterConstructor &buildDependenciesStorage); + + void Call() + { + NonConstParameterConstructor foo; + NonConstParameterConstructor bar(foo); + } +}; diff --git a/tests/unit/unittest/mockbuilddependenciesprovider.h b/tests/unit/unittest/mockbuilddependenciesprovider.h index 8bb048bd248..2a1fd8f93f1 100644 --- a/tests/unit/unittest/mockbuilddependenciesprovider.h +++ b/tests/unit/unittest/mockbuilddependenciesprovider.h @@ -32,6 +32,7 @@ class MockBuildDependenciesProvider : public ClangBackEnd::BuildDependenciesProviderInterface { public: - MOCK_CONST_METHOD1(create, - ClangBackEnd::BuildDependency (const ClangBackEnd::V2::ProjectPartContainer &projectPart)); + MOCK_METHOD1( + create, + ClangBackEnd::BuildDependency(const ClangBackEnd::V2::ProjectPartContainer &projectPart)); }; diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp index 2935a853814..f48d546cb10 100644 --- a/tests/unit/unittest/tokenprocessor-test.cpp +++ b/tests/unit/unittest/tokenprocessor-test.cpp @@ -1679,6 +1679,24 @@ TEST_F(TokenProcessor, QtOldStyleSignalFunctionPointerType) ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Type)); } +TEST_F(TokenProcessor, NonConstParameterConstructor) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(681, 90)); + + infos[1]; + + ASSERT_THAT(infos[4], Not(HasMixin(HighlightingType::OutputArgument))); +} + +TEST_F(TokenProcessor, DISABLED_NonConstArgumentConstructor) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(686, 47)); + + infos[2]; + + ASSERT_THAT(infos[3], HasMixin(HighlightingType::OutputArgument)); +} + Data *TokenProcessor::d; void TokenProcessor::SetUpTestCase() diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 8c2c112230a..c67771bd438 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -107,8 +107,7 @@ SOURCES += \ pchtaskgenerator-test.cpp \ compilationdatabaseutils-test.cpp \ builddependenciesprovider-test.cpp \ - builddependenciesstorage-test.cpp \ - builddependencycollector-test.cpp + builddependenciesstorage-test.cpp !isEmpty(LIBCLANG_LIBS) { SOURCES += \ @@ -185,7 +184,8 @@ SOURCES += \ symbolscollector-test.cpp \ symbolfinder-test.cpp \ testclangtool.cpp \ - usedmacrocollector-test.cpp + usedmacrocollector-test.cpp \ + builddependencycollector-test.cpp } exists($$GOOGLEBENCHMARK_DIR) {