diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3472,21 +3472,16 @@ typedef std::function( const Environment &)> AnalyzerPass; - SmallVector Passes; + + SmallVector Passes; Passes.emplace_back([&](const Environment &Env) { return IntegerLiteralSeparatorFixer().process(Env, Expanded); }); if (Style.isCpp()) { - if (Style.QualifierAlignment != FormatStyle::QAS_Leave) { - Passes.emplace_back([&](const Environment &Env) { - return QualifierAlignmentFixer(Env, Expanded, Code, Ranges, - FirstStartColumn, NextStartColumn, - LastStartColumn, FileName) - .process(); - }); - } + if (Style.QualifierAlignment != FormatStyle::QAS_Leave) + addQualifierAlignmentFixerPasses(Expanded, Passes); if (Style.InsertBraces) { FormatStyle S = Expanded; @@ -3571,6 +3566,24 @@ } } + if (Style.QualifierAlignment != FormatStyle::QAS_Leave) { + // Don't make replacements that replace nothing. QualifierAlignment can + // produce them if one of its early passes changes e.g. `const volatile` to + // `volatile const` and then a later pass changes it back again. + tooling::Replacements NonNoOpFixes; + for (const tooling::Replacement &Fix : Fixes) { + StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength()); + if (!OriginalCode.equals(Fix.getReplacementText())) { + auto Err = NonNoOpFixes.add(Fix); + if (Err) { + llvm::errs() << "Error adding replacements : " + << llvm::toString(std::move(Err)) << "\n"; + } + } + } + Fixes = std::move(NonNoOpFixes); + } + return {Fixes, Penalty}; } } // namespace internal diff --git a/clang/lib/Format/QualifierAlignmentFixer.h b/clang/lib/Format/QualifierAlignmentFixer.h --- a/clang/lib/Format/QualifierAlignmentFixer.h +++ b/clang/lib/Format/QualifierAlignmentFixer.h @@ -25,32 +25,13 @@ const Environment &)> AnalyzerPass; -class QualifierAlignmentFixer : public TokenAnalyzer { - // Left to Right ordering requires multiple passes - SmallVector Passes; - StringRef &Code; - ArrayRef Ranges; - unsigned FirstStartColumn; - unsigned NextStartColumn; - unsigned LastStartColumn; - StringRef FileName; +void addQualifierAlignmentFixerPasses(const FormatStyle &Style, + SmallVectorImpl &Passes); -public: - QualifierAlignmentFixer(const Environment &Env, const FormatStyle &Style, - StringRef &Code, ArrayRef Ranges, - unsigned FirstStartColumn, unsigned NextStartColumn, - unsigned LastStartColumn, StringRef FileName); - - std::pair - analyze(TokenAnnotator &Annotator, - SmallVectorImpl &AnnotatedLines, - FormatTokenLexer &Tokens) override; - - static void PrepareLeftRightOrdering(const std::vector &Order, - std::vector &LeftOrder, - std::vector &RightOrder, - std::vector &Qualifiers); -}; +void prepareLeftRightOrderingForQualifierAlignmentFixer( + const std::vector &Order, std::vector &LeftOrder, + std::vector &RightOrder, + std::vector &Qualifiers); class LeftRightQualifierAlignmentFixer : public TokenAnalyzer { std::string Qualifier; diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -25,18 +25,13 @@ namespace clang { namespace format { -QualifierAlignmentFixer::QualifierAlignmentFixer( - const Environment &Env, const FormatStyle &Style, StringRef &Code, - ArrayRef Ranges, unsigned FirstStartColumn, - unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName) - : TokenAnalyzer(Env, Style), Code(Code), Ranges(Ranges), - FirstStartColumn(FirstStartColumn), NextStartColumn(NextStartColumn), - LastStartColumn(LastStartColumn), FileName(FileName) { +void addQualifierAlignmentFixerPasses(const FormatStyle &Style, + SmallVectorImpl &Passes) { std::vector LeftOrder; std::vector RightOrder; std::vector ConfiguredQualifierTokens; - PrepareLeftRightOrdering(Style.QualifierOrder, LeftOrder, RightOrder, - ConfiguredQualifierTokens); + prepareLeftRightOrderingForQualifierAlignmentFixer( + Style.QualifierOrder, LeftOrder, RightOrder, ConfiguredQualifierTokens); // Handle the left and right alignment separately. for (const auto &Qualifier : LeftOrder) { @@ -59,51 +54,6 @@ } } -std::pair QualifierAlignmentFixer::analyze( - TokenAnnotator & /*Annotator*/, - SmallVectorImpl & /*AnnotatedLines*/, - FormatTokenLexer & /*Tokens*/) { - auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn, - NextStartColumn, LastStartColumn); - if (!Env) - return {}; - std::optional CurrentCode; - tooling::Replacements Fixes; - for (size_t I = 0, E = Passes.size(); I < E; ++I) { - std::pair PassFixes = Passes[I](*Env); - auto NewCode = applyAllReplacements( - CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first); - if (NewCode) { - Fixes = Fixes.merge(PassFixes.first); - if (I + 1 < E) { - CurrentCode = std::move(*NewCode); - Env = Environment::make( - *CurrentCode, FileName, - tooling::calculateRangesAfterReplacements(Fixes, Ranges), - FirstStartColumn, NextStartColumn, LastStartColumn); - if (!Env) - return {}; - } - } - } - - // Don't make replacements that replace nothing. - tooling::Replacements NonNoOpFixes; - - for (const tooling::Replacement &Fix : Fixes) { - StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength()); - - if (!OriginalCode.equals(Fix.getReplacementText())) { - auto Err = NonNoOpFixes.add(Fix); - if (Err) { - llvm::errs() << "Error adding replacements : " - << llvm::toString(std::move(Err)) << "\n"; - } - } - } - return {NonNoOpFixes, 0}; -} - static void replaceToken(const SourceManager &SourceMgr, tooling::Replacements &Fixes, const CharSourceRange &Range, std::string NewText) { @@ -612,7 +562,7 @@ return {Fixes, 0}; } -void QualifierAlignmentFixer::PrepareLeftRightOrdering( +void prepareLeftRightOrderingForQualifierAlignmentFixer( const std::vector &Order, std::vector &LeftOrder, std::vector &RightOrder, std::vector &Qualifiers) { diff --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp --- a/clang/unittests/Format/QualifierFixerTest.cpp +++ b/clang/unittests/Format/QualifierFixerTest.cpp @@ -1016,8 +1016,8 @@ std::vector Left; std::vector Right; std::vector ConfiguredTokens; - QualifierAlignmentFixer::PrepareLeftRightOrdering(Style.QualifierOrder, Left, - Right, ConfiguredTokens); + prepareLeftRightOrderingForQualifierAlignmentFixer(Style.QualifierOrder, Left, + Right, ConfiguredTokens); EXPECT_EQ(Left.size(), (size_t)2); EXPECT_EQ(Right.size(), (size_t)2); @@ -1181,10 +1181,12 @@ Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"static", "const", "type"}; - ReplacementCount = 0; - EXPECT_EQ(ReplacementCount, 0); verifyFormat("static const uint32 foo[] = {0, 31};", Style); + EXPECT_EQ(ReplacementCount, 0); + verifyFormat("#define MACRO static const", Style); + EXPECT_EQ(ReplacementCount, 0); + verifyFormat("using sc = static const", Style); EXPECT_EQ(ReplacementCount, 0); }