Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/sphinx/domains/cpp/_ast.py: 1%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

3083 statements  

1from __future__ import annotations 

2 

3import sys 

4import warnings 

5from typing import TYPE_CHECKING, Any, ClassVar, Literal 

6 

7from docutils import nodes 

8 

9from sphinx import addnodes 

10from sphinx.domains.cpp._ids import ( 

11 _id_char_from_prefix, 

12 _id_explicit_cast, 

13 _id_fundamental_v1, 

14 _id_fundamental_v2, 

15 _id_operator_unary_v2, 

16 _id_operator_v1, 

17 _id_operator_v2, 

18 _id_prefix, 

19 _id_shorthands_v1, 

20 _max_id, 

21) 

22from sphinx.util.cfamily import ( 

23 ASTAttributeList, 

24 ASTBaseBase, 

25 ASTBaseParenExprList, 

26 NoOldIdError, 

27 StringifyTransform, 

28 UnsupportedMultiCharacterCharLiteral, 

29 verify_description_mode, 

30) 

31 

32if TYPE_CHECKING: 

33 

34 from docutils.nodes import Element, TextElement 

35 

36 from sphinx.addnodes import desc_signature 

37 from sphinx.domains.cpp._symbol import Symbol 

38 from sphinx.environment import BuildEnvironment 

39 

40 

41class ASTBase(ASTBaseBase): 

42 pass 

43 

44 

45# Names 

46################################################################################ 

47 

48class ASTIdentifier(ASTBase): 

49 def __init__(self, name: str) -> None: 

50 if not isinstance(name, str) or len(name) == 0: 

51 raise AssertionError 

52 self.name = sys.intern(name) 

53 self.is_anonymous = name[0] == '@' 

54 

55 # ASTBaseBase already implements this method, 

56 # but specialising it here improves performance 

57 def __eq__(self, other: object) -> bool: 

58 if not isinstance(other, ASTIdentifier): 

59 return NotImplemented 

60 return self.name == other.name 

61 

62 def __hash__(self) -> int: 

63 return hash(self.name) 

64 

65 def _stringify(self, transform: StringifyTransform) -> str: 

66 return transform(self.name) 

67 

68 def is_anon(self) -> bool: 

69 return self.is_anonymous 

70 

71 def get_id(self, version: int) -> str: 

72 if self.is_anonymous and version < 3: 

73 raise NoOldIdError 

74 if version == 1: 

75 if self.name == 'size_t': 

76 return 's' 

77 else: 

78 return self.name 

79 if self.name == "std": 

80 return 'St' 

81 elif self.name[0] == "~": 

82 # a destructor, just use an arbitrary version of dtors 

83 return 'D0' 

84 else: 

85 if self.is_anonymous: 

86 return 'Ut%d_%s' % (len(self.name) - 1, self.name[1:]) 

87 else: 

88 return str(len(self.name)) + self.name 

89 

90 # and this is where we finally make a difference between __str__ and the display string 

91 

92 def __str__(self) -> str: 

93 return self.name 

94 

95 def get_display_string(self) -> str: 

96 return "[anonymous]" if self.is_anonymous else self.name 

97 

98 def describe_signature(self, signode: TextElement, mode: str, env: BuildEnvironment, 

99 prefix: str, templateArgs: str, symbol: Symbol) -> None: 

100 verify_description_mode(mode) 

101 if self.is_anonymous: 

102 node = addnodes.desc_sig_name(text="[anonymous]") 

103 else: 

104 node = addnodes.desc_sig_name(self.name, self.name) 

105 if mode == 'markType': 

106 targetText = prefix + self.name + templateArgs 

107 pnode = addnodes.pending_xref('', refdomain='cpp', 

108 reftype='identifier', 

109 reftarget=targetText, modname=None, 

110 classname=None) 

111 pnode['cpp:parent_key'] = symbol.get_lookup_key() 

112 pnode += node 

113 signode += pnode 

114 elif mode == 'lastIsName': 

115 nameNode = addnodes.desc_name() 

116 nameNode += node 

117 signode += nameNode 

118 elif mode == 'noneIsName': 

119 signode += node 

120 elif mode == 'param': 

121 node['classes'].append('sig-param') 

122 signode += node 

123 elif mode == 'udl': 

124 # the target is 'operator""id' instead of just 'id' 

125 assert len(prefix) == 0 

126 assert len(templateArgs) == 0 

127 assert not self.is_anonymous 

128 targetText = 'operator""' + self.name 

129 pnode = addnodes.pending_xref('', refdomain='cpp', 

130 reftype='identifier', 

131 reftarget=targetText, modname=None, 

132 classname=None) 

133 pnode['cpp:parent_key'] = symbol.get_lookup_key() 

134 pnode += node 

135 signode += pnode 

136 else: 

137 raise Exception('Unknown description mode: %s' % mode) 

138 

139 @property 

140 def identifier(self) -> str: 

141 warnings.warn( 

142 '`ASTIdentifier.identifier` is deprecated, use `ASTIdentifier.name` instead', 

143 DeprecationWarning, stacklevel=2, 

144 ) 

145 return self.name 

146 

147 

148class ASTNestedNameElement(ASTBase): 

149 def __init__(self, identOrOp: ASTIdentifier | ASTOperator, 

150 templateArgs: ASTTemplateArgs | None) -> None: 

151 self.identOrOp = identOrOp 

152 self.templateArgs = templateArgs 

153 

154 def __eq__(self, other: object) -> bool: 

155 if not isinstance(other, ASTNestedNameElement): 

156 return NotImplemented 

157 return self.identOrOp == other.identOrOp and self.templateArgs == other.templateArgs 

158 

159 def __hash__(self) -> int: 

160 return hash((self.identOrOp, self.templateArgs)) 

161 

162 def is_operator(self) -> bool: 

163 return False 

164 

165 def get_id(self, version: int) -> str: 

166 res = self.identOrOp.get_id(version) 

167 if self.templateArgs: 

168 res += self.templateArgs.get_id(version) 

169 return res 

170 

171 def _stringify(self, transform: StringifyTransform) -> str: 

172 res = transform(self.identOrOp) 

173 if self.templateArgs: 

174 res += transform(self.templateArgs) 

175 return res 

176 

177 def describe_signature(self, signode: TextElement, mode: str, 

178 env: BuildEnvironment, prefix: str, symbol: Symbol) -> None: 

179 tArgs = str(self.templateArgs) if self.templateArgs is not None else '' 

180 self.identOrOp.describe_signature(signode, mode, env, prefix, tArgs, symbol) 

181 if self.templateArgs is not None: 

182 self.templateArgs.describe_signature(signode, 'markType', env, symbol) 

183 

184 

185class ASTNestedName(ASTBase): 

186 def __init__(self, names: list[ASTNestedNameElement], 

187 templates: list[bool], rooted: bool) -> None: 

188 assert len(names) > 0 

189 self.names = names 

190 self.templates = templates 

191 assert len(self.names) == len(self.templates) 

192 self.rooted = rooted 

193 

194 def __eq__(self, other: object) -> bool: 

195 if not isinstance(other, ASTNestedName): 

196 return NotImplemented 

197 return ( 

198 self.names == other.names 

199 and self.templates == other.templates 

200 and self.rooted == other.rooted 

201 ) 

202 

203 def __hash__(self) -> int: 

204 return hash((self.names, self.templates, self.rooted)) 

205 

206 @property 

207 def name(self) -> ASTNestedName: 

208 return self 

209 

210 def num_templates(self) -> int: 

211 count = 0 

212 for n in self.names: 

213 if n.is_operator(): 

214 continue 

215 if n.templateArgs: 

216 count += 1 

217 return count 

218 

219 def get_id(self, version: int, modifiers: str = '') -> str: 

220 if version == 1: 

221 tt = str(self) 

222 if tt in _id_shorthands_v1: 

223 return _id_shorthands_v1[tt] 

224 else: 

225 return '::'.join(n.get_id(version) for n in self.names) 

226 

227 res = [] 

228 if len(self.names) > 1 or len(modifiers) > 0: 

229 res.append('N') 

230 res.append(modifiers) 

231 res.extend(n.get_id(version) for n in self.names) 

232 if len(self.names) > 1 or len(modifiers) > 0: 

233 res.append('E') 

234 return ''.join(res) 

235 

236 def _stringify(self, transform: StringifyTransform) -> str: 

237 res = [] 

238 if self.rooted: 

239 res.append('') 

240 for i in range(len(self.names)): 

241 n = self.names[i] 

242 if self.templates[i]: 

243 res.append("template " + transform(n)) 

244 else: 

245 res.append(transform(n)) 

246 return '::'.join(res) 

247 

248 def describe_signature(self, signode: TextElement, mode: str, 

249 env: BuildEnvironment, symbol: Symbol) -> None: 

250 verify_description_mode(mode) 

251 # just print the name part, with template args, not template params 

252 if mode == 'noneIsName': 

253 if self.rooted: 

254 unreachable = "Can this happen?" 

255 raise AssertionError(unreachable) # TODO 

256 signode += nodes.Text('::') 

257 for i in range(len(self.names)): 

258 if i != 0: 

259 unreachable = "Can this happen?" 

260 raise AssertionError(unreachable) # TODO 

261 signode += nodes.Text('::blah') 

262 n = self.names[i] 

263 if self.templates[i]: 

264 unreachable = "Can this happen?" 

265 raise AssertionError(unreachable) # TODO 

266 signode += nodes.Text("template") 

267 signode += nodes.Text(" ") 

268 n.describe_signature(signode, mode, env, '', symbol) 

269 elif mode == 'param': 

270 assert not self.rooted, str(self) 

271 assert len(self.names) == 1 

272 assert not self.templates[0] 

273 self.names[0].describe_signature(signode, 'param', env, '', symbol) 

274 elif mode in ('markType', 'lastIsName', 'markName'): 

275 # Each element should be a pending xref targeting the complete 

276 # prefix. however, only the identifier part should be a link, such 

277 # that template args can be a link as well. 

278 # For 'lastIsName' we should also prepend template parameter lists. 

279 templateParams: list[Any] = [] 

280 if mode == 'lastIsName': 

281 assert symbol is not None 

282 if symbol.declaration.templatePrefix is not None: 

283 templateParams = symbol.declaration.templatePrefix.templates 

284 iTemplateParams = 0 

285 templateParamsPrefix = '' 

286 prefix = '' 

287 first = True 

288 names = self.names[:-1] if mode == 'lastIsName' else self.names 

289 # If lastIsName, then wrap all of the prefix in a desc_addname, 

290 # else append directly to signode. 

291 # NOTE: Breathe previously relied on the prefix being in the desc_addname node, 

292 # so it can remove it in inner declarations. 

293 dest = signode 

294 if mode == 'lastIsName': 

295 dest = addnodes.desc_addname() 

296 if self.rooted: 

297 prefix += '::' 

298 if mode == 'lastIsName' and len(names) == 0: 

299 signode += addnodes.desc_sig_punctuation('::', '::') 

300 else: 

301 dest += addnodes.desc_sig_punctuation('::', '::') 

302 for i in range(len(names)): 

303 nne = names[i] 

304 template = self.templates[i] 

305 if not first: 

306 dest += addnodes.desc_sig_punctuation('::', '::') 

307 prefix += '::' 

308 if template: 

309 dest += addnodes.desc_sig_keyword('template', 'template') 

310 dest += addnodes.desc_sig_space() 

311 first = False 

312 txt_nne = str(nne) 

313 if txt_nne != '': 

314 if nne.templateArgs and iTemplateParams < len(templateParams): 

315 templateParamsPrefix += str(templateParams[iTemplateParams]) 

316 iTemplateParams += 1 

317 nne.describe_signature(dest, 'markType', 

318 env, templateParamsPrefix + prefix, symbol) 

319 prefix += txt_nne 

320 if mode == 'lastIsName': 

321 if len(self.names) > 1: 

322 dest += addnodes.desc_sig_punctuation('::', '::') 

323 signode += dest 

324 if self.templates[-1]: 

325 signode += addnodes.desc_sig_keyword('template', 'template') 

326 signode += addnodes.desc_sig_space() 

327 self.names[-1].describe_signature(signode, mode, env, '', symbol) 

328 else: 

329 raise Exception('Unknown description mode: %s' % mode) 

330 

331 

332################################################################################ 

333# Expressions 

334################################################################################ 

335 

336class ASTExpression(ASTBase): 

337 def get_id(self, version: int) -> str: 

338 raise NotImplementedError(repr(self)) 

339 

340 def describe_signature(self, signode: TextElement, mode: str, 

341 env: BuildEnvironment, symbol: Symbol) -> None: 

342 raise NotImplementedError(repr(self)) 

343 

344 

345# Primary expressions 

346################################################################################ 

347 

348class ASTLiteral(ASTExpression): 

349 pass 

350 

351 

352class ASTPointerLiteral(ASTLiteral): 

353 def __eq__(self, other: object) -> bool: 

354 return isinstance(other, ASTPointerLiteral) 

355 

356 def __hash__(self) -> int: 

357 return hash('nullptr') 

358 

359 def _stringify(self, transform: StringifyTransform) -> str: 

360 return 'nullptr' 

361 

362 def get_id(self, version: int) -> str: 

363 return 'LDnE' 

364 

365 def describe_signature(self, signode: TextElement, mode: str, 

366 env: BuildEnvironment, symbol: Symbol) -> None: 

367 signode += addnodes.desc_sig_keyword('nullptr', 'nullptr') 

368 

369 

370class ASTBooleanLiteral(ASTLiteral): 

371 def __init__(self, value: bool) -> None: 

372 self.value = value 

373 

374 def __eq__(self, other: object) -> bool: 

375 if not isinstance(other, ASTBooleanLiteral): 

376 return NotImplemented 

377 return self.value == other.value 

378 

379 def __hash__(self) -> int: 

380 return hash(self.value) 

381 

382 def _stringify(self, transform: StringifyTransform) -> str: 

383 if self.value: 

384 return 'true' 

385 else: 

386 return 'false' 

387 

388 def get_id(self, version: int) -> str: 

389 if self.value: 

390 return 'L1E' 

391 else: 

392 return 'L0E' 

393 

394 def describe_signature(self, signode: TextElement, mode: str, 

395 env: BuildEnvironment, symbol: Symbol) -> None: 

396 signode += addnodes.desc_sig_keyword(str(self), str(self)) 

397 

398 

399class ASTNumberLiteral(ASTLiteral): 

400 def __init__(self, data: str) -> None: 

401 self.data = data 

402 

403 def __eq__(self, other: object) -> bool: 

404 if not isinstance(other, ASTNumberLiteral): 

405 return NotImplemented 

406 return self.data == other.data 

407 

408 def __hash__(self) -> int: 

409 return hash(self.data) 

410 

411 def _stringify(self, transform: StringifyTransform) -> str: 

412 return self.data 

413 

414 def get_id(self, version: int) -> str: 

415 # TODO: floats should be mangled by writing the hex of the binary representation 

416 return "L%sE" % self.data.replace("'", "") 

417 

418 def describe_signature(self, signode: TextElement, mode: str, 

419 env: BuildEnvironment, symbol: Symbol) -> None: 

420 signode += addnodes.desc_sig_literal_number(self.data, self.data) 

421 

422 

423class ASTStringLiteral(ASTLiteral): 

424 def __init__(self, data: str) -> None: 

425 self.data = data 

426 

427 def __eq__(self, other: object) -> bool: 

428 if not isinstance(other, ASTStringLiteral): 

429 return NotImplemented 

430 return self.data == other.data 

431 

432 def __hash__(self) -> int: 

433 return hash(self.data) 

434 

435 def _stringify(self, transform: StringifyTransform) -> str: 

436 return self.data 

437 

438 def get_id(self, version: int) -> str: 

439 # note: the length is not really correct with escaping 

440 return "LA%d_KcE" % (len(self.data) - 2) 

441 

442 def describe_signature(self, signode: TextElement, mode: str, 

443 env: BuildEnvironment, symbol: Symbol) -> None: 

444 signode += addnodes.desc_sig_literal_string(self.data, self.data) 

445 

446 

447class ASTCharLiteral(ASTLiteral): 

448 def __init__(self, prefix: str, data: str) -> None: 

449 self.prefix = prefix # may be None when no prefix 

450 self.data = data 

451 assert prefix in _id_char_from_prefix 

452 self.type = _id_char_from_prefix[prefix] 

453 decoded = data.encode().decode('unicode-escape') 

454 if len(decoded) == 1: 

455 self.value = ord(decoded) 

456 else: 

457 raise UnsupportedMultiCharacterCharLiteral(decoded) 

458 

459 def __eq__(self, other: object) -> bool: 

460 if not isinstance(other, ASTCharLiteral): 

461 return NotImplemented 

462 return ( 

463 self.prefix == other.prefix 

464 and self.value == other.value 

465 ) 

466 

467 def __hash__(self) -> int: 

468 return hash((self.prefix, self.value)) 

469 

470 def _stringify(self, transform: StringifyTransform) -> str: 

471 if self.prefix is None: 

472 return "'" + self.data + "'" 

473 else: 

474 return self.prefix + "'" + self.data + "'" 

475 

476 def get_id(self, version: int) -> str: 

477 # TODO: the ID should be have L E around it 

478 return self.type + str(self.value) 

479 

480 def describe_signature(self, signode: TextElement, mode: str, 

481 env: BuildEnvironment, symbol: Symbol) -> None: 

482 if self.prefix is not None: 

483 signode += addnodes.desc_sig_keyword(self.prefix, self.prefix) 

484 txt = "'" + self.data + "'" 

485 signode += addnodes.desc_sig_literal_char(txt, txt) 

486 

487 

488class ASTUserDefinedLiteral(ASTLiteral): 

489 def __init__(self, literal: ASTLiteral, ident: ASTIdentifier) -> None: 

490 self.literal = literal 

491 self.ident = ident 

492 

493 def __eq__(self, other: object) -> bool: 

494 if not isinstance(other, ASTUserDefinedLiteral): 

495 return NotImplemented 

496 return self.literal == other.literal and self.ident == other.ident 

497 

498 def __hash__(self) -> int: 

499 return hash((self.literal, self.ident)) 

500 

501 def _stringify(self, transform: StringifyTransform) -> str: 

502 return transform(self.literal) + transform(self.ident) 

503 

504 def get_id(self, version: int) -> str: 

505 # mangle as if it was a function call: ident(literal) 

506 return f'clL_Zli{self.ident.get_id(version)}E{self.literal.get_id(version)}E' 

507 

508 def describe_signature(self, signode: TextElement, mode: str, 

509 env: BuildEnvironment, symbol: Symbol) -> None: 

510 self.literal.describe_signature(signode, mode, env, symbol) 

511 self.ident.describe_signature(signode, "udl", env, "", "", symbol) 

512 

513 

514################################################################################ 

515 

516class ASTThisLiteral(ASTExpression): 

517 def __eq__(self, other: object) -> bool: 

518 return isinstance(other, ASTThisLiteral) 

519 

520 def __hash__(self) -> int: 

521 return hash("this") 

522 

523 def _stringify(self, transform: StringifyTransform) -> str: 

524 return "this" 

525 

526 def get_id(self, version: int) -> str: 

527 return "fpT" 

528 

529 def describe_signature(self, signode: TextElement, mode: str, 

530 env: BuildEnvironment, symbol: Symbol) -> None: 

531 signode += addnodes.desc_sig_keyword('this', 'this') 

532 

533 

534class ASTFoldExpr(ASTExpression): 

535 def __init__(self, leftExpr: ASTExpression | None, 

536 op: str, rightExpr: ASTExpression | None) -> None: 

537 assert leftExpr is not None or rightExpr is not None 

538 self.leftExpr = leftExpr 

539 self.op = op 

540 self.rightExpr = rightExpr 

541 

542 def __eq__(self, other: object) -> bool: 

543 if not isinstance(other, ASTFoldExpr): 

544 return NotImplemented 

545 return ( 

546 self.leftExpr == other.leftExpr 

547 and self.op == other.op 

548 and self.rightExpr == other.rightExpr 

549 ) 

550 

551 def __hash__(self) -> int: 

552 return hash((self.leftExpr, self.op, self.rightExpr)) 

553 

554 def _stringify(self, transform: StringifyTransform) -> str: 

555 res = ['('] 

556 if self.leftExpr: 

557 res.append(transform(self.leftExpr)) 

558 res.append(' ') 

559 res.append(self.op) 

560 res.append(' ') 

561 res.append('...') 

562 if self.rightExpr: 

563 res.append(' ') 

564 res.append(self.op) 

565 res.append(' ') 

566 res.append(transform(self.rightExpr)) 

567 res.append(')') 

568 return ''.join(res) 

569 

570 def get_id(self, version: int) -> str: 

571 assert version >= 3 

572 if version == 3: 

573 return str(self) 

574 # https://github.com/itanium-cxx-abi/cxx-abi/pull/67 

575 res = [] 

576 if self.leftExpr is None: # (... op expr) 

577 res.append('fl') 

578 elif self.rightExpr is None: # (expr op ...) 

579 res.append('fr') 

580 else: # (expr op ... op expr) 

581 # we don't check where the parameter pack is, 

582 # we just always call this a binary left fold 

583 res.append('fL') 

584 res.append(_id_operator_v2[self.op]) 

585 if self.leftExpr: 

586 res.append(self.leftExpr.get_id(version)) 

587 if self.rightExpr: 

588 res.append(self.rightExpr.get_id(version)) 

589 return ''.join(res) 

590 

591 def describe_signature(self, signode: TextElement, mode: str, 

592 env: BuildEnvironment, symbol: Symbol) -> None: 

593 signode += addnodes.desc_sig_punctuation('(', '(') 

594 if self.leftExpr: 

595 self.leftExpr.describe_signature(signode, mode, env, symbol) 

596 signode += addnodes.desc_sig_space() 

597 signode += addnodes.desc_sig_operator(self.op, self.op) 

598 signode += addnodes.desc_sig_space() 

599 signode += addnodes.desc_sig_punctuation('...', '...') 

