Skip to content

Tsbindgen cpp classes - #562

Merged
ASDAlexander77 merged 2 commits into
mainfrom
tsbindgen-cpp-classes
Oct 12, 2026
Merged

ASDAlexander77 merged 2 commits into
mainfrom
tsbindgen-cpp-classes

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

No description provided.

ASDAlexander77 and others added 2 commits October 12, 2026 21:42
tsbindgen left every C++ class out (a pointer to one was Opaque), so a
C++ interface needed an extern "C" wrapper per method, or a @cpp class
written by hand with its slots counted from the compiler's layout report.

A polymorphic class, in any namespace, is now a @cpp class, when it has
the layout one has: not a template, at most one base, itself bound and
not virtual, on a 64-bit target.

- Its virtual methods are @slot(N), N from clang's vtable layout for
  the target's ABI (MicrosoftVTableContext / ItaniumVTableContext), so
  MSVC's single destructor slot and reversed overloads, and the Itanium
  ABI's two destructors, come out as the compilers number them. Only
  the methods a class introduces are declared: an override keeps its
  base's slot by name. Destructors and methods that aren't public are
  slots left out.
- Its non-virtual methods are @Linkname with the mangled symbol clang's
  MangleContext gives; an inline one (no symbol) is skipped.
- Overloads get `_2`, `_3`, ... in declaration order, the same on
  every ABI.
- A record returned by value is an inline tuple with its layout (an
  8-byte union of pointers and integers, such as nvrhi::Object, one
  field), @cppnontrivial when clang can't pass it in registers; on the
  Itanium ABI a trivial one other than one or two 8-byte integer or
  pointer fields is skipped, as tslang can't return it. A class
  template specialization only named as a result (RefCountPtr<IBuffer>)
  is instantiated through Sema to get there.
- Fields are declared when they are where a @cpp class puts them: after
  the vtable pointer and the base's storage, padded to its alignment
  (the Itanium ABI's use of a base's tail padding leaves them out).

The type mapping learns C++ references (as pointers), a pointer or a
reference to a bound class (the class), and enums and typedefs in a
namespace or a class (their integer type, where a dangling name was
printed before).

Checked against the compilers on NVRHI's nvrhi.h: the 160 slots
generated for 23 interfaces for x86_64-pc-windows-msvc are those of
cl /d1reportSingleClassLayout, and the 152 checked for
x86_64-linux-android29 and aarch64-linux-android29 those of the NDK
clang's -fdump-vtable-layouts; the generated bindings compile.

Tests: CppClassTest.cpp (slots for both ABIs taken from cl and clang,
symbols, records, parameter types, fields, unbound classes, --filter),
and test-bindgen-cpp, which builds fixture_cpp.cpp with the in-tree
clang and calls it through the generated bindings, linked and under
the JIT. README and docs/cpp-classes.md describe it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit af6564a into main Oct 12, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the tsbindgen-cpp-classes branch October 12, 2026 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant