# Headers tools/check_header_offsets.py tolerates today, by path.
#
# Modelled on config/layout-known-issues.txt and config/rombuild-exclude.txt: the gate
# is real for anything NEW, and the debt already in the tree is written down instead of
# silently allowed. This list should only ever shrink.
#
# All four were found the moment the tool was first run over the whole tree. It had
# never gated anything -- no workflow and no hook invoked it, and run with no arguments
# it checked nothing and exited 0 -- so none of these had ever been reported.
#
# Format: one repo-relative header path per line. '#' starts a comment.

# --- tool cannot parse the declaration (NOT a layout defect) ----------------------
# A two-word scalar type. DECL reads `unsigned` as the type and `short` as the field
# name, so all four members come back UNPARSED. The offsets in the file are right;
# the parser is what is short. Teaching DECL about `unsigned short`/`unsigned long`
# and friends retires this entry.
include/OamAttr.h

# An anonymous inline aggregate as a member type -- `struct { s32 a; s32 b; } unk_034[3];`.
# AGG matches a struct body with no nested braces, so a member whose type IS a brace
# body cannot be walked. Two members affected.
include/cMgSmartball_slot_c.h

# `T val;` inside a template. There is no width for T until it is instantiated, so
# this is not answerable by textual walk at all and probably never leaves this list.
include/math/Fix12.h

# --- a real disagreement, unresolved ----------------------------------------------
# Four fields sit exactly 3 bytes later than the tool computes (0x4660 vs 0x465d, and
# three pads after it). A constant 3-byte shortfall means one earlier member is modelled
# 3 bytes too small, so either the header's comments or an earlier field's type is wrong.
# Whichever it is, it is a pre-existing question about this header and not something the
# validator work that wired this gate up should have been deciding.
include/dScMgSlot1_c.h

# --- unskipped by the root-vptr change; each is a PARSER limit, not a layout defect ---
# Until this batch landed, tools/check_header_offsets.py bailed out of any ROOT struct
# the moment it saw a method declaration, on the grounds that a polymorphic root's
# implicit vptr made the running offset underivable. It is derivable -- the tree writes
# the model down by hand in dExtFrameCtrl_c.h and dCc_c.h -- so the bail-out is gone and nine
# of the eighteen headers it was hiding now check clean. These nine still do not, each
# for a reason that is about the tool's textual walk and not about the header. Every
# offset comment below is believed correct; none of these is a known layout question.

# `Manager manager;` is fBase_c::Manager -- SceneNode(0x14) + 2 * fLiNdBaPr_c(0x10) =
# 0x34. CLASS_SIZES is keyed by the bare tag, so it answered with
# `Manager_size_must_be_0x3c` from include/Particle__Manager.h, an unrelated
# Particle::Manager, and reported the two fields after it 8 bytes late -- against a
# header whose own `fBase_c_size_must_be_0x50` proves the comments right. The gate now
# refuses instead of guessing (see _shadowed_by_nested). Deriving a local size for a
# nested body that carries inline method definitions retires this entry.
include/fBase_c.h

# A pointer to MEMBER function -- `typedef void (dMgState_c::*Callback)();` -- is 8
# bytes on this ABI, not 4, and DECL has no notion of one. Three members each.
include/dMgState_c.h
include/dMg3DEspModel_c.h

# RETIRED from this list: include/dMgPsOpt_c.h. The lookup now reads the qualified
# name out of the assertion's own sizeof() operand instead of trying to derive it from
# the typedef identifier, so `dMgPsOpt_c::TouchIcon_c` resolves and the header walks to
# `struct spans 0x128` -- exactly its own dMgPsOpt_c_size_must_be_0x128.

# `class X : public Y {` nested inside dPa_c. The nested-type consumer matches `struct`
# only, so the body is not consumed and its `public:` falls through as a declaration.
include/dPa_c.h

# `struct anmModel_c : param_c, dExtAnmModel_c {` nested inside daDemo_c. The
# nested-type consumer allows exactly one base, so it does not match.
include/daDemo_c.h

# `CLPS_BlockRef &operator=(CLPS_Block &block);`. The method-declaration pattern's type
# character class has no `=` in it, so an assignment operator is not recognised as a
# method and is read as a field.
include/CLPS_BlockRef.h

# A function-POINTER member split across three lines (`void (*beforeClsnCallback)(...)`
# with its parameter list wrapped). DECL is line-at-a-time.
include/dBgW.h

# Inline-DEFINED structors -- `dThIcon_c() {}`. The method-declaration pattern requires
# a trailing `;`, which a defined-in-place body does not have, so both lines fall
# through to DECL. Note the field list here is empty, so nothing is left unchecked.
include/dThIcon_c.h
