Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -1079,7 +1079,7 @@ /// line. unsigned PenaltyReturnTypeOnItsOwnLine; - /// \brief The ``&`` and ``*`` alignment style. + /// \brief The ``&``, ``&&`` and ``*`` alignment style. enum PointerAlignmentStyle { /// Align pointer to the left. /// \code @@ -1101,6 +1101,30 @@ /// \brief Pointer and reference alignment style. PointerAlignmentStyle PointerAlignment; + /// \brief The ``&`` and ``&&`` alignment style. + enum ReferenceAlignmentStyle { + /// Align reference like ``PointerAlignment``. + RAS_Pointer, + /// Align reference to the left. + /// \code + /// int& a; + /// \endcode + RAS_Left, + /// Align reference to the right. + /// \code + /// int &a; + /// \endcode + RAS_Right, + /// Align reference in the middle. + /// \code + /// int & a; + /// \endcode + RAS_Middle + }; + + /// \brief Reference alignment style (overrides ``PointerAlignment`` for references). + ReferenceAlignmentStyle ReferenceAlignment; + /// \brief If ``true``, clang-format will attempt to re-flow comments. /// \code /// false: @@ -1354,6 +1378,7 @@ PenaltyExcessCharacter == R.PenaltyExcessCharacter && PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine && PointerAlignment == R.PointerAlignment && + ReferenceAlignment == R.ReferenceAlignment && SpaceAfterCStyleCast == R.SpaceAfterCStyleCast && SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword && SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators && Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -183,6 +183,15 @@ } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) { + IO.enumCase(Value, "Pointer", FormatStyle::RAS_Pointer); + IO.enumCase(Value, "Middle", FormatStyle::RAS_Middle); + IO.enumCase(Value, "Left", FormatStyle::RAS_Left); + IO.enumCase(Value, "Right", FormatStyle::RAS_Right); + } +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, @@ -340,6 +349,7 @@ IO.mapOptional("PenaltyReturnTypeOnItsOwnLine", Style.PenaltyReturnTypeOnItsOwnLine); IO.mapOptional("PointerAlignment", Style.PointerAlignment); + IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment); IO.mapOptional("ReflowComments", Style.ReflowComments); IO.mapOptional("SortIncludes", Style.SortIncludes); IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast); @@ -554,6 +564,7 @@ LLVMStyle.ObjCSpaceAfterProperty = false; LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; + LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; LLVMStyle.SpacesBeforeTrailingComments = 1; LLVMStyle.Standard = FormatStyle::LS_Cpp11; LLVMStyle.UseTab = FormatStyle::UT_Never; @@ -601,6 +612,7 @@ GoogleStyle.ObjCSpaceAfterProperty = false; GoogleStyle.ObjCSpaceBeforeProtocolList = false; GoogleStyle.PointerAlignment = FormatStyle::PAS_Left; + GoogleStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; GoogleStyle.SpacesBeforeTrailingComments = 2; GoogleStyle.Standard = FormatStyle::LS_Auto; @@ -688,6 +700,7 @@ MozillaStyle.ObjCSpaceBeforeProtocolList = false; MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; MozillaStyle.PointerAlignment = FormatStyle::PAS_Left; + MozillaStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; MozillaStyle.SpaceAfterTemplateKeyword = false; return MozillaStyle; } @@ -709,6 +722,7 @@ Style.ObjCBlockIndentWidth = 4; Style.ObjCSpaceAfterProperty = true; Style.PointerAlignment = FormatStyle::PAS_Left; + Style.ReferenceAlignment = FormatStyle::RAS_Pointer; return Style; } Index: lib/Format/TokenAnnotator.h =================================================================== --- lib/Format/TokenAnnotator.h +++ lib/Format/TokenAnnotator.h @@ -168,6 +168,8 @@ void calculateUnbreakableTailLengths(AnnotatedLine &Line); + FormatStyle::PointerAlignmentStyle getTokenPointerAlignment(const FormatToken &Token); + const FormatStyle &Style; const AdditionalKeywords &Keywords; Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -2142,13 +2142,13 @@ (Left.Tok.isLiteral() || (Left.is(tok::kw_const) && Left.Previous && Left.Previous->is(tok::r_paren)) || (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) && - (Style.PointerAlignment != FormatStyle::PAS_Left || + (getTokenPointerAlignment(Right) != FormatStyle::PAS_Left || (Line.IsMultiVariableDeclStmt && (Left.NestingLevel == 0 || (Left.NestingLevel == 1 && Line.First->is(tok::kw_for))))))); if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) && (!Left.is(TT_PointerOrReference) || - (Style.PointerAlignment != FormatStyle::PAS_Right && + (getTokenPointerAlignment(Left) != FormatStyle::PAS_Right && !Line.IsMultiVariableDeclStmt))) return true; if (Left.is(TT_PointerOrReference)) @@ -2158,7 +2158,7 @@ (Right.is(tok::l_brace) && Right.BlockKind == BK_Block) || (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare, tok::l_paren) && - (Style.PointerAlignment != FormatStyle::PAS_Right && + (getTokenPointerAlignment(Left) != FormatStyle::PAS_Right && !Line.IsMultiVariableDeclStmt) && Left.Previous && !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon)); @@ -2586,7 +2586,7 @@ return !Right.is(tok::l_paren); if (Right.is(TT_PointerOrReference)) return Line.IsMultiVariableDeclStmt || - (Style.PointerAlignment == FormatStyle::PAS_Right && + (getTokenPointerAlignment(Right) == FormatStyle::PAS_Right && (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName))); if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) || Right.is(tok::kw_operator)) @@ -2735,5 +2735,21 @@ llvm::errs() << "----\n"; } +FormatStyle::PointerAlignmentStyle TokenAnnotator::getTokenPointerAlignment(const FormatToken &Token) { + if (Token.isOneOf(tok::amp, tok::ampamp)) { + switch (Style.ReferenceAlignment) { + case FormatStyle::RAS_Pointer: + return Style.PointerAlignment; + case FormatStyle::RAS_Left: + return FormatStyle::PAS_Left; + case FormatStyle::RAS_Right: + return FormatStyle::PAS_Right; + case FormatStyle::RAS_Middle: + return FormatStyle::PAS_Middle; + } + } + return Style.PointerAlignment; +} + } // namespace format } // namespace clang