4 * Copyright 2020 Zebediah Figura for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #ifndef __VKD3D_SHADER_PREPROC_H
22 #define __VKD3D_SHADER_PREPROC_H
24 #include "vkd3d_shader_private.h"
27 struct preproc_if_state
29 /* Are we currently in a "true" block? */
31 /* Have we seen a "true" block in this #if..#endif yet? */
33 /* Have we seen an #else yet? */
40 struct vkd3d_shader_location location
;
45 struct preproc_buffer buffer
;
46 struct vkd3d_shader_code code
;
49 struct preproc_if_state
*if_stack
;
50 size_t if_count
, if_stack_size
;
55 struct vkd3d_string_buffer text
;
56 struct vkd3d_shader_location location
;
59 struct preproc_expansion
61 struct preproc_buffer buffer
;
62 const struct preproc_text
*text
;
63 /* Back-pointer to the macro, if this expansion a macro body. This is
64 * necessary so that argument tokens can be correctly replaced. */
65 struct preproc_macro
*macro
;
70 struct rb_entry entry
;
75 struct preproc_text
*arg_values
;
77 struct preproc_text body
;
82 const struct vkd3d_shader_preprocess_info
*preprocess_info
;
85 struct vkd3d_shader_message_context
*message_context
;
86 struct vkd3d_string_buffer buffer
;
88 struct preproc_file
*file_stack
;
89 size_t file_count
, file_stack_size
;
91 struct preproc_expansion
*expansion_stack
;
92 size_t expansion_count
, expansion_stack_size
;
94 struct rb_tree macros
;
96 /* It's possible to parse as many as two function-like macros at once: one
97 * in the main text, and another inside of #if directives. E.g.
104 * It's not possible to parse more than two, however. In the case of nested
105 * calls like "func1(func2(...))", we store everything inside the outer
106 * parentheses as unparsed text, and then parse it once the argument is
109 struct preproc_func_state
111 struct preproc_macro
*macro
;
119 unsigned int paren_depth
;
120 } text_func
, directive_func
;
122 int current_directive
;
126 bool last_was_newline
;
128 bool last_was_defined
;
133 bool preproc_add_macro(struct preproc_ctx
*ctx
, const struct vkd3d_shader_location
*loc
, char *name
, char **arg_names
,
134 size_t arg_count
, const struct vkd3d_shader_location
*body_loc
, struct vkd3d_string_buffer
*body
);
135 void preproc_close_include(struct preproc_ctx
*ctx
, const struct vkd3d_shader_code
*code
);
136 struct preproc_macro
*preproc_find_macro(struct preproc_ctx
*ctx
, const char *name
);
137 void preproc_free_macro(struct preproc_macro
*macro
);
138 bool preproc_push_include(struct preproc_ctx
*ctx
, char *filename
, const struct vkd3d_shader_code
*code
);
139 void preproc_warning(struct preproc_ctx
*ctx
, const struct vkd3d_shader_location
*loc
,
140 enum vkd3d_shader_error error
, const char *format
, ...) VKD3D_PRINTF_FUNC(4, 5);
142 static inline struct preproc_file
*preproc_get_top_file(struct preproc_ctx
*ctx
)
144 assert(ctx
->file_count
);
145 return &ctx
->file_stack
[ctx
->file_count
- 1];