omarahmed updated this revision to Diff 437468.
omarahmed edited the summary of this revision.
omarahmed added a comment.

Add coverage for placement delete expressions and transform bool option to enum


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127270/new/

https://reviews.llvm.org/D127270

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10130,6 +10130,37 @@
             "void delete(link p);\n",
             format("void new (link p);\n"
                    "void delete (link p);\n"));
+
+  FormatStyle AfterPlacementOperator = getLLVMStyle();
+  AfterPlacementOperator.SpaceBeforeParens = FormatStyle::SBPO_Custom;
+  EXPECT_EQ(
+      AfterPlacementOperator.SpaceBeforeParensOptions.AfterPlacementOperator,
+      FormatStyle::SpaceBeforeParensCustom::APO_Always);
+  verifyFormat("new (buf) T;", AfterPlacementOperator);
+  verifyFormat("T *p = new (buf) T;", AfterPlacementOperator);
+  verifyFormat("T *p = new (buf) T(3);", AfterPlacementOperator);
+  verifyFormat("T *p = delete (buf)T(3);", AfterPlacementOperator);
+  verifyFormat("struct A {\n"
+               "  void *a;\n"
+               "  A(void *p) : a(new (p) int) {}\n"
+               "};",
+               AfterPlacementOperator);
+
+  AfterPlacementOperator.SpaceBeforeParensOptions.AfterPlacementOperator =
+      FormatStyle::SpaceBeforeParensCustom::APO_Never;
+  verifyFormat("new(buf) T;", AfterPlacementOperator);
+  verifyFormat("T *p = new(buf) T;", AfterPlacementOperator);
+  verifyFormat("T *p = delete(buf)T(3);", AfterPlacementOperator);
+  verifyFormat("struct A {\n"
+               "  void *a;\n"
+               "  A(void *p) : a(new(p) int) {}\n"
+               "};",
+               AfterPlacementOperator);
+
+  AfterPlacementOperator.SpaceBeforeParensOptions.AfterPlacementOperator =
+      FormatStyle::SpaceBeforeParensCustom::APO_Leave;
+  EXPECT_EQ("new (buf) T;", format("new (buf) T;", AfterPlacementOperator));
+  EXPECT_EQ("new(buf) T;", format("new(buf) T;", AfterPlacementOperator));
 }
 
 TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3393,6 +3393,18 @@
     if (Left.is(TT_IfMacro))
       return Style.SpaceBeforeParensOptions.AfterIfMacros ||
              spaceRequiredBeforeParens(Right);
+    if (Style.SpaceBeforeParens == FormatStyle::SBPO_Custom &&
+        Left.isOneOf(tok::kw_new, tok::kw_delete) &&
+        Right.isNot(TT_OverloadedOperatorLParen) &&
+        !(Line.MightBeFunctionDecl && Left.is(TT_FunctionDeclarationName))) {
+      if (Style.SpaceBeforeParensOptions.AfterPlacementOperator ==
+              FormatStyle::SpaceBeforeParensCustom::APO_Always ||
+          (Style.SpaceBeforeParensOptions.AfterPlacementOperator ==
+               FormatStyle::SpaceBeforeParensCustom::APO_Leave &&
+           Right.hasWhitespaceBefore()))
+        return true;
+      return false;
+    }
     if (Line.Type == LT_ObjCDecl)
       return true;
     if (Left.is(tok::semi))
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -936,6 +936,7 @@
                    Spacing.AfterFunctionDeclarationName);
     IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);
     IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
+    IO.mapOptional("AfterPlacementOperator", Spacing.AfterPlacementOperator);
     IO.mapOptional("AfterRequiresInClause", Spacing.AfterRequiresInClause);
     IO.mapOptional("AfterRequiresInExpression",
                    Spacing.AfterRequiresInExpression);
@@ -944,6 +945,22 @@
   }
 };
 
