[clang-tools-extra] readability-identifier-naming should add universal default options (PR #171686)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 11 11:36:04 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tidy
Author: Dominik Kaszewski (dkaszews)
<details>
<summary>Changes</summary>
Adds a `DefaultCase` (and other options, but `DefaultPrefix/Suffix` is probably not useful), which is used as a base in the override hierarchy.
Resolves #<!-- -->75688
---
Full diff: https://github.com/llvm/llvm-project/pull/171686.diff
6 Files Affected:
- (modified) clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp (+24-12)
- (modified) clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h (+4)
- (modified) clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst (+57)
- (added) clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp (+67)
- (added) clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp (+45)
- (added) clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp (+71)
``````````diff
diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
index 79f8437057b23..3f65fb362af68 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>
@@ -1402,9 +1403,14 @@ IdentifierNamingCheck::getMacroFailureInfo(const Token &MacroNameTok,
if (!Style.isActive())
return std::nullopt;
+ const auto &Styles = Style.getStyles();
+ const StyleKind UsedKind = !Styles[SK_MacroDefinition] && Styles[SK_Default]
+ ? SK_Default
+ : SK_MacroDefinition;
+
return getFailureInfo("", MacroNameTok.getIdentifierInfo()->getName(),
nullptr, Loc, Style.getStyles(), Style.getHNOption(),
- SK_MacroDefinition, SM, IgnoreFailedSplit);
+ UsedKind, SM, IgnoreFailedSplit);
}
RenamerClangTidyCheck::DiagInfo
@@ -1468,7 +1474,7 @@ StyleKind IdentifierNamingCheck::findStyleKindForAnonField(
return findStyleKindForVar(V, Type, NamingStyles);
}
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
StyleKind IdentifierNamingCheck::findStyleKindForField(
@@ -1494,7 +1500,7 @@ StyleKind IdentifierNamingCheck::findStyleKindForField(
if (NamingStyles[SK_Member])
return SK_Member;
- return SK_Invalid;
+ return undefinedStyle(NamingStyles);
}
StyleKind IdentifierNamingCheck::findStyleKindForVar(
@@ -1571,8 +1577,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
+
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
new file mode 100644
index 0000000000000..20ea67dd136a5
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-lower.cpp
@@ -0,0 +1,67 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN: -config='{CheckOptions: { \
+// RUN: readability-identifier-naming.DefaultCase: "lower_case", \
+// RUN: }}'
+
+// 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]
+// 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 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;
+};
+
+template <typename my_typename>
+int my_function(int my_argument) {
+ int my_variable = my_argument;
+ return my_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..b2370642cd37d
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-none.cpp
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN: -config='{CheckOptions: {}}'
+
+// Empty options effectively disable the check, allowing PascalCase...
+#define MyMacro
+
+namespace MyNamespace {
+
+using MyAlias = int;
+
+int MyGlobal;
+
+struct MyStruct {
+ int MyField;
+};
+
+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;
+};
+
+template <typename my_typename>
+int my_function(int my_argument) {
+ int my_variable = my_argument;
+ return my_variable;
+}
+
+}
+
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..71f65c0ce0e14
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-default-override.cpp
@@ -0,0 +1,71 @@
+// 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: }}'
+
+#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;
+}
+
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/171686
More information about the cfe-commits
mailing list