From 682e9b75b9dc14340c5aa6afb52fac48b3f34217 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Wed, 13 May 2026 11:56:51 +0200 Subject: [PATCH 1/2] Prepend a stdbool stub when invoking libclang on MEOS headers MEOS public headers reference bool but do not include stdbool.h; when libclang parses them without system header paths it silently demotes every bool return and bool * pointer to int / int *, losing the distinction that every binding depends on. Prepending a minimal stub with `#define bool _Bool` (plus the size_t typedef libclang needs to honour the WKB-size accessors) keeps the spelling intact, and a regex-based normaliser in _c_spelling rewrites the resulting `_Bool *` back to `bool *` so the IDL matches the source code. Before the fix all 641 bool-returning functions and the bool * out-parameters of tbox_*_inc / tbool_value_at_timestamptz / tbool_value_n / tbool_values landed in meos-idl.json as int. --- parser/extractors.py | 10 ++++++---- parser/parser.py | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/parser/extractors.py b/parser/extractors.py index a5855e9..1b63588 100644 --- a/parser/extractors.py +++ b/parser/extractors.py @@ -19,16 +19,18 @@ def _canonical_spelling(ty) -> str: _BOOL_SPELLINGS = {"bool", "_Bool"} +_BOOL_TOKEN_RE = re.compile(r"\b_Bool\b") + + def _c_spelling(ty) -> str: # Return the declared C spelling, with ``_Bool`` normalised to ``"bool"``. # Two bool representations arise depending on which postgres_int_defs.h is # in play: # - PostgreSQL headers: ``typedef char bool`` -> spelling already ``"bool"`` # - Stub header: ``#define bool _Bool`` -> spelling is ``"_Bool"`` - spelling = ty.spelling - if spelling == "_Bool": - return "bool" - return spelling + # Compound types preserve the inner spelling, so ``bool *`` arrives as + # ``_Bool *``; substitute on the token rather than the whole string. + return _BOOL_TOKEN_RE.sub("bool", ty.spelling) def _canonical_c_spelling(ty) -> str: diff --git a/parser/parser.py b/parser/parser.py index b19201c..88f0ec4 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -94,8 +94,26 @@ def _dedup(items: list) -> list: return resolve_idl_types(idl, mappings_path) +# Minimal stand-in for system headers so libclang does not fall back to +# treating undeclared identifiers as int. stdbool.h is the load-bearing one: +# without it every `bool`-returning function is parsed with result_type +# TypeKind.INT. +_SYSTEM_HEADER_STUBS = """ +#ifndef bool +#define bool _Bool +#endif +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif +typedef unsigned long size_t; +""" + + def build_entry_point(headers_dir: Path) -> str: - lines = [] + lines = [_SYSTEM_HEADER_STUBS] for h in sorted(headers_dir.glob("**/*.h")): lines.append(f'#include "{h.resolve()}"') return "\n".join(lines) From fd83b2825af641f8c54f422dd7f66b148b287b68 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Sun, 17 May 2026 00:33:27 +0200 Subject: [PATCH 2/2] Stub postgres integer typedefs so int64 is not implicit int Without a real pg_config.h, postgres/c.h never typedefs int64, so int64 and every type built on it (TimestampTz, Timestamp, TimeADT, DateADT) collapsed to implicit int and timestamp parameters were emitted 32-bit. Extend the system-header stub with the postgres integer family, mirroring postgres/c.h (LP64 branch), timestamp_def.h and date.h exactly. --- parser/parser.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/parser/parser.py b/parser/parser.py index 88f0ec4..5dd3d44 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -98,6 +98,13 @@ def _dedup(items: list) -> list: # treating undeclared identifiers as int. stdbool.h is the load-bearing one: # without it every `bool`-returning function is parsed with result_type # TypeKind.INT. +# +# The postgres integer typedefs are the same hazard: without a real +# pg_config.h, postgres/c.h never typedefs int64, so int64 (and every +# type built on it: TimestampTz, Timestamp, TimeADT, DateADT, ...) +# collapses to implicit int and timestamp parameters are emitted 32-bit. +# These mirror MobilityDB's postgres/c.h (LP64 branch), timestamp_def.h +# and date.h exactly. _SYSTEM_HEADER_STUBS = """ #ifndef bool #define bool _Bool @@ -109,6 +116,21 @@ def _dedup(items: list) -> list: #define false 0 #endif typedef unsigned long size_t; +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; +typedef long int int64; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned long int uint64; +typedef float float4; +typedef double float8; +typedef int64 Timestamp; +typedef int64 TimestampTz; +typedef int64 TimeADT; +typedef int64 TimeOffset; +typedef int32 DateADT; """