[all-commits] [llvm/llvm-project] 899c86: [clang-format] Fixed bad performance with enabled ...

Sedenion via All-commits all-commits at lists.llvm.org
Mon Jul 3 03:55:03 PDT 2023

  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 899c86779440dca84085fb53a1fbba6c5aa5a3b6
  Author: Sedenion <39583823+Sedeniono at users.noreply.github.com>
  Date:   2023-07-03 (Mon, 03 Jul 2023)

  Changed paths:
    M clang/lib/Format/Format.cpp
    M clang/lib/Format/QualifierAlignmentFixer.cpp
    M clang/lib/Format/QualifierAlignmentFixer.h
    M clang/unittests/Format/QualifierFixerTest.cpp

  Log Message:
  [clang-format] Fixed bad performance with enabled qualifier fixer.

This fixes github issue #57117: If the "QualifierAlignment"
option of clang-format is set to anything else but "Leave", the
"QualifierAlignmentFixer" pass gets enabled. This pass scales
quadratically with the number of preprocessor branches, i.e.
with the number of elements in TokenAnalyzer::UnwrappedLines.
The reason is that QualifierAlignmentFixer::process() generates
the UnwrappedLines, but then QualifierAlignmentFixer::analyze()
calls LeftRightQualifierAlignmentFixer::process() several times
(once for each qualifier) which again each time generates the

This commit gets rid of this double loop by registering the
individual LeftRightQualifierAlignmentFixer passes directly in
the top most container of passes (local variable "Passes" in
With this change, the original example in the github issue #57117
now takes only around 3s instead of >300s to format.

Since QualifierAlignmentFixer::analyze() got deleted, we also
no longer have the code with the NonNoOpFixes. This causes
replacements that end up not changing anything to appear in the
list of final replacements. There is a unit test to check that
this does not happen: QualifierFixerTest.NoOpQualifierReplacements.
However, it got broken at some point in time. So this commit
fixes the test. To keep the behavior that no no-op replacements
should appear from the qualifier fixer, the corresponding code
from QualifierAlignmentFixer::analyze() was moved to the top
reformat() function. Thus, is now done for **every** replacement
of every formatting pass. If no-op replacements are a problem
for the qualifier fixer, then it seems to be a good idea to
filter them out always.

for some more details.

Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan

Differential Revision: https://reviews.llvm.org/D153228

More information about the All-commits mailing list