600 if self.rightExpr: 

601 signode += addnodes.desc_sig_space() 

602 signode += addnodes.desc_sig_operator(self.op, self.op) 

603 signode += addnodes.desc_sig_space() 

604 self.rightExpr.describe_signature(signode, mode, env, symbol) 

605 signode += addnodes.desc_sig_punctuation(')', ')') 

606 

607 

608class ASTParenExpr(ASTExpression): 

609 def __init__(self, expr: ASTExpression) -> None: 

610 self.expr = expr 

611 

612 def __eq__(self, other: object) -> bool: 

613 if not isinstance(other, ASTParenExpr): 

614 return NotImplemented 

615 return self.expr == other.expr 

616 

617 def __hash__(self) -> int: 

618 return hash(self.expr) 

619 

620 def _stringify(self, transform: StringifyTransform) -> str: 

621 return '(' + transform(self.expr) + ')' 

622 

623 def get_id(self, version: int) -> str: 

624 return self.expr.get_id(version) 

625 

626 def describe_signature(self, signode: TextElement, mode: str, 

627 env: BuildEnvironment, symbol: Symbol) -> None: 

628 signode += addnodes.desc_sig_punctuation('(', '(') 

629 self.expr.describe_signature(signode, mode, env, symbol) 

630 signode += addnodes.desc_sig_punctuation(')', ')') 

631 

632 

633class ASTIdExpression(ASTExpression): 

634 def __init__(self, name: ASTNestedName) -> None: 

635 # note: this class is basically to cast a nested name as an expression 

636 self.name = name 

637 

638 def __eq__(self, other: object) -> bool: 

639 if not isinstance(other, ASTIdExpression): 

640 return NotImplemented 

641 return self.name == other.name 

642 

643 def __hash__(self) -> int: 

644 return hash(self.name) 

645 

646 def _stringify(self, transform: StringifyTransform) -> str: 

647 return transform(self.name) 

648 

649 def get_id(self, version: int) -> str: 

650 return self.name.get_id(version) 

651 

652 def describe_signature(self, signode: TextElement, mode: str, 

653 env: BuildEnvironment, symbol: Symbol) -> None: 

654 self.name.describe_signature(signode, mode, env, symbol) 

655 

656 

657# Postfix expressions 

658################################################################################ 

659 

660class ASTPostfixOp(ASTBase): 

661 def get_id(self, idPrefix: str, version: int) -> str: 

662 raise NotImplementedError(repr(self)) 

663 

664 def describe_signature(self, signode: TextElement, mode: str, 

665 env: BuildEnvironment, symbol: Symbol) -> None: 

666 raise NotImplementedError(repr(self)) 

667 

668 

669class ASTPostfixArray(ASTPostfixOp): 

670 def __init__(self, expr: ASTExpression) -> None: 

671 self.expr = expr 

672 

673 def __eq__(self, other: object) -> bool: 

674 if not isinstance(other, ASTPostfixArray): 

675 return NotImplemented 

676 return self.expr == other.expr 

677 

678 def __hash__(self) -> int: 

679 return hash(self.expr) 

680 

681 def _stringify(self, transform: StringifyTransform) -> str: 

682 return '[' + transform(self.expr) + ']' 

683 

684 def get_id(self, idPrefix: str, version: int) -> str: 

685 return 'ix' + idPrefix + self.expr.get_id(version) 

686 

687 def describe_signature(self, signode: TextElement, mode: str, 

688 env: BuildEnvironment, symbol: Symbol) -> None: 

689 signode += addnodes.desc_sig_punctuation('[', '[') 

690 self.expr.describe_signature(signode, mode, env, symbol) 

691 signode += addnodes.desc_sig_punctuation(']', ']') 

692 

693 

694class ASTPostfixMember(ASTPostfixOp): 

695 def __init__(self, name: ASTNestedName) -> None: 

696 self.name = name 

697 

698 def __eq__(self, other: object) -> bool: 

699 if not isinstance(other, ASTPostfixMember): 

700 return NotImplemented 

701 return self.name == other.name 

702 

703 def __hash__(self) -> int: 

704 return hash(self.name) 

705 

706 def _stringify(self, transform: StringifyTransform) -> str: 

707 return '.' + transform(self.name) 

708 

709 def get_id(self, idPrefix: str, version: int) -> str: 

710 return 'dt' + idPrefix + self.name.get_id(version) 

711 

712 def describe_signature(self, signode: TextElement, mode: str, 

713 env: BuildEnvironment, symbol: Symbol) -> None: 

714 signode += addnodes.desc_sig_punctuation('.', '.') 

715 self.name.describe_signature(signode, 'noneIsName', env, symbol) 

716 

717 

718class ASTPostfixMemberOfPointer(ASTPostfixOp): 

719 def __init__(self, name: ASTNestedName) -> None: 

720 self.name = name 

721 

722 def __eq__(self, other: object) -> bool: 

723 if not isinstance(other, ASTPostfixMemberOfPointer): 

724 return NotImplemented 

725 return self.name == other.name 

726 

727 def __hash__(self) -> int: 

728 return hash(self.name) 

729 

730 def _stringify(self, transform: StringifyTransform) -> str: 

731 return '->' + transform(self.name) 

732 

733 def get_id(self, idPrefix: str, version: int) -> str: 

734 return 'pt' + idPrefix + self.name.get_id(version) 

735 

736 def describe_signature(self, signode: TextElement, mode: str, 

737 env: BuildEnvironment, symbol: Symbol) -> None: 

738 signode += addnodes.desc_sig_operator('->', '->') 

739 self.name.describe_signature(signode, 'noneIsName', env, symbol) 

740 

741 

742class ASTPostfixInc(ASTPostfixOp): 

743 def __eq__(self, other: object) -> bool: 

744 return isinstance(other, ASTPostfixInc) 

745 

746 def __hash__(self) -> int: 

747 return hash('++') 

748 

749 def _stringify(self, transform: StringifyTransform) -> str: 

750 return '++' 

751 

752 def get_id(self, idPrefix: str, version: int) -> str: 

753 return 'pp' + idPrefix 

754 

755 def describe_signature(self, signode: TextElement, mode: str, 

756 env: BuildEnvironment, symbol: Symbol) -> None: 

757 signode += addnodes.desc_sig_operator('++', '++') 

758 

759 

760class ASTPostfixDec(ASTPostfixOp): 

761 def __eq__(self, other: object) -> bool: 

762 return isinstance(other, ASTPostfixDec) 

763 

764 def __hash__(self) -> int: 

765 return hash('--') 

766 

767 def _stringify(self, transform: StringifyTransform) -> str: 

768 return '--' 

769 

770 def get_id(self, idPrefix: str, version: int) -> str: 

771 return 'mm' + idPrefix 

772 

773 def describe_signature(self, signode: TextElement, mode: str, 

774 env: BuildEnvironment, symbol: Symbol) -> None: 

775 signode += addnodes.desc_sig_operator('--', '--') 

776 

777 

778class ASTPostfixCallExpr(ASTPostfixOp): 

779 def __init__(self, lst: ASTParenExprList | ASTBracedInitList) -> None: 

780 self.lst = lst 

781 

782 def __eq__(self, other: object) -> bool: 

783 if not isinstance(other, ASTPostfixCallExpr): 

784 return NotImplemented 

785 return self.lst == other.lst 

786 

787 def __hash__(self) -> int: 

788 return hash(self.lst) 

789 

790 def _stringify(self, transform: StringifyTransform) -> str: 

791 return transform(self.lst) 

792 

793 def get_id(self, idPrefix: str, version: int) -> str: 

794 return ''.join([ 

795 'cl', 

796 idPrefix, 

797 *(e.get_id(version) for e in self.lst.exprs), 

798 'E', 

799 ]) 

800 

801 def describe_signature(self, signode: TextElement, mode: str, 

802 env: BuildEnvironment, symbol: Symbol) -> None: 

803 self.lst.describe_signature(signode, mode, env, symbol) 

804 

805 

806class ASTPostfixExpr(ASTExpression): 

807 def __init__(self, prefix: ASTType, postFixes: list[ASTPostfixOp]) -> None: 

808 self.prefix = prefix 

809 self.postFixes = postFixes 

810 

811 def __eq__(self, other: object) -> bool: 

812 if not isinstance(other, ASTPostfixExpr): 

813 return NotImplemented 

814 return self.prefix == other.prefix and self.postFixes == other.postFixes 

815 

816 def __hash__(self) -> int: 

817 return hash((self.prefix, self.postFixes)) 

818 

819 def _stringify(self, transform: StringifyTransform) -> str: 

820 return ''.join([transform(self.prefix), *(transform(p) for p in self.postFixes)]) 

821 

822 def get_id(self, version: int) -> str: 

823 id = self.prefix.get_id(version) 

824 for p in self.postFixes: 

825 id = p.get_id(id, version) 

826 return id 

827 

828 def describe_signature(self, signode: TextElement, mode: str, 

829 env: BuildEnvironment, symbol: Symbol) -> None: 

830 self.prefix.describe_signature(signode, mode, env, symbol) 

831 for p in self.postFixes: 

832 p.describe_signature(signode, mode, env, symbol) 

833 

834 

835class ASTExplicitCast(ASTExpression): 

836 def __init__(self, cast: str, typ: ASTType, expr: ASTExpression) -> None: 

837 assert cast in _id_explicit_cast 

838 self.cast = cast 

839 self.typ = typ 

840 self.expr = expr 

841 

842 def __eq__(self, other: object) -> bool: 

843 if not isinstance(other, ASTExplicitCast): 

844 return NotImplemented 

845 return self.cast == other.cast and self.typ == other.typ and self.expr == other.expr 

846 

847 def __hash__(self) -> int: 

848 return hash((self.cast, self.typ, self.expr)) 

849 

850 def _stringify(self, transform: StringifyTransform) -> str: 

851 res = [self.cast] 

852 res.append('<') 

853 res.append(transform(self.typ)) 

854 res.append('>(') 

855 res.append(transform(self.expr)) 

856 res.append(')') 

857 return ''.join(res) 

858 

859 def get_id(self, version: int) -> str: 

860 return (_id_explicit_cast[self.cast] + 

861 self.typ.get_id(version) + 

862 self.expr.get_id(version)) 

863 

864 def describe_signature(self, signode: TextElement, mode: str, 

865 env: BuildEnvironment, symbol: Symbol) -> None: 

866 signode += addnodes.desc_sig_keyword(self.cast, self.cast) 

867 signode += addnodes.desc_sig_punctuation('<', '<') 

868 self.typ.describe_signature(signode, mode, env, symbol) 

869 signode += addnodes.desc_sig_punctuation('>', '>') 

870 signode += addnodes.desc_sig_punctuation('(', '(') 

871 self.expr.describe_signature(signode, mode, env, symbol) 

872 signode += addnodes.desc_sig_punctuation(')', ')') 

873 

874 

875class ASTTypeId(ASTExpression): 

876 def __init__(self, typeOrExpr: ASTType | ASTExpression, isType: bool) -> None: 

877 self.typeOrExpr = typeOrExpr 

878 self.isType = isType 

879 

880 def __eq__(self, other: object) -> bool: 

881 if not isinstance(other, ASTTypeId): 

882 return NotImplemented 

883 return self.typeOrExpr == other.typeOrExpr and self.isType == other.isType 

884 

885 def __hash__(self) -> int: 

886 return hash((self.typeOrExpr, self.isType)) 

887 

888 def _stringify(self, transform: StringifyTransform) -> str: 

889 return 'typeid(' + transform(self.typeOrExpr) + ')' 

890 

891 def get_id(self, version: int) -> str: 

892 prefix = 'ti' if self.isType else 'te' 

893 return prefix + self.typeOrExpr.get_id(version) 

894 

895 def describe_signature(self, signode: TextElement, mode: str, 

896 env: BuildEnvironment, symbol: Symbol) -> None: 

897 signode += addnodes.desc_sig_keyword('typeid', 'typeid') 

898 signode += addnodes.desc_sig_punctuation('(', '(') 

899 self.typeOrExpr.describe_signature(signode, mode, env, symbol) 

900 signode += addnodes.desc_sig_punctuation(')', ')') 

901 

902 

903# Unary expressions 

904################################################################################ 

905 

906class ASTUnaryOpExpr(ASTExpression): 

907 def __init__(self, op: str, expr: ASTExpression) -> None: 

908 self.op = op 

909 self.expr = expr 

910 

911 def __eq__(self, other: object) -> bool: 

912 if not isinstance(other, ASTUnaryOpExpr): 

913 return NotImplemented 

914 return self.op == other.op and self.expr == other.expr 

915 

916 def __hash__(self) -> int: 

917 return hash((self.op, self.expr)) 

918 

919 def _stringify(self, transform: StringifyTransform) -> str: 

920 if self.op[0] in 'cn': 

921 return self.op + " " + transform(self.expr) 

922 else: 

923 return self.op + transform(self.expr) 

924 

925 def get_id(self, version: int) -> str: 

926 return _id_operator_unary_v2[self.op] + self.expr.get_id(version) 

927 

928 def describe_signature(self, signode: TextElement, mode: str, 

929 env: BuildEnvironment, symbol: Symbol) -> None: 

930 if self.op[0] in 'cn': 

931 signode += addnodes.desc_sig_keyword(self.op, self.op) 

932 signode += addnodes.desc_sig_space() 

933 else: 

934 signode += addnodes.desc_sig_operator(self.op, self.op) 

935 self.expr.describe_signature(signode, mode, env, symbol) 

936 

937 

938class ASTSizeofParamPack(ASTExpression): 

939 def __init__(self, identifier: ASTIdentifier) -> None: 

940 self.identifier = identifier 

941 

942 def __eq__(self, other: object) -> bool: 

943 if not isinstance(other, ASTSizeofParamPack): 

944 return NotImplemented 

945 return self.identifier == other.identifier 

946 

947 def __hash__(self) -> int: 

948 return hash(self.identifier) 

949 

950 def _stringify(self, transform: StringifyTransform) -> str: 

951 return "sizeof...(" + transform(self.identifier) + ")" 

952 

953 def get_id(self, version: int) -> str: 

954 return 'sZ' + self.identifier.get_id(version) 

955 

956 def describe_signature(self, signode: TextElement, mode: str, 

957 env: BuildEnvironment, symbol: Symbol) -> None: 

958 signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') 

959 signode += addnodes.desc_sig_punctuation('...', '...') 

960 signode += addnodes.desc_sig_punctuation('(', '(') 

961 self.identifier.describe_signature(signode, 'markType', env, 

962 symbol=symbol, prefix="", templateArgs="") 

963 signode += addnodes.desc_sig_punctuation(')', ')') 

964 

965 

966class ASTSizeofType(ASTExpression): 

967 def __init__(self, typ: ASTType) -> None: 

968 self.typ = typ 

969 

970 def __eq__(self, other: object) -> bool: 

971 if not isinstance(other, ASTSizeofType): 

972 return NotImplemented 

973 return self.typ == other.typ 

974 

975 def __hash__(self) -> int: 

976 return hash(self.typ) 

977 

978 def _stringify(self, transform: StringifyTransform) -> str: 

979 return "sizeof(" + transform(self.typ) + ")" 

980 

981 def get_id(self, version: int) -> str: 

982 return 'st' + self.typ.get_id(version) 

983 

984 def describe_signature(self, signode: TextElement, mode: str, 

985 env: BuildEnvironment, symbol: Symbol) -> None: 

986 signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') 

987 signode += addnodes.desc_sig_punctuation('(', '(') 

988 self.typ.describe_signature(signode, mode, env, symbol) 

989 signode += addnodes.desc_sig_punctuation(')', ')') 

990 

991 

992class ASTSizeofExpr(ASTExpression): 

993 def __init__(self, expr: ASTExpression) -> None: 

994 self.expr = expr 

995 

996 def __eq__(self, other: object) -> bool: 

997 if not isinstance(other, ASTSizeofExpr): 

998 return NotImplemented 

999 return self.expr == other.expr 

1000 

1001 def __hash__(self) -> int: 

1002 return hash(self.expr) 

1003 

1004 def _stringify(self, transform: StringifyTransform) -> str: 

1005 return "sizeof " + transform(self.expr) 

1006 

1007 def get_id(self, version: int) -> str: 

1008 return 'sz' + self.expr.get_id(version) 

1009 

1010 def describe_signature(self, signode: TextElement, mode: str, 

1011 env: BuildEnvironment, symbol: Symbol) -> None: 

1012 signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') 

1013 signode += addnodes.desc_sig_space() 

1014 self.expr.describe_signature(signode, mode, env, symbol) 

1015 

1016 

1017class ASTAlignofExpr(ASTExpression): 

1018 def __init__(self, typ: ASTType) -> None: 

1019 self.typ = typ 

1020 

1021 def __eq__(self, other: object) -> bool: 

1022 if not isinstance(other, ASTAlignofExpr): 

1023 return NotImplemented 

1024 return self.typ == other.typ 

1025 

1026 def __hash__(self) -> int: 

1027 return hash(self.typ) 

1028 

1029 def _stringify(self, transform: StringifyTransform) -> str: 

1030 return "alignof(" + transform(self.typ) + ")" 

1031 

1032 def get_id(self, version: int) -> str: 

1033 return 'at' + self.typ.get_id(version) 

1034 

1035 def describe_signature(self, signode: TextElement, mode: str, 

1036 env: BuildEnvironment, symbol: Symbol) -> None: 

1037 signode += addnodes.desc_sig_keyword('alignof', 'alignof') 

1038 signode += addnodes.desc_sig_punctuation('(', '(') 

1039 self.typ.describe_signature(signode, mode, env, symbol) 

1040 signode += addnodes.desc_sig_punctuation(')', ')') 

1041 

1042 

1043class ASTNoexceptExpr(ASTExpression): 

1044 def __init__(self, expr: ASTExpression) -> None: 

1045 self.expr = expr 

1046 

1047 def __eq__(self, other: object) -> bool: 

1048 if not isinstance(other, ASTNoexceptExpr): 

1049 return NotImplemented 

1050 return self.expr == other.expr 

1051 

1052 def __hash__(self) -> int: 

1053 return hash(self.expr) 

1054 

1055 def _stringify(self, transform: StringifyTransform) -> str: 

1056 return 'noexcept(' + transform(self.expr) + ')' 

1057 

1058 def get_id(self, version: int) -> str: 

1059 return 'nx' + self.expr.get_id(version) 

1060 

1061 def describe_signature(self, signode: TextElement, mode: str, 

1062 env: BuildEnvironment, symbol: Symbol) -> None: 

1063 signode += addnodes.desc_sig_keyword('noexcept', 'noexcept') 

1064 signode += addnodes.desc_sig_punctuation('(', '(') 

1065 self.expr.describe_signature(signode, mode, env, symbol) 

1066 signode += addnodes.desc_sig_punctuation(')', ')') 

1067 

1068 

1069class ASTNewExpr(ASTExpression): 

1070 def __init__(self, rooted: bool, isNewTypeId: bool, typ: ASTType, 

1071 initList: ASTParenExprList | ASTBracedInitList) -> None: 

1072 self.rooted = rooted 

1073 self.isNewTypeId = isNewTypeId 

1074 self.typ = typ 

1075 self.initList = initList 

1076 

1077 def __eq__(self, other: object) -> bool: 

1078 if not isinstance(other, ASTNewExpr): 

1079 return NotImplemented 

1080 return ( 

1081 self.rooted == other.rooted 

1082 and self.isNewTypeId == other.isNewTypeId 

1083 and self.typ == other.typ 

1084 and self.initList == other.initList 

1085 ) 

1086 

1087 def __hash__(self) -> int: 

1088 return hash((self.rooted, self.isNewTypeId, self.typ, self.initList)) 

1089 

1090 def _stringify(self, transform: StringifyTransform) -> str: 

1091 res = [] 

1092 if self.rooted: 

1093 res.append('::') 

1094 res.append('new ') 

1095 # TODO: placement 

1096 if self.isNewTypeId: 

1097 res.append(transform(self.typ)) 

1098 else: 

1099 raise AssertionError 

1100 if self.initList is not None: 

1101 res.append(transform(self.initList)) 

1102 return ''.join(res) 

1103 

1104 def get_id(self, version: int) -> str: 

1105 # the array part will be in the type mangling, so na is not used 

1106 res = ['nw'] 

1107 # TODO: placement 

1108 res.append('_') 

1109 res.append(self.typ.get_id(version)) 

1110 if self.initList is not None: 

1111 res.append(self.initList.get_id(version)) 

1112 else: 

1113 res.append('E') 

1114 return ''.join(res) 

1115 

1116 def describe_signature(self, signode: TextElement, mode: str, 

1117 env: BuildEnvironment, symbol: Symbol) -> None: 

1118 if self.rooted: 

1119 signode += addnodes.desc_sig_punctuation('::', '::') 

1120 signode += addnodes.desc_sig_keyword('new', 'new') 

1121 signode += addnodes.desc_sig_space() 

1122 # TODO: placement 

1123 if self.isNewTypeId: 

1124 self.typ.describe_signature(signode, mode, env, symbol) 

1125 else: 

1126 raise AssertionError 

1127 if self.initList is not None: 

1128 self.initList.describe_signature(signode, mode, env, symbol) 

1129 

1130 

1131class ASTDeleteExpr(ASTExpression): 

1132 def __init__(self, rooted: bool, array: bool, expr: ASTExpression) -> None: 

1133 self.rooted = rooted 

1134 self.array = array 

1135 self.expr = expr 

1136 

1137 def __eq__(self, other: object) -> bool: 

1138 if not isinstance(other, ASTDeleteExpr): 

1139 return NotImplemented 

1140 return ( 

1141 self.rooted == other.rooted 

1142 and self.array == other.array 

1143 and self.expr == other.expr 

1144 ) 

1145 

1146 def __hash__(self) -> int: 

1147 return hash((self.rooted, self.array, self.expr)) 

1148 

1149 def _stringify(self, transform: StringifyTransform) -> str: 

