Skip to content

Commit 283fed7

Browse files
committed
[clang-format] Add an option to format integer literal case
1 parent 49b17a0 commit 283fed7

File tree

9 files changed

+898
-1
lines changed

9 files changed

+898
-1
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4555,7 +4555,6 @@ the configuration (without a prefix: ``Auto``).
45554555
So inserting a trailing comma counteracts bin-packing.
45564556

45574557

4558-
45594558
.. _IntegerLiteralSeparator:
45604559

45614560
**IntegerLiteralSeparator** (``IntegerLiteralSeparatorStyle``) :versionbadge:`clang-format 16` :ref:`<IntegerLiteralSeparator>`
@@ -5076,6 +5075,78 @@ the configuration (without a prefix: ``Auto``).
50765075

50775076
For example: TESTSUITE
50785077

5078+
.. _NumericLiteralCase:
5079+
5080+
**NumericLiteralCase** (``NumericLiteralCaseStyle``) :versionbadge:`clang-format 21` :ref:`<NumericLiteralCase>`
5081+
Controls character case in numeric literals.
5082+
5083+
Possible values for each nexted configuration flag:
5084+
5085+
* ``0`` (Default) Do not modify characters.
5086+
5087+
* ``-1`` Convert characters to lower case.
5088+
5089+
* ``1`` Convert characters to upper case.
5090+
5091+
.. code-block:: yaml
5092+
5093+
# Example of usage:
5094+
NumericLiteralCaseStyle:
5095+
PrefixCase: -1
5096+
HexDigitCase: 1
5097+
FloatExponentSeparatorCase: 0
5098+
SuffixCase: -1
5099+
5100+
.. code-block:: c++
5101+
5102+
// Lower case prefix, upper case hexadecimal digits, lower case suffix
5103+
unsigned int 0xDEAFBEEFull;
5104+
5105+
Nested configuration flags:
5106+
5107+
* ``int PrefixCase`` Control numeric constant prefix case.
5108+
5109+
.. code-block:: c++
5110+
5111+
// PrefixCase: 1
5112+
int a = 0B101 | 0XF0;
5113+
// PrefixCase: -1
5114+
int a = 0b101 | 0xF0;
5115+
// PrefixCase: 0
5116+
int c = 0b101 | 0XF0;
5117+
5118+
* ``int HexDigitCase`` Control hexadecimal digit case.
5119+
5120+
.. code-block:: c++
5121+
5122+
// HexDigitCase: 1
5123+
int a = 0xBEAD;
5124+
// PrefixCase: -1
5125+
int b = 0xbead;
5126+
// PrefixCase: 0
5127+
int c = 0xBeAd;
5128+
5129+
* ``int FloatExponentSeparatorCase`` Control exponent separator case.
5130+
5131+
.. code-block:: c++
5132+
5133+
// FloatExponentSeparatorCase: 1
5134+
float a = 6.02E+23;
5135+
// FloatExponentSeparatorCase: -1
5136+
float b = 6.02e+23;
5137+
5138+
* ``int SuffixCase`` Control suffix case.
5139+
5140+
.. code-block:: c++
5141+
5142+
// SuffixCase: 1
5143+
unsigned long long a = 1ULL;
5144+
// SuffixCase: -1
5145+
unsigned long long a = 1ull;
5146+
// SuffixCase: 0
5147+
unsigned long long c = 1uLL;
5148+
5149+
50795150
.. _ObjCBinPackProtocolList:
50805151

50815152
**ObjCBinPackProtocolList** (``BinPackStyle``) :versionbadge:`clang-format 7` :ref:`<ObjCBinPackProtocolList>`

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ AST Matchers
279279

280280
clang-format
281281
------------
282+
- Add ``NumericLiteralCase`` option for for enforcing character case in
283+
numeric literals.
282284

283285
libclang
284286
--------

