Repository navigation
tsbindgen: a template's specializations are one generic tuple - #565
Merged
Merged
Conversation
A field holding a class template's specialization was declared once per specialization, named by its arguments (static_vector_IBindingSet_8, RefCountPtr_IShader, and std::vector's per element type with MSVC's helper structs). It is now an instance of one generic tuple per template: static_vector8<IBindingSet | null> with `type static_vector8<T> = [_Elems: [_0: T, ...], current_size: index]`. TypeMapper::genericInstance lays the specialization out as before, then writes it in terms of its type arguments: a part of the layout that is an argument's mapped type is its parameter (a @cpp class argument's pointers too, `T | null`), and a nested specialization holding one is inlined (MSVC's std::vector through _Compressed_pair and _Vector_val). Integer arguments go into the name; defaulted ones (an allocator) are left out. A specialization stays declared on its own, named by its arguments, when its layout doesn't show a type argument (std::string's characters are raw words: basic_string_char) or differs from its template's other specializations' (an explicit specialization). TsType's named types carry type arguments; the printer writes a generic's parameters. A specialization's declaration is no longer a selection seed: it is printed only for what refers to it, so the inlined helpers are not. `Ref` is one of tslang's type names, so a template named Ref is written Ref_. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A field holding a class template's specialization used to declare that specialization on its own, named by its arguments:
static_vector_IBindingSet_8,RefCountPtr_IShader, and avector_Xper element type with MSVC's helper structs. It is now an instance of one generic tuple per template.What changes
Generic instances.
nvrhi::static_vector<IBindingSet *, 8>isstatic_vector8<IBindingSet | null>, withtype static_vector8<T> = [_Elems: [_0: T, ...], current_size: index].RefCountPtr<IShader>isRefCountPtr<IShader>, withtype RefCountPtr<T> = [ptr_: T | null].MSVC's
std::vector<T>collapses: its pointers live two specializations down (_Compressed_pair, then_Vector_val<_Simple_types<T>>), and those helpers are inlined. The result istype vector<T> = [_Mypair: [_Myval2: [_Myfirst: Reference<T> | null, ...]]], and the helpers are no longer printed. libc++'s is[__begin_: Reference<T> | null, ...].How (
TypeMapper::genericInstance): the specialization is laid out exactly as before, then rewritten in terms of its type arguments.@cppclass argument this covers its pointers too, asT | null.static_vector8). Defaulted ones, such as an allocator, are left out.Fallback to the concrete name: a specialization keeps its own declaration, named by its arguments, in two cases:
std::string's characters are raw words, so it staysbasic_string_char;This check is what keeps every instance's layout identical to clang's.
Selection: a specialization's declaration is no longer a seed; it is printed only for what refers to it.
Naming:
Refjoins tslang's type names, so a template namedRefis writtenRef_instead of shadowing tslang'sRef<T>.TsType: named types carry type arguments, and the printer writes a generic's parameters.Also adds issue 13 to
TSLANG_ISSUES.md: tslang doesn't inferTfrom an argument of a generic tuple alias (count(v)withv: Vec<Item>); passingTexplicitly works.Tests
LayoutTest:SpecializationHeldByValueupdated (static_vector2<Item | null>,Ref_<Item>);MsvcShapedVectorIsOneGeneric: two element types give onevector<T>, and no helper struct is printed;SpecializationThatIsNoInstance: an explicit specialization, and a template whose layout doesn't show its argument;std::stringstaysbasic_string_char.NamespacedStructTestupdated (Vec<s32>). 78/78 pass.ctest -R bindgen: 4/4. Intest-bindgen-cpp, the fixture'sBatchnow holds aSmallVec3<Shape | null>, passed to compiled C++.char's sign): the generics match what native_ts_graphics'gen_nvrhi_classes.pywrote, and its regenerated files are byte for byte the committed ones (NVRHI's template specializations are generic tuples native_ts_graphics#59, #60).🤖 Generated with Claude Code