llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-format
Author: None (kgerlich)
<details>
<summary>Changes</summary>
… macro
This adds a new configuration option SpaceBeforeUnderscoreParens to control
spacing between underscore and opening parenthesis. This is specifically
designed for the gettext internationalization macro '_()' commonly used in GNU
projects like GDB.
The option:
- Defaults to true for LLVM style (preserving existing behavior)
- Defaults to false for GNU style (removes space before '_(')
- Only affects single underscore tokens '_', not other identifiers
- Leaves all other spacing rules unchanged
Examples:
GNU style with SpaceBeforeUnderscoreParens=false:
printf(_("Hello")); // No space before '_('
my_func (arg); // Space before other functions preserved
LLVM style with SpaceBeforeUnderscoreParens=true:
printf(_("Hello")); // Standard spacing rules apply
This addresses the common pattern in GNU software where gettext messages use
'_()' without spaces, improving consistency with GNU coding standards.
---
Full diff: https://github.com/llvm/llvm-project/pull/159925.diff
4 Files Affected:
- (modified) clang/include/clang/Format/Format.h (+10)
- (modified) clang/lib/Format/Format.cpp (+4)
- (modified) clang/lib/Format/TokenAnnotator.cpp (+6)
- (modified) clang/unittests/Format/FormatTest.cpp (+36)
``````````diff
diff --git a/clang/include/clang/Format/Format.h
b/clang/include/clang/Format/Format.h
index 342fefcfc408c..1643c575fcbba 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4667,6 +4667,16 @@ struct FormatStyle {
/// \version 7
bool SpaceBeforeInheritanceColon;
+ /// If ``false``, spaces will be removed between underscore and an opening
+ /// parenthesis. This is specifically for the gettext macro ``_()`` commonly
+ /// used in GNU projects.
+ /// \code
+ /// true: false:
+ /// _ (message); vs. _(message);
+ /// \endcode
+ /// \version 19
+ bool SpaceBeforeUnderscoreParens;
+
/// If ``true``, a space will be added before a JSON colon. For other
/// languages, e.g. JavaScript, use ``SpacesInContainerLiterals`` instead.
/// \code
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 24a36d97a6fa9..9181e9a9ecd26 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1219,6 +1219,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.SpaceBeforeCtorInitializerColon);
IO.mapOptional("SpaceBeforeInheritanceColon",
Style.SpaceBeforeInheritanceColon);
+ IO.mapOptional("SpaceBeforeUnderscoreParens",
+ Style.SpaceBeforeUnderscoreParens);
IO.mapOptional("SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
IO.mapOptional("SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
@@ -1713,6 +1715,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind
Language) {
LLVMStyle.SpaceBeforeCpp11BracedList = false;
LLVMStyle.SpaceBeforeCtorInitializerColon = true;
LLVMStyle.SpaceBeforeInheritanceColon = true;
+ LLVMStyle.SpaceBeforeUnderscoreParens = true;
LLVMStyle.SpaceBeforeJsonColon = false;
LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
LLVMStyle.SpaceBeforeParensOptions = {};
@@ -2044,6 +2047,7 @@ FormatStyle getGNUStyle() {
Style.FixNamespaceComments = false;
Style.KeepFormFeed = true;
Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+ Style.SpaceBeforeUnderscoreParens = false;
return Style;
}
diff --git a/clang/lib/Format/TokenAnnotator.cpp
b/clang/lib/Format/TokenAnnotator.cpp
index d97f56751ea69..9af90184d157e 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4901,6 +4901,12 @@ bool TokenAnnotator::spaceRequiredBetween(const
AnnotatedLine &Line,
// Handle builtins like identifiers.
if (Line.Type != LT_PreprocessorDirective &&
(Left.Tok.getIdentifierInfo() || Left.is(tok::r_paren))) {
+ // Check for special case: single underscore token (gettext macro)
+ if (Left.Tok.getIdentifierInfo() && !Style.SpaceBeforeUnderscoreParens) {
+ StringRef TokenText = Left.TokenText;
+ if (TokenText == "_")
+ return false;
+ }
return spaceRequiredBeforeParens(Right);
}
return false;
diff --git a/clang/unittests/Format/FormatTest.cpp
b/clang/unittests/Format/FormatTest.cpp
index d9db06667d802..4ca1f8fbfa363 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17852,6 +17852,42 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
Spaces);
}
+TEST_F(FormatTest, SpaceBeforeUnderscoreParens) {
+ // Test with SpaceBeforeParens = Always to clearly show the difference
+ FormatStyle Style = getLLVMStyle();
+ Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+
+ // Default LLVM style should have SpaceBeforeUnderscoreParens = true
+ EXPECT_TRUE(Style.SpaceBeforeUnderscoreParens);
+ verifyFormat("func (arg);", Style); // All functions should have space
+ verifyFormat("my_func (arg);", Style); // All functions should have space
+ verifyFormat("_ (message);", Style); // Single underscore should have
space when SpaceBeforeUnderscoreParens=true
+ verifyFormat("underscore_ (param);", Style); // Other underscores should
have space
+
+ // Now test with SpaceBeforeUnderscoreParens = false but SpaceBeforeParens =
Always
+ Style.SpaceBeforeUnderscoreParens = false;
+ verifyFormat("func (arg);", Style); // Non-underscore functions should
still have space
+ verifyFormat("my_func (arg);", Style); // Functions with underscores
should still have space
+ verifyFormat("_(message);", Style); // Single underscore (gettext
macro) should NOT have space
+ verifyFormat("underscore_ (param);", Style); // Other underscores should
still have space
+ verifyFormat("_private_func (data);", Style); // Functions starting with
underscore but not single _ should have space
+
+ // Test GNU style (should have SpaceBeforeUnderscoreParens = false by
default)
+ FormatStyle GNUStyle = getGNUStyle();
+ EXPECT_FALSE(GNUStyle.SpaceBeforeUnderscoreParens);
+ EXPECT_EQ(GNUStyle.SpaceBeforeParens, FormatStyle::SBPO_Always); // GNU
style should have SpaceBeforeParens = Always
+ verifyFormat("func (arg);", GNUStyle); // GNU style has SpaceBeforeParens
= Always
+ verifyFormat("my_func (arg);", GNUStyle); // Functions with underscores
should have space
+ verifyFormat("_(message);", GNUStyle); // Single underscore (gettext
macro) should NOT have space
+ verifyFormat("_private_func (data);", GNUStyle); // Other functions should
have space
+
+ // Test mixed scenarios with GNU style
+ verifyFormat("printf (_(\"Hello\"));\n"
+ "func (arg);\n"
+ "_(\"World\");",
+ GNUStyle);
+}
+
TEST_F(FormatTest, ConfigurableSpacesInSquareBrackets) {
verifyFormat("int a[5];");
verifyFormat("a[3] += 42;");
``````````
</details>
https://github.com/llvm/llvm-project/pull/159925
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits