[clang-tools-extra] readability-identifier-naming should add universal default options (PR #171686)
Dominik Kaszewski via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 11 11:14:23 PST 2025
https://github.com/dkaszews updated https://github.com/llvm/llvm-project/pull/171686
>From 30a266b21a6e96441886778ab85ebff08a9f68e2 Mon Sep 17 00:00:00 2001
From: Dominik Kaszewski <dakaszewski at gmail.com>
Date: Wed, 10 Dec 2025 20:28:57 +0100
Subject: [PATCH 1/5] Add default config
---
.../readability/IdentifierNamingCheck.cpp | 29 ++++++++++++-------
.../readability/IdentifierNamingCheck.h | 4 +++
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
index 79f8437057b23..3efeade89a4c9 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -71,6 +71,7 @@ namespace readability {
// clang-format off
#define NAMING_KEYS(m) \
+ m(Default) \
m(Namespace) \
m(InlineNamespace) \
m(EnumConstant) \
@@ -1162,7 +1163,7 @@ StyleKind IdentifierNamingCheck::findStyleKind(
if (NamingStyles[SK_Constant])
return SK_Constant;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
if (const auto *Decl = dyn_cast<RecordDecl>(D)) {
@@ -1194,7 +1195,7 @@ StyleKind IdentifierNamingCheck::findStyleKind(
return SK_Enum;
}
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
if (const auto *Decl = dyn_cast<FieldDecl>(D)) {
@@ -1238,7 +1239,7 @@ StyleKind IdentifierNamingCheck::findStyleKind(
if (NamingStyles[SK_Parameter])
return SK_Parameter;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
if (const auto *Decl = dyn_cast<VarDecl>(D)) {
@@ -1284,7 +1285,7 @@ StyleKind IdentifierNamingCheck::findStyleKind(
if (NamingStyles[SK_Function])
return SK_Function;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
if (const auto *Decl = dyn_cast<FunctionDecl>(D)) {
@@ -1308,7 +1309,7 @@ StyleKind IdentifierNamingCheck::findStyleKind(
if (NamingStyles[SK_TemplateParameter])
return SK_TemplateParameter;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
if (isa<NonTypeTemplateParmDecl>(D)) {
@@ -1318,7 +1319,7 @@ StyleKind IdentifierNamingCheck::findStyleKind(
if (NamingStyles[SK_TemplateParameter])
return SK_TemplateParameter;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
if (isa<TemplateTemplateParmDecl>(D)) {
@@ -1328,13 +1329,13 @@ StyleKind IdentifierNamingCheck::findStyleKind(
if (NamingStyles[SK_TemplateParameter])
return SK_TemplateParameter;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
if (isa<ConceptDecl>(D) && NamingStyles[SK_Concept])
return SK_Concept;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
std::optional<RenamerClangTidyCheck::FailureInfo>
@@ -1468,7 +1469,7 @@ StyleKind IdentifierNamingCheck::findStyleKindForAnonField(
return findStyleKindForVar(V, Type, NamingStyles);
}
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
StyleKind IdentifierNamingCheck::findStyleKindForField(
@@ -1494,7 +1495,7 @@ StyleKind IdentifierNamingCheck::findStyleKindForField(
if (NamingStyles[SK_Member])
return SK_Member;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
StyleKind IdentifierNamingCheck::findStyleKindForVar(
@@ -1571,8 +1572,14 @@ StyleKind IdentifierNamingCheck::findStyleKindForVar(
if (NamingStyles[SK_Variable])
return SK_Variable;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
+}
+
+StyleKind IdentifierNamingCheck::undefinedStyle(
+ ArrayRef<std::optional<NamingStyle>> NamingStyles) const {
+ return NamingStyles[SK_Default] ? SK_Default : SK_Invalid;
}
} // namespace readability
} // namespace clang::tidy
+
diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
index 0b17af88810c2..cc05333269b80 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
@@ -220,6 +220,9 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck {
findStyleKindForVar(const VarDecl *Var, QualType Type,
ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
+ StyleKind
+ undefinedStyle(ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
+
/// Stores the style options as a vector, indexed by the specified \ref
/// StyleKind, for a given directory.
mutable llvm::StringMap<FileStyle> NamingStylesCache;
@@ -241,3 +244,4 @@ struct OptionEnumMapping<readability::IdentifierNamingCheck::CaseType> {
} // namespace clang::tidy
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
+
>From 5dada5cefaa683092a9c1afd710e4a851dd94c38 Mon Sep 17 00:00:00 2001
From: Dominik Kaszewski <dakaszewski at gmail.com>
Date: Wed, 10 Dec 2025 21:50:08 +0100
Subject: [PATCH 2/5] WIP tests
---
.../identifier-naming-default-lower.cpp | 26 +++++++++++++++++++
.../identifier-naming-default-none.cpp | 25 ++++++++++++++++++
2 files changed, 51 insertions(+)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
new file mode 100644
index 0000000000000..276bc35a9be10
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN: -config='{CheckOptions: { \
+// RUN: readability-identifier-naming.DefaultCase: "lower_case" }}'
+
+int BadGlobal;
+
+int good_global;
+
+struct BadStruct {
+ int BadField;
+};
+
+struct good_struct {
+ int good_field;
+};
+
+int BadFunction(int BadParameter) {
+ int BadVariable = BadParameter;
+ return BadVariable;
+}
+
+int good_function(int good_parameter) {
+ int good_variable = good_parameter;
+ return good_variable;
+}
+
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp
new file mode 100644
index 0000000000000..8e82abfa61259
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN: -config='{CheckOptions: {}}'
+
+int BadGlobal;
+
+int good_global;
+
+struct BadStruct {
+ int BadField;
+};
+
+struct good_struct {
+ int good_field;
+};
+
+int BadFunction(int BadParameter) {
+ int BadVariable = BadParameter;
+ return BadVariable;
+}
+
+int good_function(int good_parameter) {
+ int good_variable = good_parameter;
+ return good_variable;
+}
+
>From 3fb5b0c3b7713b347c14732d3b4b1975223f41e8 Mon Sep 17 00:00:00 2001
From: Dominik Kaszewski <dakaszewski at gmail.com>
Date: Thu, 11 Dec 2025 19:48:05 +0100
Subject: [PATCH 3/5] Pass lower test
---
.../identifier-naming-default-lower.cpp | 66 +++++++++++++++----
.../identifier-naming-default-none.cpp | 44 +++++++++----
2 files changed, 85 insertions(+), 25 deletions(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
index 276bc35a9be10..167f41c8cf469 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
@@ -1,26 +1,66 @@
// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
// RUN: -config='{CheckOptions: { \
-// RUN: readability-identifier-naming.DefaultCase: "lower_case" }}'
+// RUN: readability-identifier-naming.DefaultCase: "lower_case", \
+// RUN: }}'
-int BadGlobal;
+// DefaultCase enables every type of symbol to be checked with same case
+// TODO: DefaultCase does not work for macros?
+#define MyMacro
-int good_global;
+namespace MyNamespace {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: invalid case style for default 'MyNamespace' [readability-identifier-naming]
+// CHECK-FIXES: namespace my_namespace {
-struct BadStruct {
- int BadField;
+using MyAlias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for default 'MyAlias' [readability-identifier-naming]
+// CHECK-FIXES: using my_alias = int;
+
+int MyGlobal;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for default 'MyGlobal' [readability-identifier-naming]
+// CHECK-FIXES: int my_global;
+
+struct MyStruct {
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for default 'MyStruct' [readability-identifier-naming]
+// CHECK-FIXES: struct my_struct {
+ int MyField;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for default 'MyField' [readability-identifier-naming]
+// CHECK-FIXES: int my_field;
};
-struct good_struct {
- int good_field;
+template <typename MyTypename>
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: invalid case style for default 'MyTypename' [readability-identifier-naming]
+// CHECK-FIXES: template <typename my_typename>
+int MyFunction(int MyArgument) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for default 'MyFunction' [readability-identifier-naming]
+// CHECK-MESSAGES: :[[@LINE-2]]:20: warning: invalid case style for default 'MyArgument' [readability-identifier-naming]
+// CHECK-FIXES: int my_function(int my_argument) {
+ int MyVariable = MyArgument;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for default 'MyVariable' [readability-identifier-naming]
+// CHECK-FIXES: int my_variable = my_argument;
+ return MyVariable;
+// CHECK-FIXES: return my_variable;
+}
+
+}
+
+// These are all already formatted as desired
+#define my_macro_2
+
+namespace my_namespace_2 {
+
+using my_alias = int;
+
+my_alias my_global;
+
+struct my_struct {
+ int my_field;
};
-int BadFunction(int BadParameter) {
- int BadVariable = BadParameter;
- return BadVariable;
+template <typename my_typename>
+int my_function(int my_argument) {
+ int my_variable = my_argument;
+ return my_variable;
}
-int good_function(int good_parameter) {
- int good_variable = good_parameter;
- return good_variable;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp
index 8e82abfa61259..b2370642cd37d 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp
@@ -1,25 +1,45 @@
// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
// RUN: -config='{CheckOptions: {}}'
-int BadGlobal;
+// Empty options effectively disable the check, allowing PascalCase...
+#define MyMacro
-int good_global;
+namespace MyNamespace {
-struct BadStruct {
- int BadField;
+using MyAlias = int;
+
+int MyGlobal;
+
+struct MyStruct {
+ int MyField;
};
-struct good_struct {
- int good_field;
+template <typename MyTypename>
+int MyFunction(int MyArgument) {
+ int MyVariable = MyArgument;
+ return MyVariable;
+}
+
+}
+
+// ...or lower_case for the same set of symbol types
+#define my_macro_2
+
+namespace my_namespace_2 {
+
+using my_alias = int;
+
+my_alias my_global;
+
+struct my_struct {
+ int my_field;
};
-int BadFunction(int BadParameter) {
- int BadVariable = BadParameter;
- return BadVariable;
+template <typename my_typename>
+int my_function(int my_argument) {
+ int my_variable = my_argument;
+ return my_variable;
}
-int good_function(int good_parameter) {
- int good_variable = good_parameter;
- return good_variable;
}
>From 1006949a5f54f62dad37704ac92792353bedcaf6 Mon Sep 17 00:00:00 2001
From: Dominik Kaszewski <dakaszewski at gmail.com>
Date: Thu, 11 Dec 2025 19:57:45 +0100
Subject: [PATCH 4/5] Add default override test
---
.../identifier-naming-default-override.cpp | 72 +++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp
new file mode 100644
index 0000000000000..bf6221122763e
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp
@@ -0,0 +1,72 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN: -config='{CheckOptions: { \
+// RUN: readability-identifier-naming.DefaultCase: "lower_case", \
+// RUN: readability-identifier-naming.MacroDefinitionCase: "UPPER_CASE", \
+// RUN: readability-identifier-naming.TemplateParameterCase: "UPPER_CASE", \
+// RUN: }}'
+
+// DefaultCase enables every type of symbol to be checked with same case
+#define MyMacro
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for macro definition 'MyMacro' [readability-identifier-naming]
+// CHECK-FIXES: #define MY_MACRO
+
+namespace MyNamespace {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: invalid case style for default 'MyNamespace' [readability-identifier-naming]
+// CHECK-FIXES: namespace my_namespace {
+
+using MyAlias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for default 'MyAlias' [readability-identifier-naming]
+// CHECK-FIXES: using my_alias = int;
+
+int MyGlobal;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for default 'MyGlobal' [readability-identifier-naming]
+// CHECK-FIXES: int my_global;
+
+struct MyStruct {
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for default 'MyStruct' [readability-identifier-naming]
+// CHECK-FIXES: struct my_struct {
+ int MyField;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for default 'MyField' [readability-identifier-naming]
+// CHECK-FIXES: int my_field;
+};
+
+template <typename MyTypename>
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: invalid case style for template parameter 'MyTypename' [readability-identifier-naming]
+// CHECK-FIXES: template <typename MY_TYPENAME>
+int MyFunction(int MyArgument) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for default 'MyFunction' [readability-identifier-naming]
+// CHECK-MESSAGES: :[[@LINE-2]]:20: warning: invalid case style for default 'MyArgument' [readability-identifier-naming]
+// CHECK-FIXES: int my_function(int my_argument) {
+ int MyVariable = MyArgument;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for default 'MyVariable' [readability-identifier-naming]
+// CHECK-FIXES: int my_variable = my_argument;
+ return MyVariable;
+// CHECK-FIXES: return my_variable;
+}
+
+}
+
+#define my_macro_2
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for macro definition 'my_macro_2' [readability-identifier-naming]
+// CHECK-FIXES: #define MY_MACRO_2
+
+namespace my_namespace_2 {
+
+using my_alias = int;
+
+my_alias my_global;
+
+struct my_struct {
+ int my_field;
+};
+
+template <typename my_typename>
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: invalid case style for template parameter 'my_typename' [readability-identifier-naming]
+// CHECK-FIXES: template <typename MY_TYPENAME>
+int my_function(int my_argument) {
+ int my_variable = my_argument;
+ return my_variable;
+}
+
+}
+
>From 85f628a714251aa524be97d45458b2a0374b2006 Mon Sep 17 00:00:00 2001
From: Dominik Kaszewski <dakaszewski at gmail.com>
Date: Thu, 11 Dec 2025 20:13:12 +0100
Subject: [PATCH 5/5] Add docs, enable failing macro case
---
.../checks/readability/identifier-naming.rst | 57 +++++++++++++++++++
.../identifier-naming-default-lower.cpp | 5 +-
.../identifier-naming-default-override.cpp | 1 -
3 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst
index 2c0d69f0264e7..f632f89071250 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst
@@ -58,6 +58,9 @@ The available options are summarized below:
**Specific options**
+ - :option:`DefaultCase`, :option:`DefaultPrefix`,
+ :option:`DefaultSuffix`, :option:`DefaultIgnoredRegexp`,
+ :option:`DefaultHungarianPrefix`
- :option:`AbstractClassCase`, :option:`AbstractClassPrefix`,
:option:`AbstractClassSuffix`, :option:`AbstractClassIgnoredRegexp`,
:option:`AbstractClassHungarianPrefix`
@@ -223,6 +226,60 @@ Options description
A detailed description of each option is presented below:
+.. option:: DefaultCase
+
+ When defined, the check will ensure all name by default conform to the
+ selected casing.
+
+.. option:: DefaultPrefix
+
+ When defined, the check will ensure all name by default will add the
+ prefixed with the given value (regardless of casing).
+
+.. option:: DefaultIgnoredRegexp
+
+ Identifier naming checks won't be enforced for all name by default
+ matching this regular expression.
+
+.. option:: DefaultSuffix
+
+ When defined, the check will ensure all name by default will add the
+ suffix with the given value (regardless of casing).
+
+.. option:: DefaultHungarianPrefix
+
+ When enabled, the check ensures that the declared identifier will
+ have a Hungarian notation prefix based on the declared type.
+
+The check only works on kinds of identifiers which have been configured,
+so an empty config effectively disables it.
+The "default" option can be used to enable all kinds of identifiers,
+then optionally override specific kinds which are desired with a different case.
+
+For example using values of:
+
+ - DefaultCase of ``lower_case``
+ - MacroDefinitionCase of ``UPPER_CASE``
+ - TemplateParameterCase of ``CamelCase``
+
+Identifies and/or transforms names as follows:
+
+Before:
+
+.. code-block:: c++
+
+ #define macroDefinition
+ template <typename typenameParameter>
+ int functionDeclaration(typenameParameter paramVal, int paramCount);
+
+After:
+
+.. code-block:: c++
+
+ #define MACRO_DEFINITION
+ template <typename TypenameParameter>
+ int function_declarations(TypenameParameter param_val, int param_count);
+
.. option:: AbstractClassCase
When defined, the check will ensure abstract class names conform to the
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
index 167f41c8cf469..20ea67dd136a5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
@@ -3,9 +3,10 @@
// RUN: readability-identifier-naming.DefaultCase: "lower_case", \
// RUN: }}'
-// DefaultCase enables every type of symbol to be checked with same case
-// TODO: DefaultCase does not work for macros?
+// DefaultCase enables every type of identifier to be checked with same case
#define MyMacro
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for default 'MyMacro' [readability-identifier-naming]
+// CHECK-FIXES: #define my_macro
namespace MyNamespace {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: invalid case style for default 'MyNamespace' [readability-identifier-naming]
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp
index bf6221122763e..71f65c0ce0e14 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp
@@ -5,7 +5,6 @@
// RUN: readability-identifier-naming.TemplateParameterCase: "UPPER_CASE", \
// RUN: }}'
-// DefaultCase enables every type of symbol to be checked with same case
#define MyMacro
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for macro definition 'MyMacro' [readability-identifier-naming]
// CHECK-FIXES: #define MY_MACRO
More information about the cfe-commits
mailing list