clang/include/clang/Format/Format.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3100,6 +3100,54 @@ struct FormatStyle {
31003100
/// \version 11
31013101
TrailingCommaStyle InsertTrailingCommas;
31023102

3103+
/// Character case format for different components of a numeric literal.
3104+
///
3105+
/// For all options, ``0`` leave the case unchanged, ``-1``
3106+
/// uses lower case and, ``1`` uses upper case.
3107+
///
3108+
struct NumericLiteralCaseStyle {
3109+
/// Format numeric constant prefixes.
3110+
/// \code{.text}
3111+
/// /* -1: lower case */ b = 0x01;
3112+
/// /* 0: don't care */
3113+
/// /* 1: upper case */ b = 0X01;
3114+
/// \endcode
3115+
int8_t PrefixCase;
3116+
/// Format hexadecimal digit case.
3117+
/// \code{.text}
3118+
/// /* -1: lower case */ b = 0xabcdef;
3119+
/// /* 0: don't care */
3120+
/// /* 1: upper case */ b = 0xABCDEF;
3121+
/// \endcode
3122+
int8_t HexDigitCase;
3123+
/// Format exponent separator character case in floating point literals.
3124+
/// \code{.text}
3125+
/// /* -1: lower case */ b = 6.02e23;
3126+
/// /* 0: don't care */
3127+
/// /* 1: upper case */ b = 6.02E23;
3128+
/// \endcode
3129+
int8_t FloatExponentSeparatorCase;
3130+
/// Format suffix case. This option excludes case-specific reserved
3131+
/// suffixes, such as ``min`` in C++.
3132+
/// \code{.text}
3133+
/// /* -1: lower case */ b = 10u;
3134+
/// /* 0: don't care */
3135+
/// /* 1: upper case */ b = 10U;
3136+
/// \endcode
3137+
int8_t SuffixCase;
3138+
3139+
bool operator==(const NumericLiteralCaseStyle &R) const {
3140+
return PrefixCase == R.PrefixCase && HexDigitCase == R.HexDigitCase &&
3141+
FloatExponentSeparatorCase == R.FloatExponentSeparatorCase &&
3142+
SuffixCase == R.SuffixCase;
3143+
}
3144+
};
3145+
3146+
/// Format numeric literals for languages that support flexible character case
3147+
/// in numeric literal constants.
3148+
/// \version 22
3149+
NumericLiteralCaseStyle NumericLiteralCase;
3150+
31033151
/// Separator format of integer literals of different bases.
31043152
///
31053153
/// If negative, remove separators. If ``0``, leave the literal as is. If
@@ -5424,6 +5472,7 @@ struct FormatStyle {
54245472
IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
54255473
InsertBraces == R.InsertBraces &&
54265474
InsertNewlineAtEOF == R.InsertNewlineAtEOF &&
5475+
NumericLiteralCase == R.NumericLiteralCase &&
54275476
IntegerLiteralSeparator == R.IntegerLiteralSeparator &&
54285477
JavaImportGroups == R.JavaImportGroups &&
54295478
JavaScriptQuotes == R.JavaScriptQuotes &&

clang/lib/Format/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ add_clang_library(clangFormat
1414
MatchFilePath.cpp
1515
NamespaceEndCommentsFixer.cpp
1616
NumericLiteralInfo.cpp
17+
NumericLiteralCaseFixer.cpp
1718
ObjCPropertyAttributeOrderFixer.cpp
1819
QualifierAlignmentFixer.cpp
1920
SortJavaScriptImports.cpp

clang/lib/Format/Format.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "DefinitionBlockSeparator.h"
1717
#include "IntegerLiteralSeparatorFixer.h"
1818
#include "NamespaceEndCommentsFixer.h"
19+
#include "NumericLiteralCaseFixer.h"
1920
#include "ObjCPropertyAttributeOrderFixer.h"
2021
#include "QualifierAlignmentFixer.h"
2122
#include "SortJavaScriptImports.h"
@@ -382,6 +383,16 @@ struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {
382383
}
383384
};
384385

386+
template <> struct MappingTraits<FormatStyle::NumericLiteralCaseStyle> {
387+
static void mapping(IO &IO, FormatStyle::NumericLiteralCaseStyle &Base) {
388+
IO.mapOptional("PrefixCase", Base.PrefixCase);
389+
IO.mapOptional("HexDigitCase", Base.HexDigitCase);
390+
IO.mapOptional("FloatExponentSeparatorCase",
391+
Base.FloatExponentSeparatorCase);
392+
IO.mapOptional("SuffixCase", Base.SuffixCase);
393+
}
394+
};
395+
385396
template <> struct MappingTraits<FormatStyle::IntegerLiteralSeparatorStyle> {
386397
static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &Base) {
387398
IO.mapOptional("Binary", Base.Binary);
@@ -1093,6 +1104,7 @@ template <> struct MappingTraits<FormatStyle> {
10931104
IO.mapOptional("InsertBraces", Style.InsertBraces);
10941105
IO.mapOptional("InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
10951106
IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
1107+
IO.mapOptional("NumericLiteralCase", Style.NumericLiteralCase);
10961108
IO.mapOptional("IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
10971109
IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
10981110
IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
@@ -1618,6 +1630,9 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
16181630
LLVMStyle.InsertBraces = false;
16191631
LLVMStyle.InsertNewlineAtEOF = false;
16201632
LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
1633+
LLVMStyle.NumericLiteralCase = {/*PrefixCase=*/0, /*HexDigitCase=*/0,
1634+
/*FloatExponentSeparatorCase=*/0,
1635+
/*SuffixCase=*/0};
16211636
LLVMStyle.IntegerLiteralSeparator = {
16221637
/*Binary=*/0, /*BinaryMinDigits=*/0,
16231638
/*Decimal=*/0, /*DecimalMinDigits=*/0,
@@ -3872,6 +3887,10 @@ reformat(const FormatStyle &Style, StringRef Code,
38723887
return IntegerLiteralSeparatorFixer().process(Env, Expanded);
38733888
});
38743889

3890+
Passes.emplace_back([&](const Environment &Env) {
3891+
return NumericLiteralCaseFixer().process(Env, Expanded);
3892+
});
3893+
38753894
if (Style.isCpp()) {
38763895
if (Style.QualifierAlignment != FormatStyle::QAS_Leave)
38773896
addQualifierAlignmentFixerPasses(Expanded, Passes);

0 commit comments

Comments
 (0)