diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h @@ -44,7 +44,8 @@ CT_UpperCase, CT_CamelCase, CT_CamelSnakeCase, - CT_CamelSnakeBack + CT_CamelSnakeBack, + CT_LeadingUpperSnakeCase }; enum HungarianPrefixType { diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -46,7 +46,9 @@ {readability::IdentifierNamingCheck::CT_CamelSnakeCase, "Camel_Snake_Case"}, {readability::IdentifierNamingCheck::CT_CamelSnakeBack, - "camel_Snake_Back"}}; + "camel_Snake_Back"}, + {readability::IdentifierNamingCheck::CT_LeadingUpperSnakeCase, + "Leading_upper_snake_case"}}; return {Mapping}; } @@ -871,6 +873,7 @@ llvm::Regex("^[A-Z][a-zA-Z0-9]*$"), llvm::Regex("^[A-Z]([a-z0-9]*(_[A-Z])?)*"), llvm::Regex("^[a-z]([a-z0-9]*(_[A-Z])?)*"), + llvm::Regex("^[A-Z]([a-z0-9_]*[a-z])*$"), }; if (!Name.consume_front(Style.Prefix)) @@ -993,6 +996,18 @@ Fixup += Word.substr(1).lower(); } break; + + case IdentifierNamingCheck::CT_LeadingUpperSnakeCase: + for (auto const &Word : Words) { + if (&Word != &Words.front()) { + Fixup += "_"; + Fixup += Word.lower(); + } else { + Fixup += toupper(Word.front()); + Fixup += Word.substr(1).lower(); + } + } + break; } return Fixup.str().str(); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -252,7 +252,8 @@ - Improved :doc:`readability-identifier-naming ` check to emit proper - warnings when a type forward declaration precedes its definition. + warnings when a type forward declaration precedes its definition and + added support for ``Leading_upper_snake_case`` naming convention. - Improved :doc:`readability-implicit-bool-conversion ` check to take 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 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst @@ -17,7 +17,8 @@ - ``CamelCase``, - ``camel_Snake_Back``, - ``Camel_Snake_Case``, - - ``aNy_CasE``. + - ``aNy_CasE``, + - ``Leading_upper_snake_case``. It also supports a fixed prefix and suffix that will be prepended or appended to the identifiers, regardless of the casing. @@ -30,6 +31,10 @@ but not where they are overridden, as it can't be fixed locally there. This also applies for pseudo-override patterns like CRTP. +``Leading_upper_snake_case`` is a naming convention where the first word is capitalized +followed by lower case word(s) seperated by underscore(s) '_'. Examples include: +Cap_snake_case, Cobra_case, Foo_bar_baz, and Master_copy_8gb. + Options ------- diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-case-violation.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-case-violation.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-case-violation.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-case-violation.cpp @@ -5,6 +5,7 @@ // RUN: readability-identifier-naming.ClassCase: UUPER_CASE, \ // RUN: readability-identifier-naming.StructCase: CAMEL, \ // RUN: readability-identifier-naming.EnumCase: AnY_cASe, \ +// RUN: readability-identifier-naming.VirtualMethodCase: lEaDiNg_upper_SNAKE_CaSe, \ // RUN: }}" -- 2>&1 | FileCheck %s --implicit-check-not="{{warning|error}}:" // CHECK-DAG: warning: invalid configuration value 'camelback' for option 'readability-identifier-naming.FunctionCase'; did you mean 'camelBack'? [clang-tidy-config] @@ -13,3 +14,4 @@ // CHECK-DAG: warning: invalid configuration value 'CAMEL' for option 'readability-identifier-naming.StructCase' [clang-tidy-config] // This fails on the EditDistance, but as it matches ignoring case suggest the correct value // CHECK-DAG: warning: invalid configuration value 'AnY_cASe' for option 'readability-identifier-naming.EnumCase'; did you mean 'aNy_CasE'? [clang-tidy-config] +// CHECK-DAG: warning: invalid configuration value 'lEaDiNg_upper_SNAKE_CaSe' for option 'readability-identifier-naming.VirtualMethodCase'; did you mean 'Leading_upper_snake_case'? [clang-tidy-config] diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp @@ -49,7 +49,7 @@ // RUN: readability-identifier-naming.StaticConstantCase: UPPER_CASE, \ // RUN: readability-identifier-naming.StaticVariableCase: camelBack, \ // RUN: readability-identifier-naming.StaticVariablePrefix: 's_', \ -// RUN: readability-identifier-naming.StructCase: lower_case, \ +// RUN: readability-identifier-naming.StructCase: Leading_upper_snake_case, \ // RUN: readability-identifier-naming.TemplateParameterCase: UPPER_CASE, \ // RUN: readability-identifier-naming.TemplateTemplateParameterCase: CamelCase, \ // RUN: readability-identifier-naming.TemplateUsingCase: lower_case, \ @@ -513,9 +513,9 @@ struct THIS___Structure { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for struct 'THIS___Structure' -// CHECK-FIXES: {{^}}struct this_structure {{{$}} +// CHECK-FIXES: {{^}}struct This_structure {{{$}} THIS___Structure(); -// CHECK-FIXES: {{^}} this_structure();{{$}} +// CHECK-FIXES: {{^}} This_structure();{{$}} union __MyUnion_is_wonderful__ {}; // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for union '__MyUnion_is_wonderful__' @@ -524,7 +524,7 @@ typedef THIS___Structure struct_type; // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: invalid case style for typedef 'struct_type' -// CHECK-FIXES: {{^}}typedef this_structure struct_type_t;{{$}} +// CHECK-FIXES: {{^}}typedef This_structure struct_type_t;{{$}} struct_type GlobalTypedefTestFunction(struct_type a_argument1) { // CHECK-FIXES: {{^}}struct_type_t GlobalTypedefTestFunction(struct_type_t a_argument1) { @@ -534,7 +534,7 @@ using my_struct_type = THIS___Structure; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for type alias 'my_struct_type' -// CHECK-FIXES: {{^}}using my_Struct_Type_t = this_structure;{{$}} +// CHECK-FIXES: {{^}}using my_Struct_Type_t = This_structure;{{$}} template using SomeOtherTemplate = my_other_templated_class <:: FOO_NS ::my_class>; @@ -596,6 +596,8 @@ } template struct a { +// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: invalid case style for struct 'a' +// CHECK-FIXES: {{^}}template struct A {{{$}} typename t_t::template b<> c; char const MY_ConstMember_string[4] = "123"; @@ -609,9 +611,11 @@ template char const a::MyConstClass_string[] = "123"; -// CHECK-FIXES: {{^}}char const a::kMyConstClassString[] = "123";{{$}} +// CHECK-FIXES: {{^}}char const A::kMyConstClassString[] = "123";{{$}} template