Skip to content

Commit ebdf420

Browse files
committed
feat(generator): coalesce consecutive identical #ifdef/#endif blocks in generated header
Introduce ProtectedGroup<T> in the resolver to group consecutive items that share the same platform protection macros. A single O(n) pass over each item list (types, extensions, commands) merges adjacent runs into one group, which the header template emits as a single #ifdef/#endif pair instead of one per item. Applies to all six protection-guarded sections in the header: include types, non-include types, extension compile-time guards, extension presence macros, PFN typedefs, and IntelliSense/dispatch macros. The context struct pfnArray union also benefits: a protected group emits all typed members under one #ifdef, all pads under one #else, and one #endif — replacing per-slot #ifdef/#else/#endif triples. For a full Vulkan build this eliminates hundreds of redundant preprocessor blocks. No semantic change to the generated code. Signed-off-by: Steven Noonan <steven@uplinklabs.net>
1 parent 1e405a4 commit ebdf420

3 files changed

Lines changed: 249 additions & 43 deletions

File tree

src/generator/c/templates/header.h.j2

Lines changed: 69 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,16 @@
6969

7070
{# Platform / WSI system headers: include-category types whose protection
7171
guards were inferred at generation time from which extensions require them.
72-
An empty protect list means the include is unconditional. #}
73-
{%- for type in fs.types -%}
74-
{% if type.category == "include" and type.raw_c -%}
75-
{{ u.protect_begin(type.protect) -}}
72+
An empty protect list means the include is unconditional.
73+
Consecutive types sharing the same guard are coalesced into a single
74+
#ifdef/#endif block by the resolver. #}
75+
{%- for group in fs.include_type_groups -%}
76+
{{ u.protect_begin(group.protect) -}}
77+
{% for type in group.items -%}
7678
{{ type.raw_c }}
77-
{{ u.protect_end(type.protect) -}}
78-
{% endif -%}
79-
{%- endfor %}
79+
{% endfor -%}
80+
{{ u.protect_end(group.protect) -}}
81+
{% endfor %}
8082
#ifdef __cplusplus
8183
extern "C" {
8284
#endif
@@ -131,15 +133,17 @@ struct _cl_event;
131133
#define {{ feat.full_name }} 1
132134
{% endfor -%}
133135
{% endif -%}
134-
{%- if not fs.is_vulkan and fs.extensions | length > 0 %}
136+
{%- if not fs.is_vulkan and fs.ext_guard_groups | length > 0 %}
135137
/* ---- Extension compile-time guards ---------------------------------------
136138
These mirror the definitions in standard glext.h/gl2ext.h/eglext.h so
137139
that code guarded by e.g. #ifdef GL_ARB_draw_indirect compiles correctly
138140
against this header. */
139-
{% for ext in fs.extensions %}
140-
{{- u.protect_begin(ext.protect) -}}
141+
{% for group in fs.ext_guard_groups -%}
142+
{{- u.protect_begin(group.protect) -}}
143+
{% for ext in group.items -%}
141144
#define {{ ext.name }} 1
142-
{{ u.protect_end(ext.protect) -}}
145+
{% endfor -%}
146+
{{ u.protect_end(group.protect) -}}
143147
{%- endfor %}
144148
{% endif -%}
145149
{%- if fs.flat_enums | length > 0 -%}
@@ -181,28 +185,41 @@ typedef enum {{ group.name }} {
181185
{% endfor -%}
182186
{% endif %}
183187
/* ---- Types ----------------------------------------------------------------
184-
Emitted in topological dependency order. */
185-
{% for type in fs.types -%}
186-
{%- if type.category != "include" and type.raw_c %}
187-
{{ u.protect_begin(type.protect if type.protect else []) -}}
188+
Emitted in topological dependency order. Consecutive types sharing the
189+
same platform guard are coalesced into a single #ifdef/#endif block. */
190+
{% for group in fs.type_groups -%}
191+
{% if group.protect | length > 0 -%}
192+
#if defined({{ group.protect | join(") && defined(") }})
193+
{% endif -%}
194+
{% for type in group.items -%}
188195
{{ type.raw_c }}
189-
{{ u.protect_end(type.protect if type.protect else []) -}}
196+
{% if not loop.last %}
197+
{% endif -%}
198+
{% endfor -%}
199+
{% if group.protect | length > 0 -%}
200+
#endif
201+
{% endif -%}
202+
{% if not loop.last %}
190203
{% endif -%}
191204
{% endfor %}
192205

193206
/* ---- PFN typedefs -------------------------------------------------------- */
194207
{% if fs.is_gl_family -%}
195-
{% for cmd in fs.commands -%}
196-
{{ u.cmd_protect_begin(cmd) -}}
208+
{% for group in fs.cmd_pfn_groups -%}
209+
{{- u.protect_begin(group.protect) -}}
210+
{% for cmd in group.items -%}
197211
typedef {{ cmd.return_type }} (APIENTRYP {{ cmd.pfn_type }})({{ cmd.params_str }});
198-
{{ u.cmd_protect_end(cmd) }}
199-
{%- endfor %}
212+
{% endfor -%}
213+
{{ u.protect_end(group.protect) -}}
214+
{% endfor -%}
200215
{% else %}
201-
{% for cmd in fs.commands %}
202-
{{ u.cmd_protect_begin(cmd) -}}
216+
{% for group in fs.cmd_pfn_groups -%}
217+
{{- u.protect_begin(group.protect) -}}
218+
{% for cmd in group.items -%}
203219
typedef {{ cmd.return_type }} (VKAPI_PTR *{{ cmd.pfn_type }})({{ cmd.params_str }});
204-
{{- u.cmd_protect_end(cmd) }}
205-
{% endfor %}
220+
{% endfor -%}
221+
{{- u.protect_end(group.protect) -}}
222+
{% endfor -%}
206223
{% endif %}
207224

208225
/* ---- Context struct ------------------------------------------------------
@@ -236,15 +253,21 @@ typedef struct {{ fs.context_name }} {
236253
union {
237254
void *pfnArray[{{ fs.commands | length }}];
238255
struct {
239-
{%- for cmd in fs.commands %}
240-
{%- if cmd.protect %}
241-
#ifdef {{ cmd.protect }}
256+
{%- for group in fs.cmd_pfn_groups %}
257+
{%- if group.protect | length > 0 %}
258+
#if defined({{ group.protect | join(") && defined(") }})
259+
{%- for cmd in group.items %}
242260
/* {{ cmd.index | rjust(4) }} */ {{ cmd.pfn_type }} {{ cmd.short_name }};
261+
{%- endfor %}
243262
#else
263+
{%- for cmd in group.items %}
244264
/* {{ cmd.index | rjust(4) }} */ void *_pad{{ cmd.index }};
245-
#endif /* {{ cmd.protect }} */
246-
{% else %}
265+
{%- endfor %}
266+
#endif
267+
{%- else %}
268+
{%- for cmd in group.items %}
247269
/* {{ cmd.index | rjust(4) }} */ {{ cmd.pfn_type }} {{ cmd.short_name }};
270+
{%- endfor %}
248271
{%- endif %}
249272
{%- endfor %}
250273
};
@@ -280,28 +303,34 @@ extern {{ fs.context_name }} gloam_{{ fs.spec_name }}_context;
280303
{%- endfor %}
281304

282305
/* ---- Extension presence macros ------------------------------------------ */
283-
{% for ext in fs.extensions %}
284-
{{- u.protect_begin(ext.protect) -}}
306+
{% for group in fs.ext_guard_groups %}
307+
{{- u.protect_begin(group.protect) -}}
308+
{% for ext in group.items -%}
285309
#define GLOAM_{{ ext.name }} (gloam_{{ fs.spec_name }}_context.{{ ext.short_name | c_ident }})
286-
{{ u.protect_end(ext.protect) -}}
310+
{% endfor -%}
311+
{{- u.protect_end(group.protect) -}}
287312
{%- endfor %}
288313

289314
/* ---- Dispatch macros and IntelliSense prototypes -------------------------
290315
Under __INTELLISENSE__ we expose real function declarations so IDEs can
291316
provide parameter info and type checking. In normal compilation the macros
292317
dispatch directly through the global context struct. */
293318
#ifdef __INTELLISENSE__
294-
{%- for cmd in fs.commands %}
295-
{{ u.cmd_protect_begin(cmd) -}}
319+
{%- for group in fs.cmd_pfn_groups -%}
320+
{{- u.protect_begin(group.protect) -}}
321+
{%- for cmd in group.items -%}
296322
{{ cmd.return_type }} {{ cmd.name }}({{ cmd.params_str }});
297-
{{- u.cmd_protect_end(cmd) }}
298-
{%- endfor %}
323+
{% endfor -%}
324+
{{- u.protect_end(group.protect) }}
325+
{%- endfor -%}
299326
#else
300-
{%- for cmd in fs.commands %}
301-
{{ u.cmd_protect_begin(cmd) -}}
327+
{%- for group in fs.cmd_pfn_groups -%}
328+
{{- u.protect_begin(group.protect) -}}
329+
{%- for cmd in group.items -%}
302330
#define {{ cmd.name }} (gloam_{{ fs.spec_name }}_context.{{ cmd.short_name }})
303-
{{- u.cmd_protect_end(cmd) }}
304-
{%- endfor %}
331+
{% endfor -%}
332+
{{- u.protect_end(group.protect) }}
333+
{%- endfor -%}
305334
#endif /* __INTELLISENSE__ */
306335

307336
/* ---- API declarations ---------------------------------------------------- */
@@ -405,4 +434,3 @@ void gloamLoaderResetVulkan(void);
405434
#endif /* _WIN32 */
406435
{% endif %}
407436
#endif /* GLOAM_{{ guard }} */
408-

src/generator/c/templates/utils.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
Emits nothing when the list is empty.
1818
-#}
1919
{%- macro protect_begin(protects) -%}
20-
{%- if protects | length > 0 %}
20+
{%- if protects | length > 0 -%}
2121
#if {% for p in protects %}defined({{ p }}){% if not loop.last %} || {% endif %}{% endfor %}
2222
{% endif -%}
2323
{%- endmacro -%}

0 commit comments

Comments
 (0)