omarahmed updated this revision to Diff 438433.
omarahmed added a comment.
- Add version for nestedEnums and nestedFields
- Make tests valid
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/docs/tools/dump_format_style.py
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,42 @@
"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_Never);
+ verifyFormat("struct A {\n"
+ " int *a;\n"
+ " A(int *p) : a(new(p) int) {\n"
+ " new(p) int;\n"
+ " int *b = new(p) int;\n"
+ " int *c = new(p) int(3);\n"
+ " delete(b);\n"
+ " }\n"
+ "};",
+ AfterPlacementOperator);
+ verifyFormat("void operator new(void *foo) ATTRIB;", AfterPlacementOperator);
+
+ AfterPlacementOperator.SpaceBeforeParensOptions.AfterPlacementOperator =
+ FormatStyle::SpaceBeforeParensCustom::APO_Always;
+ verifyFormat("struct A {\n"
+ " int *a;\n"
+ " A(int *p) : a(new (p) int) {\n"
+ " new (p) int;\n"
+ " int *b = new (p) int;\n"
+ " int *c = new (p) int(3);\n"
+ " delete (b);\n"
+ " }\n"
+ "};",
+ AfterPlacementOperator);
+ verifyFormat("void operator new(void *foo) ATTRIB;", AfterPlacementOperator);
+
+ AfterPlacementOperator.SpaceBeforeParensOptions.AfterPlacementOperator =
+ FormatStyle::SpaceBeforeParensCustom::APO_Leave;
+ EXPECT_EQ("new (buf) int;", format("new (buf) int;", AfterPlacementOperator));
+ EXPECT_EQ("new(buf) int;", format("new(buf) int;", AfterPlacementOperator));
}
TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
@@ -20308,6 +20344,24 @@
SpaceBeforeParens,
FormatStyle::SBPO_ControlStatementsExceptControlMacros);
+ Style.SpaceBeforeParens = FormatStyle::SBPO_Custom;
+ Style.SpaceBeforeParensOptions.AfterPlacementOperator =
+ FormatStyle::SpaceBeforeParensCustom::APO_Always;
+ CHECK_PARSE("SpaceBeforeParensOptions:\n"
+ " AfterPlacementOperator: Never",
+ SpaceBeforeParensOptions.AfterPlacementOperator,
+ FormatStyle::SpaceBeforeParensCustom::APO_Never);
+
+ CHECK_PARSE("SpaceBeforeParensOptions:\n"
+ " AfterPlacementOperator: Always",
+ SpaceBeforeParensOptions.AfterPlacementOperator,
+ FormatStyle::SpaceBeforeParensCustom::APO_Always);
+
+ CHECK_PARSE("SpaceBeforeParensOptions:\n"
+ " AfterPlacementOperator: Leave",
+ SpaceBeforeParensOptions.AfterPlacementOperator,
+ FormatStyle::SpaceBeforeParensCustom::APO_Leave);
+
Style.ColumnLimit = 123;
FormatStyle BaseStyle = getLLVMStyle();
CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
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
@@ -3498,6 +3498,28 @@
/// object.operator++ (10); object.operator++(10);
/// \endcode
bool AfterOverloadedOperator;
+ /// Styles for adding spacing between ``new/delete`` operators and opening
+ /// parentheses.
+ enum AfterPlacementOperatorStyle : int8_t {
+ /// Removes 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 14
+ AfterPlacementOperatorStyle AfterPlacementOperator;
/// If ``true``, put space between requires keyword in a requires clause and
/// opening parentheses, if there is one.
/// \code
@@ -3530,8 +3552,9 @@
: AfterControlStatements(false), AfterForeachMacros(false),
AfterFunctionDeclarationName(false),
AfterFunctionDefinitionName(false), AfterIfMacros(false),
- AfterOverloadedOperator(false), AfterRequiresInClause(false),
- AfterRequiresInExpression(false), BeforeNonEmptyParentheses(false) {}
+ AfterOverloadedOperator(false), AfterPlacementOperator(APO_Never),
+ AfterRequiresInClause(false), AfterRequiresInExpression(false),
+ BeforeNonEmptyParentheses(false) {}
bool operator==(const SpaceBeforeParensCustom &Other) const {
return AfterControlStatements == Other.AfterControlStatements &&
@@ -3541,6 +3564,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/tools/dump_format_style.py
===================================================================
--- clang/docs/tools/dump_format_style.py
+++ clang/docs/tools/dump_format_style.py
@@ -121,11 +121,17 @@
return self.comment + '\n' + '\n'.join(map(str, self.values))
class NestedField(object):
- def __init__(self, name, comment):
+ def __init__(self, name, comment, version):
self.name = name
self.comment = comment.strip()
+ self.version = version
def __str__(self):
+ if self.version:
+ return '\n* ``%s`` :versionbadge:`clang-format %s`\n%s' % (
+ self.name,
+ self.version,
+ doxygen2rst(indent(self.comment, 2, indent_first_line=False)))
return '\n* ``%s`` %s' % (
self.name,
doxygen2rst(indent(self.comment, 2, indent_first_line=False)))
@@ -140,14 +146,20 @@
return '\n'.join(map(str, self.values))
class NestedEnum(object):
- def __init__(self, name, enumtype, comment, values):
+ def __init__(self, name, enumtype, comment,version, values):
self.name = name
self.comment = comment
self.values = values
self.type = enumtype
+ self.version = version
def __str__(self):
- s = '\n* ``%s %s``\n%s' % (to_yaml_type(self.type), self.name,
+ s = ""
+ if self.version:
+ s = '\n* ``%s %s`` :versionbadge:`clang-format %s`\n\n%s' % (to_yaml_type(self.type), self.name, self.version,
+ doxygen2rst(indent(self.comment, 2)))
+ else:
+ s = '\n* ``%s %s``\n%s' % (to_yaml_type(self.type), self.name,
doxygen2rst(indent(self.comment, 2)))
s += indent('\nPossible values:\n\n', 2)
s += indent('\n'.join(map(str, self.values)), 2)
@@ -227,7 +239,7 @@
def read_options(self):
class State:
BeforeStruct, Finished, InStruct, InNestedStruct, InNestedFieldComment, \
- InFieldComment, InEnum, InEnumMemberComment = range(8)
+ InFieldComment, InEnum, InEnumMemberComment, InNestedEnum, InNestedEnumMemberComment = range(10)
state = State.BeforeStruct
options = []
@@ -286,19 +298,30 @@
state = State.InStruct
nested_structs[nested_struct.name] = nested_struct
elif state == State.InNestedFieldComment:
- if line.startswith('///'):
+ if line.startswith(r'/// \version'):
+ match = re.match(r'/// \\version\s*(?P<version>[0-9.]+)*', line)
+ if match:
+ version = match.group('version')
+ elif line.startswith('///'):
comment += self.__clean_comment_line(line)
+ elif line.startswith('enum'):
+ state = State.InNestedEnum
+ name = re.sub(r'enum\s+(\w+)\s*(:((\s*\w+)+)\s*)?\{', '\\1', line)
+ enum = Enum(name, comment)
else:
state = State.InNestedStruct
field_type, field_name = re.match(r'([<>:\w(,\s)]+)\s+(\w+);', line).groups()
+ if not version:
+ self.__warning(f'missing version for {field_name}', line)
if field_type in enums:
nested_struct.values.append(NestedEnum(field_name,
field_type,
comment,
+ version,
enums[field_type].values))
else:
- nested_struct.values.append(NestedField(field_type + " " + field_name, comment))
-
+ nested_struct.values.append(NestedField(field_type + " " + field_name, comment, version))
+ version = None
elif state == State.InEnum:
if line.startswith('///'):
state = State.InEnumMemberComment
@@ -310,6 +333,17 @@
# Enum member without documentation. Must be documented where the enum
# is used.
pass
+ elif state == State.InNestedEnum:
+ if line.startswith('///'):
+ state = State.InNestedEnumMemberComment
+ comment = self.__clean_comment_line(line)
+ elif line == '};':
+ state = State.InNestedStruct
+ enums[enum.name] = enum
+ else:
+ # Enum member without documentation. Must be documented where the enum
+ # is used.
+ pass
elif state == State.InEnumMemberComment:
if line.startswith('///'):
comment += self.__clean_comment_line(line)
@@ -323,6 +357,19 @@
else:
config = val
enum.values.append(EnumValue(val, comment, config))
+ elif state == State.InNestedEnumMemberComment:
+ if line.startswith('///'):
+ comment += self.__clean_comment_line(line)
+ else:
+ state = State.InNestedEnum
+ val = line.replace(',', '')
+ pos = val.find(" // ")
+ if pos != -1:
+ config = val[pos + 4:]
+ val = val[:pos]
+ else:
+ config = val
+ enum.values.append(EnumValue(val, comment, config))
if state != State.Finished:
raise Exception('Not finished by the end of file')
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -4258,6 +4258,33 @@
void operator++ (int a); vs. void operator++(int a);
object.operator++ (10); object.operator++(10);
+ * ``AfterPlacementOperatorStyle AfterPlacementOperator`` :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``)
+ Removes space after ``new/delete`` operators and before ``(``.
+
+ .. code-block:: c++
+
+ new(buf) T;
+ delete(buf) T;
+
+ * ``APO_Always`` (in configuration: ``Always``)
+ Always add space after ``new/delete`` operators and before ``(``.
+
+ .. code-block:: c++
+
+ new (buf) T;
+ delete (buf) T;
+
+ * ``APO_Leave`` (in configuration: ``Leave``)
+ 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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits