diff --git a/.clang-tidy b/.clang-tidy index 4f643546..136c4c10 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -9,6 +9,7 @@ Checks: -bugprone-assignment-in-if-condition, -bugprone-narrowing-conversions, -bugprone-switch-missing-default-case, + -bugprone-crtp-constructor-accessibility, concurrency-*, misc-*, -misc-no-recursion, @@ -20,6 +21,8 @@ Checks: performance-*, -performance-enum-size, portability-*, + -portability-avoid-pragma-once, + -portability-template-virtual-member-function, readability-*, -readability-braces-around-statements, -readability-uppercase-literal-suffix, diff --git a/.cmake-format.py b/.cmake-format.py index 420b5aa9..e0cb9bc8 100644 --- a/.cmake-format.py +++ b/.cmake-format.py @@ -4,8 +4,12 @@ with section("parse"): # Specify structure for custom cmake functions - additional_commands = {'foo': {'flags': ['BAR', 'BAZ'], - 'kwargs': {'DEPENDS': '*', 'HEADERS': '*', 'SOURCES': '*'}}} + additional_commands = { + "foo": { + "flags": ["BAR", "BAZ"], + "kwargs": {"DEPENDS": "*", "HEADERS": "*", "SOURCES": "*"}, + } + } # Override configurations per-command where available override_spec = {} @@ -41,7 +45,7 @@ # 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set # to `round-up` fractional indentation is replaced with a single tab character # (utf-8 0x09) effectively shifting the column to the next tabstop - fractional_tab_policy = 'use-space' + fractional_tab_policy = "use-space" # If an argument group contains more than this many sub-groups (parg or kwarg # groups) then force it to a vertical layout. @@ -69,7 +73,7 @@ # to this reference: `prefix`: the start of the statement, `prefix-indent`: # the start of the statement, plus one indentation level, `child`: align to # the column of the arguments - dangle_align = 'prefix' + dangle_align = "prefix" # If the statement spelling length (including space and parenthesis) is # smaller than this amount, then force reject nested layouts. @@ -85,17 +89,22 @@ max_lines_hwrap = 2 # What style line endings to use in the output. - line_ending = 'unix' + line_ending = "unix" # Format command names consistently as 'lower' or 'upper' case - command_case = 'lower' + command_case = "lower" # Format keywords consistently as 'lower' or 'upper' case - keyword_case = 'upper' + keyword_case = "upper" # A list of command names which should always be wrapped - always_wrap = ["add_executable", "add_library", - "target_link_libraries", "target_include_directories", "install"] + always_wrap = [ + "add_executable", + "add_library", + "target_link_libraries", + "target_include_directories", + "install", + ] # If true, the argument lists which are known to be sortable will be sorted # lexicographicall @@ -121,10 +130,10 @@ with section("markup"): # What character to use for bulleted lists - bullet_char = '*' + bullet_char = "*" # What character to use as punctuation after numerals in an enumerated list - enum_char = '.' + enum_char = "." # If comment markup is enabled, don't reflow the first comment block in each # listfile. Use this to preserve formatting of your copyright/license @@ -137,15 +146,15 @@ # Regular expression to match preformat fences in comments default= # ``r'^\s*([`~]{3}[`~]*)(.*)$'`` - fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$' + fence_pattern = "^\\s*([`~]{3}[`~]*)(.*)$" # Regular expression to match rulers in comments default= # ``r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'`` - ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$' + ruler_pattern = "^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$" # If a comment line matches starts with this pattern then it is explicitly a # trailing comment for the preceeding argument. Default is '#<' - explicit_trailing_pattern = '#<' + explicit_trailing_pattern = "#<" # If a comment line starts with at least this many consecutive hash # characters, then don't lstrip() them off. This allows for lazy hash rulers @@ -168,38 +177,38 @@ disabled_codes = [] # regular expression pattern describing valid function names - function_pattern = '[0-9a-z_]+' + function_pattern = "[0-9a-z_]+" # regular expression pattern describing valid macro names - macro_pattern = '[0-9a-z_]+' + macro_pattern = "[0-9a-z_]+" # regular expression pattern describing valid names for variables with global # (cache) scope - global_var_pattern = '[A-Z][0-9A-Z_]+' + global_var_pattern = "[A-Z][0-9A-Z_]+" # regular expression pattern describing valid names for variables with global # scope (but internal semantic) - internal_var_pattern = '[A-Z][0-9A-Z_]+' + internal_var_pattern = "[A-Z][0-9A-Z_]+" # regular expression pattern describing valid names for variables with local # scope - local_var_pattern = '[A-Za-z][A-Za-z0-9_]+' + local_var_pattern = "[A-Za-z][A-Za-z0-9_]+" # regular expression pattern describing valid names for privatedirectory # variables - private_var_pattern = '[0-9a-z_]+' + private_var_pattern = "[0-9a-z_]+" # regular expression pattern describing valid names for public directory # variables - public_var_pattern = '.*' + public_var_pattern = ".*" # regular expression pattern describing valid names for function/macro # arguments and loop variables. - argument_var_pattern = '[a-z_][a-z0-9_]+' + argument_var_pattern = "[a-z_][a-z0-9_]+" # regular expression pattern describing valid names for keywords used in # functions or macros - keyword_pattern = '[A-Z][0-9A-Z_]+' + keyword_pattern = "[A-Z][0-9A-Z_]+" # In the heuristic for C0201, how many conditionals to match within a loop in # before considering the loop a parser. @@ -225,11 +234,11 @@ emit_byteorder_mark = False # Specify the encoding of the input file. Defaults to utf-8 - input_encoding = 'utf-8' + input_encoding = "utf-8" # Specify the encoding of the output file. Defaults to utf-8. Note that cmake # only claims to support utf-8 so be careful when using anything else - output_encoding = 'utf-8' + output_encoding = "utf-8" # ------------------------------------- # Miscellaneous configurations options. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 763254be..f0220275 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,10 +26,10 @@ repos: - id: pylint args: ["--disable=C0103,C0301,C0114,R0801,E0401"] exclude: (\.cmake-format\.py) -- repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.7.0 +- repo: https://github.com/psf/black + rev: 26.3.1 hooks: - - id: autopep8 + - id: black - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 hooks: diff --git a/hotspot-config.h.cmake b/hotspot-config.h.cmake index 9481d43d..ae77c3b3 100644 --- a/hotspot-config.h.cmake +++ b/hotspot-config.h.cmake @@ -7,6 +7,8 @@ #pragma once +// NOLINTBEGIN(modernize-macro-to-enum) + #define HOTSPOT_VERSION_STRING "@HOTSPOT_VERSION_STRING@" #define HOTSPOT_VERSION_MAJOR @hotspot_VERSION_MAJOR@ #define HOTSPOT_VERSION_MINOR @hotspot_VERSION_MINOR@ @@ -26,3 +28,5 @@ #cmakedefine01 QCustomPlot_FOUND #cmakedefine01 KGraphViewerPart_FOUND + +// NOLINTEND(modernize-macro-to-enum) diff --git a/scripts/run_clang_tidy.sh b/scripts/run_clang_tidy.sh index c71638fd..03281358 100755 --- a/scripts/run_clang_tidy.sh +++ b/scripts/run_clang_tidy.sh @@ -14,6 +14,7 @@ rm -Rf scripts/fixits mkdir -p scripts/fixits run-clang-tidy -quiet -extra-arg="-Wno-gnu-zero-variadic-macro-arguments" \ + -exclude-header-filter "autogen.+(\.moc$|ui_.+\.h$)" \ -j $(nproc) -config-file .clang-tidy -export-fixes scripts/fixits/fixits.yaml \ -use-color -p "$build_dir" "$PWD/src" @@ -24,5 +25,5 @@ if [ -s "scripts/fixits/fixits.yaml" ]; then echo "fixits with auto replacements:" - grep -l Replacements:$ scripts/fixits/*/fixits.yaml | xargs dirname + grep -l Replacements:$ scripts/fixits/*/fixits.yaml | xargs dirname 2> /dev/null fi diff --git a/scripts/split-clang-tidy-fixits.py b/scripts/split-clang-tidy-fixits.py index 5cb466bd..0fc20622 100755 --- a/scripts/split-clang-tidy-fixits.py +++ b/scripts/split-clang-tidy-fixits.py @@ -8,32 +8,54 @@ import yaml +def normalizePaths(message): + """to enable deduplication, normalize paths""" + message["FilePath"] = os.path.normpath(message["FilePath"]) + + def fileOffsetToLine(message): - ''' to ease manual inspection, translate FileOffset to a FileLine ''' - if message['FilePath'] == "": + """to ease manual inspection, translate FileOffset to a FileLine""" + if message["FilePath"] == "": return - with open(message['FilePath'], 'r', encoding='utf-8') as sourceFile: - numNewlines = sourceFile.read(message['FileOffset']).count('\n') - message['FileLine'] = numNewlines + 1 + with open(message["FilePath"], "r", encoding="utf-8") as sourceFile: + numNewlines = sourceFile.read(message["FileOffset"]).count("\n") + message["FileLine"] = numNewlines + 1 inputFile = sys.argv[1] groupedFixits = {} +seenFixits = {} -with open(inputFile, 'r', encoding='utf-8') as mainFixitsFile: +with open(inputFile, "r", encoding="utf-8") as mainFixitsFile: mainFixits = yaml.safe_load(mainFixitsFile) if not mainFixits: print("no diagnostics found") sys.exit(0) - for fixit in mainFixits['Diagnostics']: - fileOffsetToLine(fixit['DiagnosticMessage']) - for note in fixit.get('Notes', []): + for fixit in mainFixits["Diagnostics"]: + diagnostic = fixit["DiagnosticName"] + + # normalize and add file offsets + normalizePaths(fixit["DiagnosticMessage"]) + fileOffsetToLine(fixit["DiagnosticMessage"]) + for note in fixit.get("Notes", []): + normalizePaths(note) fileOffsetToLine(note) + for replacement in fixit["DiagnosticMessage"].get("Replacements", []): + normalizePaths(replacement) + + stringified = yaml.dump(fixit, sort_keys=True) + seenGroup = seenFixits.get(diagnostic) + if not seenGroup: + seenFixits[diagnostic] = set(stringified) + elif stringified in seenGroup: + # duplicate entry, e.g. from header + continue + else: + seenGroup.add(stringified) - diagnostic = fixit['DiagnosticName'] group = groupedFixits.get(diagnostic) if not group: groupedFixits[diagnostic] = [fixit] @@ -46,12 +68,12 @@ def fileOffsetToLine(message): diagnosticDir = f"{baseDir}/{diagnostic}" if not os.path.isdir(diagnosticDir): os.mkdir(diagnosticDir) - with open(f"{diagnosticDir}/fixits.yaml", 'w', encoding='utf-8') as fixitsFile: - text = yaml.dump({'Diagnostics': fixits, 'MainSourceFile': ''}) + with open(f"{diagnosticDir}/fixits.yaml", "w", encoding="utf-8") as fixitsFile: + text = yaml.dump({"Diagnostics": fixits, "MainSourceFile": ""}) # sadly clang-apply-replacements doesn't like our additional FileLine # and we cannot add comments directly with pyaml # so instead we do this manually here - text = text.replace('FileLine:', '# FileLine:') + text = text.replace("FileLine:", "# FileLine:") fixitsFile.write(text) diff --git a/src/aboutdialog.h b/src/aboutdialog.h index e77fd0a6..e7bde2a0 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -21,7 +21,7 @@ class AboutDialog : public QDialog Q_OBJECT public: explicit AboutDialog(QWidget* parent = nullptr); - ~AboutDialog(); + ~AboutDialog() override; void setTitle(const QString& title); void setText(const QString& text); diff --git a/src/callgraphwidget.h b/src/callgraphwidget.h index a081c418..e8155577 100644 --- a/src/callgraphwidget.h +++ b/src/callgraphwidget.h @@ -33,12 +33,14 @@ class CallgraphWidget : public QWidget { Q_OBJECT public: - ~CallgraphWidget(); + ~CallgraphWidget() override; static CallgraphWidget* createCallgraphWidget(const Data::CallerCalleeResults& results, QWidget* parent = nullptr); void selectSymbol(const Data::Symbol& symbol); + bool eventFilter(QObject* watched, QEvent* event) override; + signals: void clickedOn(const Data::Symbol& symbol); @@ -46,7 +48,6 @@ public slots: void setResults(const Data::CallerCalleeResults& results); protected: - bool eventFilter(QObject* watched, QEvent* event) override; void changeEvent(QEvent* event) override; void showEvent(QShowEvent* event) override; diff --git a/src/costcontextmenu.h b/src/costcontextmenu.h index 8f32b6b6..d92b8d4e 100644 --- a/src/costcontextmenu.h +++ b/src/costcontextmenu.h @@ -20,7 +20,7 @@ class CostContextMenu : public QObject Q_OBJECT public: explicit CostContextMenu(QObject* parent = nullptr); - ~CostContextMenu(); + ~CostContextMenu() override; void addToMenu(QHeaderView* view, QMenu* menu); void hideColumns(QTreeView* view); diff --git a/src/costheaderview.h b/src/costheaderview.h index f7d6285a..425c7ff0 100644 --- a/src/costheaderview.h +++ b/src/costheaderview.h @@ -16,17 +16,18 @@ class CostHeaderView : public QHeaderView Q_OBJECT public: explicit CostHeaderView(CostContextMenu* contextMenu, QWidget* parent = nullptr); - ~CostHeaderView(); + ~CostHeaderView() override; void setAutoResize(bool autoResize) { m_autoResize = autoResize; } -private: +protected: void resizeEvent(QResizeEvent* event) override; void resizeColumns(bool reset); +private: bool m_isResizing = false; bool m_autoResize = true; }; diff --git a/src/dockwidgetsetup.cpp b/src/dockwidgetsetup.cpp index e2a0159b..a1a485c7 100644 --- a/src/dockwidgetsetup.cpp +++ b/src/dockwidgetsetup.cpp @@ -25,7 +25,6 @@ class DockingArea : public DockMainWindow public: using DockMainWindow::MainWindow; -protected: QMargins centerWidgetMargins() const override { return {}; diff --git a/src/flamegraph.cpp b/src/flamegraph.cpp index cc2ef7af..aff2c22f 100644 --- a/src/flamegraph.cpp +++ b/src/flamegraph.cpp @@ -35,12 +35,12 @@ #include #include #include +#include #include #include #include #include -#include #include "models/filterandzoomstack.h" #include "resultsutil.h" @@ -66,6 +66,7 @@ class CustomWidgetAction : public QWidgetAction { } +protected: QWidget* createWidget(QWidget* parent) override { auto widget = new QWidget(parent); @@ -110,6 +111,7 @@ class FrameGraphicsItem : public QGraphicsRectItem }; Q_DECLARE_METATYPE(FrameGraphicsItem*) +namespace { class FrameGraphicsRootItem : public FrameGraphicsItem { public: @@ -133,6 +135,7 @@ class FrameGraphicsRootItem : public FrameGraphicsItem QString m_costName; Data::Costs::Unit m_unit; }; +} Q_DECLARE_METATYPE(FrameGraphicsRootItem*) @@ -473,7 +476,7 @@ void layoutItems(FrameGraphicsItem* parent) for (auto child : std::as_const(children)) { auto frameChild = static_cast(child); - const qreal w = maxWidth * double(frameChild->cost()) / parent->cost(); + const qreal w = maxWidth * static_cast(frameChild->cost()) / parent->cost(); frameChild->setVisible(w > 1); if (frameChild->isVisible()) { frameChild->setRect(QRectF(x, y, w, h)); @@ -999,8 +1002,7 @@ void FlameGraph::setBottomUpData(const Data::BottomUpResults& bottomUpData) disconnect(m_costSource, nullptr, this, nullptr); ResultsUtil::fillEventSourceComboBox(m_costSource, bottomUpData.costs, tr("Show a flame graph over the aggregated %1 sample costs.")); - connect(m_costSource, static_cast(&QComboBox::currentIndexChanged), this, - &FlameGraph::showData); + connect(m_costSource, &QComboBox::currentIndexChanged, this, &FlameGraph::showData); rebuild(); } @@ -1075,7 +1077,6 @@ void FlameGraph::showData() setData(nullptr); m_buildingScene = true; - using namespace ThreadWeaver; auto bottomUpData = m_bottomUpData; auto topDownData = m_topDownData; const auto collapseRecursion = m_collapseRecursion; @@ -1083,18 +1084,15 @@ void FlameGraph::showData() auto threshold = m_costThreshold; auto brushConfig = ::brushConfig(Settings::instance()->colorScheme()); - stream() << make_job( - [showBottomUpData, bottomUpData, topDownData, type, threshold, brushConfig, collapseRecursion, this]() { - FrameGraphicsItem* parsedData = nullptr; - if (showBottomUpData) { - parsedData = parseData(bottomUpData.costs, type, bottomUpData.root.children, threshold, brushConfig, - collapseRecursion); - } else { - parsedData = parseData(topDownData.inclusiveCosts, type, topDownData.root.children, threshold, - brushConfig, collapseRecursion); - } - QMetaObject::invokeMethod(this, "setData", Qt::QueuedConnection, Q_ARG(FrameGraphicsItem*, parsedData)); - }); + QtConcurrent::run([showBottomUpData, bottomUpData, topDownData, type, threshold, brushConfig, collapseRecursion]() { + if (showBottomUpData) { + return parseData(bottomUpData.costs, type, bottomUpData.root.children, threshold, brushConfig, + collapseRecursion); + } else { + return parseData(topDownData.inclusiveCosts, type, topDownData.root.children, threshold, brushConfig, + collapseRecursion); + } + }).then(this, [this](FrameGraphicsItem* parsedData) { setData(parsedData); }); updateNavigationActions(); } diff --git a/src/flamegraph.h b/src/flamegraph.h index 53803517..304f04f2 100644 --- a/src/flamegraph.h +++ b/src/flamegraph.h @@ -28,7 +28,7 @@ class FlameGraph : public QWidget Q_OBJECT public: explicit FlameGraph(QWidget* parent = nullptr, Qt::WindowFlags flags = {}); - ~FlameGraph(); + ~FlameGraph() override; void setHoveredStacks(const QVector>& stacks); void setFilterStack(FilterAndZoomStack* filterStack); @@ -40,7 +40,6 @@ class FlameGraph : public QWidget void saveSvg(const QString& fileName) const; bool canConvertToImage() const; -protected: bool eventFilter(QObject* object, QEvent* event) override; private slots: diff --git a/src/frequencypage.h b/src/frequencypage.h index 4a9050f1..b527cbbc 100644 --- a/src/frequencypage.h +++ b/src/frequencypage.h @@ -26,7 +26,7 @@ class FrequencyPage : public QWidget Q_OBJECT public: FrequencyPage(PerfParser* parser, QWidget* parent = nullptr); - ~FrequencyPage(); + ~FrequencyPage() override; protected: void changeEvent(QEvent* event) override; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 20752ad9..ecc3f515 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -134,8 +134,7 @@ MainWindow::MainWindow(QWidget* parent) connect(m_startPage, &StartPage::openFileButtonClicked, this, &MainWindow::onOpenFileButtonClicked); connect(m_startPage, &StartPage::recordButtonClicked, this, &MainWindow::onRecordButtonClicked); - connect(m_startPage, &StartPage::stopParseButtonClicked, this, - static_cast(&MainWindow::clear)); + connect(m_startPage, &StartPage::stopParseButtonClicked, this, [this]() { clear(); }); connect(m_parser, &PerfParser::progress, m_startPage, &StartPage::onParseFileProgress); connect(m_parser, &PerfParser::debugInfoDownloadProgress, m_startPage, &StartPage::onDebugInfoDownloadProgress); connect(this, &MainWindow::openFileError, m_startPage, &StartPage::onOpenFileError); diff --git a/src/mainwindow.h b/src/mainwindow.h index bc8f20ff..37a83d90 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -29,13 +29,13 @@ class ResultsPage; class RecordPage; class SettingsDialog; -class MainWindow : public KParts::MainWindow +class MainWindow : public KParts::MainWindow // NOLINT(misc-multiple-inheritance) { Q_OBJECT public: explicit MainWindow(QWidget* parent = nullptr); - ~MainWindow(); + ~MainWindow() override; public slots: void clear(); @@ -64,10 +64,12 @@ public slots: void exportFinished(const QUrl& url); void exportFailed(const QString& errorMessage); +protected: + void closeEvent(QCloseEvent* event) override; + private: void clear(bool isReload); void openFile(const QString& path, bool isReload); - void closeEvent(QCloseEvent* event) override; void setupCodeNavigationMenu(); QString queryOpenDataFile(); diff --git a/src/models/byfilemodel.h b/src/models/byfilemodel.h index d520d629..6763669d 100644 --- a/src/models/byfilemodel.h +++ b/src/models/byfilemodel.h @@ -17,7 +17,7 @@ class ByFileModel : public HashModel Q_OBJECT public: explicit ByFileModel(QObject* parent = nullptr); - ~ByFileModel(); + ~ByFileModel() override; void setResults(const Data::ByFileResults& results); @@ -41,11 +41,12 @@ class ByFileModel : public HashModel FileRole, }; - QVariant headerCell(int column, int role) const final override; - QVariant cell(int column, int role, const QString& file, const Data::ByFileEntry& entry) const final override; - int numColumns() const final override; QModelIndex indexForFile(const QString& file) const; private: + QVariant headerCell(int column, int role) const final; + QVariant cell(int column, int role, const QString& file, const Data::ByFileEntry& entry) const final; + int numColumns() const final; + Data::ByFileResults m_results; }; diff --git a/src/models/callercalleemodel.h b/src/models/callercalleemodel.h index 98d3e479..0eac55d2 100644 --- a/src/models/callercalleemodel.h +++ b/src/models/callercalleemodel.h @@ -20,7 +20,7 @@ class CallerCalleeModel : public HashModel Parent::connect(Settings::instance(), &Settings::collapseDepthChanged, this, dataChangedHelper); } - virtual ~SymbolCostModelImpl() = default; + ~SymbolCostModelImpl() override = default; void setResults(const Data::SymbolCostMap& map, const Data::Costs& costs) { @@ -106,7 +106,8 @@ class SymbolCostModelImpl : public HashModel SymbolRole }; - QVariant headerCell(int column, int role) const final override +private: + QVariant headerCell(int column, int role) const final { if (role == Qt::InitialSortOrderRole && column > Binary) { return Qt::DescendingOrder; @@ -134,7 +135,7 @@ class SymbolCostModelImpl : public HashModel return {}; } - QVariant cell(int column, int role, const Data::Symbol& symbol, const Data::ItemCost& costs) const final override + QVariant cell(int column, int role, const Data::Symbol& symbol, const Data::ItemCost& costs) const final { if (role == SortRole) { switch (column) { @@ -164,12 +165,11 @@ class SymbolCostModelImpl : public HashModel return {}; } - int numColumns() const final override + int numColumns() const final { return NUM_BASE_COLUMNS + m_costs.numTypes(); } -private: virtual QString symbolHeader() const = 0; Data::Costs m_costs; @@ -180,9 +180,10 @@ class CallerModel : public SymbolCostModelImpl Q_OBJECT public: explicit CallerModel(QObject* parent = nullptr); - ~CallerModel(); + ~CallerModel() override; - QString symbolHeader() const final override; +private: + QString symbolHeader() const final; }; class CalleeModel : public SymbolCostModelImpl @@ -190,9 +191,10 @@ class CalleeModel : public SymbolCostModelImpl Q_OBJECT public: explicit CalleeModel(QObject* parent = nullptr); - ~CalleeModel(); + ~CalleeModel() override; - QString symbolHeader() const final override; +private: + QString symbolHeader() const final; }; template @@ -204,7 +206,7 @@ class LocationCostModelImpl : public HashModel Location) { return Qt::DescendingOrder; @@ -260,8 +263,7 @@ class LocationCostModelImpl : public HashModel Q_OBJECT public: explicit SourceMapModel(QObject* parent = nullptr); - ~SourceMapModel(); + ~SourceMapModel() override; }; diff --git a/src/models/callercalleeproxy.h b/src/models/callercalleeproxy.h index bbe7362b..d5f90aed 100644 --- a/src/models/callercalleeproxy.h +++ b/src/models/callercalleeproxy.h @@ -53,7 +53,7 @@ class SourceMapProxy : public CallerCalleeProxy Q_OBJECT public: SourceMapProxy(QObject* parent = nullptr); - ~SourceMapProxy(); + ~SourceMapProxy() override; protected: bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override; diff --git a/src/models/codedelegate.h b/src/models/codedelegate.h index 89b0a223..cf1d6aab 100644 --- a/src/models/codedelegate.h +++ b/src/models/codedelegate.h @@ -14,7 +14,7 @@ class CodeDelegate : public QStyledItemDelegate Q_OBJECT public: CodeDelegate(int lineNumberRole, int highlightRole, int syntaxHighlightRole, QObject* parent = nullptr); - ~CodeDelegate(); + ~CodeDelegate() override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; diff --git a/src/models/costdelegate.cpp b/src/models/costdelegate.cpp index 9908d66b..c825fec3 100644 --- a/src/models/costdelegate.cpp +++ b/src/models/costdelegate.cpp @@ -31,7 +31,7 @@ void CostDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, } const auto totalCost = index.data(m_totalCostRole).toULongLong(); - const auto fraction = std::abs(float(cost) / totalCost); + const auto fraction = std::abs(static_cast(cost) / totalCost); auto rect = option.rect; rect.setWidth(rect.width() * fraction); diff --git a/src/models/costdelegate.h b/src/models/costdelegate.h index 176e14e9..c71c0414 100644 --- a/src/models/costdelegate.h +++ b/src/models/costdelegate.h @@ -14,7 +14,7 @@ class CostDelegate : public QStyledItemDelegate Q_OBJECT public: explicit CostDelegate(quint32 sortRole, quint32 totalCostRole, QObject* parent = nullptr); - ~CostDelegate(); + ~CostDelegate() override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; diff --git a/src/models/data.h b/src/models/data.h index 56ea1401..03d935f7 100644 --- a/src/models/data.h +++ b/src/models/data.h @@ -18,6 +18,7 @@ #include #include +#include #include namespace Data { @@ -25,15 +26,15 @@ QString prettifySymbol(const QString& symbol); struct Symbol { - Symbol(const QString& symbol = {}, quint64 relAddr = 0, quint64 size = 0, const QString& binary = {}, - const QString& path = {}, const QString& actualPath = {}, bool isKernel = false, bool isInline = false) + Symbol(const QString& symbol = {}, quint64 relAddr = 0, quint64 size = 0, QString binary = {}, QString path = {}, + QString actualPath = {}, bool isKernel = false, bool isInline = false) : symbol(symbol) , prettySymbol(Data::prettifySymbol(symbol)) , relAddr(relAddr) , size(size) - , binary(binary) - , path(path) - , actualPath(actualPath) + , binary(std::move(std::move(binary))) + , path(std::move(path)) + , actualPath(std::move(actualPath)) , isKernel(isKernel) , isInline(isInline) { @@ -87,19 +88,14 @@ inline bool operator!=(const Symbol& lhs, const Symbol& rhs) inline uint qHash(const Symbol& symbol, uint seed = 0) { - Util::HashCombine hash; - seed = hash(seed, symbol.symbol); - seed = hash(seed, symbol.binary); - seed = hash(seed, symbol.path); - seed = hash(seed, symbol.relAddr); - return seed; + return qHashMulti(seed, symbol.symbol, symbol.binary, symbol.path, symbol.relAddr); } struct FileLine { FileLine() = default; - FileLine(const QString& file, int line) - : file(file) + FileLine(QString file, int line) + : file(std::move(file)) , line(line) { } @@ -143,10 +139,7 @@ inline bool operator!=(const FileLine& lhs, const FileLine& rhs) inline uint qHash(const FileLine& fileLine, uint seed = 0) { - Util::HashCombine hash; - seed = hash(seed, fileLine.file); - seed = hash(seed, fileLine.line); - return seed; + return qHashMulti(seed, fileLine.file, fileLine.line); } struct Location @@ -184,18 +177,14 @@ inline bool operator!=(const Location& lhs, const Location& rhs) inline uint qHash(const Location& location, uint seed = 0) { - Util::HashCombine hash; - seed = hash(seed, location.address); - seed = hash(seed, location.relAddr); - seed = hash(seed, location.fileLine); - return seed; + return qHashMulti(seed, location.address, location.relAddr, location.fileLine); } struct FrameLocation { - FrameLocation(qint32 parentLocationId = -1, const Data::Location& location = {}) + FrameLocation(qint32 parentLocationId = -1, Data::Location location = {}) : parentLocationId(parentLocationId) - , location(location) + , location(std::move(location)) { } @@ -896,8 +885,8 @@ struct CpuEvents struct CostSummary { CostSummary() = default; - CostSummary(const QString& label, quint64 sampleCount, quint64 totalPeriod, Costs::Unit unit) - : label(label) + CostSummary(QString label, quint64 sampleCount, quint64 totalPeriod, Costs::Unit unit) + : label(std::move(label)) , sampleCount(sampleCount) , totalPeriod(totalPeriod) , unit(unit) diff --git a/src/models/disassemblymodel.cpp b/src/models/disassemblymodel.cpp index 8cce7808..df0d4656 100644 --- a/src/models/disassemblymodel.cpp +++ b/src/models/disassemblymodel.cpp @@ -152,14 +152,16 @@ QVariant DisassemblyModel::data(const QModelIndex& index, int role) const return costLine; } else if (role == TotalCostRole) { return totalCost; - } else if (!costLine) + } else if (!costLine) { return {}; + } return Util::formatCostRelative(costLine, totalCost, true); } else { if (role == Qt::ToolTipRole) { return tr("%1
No samples at this location.
").arg(tooltip); - } else + } else { return QString(); + } } } else if (role == DisassemblyModel::HighlightRole) { return data.fileLine.line == m_highlightLine; diff --git a/src/models/disassemblymodel.h b/src/models/disassemblymodel.h index 14b2aa24..17984474 100644 --- a/src/models/disassemblymodel.h +++ b/src/models/disassemblymodel.h @@ -61,7 +61,7 @@ class DisassemblyModel : public QAbstractTableModel enum CustomRoles { CostRole = Qt::UserRole, - TotalCostRole = Qt::UserRole + 1, + TotalCostRole, HighlightRole, AddrRole, LinkedFunctionNameRole, diff --git a/src/models/eventmodel.h b/src/models/eventmodel.h index 60f0ac78..54f432f9 100644 --- a/src/models/eventmodel.h +++ b/src/models/eventmodel.h @@ -16,7 +16,7 @@ class EventModel : public QAbstractItemModel Q_OBJECT public: explicit EventModel(QObject* parent = nullptr); - virtual ~EventModel(); + ~EventModel() override; enum Columns { @@ -63,10 +63,10 @@ class EventModel : public QAbstractItemModel struct Process { - Process(qint32 pid = Data::INVALID_PID, const QVector& threads = {}, const QString& name = {}) + Process(qint32 pid = Data::INVALID_PID, const QVector& threads = {}, QString name = {}) : pid(pid) , threads(threads) - , name(name) + , name(std::move(name)) { } qint32 pid; diff --git a/src/models/filterandzoomstack.h b/src/models/filterandzoomstack.h index da999f85..90ba38a3 100644 --- a/src/models/filterandzoomstack.h +++ b/src/models/filterandzoomstack.h @@ -18,7 +18,7 @@ class FilterAndZoomStack : public QObject Q_OBJECT public: explicit FilterAndZoomStack(QObject* parent = nullptr); - ~FilterAndZoomStack(); + ~FilterAndZoomStack() override; Data::FilterAction filter() const; Data::ZoomAction zoom() const; diff --git a/src/models/frequencymodel.h b/src/models/frequencymodel.h index 31ea241d..284a09a1 100644 --- a/src/models/frequencymodel.h +++ b/src/models/frequencymodel.h @@ -16,7 +16,7 @@ class FrequencyModel : public QAbstractTableModel Q_OBJECT public: explicit FrequencyModel(QObject* parent = nullptr); - ~FrequencyModel(); + ~FrequencyModel() override; int rowCount(const QModelIndex& parent = {}) const override; int columnCount(const QModelIndex& parent = {}) const override; diff --git a/src/models/hashmodel.h b/src/models/hashmodel.h index bd09bcca..a7c0dfce 100644 --- a/src/models/hashmodel.h +++ b/src/models/hashmodel.h @@ -19,20 +19,20 @@ class HashModel : public QAbstractTableModel : QAbstractTableModel(parent) { } - virtual ~HashModel() = default; + ~HashModel() override = default; - int columnCount(const QModelIndex& parent = {}) const final override + int columnCount(const QModelIndex& parent = {}) const final { return parent.isValid() ? 0 : numColumns(); } - int rowCount(const QModelIndex& parent = {}) const final override + int rowCount(const QModelIndex& parent = {}) const final { return parent.isValid() ? 0 : m_keys.size(); } QVariant headerData(int section, Qt::Orientation orientation = Qt::Horizontal, - int role = Qt::DisplayRole) const final override + int role = Qt::DisplayRole) const final { if (section < 0 || section > numColumns() || orientation != Qt::Horizontal) { return {}; @@ -41,7 +41,7 @@ class HashModel : public QAbstractTableModel return headerCell(section, role); } - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const final override + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const final { if (!hasIndex(index.row(), index.column(), index.parent())) { return {}; @@ -83,6 +83,7 @@ class HashModel : public QAbstractTableModel endResetModel(); } +private: virtual QVariant headerCell(int column, int role) const = 0; virtual QVariant cell(int column, int role, const typename Rows::key_type& key, const typename Rows::mapped_type& entry) const = 0; diff --git a/src/models/highlightedtext.cpp b/src/models/highlightedtext.cpp index e82ff117..dc679007 100644 --- a/src/models/highlightedtext.cpp +++ b/src/models/highlightedtext.cpp @@ -89,13 +89,6 @@ class HighlightingImplementation : public KSyntaxHighlighting::AbstractHighlight return definition().name(); } - virtual LineFormat formatLine(const QString& line) - { - m_lineFormat.clear(); - m_state = highlightLine(line, m_state); - return m_lineFormat; - } - protected: void applyFormat(int offset, int length, const KSyntaxHighlighting::Format& format) override { @@ -106,6 +99,13 @@ class HighlightingImplementation : public KSyntaxHighlighting::AbstractHighlight } private: + virtual LineFormat formatLine(const QString& line) + { + m_lineFormat.clear(); + m_state = highlightLine(line, m_state); + return m_lineFormat; + } + KSyntaxHighlighting::Repository* m_repository; KSyntaxHighlighting::State m_state; QStringList m_lines; // for reformatting if definition changes @@ -154,6 +154,7 @@ class HighlightingImplementation }; #endif +namespace { class AnsiHighlightingImplementation : public HighlightingImplementation { public: @@ -226,6 +227,7 @@ class AnsiHighlightingImplementation : public HighlightingImplementation KColorScheme m_colorScheme; }; +} // QTextLayout is slow, this class acts as a cache that only creates and fills the QTextLayout on demand class HighlightedLine diff --git a/src/models/processfiltermodel.h b/src/models/processfiltermodel.h index 42a0e119..5184e431 100644 --- a/src/models/processfiltermodel.h +++ b/src/models/processfiltermodel.h @@ -17,11 +17,12 @@ class ProcessFilterModel : public QSortFilterProxyModel public: explicit ProcessFilterModel(QObject* parent); +protected: bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const override; + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; private: - bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; QString m_currentProcId; QString m_currentUser; }; diff --git a/src/models/processlist.h b/src/models/processlist.h index f9f09c76..326be74f 100644 --- a/src/models/processlist.h +++ b/src/models/processlist.h @@ -42,7 +42,7 @@ struct ProcData QString state; QString user; - inline bool equals(const ProcData& other) const + bool equals(const ProcData& other) const { return ppid == other.ppid && name == other.name && state == other.state && user == other.user; } diff --git a/src/models/processmodel.h b/src/models/processmodel.h index ba20be5b..21c65425 100644 --- a/src/models/processmodel.h +++ b/src/models/processmodel.h @@ -18,7 +18,7 @@ class ProcessModel : public QAbstractTableModel Q_OBJECT public: explicit ProcessModel(QObject* parent = nullptr); - virtual ~ProcessModel(); + ~ProcessModel() override; void setProcesses(const ProcDataList& processes); void mergeProcesses(const ProcDataList& processes); diff --git a/src/models/search.h b/src/models/search.h index 45d4e3be..0e351725 100644 --- a/src/models/search.h +++ b/src/models/search.h @@ -23,7 +23,7 @@ enum class Direction * return: offset from begin * */ template -int search_helper(const it begin, const it end, const it current, SearchFunc searchFunc, EndReached endReached) +int search_helper(const it& begin, const it& end, const it& current, SearchFunc searchFunc, EndReached endReached) { // if current points to the last line, current will now point to end -> wrap around const auto start = (current == end) ? begin : current; @@ -58,7 +58,7 @@ int search(const it begin, const it end, int current, Direction direction, Searc return search_helper(begin, end, std::next(currentIt), searchFunc, endReached); } - int resultIndex = search_helper(std::make_reverse_iterator(end), std::make_reverse_iterator(begin), - std::make_reverse_iterator(currentIt), searchFunc, endReached); + int const resultIndex = search_helper(std::make_reverse_iterator(end), std::make_reverse_iterator(begin), + std::make_reverse_iterator(currentIt), searchFunc, endReached); return resultIndex != -1 ? (size - resultIndex - 1) : -1; } diff --git a/src/models/timelinedelegate.cpp b/src/models/timelinedelegate.cpp index 21b5460e..cb275697 100644 --- a/src/models/timelinedelegate.cpp +++ b/src/models/timelinedelegate.cpp @@ -37,30 +37,30 @@ TimeLineData::TimeLineData(Data::Events events, quint64 maxCost, Data::TimeRange , threadTime(threadTime) , h(rect.height() - (2 * padding)) , w(rect.width() - (2 * padding)) - , xMultiplicator(double(w) / time.delta()) - , yMultiplicator(double(h) / maxCost) + , xMultiplicator(static_cast(w) / time.delta()) + , yMultiplicator(static_cast(h) / maxCost) { } int TimeLineData::mapTimeToX(quint64 t) const { - return time.start > t ? 0 : int(double(t - time.start) * xMultiplicator); + return time.start > t ? 0 : static_cast(static_cast(t - time.start) * xMultiplicator); } quint64 TimeLineData::mapXToTime(int x) const { - return quint64(double(x) / xMultiplicator) + time.start; + return static_cast(static_cast(x) / xMultiplicator) + time.start; } int TimeLineData::mapCostToY(quint64 cost) const { - return double(cost) * yMultiplicator; + return static_cast(cost) * yMultiplicator; } void TimeLineData::zoom(Data::TimeRange t) { time = t; - xMultiplicator = double(w) / time.delta(); + xMultiplicator = static_cast(w) / time.delta(); } template diff --git a/src/models/timelinedelegate.h b/src/models/timelinedelegate.h index 1886f864..0c8d6c78 100644 --- a/src/models/timelinedelegate.h +++ b/src/models/timelinedelegate.h @@ -54,7 +54,7 @@ class TimeLineDelegate : public QStyledItemDelegate Q_OBJECT public: explicit TimeLineDelegate(FilterAndZoomStack* filterAndZoomStack, QAbstractItemView* view, QObject* parent); - virtual ~TimeLineDelegate(); + ~TimeLineDelegate() override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; diff --git a/src/models/topproxy.h b/src/models/topproxy.h index 86d55b3c..a087351d 100644 --- a/src/models/topproxy.h +++ b/src/models/topproxy.h @@ -20,12 +20,13 @@ class TopProxy : public QSortFilterProxyModel void setCostColumn(int costColumn); void setNumBaseColumns(int numBaseColumns); + int rowCount(const QModelIndex& parent = {}) const override; + +protected: bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const override; - int rowCount(const QModelIndex& parent = {}) const override; - private: - int m_costColumn; - int m_numBaseColumns; + int m_costColumn; // NOLINT(modernize-use-default-member-init) + int m_numBaseColumns; // NOLINT(modernize-use-default-member-init) }; diff --git a/src/models/treemodel.h b/src/models/treemodel.h index 55cfb5cf..adb9f6cd 100644 --- a/src/models/treemodel.h +++ b/src/models/treemodel.h @@ -16,7 +16,7 @@ class AbstractTreeModel : public QAbstractItemModel Q_OBJECT public: explicit AbstractTreeModel(QObject* parent = nullptr); - ~AbstractTreeModel(); + ~AbstractTreeModel() override; enum Roles { @@ -35,9 +35,9 @@ class TreeModel : public AbstractTreeModel : AbstractTreeModel(parent) { } - ~TreeModel() = default; + ~TreeModel() override = default; - bool hasChildren(const QModelIndex& parent = {}) const final override + bool hasChildren(const QModelIndex& parent = {}) const final { if (parent.column() >= 1) return false; @@ -49,7 +49,7 @@ class TreeModel : public AbstractTreeModel return item && !item->children.isEmpty(); } - int rowCount(const QModelIndex& parent = {}) const final override + int rowCount(const QModelIndex& parent = {}) const final { if (parent.column() >= 1) { return 0; @@ -69,12 +69,12 @@ class TreeModel : public AbstractTreeModel item = item->children.constData(); } return numChildren; - } else { - return 0; } + + return 0; } - int columnCount(const QModelIndex& parent = {}) const final override + int columnCount(const QModelIndex& parent = {}) const final { if (!parent.isValid() || parent.column() == 0) { return numColumns(); @@ -83,7 +83,7 @@ class TreeModel : public AbstractTreeModel } } - QModelIndex index(int row, int column, const QModelIndex& parent = {}) const final override + QModelIndex index(int row, int column, const QModelIndex& parent = {}) const final { if (row < 0 || column < 0 || column >= numColumns() || row > rowCount(parent)) { return {}; @@ -98,7 +98,7 @@ class TreeModel : public AbstractTreeModel return createIndex(row, column, tag); } - QModelIndex parent(const QModelIndex& child) const final override + QModelIndex parent(const QModelIndex& child) const final { const auto* childItem = itemFromIndex(child); if (!childItem) { @@ -114,7 +114,7 @@ class TreeModel : public AbstractTreeModel return indexFromItem(parent, 0); } - QVariant headerData(int section, Qt::Orientation orientation, int role) const final override + QVariant headerData(int section, Qt::Orientation orientation, int role) const final { if (orientation != Qt::Horizontal || section < 0 || section >= numColumns()) { return {}; @@ -123,7 +123,7 @@ class TreeModel : public AbstractTreeModel return headerColumnData(section, role); } - QVariant data(const QModelIndex& index, int role) const final override + QVariant data(const QModelIndex& index, int role) const final { const auto* item = itemFromIndex(index); if (!item || item == rootItem()) { @@ -233,7 +233,7 @@ class CostTreeModel : public TreeModel : Base(parent) { } - ~CostTreeModel() = default; + ~CostTreeModel() override = default; using Base::setData; void setData(const Results& data) @@ -248,13 +248,14 @@ class CostTreeModel : public TreeModel return m_results; } -protected: - const typename Base::TreeNode* rootItem() const final override +private: + const typename Base::TreeNode* rootItem() const final { return &m_results.root; } - Results m_results; +protected: + Results m_results; // NOLINT(misc-non-private-member-variables-in-classes) }; class BottomUpModel : public CostTreeModel @@ -262,7 +263,7 @@ class BottomUpModel : public CostTreeModel Q_OBJECT public: explicit BottomUpModel(QObject* parent = nullptr); - ~BottomUpModel(); + ~BottomUpModel() override; enum Columns { Symbol = 0, @@ -274,9 +275,10 @@ class BottomUpModel : public CostTreeModel InitialSortColumn = Binary + 1 // the first cost column }; - QVariant headerColumnData(int column, int role) const final override; - QVariant rowData(const Data::BottomUp* row, int column, int role) const final override; - int numColumns() const final override; +private: + QVariant headerColumnData(int column, int role) const final; + QVariant rowData(const Data::BottomUp* row, int column, int role) const final; + int numColumns() const final; }; class TopDownModel : public CostTreeModel @@ -284,7 +286,7 @@ class TopDownModel : public CostTreeModel Q_OBJECT public: explicit TopDownModel(QObject* parent = nullptr); - ~TopDownModel(); + ~TopDownModel() override; enum Columns { @@ -297,10 +299,12 @@ class TopDownModel : public CostTreeModel InitialSortColumn = Binary + 1 // the first cost column }; - QVariant headerColumnData(int column, int role) const final override; - QVariant rowData(const Data::TopDown* row, int column, int role) const final override; - int numColumns() const final override; int selfCostColumn(int cost) const; + +private: + QVariant headerColumnData(int column, int role) const final; + QVariant rowData(const Data::TopDown* row, int column, int role) const final; + int numColumns() const final; }; class PerLibraryModel : public CostTreeModel @@ -311,7 +315,7 @@ class PerLibraryModel : public CostTreeModel #include -#include - #include "settings.h" #if KFArchive_FOUND @@ -669,6 +667,7 @@ QProcessEnvironment perfparserEnvironment(const QStringList& debuginfodUrls) Q_DECLARE_TYPEINFO(AttributesDefinition, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(SampleCost, Q_MOVABLE_TYPE); +namespace { class PerfParserPrivate : public QObject { Q_OBJECT @@ -1502,6 +1501,7 @@ public slots: void progress(float percent); void debugInfoDownloadProgress(const QString& module, const QString& url, qint64 numerator, qint64 denominator); }; +} PerfParser::PerfParser(QObject* parent) : QObject(parent) @@ -1563,7 +1563,7 @@ PerfParser::PerfParser(QObject* parent) auto parsingStopped = [this] { m_isParsing = false; - m_decompressed.reset(); + m_decompressed = {}; }; connect(Settings::instance(), &Settings::costAggregationChanged, this, [this] { m_costAggregationChanged = true; }); @@ -1742,55 +1742,54 @@ void PerfParser::startParseFile(const QString& path) d.setInput(&process); - connect(&process, static_cast(&QProcess::finished), &process, - [finalize, this](int exitCode, QProcess::ExitStatus exitStatus) { - if (m_stopRequested) { - emit parsingFailed(tr("Parsing stopped.")); - return; - } - qCDebug(LOG_PERFPARSER) << exitCode << exitStatus; - - enum ErrorCodes - { - NoError, - TcpSocketError, - CannotOpen, - BadMagic, - HeaderError, - DataError, - MissingData, - InvalidOption - }; - switch (exitCode) { - case NoError: - finalize(); - break; - case TcpSocketError: - emit parsingFailed( - tr("The hotspot-perfparser binary exited with code %1 (TCP socket error).").arg(exitCode)); - break; - case CannotOpen: - emit parsingFailed( - tr("The hotspot-perfparser binary exited with code %1 (file could not be opened).") - .arg(exitCode)); - break; - case BadMagic: - case HeaderError: - case DataError: - case MissingData: - emit parsingFailed( - tr("The hotspot-perfparser binary exited with code %1 (invalid perf data file).") - .arg(exitCode)); - break; - case InvalidOption: - emit parsingFailed( - tr("The hotspot-perfparser binary exited with code %1 (invalid option).").arg(exitCode)); - break; - default: - emit parsingFailed(tr("The hotspot-perfparser binary exited with code %1.").arg(exitCode)); - break; - } - }); + connect( + &process, &QProcess::finished, &process, [finalize, this](int exitCode, QProcess::ExitStatus exitStatus) { + if (m_stopRequested) { + emit parsingFailed(tr("Parsing stopped.")); + return; + } + qCDebug(LOG_PERFPARSER) << exitCode << exitStatus; + + enum ErrorCodes + { + NoError, + TcpSocketError, + CannotOpen, + BadMagic, + HeaderError, + DataError, + MissingData, + InvalidOption + }; + switch (exitCode) { + case NoError: + finalize(); + break; + case TcpSocketError: + emit parsingFailed( + tr("The hotspot-perfparser binary exited with code %1 (TCP socket error).").arg(exitCode)); + break; + case CannotOpen: + emit parsingFailed( + tr("The hotspot-perfparser binary exited with code %1 (file could not be opened).") + .arg(exitCode)); + break; + case BadMagic: + case HeaderError: + case DataError: + case MissingData: + emit parsingFailed(tr("The hotspot-perfparser binary exited with code %1 (invalid perf data file).") + .arg(exitCode)); + break; + case InvalidOption: + emit parsingFailed( + tr("The hotspot-perfparser binary exited with code %1 (invalid option).").arg(exitCode)); + break; + default: + emit parsingFailed(tr("The hotspot-perfparser binary exited with code %1.").arg(exitCode)); + break; + } + }); connect(&process, &QProcess::errorOccurred, &process, [&process, this](QProcess::ProcessError error) { if (m_stopRequested) { @@ -1810,8 +1809,7 @@ void PerfParser::startParseFile(const QString& path) } QEventLoop loop; - connect(&process, static_cast(&QProcess::finished), &loop, - &QEventLoop::quit); + connect(&process, &QProcess::finished, &loop, &QEventLoop::quit); loop.exec(); }); } diff --git a/src/parsers/perf/perfparser.h b/src/parsers/perf/perfparser.h index 7133f49b..f7b02408 100644 --- a/src/parsers/perf/perfparser.h +++ b/src/parsers/perf/perfparser.h @@ -22,7 +22,7 @@ class PerfParser : public QObject Q_OBJECT public: explicit PerfParser(QObject* parent = nullptr); - ~PerfParser(); + ~PerfParser() override; void startParseFile(const QString& path); diff --git a/src/perfcontrolfifowrapper.h b/src/perfcontrolfifowrapper.h index 5a56e8d3..cccc8433 100644 --- a/src/perfcontrolfifowrapper.h +++ b/src/perfcontrolfifowrapper.h @@ -26,7 +26,7 @@ class PerfControlFifoWrapper : public QObject public: using QObject::QObject; - ~PerfControlFifoWrapper(); + ~PerfControlFifoWrapper() override; bool isOpen() const { diff --git a/src/perfoutputwidget.h b/src/perfoutputwidget.h index c0295177..057f9108 100644 --- a/src/perfoutputwidget.h +++ b/src/perfoutputwidget.h @@ -15,7 +15,7 @@ class PerfOutputWidget : public QWidget Q_OBJECT public: PerfOutputWidget(QWidget* parent = nullptr); - virtual ~PerfOutputWidget(); + ~PerfOutputWidget() override; virtual void addOutput(const QString&) = 0; virtual void clear() = 0; diff --git a/src/perfoutputwidgetkonsole.h b/src/perfoutputwidgetkonsole.h index 61086dff..8ca810eb 100644 --- a/src/perfoutputwidgetkonsole.h +++ b/src/perfoutputwidgetkonsole.h @@ -23,7 +23,7 @@ class PerfOutputWidgetKonsole : public PerfOutputWidget Q_OBJECT public: PerfOutputWidgetKonsole(KParts::ReadOnlyPart* part, QWidget* parent = nullptr); - ~PerfOutputWidgetKonsole(); + ~PerfOutputWidgetKonsole() override; static PerfOutputWidgetKonsole* create(QWidget* parent = nullptr); diff --git a/src/perfrecord.h b/src/perfrecord.h index bf4436fb..cbb85d48 100644 --- a/src/perfrecord.h +++ b/src/perfrecord.h @@ -22,7 +22,7 @@ class PerfRecord : public QObject Q_OBJECT public: explicit PerfRecord(const RecordHost* host, QObject* parent = nullptr); - ~PerfRecord(); + ~PerfRecord() override; void record(const QStringList& perfOptions, const QString& outputPath, bool elevatePrivileges, const QString& exePath, const QStringList& exeOptions, const QString& workingDirectory = QString()); diff --git a/src/recordpage.cpp b/src/recordpage.cpp index be29b9ad..129e8b83 100644 --- a/src/recordpage.cpp +++ b/src/recordpage.cpp @@ -462,7 +462,7 @@ RecordPage::RecordPage(QWidget* parent) m_updateRuntimeTimer->setInterval(1000); connect(m_updateRuntimeTimer, &QTimer::timeout, this, [this] { // round to the nearest second - const auto roundedElapsed = std::round(double(m_recordTimer.nsecsElapsed()) / 1E9) * 1E9; + const auto roundedElapsed = std::round(static_cast(m_recordTimer.nsecsElapsed()) / 1E9) * 1E9; ui->startRecordingButton->setText(tr("Stop Recording (%1)").arg(Util::formatTimeString(roundedElapsed, true))); }); @@ -620,7 +620,7 @@ void RecordPage::onStartRecordingButtonClicked(bool checked) break; } case RecordType::AttachToProcess: { - QItemSelectionModel* selectionModel = ui->processesTableView->selectionModel(); + QItemSelectionModel const* selectionModel = ui->processesTableView->selectionModel(); QStringList pids; const auto selection = selectionModel->selectedIndexes(); diff --git a/src/recordpage.h b/src/recordpage.h index 9baacded..c6659b67 100644 --- a/src/recordpage.h +++ b/src/recordpage.h @@ -39,7 +39,7 @@ class RecordPage : public QWidget Q_OBJECT public: explicit RecordPage(QWidget* parent = nullptr); - ~RecordPage(); + ~RecordPage() override; void showRecordPage(); void stopRecording(); diff --git a/src/resultsbottomuppage.h b/src/resultsbottomuppage.h index c906e491..5e3cdefe 100644 --- a/src/resultsbottomuppage.h +++ b/src/resultsbottomuppage.h @@ -34,7 +34,7 @@ class ResultsBottomUpPage : public QWidget public: explicit ResultsBottomUpPage(FilterAndZoomStack* filterStack, PerfParser* parser, CostContextMenu* contextMenu, QMenu* exportMenu, QWidget* parent = nullptr); - ~ResultsBottomUpPage(); + ~ResultsBottomUpPage() override; void clear(); diff --git a/src/resultsbyfilepage.h b/src/resultsbyfilepage.h index c810d2aa..6b5e84f3 100644 --- a/src/resultsbyfilepage.h +++ b/src/resultsbyfilepage.h @@ -32,7 +32,7 @@ class ResultsByFilePage : public QWidget public: explicit ResultsByFilePage(FilterAndZoomStack* filterStack, PerfParser* parser, CostContextMenu* contextMenu, QWidget* parent = nullptr); - ~ResultsByFilePage(); + ~ResultsByFilePage() override; void clear(); diff --git a/src/resultscallercalleepage.h b/src/resultscallercalleepage.h index 6bb68353..db8c1b4e 100644 --- a/src/resultscallercalleepage.h +++ b/src/resultscallercalleepage.h @@ -36,7 +36,7 @@ class ResultsCallerCalleePage : public QWidget public: explicit ResultsCallerCalleePage(FilterAndZoomStack* filterStack, PerfParser* parser, CostContextMenu* contextMenu, QWidget* parent = nullptr); - ~ResultsCallerCalleePage(); + ~ResultsCallerCalleePage() override; void setSysroot(const QString& path); void setAppPath(const QString& path); @@ -58,7 +58,7 @@ class ResultsCallerCalleePage : public QWidget struct SourceMapLocation { - inline explicit operator bool() const + explicit operator bool() const { return !path.isEmpty(); } diff --git a/src/resultsdisassemblypage.h b/src/resultsdisassemblypage.h index 3cbb91ec..b9ecf61b 100644 --- a/src/resultsdisassemblypage.h +++ b/src/resultsdisassemblypage.h @@ -44,7 +44,7 @@ class ResultsDisassemblyPage : public QWidget Q_OBJECT public: explicit ResultsDisassemblyPage(CostContextMenu* costContextMenu, QWidget* parent = nullptr); - ~ResultsDisassemblyPage(); + ~ResultsDisassemblyPage() override; void clear(); void setSymbol(const Data::Symbol& data); diff --git a/src/resultsflamegraphpage.h b/src/resultsflamegraphpage.h index fe0f038f..8c4015c9 100644 --- a/src/resultsflamegraphpage.h +++ b/src/resultsflamegraphpage.h @@ -32,7 +32,7 @@ class ResultsFlameGraphPage : public QWidget public: explicit ResultsFlameGraphPage(FilterAndZoomStack* filterStack, PerfParser* parser, QMenu* exportMenu, QWidget* parent = nullptr); - ~ResultsFlameGraphPage(); + ~ResultsFlameGraphPage() override; void clear(); diff --git a/src/resultspage.cpp b/src/resultspage.cpp index 1d997d01..58504190 100644 --- a/src/resultspage.cpp +++ b/src/resultspage.cpp @@ -87,7 +87,7 @@ ResultsPage::ResultsPage(PerfParser* parser, QWidget* parent) #if QCustomPlot_FOUND , m_frequencyPage(new FrequencyPage(parser, this)) #endif - , m_timelineVisible(true) + { m_exportMenu->setIcon(QIcon::fromTheme(QStringLiteral("document-export"))); { diff --git a/src/resultspage.h b/src/resultspage.h index abc525aa..2364fba7 100644 --- a/src/resultspage.h +++ b/src/resultspage.h @@ -44,7 +44,7 @@ class ResultsPage : public QWidget Q_OBJECT public: explicit ResultsPage(PerfParser* parser, QWidget* parent = nullptr); - ~ResultsPage(); + ~ResultsPage() override; void selectSummaryTab(); void clear(); @@ -67,8 +67,10 @@ public slots: signals: void navigateToCode(const QString& url, int lineNumber, int columnNumber); -private: +protected: void resizeEvent(QResizeEvent* event) override; + +private: void repositionFilterBusyIndicator(); std::unique_ptr ui; @@ -96,5 +98,5 @@ public slots: FrequencyPage* m_frequencyPage = nullptr; DockWidget* m_frequencyDock = nullptr; QWidget* m_filterBusyIndicator = nullptr; - bool m_timelineVisible; + bool m_timelineVisible = true; }; diff --git a/src/resultssummarypage.cpp b/src/resultssummarypage.cpp index 747b8ae9..be20cb43 100644 --- a/src/resultssummarypage.cpp +++ b/src/resultssummarypage.cpp @@ -55,11 +55,10 @@ ResultsSummaryPage::ResultsSummaryPage(FilterAndZoomStack* filterStack, PerfPars ResultsUtil::setupHeaderView(ui->topLibraryTreeView, contextMenu); ResultsUtil::setupContextMenu(ui->topLibraryTreeView, contextMenu, perLibraryModel, filterStack, this, {}); - connect(ui->eventSourceComboBox, static_cast(&QComboBox::currentIndexChanged), this, - [topHotspotsProxy, this]() { - topHotspotsProxy->setCostColumn(ui->eventSourceComboBox->currentData().toInt() - + BottomUpModel::NUM_BASE_COLUMNS); - }); + connect(ui->eventSourceComboBox, &QComboBox::currentIndexChanged, this, [topHotspotsProxy, this]() { + topHotspotsProxy->setCostColumn(ui->eventSourceComboBox->currentData().toInt() + + BottomUpModel::NUM_BASE_COLUMNS); + }); connect(ui->eventSourceComboBox_2, qOverload(&QComboBox::currentIndexChanged), this, [topLibraryProxy, this]() { diff --git a/src/resultssummarypage.h b/src/resultssummarypage.h index 13add3b3..a47bb7e5 100644 --- a/src/resultssummarypage.h +++ b/src/resultssummarypage.h @@ -30,7 +30,7 @@ class ResultsSummaryPage : public QWidget public: explicit ResultsSummaryPage(FilterAndZoomStack* filterStack, PerfParser* parser, CostContextMenu* contextMenu, QWidget* parent = nullptr); - ~ResultsSummaryPage(); + ~ResultsSummaryPage() override; signals: void jumpToCallerCallee(const Data::Symbol& symbol); diff --git a/src/resultstopdownpage.h b/src/resultstopdownpage.h index 85e0b3bf..5e593a58 100644 --- a/src/resultstopdownpage.h +++ b/src/resultstopdownpage.h @@ -32,7 +32,7 @@ class ResultsTopDownPage : public QWidget public: explicit ResultsTopDownPage(FilterAndZoomStack* filterStack, PerfParser* parser, CostContextMenu* contextMenu, QWidget* parent = nullptr); - ~ResultsTopDownPage(); + ~ResultsTopDownPage() override; void clear(); diff --git a/src/settings.h b/src/settings.h index eadccf91..afccca38 100644 --- a/src/settings.h +++ b/src/settings.h @@ -224,7 +224,7 @@ public slots: private: using QObject::QObject; - ~Settings(); + ~Settings() override; bool m_prettifySymbols = true; bool m_collapseTemplates = true; diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 19a32ef6..d2e9b84f 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -29,7 +29,7 @@ class SettingsDialog : public KPageDialog public: explicit SettingsDialog(QWidget* parent = nullptr); - ~SettingsDialog(); + ~SettingsDialog() override; void initSettings(); QString sysroot() const; QString appPath() const; @@ -40,6 +40,7 @@ class SettingsDialog : public KPageDialog QString objdump() const; QString perfMapPath() const; +protected: void keyPressEvent(QKeyEvent* event) override; private: diff --git a/src/startpage.h b/src/startpage.h index d6639072..143611eb 100644 --- a/src/startpage.h +++ b/src/startpage.h @@ -23,7 +23,7 @@ class StartPage : public QWidget Q_OBJECT public: explicit StartPage(QWidget* parent = nullptr); - ~StartPage(); + ~StartPage() override; void showStartPage(); void showParseFileProgress(); diff --git a/src/timelinewidget.cpp b/src/timelinewidget.cpp index 3c2e124b..2232006f 100644 --- a/src/timelinewidget.cpp +++ b/src/timelinewidget.cpp @@ -109,11 +109,10 @@ TimeLineWidget::TimeLineWidget(PerfParser* parser, QMenu* filterMenu, FilterAndZ connect(m_parser, &PerfParser::tracepointDataAvailable, this, [this](const Data::TracepointResults& data) { m_timeAxisHeaderView->setTracepoints(data); }); - connect(ui->timeLineEventSource, static_cast(&QComboBox::currentIndexChanged), this, - [this](int index) { - const auto typeId = ui->timeLineEventSource->itemData(index).toInt(); - m_timeLineDelegate->setEventType(typeId); - }); + connect(ui->timeLineEventSource, &QComboBox::currentIndexChanged, this, [this](int index) { + const auto typeId = ui->timeLineEventSource->itemData(index).toInt(); + m_timeLineDelegate->setEventType(typeId); + }); connect(m_timeLineDelegate, &TimeLineDelegate::stacksHovered, this, [this](const QSet& stackIds) { if (stackIds.isEmpty()) { diff --git a/src/util.h b/src/util.h index 2897ab86..b10516b6 100644 --- a/src/util.h +++ b/src/util.h @@ -7,7 +7,6 @@ #pragma once -#include #include class QString; @@ -38,18 +37,6 @@ QString findLibexecBinary(const QString& name); */ QString perfParserBinaryPath(); -// HashCombine was taken from Qt's file qhashfunctions.h -struct HashCombine -{ - typedef uint result_type; - template - Q_DECL_CONSTEXPR result_type operator()(uint seed, const T& t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t))) - // combiner taken from N3876 / boost::hash_combine - { - return seed ^ (qHash(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); - } -}; - QString formatString(const QString& input, bool replaceEmptyString = true); QString formatSymbol(const Data::Symbol& symbol, bool replaceEmptyString = true); QString formatSymbolExtended(const Data::Symbol& symbol);