mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #9379 from jakobandersen/cpp_various
C++ (and C), various additions
This commit is contained in:
commit
eda4b1cfc4
12
CHANGES
12
CHANGES
@ -53,6 +53,18 @@ Features added
|
||||
* #9097: Optimize the paralell build
|
||||
* #9131: Add :confval:`nitpick_ignore_regex` to ignore nitpicky warnings using
|
||||
regular expressions
|
||||
* C++, add support for
|
||||
|
||||
- ``inline`` variables,
|
||||
- ``consteval`` functions,
|
||||
- ``constinit`` variables,
|
||||
- ``char8_t``,
|
||||
- ``explicit(<constant expression>)`` specifier,
|
||||
- digit separators in literals, and
|
||||
- constraints in placeholder type specifiers, aka. adjective syntax
|
||||
(e.g., ``Sortable auto &v``).
|
||||
|
||||
* C, add support for digit separators in literals.
|
||||
|
||||
|
||||
Bugs fixed
|
||||
|
@ -319,8 +319,9 @@ _fold_operator_re = re.compile(r'''(?x)
|
||||
# see https://en.cppreference.com/w/cpp/keyword
|
||||
_keywords = [
|
||||
'alignas', 'alignof', 'and', 'and_eq', 'asm', 'auto', 'bitand', 'bitor',
|
||||
'bool', 'break', 'case', 'catch', 'char', 'char16_t', 'char32_t', 'class',
|
||||
'compl', 'concept', 'const', 'constexpr', 'const_cast', 'continue',
|
||||
'bool', 'break', 'case', 'catch', 'char', 'char8_t', 'char16_t', 'char32_t',
|
||||
'class', 'compl', 'concept', 'const', 'consteval', 'constexpr', 'constinit',
|
||||
'const_cast', 'continue',
|
||||
'decltype', 'default', 'delete', 'do', 'double', 'dynamic_cast', 'else',
|
||||
'enum', 'explicit', 'export', 'extern', 'false', 'float', 'for', 'friend',
|
||||
'goto', 'if', 'inline', 'int', 'long', 'mutable', 'namespace', 'new',
|
||||
@ -426,6 +427,7 @@ _id_fundamental_v2 = {
|
||||
'wchar_t': 'w',
|
||||
'char32_t': 'Di',
|
||||
'char16_t': 'Ds',
|
||||
'char8_t': 'Du',
|
||||
'short': 's',
|
||||
'short int': 's',
|
||||
'signed short': 's',
|
||||
@ -1880,9 +1882,11 @@ class ASTTrailingTypeSpecDecltype(ASTTrailingTypeSpec):
|
||||
|
||||
|
||||
class ASTTrailingTypeSpecName(ASTTrailingTypeSpec):
|
||||
def __init__(self, prefix: str, nestedName: ASTNestedName) -> None:
|
||||
def __init__(self, prefix: str, nestedName: ASTNestedName,
|
||||
placeholderType: Optional[str]) -> None:
|
||||
self.prefix = prefix
|
||||
self.nestedName = nestedName
|
||||
self.placeholderType = placeholderType
|
||||
|
||||
@property
|
||||
def name(self) -> ASTNestedName:
|
||||
@ -1897,6 +1901,9 @@ class ASTTrailingTypeSpecName(ASTTrailingTypeSpec):
|
||||
res.append(self.prefix)
|
||||
res.append(' ')
|
||||
res.append(transform(self.nestedName))
|
||||
if self.placeholderType is not None:
|
||||
res.append(' ')
|
||||
res.append(self.placeholderType)
|
||||
return ''.join(res)
|
||||
|
||||
def describe_signature(self, signode: TextElement, mode: str,
|
||||
@ -1905,6 +1912,17 @@ class ASTTrailingTypeSpecName(ASTTrailingTypeSpec):
|
||||
signode += addnodes.desc_sig_keyword(self.prefix, self.prefix)
|
||||
signode += addnodes.desc_sig_space()
|
||||
self.nestedName.describe_signature(signode, mode, env, symbol=symbol)
|
||||
if self.placeholderType is not None:
|
||||
signode += addnodes.desc_sig_space()
|
||||
if self.placeholderType == 'auto':
|
||||
signode += addnodes.desc_sig_keyword('auto', 'auto')
|
||||
elif self.placeholderType == 'decltype(auto)':
|
||||
signode += addnodes.desc_sig_keyword('decltype', 'decltype')
|
||||
signode += addnodes.desc_sig_punctuation('(', '(')
|
||||
signode += addnodes.desc_sig_keyword('auto', 'auto')
|
||||
signode += addnodes.desc_sig_punctuation(')', ')')
|
||||
else:
|
||||
assert False, self.placeholderType
|
||||
|
||||
|
||||
class ASTFunctionParameter(ASTBase):
|
||||
@ -2099,16 +2117,41 @@ class ASTParametersQualifiers(ASTBase):
|
||||
signode += addnodes.desc_sig_keyword(self.initializer, self.initializer)
|
||||
|
||||
|
||||
class ASTExplicitSpec(ASTBase):
|
||||
def __init__(self, expr: Optional[ASTExpression]) -> None:
|
||||
self.expr = expr
|
||||
|
||||
def _stringify(self, transform: StringifyTransform) -> str:
|
||||
res = ['explicit']
|
||||
if self.expr is not None:
|
||||
res.append('(')
|
||||
res.append(transform(self.expr))
|
||||
res.append(')')
|
||||
return ''.join(res)
|
||||
|
||||
def describe_signature(self, signode: TextElement,
|
||||
env: "BuildEnvironment", symbol: "Symbol") -> None:
|
||||
signode += addnodes.desc_sig_keyword('explicit', 'explicit')
|
||||
if self.expr is not None:
|
||||
signode += addnodes.desc_sig_punctuation('(', '(')
|
||||
self.expr.describe_signature(signode, 'markType', env, symbol)
|
||||
signode += addnodes.desc_sig_punctuation(')', ')')
|
||||
|
||||
|
||||
class ASTDeclSpecsSimple(ASTBase):
|
||||
def __init__(self, storage: str, threadLocal: bool, inline: bool, virtual: bool,
|
||||
explicit: bool, constexpr: bool, volatile: bool, const: bool,
|
||||
friend: bool, attrs: List[ASTAttribute]) -> None:
|
||||
explicitSpec: Optional[ASTExplicitSpec],
|
||||
consteval: bool, constexpr: bool, constinit: bool,
|
||||
volatile: bool, const: bool, friend: bool,
|
||||
attrs: List[ASTAttribute]) -> None:
|
||||
self.storage = storage
|
||||
self.threadLocal = threadLocal
|
||||
self.inline = inline
|
||||
self.virtual = virtual
|
||||
self.explicit = explicit
|
||||
self.explicitSpec = explicitSpec
|
||||
self.consteval = consteval
|
||||
self.constexpr = constexpr
|
||||
self.constinit = constinit
|
||||
self.volatile = volatile
|
||||
self.const = const
|
||||
self.friend = friend
|
||||
@ -2121,8 +2164,10 @@ class ASTDeclSpecsSimple(ASTBase):
|
||||
self.threadLocal or other.threadLocal,
|
||||
self.inline or other.inline,
|
||||
self.virtual or other.virtual,
|
||||
self.explicit or other.explicit,
|
||||
self.explicitSpec or other.explicitSpec,
|
||||
self.consteval or other.consteval,
|
||||
self.constexpr or other.constexpr,
|
||||
self.constinit or other.constinit,
|
||||
self.volatile or other.volatile,
|
||||
self.const or other.const,
|
||||
self.friend or other.friend,
|
||||
@ -2141,17 +2186,22 @@ class ASTDeclSpecsSimple(ASTBase):
|
||||
res.append('friend')
|
||||
if self.virtual:
|
||||
res.append('virtual')
|
||||
if self.explicit:
|
||||
res.append('explicit')
|
||||
if self.explicitSpec:
|
||||
res.append(transform(self.explicitSpec))
|
||||
if self.consteval:
|
||||
res.append('consteval')
|
||||
if self.constexpr:
|
||||
res.append('constexpr')
|
||||
if self.constinit:
|
||||
res.append('constinit')
|
||||
if self.volatile:
|
||||
res.append('volatile')
|
||||
if self.const:
|
||||
res.append('const')
|
||||
return ' '.join(res)
|
||||
|
||||
def describe_signature(self, signode: TextElement) -> None:
|
||||
def describe_signature(self, signode: TextElement,
|
||||
env: "BuildEnvironment", symbol: "Symbol") -> None:
|
||||
addSpace = False
|
||||
for attr in self.attrs:
|
||||
if addSpace:
|
||||
@ -2175,10 +2225,17 @@ class ASTDeclSpecsSimple(ASTBase):
|
||||
addSpace = _add(signode, 'friend')
|
||||
if self.virtual:
|
||||
addSpace = _add(signode, 'virtual')
|
||||
if self.explicit:
|
||||
addSpace = _add(signode, 'explicit')
|
||||
if self.explicitSpec:
|
||||
if addSpace:
|
||||
signode += addnodes.desc_sig_space()
|
||||
self.explicitSpec.describe_signature(signode, env, symbol)
|
||||
addSpace = True
|
||||
if self.consteval:
|
||||
addSpace = _add(signode, 'consteval')
|
||||
if self.constexpr:
|
||||
addSpace = _add(signode, 'constexpr')
|
||||
if self.constinit:
|
||||
addSpace = _add(signode, 'constinit')
|
||||
if self.volatile:
|
||||
addSpace = _add(signode, 'volatile')
|
||||
if self.const:
|
||||
@ -2235,7 +2292,7 @@ class ASTDeclSpecs(ASTBase):
|
||||
env: "BuildEnvironment", symbol: "Symbol") -> None:
|
||||
verify_description_mode(mode)
|
||||
numChildren = len(signode)
|
||||
self.leftSpecs.describe_signature(signode)
|
||||
self.leftSpecs.describe_signature(signode, env, symbol)
|
||||
addSpace = len(signode) != numChildren
|
||||
|
||||
if self.trailingTypeSpec:
|
||||
@ -2249,7 +2306,7 @@ class ASTDeclSpecs(ASTBase):
|
||||
if len(str(self.rightSpecs)) > 0:
|
||||
if addSpace:
|
||||
signode += addnodes.desc_sig_space()
|
||||
self.rightSpecs.describe_signature(signode)
|
||||
self.rightSpecs.describe_signature(signode, env, symbol)
|
||||
|
||||
|
||||
# Declarator
|
||||
@ -4942,8 +4999,8 @@ class DefinitionParser(BaseParser):
|
||||
# those without signedness and size modifiers
|
||||
# see https://en.cppreference.com/w/cpp/language/types
|
||||
_simple_fundemental_types = (
|
||||
'void', 'bool', 'char', 'wchar_t', 'char16_t', 'char32_t', 'int',
|
||||
'float', 'double', 'auto'
|
||||
'void', 'bool', 'char', 'wchar_t', 'char8_t', 'char16_t', 'char32_t',
|
||||
'int', 'float', 'double', 'auto'
|
||||
)
|
||||
|
||||
_prefix_keys = ('class', 'struct', 'enum', 'union', 'typename')
|
||||
@ -5815,7 +5872,19 @@ class DefinitionParser(BaseParser):
|
||||
prefix = k
|
||||
break
|
||||
nestedName = self._parse_nested_name()
|
||||
return ASTTrailingTypeSpecName(prefix, nestedName)
|
||||
self.skip_ws()
|
||||
placeholderType = None
|
||||
if self.skip_word('auto'):
|
||||
placeholderType = 'auto'
|
||||
elif self.skip_word_and_ws('decltype'):
|
||||
if not self.skip_string_and_ws('('):
|
||||
self.fail("Expected '(' after 'decltype' in placeholder type specifier.")
|
||||
if not self.skip_word_and_ws('auto'):
|
||||
self.fail("Expected 'auto' after 'decltype(' in placeholder type specifier.")
|
||||
if not self.skip_string_and_ws(')'):
|
||||
self.fail("Expected ')' after 'decltype(auto' in placeholder type specifier.")
|
||||
placeholderType = 'decltype(auto)'
|
||||
return ASTTrailingTypeSpecName(prefix, nestedName, placeholderType)
|
||||
|
||||
def _parse_parameters_and_qualifiers(self, paramMode: str) -> ASTParametersQualifiers:
|
||||
if paramMode == 'new':
|
||||
@ -5929,14 +5998,24 @@ class DefinitionParser(BaseParser):
|
||||
threadLocal = None
|
||||
inline = None
|
||||
virtual = None
|
||||
explicit = None
|
||||
explicitSpec = None
|
||||
consteval = None
|
||||
constexpr = None
|
||||
constinit = None
|
||||
volatile = None
|
||||
const = None
|
||||
friend = None
|
||||
attrs = []
|
||||
while 1: # accept any permutation of a subset of some decl-specs
|
||||
self.skip_ws()
|
||||
if not const and typed:
|
||||
const = self.skip_word('const')
|
||||
if const:
|
||||
continue
|
||||
if not volatile and typed:
|
||||
volatile = self.skip_word('volatile')
|
||||
if volatile:
|
||||
continue
|
||||
if not storage:
|
||||
if outer in ('member', 'function'):
|
||||
if self.skip_word('static'):
|
||||
@ -5952,16 +6031,28 @@ class DefinitionParser(BaseParser):
|
||||
if self.skip_word('register'):
|
||||
storage = 'register'
|
||||
continue
|
||||
if not threadLocal and outer == 'member':
|
||||
threadLocal = self.skip_word('thread_local')
|
||||
if threadLocal:
|
||||
if not inline and outer in ('function', 'member'):
|
||||
inline = self.skip_word('inline')
|
||||
if inline:
|
||||
continue
|
||||
if not constexpr and outer in ('member', 'function'):
|
||||
constexpr = self.skip_word("constexpr")
|
||||
if constexpr:
|
||||
continue
|
||||
|
||||
if outer == 'member':
|
||||
if not constinit:
|
||||
constinit = self.skip_word('constinit')
|
||||
if constinit:
|
||||
continue
|
||||
if not threadLocal:
|
||||
threadLocal = self.skip_word('thread_local')
|
||||
if threadLocal:
|
||||
continue
|
||||
if outer == 'function':
|
||||
# function-specifiers
|
||||
if not inline:
|
||||
inline = self.skip_word('inline')
|
||||
if inline:
|
||||
if not consteval:
|
||||
consteval = self.skip_word('consteval')
|
||||
if consteval:
|
||||
continue
|
||||
if not friend:
|
||||
friend = self.skip_word('friend')
|
||||
@ -5971,31 +6062,28 @@ class DefinitionParser(BaseParser):
|
||||
virtual = self.skip_word('virtual')
|
||||
if virtual:
|
||||
continue
|
||||
if not explicit:
|
||||
explicit = self.skip_word('explicit')
|
||||
if not explicitSpec:
|
||||
explicit = self.skip_word_and_ws('explicit')
|
||||
if explicit:
|
||||
expr: ASTExpression = None
|
||||
if self.skip_string('('):
|
||||
expr = self._parse_constant_expression(inTemplate=False)
|
||||
if not expr:
|
||||
self.fail("Expected constant expression after '('" +
|
||||
" in explicit specifier.")
|
||||
self.skip_ws()
|
||||
if not self.skip_string(')'):
|
||||
self.fail("Expected ')' to end explicit specifier.")
|
||||
explicitSpec = ASTExplicitSpec(expr)
|
||||
continue
|
||||
|
||||
if not constexpr and outer in ('member', 'function'):
|
||||
constexpr = self.skip_word("constexpr")
|
||||
if constexpr:
|
||||
continue
|
||||
if not volatile and typed:
|
||||
volatile = self.skip_word('volatile')
|
||||
if volatile:
|
||||
continue
|
||||
if not const and typed:
|
||||
const = self.skip_word('const')
|
||||
if const:
|
||||
continue
|
||||
attr = self._parse_attribute()
|
||||
if attr:
|
||||
attrs.append(attr)
|
||||
continue
|
||||
break
|
||||
return ASTDeclSpecsSimple(storage, threadLocal, inline, virtual,
|
||||
explicit, constexpr, volatile, const,
|
||||
friend, attrs)
|
||||
explicitSpec, consteval, constexpr, constinit,
|
||||
volatile, const, friend, attrs)
|
||||
|
||||
def _parse_decl_specs(self, outer: str, typed: bool = True) -> ASTDeclSpecs:
|
||||
if outer:
|
||||
|
@ -33,10 +33,10 @@ identifier_re = re.compile(r'''(?x)
|
||||
)
|
||||
[a-zA-Z0-9_]*\b
|
||||
''')
|
||||
integer_literal_re = re.compile(r'[1-9][0-9]*')
|
||||
octal_literal_re = re.compile(r'0[0-7]*')
|
||||
hex_literal_re = re.compile(r'0[xX][0-9a-fA-F][0-9a-fA-F]*')
|
||||
binary_literal_re = re.compile(r'0[bB][01][01]*')
|
||||
integer_literal_re = re.compile(r'[1-9][0-9]*(\'[0-9]+)*')
|
||||
octal_literal_re = re.compile(r'0[0-7]*(\'[0-7]+)*')
|
||||
hex_literal_re = re.compile(r'0[xX][0-9a-fA-F]+(\'[0-9a-fA-F]+)*')
|
||||
binary_literal_re = re.compile(r'0[bB][01]+(\'[01]+)*')
|
||||
integers_literal_suffix_re = re.compile(r'''(?x)
|
||||
# unsigned and/or (long) long, in any order, but at least one of them
|
||||
(
|
||||
@ -50,13 +50,14 @@ integers_literal_suffix_re = re.compile(r'''(?x)
|
||||
float_literal_re = re.compile(r'''(?x)
|
||||
[+-]?(
|
||||
# decimal
|
||||
([0-9]+[eE][+-]?[0-9]+)
|
||||
| ([0-9]*\.[0-9]+([eE][+-]?[0-9]+)?)
|
||||
| ([0-9]+\.([eE][+-]?[0-9]+)?)
|
||||
([0-9]+(\'[0-9]+)*[eE][+-]?[0-9]+(\'[0-9]+)*)
|
||||
| (([0-9]+(\'[0-9]+)*)?\.[0-9]+(\'[0-9]+)*([eE][+-]?[0-9]+(\'[0-9]+)*)?)
|
||||
| ([0-9]+(\'[0-9]+)*\.([eE][+-]?[0-9]+(\'[0-9]+)*)?)
|
||||
# hex
|
||||
| (0[xX][0-9a-fA-F]+[pP][+-]?[0-9a-fA-F]+)
|
||||
| (0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+([pP][+-]?[0-9a-fA-F]+)?)
|
||||
| (0[xX][0-9a-fA-F]+\.([pP][+-]?[0-9a-fA-F]+)?)
|
||||
| (0[xX][0-9a-fA-F]+(\'[0-9a-fA-F]+)*[pP][+-]?[0-9a-fA-F]+(\'[0-9a-fA-F]+)*)
|
||||
| (0[xX]([0-9a-fA-F]+(\'[0-9a-fA-F]+)*)?\.
|
||||
[0-9a-fA-F]+(\'[0-9a-fA-F]+)*([pP][+-]?[0-9a-fA-F]+(\'[0-9a-fA-F]+)*)?)
|
||||
| (0[xX][0-9a-fA-F]+(\'[0-9a-fA-F]+)*\.([pP][+-]?[0-9a-fA-F]+(\'[0-9a-fA-F]+)*)?)
|
||||
)
|
||||
''')
|
||||
float_literal_suffix_re = re.compile(r'[fFlL]\b')
|
||||
|
@ -155,7 +155,8 @@ def test_domain_c_ast_expressions():
|
||||
# primary
|
||||
exprCheck('true')
|
||||
exprCheck('false')
|
||||
ints = ['5', '0', '075', '0x0123456789ABCDEF', '0XF', '0b1', '0B1']
|
||||
ints = ['5', '0', '075', '0x0123456789ABCDEF', '0XF', '0b1', '0B1',
|
||||
"0b0'1'0", "00'1'2", "0x0'1'2", "1'2'3"]
|
||||
unsignedSuffix = ['', 'u', 'U']
|
||||
longSuffix = ['', 'l', 'L', 'll', 'LL']
|
||||
for i in ints:
|
||||
@ -170,14 +171,18 @@ def test_domain_c_ast_expressions():
|
||||
'5e42', '5e+42', '5e-42',
|
||||
'5.', '5.e42', '5.e+42', '5.e-42',
|
||||
'.5', '.5e42', '.5e+42', '.5e-42',
|
||||
'5.0', '5.0e42', '5.0e+42', '5.0e-42']:
|
||||
'5.0', '5.0e42', '5.0e+42', '5.0e-42',
|
||||
"1'2'3e7'8'9", "1'2'3.e7'8'9",
|
||||
".4'5'6e7'8'9", "1'2'3.4'5'6e7'8'9"]:
|
||||
expr = e + suffix
|
||||
exprCheck(expr)
|
||||
for e in [
|
||||
'ApF', 'Ap+F', 'Ap-F',
|
||||
'A.', 'A.pF', 'A.p+F', 'A.p-F',
|
||||
'.A', '.ApF', '.Ap+F', '.Ap-F',
|
||||
'A.B', 'A.BpF', 'A.Bp+F', 'A.Bp-F']:
|
||||
'A.B', 'A.BpF', 'A.Bp+F', 'A.Bp-F',
|
||||
"A'B'Cp1'2'3", "A'B'C.p1'2'3",
|
||||
".D'E'Fp1'2'3", "A'B'C.D'E'Fp1'2'3"]:
|
||||
expr = "0x" + e + suffix
|
||||
exprCheck(expr)
|
||||
exprCheck('"abc\\"cba"') # string
|
||||
|
@ -126,6 +126,7 @@ def test_domain_cpp_ast_fundamental_types():
|
||||
id = t.replace(" ", "-").replace("long", "l").replace("int", "i")
|
||||
id = id.replace("bool", "b").replace("char", "c")
|
||||
id = id.replace("wc_t", "wchar_t").replace("c16_t", "char16_t")
|
||||
id = id.replace("c8_t", "char8_t")
|
||||
id = id.replace("c32_t", "char32_t")
|
||||
return "f__%s" % id
|
||||
|
||||
@ -173,7 +174,8 @@ def test_domain_cpp_ast_expressions():
|
||||
exprCheck('nullptr', 'LDnE')
|
||||
exprCheck('true', 'L1E')
|
||||
exprCheck('false', 'L0E')
|
||||
ints = ['5', '0', '075', '0x0123456789ABCDEF', '0XF', '0b1', '0B1']
|
||||
ints = ['5', '0', '075', '0x0123456789ABCDEF', '0XF', '0b1', '0B1',
|
||||
"0b0'1'0", "00'1'2", "0x0'1'2", "1'2'3"]
|
||||
unsignedSuffix = ['', 'u', 'U']
|
||||
longSuffix = ['', 'l', 'L', 'll', 'LL']
|
||||
for i in ints:
|
||||
@ -186,11 +188,15 @@ def test_domain_cpp_ast_expressions():
|
||||
decimalFloats = ['5e42', '5e+42', '5e-42',
|
||||
'5.', '5.e42', '5.e+42', '5.e-42',
|
||||
'.5', '.5e42', '.5e+42', '.5e-42',
|
||||
'5.0', '5.0e42', '5.0e+42', '5.0e-42']
|
||||
'5.0', '5.0e42', '5.0e+42', '5.0e-42',
|
||||
"1'2'3e7'8'9", "1'2'3.e7'8'9",
|
||||
".4'5'6e7'8'9", "1'2'3.4'5'6e7'8'9"]
|
||||
hexFloats = ['ApF', 'Ap+F', 'Ap-F',
|
||||
'A.', 'A.pF', 'A.p+F', 'A.p-F',
|
||||
'.A', '.ApF', '.Ap+F', '.Ap-F',
|
||||
'A.B', 'A.BpF', 'A.Bp+F', 'A.Bp-F']
|
||||
'A.B', 'A.BpF', 'A.Bp+F', 'A.Bp-F',
|
||||
"A'B'Cp1'2'3", "A'B'C.p1'2'3",
|
||||
".D'E'Fp1'2'3", "A'B'C.D'E'Fp1'2'3"]
|
||||
for suffix in ['', 'f', 'F', 'l', 'L']:
|
||||
for e in decimalFloats:
|
||||
expr = e + suffix
|
||||
@ -435,6 +441,9 @@ def test_domain_cpp_ast_member_definitions():
|
||||
# check('member', 'int b : (true ? 8 : a) = 42', {1: 'b__i', 2: '1b'})
|
||||
check('member', 'int b : 1 || new int{0}', {1: 'b__i', 2: '1b'})
|
||||
|
||||
check('member', 'inline int n', {1: 'n__i', 2: '1n'})
|
||||
check('member', 'constinit int n', {1: 'n__i', 2: '1n'})
|
||||
|
||||
|
||||
def test_domain_cpp_ast_function_definitions():
|
||||
check('function', 'void f(volatile int)', {1: "f__iV", 2: "1fVi"})
|
||||
@ -565,6 +574,9 @@ def test_domain_cpp_ast_function_definitions():
|
||||
check("function", "void f(int *volatile const p)", {1: "f__iPVC", 2: "1fPVCi"})
|
||||
|
||||
check('function', 'extern int f()', {1: 'f', 2: '1fv'})
|
||||
check('function', 'consteval int f()', {1: 'f', 2: '1fv'})
|
||||
|
||||
check('function', 'explicit(true) void f()', {1: 'f', 2: '1fv'})
|
||||
|
||||
check('function', 'decltype(auto) f()', {1: 'f', 2: "1fv"})
|
||||
|
||||
@ -854,6 +866,15 @@ def test_domain_cpp_ast_templates():
|
||||
check('type', 'template<C T = int&> {key}A', {2: 'I_1CE1A'}, key='using')
|
||||
|
||||
|
||||
def test_domain_cpp_ast_placeholder_types():
|
||||
check('function', 'void f(Sortable auto &v)', {1: 'f__SortableR', 2: '1fR8Sortable'})
|
||||
check('function', 'void f(const Sortable auto &v)', {1: 'f__SortableCR', 2: '1fRK8Sortable'})
|
||||
check('function', 'void f(Sortable decltype(auto) &v)', {1: 'f__SortableR', 2: '1fR8Sortable'})
|
||||
check('function', 'void f(const Sortable decltype(auto) &v)', {1: 'f__SortableCR', 2: '1fRK8Sortable'})
|
||||
check('function', 'void f(Sortable decltype ( auto ) &v)', {1: 'f__SortableR', 2: '1fR8Sortable'},
|
||||
output='void f(Sortable decltype(auto) &v)')
|
||||
|
||||
|
||||
def test_domain_cpp_ast_requires_clauses():
|
||||
check('function', 'template<typename T> requires A auto f() -> void requires B',
|
||||
{4: 'I0EIQaa1A1BE1fvv'})
|
||||
|
Loading…
Reference in New Issue
Block a user