25
25
Concept ,
26
26
DecltypeSpecifier ,
27
27
DecoratedType ,
28
+ DeductionGuide ,
28
29
EnumDecl ,
29
30
Enumerator ,
30
31
Field ,
@@ -1868,10 +1869,9 @@ def _parse_parameters(
1868
1869
_auto_return_typename = PQName ([AutoSpecifier ()])
1869
1870
1870
1871
def _parse_trailing_return_type (
1871
- self , fn : typing .Union [ Function , FunctionType ]
1872
- ) -> None :
1872
+ self , return_type : typing .Optional [ DecoratedType ]
1873
+ ) -> DecoratedType :
1873
1874
# entry is "->"
1874
- return_type = fn .return_type
1875
1875
if not (
1876
1876
isinstance (return_type , Type )
1877
1877
and not return_type .const
@@ -1890,8 +1890,7 @@ def _parse_trailing_return_type(
1890
1890
1891
1891
dtype = self ._parse_cv_ptr (parsed_type )
1892
1892
1893
- fn .has_trailing_return = True
1894
- fn .return_type = dtype
1893
+ return dtype
1895
1894
1896
1895
def _parse_fn_end (self , fn : Function ) -> None :
1897
1896
"""
@@ -1918,7 +1917,9 @@ def _parse_fn_end(self, fn: Function) -> None:
1918
1917
fn .raw_requires = self ._parse_requires (rtok )
1919
1918
1920
1919
if self .lex .token_if ("ARROW" ):
1921
- self ._parse_trailing_return_type (fn )
1920
+ return_type = self ._parse_trailing_return_type (fn .return_type )
1921
+ fn .has_trailing_return = True
1922
+ fn .return_type = return_type
1922
1923
1923
1924
if self .lex .token_if ("{" ):
1924
1925
self ._discard_contents ("{" , "}" )
@@ -1966,7 +1967,9 @@ def _parse_method_end(self, method: Method) -> None:
1966
1967
elif tok_value in ("&" , "&&" ):
1967
1968
method .ref_qualifier = tok_value
1968
1969
elif tok_value == "->" :
1969
- self ._parse_trailing_return_type (method )
1970
+ return_type = self ._parse_trailing_return_type (method .return_type )
1971
+ method .has_trailing_return = True
1972
+ method .return_type = return_type
1970
1973
if self .lex .token_if ("{" ):
1971
1974
self ._discard_contents ("{" , "}" )
1972
1975
method .has_body = True
@@ -2000,6 +2003,7 @@ def _parse_function(
2000
2003
is_friend : bool ,
2001
2004
is_typedef : bool ,
2002
2005
msvc_convention : typing .Optional [LexToken ],
2006
+ is_guide : bool = False ,
2003
2007
) -> bool :
2004
2008
"""
2005
2009
Assumes the caller has already consumed the return type and name, this consumes the
@@ -2076,7 +2080,21 @@ def _parse_function(
2076
2080
self .visitor .on_method_impl (state , method )
2077
2081
2078
2082
return method .has_body or method .has_trailing_return
2079
-
2083
+ elif is_guide :
2084
+ assert isinstance (state , (ExternBlockState , NamespaceBlockState ))
2085
+ if not self .lex .token_if ("ARROW" ):
2086
+ raise self ._parse_error (None , expected = "Trailing return type" )
2087
+ return_type = self ._parse_trailing_return_type (
2088
+ Type (PQName ([AutoSpecifier ()]))
2089
+ )
2090
+ guide = DeductionGuide (
2091
+ return_type ,
2092
+ name = pqname ,
2093
+ parameters = params ,
2094
+ doxygen = doxygen ,
2095
+ )
2096
+ self .visitor .on_deduction_guide (state , guide )
2097
+ return False
2080
2098
else :
2081
2099
assert return_type is not None
2082
2100
fn = Function (
@@ -2210,7 +2228,9 @@ def _parse_cv_ptr_or_fn(
2210
2228
assert not isinstance (dtype , FunctionType )
2211
2229
dtype = dtype_fn = FunctionType (dtype , fn_params , vararg )
2212
2230
if self .lex .token_if ("ARROW" ):
2213
- self ._parse_trailing_return_type (dtype_fn )
2231
+ return_type = self ._parse_trailing_return_type (dtype_fn .return_type )
2232
+ dtype_fn .has_trailing_return = True
2233
+ dtype_fn .return_type = return_type
2214
2234
2215
2235
else :
2216
2236
msvc_convention = None
@@ -2391,6 +2411,7 @@ def _parse_decl(
2391
2411
destructor = False
2392
2412
op = None
2393
2413
msvc_convention = None
2414
+ is_guide = False
2394
2415
2395
2416
# If we have a leading (, that's either an obnoxious grouping
2396
2417
# paren or it's a constructor
@@ -2441,8 +2462,15 @@ def _parse_decl(
2441
2462
# grouping paren like "void (name(int x));"
2442
2463
toks = self ._consume_balanced_tokens (tok )
2443
2464
2444
- # .. not sure what it's grouping, so put it back?
2445
- self .lex .return_tokens (toks [1 :- 1 ])
2465
+ # check to see if the next token is an arrow, and thus a trailing return
2466
+ if self .lex .token_peek_if ("ARROW" ):
2467
+ self .lex .return_tokens (toks )
2468
+ # the leading name of the class/ctor has been parsed as a type before the parens
2469
+ pqname = parsed_type .typename
2470
+ is_guide = True
2471
+ else :
2472
+ # .. not sure what it's grouping, so put it back?
2473
+ self .lex .return_tokens (toks [1 :- 1 ])
2446
2474
2447
2475
if dtype :
2448
2476
msvc_convention = self .lex .token_if_val (* self ._msvc_conventions )
@@ -2473,6 +2501,7 @@ def _parse_decl(
2473
2501
is_friend ,
2474
2502
is_typedef ,
2475
2503
msvc_convention ,
2504
+ is_guide ,
2476
2505
)
2477
2506
elif msvc_convention :
2478
2507
raise self ._parse_error (msvc_convention )
0 commit comments