1150 res = [] 

1151 if self.rooted: 

1152 res.append('::') 

1153 res.append('delete ') 

1154 if self.array: 

1155 res.append('[] ') 

1156 res.append(transform(self.expr)) 

1157 return ''.join(res) 

1158 

1159 def get_id(self, version: int) -> str: 

1160 if self.array: 

1161 id = "da" 

1162 else: 

1163 id = "dl" 

1164 return id + self.expr.get_id(version) 

1165 

1166 def describe_signature(self, signode: TextElement, mode: str, 

1167 env: BuildEnvironment, symbol: Symbol) -> None: 

1168 if self.rooted: 

1169 signode += addnodes.desc_sig_punctuation('::', '::') 

1170 signode += addnodes.desc_sig_keyword('delete', 'delete') 

1171 signode += addnodes.desc_sig_space() 

1172 if self.array: 

1173 signode += addnodes.desc_sig_punctuation('[]', '[]') 

1174 signode += addnodes.desc_sig_space() 

1175 self.expr.describe_signature(signode, mode, env, symbol) 

1176 

1177 

1178# Other expressions 

1179################################################################################ 

1180 

1181class ASTCastExpr(ASTExpression): 

1182 def __init__(self, typ: ASTType, expr: ASTExpression) -> None: 

1183 self.typ = typ 

1184 self.expr = expr 

1185 

1186 def __eq__(self, other: object) -> bool: 

1187 if not isinstance(other, ASTCastExpr): 

1188 return NotImplemented 

1189 return ( 

1190 self.typ == other.typ 

1191 and self.expr == other.expr 

1192 ) 

1193 

1194 def __hash__(self) -> int: 

1195 return hash((self.typ, self.expr)) 

1196 

1197 def _stringify(self, transform: StringifyTransform) -> str: 

1198 res = ['('] 

1199 res.append(transform(self.typ)) 

1200 res.append(')') 

1201 res.append(transform(self.expr)) 

1202 return ''.join(res) 

1203 

1204 def get_id(self, version: int) -> str: 

1205 return 'cv' + self.typ.get_id(version) + self.expr.get_id(version) 

1206 

1207 def describe_signature(self, signode: TextElement, mode: str, 

1208 env: BuildEnvironment, symbol: Symbol) -> None: 

1209 signode += addnodes.desc_sig_punctuation('(', '(') 

1210 self.typ.describe_signature(signode, mode, env, symbol) 

1211 signode += addnodes.desc_sig_punctuation(')', ')') 

1212 self.expr.describe_signature(signode, mode, env, symbol) 

1213 

1214 

1215class ASTBinOpExpr(ASTExpression): 

1216 def __init__(self, exprs: list[ASTExpression], ops: list[str]) -> None: 

1217 assert len(exprs) > 0 

1218 assert len(exprs) == len(ops) + 1 

1219 self.exprs = exprs 

1220 self.ops = ops 

1221 

1222 def __eq__(self, other: object) -> bool: 

1223 if not isinstance(other, ASTBinOpExpr): 

1224 return NotImplemented 

1225 return ( 

1226 self.exprs == other.exprs 

1227 and self.ops == other.ops 

1228 ) 

1229 

1230 def __hash__(self) -> int: 

1231 return hash((self.exprs, self.ops)) 

1232 

1233 def _stringify(self, transform: StringifyTransform) -> str: 

1234 res = [] 

1235 res.append(transform(self.exprs[0])) 

1236 for i in range(1, len(self.exprs)): 

1237 res.append(' ') 

1238 res.append(self.ops[i - 1]) 

1239 res.append(' ') 

1240 res.append(transform(self.exprs[i])) 

1241 return ''.join(res) 

1242 

1243 def get_id(self, version: int) -> str: 

1244 assert version >= 2 

1245 res = [] 

1246 for i in range(len(self.ops)): 

1247 res.append(_id_operator_v2[self.ops[i]]) 

1248 res.append(self.exprs[i].get_id(version)) 

1249 res.append(self.exprs[-1].get_id(version)) 

1250 return ''.join(res) 

1251 

1252 def describe_signature(self, signode: TextElement, mode: str, 

1253 env: BuildEnvironment, symbol: Symbol) -> None: 

1254 self.exprs[0].describe_signature(signode, mode, env, symbol) 

1255 for i in range(1, len(self.exprs)): 

1256 signode += addnodes.desc_sig_space() 

1257 op = self.ops[i - 1] 

1258 if ord(op[0]) >= ord('a') and ord(op[0]) <= ord('z'): 

1259 signode += addnodes.desc_sig_keyword(op, op) 

1260 else: 

1261 signode += addnodes.desc_sig_operator(op, op) 

1262 signode += addnodes.desc_sig_space() 

1263 self.exprs[i].describe_signature(signode, mode, env, symbol) 

1264 

1265 

1266class ASTConditionalExpr(ASTExpression): 

1267 def __init__(self, ifExpr: ASTExpression, thenExpr: ASTExpression, 

1268 elseExpr: ASTExpression) -> None: 

1269 self.ifExpr = ifExpr 

1270 self.thenExpr = thenExpr 

1271 self.elseExpr = elseExpr 

1272 

1273 def __eq__(self, other: object) -> bool: 

1274 if not isinstance(other, ASTConditionalExpr): 

1275 return NotImplemented 

1276 return ( 

1277 self.ifExpr == other.ifExpr 

1278 and self.thenExpr == other.thenExpr 

1279 and self.elseExpr == other.elseExpr 

1280 ) 

1281 

1282 def __hash__(self) -> int: 

1283 return hash((self.ifExpr, self.thenExpr, self.elseExpr)) 

1284 

1285 def _stringify(self, transform: StringifyTransform) -> str: 

1286 res = [] 

1287 res.append(transform(self.ifExpr)) 

1288 res.append(' ? ') 

1289 res.append(transform(self.thenExpr)) 

1290 res.append(' : ') 

1291 res.append(transform(self.elseExpr)) 

1292 return ''.join(res) 

1293 

1294 def get_id(self, version: int) -> str: 

1295 assert version >= 2 

1296 res = [] 

1297 res.append(_id_operator_v2['?']) 

1298 res.append(self.ifExpr.get_id(version)) 

1299 res.append(self.thenExpr.get_id(version)) 

1300 res.append(self.elseExpr.get_id(version)) 

1301 return ''.join(res) 

1302 

1303 def describe_signature(self, signode: TextElement, mode: str, 

1304 env: BuildEnvironment, symbol: Symbol) -> None: 

1305 self.ifExpr.describe_signature(signode, mode, env, symbol) 

1306 signode += addnodes.desc_sig_space() 

1307 signode += addnodes.desc_sig_operator('?', '?') 

1308 signode += addnodes.desc_sig_space() 

1309 self.thenExpr.describe_signature(signode, mode, env, symbol) 

1310 signode += addnodes.desc_sig_space() 

1311 signode += addnodes.desc_sig_operator(':', ':') 

1312 signode += addnodes.desc_sig_space() 

1313 self.elseExpr.describe_signature(signode, mode, env, symbol) 

1314 

1315 

1316class ASTBracedInitList(ASTBase): 

1317 def __init__(self, exprs: list[ASTExpression | ASTBracedInitList], 

1318 trailingComma: bool) -> None: 

1319 self.exprs = exprs 

1320 self.trailingComma = trailingComma 

1321 

1322 def __eq__(self, other: object) -> bool: 

1323 if not isinstance(other, ASTBracedInitList): 

1324 return NotImplemented 

1325 return self.exprs == other.exprs and self.trailingComma == other.trailingComma 

1326 

1327 def __hash__(self) -> int: 

1328 return hash((self.exprs, self.trailingComma)) 

1329 

1330 def get_id(self, version: int) -> str: 

1331 return "il%sE" % ''.join(e.get_id(version) for e in self.exprs) 

1332 

1333 def _stringify(self, transform: StringifyTransform) -> str: 

1334 exprs = ', '.join(transform(e) for e in self.exprs) 

1335 trailingComma = ',' if self.trailingComma else '' 

1336 return f'{{{exprs}{trailingComma}}}' 

1337 

1338 def describe_signature(self, signode: TextElement, mode: str, 

1339 env: BuildEnvironment, symbol: Symbol) -> None: 

1340 verify_description_mode(mode) 

1341 signode += addnodes.desc_sig_punctuation('{', '{') 

1342 first = True 

1343 for e in self.exprs: 

1344 if not first: 

1345 signode += addnodes.desc_sig_punctuation(',', ',') 

1346 signode += addnodes.desc_sig_space() 

1347 else: 

1348 first = False 

1349 e.describe_signature(signode, mode, env, symbol) 

1350 if self.trailingComma: 

1351 signode += addnodes.desc_sig_punctuation(',', ',') 

1352 signode += addnodes.desc_sig_punctuation('}', '}') 

1353 

1354 

1355class ASTAssignmentExpr(ASTExpression): 

1356 def __init__(self, leftExpr: ASTExpression, op: str, 

1357 rightExpr: ASTExpression | ASTBracedInitList) -> None: 

1358 self.leftExpr = leftExpr 

1359 self.op = op 

1360 self.rightExpr = rightExpr 

1361 

1362 def __eq__(self, other: object) -> bool: 

1363 if not isinstance(other, ASTAssignmentExpr): 

1364 return NotImplemented 

1365 return ( 

1366 self.leftExpr == other.leftExpr 

1367 and self.op == other.op 

1368 and self.rightExpr == other.rightExpr 

1369 ) 

1370 

1371 def __hash__(self) -> int: 

1372 return hash((self.leftExpr, self.op, self.rightExpr)) 

1373 

1374 def _stringify(self, transform: StringifyTransform) -> str: 

1375 res = [] 

1376 res.append(transform(self.leftExpr)) 

1377 res.append(' ') 

1378 res.append(self.op) 

1379 res.append(' ') 

1380 res.append(transform(self.rightExpr)) 

1381 return ''.join(res) 

1382 

1383 def get_id(self, version: int) -> str: 

1384 # we end up generating the ID from left to right, instead of right to left 

1385 res = [] 

1386 res.append(_id_operator_v2[self.op]) 

1387 res.append(self.leftExpr.get_id(version)) 

1388 res.append(self.rightExpr.get_id(version)) 

1389 return ''.join(res) 

1390 

1391 def describe_signature(self, signode: TextElement, mode: str, 

1392 env: BuildEnvironment, symbol: Symbol) -> None: 

1393 self.leftExpr.describe_signature(signode, mode, env, symbol) 

1394 signode += addnodes.desc_sig_space() 

1395 if ord(self.op[0]) >= ord('a') and ord(self.op[0]) <= ord('z'): 

1396 signode += addnodes.desc_sig_keyword(self.op, self.op) 

1397 else: 

1398 signode += addnodes.desc_sig_operator(self.op, self.op) 

1399 signode += addnodes.desc_sig_space() 

1400 self.rightExpr.describe_signature(signode, mode, env, symbol) 

1401 

1402 

1403class ASTCommaExpr(ASTExpression): 

1404 def __init__(self, exprs: list[ASTExpression]) -> None: 

1405 assert len(exprs) > 0 

1406 self.exprs = exprs 

1407 

1408 def __eq__(self, other: object) -> bool: 

1409 if not isinstance(other, ASTCommaExpr): 

1410 return NotImplemented 

1411 return self.exprs == other.exprs 

1412 

1413 def __hash__(self) -> int: 

1414 return hash(self.exprs) 

1415 

1416 def _stringify(self, transform: StringifyTransform) -> str: 

1417 return ', '.join(transform(e) for e in self.exprs) 

1418 

1419 def get_id(self, version: int) -> str: 

1420 id_ = _id_operator_v2[','] 

1421 res = [] 

1422 for i in range(len(self.exprs) - 1): 

1423 res.append(id_) 

1424 res.append(self.exprs[i].get_id(version)) 

1425 res.append(self.exprs[-1].get_id(version)) 

1426 return ''.join(res) 

1427 

1428 def describe_signature(self, signode: TextElement, mode: str, 

1429 env: BuildEnvironment, symbol: Symbol) -> None: 

1430 self.exprs[0].describe_signature(signode, mode, env, symbol) 

1431 for i in range(1, len(self.exprs)): 

1432 signode += addnodes.desc_sig_punctuation(',', ',') 

1433 signode += addnodes.desc_sig_space() 

1434 self.exprs[i].describe_signature(signode, mode, env, symbol) 

1435 

1436 

1437class ASTFallbackExpr(ASTExpression): 

1438 def __init__(self, expr: str) -> None: 

1439 self.expr = expr 

1440 

1441 def __eq__(self, other: object) -> bool: 

1442 if not isinstance(other, ASTFallbackExpr): 

1443 return NotImplemented 

1444 return self.expr == other.expr 

1445 

1446 def __hash__(self) -> int: 

1447 return hash(self.expr) 

1448 

1449 def _stringify(self, transform: StringifyTransform) -> str: 

1450 return self.expr 

1451 

1452 def get_id(self, version: int) -> str: 

1453 return str(self.expr) 

1454 

1455 def describe_signature(self, signode: TextElement, mode: str, 

1456 env: BuildEnvironment, symbol: Symbol) -> None: 

1457 signode += nodes.literal(self.expr, self.expr) 

1458 

1459 

1460################################################################################ 

1461# Types 

1462################################################################################ 

1463 

1464# Things for ASTNestedName 

1465################################################################################ 

1466 

1467class ASTOperator(ASTBase): 

1468 is_anonymous: ClassVar[Literal[False]] = False 

1469 

1470 def __eq__(self, other: object) -> bool: 

1471 raise NotImplementedError(repr(self)) 

1472 

1473 def __hash__(self) -> int: 

1474 raise NotImplementedError(repr(self)) 

1475 

1476 def is_anon(self) -> bool: 

1477 return self.is_anonymous 

1478 

1479 def is_operator(self) -> bool: 

1480 return True 

1481 

1482 def get_id(self, version: int) -> str: 

1483 raise NotImplementedError 

1484 

1485 def _describe_identifier(self, signode: TextElement, identnode: TextElement, 

1486 env: BuildEnvironment, symbol: Symbol) -> None: 

1487 """Render the prefix into signode, and the last part into identnode.""" 

1488 raise NotImplementedError 

1489 

1490 def describe_signature(self, signode: TextElement, mode: str, 

1491 env: BuildEnvironment, prefix: str, templateArgs: str, 

1492 symbol: Symbol) -> None: 

1493 verify_description_mode(mode) 

1494 if mode == 'lastIsName': 

1495 mainName = addnodes.desc_name() 

1496 self._describe_identifier(mainName, mainName, env, symbol) 

1497 signode += mainName 

1498 elif mode == 'markType': 

1499 targetText = prefix + str(self) + templateArgs 

1500 pnode = addnodes.pending_xref('', refdomain='cpp', 

1501 reftype='identifier', 

1502 reftarget=targetText, modname=None, 

1503 classname=None) 

1504 pnode['cpp:parent_key'] = symbol.get_lookup_key() 

1505 # Render the identifier part, but collapse it into a string 

1506 # and make that the a link to this operator. 

1507 # E.g., if it is 'operator SomeType', then 'SomeType' becomes 

1508 # a link to the operator, not to 'SomeType'. 

1509 container = nodes.literal() 

1510 self._describe_identifier(signode, container, env, symbol) 

1511 txt = container.astext() 

1512 pnode += addnodes.desc_name(txt, txt) 

1513 signode += pnode 

1514 else: 

1515 addName = addnodes.desc_addname() 

1516 self._describe_identifier(addName, addName, env, symbol) 

1517 signode += addName 

1518 

1519 

1520class ASTOperatorBuildIn(ASTOperator): 

1521 def __init__(self, op: str) -> None: 

1522 self.op = op 

1523 

1524 def __eq__(self, other: object) -> bool: 

1525 if not isinstance(other, ASTOperatorBuildIn): 

1526 return NotImplemented 

1527 return self.op == other.op 

1528 

1529 def __hash__(self) -> int: 

1530 return hash(self.op) 

1531 

1532 def get_id(self, version: int) -> str: 

1533 if version == 1: 

1534 ids = _id_operator_v1 

1535 if self.op not in ids: 

1536 raise NoOldIdError 

1537 else: 

1538 ids = _id_operator_v2 

1539 if self.op not in ids: 

1540 raise Exception('Internal error: Built-in operator "%s" can not ' 

1541 'be mapped to an id.' % self.op) 

1542 return ids[self.op] 

1543 

1544 def _stringify(self, transform: StringifyTransform) -> str: 

1545 if self.op in ('new', 'new[]', 'delete', 'delete[]') or self.op[0] in "abcnox": 

1546 return 'operator ' + self.op 

1547 else: 

1548 return 'operator' + self.op 

1549 

1550 def _describe_identifier(self, signode: TextElement, identnode: TextElement, 

1551 env: BuildEnvironment, symbol: Symbol) -> None: 

1552 signode += addnodes.desc_sig_keyword('operator', 'operator') 

1553 if self.op in ('new', 'new[]', 'delete', 'delete[]') or self.op[0] in "abcnox": 

1554 signode += addnodes.desc_sig_space() 

1555 identnode += addnodes.desc_sig_operator(self.op, self.op) 

1556 

1557 

1558class ASTOperatorLiteral(ASTOperator): 

1559 def __init__(self, identifier: ASTIdentifier) -> None: 

1560 self.identifier = identifier 

1561 

1562 def __eq__(self, other: object) -> bool: 

1563 if not isinstance(other, ASTOperatorLiteral): 

1564 return NotImplemented 

1565 return self.identifier == other.identifier 

1566 

1567 def __hash__(self) -> int: 

1568 return hash(self.identifier) 

1569 

1570 def get_id(self, version: int) -> str: 

1571 if version == 1: 

1572 raise NoOldIdError 

1573 return 'li' + self.identifier.get_id(version) 

1574 

1575 def _stringify(self, transform: StringifyTransform) -> str: 

1576 return 'operator""' + transform(self.identifier) 

1577 

1578 def _describe_identifier(self, signode: TextElement, identnode: TextElement, 

1579 env: BuildEnvironment, symbol: Symbol) -> None: 

1580 signode += addnodes.desc_sig_keyword('operator', 'operator') 

1581 signode += addnodes.desc_sig_literal_string('""', '""') 

1582 self.identifier.describe_signature(identnode, 'markType', env, '', '', symbol) 

1583 

1584 

1585class ASTOperatorType(ASTOperator): 

1586 def __init__(self, type: ASTType) -> None: 

1587 self.type = type 

1588 

1589 def __eq__(self, other: object) -> bool: 

1590 if not isinstance(other, ASTOperatorType): 

1591 return NotImplemented 

1592 return self.type == other.type 

1593 

1594 def __hash__(self) -> int: 

1595 return hash(self.type) 

1596 

1597 def get_id(self, version: int) -> str: 

1598 if version == 1: 

1599 return 'castto-%s-operator' % self.type.get_id(version) 

1600 else: 

1601 return 'cv' + self.type.get_id(version) 

1602 

1603 def _stringify(self, transform: StringifyTransform) -> str: 

1604 return f'operator {transform(self.type)}' 

1605 

1606 def get_name_no_template(self) -> str: 

1607 return str(self) 

1608 

1609 def _describe_identifier(self, signode: TextElement, identnode: TextElement, 

1610 env: BuildEnvironment, symbol: Symbol) -> None: 

1611 signode += addnodes.desc_sig_keyword('operator', 'operator') 

1612 signode += addnodes.desc_sig_space() 

1613 self.type.describe_signature(identnode, 'markType', env, symbol) 

1614 

1615 

1616class ASTTemplateArgConstant(ASTBase): 

1617 def __init__(self, value: ASTExpression) -> None: 

1618 self.value = value 

1619 

1620 def __eq__(self, other: object) -> bool: 

1621 if not isinstance(other, ASTTemplateArgConstant): 

1622 return NotImplemented 

1623 return self.value == other.value 

1624 

1625 def __hash__(self) -> int: 

1626 return hash(self.value) 

1627 

1628 def _stringify(self, transform: StringifyTransform) -> str: 

1629 return transform(self.value) 

1630 

1631 def get_id(self, version: int) -> str: 

1632 if version == 1: 

1633 return str(self).replace(' ', '-') 

1634 if version == 2: 

1635 return 'X' + str(self) + 'E' 

1636 return 'X' + self.value.get_id(version) + 'E' 

1637 

1638 def describe_signature(self, signode: TextElement, mode: str, 

1639 env: BuildEnvironment, symbol: Symbol) -> None: 

1640 verify_description_mode(mode) 

1641 self.value.describe_signature(signode, mode, env, symbol) 

1642 

1643 

1644class ASTTemplateArgs(ASTBase): 

1645 def __init__(self, args: list[ASTType | ASTTemplateArgConstant], 

1646 packExpansion: bool) -> None: 

1647 assert args is not None 

1648 self.args = args 

1649 self.packExpansion = packExpansion 

1650 

1651 def __eq__(self, other: object) -> bool: 

1652 if not isinstance(other, ASTTemplateArgs): 

1653 return NotImplemented 

1654 return self.args == other.args and self.packExpansion == other.packExpansion 

1655 

1656 def __hash__(self) -> int: 

1657 return hash((self.args, self.packExpansion)) 

1658 

1659 def get_id(self, version: int) -> str: 

1660 if version == 1: 

1661 res = [] 

1662 res.append(':') 

1663 res.append('.'.join(a.get_id(version) for a in self.args)) 

1664 res.append(':') 

1665 return ''.join(res) 

1666 

1667 res = [] 

1668 res.append('I') 

1669 if len(self.args) > 0: 

1670 for a in self.args[:-1]: 

1671 res.append(a.get_id(version)) 

1672 if self.packExpansion: 

1673 res.append('J') 

1674 res.append(self.args[-1].get_id(version)) 

1675 if self.packExpansion: 

1676 res.append('E') 

1677 res.append('E') 

1678 return ''.join(res) 

1679 

1680 def _stringify(self, transform: StringifyTransform) -> str: 

