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