true: false:
template <int> void foo(); vs. template<int> void foo();
+**SpaceAroundPointerQualifiers** (``SpaceAroundPointerQualifiersStyle``)
+ Defines in which cases to put a space before or after pointer qualifiers
+
+ Possible values:
+
+ * ``SAPQ_Default`` (in configuration: ``Default``)
+ Don't ensure spaces around pointer qualifiers and use PointerAlignment
+ instead.
+
+ .. code-block:: c++
+
+ PointerAlignment: Left PointerAlignment: Right
+ void* const* x = NULL; vs. void *const *x = NULL;
+
+ * ``SAPQ_Before`` (in configuration: ``Before``)
+ Ensure that there is a space before pointer qualifiers.
+
+ .. code-block:: c++
+
+ PointerAlignment: Left PointerAlignment: Right
+ void* const* x = NULL; vs. void * const *x = NULL;
+
+ * ``SAPQ_After`` (in configuration: ``After``)
+ Ensure that there is a space after pointer qualifiers.
+
+ .. code-block:: c++
+
+ PointerAlignment: Left PointerAlignment: Right
+ void* const * x = NULL; vs. void *const *x = NULL;
+
+ * ``SAPQ_Both`` (in configuration: ``Both``)
+ Ensure that there is a space both before and after pointer qualifiers.
+
+ .. code-block:: c++
+
+ PointerAlignment: Left PointerAlignment: Right
+ void* const * x = NULL; vs. void * const *x = NULL;
+
+
+
**SpaceBeforeAssignmentOperators** (``bool``)
If ``false``, spaces will be removed before assignment operators.
/// \endcode
bool SpaceAfterTemplateKeyword;
+ /// Different ways to put a space before opening parentheses.
+ enum SpaceAroundPointerQualifiersStyle {
+ /// Don't ensure spaces around pointer qualifiers and use PointerAlignment
+ /// instead.
+ /// \code
+ /// PointerAlignment: Left PointerAlignment: Right
+ /// void* const* x = NULL; vs. void *const *x = NULL;
+ /// \endcode
+ SAPQ_Default,
+ /// Ensure that there is a space before pointer qualifiers.
+ /// \code
+ /// PointerAlignment: Left PointerAlignment: Right
+ /// void* const* x = NULL; vs. void * const *x = NULL;
+ /// \endcode
+ SAPQ_Before,
+ /// Ensure that there is a space after pointer qualifiers.
+ /// \code
+ /// PointerAlignment: Left PointerAlignment: Right
+ /// void* const * x = NULL; vs. void *const *x = NULL;
+ /// \endcode
+ SAPQ_After,
+ /// Ensure that there is a space both before and after pointer qualifiers.
+ /// \code
+ /// PointerAlignment: Left PointerAlignment: Right
+ /// void* const * x = NULL; vs. void * const *x = NULL;
+ /// \endcode
+ SAPQ_Both,
+ };
+
+ /// Defines in which cases to put a space before or after pointer qualifiers
+ SpaceAroundPointerQualifiersStyle SpaceAroundPointerQualifiers;
+
/// If ``false``, spaces will be removed before assignment operators.
/// \code
/// true: false:
R.SpaceBeforeCtorInitializerColon &&
SpaceBeforeInheritanceColon == R.SpaceBeforeInheritanceColon &&
SpaceBeforeParens == R.SpaceBeforeParens &&
+ SpaceAroundPointerQualifiers == R.SpaceAroundPointerQualifiers &&
SpaceBeforeRangeBasedForLoopColon ==
R.SpaceBeforeRangeBasedForLoopColon &&
SpaceInEmptyBlock == R.SpaceInEmptyBlock &&
};
template <>
+struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
+ static void
+ enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) {
+ IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default);
+ IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before);
+ IO.enumCase(Value, "After", FormatStyle::SAPQ_After);
+ IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both);
+ }
+};
+
+template <>
struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
static void enumeration(IO &IO,
FormatStyle::SpaceBeforeParensOptions &Value) {
IO.mapOptional("SpaceBeforeInheritanceColon",
Style.SpaceBeforeInheritanceColon);
IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
+ IO.mapOptional("SpaceAroundPointerQualifiers",
+ Style.SpaceAroundPointerQualifiers);
IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
Style.SpaceBeforeRangeBasedForLoopColon);
IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock);
LLVMStyle.SpaceAfterCStyleCast = false;
LLVMStyle.SpaceAfterLogicalNot = false;
LLVMStyle.SpaceAfterTemplateKeyword = true;
+ LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
LLVMStyle.SpaceBeforeCtorInitializerColon = true;
LLVMStyle.SpaceBeforeInheritanceColon = true;
LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
if (!TokenBeforeMatchingParen || !Left.is(TT_TypeDeclarationParen))
return true;
}
+ // Add a space if the previous token is a pointer qualifer or the closing
+ // parenthesis of __attribute__(()) expression and the style requires spaces
+ // after pointer qualifiers.
+ if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After ||
+ Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
+ (Left.is(TT_AttributeParen) || Left.canBePointerOrReferenceQualifier()))
+ return true;
return (Left.Tok.isLiteral() ||
(!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
(Style.PointerAlignment != FormatStyle::PAS_Left ||
(Style.PointerAlignment != FormatStyle::PAS_Right &&
!Line.IsMultiVariableDeclStmt)))
return true;
- if (Left.is(TT_PointerOrReference))
+ if (Left.is(TT_PointerOrReference)) {
+ // Add a space if the next token is a pointer qualifer and the style
+ // requires spaces before pointer qualifiers.
+ if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Before ||
+ Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
+ Right.canBePointerOrReferenceQualifier())
+ return true;
return Right.Tok.isLiteral() || Right.is(TT_BlockComment) ||
(Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
!Right.is(TT_StartOfName)) ||
Left.Previous &&
!Left.Previous->isOneOf(tok::l_paren, tok::coloncolon,
tok::l_square));
+ }
// Ensure right pointer alignement with ellipsis e.g. int *...P
if (Left.is(tok::ellipsis) && Left.Previous &&
Left.Previous->isOneOf(tok::star, tok::amp, tok::ampamp))
NoSpaceStyle);
}
+TEST_F(FormatTest, ConfigurableSpaceAroundPointerQualifiers) {
+ FormatStyle Style = getLLVMStyle();
+
+ Style.PointerAlignment = FormatStyle::PAS_Left;
+ Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
+ verifyFormat("void* const* x = NULL;", Style);
+
+#define verifyQualifierSpaces(Code, Pointers, Qualifiers) \
+ do { \
+ Style.PointerAlignment = FormatStyle::Pointers; \
+ Style.SpaceAroundPointerQualifiers = FormatStyle::Qualifiers; \
+ verifyFormat(Code, Style); \
+ } while (false)
+
+ verifyQualifierSpaces("void* const* x = NULL;", PAS_Left, SAPQ_Default);
+ verifyQualifierSpaces("void *const *x = NULL;", PAS_Right, SAPQ_Default);
+ verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_Default);
+
+ verifyQualifierSpaces("void* const* x = NULL;", PAS_Left, SAPQ_Before);
+ verifyQualifierSpaces("void * const *x = NULL;", PAS_Right, SAPQ_Before);
+ verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_Before);
+
+ verifyQualifierSpaces("void* const * x = NULL;", PAS_Left, SAPQ_After);
+ verifyQualifierSpaces("void *const *x = NULL;", PAS_Right, SAPQ_After);
+ verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_After);
+
+ verifyQualifierSpaces("void* const * x = NULL;", PAS_Left, SAPQ_Both);
+ verifyQualifierSpaces("void * const *x = NULL;", PAS_Right, SAPQ_Both);
+ verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_Both);
+
+#undef verifyQualifierSpaces
+
+ FormatStyle Spaces = getLLVMStyle();
+ Spaces.AttributeMacros.push_back("qualified");
+ Spaces.PointerAlignment = FormatStyle::PAS_Right;
+ Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
+ verifyFormat("SomeType *volatile *a = NULL;", Spaces);
+ verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
+ verifyFormat("std::vector<SomeType *const *> x;", Spaces);
+ verifyFormat("std::vector<SomeType *qualified *> x;", Spaces);
+ verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces);
+ Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Before;
+ verifyFormat("SomeType * volatile *a = NULL;", Spaces);
+ verifyFormat("SomeType * __attribute__((attr)) *a = NULL;", Spaces);
+ verifyFormat("std::vector<SomeType * const *> x;", Spaces);
+ verifyFormat("std::vector<SomeType * qualified *> x;", Spaces);
+ verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces);
+
+ // Check that SAPQ_Before doesn't result in extra spaces for PAS_Left.
+ Spaces.PointerAlignment = FormatStyle::PAS_Left;
+ Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Before;
+ verifyFormat("SomeType* volatile* a = NULL;", Spaces);
+ verifyFormat("SomeType* __attribute__((attr))* a = NULL;", Spaces);
+ verifyFormat("std::vector<SomeType* const*> x;", Spaces);
+ verifyFormat("std::vector<SomeType* qualified*> x;", Spaces);
+ verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces);
+ // However, setting it to SAPQ_After should add spaces after __attribute, etc.
+ Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_After;
+ verifyFormat("SomeType* volatile * a = NULL;", Spaces);
+ verifyFormat("SomeType* __attribute__((attr)) * a = NULL;", Spaces);
+ verifyFormat("std::vector<SomeType* const *> x;", Spaces);
+ verifyFormat("std::vector<SomeType* qualified *> x;", Spaces);
+ verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces);
+
+ // PAS_Middle should not have any noticeable changes even for SAPQ_Both
+ Spaces.PointerAlignment = FormatStyle::PAS_Middle;
+ Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_After;
+ verifyFormat("SomeType * volatile * a = NULL;", Spaces);
+ verifyFormat("SomeType * __attribute__((attr)) * a = NULL;", Spaces);
+ verifyFormat("std::vector<SomeType * const *> x;", Spaces);
+ verifyFormat("std::vector<SomeType * qualified *> x;", Spaces);
+ verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces);
+}
+
TEST_F(FormatTest, AlignConsecutiveMacros) {
FormatStyle Style = getLLVMStyle();
Style.AlignConsecutiveAssignments = true;
CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+ Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both;
+ CHECK_PARSE("SpaceAroundPointerQualifiers: Default",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default);
+ CHECK_PARSE("SpaceAroundPointerQualifiers: Before",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Before);
+ CHECK_PARSE("SpaceAroundPointerQualifiers: After",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_After);
+ CHECK_PARSE("SpaceAroundPointerQualifiers: Both",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Both);
+
Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens,
FormatStyle::SBPO_Never);