1681 res = ', '.join(transform(a) for a in self.args) 

1682 if self.packExpansion: 

1683 res += '...' 

1684 return '<' + res + '>' 

1685 

1686 def describe_signature(self, signode: TextElement, mode: str, 

1687 env: BuildEnvironment, symbol: Symbol) -> None: 

1688 verify_description_mode(mode) 

1689 signode += addnodes.desc_sig_punctuation('<', '<') 

1690 first = True 

1691 for a in self.args: 

1692 if not first: 

1693 signode += addnodes.desc_sig_punctuation(',', ',') 

1694 signode += addnodes.desc_sig_space() 

1695 first = False 

1696 a.describe_signature(signode, 'markType', env, symbol=symbol) 

1697 if self.packExpansion: 

1698 signode += addnodes.desc_sig_punctuation('...', '...') 

1699 signode += addnodes.desc_sig_punctuation('>', '>') 

1700 

1701 

1702# Main part of declarations 

1703################################################################################ 

1704 

1705class ASTTrailingTypeSpec(ASTBase): 

1706 def get_id(self, version: int) -> str: 

1707 raise NotImplementedError(repr(self)) 

1708 

1709 def describe_signature(self, signode: TextElement, mode: str, 

1710 env: BuildEnvironment, symbol: Symbol) -> None: 

1711 raise NotImplementedError(repr(self)) 

1712 

1713 

1714class ASTTrailingTypeSpecFundamental(ASTTrailingTypeSpec): 

1715 def __init__(self, names: list[str], canonNames: list[str]) -> None: 

1716 assert len(names) != 0 

1717 assert len(names) == len(canonNames), (names, canonNames) 

1718 self.names = names 

1719 # the canonical name list is for ID lookup 

1720 self.canonNames = canonNames 

1721 

1722 def __eq__(self, other: object) -> bool: 

1723 if not isinstance(other, ASTTrailingTypeSpecFundamental): 

1724 return NotImplemented 

1725 return self.names == other.names and self.canonNames == other.canonNames 

1726 

1727 def __hash__(self) -> int: 

1728 return hash((self.names, self.canonNames)) 

1729 

1730 def _stringify(self, transform: StringifyTransform) -> str: 

1731 return ' '.join(self.names) 

1732 

1733 def get_id(self, version: int) -> str: 

1734 if version == 1: 

1735 res = [] 

1736 for a in self.canonNames: 

1737 if a in _id_fundamental_v1: 

1738 res.append(_id_fundamental_v1[a]) 

1739 else: 

1740 res.append(a) 

1741 return '-'.join(res) 

1742 

1743 txt = ' '.join(self.canonNames) 

1744 if txt not in _id_fundamental_v2: 

1745 raise Exception( 

1746 'Semi-internal error: Fundamental type "%s" can not be mapped ' 

1747 'to an ID. Is it a true fundamental type? If not so, the ' 

1748 'parser should have rejected it.' % txt) 

1749 return _id_fundamental_v2[txt] 

1750 

1751 def describe_signature(self, signode: TextElement, mode: str, 

1752 env: BuildEnvironment, symbol: Symbol) -> None: 

1753 first = True 

1754 for n in self.names: 

1755 if not first: 

1756 signode += addnodes.desc_sig_space() 

1757 else: 

1758 first = False 

1759 signode += addnodes.desc_sig_keyword_type(n, n) 

1760 

1761 

1762class ASTTrailingTypeSpecDecltypeAuto(ASTTrailingTypeSpec): 

1763 def __eq__(self, other: object) -> bool: 

1764 return isinstance(other, ASTTrailingTypeSpecDecltypeAuto) 

1765 

1766 def __hash__(self) -> int: 

1767 return hash('decltype(auto)') 

1768 

1769 def _stringify(self, transform: StringifyTransform) -> str: 

1770 return 'decltype(auto)' 

1771 

1772 def get_id(self, version: int) -> str: 

1773 if version == 1: 

1774 raise NoOldIdError 

1775 return 'Dc' 

1776 

1777 def describe_signature(self, signode: TextElement, mode: str, 

1778 env: BuildEnvironment, symbol: Symbol) -> None: 

1779 signode += addnodes.desc_sig_keyword('decltype', 'decltype') 

1780 signode += addnodes.desc_sig_punctuation('(', '(') 

1781 signode += addnodes.desc_sig_keyword('auto', 'auto') 

1782 signode += addnodes.desc_sig_punctuation(')', ')') 

1783 

1784 

1785class ASTTrailingTypeSpecDecltype(ASTTrailingTypeSpec): 

1786 def __init__(self, expr: ASTExpression) -> None: 

1787 self.expr = expr 

1788 

1789 def __eq__(self, other: object) -> bool: 

1790 if not isinstance(other, ASTTrailingTypeSpecDecltype): 

1791 return NotImplemented 

1792 return self.expr == other.expr 

1793 

1794 def __hash__(self) -> int: 

1795 return hash(self.expr) 

1796 

1797 def _stringify(self, transform: StringifyTransform) -> str: 

1798 return 'decltype(' + transform(self.expr) + ')' 

1799 

1800 def get_id(self, version: int) -> str: 

1801 if version == 1: 

1802 raise NoOldIdError 

1803 return 'DT' + self.expr.get_id(version) + "E" 

1804 

1805 def describe_signature(self, signode: TextElement, mode: str, 

1806 env: BuildEnvironment, symbol: Symbol) -> None: 

1807 signode += addnodes.desc_sig_keyword('decltype', 'decltype') 

1808 signode += addnodes.desc_sig_punctuation('(', '(') 

1809 self.expr.describe_signature(signode, mode, env, symbol) 

1810 signode += addnodes.desc_sig_punctuation(')', ')') 

1811 

1812 

1813class ASTTrailingTypeSpecName(ASTTrailingTypeSpec): 

1814 def __init__(self, prefix: str, nestedName: ASTNestedName, 

1815 placeholderType: str | None) -> None: 

1816 self.prefix = prefix 

1817 self.nestedName = nestedName 

1818 self.placeholderType = placeholderType 

1819 

1820 def __eq__(self, other: object) -> bool: 

1821 if not isinstance(other, ASTTrailingTypeSpecName): 

1822 return NotImplemented 

1823 return ( 

1824 self.prefix == other.prefix 

1825 and self.nestedName == other.nestedName 

1826 and self.placeholderType == other.placeholderType 

1827 ) 

1828 

1829 def __hash__(self) -> int: 

1830 return hash((self.prefix, self.nestedName, self.placeholderType)) 

1831 

1832 @property 

1833 def name(self) -> ASTNestedName: 

1834 return self.nestedName 

1835 

1836 def get_id(self, version: int) -> str: 

1837 return self.nestedName.get_id(version) 

1838 

1839 def _stringify(self, transform: StringifyTransform) -> str: 

1840 res = [] 

1841 if self.prefix: 

1842 res.append(self.prefix) 

1843 res.append(' ') 

1844 res.append(transform(self.nestedName)) 

1845 if self.placeholderType is not None: 

1846 res.append(' ') 

1847 res.append(self.placeholderType) 

1848 return ''.join(res) 

1849 

1850 def describe_signature(self, signode: TextElement, mode: str, 

1851 env: BuildEnvironment, symbol: Symbol) -> None: 

1852 if self.prefix: 

1853 signode += addnodes.desc_sig_keyword(self.prefix, self.prefix) 

1854 signode += addnodes.desc_sig_space() 

1855 self.nestedName.describe_signature(signode, mode, env, symbol=symbol) 

1856 if self.placeholderType is not None: 

1857 signode += addnodes.desc_sig_space() 

1858 if self.placeholderType == 'auto': 

1859 signode += addnodes.desc_sig_keyword('auto', 'auto') 

1860 elif self.placeholderType == 'decltype(auto)': 

1861 signode += addnodes.desc_sig_keyword('decltype', 'decltype') 

1862 signode += addnodes.desc_sig_punctuation('(', '(') 

1863 signode += addnodes.desc_sig_keyword('auto', 'auto') 

1864 signode += addnodes.desc_sig_punctuation(')', ')') 

1865 else: 

1866 raise AssertionError(self.placeholderType) 

1867 

1868 

1869class ASTFunctionParameter(ASTBase): 

1870 def __init__(self, arg: ASTTypeWithInit | ASTTemplateParamConstrainedTypeWithInit, 

1871 ellipsis: bool = False) -> None: 

1872 self.arg = arg 

1873 self.ellipsis = ellipsis 

1874 

1875 def __eq__(self, other: object) -> bool: 

1876 if not isinstance(other, ASTFunctionParameter): 

1877 return NotImplemented 

1878 return self.arg == other.arg and self.ellipsis == other.ellipsis 

1879 

1880 def __hash__(self) -> int: 

1881 return hash((self.arg, self.ellipsis)) 

1882 

1883 def get_id( 

1884 self, version: int, objectType: str | None = None, symbol: Symbol | None = None, 

1885 ) -> str: 

1886 # this is not part of the normal name mangling in C++ 

1887 if symbol: 

1888 # the anchor will be our parent 

1889 return symbol.parent.declaration.get_id(version, prefixed=False) 

1890 # else, do the usual 

1891 if self.ellipsis: 

1892 return 'z' 

1893 else: 

1894 return self.arg.get_id(version) 

1895 

1896 def _stringify(self, transform: StringifyTransform) -> str: 

1897 if self.ellipsis: 

1898 return '...' 

1899 else: 

1900 return transform(self.arg) 

1901 

1902 def describe_signature(self, signode: TextElement, mode: str, 

1903 env: BuildEnvironment, symbol: Symbol) -> None: 

1904 verify_description_mode(mode) 

1905 if self.ellipsis: 

1906 signode += addnodes.desc_sig_punctuation('...', '...') 

1907 else: 

1908 self.arg.describe_signature(signode, mode, env, symbol=symbol) 

1909 

1910 

1911class ASTNoexceptSpec(ASTBase): 

1912 def __init__(self, expr: ASTExpression | None) -> None: 

1913 self.expr = expr 

1914 

1915 def __eq__(self, other: object) -> bool: 

1916 if not isinstance(other, ASTNoexceptSpec): 

1917 return NotImplemented 

1918 return self.expr == other.expr 

1919 

1920 def __hash__(self) -> int: 

1921 return hash(self.expr) 

1922 

1923 def _stringify(self, transform: StringifyTransform) -> str: 

1924 if self.expr: 

1925 return 'noexcept(' + transform(self.expr) + ')' 

1926 return 'noexcept' 

1927 

1928 def describe_signature(self, signode: TextElement, mode: str, 

1929 env: BuildEnvironment, symbol: Symbol) -> None: 

1930 signode += addnodes.desc_sig_keyword('noexcept', 'noexcept') 

1931 if self.expr: 

1932 signode += addnodes.desc_sig_punctuation('(', '(') 

1933 self.expr.describe_signature(signode, 'markType', env, symbol) 

1934 signode += addnodes.desc_sig_punctuation(')', ')') 

1935 

1936 

1937class ASTParametersQualifiers(ASTBase): 

1938 def __init__(self, args: list[ASTFunctionParameter], volatile: bool, const: bool, 

1939 refQual: str | None, exceptionSpec: ASTNoexceptSpec, 

1940 trailingReturn: ASTType, 

1941 override: bool, final: bool, attrs: ASTAttributeList, 

1942 initializer: str | None) -> None: 

1943 self.args = args 

1944 self.volatile = volatile 

1945 self.const = const 

1946 self.refQual = refQual 

1947 self.exceptionSpec = exceptionSpec 

1948 self.trailingReturn = trailingReturn 

1949 self.override = override 

1950 self.final = final 

1951 self.attrs = attrs 

1952 self.initializer = initializer 

1953 

1954 def __eq__(self, other: object) -> bool: 

1955 if not isinstance(other, ASTParametersQualifiers): 

1956 return NotImplemented 

1957 return ( 

1958 self.args == other.args 

1959 and self.volatile == other.volatile 

1960 and self.const == other.const 

1961 and self.refQual == other.refQual 

1962 and self.exceptionSpec == other.exceptionSpec 

1963 and self.trailingReturn == other.trailingReturn 

1964 and self.override == other.override 

1965 and self.final == other.final 

1966 and self.attrs == other.attrs 

1967 and self.initializer == other.initializer 

1968 ) 

1969 

1970 def __hash__(self) -> int: 

1971 return hash(( 

1972 self.args, self.volatile, self.const, self.refQual, self.exceptionSpec, 

1973 self.trailingReturn, self.override, self.final, self.attrs, self.initializer 

1974 )) 

1975 

1976 @property 

1977 def function_params(self) -> list[ASTFunctionParameter]: 

1978 return self.args 

1979 

1980 def get_modifiers_id(self, version: int) -> str: 

1981 res = [] 

1982 if self.volatile: 

1983 res.append('V') 

1984 if self.const: 

1985 if version == 1: 

1986 res.append('C') 

1987 else: 

1988 res.append('K') 

1989 if self.refQual == '&&': 

1990 res.append('O') 

1991 elif self.refQual == '&': 

1992 res.append('R') 

1993 return ''.join(res) 

1994 

1995 def get_param_id(self, version: int) -> str: 

1996 if version == 1: 

1997 if len(self.args) == 0: 

1998 return '' 

1999 else: 

2000 return '__' + '.'.join(a.get_id(version) for a in self.args) 

2001 if len(self.args) == 0: 

2002 return 'v' 

2003 else: 

2004 return ''.join(a.get_id(version) for a in self.args) 

2005 

2006 def _stringify(self, transform: StringifyTransform) -> str: 

2007 res = [] 

2008 res.append('(') 

2009 first = True 

2010 for a in self.args: 

2011 if not first: 

2012 res.append(', ') 

2013 first = False 

2014 res.append(str(a)) 

2015 res.append(')') 

2016 if self.volatile: 

2017 res.append(' volatile') 

2018 if self.const: 

2019 res.append(' const') 

2020 if self.refQual: 

2021 res.append(' ') 

2022 res.append(self.refQual) 

2023 if self.exceptionSpec: 

2024 res.append(' ') 

2025 res.append(transform(self.exceptionSpec)) 

2026 if self.trailingReturn: 

2027 res.append(' -> ') 

2028 res.append(transform(self.trailingReturn)) 

2029 if self.final: 

2030 res.append(' final') 

2031 if self.override: 

2032 res.append(' override') 

2033 if len(self.attrs) != 0: 

2034 res.append(' ') 

2035 res.append(transform(self.attrs)) 

2036 if self.initializer: 

2037 res.append(' = ') 

2038 res.append(self.initializer) 

2039 return ''.join(res) 

2040 

2041 def describe_signature(self, signode: TextElement, mode: str, 

2042 env: BuildEnvironment, symbol: Symbol) -> None: 

2043 verify_description_mode(mode) 

2044 multi_line_parameter_list = False 

2045 test_node: Element = signode 

2046 while test_node.parent: 

2047 if not isinstance(test_node, addnodes.desc_signature): 

2048 test_node = test_node.parent 

2049 continue 

2050 multi_line_parameter_list = test_node.get('multi_line_parameter_list', False) 

2051 break 

2052 

2053 # only use the desc_parameterlist for the outer list, not for inner lists 

2054 if mode == 'lastIsName': 

2055 paramlist = addnodes.desc_parameterlist() 

2056 paramlist['multi_line_parameter_list'] = multi_line_parameter_list 

2057 for arg in self.args: 

2058 param = addnodes.desc_parameter('', '', noemph=True) 

2059 arg.describe_signature(param, 'param', env, symbol=symbol) 

2060 paramlist += param 

2061 signode += paramlist 

2062 else: 

2063 signode += addnodes.desc_sig_punctuation('(', '(') 

2064 first = True 

2065 for arg in self.args: 

2066 if not first: 

2067 signode += addnodes.desc_sig_punctuation(',', ',') 

2068 signode += addnodes.desc_sig_space() 

2069 first = False 

2070 arg.describe_signature(signode, 'markType', env, symbol=symbol) 

2071 signode += addnodes.desc_sig_punctuation(')', ')') 

2072 

2073 def _add_anno(signode: TextElement, text: str) -> None: 

2074 signode += addnodes.desc_sig_space() 

2075 signode += addnodes.desc_sig_keyword(text, text) 

2076 

2077 if self.volatile: 

2078 _add_anno(signode, 'volatile') 

2079 if self.const: 

2080 _add_anno(signode, 'const') 

2081 if self.refQual: 

2082 signode += addnodes.desc_sig_space() 

2083 signode += addnodes.desc_sig_punctuation(self.refQual, self.refQual) 

2084 if self.exceptionSpec: 

2085 signode += addnodes.desc_sig_space() 

2086 self.exceptionSpec.describe_signature(signode, mode, env, symbol) 

2087 if self.trailingReturn: 

2088 signode += addnodes.desc_sig_space() 

2089 signode += addnodes.desc_sig_operator('->', '->') 

2090 signode += addnodes.desc_sig_space() 

2091 self.trailingReturn.describe_signature(signode, mode, env, symbol) 

2092 if self.final: 

2093 _add_anno(signode, 'final') 

2094 if self.override: 

2095 _add_anno(signode, 'override') 

2096 if len(self.attrs) != 0: 

2097 signode += addnodes.desc_sig_space() 

2098 self.attrs.describe_signature(signode) 

2099 if self.initializer: 

2100 signode += addnodes.desc_sig_space() 

2101 signode += addnodes.desc_sig_punctuation('=', '=') 

2102 signode += addnodes.desc_sig_space() 

2103 assert self.initializer in ('0', 'delete', 'default') 

2104 if self.initializer == '0': 

2105 signode += addnodes.desc_sig_literal_number('0', '0') 

2106 else: 

2107 signode += addnodes.desc_sig_keyword(self.initializer, self.initializer) 

2108 

2109 

2110class ASTExplicitSpec(ASTBase): 

2111 def __init__(self, expr: ASTExpression | None) -> None: 

2112 self.expr = expr 

2113 

2114 def __eq__(self, other: object) -> bool: 

2115 if not isinstance(other, ASTExplicitSpec): 

2116 return NotImplemented 

2117 return self.expr == other.expr 

2118 

2119 def __hash__(self) -> int: 

2120 return hash(self.expr) 

2121 

2122 def _stringify(self, transform: StringifyTransform) -> str: 

2123 res = ['explicit'] 

2124 if self.expr is not None: 

2125 res.append('(') 

2126 res.append(transform(self.expr)) 

2127 res.append(')') 

2128 return ''.join(res) 

2129 

2130 def describe_signature(self, signode: TextElement, 

2131 env: BuildEnvironment, symbol: Symbol) -> None: 

2132 signode += addnodes.desc_sig_keyword('explicit', 'explicit') 

2133 if self.expr is not None: 

2134 signode += addnodes.desc_sig_punctuation('(', '(') 

2135 self.expr.describe_signature(signode, 'markType', env, symbol) 

2136 signode += addnodes.desc_sig_punctuation(')', ')') 

2137 

2138 

2139class ASTDeclSpecsSimple(ASTBase): 

2140 def __init__(self, storage: str, threadLocal: bool, inline: bool, virtual: bool, 

2141 explicitSpec: ASTExplicitSpec | None, 

2142 consteval: bool, constexpr: bool, constinit: bool, 

2143 volatile: bool, const: bool, friend: bool, 

2144 attrs: ASTAttributeList) -> None: 

2145 self.storage = storage 

2146 self.threadLocal = threadLocal 

2147 self.inline = inline 

2148 self.virtual = virtual 

2149 self.explicitSpec = explicitSpec 

2150 self.consteval = consteval 

2151 self.constexpr = constexpr 

2152 self.constinit = constinit 

2153 self.volatile = volatile 

2154 self.const = const 

2155 self.friend = friend 

2156 self.attrs = attrs 

2157 

2158 def __eq__(self, other: object) -> bool: 

2159 if not isinstance(other, ASTDeclSpecsSimple): 

2160 return NotImplemented 

2161 return ( 

2162 self.storage == other.storage 

2163 and self.threadLocal == other.threadLocal 

2164 and self.inline == other.inline 

2165 and self.virtual == other.virtual 

2166 and self.explicitSpec == other.explicitSpec 

2167 and self.consteval == other.consteval 

2168 and self.constexpr == other.constexpr 

2169 and self.constinit == other.constinit 

2170 and self.volatile == other.volatile 

2171 and self.const == other.const 

2172 and self.friend == other.friend 

2173 and self.attrs == other.attrs 

2174 ) 

2175 

2176 def __hash__(self) -> int: 

2177 return hash(( 

2178 self.storage, 

2179 self.threadLocal, 

2180 self.inline, 

2181 self.virtual, 

2182 self.explicitSpec, 

2183 self.consteval, 

2184 self.constexpr, 

2185 self.constinit, 

2186 self.volatile, 

2187 self.const, 

2188 self.friend, 

2189 self.attrs, 

2190 )) 

2191 

2192 def mergeWith(self, other: ASTDeclSpecsSimple) -> ASTDeclSpecsSimple: 

2193 if not other: 

2194 return self 

2195 return ASTDeclSpecsSimple(self.storage or other.storage, 

2196 self.threadLocal or other.threadLocal, 

2197 self.inline or other.inline, 

2198 self.virtual or other.virtual, 

2199 self.explicitSpec or other.explicitSpec, 

2200 self.consteval or other.consteval, 

2201 self.constexpr or other.constexpr, 

2202 self.constinit or other.constinit, 

2203 self.volatile or other.volatile, 

2204 self.const or other.const, 

2205 self.friend or other.friend, 

2206 self.attrs + other.attrs) 

2207 

2208 def _stringify(self, transform: StringifyTransform) -> str: 

2209 res: list[str] = [] 

2210 if len(self.attrs) != 0: 

2211 res.append(transform(self.attrs)) 

2212 if self.storage: 

2213 res.append(self.storage) 

2214 if self.threadLocal: 

2215 res.append('thread_local') 

2216 if self.inline: 

2217 res.append('inline') 

2218 if self.friend: 

2219 res.append('friend') 

2220 if self.virtual: 