+template <>
+struct MappingTraits<
+    FormatStyle::SpaceBeforeParensCustom::AfterPlacementOperatorStyle> {
+  static void
+  mapping(IO &IO,
+          FormatStyle::SpaceBeforeParensCustom::AfterPlacementOperatorStyle
+              &Value) {
+    IO.enumCase(Value, "Always",
+                FormatStyle::SpaceBeforeParensCustom::APO_Always);
+    IO.enumCase(Value, "Never",
+                FormatStyle::SpaceBeforeParensCustom::APO_Never);
+    IO.enumCase(Value, "Leave",
+                FormatStyle::SpaceBeforeParensCustom::APO_Leave);
+  }
+};
+
 template <> struct MappingTraits<FormatStyle::RawStringFormat> {
   static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
     IO.mapOptional("Language", Format.Language);
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3490,6 +3490,11 @@
     ///      <conditional-body>                     <conditional-body>
     /// \endcode
     bool AfterIfMacros;
+    /// If ``true``, put space between placement new and opening parentheses.
+    /// \code
+    ///    true:                                  false:
+    ///    new (buf) T;                    vs.    new(buf) T;
+    /// \endcode
     /// If ``true``, put a space between operator overloading and opening
     /// parentheses.
     /// \code
@@ -3498,6 +3503,27 @@
     ///    object.operator++ (10);                object.operator++(10);
     /// \endcode
     bool AfterOverloadedOperator;
+    /// Styles for adding spacing between ``new/delete`` operators and opening
+    /// parentheses.
+    enum AfterPlacementOperatorStyle : int8_t {
+      /// Never add space after ``new/delete`` operators and before ``(``.
+      /// \code
+      ///    new(buf) T;
+      ///    delete(buf) T;
+      /// \endcode
+      APO_Never,
+      /// Always add space after ``new/delete`` operators and before ``(``.
+      /// \code
+      ///    new (buf) T;
+      ///    delete (buf) T;
+      /// \endcode
+      APO_Always,
+      /// Leave placement ``new/delete`` expressions as they are.
+      APO_Leave
+    };
+    /// Defines in which cases to put a space between ``new/delete`` operators
+    /// and opening parentheses. \version 3.5
+    AfterPlacementOperatorStyle AfterPlacementOperator;
     /// If ``true``, put space between requires keyword in a requires clause and
     /// opening parentheses, if there is one.
     /// \code
@@ -3530,8 +3556,9 @@
         : AfterControlStatements(false), AfterForeachMacros(false),
           AfterFunctionDeclarationName(false),
           AfterFunctionDefinitionName(false), AfterIfMacros(false),
-          AfterOverloadedOperator(false), AfterRequiresInClause(false),
-          AfterRequiresInExpression(false), BeforeNonEmptyParentheses(false) {}
+          AfterOverloadedOperator(false), AfterPlacementOperator(APO_Always),
+          AfterRequiresInClause(false), AfterRequiresInExpression(false),
+          BeforeNonEmptyParentheses(false) {}
 
     bool operator==(const SpaceBeforeParensCustom &Other) const {
       return AfterControlStatements == Other.AfterControlStatements &&
@@ -3541,6 +3568,7 @@
              AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName &&
              AfterIfMacros == Other.AfterIfMacros &&
              AfterOverloadedOperator == Other.AfterOverloadedOperator &&
+             AfterPlacementOperator == Other.AfterPlacementOperator &&
              AfterRequiresInClause == Other.AfterRequiresInClause &&
              AfterRequiresInExpression == Other.AfterRequiresInExpression &&
              BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses;
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -4248,7 +4248,7 @@
        true:                                  false:
        IF (...)                        vs.    IF(...)
          <conditional-body>                     <conditional-body>
-
+  
   * ``bool AfterOverloadedOperator`` If ``true``, put a space between operator overloading and opening
     parentheses.
 
@@ -4258,6 +4258,31 @@
        void operator++ (int a);        vs.    void operator++(int a);
        object.operator++ (10);                object.operator++(10);
 
+  **AfterPlacementOperator** (``AfterPlacementOperatorStyle``) :versionbadge:`clang-format 14`
+    Defines in which cases to put a space between new/delete operators and opening parentheses.
+
+    Possible values:
+
+    * ``APO_Never`` (in configuration: ``Never``)
+      Remove spaces between new/delete operators and opening parentheses.
+
+      .. code-block:: c++
+
+        new(placement) Type;
+        delete(placement) Type;
+
+    * ``APO_Always`` (in configuration: ``Always``)
+      Add space between new/delete operators and opening parentheses.
+
+      .. code-block:: c++
+
+        new (placement) Type;
+        delete (placement) Type;
+    
+    * ``APO_Leave`` (in configuration: ``Always``)
+      Leave placement ``new/delete`` expressions as they are..
+
+
   * ``bool AfterRequiresInClause`` If ``true``, put space between requires keyword in a requires clause and
     opening parentheses, if there is one.
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to