(cl: ClassIR, emitter: Emitter)
| 435 | |
| 436 | |
| 437 | def generate_object_struct(cl: ClassIR, emitter: Emitter) -> None: |
| 438 | seen_attrs: set[str] = set() |
| 439 | lines: list[str] = [] |
| 440 | lines += ["typedef struct {", "PyObject_HEAD", "CPyVTableItem *vtable;"] |
| 441 | if cl.has_method("__call__"): |
| 442 | lines.append("vectorcallfunc vectorcall;") |
| 443 | bitmap_attrs = [] |
| 444 | for base in reversed(cl.base_mro): |
| 445 | if not base.is_trait: |
| 446 | if base.bitmap_attrs: |
| 447 | # Do we need another attribute bitmap field? |
| 448 | if emitter.bitmap_field(len(base.bitmap_attrs) - 1) not in bitmap_attrs: |
| 449 | for i in range(0, len(base.bitmap_attrs), BITMAP_BITS): |
| 450 | attr = emitter.bitmap_field(i) |
| 451 | if attr not in bitmap_attrs: |
| 452 | lines.append(f"{BITMAP_TYPE} {attr};") |
| 453 | bitmap_attrs.append(attr) |
| 454 | for attr, rtype in base.attributes.items(): |
| 455 | # Generated class may redefine certain attributes with different |
| 456 | # types in subclasses (this would be unsafe for user-defined classes). |
| 457 | if attr not in seen_attrs: |
| 458 | lines.append(f"{emitter.ctype_spaced(rtype)}{emitter.attr(attr)};") |
| 459 | seen_attrs.add(attr) |
| 460 | |
| 461 | if isinstance(rtype, RTuple): |
| 462 | emitter.declare_tuple_struct(rtype) |
| 463 | |
| 464 | lines.append(f"}} {cl.struct_name(emitter.names)};") |
| 465 | lines.append("") |
| 466 | emitter.context.declarations[cl.struct_name(emitter.names)] = HeaderDeclaration( |
| 467 | lines, is_type=True |
| 468 | ) |
| 469 | |
| 470 | |
| 471 | def generate_vtables( |
no test coverage detected
searching dependent graphs…