Skip to content

Conversation

@owenca
Copy link
Contributor

@owenca owenca commented Nov 9, 2025

Fixes #154846

@llvmbot
Copy link
Member

llvmbot commented Nov 9, 2025

@llvm/pr-subscribers-clang-format

Author: owenca (owenca)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/167191.diff

2 Files Affected:

  • (modified) clang/lib/Format/QualifierAlignmentFixer.cpp (+14-5)
  • (modified) clang/unittests/Format/QualifierFixerTest.cpp (+2)
diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp
index e3e30ca8e2e89..54d90fe2c7f82 100644
--- a/clang/lib/Format/QualifierAlignmentFixer.cpp
+++ b/clang/lib/Format/QualifierAlignmentFixer.cpp
@@ -177,13 +177,16 @@ static bool isQualifier(const FormatToken *const Tok) {
 
 const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
     const SourceManager &SourceMgr, const AdditionalKeywords &Keywords,
-    tooling::Replacements &Fixes, const FormatToken *const Tok,
+    tooling::Replacements &Fixes, const FormatToken *Tok,
     const std::string &Qualifier, tok::TokenKind QualifierType) {
   // We only need to think about streams that begin with a qualifier.
   if (Tok->isNot(QualifierType))
     return Tok;
+
+  const auto *Next = Tok->getNextNonComment();
+
   // Don't concern yourself if nothing follows the qualifier.
-  if (!Tok->Next)
+  if (!Next)
     return Tok;
 
   // Skip qualifiers to the left to find what preceeds the qualifiers.
@@ -247,9 +250,15 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
   }();
 
   // Find the last qualifier to the right.
-  const FormatToken *LastQual = Tok;
-  while (isQualifier(LastQual->getNextNonComment()))
-    LastQual = LastQual->getNextNonComment();
+  const auto *LastQual = Tok;
+  for (; isQualifier(Next); Next = Next->getNextNonComment())
+    LastQual = Next;
+
+  if (!LastQual || !Next ||
+      (LastQual->isOneOf(tok::kw_const, tok::kw_volatile) &&
+       Next->isOneOf(Keywords.kw_override, Keywords.kw_final))) {
+    return Tok;
+  }
 
   // If this qualifier is to the right of a type or pointer do a partial sort
   // and return.
diff --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp
index 58e64ff368946..056373a04232d 100644
--- a/clang/unittests/Format/QualifierFixerTest.cpp
+++ b/clang/unittests/Format/QualifierFixerTest.cpp
@@ -215,6 +215,8 @@ TEST_F(QualifierFixerTest, RightQualifier) {
                Style);
   verifyFormat("void foo() const override;", Style);
   verifyFormat("void foo() const override LLVM_READONLY;", Style);
+  verifyFormat("MOCK_METHOD(ReturnType, myMethod, (int), (const override))",
+               Style);
   verifyFormat("void foo() const final;", Style);
   verifyFormat("void foo() const final LLVM_READONLY;", Style);
   verifyFormat("void foo() const LLVM_READONLY;", Style);

@owenca owenca changed the title 154846 [clang-format] Don't swap (const override) with QAS_Right Nov 9, 2025
@@ -177,13 +177,16 @@ static bool isQualifier(const FormatToken *const Tok) {

const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
const SourceManager &SourceMgr, const AdditionalKeywords &Keywords,
tooling::Replacements &Fixes, const FormatToken *const Tok,
tooling::Replacements &Fixes, const FormatToken *Tok,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep that. We want most of our locals to be const, why not arguments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's superfluous. It's similar to the const in void f(const int);.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clang-format QualifierAlignment=Right breaks qualifiers with MOCK_METHOD

3 participants