2221 res.append('virtual') 

2222 if self.explicitSpec: 

2223 res.append(transform(self.explicitSpec)) 

2224 if self.consteval: 

2225 res.append('consteval') 

2226 if self.constexpr: 

2227 res.append('constexpr') 

2228 if self.constinit: 

2229 res.append('constinit') 

2230 if self.volatile: 

2231 res.append('volatile') 

2232 if self.const: 

2233 res.append('const') 

2234 return ' '.join(res) 

2235 

2236 def describe_signature(self, signode: TextElement, 

2237 env: BuildEnvironment, symbol: Symbol) -> None: 

2238 self.attrs.describe_signature(signode) 

2239 addSpace = len(self.attrs) != 0 

2240 

2241 def _add(signode: TextElement, text: str) -> bool: 

2242 if addSpace: 

2243 signode += addnodes.desc_sig_space() 

2244 signode += addnodes.desc_sig_keyword(text, text) 

2245 return True 

2246 

2247 if self.storage: 

2248 addSpace = _add(signode, self.storage) 

2249 if self.threadLocal: 

2250 addSpace = _add(signode, 'thread_local') 

2251 if self.inline: 

2252 addSpace = _add(signode, 'inline') 

2253 if self.friend: 

2254 addSpace = _add(signode, 'friend') 

2255 if self.virtual: 

2256 addSpace = _add(signode, 'virtual') 

2257 if self.explicitSpec: 

2258 if addSpace: 

2259 signode += addnodes.desc_sig_space() 

2260 self.explicitSpec.describe_signature(signode, env, symbol) 

2261 addSpace = True 

2262 if self.consteval: 

2263 addSpace = _add(signode, 'consteval') 

2264 if self.constexpr: 

2265 addSpace = _add(signode, 'constexpr') 

2266 if self.constinit: 

2267 addSpace = _add(signode, 'constinit') 

2268 if self.volatile: 

2269 addSpace = _add(signode, 'volatile') 

2270 if self.const: 

2271 addSpace = _add(signode, 'const') 

2272 

2273 

2274class ASTDeclSpecs(ASTBase): 

2275 def __init__(self, outer: str, 

2276 leftSpecs: ASTDeclSpecsSimple, rightSpecs: ASTDeclSpecsSimple, 

2277 trailing: ASTTrailingTypeSpec) -> None: 

2278 # leftSpecs and rightSpecs are used for output 

2279 # allSpecs are used for id generation 

2280 self.outer = outer 

2281 self.leftSpecs = leftSpecs 

2282 self.rightSpecs = rightSpecs 

2283 self.allSpecs = self.leftSpecs.mergeWith(self.rightSpecs) 

2284 self.trailingTypeSpec = trailing 

2285 

2286 def __eq__(self, other: object) -> bool: 

2287 if not isinstance(other, ASTDeclSpecs): 

2288 return NotImplemented 

2289 return ( 

2290 self.outer == other.outer 

2291 and self.leftSpecs == other.leftSpecs 

2292 and self.rightSpecs == other.rightSpecs 

2293 and self.trailingTypeSpec == other.trailingTypeSpec 

2294 ) 

2295 

2296 def __hash__(self) -> int: 

2297 return hash(( 

2298 self.outer, 

2299 self.leftSpecs, 

2300 self.rightSpecs, 

2301 self.trailingTypeSpec, 

2302 )) 

2303 

2304 def get_id(self, version: int) -> str: 

2305 if version == 1: 

2306 res = [] 

2307 res.append(self.trailingTypeSpec.get_id(version)) 

2308 if self.allSpecs.volatile: 

2309 res.append('V') 

2310 if self.allSpecs.const: 

2311 res.append('C') 

2312 return ''.join(res) 

2313 res = [] 

2314 if self.allSpecs.volatile: 

2315 res.append('V') 

2316 if self.allSpecs.const: 

2317 res.append('K') 

2318 if self.trailingTypeSpec is not None: 

2319 res.append(self.trailingTypeSpec.get_id(version)) 

2320 return ''.join(res) 

2321 

2322 def _stringify(self, transform: StringifyTransform) -> str: 

2323 res: list[str] = [] 

2324 l = transform(self.leftSpecs) 

2325 if len(l) > 0: 

2326 res.append(l) 

2327 if self.trailingTypeSpec: 

2328 if len(res) > 0: 

2329 res.append(" ") 

2330 res.append(transform(self.trailingTypeSpec)) 

2331 r = str(self.rightSpecs) 

2332 if len(r) > 0: 

2333 if len(res) > 0: 

2334 res.append(" ") 

2335 res.append(r) 

2336 return "".join(res) 

2337 

2338 def describe_signature(self, signode: TextElement, mode: str, 

2339 env: BuildEnvironment, symbol: Symbol) -> None: 

2340 verify_description_mode(mode) 

2341 numChildren = len(signode) 

2342 self.leftSpecs.describe_signature(signode, env, symbol) 

2343 addSpace = len(signode) != numChildren 

2344 

2345 if self.trailingTypeSpec: 

2346 if addSpace: 

2347 signode += addnodes.desc_sig_space() 

2348 numChildren = len(signode) 

2349 self.trailingTypeSpec.describe_signature(signode, mode, env, 

2350 symbol=symbol) 

2351 addSpace = len(signode) != numChildren 

2352 

2353 if len(str(self.rightSpecs)) > 0: 

2354 if addSpace: 

2355 signode += addnodes.desc_sig_space() 

2356 self.rightSpecs.describe_signature(signode, env, symbol) 

2357 

2358 

2359# Declarator 

2360################################################################################ 

2361 

2362class ASTArray(ASTBase): 

2363 def __init__(self, size: ASTExpression) -> None: 

2364 self.size = size 

2365 

2366 def __eq__(self, other: object) -> bool: 

2367 if not isinstance(other, ASTArray): 

2368 return NotImplemented 

2369 return self.size == other.size 

2370 

2371 def __hash__(self) -> int: 

2372 return hash(self.size) 

2373 

2374 def _stringify(self, transform: StringifyTransform) -> str: 

2375 if self.size: 

2376 return '[' + transform(self.size) + ']' 

2377 else: 

2378 return '[]' 

2379 

2380 def get_id(self, version: int) -> str: 

2381 if version == 1: 

2382 return 'A' 

2383 if version == 2: 

2384 if self.size: 

2385 return 'A' + str(self.size) + '_' 

2386 else: 

2387 return 'A_' 

2388 if self.size: 

2389 return 'A' + self.size.get_id(version) + '_' 

2390 else: 

2391 return 'A_' 

2392 

2393 def describe_signature(self, signode: TextElement, mode: str, 

2394 env: BuildEnvironment, symbol: Symbol) -> None: 

2395 verify_description_mode(mode) 

2396 signode += addnodes.desc_sig_punctuation('[', '[') 

2397 if self.size: 

2398 self.size.describe_signature(signode, 'markType', env, symbol) 

2399 signode += addnodes.desc_sig_punctuation(']', ']') 

2400 

2401 

2402class ASTDeclarator(ASTBase): 

2403 @property 

2404 def name(self) -> ASTNestedName: 

2405 raise NotImplementedError(repr(self)) 

2406 

2407 @name.setter 

2408 def name(self, name: ASTNestedName) -> None: 

2409 raise NotImplementedError(repr(self)) 

2410 

2411 @property 

2412 def isPack(self) -> bool: 

2413 raise NotImplementedError(repr(self)) 

2414 

2415 @property 

2416 def function_params(self) -> list[ASTFunctionParameter]: 

2417 raise NotImplementedError(repr(self)) 

2418 

2419 @property 

2420 def trailingReturn(self) -> ASTType: 

2421 raise NotImplementedError(repr(self)) 

2422 

2423 def require_space_after_declSpecs(self) -> bool: 

2424 raise NotImplementedError(repr(self)) 

2425 

2426 def get_modifiers_id(self, version: int) -> str: 

2427 raise NotImplementedError(repr(self)) 

2428 

2429 def get_param_id(self, version: int) -> str: 

2430 raise NotImplementedError(repr(self)) 

2431 

2432 def get_ptr_suffix_id(self, version: int) -> str: 

2433 raise NotImplementedError(repr(self)) 

2434 

2435 def get_type_id(self, version: int, returnTypeId: str) -> str: 

2436 raise NotImplementedError(repr(self)) 

2437 

2438 def is_function_type(self) -> bool: 

2439 raise NotImplementedError(repr(self)) 

2440 

2441 def describe_signature(self, signode: TextElement, mode: str, 

2442 env: BuildEnvironment, symbol: Symbol) -> None: 

2443 raise NotImplementedError(repr(self)) 

2444 

2445 

2446class ASTDeclaratorNameParamQual(ASTDeclarator): 

2447 def __init__(self, declId: ASTNestedName, 

2448 arrayOps: list[ASTArray], 

2449 paramQual: ASTParametersQualifiers) -> None: 

2450 self.declId = declId 

2451 self.arrayOps = arrayOps 

2452 self.paramQual = paramQual 

2453 

2454 def __eq__(self, other: object) -> bool: 

2455 if not isinstance(other, ASTDeclaratorNameParamQual): 

2456 return NotImplemented 

2457 return ( 

2458 self.declId == other.declId 

2459 and self.arrayOps == other.arrayOps 

2460 and self.paramQual == other.paramQual 

2461 ) 

2462 

2463 def __hash__(self) -> int: 

2464 return hash((self.declId, self.arrayOps, self.paramQual)) 

2465 

2466 @property 

2467 def name(self) -> ASTNestedName: 

2468 return self.declId 

2469 

2470 @name.setter 

2471 def name(self, name: ASTNestedName) -> None: 

2472 self.declId = name 

2473 

2474 @property 

2475 def isPack(self) -> bool: 

2476 return False 

2477 

2478 @property 

2479 def function_params(self) -> list[ASTFunctionParameter]: 

2480 return self.paramQual.function_params 

2481 

2482 @property 

2483 def trailingReturn(self) -> ASTType: 

2484 return self.paramQual.trailingReturn 

2485 

2486 # only the modifiers for a function, e.g., 

2487 def get_modifiers_id(self, version: int) -> str: 

2488 # cv-qualifiers 

2489 if self.paramQual: 

2490 return self.paramQual.get_modifiers_id(version) 

2491 raise Exception("This should only be called on a function: %s" % self) 

2492 

2493 def get_param_id(self, version: int) -> str: # only the parameters (if any) 

2494 if self.paramQual: 

2495 return self.paramQual.get_param_id(version) 

2496 else: 

2497 return '' 

2498 

2499 def get_ptr_suffix_id(self, version: int) -> str: # only the array specifiers 

2500 return ''.join(a.get_id(version) for a in self.arrayOps) 

2501 

2502 def get_type_id(self, version: int, returnTypeId: str) -> str: 

2503 assert version >= 2 

2504 res = [] 

2505 # TODO: can we actually have both array ops and paramQual? 

2506 res.append(self.get_ptr_suffix_id(version)) 

2507 if self.paramQual: 

2508 res.append(self.get_modifiers_id(version)) 

2509 res.append('F') 

2510 res.append(returnTypeId) 

2511 res.append(self.get_param_id(version)) 

2512 res.append('E') 

2513 else: 

2514 res.append(returnTypeId) 

2515 return ''.join(res) 

2516 

2517 # ------------------------------------------------------------------------ 

2518 

2519 def require_space_after_declSpecs(self) -> bool: 

2520 return self.declId is not None 

2521 

2522 def is_function_type(self) -> bool: 

2523 return self.paramQual is not None 

2524 

2525 def _stringify(self, transform: StringifyTransform) -> str: 

2526 res = [] 

2527 if self.declId: 

2528 res.append(transform(self.declId)) 

2529 res.extend(transform(op) for op in self.arrayOps) 

2530 if self.paramQual: 

2531 res.append(transform(self.paramQual)) 

2532 return ''.join(res) 

2533 

2534 def describe_signature(self, signode: TextElement, mode: str, 

2535 env: BuildEnvironment, symbol: Symbol) -> None: 

2536 verify_description_mode(mode) 

2537 if self.declId: 

2538 self.declId.describe_signature(signode, mode, env, symbol) 

2539 for op in self.arrayOps: 

2540 op.describe_signature(signode, mode, env, symbol) 

2541 if self.paramQual: 

2542 self.paramQual.describe_signature(signode, mode, env, symbol) 

2543 

2544 

2545class ASTDeclaratorNameBitField(ASTDeclarator): 

2546 def __init__(self, declId: ASTNestedName, size: ASTExpression) -> None: 

2547 self.declId = declId 

2548 self.size = size 

2549 

2550 def __eq__(self, other: object) -> bool: 

2551 if not isinstance(other, ASTDeclaratorNameBitField): 

2552 return NotImplemented 

2553 return self.declId == other.declId and self.size == other.size 

2554 

2555 def __hash__(self) -> int: 

2556 return hash((self.declId, self.size)) 

2557 

2558 @property 

2559 def name(self) -> ASTNestedName: 

2560 return self.declId 

2561 

2562 @name.setter 

2563 def name(self, name: ASTNestedName) -> None: 

2564 self.declId = name 

2565 

2566 def get_param_id(self, version: int) -> str: # only the parameters (if any) 

2567 return '' 

2568 

2569 def get_ptr_suffix_id(self, version: int) -> str: # only the array specifiers 

2570 return '' 

2571 

2572 # ------------------------------------------------------------------------ 

2573 

2574 def require_space_after_declSpecs(self) -> bool: 

2575 return self.declId is not None 

2576 

2577 def is_function_type(self) -> bool: 

2578 return False 

2579 

2580 def _stringify(self, transform: StringifyTransform) -> str: 

2581 res = [] 

2582 if self.declId: 

2583 res.append(transform(self.declId)) 

2584 res.append(" : ") 

2585 res.append(transform(self.size)) 

2586 return ''.join(res) 

2587 

2588 def describe_signature(self, signode: TextElement, mode: str, 

2589 env: BuildEnvironment, symbol: Symbol) -> None: 

2590 verify_description_mode(mode) 

2591 if self.declId: 

2592 self.declId.describe_signature(signode, mode, env, symbol) 

2593 signode += addnodes.desc_sig_space() 

2594 signode += addnodes.desc_sig_punctuation(':', ':') 

2595 signode += addnodes.desc_sig_space() 

2596 self.size.describe_signature(signode, mode, env, symbol) 

2597 

2598 

2599class ASTDeclaratorPtr(ASTDeclarator): 

2600 def __init__(self, next: ASTDeclarator, volatile: bool, const: bool, 

2601 attrs: ASTAttributeList) -> None: 

2602 assert next 

2603 self.next = next 

2604 self.volatile = volatile 

2605 self.const = const 

2606 self.attrs = attrs 

2607 

2608 def __eq__(self, other: object) -> bool: 

2609 if not isinstance(other, ASTDeclaratorPtr): 

2610 return NotImplemented 

2611 return ( 

2612 self.next == other.next 

2613 and self.volatile == other.volatile 

2614 and self.const == other.const 

2615 and self.attrs == other.attrs 

2616 ) 

2617 

2618 def __hash__(self) -> int: 

2619 return hash((self.next, self.volatile, self.const, self.attrs)) 

2620 

2621 @property 

2622 def name(self) -> ASTNestedName: 

2623 return self.next.name 

2624 

2625 @name.setter 

2626 def name(self, name: ASTNestedName) -> None: 

2627 self.next.name = name 

2628 

2629 @property 

2630 def isPack(self) -> bool: 

2631 return self.next.isPack 

2632 

2633 @property 

2634 def function_params(self) -> list[ASTFunctionParameter]: 

2635 return self.next.function_params 

2636 

2637 @property 

2638 def trailingReturn(self) -> ASTType: 

2639 return self.next.trailingReturn 

2640 

2641 def require_space_after_declSpecs(self) -> bool: 

2642 return self.next.require_space_after_declSpecs() 

2643 

2644 def _stringify(self, transform: StringifyTransform) -> str: 

2645 res = ['*'] 

2646 res.append(transform(self.attrs)) 

2647 if len(self.attrs) != 0 and (self.volatile or self.const): 

2648 res.append(' ') 

2649 if self.volatile: 

2650 res.append('volatile') 

2651 if self.const: 

2652 if self.volatile: 

2653 res.append(' ') 

2654 res.append('const') 

2655 if self.const or self.volatile or len(self.attrs) > 0: 

2656 if self.next.require_space_after_declSpecs(): 

2657 res.append(' ') 

2658 res.append(transform(self.next)) 

2659 return ''.join(res) 

2660 

2661 def get_modifiers_id(self, version: int) -> str: 

2662 return self.next.get_modifiers_id(version) 

2663 

2664 def get_param_id(self, version: int) -> str: 

2665 return self.next.get_param_id(version) 

2666 

2667 def get_ptr_suffix_id(self, version: int) -> str: 

2668 if version == 1: 

2669 res = ['P'] 

2670 if self.volatile: 

2671 res.append('V') 

2672 if self.const: 

2673 res.append('C') 

2674 res.append(self.next.get_ptr_suffix_id(version)) 

2675 return ''.join(res) 

2676 

2677 res = [self.next.get_ptr_suffix_id(version)] 

2678 res.append('P') 

2679 if self.volatile: 

2680 res.append('V') 

2681 if self.const: 

2682 res.append('C') 

2683 return ''.join(res) 

2684 

2685 def get_type_id(self, version: int, returnTypeId: str) -> str: 

2686 # ReturnType *next, so we are part of the return type of 'next 

2687 res = ['P'] 

2688 if self.volatile: 

2689 res.append('V') 

2690 if self.const: 

2691 res.append('C') 

2692 res.append(returnTypeId) 

2693 return self.next.get_type_id(version, returnTypeId=''.join(res)) 

2694 

2695 def is_function_type(self) -> bool: 

2696 return self.next.is_function_type() 

2697 

2698 def describe_signature(self, signode: TextElement, mode: str, 

2699 env: BuildEnvironment, symbol: Symbol) -> None: 

2700 verify_description_mode(mode) 

2701 signode += addnodes.desc_sig_punctuation('*', '*') 

2702 self.attrs.describe_signature(signode) 

2703 if len(self.attrs) != 0 and (self.volatile or self.const): 

2704 signode += addnodes.desc_sig_space() 

2705 

2706 def _add_anno(signode: TextElement, text: str) -> None: 

2707 signode += addnodes.desc_sig_keyword(text, text) 

2708 if self.volatile: 

2709 _add_anno(signode, 'volatile') 

2710 if self.const: 

2711 if self.volatile: 

2712 signode += addnodes.desc_sig_space() 

2713 _add_anno(signode, 'const') 

2714 if self.const or self.volatile or len(self.attrs) > 0: 

2715 if self.next.require_space_after_declSpecs(): 

2716 signode += addnodes.desc_sig_space() 

2717 self.next.describe_signature(signode, mode, env, symbol) 

2718 

2719 

2720class ASTDeclaratorRef(ASTDeclarator): 

2721 def __init__(self, next: ASTDeclarator, attrs: ASTAttributeList) -> None: 

2722 assert next 

2723 self.next = next 

2724 self.attrs = attrs 

2725 

2726 def __eq__(self, other: object) -> bool: 

2727 if not isinstance(other, ASTDeclaratorRef): 

2728 return NotImplemented 

2729 return self.next == other.next and self.attrs == other.attrs 

2730 

2731 def __hash__(self) -> int: 

2732 return hash((self.next, self.attrs)) 

2733 

2734 @property 

2735 def name(self) -> ASTNestedName: 

2736 return self.next.name 

2737 

2738 @name.setter 

2739 def name(self, name: ASTNestedName) -> None: 

2740 self.next.name = name 

2741 

2742 @property 

2743 def isPack(self) -> bool: 

2744 return self.next.isPack 

2745 

2746 @property 

2747 def function_params(self) -> list[ASTFunctionParameter]: 

2748 return self.next.function_params 

2749 

2750 @property 

2751 def trailingReturn(self) -> ASTType: 

2752 return self.next.trailingReturn 

2753 

2754 def require_space_after_declSpecs(self) -> bool: 

2755 return self.next.require_space_after_declSpecs() 

2756 

2757 def _stringify(self, transform: StringifyTransform) -> str: 

2758 res = ['&'] 

2759 res.append(transform(self.attrs)) 

2760 if len(self.attrs) != 0 and self.next.require_space_after_declSpecs(): 

2761 res.append(' ') 

2762 res.append(transform(self.next)) 

2763 return ''.join(res) 

2764 

2765 def get_modifiers_id(self, version: int) -> str: 

2766 return self.next.get_modifiers_id(version) 

2767 

2768 def get_param_id(self, version: int) -> str: # only the parameters (if any) 

2769 return self.next.get_param_id(version) 

2770 

2771 def get_ptr_suffix_id(self, version: int) -> str: 

2772 if version == 1: 

2773 return 'R' + self.next.get_ptr_suffix_id(version) 

2774 else: 

2775 return self.next.get_ptr_suffix_id(version) + 'R' 

2776 

2777 def get_type_id(self, version: int, returnTypeId: str) -> str: 

2778 assert version >= 2 

2779 # ReturnType &next, so we are part of the return type of 'next 

2780 return self.next.get_type_id(version, returnTypeId='R' + returnTypeId) 

2781 

2782 def is_function_type(self) -> bool: 

2783 return self.next.is_function_type() 

2784 

2785 def describe_signature(self, signode: TextElement, mode: str, 

2786 env: BuildEnvironment, symbol: Symbol) -> None: 

2787 verify_description_mode(mode) 

2788 signode += addnodes.desc_sig_punctuation('&', '&') 

2789 self.attrs.describe_signature(signode) 

2790 if len(self.attrs) > 0 and self.next.require_space_after_declSpecs(): 

2791 signode += addnodes.desc_sig_space() 

2792 self.next.describe_signature(signode, mode, env, symbol) 

2793 

2794 

2795class ASTDeclaratorParamPack(ASTDeclarator): 

2796 def __init__(self, next: ASTDeclarator) -> None: 

2797 assert next 

2798 self.next = next 

2799 

2800 def __eq__(self, other: object) -> bool: 

2801 if not isinstance(other, ASTDeclaratorParamPack): 

2802 return NotImplemented 

2803 return self.next == other.next 

2804 

2805 def __hash__(self) -> int: 

2806 return hash(self.next) 

2807 

2808 @property 

2809 def name(self) -> ASTNestedName: 

2810 return self.next.name 

2811 

2812 @name.setter 

2813 def name(self, name: ASTNestedName) -> None: 

2814 self.next.name = name 

2815 

2816 @property 

2817 def function_params(self) -> list[ASTFunctionParameter]: 

2818 return self.next.function_params 

2819 

2820 @property 

2821 def trailingReturn(self) -> ASTType: 

2822 return self.next.trailingReturn 

2823 

2824 @property 

2825 def isPack(self) -> bool: 

2826 return True 

2827 

2828 def require_space_after_declSpecs(self) -> bool: 

2829 return False 

2830 

2831 def _stringify(self, transform: StringifyTransform) -> str: 

2832 res = transform(self.next) 

2833 if self.next.name: 

2834 res = ' ' + res 

2835 return '...' + res 

2836 

2837 def get_modifiers_id(self, version: int) -> str: 

2838 return self.next.get_modifiers_id(version) 

2839 

2840 def get_param_id(self, version: int) -> str: # only the parameters (if any) 

2841 return self.next.get_param_id(version) 

2842 

2843 def get_ptr_suffix_id(self, version: int) -> str: 

2844 if version == 1: 

2845 return 'Dp' + self.next.get_ptr_suffix_id(version) 

2846 else: 

2847 return self.next.get_ptr_suffix_id(version) + 'Dp' 

2848 

2849 def get_type_id(self, version: int, returnTypeId: str) -> str: 

2850 assert version >= 2 

2851 # ReturnType... next, so we are part of the return type of 'next 

2852 return self.next.get_type_id(version, returnTypeId='Dp' + returnTypeId) 

2853 

2854 def is_function_type(self) -> bool: 

2855 return self.next.is_function_type() 

2856 

2857 def describe_signature(self, signode: TextElement, mode: str, 

2858 env: BuildEnvironment, symbol: Symbol) -> None: 

2859 verify_description_mode(mode) 

2860 signode += addnodes.desc_sig_punctuation('...', '...') 

2861 if self.next.name: 

2862 signode += addnodes.desc_sig_space() 

2863 self.next.describe_signature(signode, mode, env, symbol) 

2864 

2865 

2866class ASTDeclaratorMemPtr(ASTDeclarator): 

2867 def __init__(self, className: ASTNestedName, 

2868 const: bool, volatile: bool, next: ASTDeclarator) -> None: 

2869 assert className 

2870 assert next 

2871 self.className = className 

2872 self.const = const 

2873 self.volatile = volatile 

2874 self.next = next 

2875 

2876 def __eq__(self, other: object) -> bool: 

2877 if not isinstance(other, ASTDeclaratorMemPtr): 

2878 return NotImplemented 

2879 return ( 

2880 self.className == other.className 

2881 and self.const == other.const 

2882 and self.volatile == other.volatile 

2883 and self.next == other.next 

2884 ) 

2885 

2886 def __hash__(self) -> int: 

2887 return hash((self.className, self.const, self.volatile, self.next)) 

2888 

2889 @property 

2890 def name(self) -> ASTNestedName: 

2891 return self.next.name 

2892 

2893 @name.setter 

2894 def name(self, name: ASTNestedName) -> None: 

2895 self.next.name = name 

2896 

2897 @property 

2898 def isPack(self) -> bool: 

2899 return self.next.isPack 

2900 

2901 @property 

2902 def function_params(self) -> list[ASTFunctionParameter]: 

2903 return self.next.function_params 

2904 

2905 @property 

2906 def trailingReturn(self) -> ASTType: 

2907 return self.next.trailingReturn 

2908 

2909 def require_space_after_declSpecs(self) -> bool: 

2910 return True 

2911 

2912 def _stringify(self, transform: StringifyTransform) -> str: 

2913 res = [] 

2914 res.append(transform(self.className)) 

2915 res.append('::*') 

2916 if self.volatile: 

2917 res.append('volatile') 

2918 if self.const: 

2919 if self.volatile: 

2920 res.append(' ') 

2921 res.append('const') 

2922 if self.next.require_space_after_declSpecs(): 

2923 res.append(' ') 

2924 res.append(transform(self.next)) 

2925 return ''.join(res) 

2926 

2927 def get_modifiers_id(self, version: int) -> str: 

2928 if version == 1: 

2929 raise NoOldIdError 

2930 return self.next.get_modifiers_id(version) 

2931 

2932 def get_param_id(self, version: int) -> str: # only the parameters (if any) 

2933 if version == 1: 

2934 raise NoOldIdError 

2935 return self.next.get_param_id(version) 

2936 

2937 def get_ptr_suffix_id(self, version: int) -> str: 

2938 if version == 1: 

2939 raise NoOldIdError 

2940 raise NotImplementedError 

2941 return self.next.get_ptr_suffix_id(version) + 'Dp' 

2942 

2943 def get_type_id(self, version: int, returnTypeId: str) -> str: 

2944 assert version >= 2 

2945 # ReturnType name::* next, so we are part of the return type of next 

2946 nextReturnTypeId = '' 

2947 if self.volatile: 

2948 nextReturnTypeId += 'V' 

2949 if self.const: 

2950 nextReturnTypeId += 'K' 

2951 nextReturnTypeId += 'M' 

2952 nextReturnTypeId += self.className.get_id(version) 

2953 nextReturnTypeId += returnTypeId 

2954 return self.next.get_type_id(version, nextReturnTypeId) 

2955 

2956 def is_function_type(self) -> bool: 

2957 return self.next.is_function_type() 

2958 

2959 def describe_signature(self, signode: TextElement, mode: str, 

2960 env: BuildEnvironment, symbol: Symbol) -> None: 

2961 verify_description_mode(mode) 

2962 self.className.describe_signature(signode, 'markType', env, symbol) 

2963 signode += addnodes.desc_sig_punctuation('::', '::') 

2964 signode += addnodes.desc_sig_punctuation('*', '*') 

2965 

2966 def _add_anno(signode: TextElement, text: str) -> None: 

2967 signode += addnodes.desc_sig_keyword(text, text) 

2968 if self.volatile: 

2969 _add_anno(signode, 'volatile') 

2970 if self.const: 

2971 if self.volatile: 

2972 signode += addnodes.desc_sig_space() 

2973 _add_anno(signode, 'const') 

2974 if self.next.require_space_after_declSpecs(): 

2975 signode += addnodes.desc_sig_space() 

2976 self.next.describe_signature(signode, mode, env, symbol) 

2977 

2978 

2979class ASTDeclaratorParen(ASTDeclarator): 

2980 def __init__(self, inner: ASTDeclarator, next: ASTDeclarator) -> None: 

2981 assert inner 

2982 assert next 

2983 self.inner = inner 

2984 self.next = next 

2985 # TODO: we assume the name, params, and qualifiers are in inner 

2986 

2987 def __eq__(self, other: object) -> bool: 

2988 if not isinstance(other, ASTDeclaratorParen): 

2989 return NotImplemented 

2990 return self.inner == other.inner and self.next == other.next 

2991 

2992 def __hash__(self) -> int: 

2993 return hash((self.inner, self.next)) 

2994 

2995 @property 

2996 def name(self) -> ASTNestedName: 

2997 return self.inner.name 

2998 

2999 @name.setter 

3000 def name(self, name: ASTNestedName) -> None: 

3001 self.inner.name = name 

3002 

3003 @property 

3004 def isPack(self) -> bool: 

3005 return self.inner.isPack or self.next.isPack 

3006 

3007 @property 

3008 def function_params(self) -> list[ASTFunctionParameter]: 

3009 return self.inner.function_params 

3010 

3011 @property 

3012 def trailingReturn(self) -> ASTType: 

3013 return self.inner.trailingReturn 

3014 

3015 def require_space_after_declSpecs(self) -> bool: 

3016 return True 

3017 

3018 def _stringify(self, transform: StringifyTransform) -> str: 

3019 res = ['('] 

3020 res.append(transform(self.inner)) 

3021 res.append(')') 

3022 res.append(transform(self.next)) 

3023 return ''.join(res) 

3024 

3025 def get_modifiers_id(self, version: int) -> str: 

3026 return self.inner.get_modifiers_id(version) 

3027 

3028 def get_param_id(self, version: int) -> str: # only the parameters (if any) 

3029 return self.inner.get_param_id(version) 

3030 

3031 def get_ptr_suffix_id(self, version: int) -> str: 

3032 if version == 1: 

3033 raise NoOldIdError # TODO: was this implemented before? 

3034 return self.next.get_ptr_suffix_id(version) + \ 

3035 self.inner.get_ptr_suffix_id(version) 

3036 return self.inner.get_ptr_suffix_id(version) + \ 

3037 self.next.get_ptr_suffix_id(version) 

3038 

3039 def get_type_id(self, version: int, returnTypeId: str) -> str: 

3040 assert version >= 2 

3041 # ReturnType (inner)next, so 'inner' returns everything outside 

3042 nextId = self.next.get_type_id(version, returnTypeId) 

3043 return self.inner.get_type_id(version, returnTypeId=nextId) 

3044 

3045 def is_function_type(self) -> bool: 

3046 return self.inner.is_function_type() 

3047 

3048 def describe_signature(self, signode: TextElement, mode: str, 

3049 env: BuildEnvironment, symbol: Symbol) -> None: 

3050 verify_description_mode(mode) 

3051 signode += addnodes.desc_sig_punctuation('(', '(') 

3052 self.inner.describe_signature(signode, mode, env, symbol) 

3053 signode += addnodes.desc_sig_punctuation(')', ')') 

3054 self.next.describe_signature(signode, "noneIsName", env, symbol) 

3055 

3056 

3057# Type and initializer stuff 

3058############################################################################################## 

3059 

3060class ASTPackExpansionExpr(ASTExpression): 

3061 def __init__(self, expr: ASTExpression | ASTBracedInitList) -> None: 

3062 self.expr = expr 

3063 

3064 def __eq__(self, other: object) -> bool: 

3065 if not isinstance(other, ASTPackExpansionExpr): 

3066 return NotImplemented 

3067 return self.expr == other.expr 

3068 

3069 def __hash__(self) -> int: 

3070 return hash(self.expr) 

3071 

3072 def _stringify(self, transform: StringifyTransform) -> str: 

3073 return transform(self.expr) + '...' 

3074 

3075 def get_id(self, version: int) -> str: 

3076 id = self.expr.get_id(version) 

3077 return 'sp' + id 

3078 

3079 def describe_signature(self, signode: TextElement, mode: str, 

3080 env: BuildEnvironment, symbol: Symbol) -> None: 

3081 self.expr.describe_signature(signode, mode, env, symbol) 

3082 signode += addnodes.desc_sig_punctuation('...', '...') 

3083 

3084 

3085class ASTParenExprList(ASTBaseParenExprList): 

3086 def __init__(self, exprs: list[ASTExpression | ASTBracedInitList]) -> None: 

3087 self.exprs = exprs 

3088 

3089 def __eq__(self, other: object) -> bool: 

3090 if not isinstance(other, ASTParenExprList): 

3091 return NotImplemented 

3092 return self.exprs == other.exprs 

3093 

3094 def __hash__(self) -> int: 

3095 return hash(self.exprs) 

3096 

3097 def get_id(self, version: int) -> str: 

3098 return "pi%sE" % ''.join(e.get_id(version) for e in self.exprs) 

3099 

3100 def _stringify(self, transform: StringifyTransform) -> str: 

3101 exprs = [transform(e) for e in self.exprs] 

3102 return '(%s)' % ', '.join(exprs) 

3103 

3104 def describe_signature(self, signode: TextElement, mode: str, 

3105 env: BuildEnvironment, symbol: Symbol) -> None: 

3106 verify_description_mode(mode) 

3107 signode += addnodes.desc_sig_punctuation('(', '(') 

3108 first = True 

3109 for e in self.exprs: 

3110 if not first: 

3111 signode += addnodes.desc_sig_punctuation(',', ',') 

3112 signode += addnodes.desc_sig_space() 

3113 else: 

3114 first = False 

3115 e.describe_signature(signode, mode, env, symbol) 

3116 signode += addnodes.desc_sig_punctuation(')', ')') 

3117 

3118 

3119class ASTInitializer(ASTBase): 

3120 def __init__(self, value: ASTExpression | ASTBracedInitList, 

3121 hasAssign: bool = True) -> None: 

3122 self.value = value 

3123 self.hasAssign = hasAssign 

3124 

3125 def __eq__(self, other: object) -> bool: 

3126 if not isinstance(other, ASTInitializer): 

3127 return NotImplemented 

3128 return self.value == other.value and self.hasAssign == other.hasAssign 

3129 

3130 def __hash__(self) -> int: 

3131 return hash((self.value, self.hasAssign)) 

3132 

3133 def _stringify(self, transform: StringifyTransform) -> str: 

3134 val = transform(self.value) 

3135 if self.hasAssign: 

3136 return ' = ' + val 

3137 else: 

3138 return val 

3139 

3140 def describe_signature(self, signode: TextElement, mode: str, 

3141 env: BuildEnvironment, symbol: Symbol) -> None: 

3142 verify_description_mode(mode) 

3143 if self.hasAssign: 

3144 signode += addnodes.desc_sig_space() 

3145 signode += addnodes.desc_sig_punctuation('=', '=') 

3146 signode += addnodes.desc_sig_space() 

3147 self.value.describe_signature(signode, 'markType', env, symbol) 

3148 

3149 

3150class ASTType(ASTBase): 

3151 def __init__(self, declSpecs: ASTDeclSpecs, decl: ASTDeclarator) -> None: 

3152 assert declSpecs 

3153 assert decl 

3154 self.declSpecs = declSpecs 

3155 self.decl = decl 

3156 

3157 def __eq__(self, other: object) -> bool: 

3158 if not isinstance(other, ASTType): 

3159 return NotImplemented 

3160 return self.declSpecs == other.declSpecs and self.decl == other.decl 

3161 

3162 def __hash__(self) -> int: 

3163 return hash((self.declSpecs, self.decl)) 

3164 

3165 @property 

3166 def name(self) -> ASTNestedName: 

3167 return self.decl.name 

3168 

3169 @name.setter 

3170 def name(self, name: ASTNestedName) -> None: 

3171 self.decl.name = name 

3172 

3173 @property 

3174 def isPack(self) -> bool: 

3175 return self.decl.isPack 

3176 

3177 @property 

3178 def function_params(self) -> list[ASTFunctionParameter]: 

3179 return self.decl.function_params 

3180 

3181 @property 

3182 def trailingReturn(self) -> ASTType: 

3183 return self.decl.trailingReturn 

3184 

3185 def get_id(self, version: int, objectType: str | None = None, 

3186 symbol: Symbol | None = None) -> str: 

3187 if version == 1: 

3188 res = [] 

3189 if objectType: # needs the name 

3190 if objectType == 'function': # also modifiers 

3191 res.append(symbol.get_full_nested_name().get_id(version)) 

3192 res.append(self.decl.get_param_id(version)) 

3193 res.append(self.decl.get_modifiers_id(version)) 

3194 if (self.declSpecs.leftSpecs.constexpr or 

3195 (self.declSpecs.rightSpecs and 

3196 self.declSpecs.rightSpecs.constexpr)): 

3197 res.append('CE') 

3198 elif objectType == 'type': # just the name 

3199 res.append(symbol.get_full_nested_name().get_id(version)) 

3200 else: 

3201 raise AssertionError(objectType) 

3202 else: # only type encoding 

3203 if self.decl.is_function_type(): 

3204 raise NoOldIdError 

3205 res.append(self.declSpecs.get_id(version)) 

3206 res.append(self.decl.get_ptr_suffix_id(version)) 

3207 res.append(self.decl.get_param_id(version)) 

3208 return ''.join(res) 

3209 # other versions 

3210 res = [] 

3211 if objectType: # needs the name 

3212 if objectType == 'function': # also modifiers 

3213 modifiers = self.decl.get_modifiers_id(version) 

3214 res.append(symbol.get_full_nested_name().get_id(version, modifiers)) 

3215 if version >= 4: 

3216 # with templates we need to mangle the return type in as well 

3217 templ = symbol.declaration.templatePrefix 

3218 if templ is not None: 

3219 typeId = self.decl.get_ptr_suffix_id(version) 

3220 if self.trailingReturn: 

3221 returnTypeId = self.trailingReturn.get_id(version) 

3222 else: 

3223 returnTypeId = self.declSpecs.get_id(version) 

3224 res.append(typeId) 

3225 res.append(returnTypeId) 

3226 res.append(self.decl.get_param_id(version)) 

3227 elif objectType == 'type': # just the name 

3228 res.append(symbol.get_full_nested_name().get_id(version)) 

3229 else: 

3230 raise AssertionError(objectType) 

3231 else: # only type encoding 

3232 # the 'returnType' of a non-function type is simply just the last 

3233 # type, i.e., for 'int*' it is 'int' 

3234 returnTypeId = self.declSpecs.get_id(version) 

3235 typeId = self.decl.get_type_id(version, returnTypeId) 

3236 res.append(typeId) 

3237 return ''.join(res) 

3238 

3239 def _stringify(self, transform: StringifyTransform) -> str: 

3240 res = [] 

3241 declSpecs = transform(self.declSpecs) 

3242 res.append(declSpecs) 

3243 if self.decl.require_space_after_declSpecs() and len(declSpecs) > 0: 

3244 res.append(' ') 

3245 res.append(transform(self.decl)) 

3246 return ''.join(res) 

3247 

3248 def get_type_declaration_prefix(self) -> str: 

3249 if self.declSpecs.trailingTypeSpec: 

3250 return 'typedef' 

3251 else: 

3252 return 'type' 

3253 

3254 def describe_signature(self, signode: TextElement, mode: str, 

3255 env: BuildEnvironment, symbol: Symbol) -> None: 

3256 verify_description_mode(mode) 

3257 self.declSpecs.describe_signature(signode, 'markType', env, symbol) 

3258 if (self.decl.require_space_after_declSpecs() and 

3259 len(str(self.declSpecs)) > 0): 

3260 signode += addnodes.desc_sig_space() 

3261 # for parameters that don't really declare new names we get 'markType', 

3262 # this should not be propagated, but be 'noneIsName'. 

3263 if mode == 'markType': 

3264 mode = 'noneIsName' 

3265 self.decl.describe_signature(signode, mode, env, symbol) 

3266 

3267 

3268class ASTTemplateParamConstrainedTypeWithInit(ASTBase): 

3269 def __init__(self, type: ASTType, init: ASTType) -> None: 

3270 assert type 

3271 self.type = type 

3272 self.init = init 

3273 

3274 def __eq__(self, other: object) -> bool: 

3275 if not isinstance(other, ASTTemplateParamConstrainedTypeWithInit): 

3276 return NotImplemented 

3277 return self.type == other.type and self.init == other.init 

3278 

3279 def __hash__(self) -> int: 

3280 return hash((self.type, self.init)) 

3281 

3282 @property 

3283 def name(self) -> ASTNestedName: 

3284 return self.type.name 

3285 

3286 @property 

3287 def isPack(self) -> bool: 

3288 return self.type.isPack 

3289 

3290 def get_id( 

3291 self, version: int, objectType: str | None = None, symbol: Symbol | None = None, 

3292 ) -> str: 

3293 # this is not part of the normal name mangling in C++ 

3294 assert version >= 2 

3295 if symbol: 

3296 # the anchor will be our parent 

3297 return symbol.parent.declaration.get_id(version, prefixed=False) 

3298 else: 

3299 return self.type.get_id(version) 

3300 

3301 def _stringify(self, transform: StringifyTransform) -> str: 

3302 res = transform(self.type) 

3303 if self.init: 

3304 res += " = " 

3305 res += transform(self.init) 

3306 return res 

3307 

3308 def describe_signature(self, signode: TextElement, mode: str, 

3309 env: BuildEnvironment, symbol: Symbol) -> None: 

3310 self.type.describe_signature(signode, mode, env, symbol) 

3311 if self.init: 

3312 signode += addnodes.desc_sig_space() 

3313 signode += addnodes.desc_sig_punctuation('=', '=') 

3314 signode += addnodes.desc_sig_space() 

3315 self.init.describe_signature(signode, mode, env, symbol) 

3316 

3317 

3318class ASTTypeWithInit(ASTBase): 

3319 def __init__(self, type: ASTType, init: ASTInitializer) -> None: 

3320 self.type = type 

3321 self.init = init 

3322 

3323 def __eq__(self, other: object) -> bool: 

3324 if not isinstance(other, ASTTypeWithInit): 

3325 return NotImplemented 

3326 return self.type == other.type and self.init == other.init 

3327 

3328 def __hash__(self) -> int: 

3329 return hash((self.type, self.init)) 

3330 

3331 @property 

3332 def name(self) -> ASTNestedName: 

3333 return self.type.name 

3334 

3335 @property 

3336 def isPack(self) -> bool: 

3337 return self.type.isPack 

3338 

3339 def get_id(self, version: int, objectType: str | None = None, 

3340 symbol: Symbol | None = None) -> str: 

3341 if objectType != 'member': 

3342 return self.type.get_id(version, objectType) 

3343 if version == 1: 

3344 return (symbol.get_full_nested_name().get_id(version) + '__' + 

3345 self.type.get_id(version)) 

3346 return symbol.get_full_nested_name().get_id(version) 

3347 

3348 def _stringify(self, transform: StringifyTransform) -> str: 

3349 res = [] 

3350 res.append(transform(self.type)) 

3351 if self.init: 

3352 res.append(transform(self.init)) 

3353 return ''.join(res) 

3354 

3355 def describe_signature(self, signode: TextElement, mode: str, 

3356 env: BuildEnvironment, symbol: Symbol) -> None: 

3357 verify_description_mode(mode) 

3358 self.type.describe_signature(signode, mode, env, symbol) 

3359 if self.init: 

3360 self.init.describe_signature(signode, mode, env, symbol) 

3361 

3362 

3363class ASTTypeUsing(ASTBase): 

3364 def __init__(self, name: ASTNestedName, type: ASTType | None) -> None: 

3365 self.name = name 

3366 self.type = type 

3367 

3368 def __eq__(self, other: object) -> bool: 

3369 if not isinstance(other, ASTTypeUsing): 

3370 return NotImplemented 

3371 return self.name == other.name and self.type == other.type 

3372 

3373 def __hash__(self) -> int: 

3374 return hash((self.name, self.type)) 

3375 

3376 def get_id(self, version: int, objectType: str | None = None, 

3377 symbol: Symbol | None = None) -> str: 

3378 if version == 1: 

3379 raise NoOldIdError 

3380 return symbol.get_full_nested_name().get_id(version) 

3381 

3382 def _stringify(self, transform: StringifyTransform) -> str: 

3383 res = [] 

3384 res.append(transform(self.name)) 

3385 if self.type: 

3386 res.append(' = ') 

3387 res.append(transform(self.type)) 

3388 return ''.join(res) 

3389 

3390 def get_type_declaration_prefix(self) -> str: 

3391 return 'using' 

3392 

3393 def describe_signature(self, signode: TextElement, mode: str, 

3394 env: BuildEnvironment, symbol: Symbol) -> None: 

3395 verify_description_mode(mode) 

3396 self.name.describe_signature(signode, mode, env, symbol=symbol) 

3397 if self.type: 

3398 signode += addnodes.desc_sig_space() 

3399 signode += addnodes.desc_sig_punctuation('=', '=') 

3400 signode += addnodes.desc_sig_space() 

3401 self.type.describe_signature(signode, 'markType', env, symbol=symbol) 

3402 

3403 

3404# Other declarations 

3405############################################################################################## 

3406 

3407class ASTConcept(ASTBase): 

3408 def __init__(self, nestedName: ASTNestedName, initializer: ASTInitializer) -> None: 

3409 self.nestedName = nestedName 

3410 self.initializer = initializer 

3411 

3412 def __eq__(self, other: object) -> bool: 

3413 if not isinstance(other, ASTConcept): 

3414 return NotImplemented 

3415 return self.nestedName == other.nestedName and self.initializer == other.initializer 

3416 

3417 def __hash__(self) -> int: 

3418 return hash((self.nestedName, self.initializer)) 

3419 

3420 @property 

3421 def name(self) -> ASTNestedName: 

3422 return self.nestedName 

3423 

3424 def get_id(self, version: int, objectType: str | None = None, 

3425 symbol: Symbol | None = None) -> str: 

3426 if version == 1: 

3427 raise NoOldIdError 

3428 return symbol.get_full_nested_name().get_id(version) 

3429 

3430 def _stringify(self, transform: StringifyTransform) -> str: 

3431 res = transform(self.nestedName) 

3432 if self.initializer: 

3433 res += transform(self.initializer) 

3434 return res 

3435 

3436 def describe_signature(self, signode: TextElement, mode: str, 

3437 env: BuildEnvironment, symbol: Symbol) -> None: 

3438 self.nestedName.describe_signature(signode, mode, env, symbol) 

3439 if self.initializer: 

3440 self.initializer.describe_signature(signode, mode, env, symbol) 

3441 

3442 

3443class ASTBaseClass(ASTBase): 

3444 def __init__(self, name: ASTNestedName, visibility: str, 

3445 virtual: bool, pack: bool) -> None: 

3446 self.name = name 

3447 self.visibility = visibility 

3448 self.virtual = virtual 

3449 self.pack = pack 

3450 

3451 def __eq__(self, other: object) -> bool: 

3452 if not isinstance(other, ASTBaseClass): 

3453 return NotImplemented 

3454 return ( 

3455 self.name == other.name 

3456 and self.visibility == other.visibility 

3457 and self.virtual == other.virtual 

3458 and self.pack == other.pack 

3459 ) 

3460 

3461 def __hash__(self) -> int: 

3462 return hash((self.name, self.visibility, self.virtual, self.pack)) 

3463 

3464 def _stringify(self, transform: StringifyTransform) -> str: 

3465 res = [] 

3466 if self.visibility is not None: 

3467 res.append(self.visibility) 

3468 res.append(' ') 

3469 if self.virtual: 

3470 res.append('virtual ') 

3471 res.append(transform(self.name)) 

3472 if self.pack: 

3473 res.append('...') 

3474 return ''.join(res) 

3475 

3476 def describe_signature(self, signode: TextElement, mode: str, 

3477 env: BuildEnvironment, symbol: Symbol) -> None: 

3478 verify_description_mode(mode) 

3479 if self.visibility is not None: 

3480 signode += addnodes.desc_sig_keyword(self.visibility, 

3481 self.visibility) 

3482 signode += addnodes.desc_sig_space() 

3483 if self.virtual: 

3484 signode += addnodes.desc_sig_keyword('virtual', 'virtual') 

3485 signode += addnodes.desc_sig_space() 

3486 self.name.describe_signature(signode, 'markType', env, symbol=symbol) 

3487 if self.pack: 

3488 signode += addnodes.desc_sig_punctuation('...', '...') 

3489 

3490 

3491class ASTClass(ASTBase): 

3492 def __init__(self, name: ASTNestedName, final: bool, bases: list[ASTBaseClass], 

3493 attrs: ASTAttributeList) -> None: 

3494 self.name = name 

3495 self.final = final 

3496 self.bases = bases 

3497 self.attrs = attrs 

3498 

3499 def __eq__(self, other: object) -> bool: 

3500 if not isinstance(other, ASTClass): 

3501 return NotImplemented 

3502 return ( 

3503 self.name == other.name 

3504 and self.final == other.final 

3505 and self.bases == other.bases 

3506 and self.attrs == other.attrs 

3507 ) 

3508 

3509 def __hash__(self) -> int: 

3510 return hash((self.name, self.final, self.bases, self.attrs)) 

3511 

3512 def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: 

3513 return symbol.get_full_nested_name().get_id(version) 

3514 

3515 def _stringify(self, transform: StringifyTransform) -> str: 

3516 res = [] 

3517 res.append(transform(self.attrs)) 

3518 if len(self.attrs) != 0: 

3519 res.append(' ') 

3520 res.append(transform(self.name)) 

3521 if self.final: 

3522 res.append(' final') 

3523 if len(self.bases) > 0: 

3524 res.append(' : ') 

3525 first = True 

3526 for b in self.bases: 

3527 if not first: 

3528 res.append(', ') 

3529 first = False 

3530 res.append(transform(b)) 

3531 return ''.join(res) 

3532 

3533 def describe_signature(self, signode: TextElement, mode: str, 

3534 env: BuildEnvironment, symbol: Symbol) -> None: 

3535 verify_description_mode(mode) 

3536 self.attrs.describe_signature(signode) 

3537 if len(self.attrs) != 0: 

3538 signode += addnodes.desc_sig_space() 

3539 self.name.describe_signature(signode, mode, env, symbol=symbol) 

3540 if self.final: 

3541 signode += addnodes.desc_sig_space() 

3542 signode += addnodes.desc_sig_keyword('final', 'final') 

3543 if len(self.bases) > 0: 

3544 signode += addnodes.desc_sig_space() 

3545 signode += addnodes.desc_sig_punctuation(':', ':') 

3546 signode += addnodes.desc_sig_space() 

3547 for b in self.bases: 

3548 b.describe_signature(signode, mode, env, symbol=symbol) 

3549 signode += addnodes.desc_sig_punctuation(',', ',') 

3550 signode += addnodes.desc_sig_space() 

3551 signode.pop() 

3552 signode.pop() 

3553 

3554 

3555class ASTUnion(ASTBase): 

3556 def __init__(self, name: ASTNestedName, attrs: ASTAttributeList) -> None: 

3557 self.name = name 

3558 self.attrs = attrs 

3559 

3560 def __eq__(self, other: object) -> bool: 

3561 if not isinstance(other, ASTUnion): 

3562 return NotImplemented 

3563 return self.name == other.name and self.attrs == other.attrs 

3564 

3565 def __hash__(self) -> int: 

3566 return hash((self.name, self.attrs)) 

3567 

3568 def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: 

3569 if version == 1: 

3570 raise NoOldIdError 

3571 return symbol.get_full_nested_name().get_id(version) 

3572 

3573 def _stringify(self, transform: StringifyTransform) -> str: 

3574 res = [] 

3575 res.append(transform(self.attrs)) 

3576 if len(self.attrs) != 0: 

3577 res.append(' ') 

3578 res.append(transform(self.name)) 

3579 return ''.join(res) 

3580 

3581 def describe_signature(self, signode: TextElement, mode: str, 

3582 env: BuildEnvironment, symbol: Symbol) -> None: 

3583 verify_description_mode(mode) 

3584 self.attrs.describe_signature(signode) 

3585 if len(self.attrs) != 0: 

3586 signode += addnodes.desc_sig_space() 

3587 self.name.describe_signature(signode, mode, env, symbol=symbol) 

3588 

3589 

3590class ASTEnum(ASTBase): 

3591 def __init__(self, name: ASTNestedName, scoped: str, underlyingType: ASTType, 

3592 attrs: ASTAttributeList) -> None: 

3593 self.name = name 

3594 self.scoped = scoped 

3595 self.underlyingType = underlyingType 

3596 self.attrs = attrs 

3597 

3598 def __eq__(self, other: object) -> bool: 

3599 if not isinstance(other, ASTEnum): 

3600 return NotImplemented 

3601 return ( 

3602 self.name == other.name 

3603 and self.scoped == other.scoped 

3604 and self.underlyingType == other.underlyingType 

3605 and self.attrs == other.attrs 

3606 ) 

3607 

3608 def __hash__(self) -> int: 

3609 return hash((self.name, self.scoped, self.underlyingType, self.attrs)) 

3610 

3611 def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: 

3612 if version == 1: 

3613 raise NoOldIdError 

3614 return symbol.get_full_nested_name().get_id(version) 

3615 

3616 def _stringify(self, transform: StringifyTransform) -> str: 

3617 res = [] 

3618 if self.scoped: 

3619 res.append(self.scoped) 

3620 res.append(' ') 

3621 res.append(transform(self.attrs)) 

3622 if len(self.attrs) != 0: 

3623 res.append(' ') 

3624 res.append(transform(self.name)) 

3625 if self.underlyingType: 

3626 res.append(' : ') 

3627 res.append(transform(self.underlyingType)) 

3628 return ''.join(res) 

3629 

3630 def describe_signature(self, signode: TextElement, mode: str, 

3631 env: BuildEnvironment, symbol: Symbol) -> None: 

3632 verify_description_mode(mode) 

3633 # self.scoped has been done by the CPPEnumObject 

3634 self.attrs.describe_signature(signode) 

3635 if len(self.attrs) != 0: 

3636 signode += addnodes.desc_sig_space() 

3637 self.name.describe_signature(signode, mode, env, symbol=symbol) 

3638 if self.underlyingType: 

3639 signode += addnodes.desc_sig_space() 

3640 signode += addnodes.desc_sig_punctuation(':', ':') 

3641 signode += addnodes.desc_sig_space() 

3642 self.underlyingType.describe_signature(signode, 'noneIsName', 

3643 env, symbol=symbol) 

3644 

3645 

3646class ASTEnumerator(ASTBase): 

3647 def __init__(self, name: ASTNestedName, init: ASTInitializer | None, 

3648 attrs: ASTAttributeList) -> None: 

3649 self.name = name 

3650 self.init = init 

3651 self.attrs = attrs 

3652 

3653 def __eq__(self, other: object) -> bool: 

3654 if not isinstance(other, ASTEnumerator): 

3655 return NotImplemented 

3656 return ( 

3657 self.name == other.name 

3658 and self.init == other.init 

3659 and self.attrs == other.attrs 

3660 ) 

3661 

3662 def __hash__(self) -> int: 

3663 return hash((self.name, self.init, self.attrs)) 

3664 

3665 def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: 

3666 if version == 1: 

3667 raise NoOldIdError 

3668 return symbol.get_full_nested_name().get_id(version) 

3669 

3670 def _stringify(self, transform: StringifyTransform) -> str: 

3671 res = [] 

3672 res.append(transform(self.name)) 

3673 if len(self.attrs) != 0: 

3674 res.append(' ') 

3675 res.append(transform(self.attrs)) 

3676 if self.init: 

3677 res.append(transform(self.init)) 

3678 return ''.join(res) 

3679 

3680 def describe_signature(self, signode: TextElement, mode: str, 

3681 env: BuildEnvironment, symbol: Symbol) -> None: 

3682 verify_description_mode(mode) 

3683 self.name.describe_signature(signode, mode, env, symbol) 

3684 if len(self.attrs) != 0: 

3685 signode += addnodes.desc_sig_space() 

3686 self.attrs.describe_signature(signode) 

3687 if self.init: 

3688 self.init.describe_signature(signode, 'markType', env, symbol) 

3689 

3690 

3691################################################################################ 

3692# Templates 

3693################################################################################ 

3694 

3695# Parameters 

3696################################################################################ 

3697 

3698class ASTTemplateParam(ASTBase): 

3699 def get_identifier(self) -> ASTIdentifier: 

3700 raise NotImplementedError(repr(self)) 

3701 

3702 def get_id(self, version: int) -> str: 

3703 raise NotImplementedError(repr(self)) 

3704 

3705 def describe_signature(self, parentNode: TextElement, mode: str, 

3706 env: BuildEnvironment, symbol: Symbol) -> None: 

3707 raise NotImplementedError(repr(self)) 

3708 

3709 @property 

3710 def isPack(self) -> bool: 

3711 raise NotImplementedError(repr(self)) 

3712 

3713 @property 

3714 def name(self) -> ASTNestedName: 

3715 raise NotImplementedError(repr(self)) 

3716 

3717 

3718class ASTTemplateKeyParamPackIdDefault(ASTTemplateParam): 

3719 def __init__(self, key: str, identifier: ASTIdentifier, 

3720 parameterPack: bool, default: ASTType) -> None: 

3721 assert key 

3722 if parameterPack: 

3723 assert default is None 

3724 self.key = key 

3725 self.identifier = identifier 

3726 self.parameterPack = parameterPack 

3727 self.default = default 

3728 

3729 def __eq__(self, other: object) -> bool: 

3730 if not isinstance(other, ASTTemplateKeyParamPackIdDefault): 

3731 return NotImplemented 

3732 return ( 

3733 self.key == other.key 

3734 and self.identifier == other.identifier 

3735 and self.parameterPack == other.parameterPack 

3736 and self.default == other.default 

3737 ) 

3738 

3739 def __hash__(self) -> int: 

3740 return hash((self.key, self.identifier, self.parameterPack, self.default)) 

3741 

3742 def get_identifier(self) -> ASTIdentifier: 

3743 return self.identifier 

3744 

3745 def get_id(self, version: int) -> str: 

3746 assert version >= 2 

3747 # this is not part of the normal name mangling in C++ 

3748 res = [] 

3749 if self.parameterPack: 

3750 res.append('Dp') 

3751 else: 

3752 res.append('0') # we need to put something 

3753 return ''.join(res) 

3754 

3755 def _stringify(self, transform: StringifyTransform) -> str: 

3756 res = [self.key] 

3757 if self.parameterPack: 

3758 if self.identifier: 

3759 res.append(' ') 

3760 res.append('...') 

3761 if self.identifier: 

3762 if not self.parameterPack: 

3763 res.append(' ') 

3764 res.append(transform(self.identifier)) 

3765 if self.default: 

3766 res.append(' = ') 

3767 res.append(transform(self.default)) 

3768 return ''.join(res) 

3769 

3770 def describe_signature(self, signode: TextElement, mode: str, 

3771 env: BuildEnvironment, symbol: Symbol) -> None: 

3772 signode += addnodes.desc_sig_keyword(self.key, self.key) 

3773 if self.parameterPack: 

3774 if self.identifier: 

3775 signode += addnodes.desc_sig_space() 

3776 signode += addnodes.desc_sig_punctuation('...', '...') 

3777 if self.identifier: 

3778 if not self.parameterPack: 

3779 signode += addnodes.desc_sig_space() 

3780 self.identifier.describe_signature(signode, mode, env, '', '', symbol) 

3781 if self.default: 

3782 signode += addnodes.desc_sig_space() 

3783 signode += addnodes.desc_sig_punctuation('=', '=') 

3784 signode += addnodes.desc_sig_space() 

3785 self.default.describe_signature(signode, 'markType', env, symbol) 

3786 

3787 

3788class ASTTemplateParamType(ASTTemplateParam): 

3789 def __init__(self, data: ASTTemplateKeyParamPackIdDefault) -> None: 

3790 assert data 

3791 self.data = data 

3792 

3793 def __eq__(self, other: object) -> bool: 

3794 if not isinstance(other, ASTTemplateParamType): 

3795 return NotImplemented 

3796 return self.data == other.data 

3797 

3798 def __hash__(self) -> int: 

3799 return hash(self.data) 

3800 

3801 @property 

3802 def name(self) -> ASTNestedName: 

3803 id = self.get_identifier() 

3804 return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False) 

3805 

3806 @property 

3807 def isPack(self) -> bool: 

3808 return self.data.parameterPack 

3809 

3810 def get_identifier(self) -> ASTIdentifier: 

3811 return self.data.get_identifier() 

3812 

3813 def get_id( 

3814 self, version: int, objectType: str | None = None, symbol: Symbol | None = None, 

3815 ) -> str: 

3816 # this is not part of the normal name mangling in C++ 

3817 assert version >= 2 

3818 if symbol: 

3819 # the anchor will be our parent 

3820 return symbol.parent.declaration.get_id(version, prefixed=False) 

3821 else: 

3822 return self.data.get_id(version) 

3823 

3824 def _stringify(self, transform: StringifyTransform) -> str: 

3825 return transform(self.data) 

3826 

3827 def describe_signature(self, signode: TextElement, mode: str, 

3828 env: BuildEnvironment, symbol: Symbol) -> None: 

3829 self.data.describe_signature(signode, mode, env, symbol) 

3830 

3831 

3832class ASTTemplateParamTemplateType(ASTTemplateParam): 

3833 def __init__(self, nestedParams: ASTTemplateParams, 

3834 data: ASTTemplateKeyParamPackIdDefault) -> None: 

3835 assert nestedParams 

3836 assert data 

3837 self.nestedParams = nestedParams 

3838 self.data = data 

3839 

3840 def __eq__(self, other: object) -> bool: 

3841 if not isinstance(other, ASTTemplateParamTemplateType): 

3842 return NotImplemented 

3843 return ( 

3844 self.nestedParams == other.nestedParams 

3845 and self.data == other.data 

3846 ) 

3847 

3848 def __hash__(self) -> int: 

3849 return hash((self.nestedParams, self.data)) 

3850 

3851 @property 

3852 def name(self) -> ASTNestedName: 

3853 id = self.get_identifier() 

3854 return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False) 

3855 

3856 @property 

3857 def isPack(self) -> bool: 

3858 return self.data.parameterPack 

3859 

3860 def get_identifier(self) -> ASTIdentifier: 

3861 return self.data.get_identifier() 

3862 

3863 def get_id( 

3864 self, version: int, objectType: str | None = None, symbol: Symbol | None = None, 

3865 ) -> str: 

3866 assert version >= 2 

3867 # this is not part of the normal name mangling in C++ 

3868 if symbol: 

3869 # the anchor will be our parent 

3870 return symbol.parent.declaration.get_id(version, prefixed=None) 

3871 else: 

3872 return self.nestedParams.get_id(version) + self.data.get_id(version) 

3873 

3874 def _stringify(self, transform: StringifyTransform) -> str: 

3875 return transform(self.nestedParams) + transform(self.data) 

3876 

3877 def describe_signature(self, signode: TextElement, mode: str, 

3878 env: BuildEnvironment, symbol: Symbol) -> None: 

3879 self.nestedParams.describe_signature(signode, 'noneIsName', env, symbol) 

3880 signode += addnodes.desc_sig_space() 

3881 self.data.describe_signature(signode, mode, env, symbol) 

3882 

3883 

3884class ASTTemplateParamNonType(ASTTemplateParam): 

3885 def __init__(self, 

3886 param: ASTTypeWithInit | ASTTemplateParamConstrainedTypeWithInit, 

3887 parameterPack: bool = False) -> None: 

3888 assert param 

3889 self.param = param 

3890 self.parameterPack = parameterPack 

3891 

3892 def __eq__(self, other: object) -> bool: 

3893 if not isinstance(other, ASTTemplateParamNonType): 

3894 return NotImplemented 

3895 return ( 

3896 self.param == other.param 

3897 and self.parameterPack == other.parameterPack 

3898 ) 

3899 

3900 @property 

3901 def name(self) -> ASTNestedName: 

3902 id = self.get_identifier() 

3903 return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False) 

3904 

3905 @property 

3906 def isPack(self) -> bool: 

3907 return self.param.isPack or self.parameterPack 

3908 

3909 def get_identifier(self) -> ASTIdentifier: 

3910 name = self.param.name 

3911 if name: 

3912 assert len(name.names) == 1 

3913 assert name.names[0].identOrOp 

3914 assert not name.names[0].templateArgs 

3915 res = name.names[0].identOrOp 

3916 assert isinstance(res, ASTIdentifier) 

3917 return res 

3918 else: 

3919 return None 

3920 

3921 def get_id( 

3922 self, version: int, objectType: str | None = None, symbol: Symbol | None = None, 

3923 ) -> str: 

3924 assert version >= 2 

3925 # this is not part of the normal name mangling in C++ 

3926 if symbol: 

3927 # the anchor will be our parent 

3928 return symbol.parent.declaration.get_id(version, prefixed=None) 

3929 else: 

3930 res = '_' 

