yodaldevoid created this revision.
yodaldevoid added reviewers: HazardyKnusperkeks, MyDeveloperDay, curdeius, 
owenpan.
yodaldevoid requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

I personally prefer that pointers are aligned to the right in most cases to 
avoid problems when multiple variables are declared at once. That said, I 
prefer left alignment in C style casts to avoid the extra space and because 
there is no chance of the sorts of problems you see in declarations. This 
setting supports people with preferences like mine.

Currently this affects the alignment of both pointers and references in C style 
casts. If someone wanted to affect references separately then a separate 
setting for that, similar to ReferenceAlignmet, could be added.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116229

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

Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -15343,6 +15343,30 @@
                    Style));
 }
 
+TEST_F(FormatTest, AlignPointersInCasts) {
+  FormatStyle Style = getLLVMStyle();
+  Style.PointerAlignment = FormatStyle::PAS_Right;
+  verifyFormat("(const int (*(*foo)(const void *))[3]) a", Style);
+  Style.PointerAlignment = FormatStyle::PAS_Left;
+  verifyFormat("(const int (*(*foo)(const void*))[3]) a", Style);
+  Style.PointerAlignmentInCast = FormatStyle::PACS_Right;
+  verifyFormat("(const int (*(*foo)(const void *))[3]) a", Style);
+  Style.PointerAlignment = FormatStyle::PAS_Right;
+  Style.PointerAlignmentInCast = FormatStyle::PACS_Left;
+  verifyFormat("(const int (*(*foo)(const void*))[3]) a", Style);
+
+  Style.PointerAlignmentInCast = FormatStyle::PACS_Pointer;
+  Style.ReferenceAlignment = FormatStyle::RAS_Pointer;
+  verifyFormat("(const int (*(*foo)(const void &))[3]) a", Style);
+  Style.ReferenceAlignment = FormatStyle::RAS_Left;
+  verifyFormat("(const int (*(*foo)(const void&))[3]) a", Style);
+  Style.PointerAlignmentInCast = FormatStyle::PACS_Right;
+  verifyFormat("(const int (*(*foo)(const void &))[3]) a", Style);
+  Style.ReferenceAlignment = FormatStyle::RAS_Right;
+  Style.PointerAlignmentInCast = FormatStyle::PACS_Left;
+  verifyFormat("(const int (*(*foo)(const void&))[3]) a", Style);
+}
+
 TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLines) {
   FormatStyle Alignment = getLLVMStyle();
   Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
@@ -18817,6 +18841,13 @@
               FormatStyle::PAS_Right);
   CHECK_PARSE("PointerAlignment: Middle", PointerAlignment,
               FormatStyle::PAS_Middle);
+  Style.PointerAlignmentInCast = FormatStyle::PACS_Left;
+  CHECK_PARSE("PointerAlignmentInCast: Pointer", PointerAlignmentInCast,
+              FormatStyle::PACS_Pointer);
+  CHECK_PARSE("PointerAlignmentInCast: Left", PointerAlignmentInCast,
+              FormatStyle::PACS_Left);
+  CHECK_PARSE("PointerAlignmentInCast: Right", PointerAlignmentInCast,
+              FormatStyle::PACS_Right);
   Style.ReferenceAlignment = FormatStyle::RAS_Middle;
   CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment,
               FormatStyle::RAS_Pointer);
Index: clang/lib/Format/TokenAnnotator.h
===================================================================
--- clang/lib/Format/TokenAnnotator.h
+++ clang/lib/Format/TokenAnnotator.h
@@ -199,6 +199,9 @@
   FormatStyle::PointerAlignmentStyle
   getTokenPointerOrReferenceAlignment(const FormatToken &PointerOrReference);
 
+  FormatStyle::PointerAlignmentStyle getTokenPointerOrReferenceAlignmentInCase(
+      const FormatToken &PointerOrReference);
+
   const FormatStyle &Style;
 
   const AdditionalKeywords &Keywords;
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3037,6 +3037,19 @@
         Right.Next->Next->is(TT_RangeBasedForLoopColon))
       return getTokenPointerOrReferenceAlignment(Right) !=
              FormatStyle::PAS_Left;
