Merge pull request #8014 from jakobandersen/utzig-named-variadic-arg

C, named variadic arg
This commit is contained in:
Jakob Lykke Andersen 2020-07-27 19:51:17 +02:00 committed by GitHub
commit 2cf3e7cae2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 3 deletions

View File

@ -43,6 +43,7 @@ Features added
The warnings printed from this functionality can be suppressed by setting
:confval:`c_warn_on_allowed_pre_v3`` to ``True``.
The functionality is immediately deprecated.
* #7999: C, add support for named variadic macro arguments.
Bugs fixed
----------

View File

@ -1200,13 +1200,17 @@ class ASTTypeWithInit(ASTBase):
class ASTMacroParameter(ASTBase):
def __init__(self, arg: ASTNestedName, ellipsis: bool = False) -> None:
def __init__(self, arg: ASTNestedName, ellipsis: bool = False,
variadic: bool = False) -> None:
self.arg = arg
self.ellipsis = ellipsis
self.variadic = variadic
def _stringify(self, transform: StringifyTransform) -> str:
if self.ellipsis:
return '...'
elif self.variadic:
return transform(self.arg) + '...'
else:
return transform(self.arg)
@ -1215,6 +1219,9 @@ class ASTMacroParameter(ASTBase):
verify_description_mode(mode)
if self.ellipsis:
signode += nodes.Text('...')
elif self.variadic:
name = str(self)
signode += nodes.emphasis(name, name)
else:
self.arg.describe_signature(signode, mode, env, symbol=symbol)
@ -2915,9 +2922,16 @@ class DefinitionParser(BaseParser):
if not self.match(identifier_re):
self.fail("Expected identifier in macro parameters.")
nn = ASTNestedName([ASTIdentifier(self.matched_text)], rooted=False)
arg = ASTMacroParameter(nn)
args.append(arg)
# Allow named variadic args:
# https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
self.skip_ws()
if self.skip_string_and_ws('...'):
args.append(ASTMacroParameter(nn, False, True))
self.skip_ws()
if not self.skip_string(')'):
self.fail('Expected ")" after "..." in macro parameters.')
break
args.append(ASTMacroParameter(nn))
if self.skip_string_and_ws(','):
continue
elif self.skip_string_and_ws(')'):

View File

@ -296,6 +296,10 @@ def test_macro_definitions():
check('macro', 'M(arg, ...)', {1: 'M'})
check('macro', 'M(arg1, arg2, ...)', {1: 'M'})
check('macro', 'M(arg1, arg2, arg3, ...)', {1: 'M'})
# GNU extension
check('macro', 'M(arg1, arg2, arg3...)', {1: 'M'})
with pytest.raises(DefinitionError):
check('macro', 'M(arg1, arg2..., arg3)', {1: 'M'})
def test_member_definitions():