3931 if self.parameterPack: 

3932 res += 'Dp' 

3933 return res + self.param.get_id(version) 

3934 

3935 def _stringify(self, transform: StringifyTransform) -> str: 

3936 res = transform(self.param) 

3937 if self.parameterPack: 

3938 res += '...' 

3939 return res 

3940 

3941 def describe_signature(self, signode: TextElement, mode: str, 

3942 env: BuildEnvironment, symbol: Symbol) -> None: 

3943 self.param.describe_signature(signode, mode, env, symbol) 

3944 if self.parameterPack: 

3945 signode += addnodes.desc_sig_punctuation('...', '...') 

3946 

3947 

3948class ASTTemplateParams(ASTBase): 

3949 def __init__(self, params: list[ASTTemplateParam], 

3950 requiresClause: ASTRequiresClause | None) -> None: 

3951 assert params is not None 

3952 self.params = params 

3953 self.requiresClause = requiresClause 

3954 

3955 def __eq__(self, other: object) -> bool: 

3956 if not isinstance(other, ASTTemplateParams): 

3957 return NotImplemented 

3958 return self.params == other.params and self.requiresClause == other.requiresClause 

3959 

3960 def __hash__(self) -> int: 

3961 return hash((self.params, self.requiresClause)) 

3962 

3963 def get_id(self, version: int, excludeRequires: bool = False) -> str: 

3964 assert version >= 2 

3965 res = [] 

3966 res.append("I") 

3967 res.extend(param.get_id(version) for param in self.params) 

3968 res.append("E") 

3969 if not excludeRequires and self.requiresClause: 

3970 res.extend(['IQ', self.requiresClause.expr.get_id(version), 'E']) 

3971 return ''.join(res) 

3972 

3973 def _stringify(self, transform: StringifyTransform) -> str: 

3974 res = [] 

3975 res.append("template<") 

3976 res.append(", ".join(transform(a) for a in self.params)) 

3977 res.append("> ") 

3978 if self.requiresClause is not None: 

3979 res.append(transform(self.requiresClause)) 

3980 res.append(" ") 

3981 return ''.join(res) 

3982 

3983 def describe_signature(self, signode: TextElement, mode: str, 

3984 env: BuildEnvironment, symbol: Symbol) -> None: 

3985 signode += addnodes.desc_sig_keyword('template', 'template') 

3986 signode += addnodes.desc_sig_punctuation('<', '<') 

3987 first = True 

3988 for param in self.params: 

3989 if not first: 

3990 signode += addnodes.desc_sig_punctuation(',', ',') 

3991 signode += addnodes.desc_sig_space() 

3992 first = False 

3993 param.describe_signature(signode, mode, env, symbol) 

3994 signode += addnodes.desc_sig_punctuation('>', '>') 

3995 if self.requiresClause is not None: 

3996 signode += addnodes.desc_sig_space() 

3997 self.requiresClause.describe_signature(signode, mode, env, symbol) 

3998 

3999 def describe_signature_as_introducer( 

4000 self, parentNode: desc_signature, mode: str, env: BuildEnvironment, 

4001 symbol: Symbol, lineSpec: bool) -> None: 

4002 def makeLine(parentNode: desc_signature) -> addnodes.desc_signature_line: 

4003 signode = addnodes.desc_signature_line() 

4004 parentNode += signode 

4005 signode.sphinx_line_type = 'templateParams' 

4006 return signode 

4007 lineNode = makeLine(parentNode) 

4008 lineNode += addnodes.desc_sig_keyword('template', 'template') 

4009 lineNode += addnodes.desc_sig_punctuation('<', '<') 

4010 first = True 

4011 for param in self.params: 

4012 if not first: 

4013 lineNode += addnodes.desc_sig_punctuation(',', ',') 

4014 lineNode += addnodes.desc_sig_space() 

4015 first = False 

4016 if lineSpec: 

4017 lineNode = makeLine(parentNode) 

4018 param.describe_signature(lineNode, mode, env, symbol) 

4019 if lineSpec and not first: 

4020 lineNode = makeLine(parentNode) 

4021 lineNode += addnodes.desc_sig_punctuation('>', '>') 

4022 if self.requiresClause: 

4023 reqNode = addnodes.desc_signature_line() 

4024 reqNode.sphinx_line_type = 'requiresClause' 

4025 parentNode += reqNode 

4026 self.requiresClause.describe_signature(reqNode, 'markType', env, symbol) 

4027 

4028 

4029# Template introducers 

4030################################################################################ 

4031 

4032class ASTTemplateIntroductionParameter(ASTBase): 

4033 def __init__(self, identifier: ASTIdentifier, parameterPack: bool) -> None: 

4034 self.identifier = identifier 

4035 self.parameterPack = parameterPack 

4036 

4037 def __eq__(self, other: object) -> bool: 

4038 if not isinstance(other, ASTTemplateIntroductionParameter): 

4039 return NotImplemented 

4040 return ( 

4041 self.identifier == other.identifier 

4042 and self.parameterPack == other.parameterPack 

4043 ) 

4044 

4045 def __hash__(self) -> int: 

4046 return hash((self.identifier, self.parameterPack)) 

4047 

4048 @property 

4049 def name(self) -> ASTNestedName: 

4050 id = self.get_identifier() 

4051 return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False) 

4052 

4053 @property 

4054 def isPack(self) -> bool: 

4055 return self.parameterPack 

4056 

4057 def get_identifier(self) -> ASTIdentifier: 

4058 return self.identifier 

4059 

4060 def get_id( 

4061 self, version: int, objectType: str | None = None, symbol: Symbol | None = None, 

4062 ) -> str: 

4063 assert version >= 2 

4064 # this is not part of the normal name mangling in C++ 

4065 if symbol: 

4066 # the anchor will be our parent 

4067 return symbol.parent.declaration.get_id(version, prefixed=None) 

4068 else: 

4069 if self.parameterPack: 

4070 return 'Dp' 

4071 else: 

4072 return '0' # we need to put something 

4073 

4074 def get_id_as_arg(self, version: int) -> str: 

4075 assert version >= 2 

4076 # used for the implicit requires clause 

4077 res = self.identifier.get_id(version) 

4078 if self.parameterPack: 

4079 return 'sp' + res 

4080 else: 

4081 return res 

4082 

4083 def _stringify(self, transform: StringifyTransform) -> str: 

4084 res = [] 

4085 if self.parameterPack: 

4086 res.append('...') 

4087 res.append(transform(self.identifier)) 

4088 return ''.join(res) 

4089 

4090 def describe_signature(self, signode: TextElement, mode: str, 

4091 env: BuildEnvironment, symbol: Symbol) -> None: 

4092 if self.parameterPack: 

4093 signode += addnodes.desc_sig_punctuation('...', '...') 

4094 self.identifier.describe_signature(signode, mode, env, '', '', symbol) 

4095 

4096 

4097class ASTTemplateIntroduction(ASTBase): 

4098 def __init__(self, concept: ASTNestedName, 

4099 params: list[ASTTemplateIntroductionParameter]) -> None: 

4100 assert len(params) > 0 

4101 self.concept = concept 

4102 self.params = params 

4103 

4104 def __eq__(self, other: object) -> bool: 

4105 if not isinstance(other, ASTTemplateIntroduction): 

4106 return NotImplemented 

4107 return self.concept == other.concept and self.params == other.params 

4108 

4109 def __hash__(self) -> int: 

4110 return hash((self.concept, self.params)) 

4111 

4112 def get_id(self, version: int) -> str: 

4113 assert version >= 2 

4114 return ''.join([ 

4115 # first do the same as a normal template parameter list 

4116 "I", 

4117 *(param.get_id(version) for param in self.params), 

4118 "E", 

4119 # let's use X expr E, which is otherwise for constant template args 

4120 "X", 

4121 self.concept.get_id(version), 

4122 "I", 

4123 *(param.get_id_as_arg(version) for param in self.params), 

4124 "E", 

4125 "E", 

4126 ]) 

4127 

4128 def _stringify(self, transform: StringifyTransform) -> str: 

4129 res = [] 

4130 res.append(transform(self.concept)) 

4131 res.append('{') 

4132 res.append(', '.join(transform(param) for param in self.params)) 

4133 res.append('} ') 

4134 return ''.join(res) 

4135 

4136 def describe_signature_as_introducer( 

4137 self, parentNode: desc_signature, mode: str, 

4138 env: BuildEnvironment, symbol: Symbol, lineSpec: bool) -> None: 

4139 # Note: 'lineSpec' has no effect on template introductions. 

4140 signode = addnodes.desc_signature_line() 

4141 parentNode += signode 

4142 signode.sphinx_line_type = 'templateIntroduction' 

4143 self.concept.describe_signature(signode, 'markType', env, symbol) 

4144 signode += addnodes.desc_sig_punctuation('{', '{') 

4145 first = True 

4146 for param in self.params: 

4147 if not first: 

4148 signode += addnodes.desc_sig_punctuation(',', ',') 

4149 signode += addnodes.desc_sig_space() 

4150 first = False 

4151 param.describe_signature(signode, mode, env, symbol) 

4152 signode += addnodes.desc_sig_punctuation('}', '}') 

4153 

4154 

4155################################################################################ 

4156 

4157class ASTTemplateDeclarationPrefix(ASTBase): 

4158 def __init__(self, 

4159 templates: list[ASTTemplateParams | ASTTemplateIntroduction] | None) -> None: 

4160 # templates is None means it's an explicit instantiation of a variable 

4161 self.templates = templates 

4162 

4163 def __eq__(self, other: object) -> bool: 

4164 if not isinstance(other, ASTTemplateDeclarationPrefix): 

4165 return NotImplemented 

4166 return self.templates == other.templates 

4167 

4168 def __hash__(self) -> int: 

4169 return hash(self.templates) 

4170 

4171 def get_requires_clause_in_last(self) -> ASTRequiresClause | None: 

4172 if self.templates is None: 

4173 return None 

4174 lastList = self.templates[-1] 

4175 if not isinstance(lastList, ASTTemplateParams): 

4176 return None 

4177 return lastList.requiresClause # which may be None 

4178 

4179 def get_id_except_requires_clause_in_last(self, version: int) -> str: 

4180 assert version >= 2 

4181 # This is not part of the Itanium ABI mangling system. 

4182 res = [] 

4183 lastIndex = len(self.templates) - 1 

4184 for i, t in enumerate(self.templates): 

4185 if isinstance(t, ASTTemplateParams): 

4186 res.append(t.get_id(version, excludeRequires=(i == lastIndex))) 

4187 else: 

4188 res.append(t.get_id(version)) 

4189 return ''.join(res) 

4190 

4191 def _stringify(self, transform: StringifyTransform) -> str: 

4192 return ''.join(map(transform, self.templates)) 

4193 

4194 def describe_signature(self, signode: desc_signature, mode: str, 

4195 env: BuildEnvironment, symbol: Symbol, lineSpec: bool) -> None: 

4196 verify_description_mode(mode) 

4197 for t in self.templates: 

4198 t.describe_signature_as_introducer(signode, 'lastIsName', env, symbol, lineSpec) 

4199 

4200 

4201class ASTRequiresClause(ASTBase): 

4202 def __init__(self, expr: ASTExpression) -> None: 

4203 self.expr = expr 

4204 

4205 def __eq__(self, other: object) -> bool: 

4206 if not isinstance(other, ASTRequiresClause): 

4207 return NotImplemented 

4208 return self.expr == other.expr 

4209 

4210 def __hash__(self) -> int: 

4211 return hash(self.expr) 

4212 

4213 def _stringify(self, transform: StringifyTransform) -> str: 

4214 return 'requires ' + transform(self.expr) 

4215 

4216 def describe_signature(self, signode: nodes.TextElement, mode: str, 

4217 env: BuildEnvironment, symbol: Symbol) -> None: 

4218 signode += addnodes.desc_sig_keyword('requires', 'requires') 

4219 signode += addnodes.desc_sig_space() 

4220 self.expr.describe_signature(signode, mode, env, symbol) 

4221 

4222 

4223################################################################################ 

4224################################################################################ 

4225 

4226class ASTDeclaration(ASTBase): 

4227 def __init__(self, objectType: str, directiveType: str | None = None, 

4228 visibility: str | None = None, 

4229 templatePrefix: ASTTemplateDeclarationPrefix | None = None, 

4230 declaration: Any = None, 

4231 trailingRequiresClause: ASTRequiresClause | None = None, 

4232 semicolon: bool = False) -> None: 

4233 self.objectType = objectType 

4234 self.directiveType = directiveType 

4235 self.visibility = visibility 

4236 self.templatePrefix = templatePrefix 

4237 self.declaration = declaration 

4238 self.trailingRequiresClause = trailingRequiresClause 

4239 self.semicolon = semicolon 

4240 

4241 self.symbol: Symbol | None = None 

4242 # set by CPPObject._add_enumerator_to_parent 

4243 self.enumeratorScopedSymbol: Symbol | None = None 

4244 

4245 # the cache assumes that by the time get_newest_id is called, no 

4246 # further changes will be made to this object 

4247 self._newest_id_cache: str | None = None 

4248 

4249 def __eq__(self, other: object) -> bool: 

4250 if not isinstance(other, ASTDeclaration): 

4251 return NotImplemented 

4252 return ( 

4253 self.objectType == other.objectType 

4254 and self.directiveType == other.directiveType 

4255 and self.visibility == other.visibility 

4256 and self.templatePrefix == other.templatePrefix 

4257 and self.declaration == other.declaration 

4258 and self.trailingRequiresClause == other.trailingRequiresClause 

4259 and self.semicolon == other.semicolon 

4260 and self.symbol == other.symbol 

4261 and self.enumeratorScopedSymbol == other.enumeratorScopedSymbol 

4262 ) 

4263 

4264 def clone(self) -> ASTDeclaration: 

4265 templatePrefixClone = self.templatePrefix.clone() if self.templatePrefix else None 

4266 trailingRequiresClasueClone = self.trailingRequiresClause.clone() \ 

4267 if self.trailingRequiresClause else None 

4268 return ASTDeclaration(self.objectType, self.directiveType, self.visibility, 

4269 templatePrefixClone, 

4270 self.declaration.clone(), trailingRequiresClasueClone, 

4271 self.semicolon) 

4272 

4273 @property 

4274 def name(self) -> ASTNestedName: 

4275 return self.declaration.name 

4276 

4277 @property 

4278 def function_params(self) -> list[ASTFunctionParameter]: 

4279 if self.objectType != 'function': 

4280 return None 

4281 return self.declaration.function_params 

4282 

4283 def get_id(self, version: int, prefixed: bool = True) -> str: 

4284 if version == 1: 

4285 if self.templatePrefix or self.trailingRequiresClause: 

4286 raise NoOldIdError 

4287 if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: 

4288 return self.enumeratorScopedSymbol.declaration.get_id(version) 

4289 return self.declaration.get_id(version, self.objectType, self.symbol) 

4290 # version >= 2 

4291 if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: 

4292 return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed) 

4293 if prefixed: 

4294 res = [_id_prefix[version]] 

4295 else: 

4296 res = [] 

4297 # (See also https://github.com/sphinx-doc/sphinx/pull/10286#issuecomment-1168102147) 

4298 # The first implementation of requires clauses only supported a single clause after the 

4299 # template prefix, and no trailing clause. It put the ID after the template parameter 

4300 # list, i.e., 

4301 # "I" + template_parameter_list_id + "E" + "IQ" + requires_clause_id + "E" 

4302 # but the second implementation associates the requires clause with each list, i.e., 

4303 # "I" + template_parameter_list_id + "IQ" + requires_clause_id + "E" + "E" 

4304 # To avoid making a new ID version, we make an exception for the last requires clause 

4305 # in the template prefix, and still put it in the end. 

4306 # As we now support trailing requires clauses we add that as if it was a conjunction. 

4307 if self.templatePrefix is not None: 

4308 res.append(self.templatePrefix.get_id_except_requires_clause_in_last(version)) 

4309 requiresClauseInLast = self.templatePrefix.get_requires_clause_in_last() 

4310 else: 

4311 requiresClauseInLast = None 

4312 

4313 if requiresClauseInLast or self.trailingRequiresClause: 

4314 if version < 4: 

4315 raise NoOldIdError 

4316 res.append('IQ') 

4317 if requiresClauseInLast and self.trailingRequiresClause: 

4318 # make a conjunction of them 

4319 res.append('aa') 

4320 if requiresClauseInLast: 

4321 res.append(requiresClauseInLast.expr.get_id(version)) 

4322 if self.trailingRequiresClause: 

4323 res.append(self.trailingRequiresClause.expr.get_id(version)) 

4324 res.append('E') 

4325 res.append(self.declaration.get_id(version, self.objectType, self.symbol)) 

4326 return ''.join(res) 

4327 

4328 def get_newest_id(self) -> str: 

4329 if self._newest_id_cache is None: 

4330 self._newest_id_cache = self.get_id(_max_id, True) 

4331 return self._newest_id_cache 

4332 

4333 def _stringify(self, transform: StringifyTransform) -> str: 

4334 res = [] 

4335 if self.visibility and self.visibility != "public": 

4336 res.append(self.visibility) 

4337 res.append(' ') 

4338 if self.templatePrefix: 

4339 res.append(transform(self.templatePrefix)) 

4340 res.append(transform(self.declaration)) 

4341 if self.trailingRequiresClause: 

4342 res.append(' ') 

4343 res.append(transform(self.trailingRequiresClause)) 

4344 if self.semicolon: 

4345 res.append(';') 

4346 return ''.join(res) 

4347 

4348 def describe_signature(self, signode: desc_signature, mode: str, 

4349 env: BuildEnvironment, options: dict[str, bool]) -> None: 

4350 verify_description_mode(mode) 

4351 assert self.symbol 

4352 # The caller of the domain added a desc_signature node. 

4353 # Always enable multiline: 

4354 signode['is_multiline'] = True 

4355 # Put each line in a desc_signature_line node. 

4356 mainDeclNode = addnodes.desc_signature_line() 

4357 mainDeclNode.sphinx_line_type = 'declarator' 

4358 mainDeclNode['add_permalink'] = not self.symbol.isRedeclaration 

4359 

4360 if self.templatePrefix: 

4361 self.templatePrefix.describe_signature(signode, mode, env, 

4362 symbol=self.symbol, 

4363 lineSpec=options.get('tparam-line-spec')) 

4364 signode += mainDeclNode 

4365 if self.visibility and self.visibility != "public": 

4366 mainDeclNode += addnodes.desc_sig_keyword(self.visibility, self.visibility) 

4367 mainDeclNode += addnodes.desc_sig_space() 

4368 if self.objectType == 'type': 

4369 prefix = self.declaration.get_type_declaration_prefix() 

4370 mainDeclNode += addnodes.desc_sig_keyword(prefix, prefix) 

4371 mainDeclNode += addnodes.desc_sig_space() 

4372 elif self.objectType == 'concept': 

4373 mainDeclNode += addnodes.desc_sig_keyword('concept', 'concept') 

4374 mainDeclNode += addnodes.desc_sig_space() 

4375 elif self.objectType in {'member', 'function'}: 

4376 pass 

4377 elif self.objectType == 'class': 

4378 assert self.directiveType in ('class', 'struct') 

4379 mainDeclNode += addnodes.desc_sig_keyword(self.directiveType, self.directiveType) 

4380 mainDeclNode += addnodes.desc_sig_space() 

4381 elif self.objectType == 'union': 

4382 mainDeclNode += addnodes.desc_sig_keyword('union', 'union') 

4383 mainDeclNode += addnodes.desc_sig_space() 

4384 elif self.objectType == 'enum': 

4385 mainDeclNode += addnodes.desc_sig_keyword('enum', 'enum') 

4386 mainDeclNode += addnodes.desc_sig_space() 

4387 if self.directiveType == 'enum-class': 

4388 mainDeclNode += addnodes.desc_sig_keyword('class', 'class') 

4389 mainDeclNode += addnodes.desc_sig_space() 

4390 elif self.directiveType == 'enum-struct': 

4391 mainDeclNode += addnodes.desc_sig_keyword('struct', 'struct') 

4392 mainDeclNode += addnodes.desc_sig_space() 

4393 else: 

4394 assert self.directiveType == 'enum', self.directiveType 

4395 elif self.objectType == 'enumerator': 

4396 mainDeclNode += addnodes.desc_sig_keyword('enumerator', 'enumerator') 

4397 mainDeclNode += addnodes.desc_sig_space() 

4398 else: 

4399 raise AssertionError(self.objectType) 

4400 self.declaration.describe_signature(mainDeclNode, mode, env, self.symbol) 

4401 lastDeclNode = mainDeclNode 

4402 if self.trailingRequiresClause: 

4403 trailingReqNode = addnodes.desc_signature_line() 

4404 trailingReqNode.sphinx_line_type = 'trailingRequiresClause' 

4405 signode.append(trailingReqNode) 

4406 lastDeclNode = trailingReqNode 

4407 self.trailingRequiresClause.describe_signature( 

4408 trailingReqNode, 'markType', env, self.symbol) 

4409 if self.semicolon: 

4410 lastDeclNode += addnodes.desc_sig_punctuation(';', ';') 

4411 

4412 

4413class ASTNamespace(ASTBase): 

4414 def __init__(self, nestedName: ASTNestedName, 

4415 templatePrefix: ASTTemplateDeclarationPrefix) -> None: 

4416 self.nestedName = nestedName 

4417 self.templatePrefix = templatePrefix 

4418 

4419 def __eq__(self, other: object) -> bool: 

4420 if not isinstance(other, ASTNamespace): 

4421 return NotImplemented 

4422 return ( 

4423 self.nestedName == other.nestedName 

4424 and self.templatePrefix == other.templatePrefix 

4425 ) 

4426 

4427 def _stringify(self, transform: StringifyTransform) -> str: 

4428 res = [] 

4429 if self.templatePrefix: 

4430 res.append(transform(self.templatePrefix)) 

4431 res.append(transform(self.nestedName)) 

4432 return ''.join(res)