AlexanderHederstaf updated this revision to Diff 501420.
AlexanderHederstaf added a comment.
Distinguish configured qualifiers from other qualifiers.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144709/new/
https://reviews.llvm.org/D144709
Files:
clang/lib/Format/QualifierAlignmentFixer.cpp
clang/lib/Format/QualifierAlignmentFixer.h
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/QualifierFixerTest.cpp
Index: clang/unittests/Format/QualifierFixerTest.cpp
===================================================================
--- clang/unittests/Format/QualifierFixerTest.cpp
+++ clang/unittests/Format/QualifierFixerTest.cpp
@@ -241,7 +241,7 @@
verifyFormat("int const *b;", Style);
verifyFormat("int const &b;", Style);
verifyFormat("int const &&b;", Style);
- verifyFormat("int const *b const;", Style);
+ verifyFormat("int const *const b;", Style);
verifyFormat("int *const c;", Style);
verifyFormat("const Foo a;", Style);
@@ -252,7 +252,7 @@
verifyFormat("Foo const *b;", Style);
verifyFormat("Foo const &b;", Style);
verifyFormat("Foo const &&b;", Style);
- verifyFormat("Foo const *b const;", Style);
+ verifyFormat("Foo const *const b;", Style);
verifyFormat("LLVM_NODISCARD const int &Foo();", Style);
verifyFormat("LLVM_NODISCARD int const &Foo();", Style);
@@ -275,7 +275,7 @@
verifyFormat("int const *b;", Style);
verifyFormat("int const &b;", Style);
verifyFormat("int const &&b;", Style);
- verifyFormat("int const *b const;", Style);
+ verifyFormat("int const *const b;", Style);
verifyFormat("int *const c;", Style);
verifyFormat("Foo const a;", Style);
@@ -286,7 +286,7 @@
verifyFormat("Foo const *b;", Style);
verifyFormat("Foo const &b;", Style);
verifyFormat("Foo const &&b;", Style);
- verifyFormat("Foo const *b const;", Style);
+ verifyFormat("Foo const *const b;", Style);
verifyFormat("Foo *const b;", Style);
verifyFormat("Foo const *const b;", Style);
verifyFormat("auto const v = get_value();", Style);
@@ -303,6 +303,11 @@
verifyFormat("void foo() const final;", Style);
verifyFormat("void foo() const final LLVM_READONLY;", Style);
verifyFormat("void foo() const LLVM_READONLY;", Style);
+ verifyFormat("void foo() const volatile override;", Style);
+ verifyFormat("void foo() const volatile override LLVM_READONLY;", Style);
+ verifyFormat("void foo() const volatile final;", Style);
+ verifyFormat("void foo() const volatile final LLVM_READONLY;", Style);
+ verifyFormat("void foo() const volatile LLVM_READONLY;", Style);
verifyFormat(
"template <typename Func> explicit Action(Action<Func> const &action);",
@@ -343,6 +348,7 @@
verifyFormat("int const volatile;", "volatile const int;", Style);
verifyFormat("int const volatile;", "const volatile int;", Style);
verifyFormat("int const volatile;", "const int volatile;", Style);
+
verifyFormat("int const volatile *restrict;", "volatile const int *restrict;",
Style);
verifyFormat("int const volatile *restrict;", "const volatile int *restrict;",
@@ -350,9 +356,44 @@
verifyFormat("int const volatile *restrict;", "const int volatile *restrict;",
Style);
+ verifyFormat("long long int const volatile;", "const long long int volatile;",
+ Style);
+ verifyFormat("long long int const volatile;", "long const long int volatile;",
+ Style);
+ verifyFormat("long long int const volatile;", "long long volatile int const;",
+ Style);
+ verifyFormat("long long int const volatile;", "long volatile long const int;",
+ Style);
+ verifyFormat("long long int const volatile;", "const long long volatile int;",
+ Style);
+
verifyFormat("static int const bat;", "static const int bat;", Style);
verifyFormat("static int const bat;", "static int const bat;", Style);
+ // static is not configured, unchanged on the left of the right hand
+ // qualifiers.
+ verifyFormat("int static const volatile;", "volatile const int static;",
+ Style);
+ verifyFormat("int static const volatile;", "const volatile int static;",
+ Style);
+ verifyFormat("int static const volatile;", "const int volatile static;",
+ Style);
+ verifyFormat("Foo static const volatile;", "volatile const Foo static;",
+ Style);
+ verifyFormat("Foo static const volatile;", "const volatile Foo static;",
+ Style);
+ verifyFormat("Foo static const volatile;", "const Foo volatile static;",
+ Style);
+
+ verifyFormat("Foo inline static const;", "const Foo inline static;", Style);
+ verifyFormat("Foo inline static const;", "Foo const inline static;", Style);
+ verifyFormat("Foo inline static const;", "Foo inline const static;", Style);
+ verifyFormat("Foo inline static const;", "Foo inline static const;", Style);
+
+ verifyFormat("Foo<T volatile>::Bar<Type const, 5> const volatile A::*;",
+ "volatile const Foo<volatile T>::Bar<const Type, 5> A::*;",
+ Style);
+
verifyFormat("int const Foo<int>::bat = 0;", "const int Foo<int>::bat = 0;",
Style);
verifyFormat("int const Foo<int>::bat = 0;", "int const Foo<int>::bat = 0;",
@@ -418,7 +459,58 @@
verifyFormat("unsigned long long const a;", "const unsigned long long a;",
Style);
- // don't adjust macros
+ // Multiple template parameters.
+ verifyFormat("Bar<std::Foo const, 32>", "Bar<const std::Foo, 32>", Style);
+ // Variable declaration based on template type.
+ verifyFormat("Bar<std::Foo const> bar", "Bar<const std::Foo> bar", Style);
+
+ // Using typename for a nested dependent type name.
+ verifyFormat("typename Foo::iterator const;", "const typename Foo::iterator;",
+ Style);
+
+ // Don't move past C-style struct/class.
+ verifyFormat("void foo(const struct A a);", "void foo(const struct A a);",
+ Style);
+ verifyFormat("void foo(const class A a);", "void foo(const class A a);",
+ Style);
+
+ // Don't move past struct/class combined declaration and variable
+ // definition.
+ verifyFormat("const struct {\n} var;", "const struct {\n} var;", Style);
+ verifyFormat("struct {\n} const var;", "struct {\n} const var;", Style);
+ verifyFormat("const class {\n} var;", "const class {\n} var;", Style);
+ verifyFormat("class {\n} const var;", "class {\n} const var;", Style);
+
+ // Leave left qualifers unchanged for combined declaration and variable
+ // definition.
+ verifyFormat("volatile const class {\n} var;",
+ "volatile const class {\n} var;", Style);
+ verifyFormat("const volatile class {\n} var;",
+ "const volatile class {\n} var;", Style);
+ // Also do no sorting with respect to not-configured tokens.
+ verifyFormat("const static volatile class {\n} var;",
+ "const static volatile class {\n} var;", Style);
+ // Sort right qualifiers for combined declaration and variable definition.
+ verifyFormat("class {\n} const volatile var;",
+ "class {\n} const volatile var;", Style);
+ verifyFormat("class {\n} const volatile var;",
+ "class {\n} volatile const var;", Style);
+ // Static keyword is not configured, should end up on the left of the right
+ // side.
+ verifyFormat("class {\n} static const volatile var;",
+ "class {\n} static const volatile var;", Style);
+ verifyFormat("class {\n} static const volatile var;",
+ "class {\n} volatile static const var;", Style);
+
+ // TODO: Something strange is going on with this formating.
+ verifyFormat("Bar < Foo, Foo const >> ;", "Bar < Foo, const Foo >> ;", Style);
+
+ // Don't move past decltype, typeof, or _Atomic.
+ verifyFormat("const decltype(foo)", "const decltype(foo)", Style);
+ verifyFormat("const typeof(foo)", "const typeof(foo)", Style);
+ verifyFormat("const _Atomic(foo)", "const _Atomic(foo)", Style);
+
+ // Don't adjust macros
verifyFormat("const INTPTR a;", "const INTPTR a;", Style);
// Pointers to members
@@ -445,7 +537,7 @@
verifyFormat("const int *b;", Style);
verifyFormat("const int &b;", Style);
verifyFormat("const int &&b;", Style);
- verifyFormat("const int *b const;", Style);
+ verifyFormat("const int *const b;", Style);
verifyFormat("int *const c;", Style);
verifyFormat("const Foo a;", Style);
@@ -456,7 +548,7 @@
verifyFormat("const Foo *b;", Style);
verifyFormat("const Foo &b;", Style);
verifyFormat("const Foo &&b;", Style);
- verifyFormat("const Foo *b const;", Style);
+ verifyFormat("const Foo *const b;", Style);
verifyFormat("Foo *const b;", Style);
verifyFormat("const Foo *const b;", Style);
@@ -492,6 +584,17 @@
verifyFormat("const volatile int *restrict;", "const int volatile *restrict;",
Style);
+ verifyFormat("const volatile long long int;", "volatile long long int const;",
+ Style);
+ verifyFormat("const volatile long long int;", "volatile long long const int;",
+ Style);
+ verifyFormat("const volatile long long int;", "long long volatile int const;",
+ Style);
+ verifyFormat("const volatile long long int;", "long volatile long int const;",
+ Style);
+ verifyFormat("const volatile long long int;", "const long long volatile int;",
+ Style);
+
verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY;",
Style);
@@ -573,7 +676,51 @@
verifyFormat("const std::Foo < int", "const std::Foo<int", Style);
verifyFormat("const std::Foo<int>", "const std::Foo<int>", Style);
- // don't adjust macros
+ // Multiple template parameters.
+ verifyFormat("Bar<const std::Foo, 32>;", "Bar<std::Foo const, 32>;", Style);
+
+ // Variable declaration based on template type.
+ verifyFormat("Bar<const std::Foo> bar;", "Bar<std::Foo const> bar;", Style);
+
+ // Using typename for a dependent name.
+ verifyFormat("const typename Foo::iterator;", "typename Foo::iterator const;",
+ Style);
+
+ // Don't move past C-style struct/class.
+ verifyFormat("void foo(struct A const a);", "void foo(struct A const a);",
+ Style);
+ verifyFormat("void foo(class A const a);", "void foo(class A const a);",
+ Style);
+
+ // Don't move past struct/class combined declaration and variable
+ // definition.
+ verifyFormat("const struct {\n} var;", "const struct {\n} var;", Style);
+ verifyFormat("struct {\n} const var;", "struct {\n} const var;", Style);
+ verifyFormat("const class {\n} var;", "const class {\n} var;", Style);
+ verifyFormat("class {\n} const var;", "class {\n} const var;", Style);
+
+ // Sort left qualifiers for struct/class combined declaration and variable
+ // definition.
+ verifyFormat("const volatile class {\n} var;",
+ "const volatile class {\n} var;", Style);
+ verifyFormat("const volatile class {\n} var;",
+ "volatile const class {\n} var;", Style);
+ // Leave right qualifers unchanged for struct/class combined declaration and
+ // variable definition.
+ verifyFormat("class {\n} const volatile var;",
+ "class {\n} const volatile var;", Style);
+ verifyFormat("class {\n} volatile const var;",
+ "class {\n} volatile const var;", Style);
+
+ // TODO: Something strange is going on with this formating.
+ verifyFormat("Bar < Foo, const Foo >> ;", "Bar < Foo, Foo const >> ;", Style);
+
+ // Don't move past decltype, typeof, or _Atomic.
+ verifyFormat("decltype(foo) const", "decltype(foo) const", Style);
+ verifyFormat("typeof(foo) const", "typeof(foo) const", Style);
+ verifyFormat("_Atomic(foo) const", "_Atomic(foo) const", Style);
+
+ // Don't adjust macros
verifyFormat("INTPTR const a;", "INTPTR const a;", Style);
// Pointers to members
@@ -601,6 +748,12 @@
verifyFormat("const volatile int a;", "int volatile const a;", Style);
verifyFormat("const volatile int a;", "const int volatile a;", Style);
+ verifyFormat("const volatile Foo a;", "const volatile Foo a;", Style);
+ verifyFormat("const volatile Foo a;", "volatile const Foo a;", Style);
+ verifyFormat("const volatile Foo a;", "Foo const volatile a;", Style);
+ verifyFormat("const volatile Foo a;", "Foo volatile const a;", Style);
+ verifyFormat("const volatile Foo a;", "const Foo volatile a;", Style);
+
Style.QualifierAlignment = FormatStyle::QAS_Right;
Style.QualifierOrder = {"type", "const", "volatile"};
@@ -610,6 +763,12 @@
verifyFormat("int const volatile a;", "int volatile const a;", Style);
verifyFormat("int const volatile a;", "const int volatile a;", Style);
+ verifyFormat("Foo const volatile a;", "const volatile Foo a;", Style);
+ verifyFormat("Foo const volatile a;", "volatile const Foo a;", Style);
+ verifyFormat("Foo const volatile a;", "Foo const volatile a;", Style);
+ verifyFormat("Foo const volatile a;", "Foo volatile const a;", Style);
+ verifyFormat("Foo const volatile a;", "const Foo volatile a;", Style);
+
Style.QualifierAlignment = FormatStyle::QAS_Left;
Style.QualifierOrder = {"volatile", "const", "type"};
@@ -619,6 +778,12 @@
verifyFormat("volatile const int a;", "int volatile const a;", Style);
verifyFormat("volatile const int a;", "const int volatile a;", Style);
+ verifyFormat("volatile const Foo a;", "const volatile Foo a;", Style);
+ verifyFormat("volatile const Foo a;", "volatile const Foo a;", Style);
+ verifyFormat("volatile const Foo a;", "Foo const volatile a;", Style);
+ verifyFormat("volatile const Foo a;", "Foo volatile const a;", Style);
+ verifyFormat("volatile const Foo a;", "const Foo volatile a;", Style);
+
Style.QualifierAlignment = FormatStyle::QAS_Right;
Style.QualifierOrder = {"type", "volatile", "const"};
@@ -628,6 +793,12 @@
verifyFormat("int volatile const a;", "int volatile const a;", Style);
verifyFormat("int volatile const a;", "const int volatile a;", Style);
+ verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style);
+ verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style);
+ verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style);
+ verifyFormat("Foo volatile const a;", "Foo volatile const a;", Style);
+ verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style);
+
Style.QualifierAlignment = FormatStyle::QAS_Custom;
Style.QualifierOrder = {"type", "volatile", "const"};
@@ -636,6 +807,12 @@
verifyFormat("int volatile const a;", "int const volatile a;", Style);
verifyFormat("int volatile const a;", "int volatile const a;", Style);
verifyFormat("int volatile const a;", "const int volatile a;", Style);
+
+ verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style);
+ verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style);
+ verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style);
+ verifyFormat("Foo volatile const a;", "Foo volatile const a;", Style);
+ verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style);
}
TEST_F(QualifierFixerTest, InlineStatics) {
@@ -691,16 +868,16 @@
verifyFormat("const int a;", "int const a;", Style);
verifyFormat("const int *a;", "int const *a;", Style);
- verifyFormat("const int *a const;", "int const *a const;", Style);
+ verifyFormat("const int *const a;", "int const *const a;", Style);
verifyFormat("const int a = foo();", "int const a = foo();", Style);
verifyFormat("const int *a = foo();", "int const *a = foo();", Style);
- verifyFormat("const int *a const = foo();", "int const *a const = foo();",
+ verifyFormat("const int *const a = foo();", "int const *const a = foo();",
Style);
verifyFormat("const auto a = foo();", "auto const a = foo();", Style);
verifyFormat("const auto *a = foo();", "auto const *a = foo();", Style);
- verifyFormat("const auto *a const = foo();", "auto const *a const = foo();",
+ verifyFormat("const auto *const a = foo();", "auto const *const a = foo();",
Style);
}
@@ -722,8 +899,22 @@
verifyFormat("static inline int const volatile a;",
"const int inline static volatile a;", Style);
- verifyFormat("static inline int const volatile *a const;",
- "const int inline static volatile *a const;", Style);
+ verifyFormat("static inline int const volatile *const a;",
+ "const int inline static volatile *const a;", Style);
+
+ verifyFormat("static inline Foo const volatile a;",
+ "const inline static volatile Foo a;", Style);
+ verifyFormat("static inline Foo const volatile a;",
+ "volatile inline static const Foo a;", Style);
+ verifyFormat("static inline Foo const volatile a;",
+ "Foo const inline static volatile a;", Style);
+ verifyFormat("static inline Foo const volatile a;",
+ "Foo volatile inline static const a;", Style);
+ verifyFormat("static inline Foo const volatile a;",
+ "const Foo inline static volatile a;", Style);
+
+ verifyFormat("static inline Foo const volatile *const a;",
+ "const Foo inline static volatile *const a;", Style);
}
TEST_F(QualifierFixerTest, PrepareLeftRightOrdering) {
@@ -759,41 +950,65 @@
auto Tokens = annotate(
"const static inline auto restrict int double long constexpr friend");
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[0], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[1], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[2], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[3], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[4], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[5], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[6], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[7], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[8], ConfiguredTokens));
- EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
Tokens[9], ConfiguredTokens));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[0]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[1]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[2]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[3]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[4]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[5]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[6]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[7]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[8]));
+ EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[9]));
+
auto NotTokens = annotate("for while do Foo Bar ");
- EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
NotTokens[0], ConfiguredTokens));
- EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
NotTokens[1], ConfiguredTokens));
- EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
NotTokens[2], ConfiguredTokens));
- EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
NotTokens[3], ConfiguredTokens));
- EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
NotTokens[4], ConfiguredTokens));
- EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
+ EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
NotTokens[5], ConfiguredTokens));
+
+ EXPECT_FALSE(
+ LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[0]));
+ EXPECT_FALSE(
+ LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[1]));
+ EXPECT_FALSE(
+ LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[2]));
+ EXPECT_FALSE(
+ LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[3]));
+ EXPECT_FALSE(
+ LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[4]));
+ EXPECT_FALSE(
+ LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[5]));
}
TEST_F(QualifierFixerTest, IsMacro) {
@@ -819,7 +1034,7 @@
FormatStyle Style = getLLVMStyle();
Style.QualifierAlignment = FormatStyle::QAS_Left;
- Style.QualifierOrder = {"const", "type"};
+ Style.QualifierOrder = {"const", "volatile", "type"};
verifyFormat("inline static const int a;", Style);
@@ -830,6 +1045,28 @@
Style);
verifyFormat("static const int a;", "const static int a;", Style);
+
+ Style.QualifierOrder = {"const", "volatile", "type"};
+ // static is not configured, unchanged at right hand qualifiers.
+ verifyFormat("const volatile int static;", "int volatile static const;",
+ Style);
+ verifyFormat("const volatile int static;", "int const static volatile;",
+ Style);
+ verifyFormat("const volatile int static;", "const int static volatile;",
+ Style);
+ verifyFormat("const volatile Foo static;", "Foo volatile static const;",
+ Style);
+ verifyFormat("const volatile Foo static;", "Foo const static volatile;",
+ Style);
+ verifyFormat("const volatile Foo static;", "const Foo static volatile;",
+ Style);
+
+ verifyFormat("inline static const Foo;", "inline static Foo const;", Style);
+ verifyFormat("inline static const Foo;", "inline static const Foo;", Style);
+
+ // Don't move qualifiers to the right for aestethics only.
+ verifyFormat("inline const static Foo;", "inline const static Foo;", Style);
+ verifyFormat("const inline static Foo;", "const inline static Foo;", Style);
}
TEST_F(QualifierFixerTest, UnsignedQualifier) {
@@ -944,12 +1181,18 @@
Style.QualifierAlignment = FormatStyle::QAS_Custom;
Style.QualifierOrder = {"type", "const"};
+ verifyFormat("template <typename T> Foo const f();",
+ "template <typename T> const Foo f();", Style);
+ verifyFormat("template <typename T> int const f();",
+ "template <typename T> const int f();", Style);
+
+ verifyFormat("template <T const> t;", "template <const T> t;", Style);
verifyFormat("template <typename T>\n"
" requires Concept<T const>\n"
- "void f();",
+ "Foo const f();",
"template <typename T>\n"
" requires Concept<const T>\n"
- "void f();",
+ "const Foo f();",
Style);
verifyFormat("TemplateType<T const> t;", "TemplateType<const T> t;", Style);
verifyFormat("TemplateType<Container const> t;",
@@ -959,15 +1202,27 @@
TEST_F(QualifierFixerTest, TemplatesLeft) {
FormatStyle Style = getLLVMStyle();
Style.QualifierAlignment = FormatStyle::QAS_Custom;
- Style.QualifierOrder = {"const", "type"};
+ Style.QualifierOrder = {"const", "volatile", "type"};
+
+ verifyFormat("template <typename T> const Foo f();",
+ "template <typename T> Foo const f();", Style);
+ verifyFormat("template <typename T> const int f();",
+ "template <typename T> int const f();", Style);
verifyFormat("template <const T> t;", "template <T const> t;", Style);
verifyFormat("template <typename T>\n"
" requires Concept<const T>\n"
- "void f();",
+ "const Foo f();",
+ "template <typename T>\n"
+ " requires Concept<T const>\n"
+ "Foo const f();",
+ Style);
+ verifyFormat("template <typename T>\n"
+ " requires Concept<const T>\n"
+ "const volatile Foo f();",
"template <typename T>\n"
" requires Concept<T const>\n"
- "void f();",
+ "volatile const Foo f();",
Style);
verifyFormat("TemplateType<const T> t;", "TemplateType<T const> t;", Style);
verifyFormat("TemplateType<const Container> t;",
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -199,6 +199,7 @@
CurrentToken->setType(TT_DictLiteral);
} else {
CurrentToken->setType(TT_TemplateCloser);
+ CurrentToken->Tok.setLength(1);
}
if (CurrentToken->Next && CurrentToken->Next->Tok.isLiteral())
return false;
Index: clang/lib/Format/QualifierAlignmentFixer.h
===================================================================
--- clang/lib/Format/QualifierAlignmentFixer.h
+++ clang/lib/Format/QualifierAlignmentFixer.h
@@ -86,11 +86,13 @@
const std::string &Qualifier,
tok::TokenKind QualifierType);
- // is the Token a simple or qualifier type
- static bool isQualifierOrType(const FormatToken *Tok,
- const std::vector<tok::TokenKind> &Qualifiers);
+ // Is the Token a simple or qualifier type
+ static bool isQualifierOrType(const FormatToken *Tok);
+ static bool
+ isConfiguredQualifierOrType(const FormatToken *Tok,
+ const std::vector<tok::TokenKind> &Qualifiers);
- // is the Token likely a Macro
+ // Is the Token likely a Macro
static bool isPossibleMacro(const FormatToken *Tok);
};
Index: clang/lib/Format/QualifierAlignmentFixer.cpp
===================================================================
--- clang/lib/Format/QualifierAlignmentFixer.cpp
+++ clang/lib/Format/QualifierAlignmentFixer.cpp
@@ -128,14 +128,12 @@
tooling::Replacements &Fixes,
const FormatToken *First,
const std::string &Qualifier) {
- FormatToken *Next = First->Next;
- if (!Next)
- return;
- auto Range = CharSourceRange::getCharRange(Next->getStartOfNonWhitespace(),
- Next->Tok.getEndLoc());
+ auto Range = CharSourceRange::getCharRange(First->Tok.getLocation(),
+ First->Tok.getEndLoc());
- std::string NewText = " " + Qualifier + " ";
- NewText += Next->TokenText;
+ std::string NewText{};
+ NewText += First->TokenText;
+ NewText += " " + Qualifier;
replaceToken(SourceMgr, Fixes, Range, NewText);
}
@@ -204,9 +202,33 @@
replaceToken(SourceMgr, Fixes, Range, NewText);
}
+static bool
+isConfiguredQualifier(const FormatToken *const Tok,
+ const std::vector<tok::TokenKind> &Qualifiers) {
+ return Tok && llvm::is_contained(Qualifiers, Tok->Tok.getKind());
+}
+
+static bool isQualifier(const FormatToken *const Tok) {
+ if (!Tok)
+ return false;
+
+ switch (Tok->Tok.getKind()) {
+ case tok::kw_const:
+ case tok::kw_volatile:
+ case tok::kw_static:
+ case tok::kw_inline:
+ case tok::kw_constexpr:
+ case tok::kw_restrict:
+ case tok::kw_friend:
+ return true;
+ default:
+ return false;
+ }
+}
+
const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
const SourceManager &SourceMgr, const AdditionalKeywords &Keywords,
- tooling::Replacements &Fixes, const FormatToken *Tok,
+ tooling::Replacements &Fixes, const FormatToken *const Tok,
const std::string &Qualifier, tok::TokenKind QualifierType) {
// We only need to think about streams that begin with a qualifier.
if (!Tok->is(QualifierType))
@@ -214,65 +236,139 @@
// Don't concern yourself if nothing follows the qualifier.
if (!Tok->Next)
return Tok;
- if (LeftRightQualifierAlignmentFixer::isPossibleMacro(Tok->Next))
- return Tok;
- auto AnalyzeTemplate =
- [&](const FormatToken *Tok,
- const FormatToken *StartTemplate) -> const FormatToken * {
- // Read from the TemplateOpener to TemplateCloser.
- FormatToken *EndTemplate = StartTemplate->MatchingParen;
- if (EndTemplate) {
- // Move to the end of any template class members e.g.
- // `Foo<int>::iterator`.
- if (EndTemplate->startsSequence(TT_TemplateCloser, tok::coloncolon,
- tok::identifier)) {
- EndTemplate = EndTemplate->Next->Next;
- }
+ // Skip qualifiers to the left to find what preceeds the qualifiers.
+ // Use isQualifier rather than isConfiguredQualifier to cover all qualifiers.
+ const FormatToken *PreviousCheck = Tok->Previous;
+ while (isQualifier(PreviousCheck))
+ PreviousCheck = PreviousCheck->Previous;
+
+ // Examples given in order of ['type', 'const', 'volatile']
+ const bool IsRightQualifier = PreviousCheck && [PreviousCheck]() {
+ // The cases:
+ // `Foo() const` -> `Foo() const`
+ // `Foo() const final` -> `Foo() const final`
+ // `Foo() const override` -> `Foo() const final`
+ // `Foo() const volatile override` -> `Foo() const volatile override`
+ // `Foo() volatile const final` -> `Foo() const volatile final`
+ if (PreviousCheck->is(tok::r_paren))
+ return true;
+
+ // The cases:
+ // `struct {} volatile const a;` -> `struct {} const volatile a;`
+ // `class {} volatile const a;` -> `class {} const volatile a;`
+ if (PreviousCheck->is(tok::r_brace))
+ return true;
+
+ // The case:
+ // `template <class T> const Bar Foo()` ->
+ // `template <class T> Bar const Foo()`
+ // The cases:
+ // `Foo<int> const foo` -> `Foo<int> const foo`
+ // `Foo<int> volatile const` -> `Foo<int> const volatile`
+ // The case:
+ // ```
+ // template <class T>
+ // requires Concept1<T> && requires Concept2<T>
+ // const Foo f();
+ // ```
+ // ->
+ // ```
+ // template <class T>
+ // requires Concept1<T> && requires Concept2<T>
+ // Foo const f();
+ // ```
+ if (PreviousCheck->is(TT_TemplateCloser)) {
+ // If the token closes a template<> or requires clause, then it is a left
+ // qualifier and should be moved to the right.
+ return !(PreviousCheck->ClosesTemplateDeclaration ||
+ PreviousCheck->ClosesRequiresClause);
}
- if (EndTemplate && EndTemplate->Next &&
- !EndTemplate->Next->isOneOf(tok::equal, tok::l_paren)) {
- insertQualifierAfter(SourceMgr, Fixes, EndTemplate, Qualifier);
- // Remove the qualifier.
- removeToken(SourceMgr, Fixes, Tok);
- return Tok;
+
+ // The case `Foo* const` -> `Foo* const`
+ // The case `Foo* volatile const` -> `Foo* const volatile`
+ // The case `int32_t const` -> `int32_t const`
+ // The case `auto volatile const` -> `auto const volatile`
+ if (PreviousCheck->isOneOf(TT_PointerOrReference, tok::identifier,
+ tok::kw_auto)) {
+ return true;
}
- return nullptr;
- };
-
- FormatToken *Qual = Tok->Next;
- FormatToken *LastQual = Qual;
- while (Qual && isQualifierOrType(Qual, ConfiguredQualifierTokens)) {
- LastQual = Qual;
- Qual = Qual->Next;
+
+ return false;
+ }();
+
+ // Find the last qualifier to the right.
+ const FormatToken *LastQual = Tok;
+ while (isQualifier(LastQual->Next))
+ LastQual = LastQual->Next;
+
+ // If this qualifier is to the right of a type or pointer do a partial sort
+ // and return.
+ if (IsRightQualifier) {
+ if (LastQual != Tok)
+ rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false);
+ return Tok;
+ }
+
+ const FormatToken *TypeToken = LastQual->Next;
+ if (!TypeToken)
+ return Tok;
+
+ // Stay safe and don't move past macros, also don't bother with sorting.
+ if (isPossibleMacro(TypeToken))
+ return Tok;
+
+ // The case `const long long int volatile` -> `long long int const volatile`
+ // The case `long const long int volatile` -> `long long int const volatile`
+ // The case `long long volatile int const` -> `long long int const volatile`
+ // The case `const long long volatile int` -> `long long int const volatile`
+ if (TypeToken->isSimpleTypeSpecifier()) {
+ // The case `const decltype(foo)` -> `const decltype(foo)`
+ // The case `const typeof(foo)` -> `const typeof(foo)`
+ // The case `const _Atomic(foo)` -> `const _Atomic(foo)`
+ if (TypeToken->isOneOf(tok::kw_decltype, tok::kw_typeof, tok::kw__Atomic))
+ return Tok;
+
+ const FormatToken *LastSimpleTypeSpecifier = TypeToken;
+ while (isQualifierOrType(LastSimpleTypeSpecifier->Next))
+ LastSimpleTypeSpecifier = LastSimpleTypeSpecifier->Next;
+
+ rotateTokens(SourceMgr, Fixes, Tok, LastSimpleTypeSpecifier,
+ /*Left=*/false);
+ return LastSimpleTypeSpecifier;
}
- if (LastQual && Qual != LastQual) {
- rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false);
- Tok = LastQual;
- } else if (Tok->startsSequence(QualifierType, tok::identifier,
- TT_TemplateCloser)) {
- FormatToken *Closer = Tok->Next->Next;
- rotateTokens(SourceMgr, Fixes, Tok, Tok->Next, /*Left=*/false);
- Tok = Closer;
+
+ // The case `unsigned short const` -> `unsigned short const`
+ // The case:
+ // `unsigned short volatile const` -> `unsigned short const volatile`
+ if (PreviousCheck && PreviousCheck->isSimpleTypeSpecifier()) {
+ if (LastQual != Tok)
+ rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false);
+ return Tok;
+ }
+
+ // Skip the initial :: of a global-namespace type.
+ // The case `const ::...` -> `::... const`
+ if (TypeToken->is(tok::coloncolon))
+ TypeToken = TypeToken->Next;
+
+ // Skip the typename, class, and struct keywords.
+ // The case `const typename C::type` -> `typename C::type const`
+ // The case `void foo(const struct A)` -> `void foo(struct A const)`
+ // The case `void foo(const class A)` -> `void foo(class A const)`
+ if (TypeToken->is(tok::kw_typename))
+ TypeToken = TypeToken->Next;
+
+ // Don't change declarations such as
+ // `foo(const struct Foo a);` -> `foo(const struct Foo a);`
+ // as they would currently change code such as
+ // `const struct my_struct_t {} my_struct;` -> `struct my_struct_t const {}
+ // my_struct;`
+ if (TypeToken->isOneOf(tok::kw_struct, tok::kw_class))
return Tok;
- } else if (Tok->startsSequence(QualifierType, tok::identifier,
- TT_TemplateOpener)) {
- // `const ArrayRef<int> a;`
- // `const ArrayRef<int> &a;`
- const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next);
- if (NewTok)
- return NewTok;
- } else if (Tok->startsSequence(QualifierType, tok::coloncolon,
- tok::identifier, TT_TemplateOpener)) {
- // `const ::ArrayRef<int> a;`
- // `const ::ArrayRef<int> &a;`
- const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next->Next);
- if (NewTok)
- return NewTok;
- } else if (Tok->startsSequence(QualifierType, tok::identifier) ||
- Tok->startsSequence(QualifierType, tok::coloncolon,
- tok::identifier)) {
- FormatToken *Next = Tok->Next;
+
+ if (TypeToken->isOneOf(tok::kw_auto, tok::identifier)) {
+ // The case `const auto` -> `auto const`
// The case `const Foo` -> `Foo const`
// The case `const ::Foo` -> `::Foo const`
// The case `const Foo *` -> `Foo const *`
@@ -280,30 +376,28 @@
// The case `const Foo &&` -> `Foo const &&`
// The case `const std::Foo &&` -> `std::Foo const &&`
// The case `const std::Foo<T> &&` -> `std::Foo<T> const &&`
- // However, `const Bar::*` remains the same.
- while (Next && Next->isOneOf(tok::identifier, tok::coloncolon) &&
- !Next->startsSequence(tok::coloncolon, tok::star)) {
- Next = Next->Next;
- }
- if (Next && Next->is(TT_TemplateOpener)) {
- Next = Next->MatchingParen;
- // Move to the end of any template class members e.g.
- // `Foo<int>::iterator`.
- if (Next && Next->startsSequence(TT_TemplateCloser, tok::coloncolon,
- tok::identifier)) {
- return Tok;
+ while (TypeToken->Next &&
+ (TypeToken->Next->startsSequence(tok::coloncolon, tok::identifier) ||
+ TypeToken->Next->is(TT_TemplateOpener))) {
+ if (TypeToken->Next->is(TT_TemplateOpener)) {
+ assert(TypeToken->Next->MatchingParen && "Missing template closer");
+ TypeToken = TypeToken->Next->MatchingParen;
+ } else {
+ TypeToken = TypeToken->Next->Next;
}
- assert(Next && "Missing template opener");
- Next = Next->Next;
}
- if (Next && Next->isOneOf(tok::star, tok::amp, tok::ampamp) &&
- !Tok->Next->isOneOf(Keywords.kw_override, Keywords.kw_final)) {
- if (Next->Previous && !Next->Previous->is(QualifierType)) {
- insertQualifierAfter(SourceMgr, Fixes, Next->Previous, Qualifier);
- removeToken(SourceMgr, Fixes, Tok);
- }
- return Next;
+
+ // Place the Qualifier at the end of the list of qualifiers.
+ while (isQualifier(TypeToken->Next)) {
+ // The case `volatile Foo::iter const` -> `Foo::iter const volatile`
+ TypeToken = TypeToken->Next;
}
+
+ insertQualifierAfter(SourceMgr, Fixes, TypeToken, Qualifier);
+ // Remove token and following whitespace.
+ auto Range = CharSourceRange::getCharRange(
+ Tok->getStartOfNonWhitespace(), Tok->Next->getStartOfNonWhitespace());
+ replaceToken(SourceMgr, Fixes, Range, "");
}
return Tok;
@@ -311,98 +405,116 @@
const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft(
const SourceManager &SourceMgr, const AdditionalKeywords &Keywords,
- tooling::Replacements &Fixes, const FormatToken *Tok,
+ tooling::Replacements &Fixes, const FormatToken *const Tok,
const std::string &Qualifier, tok::TokenKind QualifierType) {
- // if Tok is an identifier and possibly a macro then don't convert.
- if (LeftRightQualifierAlignmentFixer::isPossibleMacro(Tok))
+ // We only need to think about streams that begin with a qualifier.
+ if (!Tok->is(QualifierType))
+ return Tok;
+ // Don't concern yourself if nothing preceeds the qualifier.
+ if (!Tok->Previous)
return Tok;
- const FormatToken *Qual = Tok;
- const FormatToken *LastQual = Qual;
- while (Qual && isQualifierOrType(Qual, ConfiguredQualifierTokens)) {
- LastQual = Qual;
- Qual = Qual->Next;
- if (Qual && Qual->is(QualifierType))
- break;
+ // Skip qualifiers to the left to find what preceeds the qualifiers.
+ const FormatToken *TypeToken = Tok->Previous;
+ while (isQualifier(TypeToken))
+ TypeToken = TypeToken->Previous;
+
+ // For left qualifiers preceeded by nothing, a template declaration, or *,&,&&
+ // we only perform sorting.
+ if (!TypeToken || TypeToken->isOneOf(tok::star, tok::amp, tok::ampamp) ||
+ TypeToken->ClosesRequiresClause || TypeToken->ClosesTemplateDeclaration) {
+
+ // Don't sort past a non-configured qualifier token.
+ const FormatToken *FirstQual = Tok;
+ while (
+ isConfiguredQualifier(FirstQual->Previous, ConfiguredQualifierTokens)) {
+ FirstQual = FirstQual->Previous;
+ }
+ if (FirstQual != Tok)
+ rotateTokens(SourceMgr, Fixes, FirstQual, Tok, /*Left=*/true);
+ return Tok;
}
- if (!Qual)
+ // Stay safe and don't move past macros, also don't bother with sorting.
+ if (isPossibleMacro(TypeToken))
return Tok;
- if (LastQual && Qual != LastQual && Qual->is(QualifierType)) {
- rotateTokens(SourceMgr, Fixes, Tok, Qual, /*Left=*/true);
- if (!Qual->Next)
- return Tok;
- Tok = Qual->Next;
- } else if (Tok->startsSequence(tok::identifier, QualifierType)) {
- if (Tok->Next->Next && Tok->Next->Next->isOneOf(tok::identifier, tok::star,
- tok::amp, tok::ampamp)) {
- // Don't swap `::iterator const` to `::const iterator`.
- if (!Tok->Previous ||
- (Tok->Previous && !Tok->Previous->is(tok::coloncolon))) {
- rotateTokens(SourceMgr, Fixes, Tok, Tok->Next, /*Left=*/true);
- Tok = Tok->Next;
- }
- } else if (Tok->startsSequence(tok::identifier, QualifierType,
- TT_TemplateCloser)) {
- FormatToken *Closer = Tok->Next->Next;
- rotateTokens(SourceMgr, Fixes, Tok, Tok->Next, /*Left=*/true);
- Tok = Closer;
+ // Examples given in order of ['const', 'volatile', 'type']
+
+ // The case `volatile long long int const` -> `const volatile long long int`
+ // The case `volatile long long const int` -> `const volatile long long int`
+ // The case `const long long volatile int` -> `const volatile long long int`
+ // The case `long volatile long int const` -> `const volatile long long int`
+ if (TypeToken->isSimpleTypeSpecifier()) {
+ const FormatToken *LastSimpleTypeSpecifier = TypeToken;
+ while (isConfiguredQualifierOrType(LastSimpleTypeSpecifier->Previous,
+ ConfiguredQualifierTokens)) {
+ LastSimpleTypeSpecifier = LastSimpleTypeSpecifier->Previous;
}
+
+ rotateTokens(SourceMgr, Fixes, LastSimpleTypeSpecifier, Tok,
+ /*Left=*/true);
+ return Tok;
}
- if (Tok->is(TT_TemplateOpener) && Tok->Next &&
- (Tok->Next->is(tok::identifier) || Tok->Next->isSimpleTypeSpecifier()) &&
- Tok->Next->Next && Tok->Next->Next->is(QualifierType)) {
- rotateTokens(SourceMgr, Fixes, Tok->Next, Tok->Next->Next, /*Left=*/true);
- }
- if ((Tok->startsSequence(tok::coloncolon, tok::identifier) ||
- Tok->is(tok::identifier)) &&
- Tok->Next) {
- if (Tok->Previous &&
- Tok->Previous->isOneOf(tok::star, tok::ampamp, tok::amp)) {
- return Tok;
- }
- const FormatToken *Next = Tok->Next;
- // The case `std::Foo<T> const` -> `const std::Foo<T> &&`
- while (Next && Next->isOneOf(tok::identifier, tok::coloncolon))
- Next = Next->Next;
- if (Next && Next->Previous &&
- Next->Previous->startsSequence(tok::identifier, TT_TemplateOpener)) {
- // Read from to the end of the TemplateOpener to
- // TemplateCloser const ArrayRef<int> a; const ArrayRef<int> &a;
- if (Next->is(tok::comment) && Next->getNextNonComment())
- Next = Next->getNextNonComment();
- assert(Next->MatchingParen && "Missing template closer");
- Next = Next->MatchingParen;
-
- // If the template closer is closing the requires clause,
- // then stop and go back to the TemplateOpener and do whatever is
- // inside the <>.
- if (Next->ClosesRequiresClause)
- return Next->MatchingParen;
- Next = Next->Next;
-
- // Move to the end of any template class members e.g.
- // `Foo<int>::iterator`.
- if (Next && Next->startsSequence(tok::coloncolon, tok::identifier))
- Next = Next->Next->Next;
- if (Next && Next->is(QualifierType)) {
- // Move the qualifier.
- insertQualifierBefore(SourceMgr, Fixes, Tok, Qualifier);
- removeToken(SourceMgr, Fixes, Next);
- return Next;
+
+ if (TypeToken->isOneOf(tok::kw_auto, tok::identifier, TT_TemplateCloser)) {
+ const auto IsStartOfType = [](const FormatToken *const Tok) -> bool {
+ if (!Tok)
+ return true;
+
+ // A template closer is not the start of a type.
+ // The case `?<> const` -> `const ?<>`
+ if (Tok->is(TT_TemplateCloser))
+ return false;
+
+ // An identifier preceeded by :: is not the start of a type.
+ // The case `?::Foo const` -> `const ?::Foo`
+ if (Tok->is(tok::identifier) && Tok->Previous &&
+ Tok->Previous->is(tok::coloncolon)) {
+ return false;
}
- }
- if (Next && Next->Next &&
- Next->Next->isOneOf(tok::amp, tok::ampamp, tok::star)) {
- if (Next->is(QualifierType)) {
- // Move the qualifier.
- insertQualifierBefore(SourceMgr, Fixes, Tok, Qualifier);
- removeToken(SourceMgr, Fixes, Next);
- return Next;
+
+ return true;
+ };
+
+ while (!IsStartOfType(TypeToken)) {
+ // The case `?<>`
+ if (TypeToken->is(TT_TemplateCloser)) {
+ assert(TypeToken->MatchingParen && "Missing template opener");
+ TypeToken = TypeToken->MatchingParen->Previous;
+ } else {
+ // The cases `?::Foo`
+ const FormatToken *const BeforeColonColon =
+ TypeToken->Previous->Previous;
+ if (!BeforeColonColon ||
+ !BeforeColonColon->isOneOf(TT_TemplateCloser, tok::identifier)) {
+ TypeToken = TypeToken->Previous;
+ } else {
+ TypeToken = TypeToken->Previous->Previous;
+ }
}
}
+
+ assert(TypeToken && "Should be auto or identifier");
+
+ // Place the Qualifier at the start of the list of qualifiers.
+ while (
+ isConfiguredQualifier(TypeToken->Previous, ConfiguredQualifierTokens) ||
+ (TypeToken->Previous && TypeToken->Previous->is(tok::kw_typename))) {
+ // The case `volatile Foo::iter const` -> `const volatile Foo::iter`
+ // The case `typename C::type const` -> `const typename C::type`
+ TypeToken = TypeToken->Previous;
+ }
+
+ // Don't change declarations such as
+ // `foo(struct Foo const a);` -> `foo(struct Foo const a);`
+ if (!TypeToken->Previous ||
+ !TypeToken->Previous->isOneOf(tok::kw_struct, tok::kw_class)) {
+ insertQualifierBefore(SourceMgr, Fixes, TypeToken, Qualifier);
+ removeToken(SourceMgr, Fixes, Tok);
+ }
}
+
return Tok;
}
@@ -502,9 +614,16 @@
}
bool LeftRightQualifierAlignmentFixer::isQualifierOrType(
- const FormatToken *Tok, const std::vector<tok::TokenKind> &specifiedTypes) {
+ const FormatToken *const Tok) {
+ return Tok && (Tok->isSimpleTypeSpecifier() || Tok->is(tok::kw_auto) ||
+ isQualifier(Tok));
+}
+
+bool LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
+ const FormatToken *const Tok,
+ const std::vector<tok::TokenKind> &Qualifiers) {
return Tok && (Tok->isSimpleTypeSpecifier() || Tok->is(tok::kw_auto) ||
- llvm::is_contained(specifiedTypes, Tok->Tok.getKind()));
+ isConfiguredQualifier(Tok, Qualifiers));
}
// If a token is an identifier and it's upper case, it could
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits