← board

typinfo facade unit: FPC's RTTI API shapes over OUR blobs

The insight this rests on

Real code does NOT read FPC's RTTI bytes. It reaches RTTI through the typinfo UNIT's record declarations and accessors — GetTypeData, GetPropInfo, GetEnumName, PropType, TTypeKind — and those declarations live inside typinfo. Since we supply typinfo, we choose what the records look like and how they are filled. Therefore: no FPC byte-layout parity, and no fork of any consumer library. (Layout would only leak for code doing pointer arithmetic past the published API — rare; handle it if a corpus target actually does.)

The work

Grow lib/rtl/typinfo.pas from its current enum-only surface into the API FPC consumers actually call:

Honesty rule, as everywhere in this RTL: where a shape cannot be answered, say so at the declaration rather than returning a plausible lie.

Gate

make lib-test + the consumers that motivated it compile (start with generics.defaults, then fpjsonrtti).

Resolution (2026-08-28, frankB)

The API surface is complete and gated. The ticket's second gate clause — "the consumers that motivated it compile" — is NOT met by this and cannot be met from Track B; see the scope note at the end.

What the unit gained

introspection PropType (by PPropInfo and by class), PropIsType, IsPublishedProp, IsStoredProp, TTypeKinds, kind-filtered GetPropList
typed accessors GetFloatProp/SetFloatProp, GetInt64Prop/SetInt64Prop, GetObjectProp/SetObjectProp, GetEnumProp/SetEnumProp (by name), GetSetProp/SetSetProp (by name), SetToString, StringToSet
FPC field spellings TTypeData grew a variant part carrying elSize, MinInt64Value, MaxInt64Value at the same offsets as our ElemSize, MinValue, MaxValue — identical storage, nothing tag-keyed, so it is not the kind-keyed variance the record deliberately avoids

The field-spelling arm exists because of frankA's measurement of vendored rtl-generics: Generics.Defaults's entire typinfo requirement is five TTypeData fields at nine sites, and three of the five were unspellable here — a facade whose field names differ from FPC's is not a facade, since the consumer would need editing, which is the one thing the design promised to avoid.

Diffed against FPC 3.2.2, not assumed

One bug found and fixed underneath it

[[bug-b-rtti-read-of-a-getter-method-property-answers-zero]] — GetOrdProp and GetStrProp handled only direct-field properties and answered 0 / '' for a read METHOD, while the write half already dispatched through setter methods. The facade could not be built on top of that.

One bug found and NOT fixed — it is a compiler defect

[[bug-p-a-class-instance-converts-implicitly-to-any-typed-pointer]] (Track P, filed). pxx lets a class instance convert implicitly to any typed pointer, which FPC rejects outright. Two consequences: a silent memory-safety hole with no cast written, and — the one that bites here — a pointer-taking overload becomes a viable, preferred candidate for a class argument. So the instance-taking overloads (GetPropInfo(AnObject, 'Caption'), the spelling every FPC consumer uses) are declared but never selected: the call binds to the PClassRTTI arm and segfaults.

Those overloads are LEFT IN PLACE as platonic code per the standing rule, with the hazard stated at the declaration so their presence is not read as a promise, and the test routes through GetInstanceRTTI with a note pointing at the ticket. The hazard predates them — the same call bound to the pointer arm and crashed before they existed.

Deliberate omission

FindPropInfo (FPC's raising form of GetPropInfo) is absent: raising needs an Exception class, which needs a uses, and this unit deliberately has none — streams, classes_lite, lfm and all of lib/pcl sit on it. Named at the declaration rather than faked. Revisit deliberately if a corpus target calls it.

Gate

make lib-test green with test/lib_typinfo_props.pas (63 rows) wired in; make demos 35/35. Both against stable v389 (325b4479070a).

Scope note — this does NOT make the generics rung green

Recorded because the dependency graph invited the opposite reading. Per frankA's compile of vendored rtl-generics, typinfo is one of four walls in generics.defaults.pas; two of the others are Track P compiler defects and one is a SysUtils ask filed separately. generics.collections (4,165 lines) is blocked only through defaults and has never been independently assessed, so a second round of findings should be expected. Nothing here was verified against the vendored tree — it is not in this checkout.

Log