C++, parse decltype(<expr>)

Fixes sphinx-doc/sphinx#4094
This commit is contained in:
Jakob Lykke Andersen
2017-11-26 21:41:15 +01:00
parent e7ba2abfb2
commit d6ec677c61
2 changed files with 30 additions and 2 deletions

View File

@@ -1931,6 +1931,24 @@ class ASTTrailingTypeSpecDecltypeAuto(ASTBase):
signode.append(nodes.Text(text_type(self)))
class ASTTrailingTypeSpecDecltype(ASTBase):
def __init__(self, expr):
self.expr = expr
def __unicode__(self):
return u'decltype(' + text_type(self.expr) + ')'
def get_id(self, version):
if version == 1:
raise NoOldIdError()
return 'DT' + self.expr.get_id(version) + "E"
def describe_signature(self, signode, mode, env, symbol):
signode.append(nodes.Text('decltype('))
self.expr.describe_signature(signode, mode, env, symbol)
signode.append(nodes.Text(')'))
class ASTFunctionParameter(ASTBase):
def __init__(self, arg, ellipsis=False):
# type: (Any, bool) -> None
@@ -4413,8 +4431,11 @@ class DefinitionParser(object):
if not self.skip_string(')'):
self.fail("Expected ')' after 'decltype(auto'.")
return ASTTrailingTypeSpecDecltypeAuto()
self.fail('"decltype(<expr>)" in trailing_type_spec not implemented')
# return ASTTrailingTypeSpecDecltype()
expr = self._parse_expression(inTemplate=False)
self.skip_ws()
if not self.skip_string(')'):
self.fail("Expected ')' after 'decltype(<expr>'.")
return ASTTrailingTypeSpecDecltype(expr)
# prefixed
prefix = None

View File

@@ -235,6 +235,7 @@ def test_type_definitions():
check("type", "bool ::B::b", {1:"B::b", 2:"N1B1bE"})
check('type', 'A = B', {2:'1A'})
check('type', 'A = decltype(b)', {2:'1A'})
# from breathe#267 (named function parameters for function pointers
check('type', 'void (*gpio_callback_t)(struct device *port, uint32_t pin)',
@@ -389,6 +390,8 @@ def test_function_definitions():
check('function', 'extern int f()', {1:'f', 2:'1fv'})
check('function', 'decltype(auto) f()', {1: 'f', 2:"1fv"})
# TODO: make tests for functions in a template, e.g., Test<int&&()>
# such that the id generation for function type types is correct.
@@ -466,6 +469,10 @@ def test_class_definitions():
check('class', 'A : B, C...', {1:'A', 2:'1A'})
check('class', 'A : B..., C', {1:'A', 2:'1A'})
# from #4094
check('class', 'template<class, class = std::void_t<>> has_var', {2:'I00E7has_var'})
check('class', 'template<class T> has_var<T, std::void_t<decltype(&T::var)>>', {2:'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'})
def test_enum_definitions():
check('enum', 'A', {2:"1A"})