+    // To find if we are currently in a C style cast we just have to follow the
+    // linked list until one of three conditions. If we have either reached the
+    // end of the list or find the opening parenthesis of a cast we can assume
+    // we are not currently in a cast. If we instead find the right-most
+    // parenthesis of a cast we know we are in a cast.
+    if (!Left.isOneOf(TT_PointerOrReference, tok::l_paren))
+      for (const FormatToken *Tok = &Right;
+           Tok &&
+           (!Tok->MatchingParen || !Tok->MatchingParen->is(TT_CastRParen));
+           Tok = Tok->Next)
+        if (Tok->Next && Tok->Next->is(TT_CastRParen))
+          return getTokenPointerOrReferenceAlignmentInCase(Right) !=
+                 FormatStyle::PAS_Left;
     return (
         (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
          (getTokenPointerOrReferenceAlignment(Right) != FormatStyle::PAS_Left ||
@@ -4444,5 +4457,20 @@
   return Style.PointerAlignment;
 }
 
+FormatStyle::PointerAlignmentStyle
+TokenAnnotator::getTokenPointerOrReferenceAlignmentInCase(
+    const FormatToken &PointerOrReference) {
+  switch (Style.PointerAlignmentInCast) {
+  case FormatStyle::PACS_Pointer:
+    return getTokenPointerOrReferenceAlignment(PointerOrReference);
+  case FormatStyle::PACS_Left:
+    return FormatStyle::PAS_Left;
+  case FormatStyle::PACS_Right:
+    return FormatStyle::PAS_Right;
+  }
+  assert(0); //"Unhandled value of PointerAlignmentInCast"
+  return Style.PointerAlignment;
+}
+
 } // namespace format
 } // namespace clang
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -429,6 +429,16 @@
   }
 };
 
+template <>
+struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentInCastStyle> {
+  static void enumeration(IO &IO,
+                          FormatStyle::PointerAlignmentInCastStyle &Value) {
+    IO.enumCase(Value, "Pointer", FormatStyle::PACS_Pointer);
+    IO.enumCase(Value, "Left", FormatStyle::PACS_Left);
+    IO.enumCase(Value, "Right", FormatStyle::PACS_Right);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
   static void
@@ -765,6 +775,7 @@
     IO.mapOptional("PenaltyIndentedWhitespace",
                    Style.PenaltyIndentedWhitespace);
     IO.mapOptional("PointerAlignment", Style.PointerAlignment);
+    IO.mapOptional("PointerAlignmentInCast", Style.PointerAlignmentInCast);
     IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
     IO.mapOptional("RawStringFormats", Style.RawStringFormats);
     IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
@@ -1192,6 +1203,7 @@
   LLVMStyle.ObjCSpaceAfterProperty = false;
   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
   LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
+  LLVMStyle.PointerAlignmentInCast = FormatStyle::PACS_Pointer;
   LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer;
   LLVMStyle.ShortNamespaceLines = 1;
   LLVMStyle.SpacesBeforeTrailingComments = 1;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -2932,6 +2932,27 @@
   /// \version 3.7
   PointerAlignmentStyle PointerAlignment;
 
+  /// The ``&``, ``&&`` and ``*`` alignment style when in C style casts.
+  enum PointerAlignmentInCastStyle {
+    /// Align pointers and references like ``PointerAlignment`` for pointers and
+    //  like `'ReferenceAlignment`' for references.
+    PACS_Pointer,
+    /// Align pointer to the left.
+    /// \code
+    ///   (int*) a;
+    /// \endcode
+    PACS_Left,
+    /// Align pointer to the right.
+    /// \code
+    ///   (int *) a;
+    /// \endcode
+    PACS_Right,
+  };
+
+  /// Pointer alignment style in C style casts.
+  /// \version 14
+  PointerAlignmentInCastStyle PointerAlignmentInCast;
+
   /// The number of columns to use for indentation of preprocessor statements.
   /// When set to -1 (default) ``IndentWidth`` is used also for preprocessor
   /// statements.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to