2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * \file slang_assemble_typeinfo.c
32 #include "slang_utility.h"
33 #include "slang_assemble_typeinfo.h"
35 /* slang_assembly_typeinfo */
37 void slang_assembly_typeinfo_construct (slang_assembly_typeinfo
*ti
)
39 slang_type_specifier_construct (&ti
->spec
);
42 void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo
*ti
)
44 slang_type_specifier_destruct (&ti
->spec
);
47 /* _slang_typeof_operation() */
49 int _slang_typeof_operation (slang_operation
*op
, slang_assembly_name_space
*space
,
50 slang_assembly_typeinfo
*ti
)
52 ti
->can_be_referenced
= 0;
57 case slang_oper_block_no_new_scope
:
58 case slang_oper_block_new_scope
:
59 case slang_oper_variable_decl
:
61 case slang_oper_break
:
62 case slang_oper_continue
:
63 case slang_oper_discard
:
64 case slang_oper_return
:
66 case slang_oper_while
:
70 ti
->spec
.type
= slang_spec_void
;
72 case slang_oper_expression
:
73 case slang_oper_assign
:
74 case slang_oper_addassign
:
75 case slang_oper_subassign
:
76 case slang_oper_mulassign
:
77 case slang_oper_divassign
:
78 case slang_oper_preincrement
:
79 case slang_oper_predecrement
:
80 if (!_slang_typeof_operation (op
->children
, space
, ti
))
83 case slang_oper_literal_bool
:
84 case slang_oper_logicalor
:
85 case slang_oper_logicalxor
:
86 case slang_oper_logicaland
:
87 case slang_oper_equal
:
88 case slang_oper_notequal
:
90 case slang_oper_greater
:
91 case slang_oper_lessequal
:
92 case slang_oper_greaterequal
:
94 ti
->spec
.type
= slang_spec_bool
;
96 case slang_oper_literal_int
:
97 ti
->spec
.type
= slang_spec_int
;
99 case slang_oper_literal_float
:
100 ti
->spec
.type
= slang_spec_float
;
102 case slang_oper_identifier
:
106 var
= _slang_locate_variable (op
->locals
, op
->identifier
, 1);
109 if (!slang_type_specifier_copy (&ti
->spec
, &var
->type
.specifier
))
111 ti
->can_be_referenced
= 1;
114 case slang_oper_sequence
:
115 /* TODO: check [0] and [1] if they match */
116 if (!_slang_typeof_operation (op
->children
+ 1, space
, ti
))
118 ti
->can_be_referenced
= 0;
121 /*case slang_oper_modassign:*/
122 /*case slang_oper_lshassign:*/
123 /*case slang_oper_rshassign:*/
124 /*case slang_oper_orassign:*/
125 /*case slang_oper_xorassign:*/
126 /*case slang_oper_andassign:*/
127 case slang_oper_select
:
128 /* TODO: check [1] and [2] if they match */
129 if (!_slang_typeof_operation (op
->children
+ 1, space
, ti
))
131 ti
->can_be_referenced
= 0;
134 /*case slang_oper_bitor:*/
135 /*case slang_oper_bitxor:*/
136 /*case slang_oper_bitand:*/
137 /*case slang_oper_lshift:*/
138 /*case slang_oper_rshift:*/
142 if (!_slang_typeof_function ("+", op
->children
, 2, space
, &ti
->spec
, &exists
))
148 case slang_oper_subtract
:
151 if (!_slang_typeof_function ("-", op
->children
, 2, space
, &ti
->spec
, &exists
))
157 case slang_oper_multiply
:
160 if (!_slang_typeof_function ("*", op
->children
, 2, space
, &ti
->spec
, &exists
))
166 case slang_oper_divide
:
169 if (!_slang_typeof_function ("/", op
->children
, 2, space
, &ti
->spec
, &exists
))
175 /*case slang_oper_modulus:*/
176 case slang_oper_plus
:
179 if (!_slang_typeof_function ("+", op
->children
, 1, space
, &ti
->spec
, &exists
))
185 case slang_oper_minus
:
188 if (!_slang_typeof_function ("-", op
->children
, 1, space
, &ti
->spec
, &exists
))
194 /*case slang_oper_complement:*/
195 case slang_oper_subscript
:
197 slang_assembly_typeinfo _ti
;
198 slang_assembly_typeinfo_construct (&_ti
);
199 if (!_slang_typeof_operation (op
->children
, space
, &_ti
))
201 slang_assembly_typeinfo_destruct (&_ti
);
204 ti
->can_be_referenced
= _ti
.can_be_referenced
;
205 switch (_ti
.spec
.type
)
207 case slang_spec_bvec2
:
208 case slang_spec_bvec3
:
209 case slang_spec_bvec4
:
210 ti
->spec
.type
= slang_spec_bool
;
212 case slang_spec_ivec2
:
213 case slang_spec_ivec3
:
214 case slang_spec_ivec4
:
215 ti
->spec
.type
= slang_spec_int
;
217 case slang_spec_vec2
:
218 case slang_spec_vec3
:
219 case slang_spec_vec4
:
220 ti
->spec
.type
= slang_spec_float
;
222 case slang_spec_mat2
:
223 ti
->spec
.type
= slang_spec_vec2
;
225 case slang_spec_mat3
:
226 ti
->spec
.type
= slang_spec_vec3
;
228 case slang_spec_mat4
:
229 ti
->spec
.type
= slang_spec_vec4
;
231 case slang_spec_array
:
232 if (!slang_type_specifier_copy (&ti
->spec
, _ti
.spec
._array
))
234 slang_assembly_typeinfo_destruct (&_ti
);
239 slang_assembly_typeinfo_destruct (&_ti
);
242 slang_assembly_typeinfo_destruct (&_ti
);
245 case slang_oper_call
:
248 if (!_slang_typeof_function (op
->identifier
, op
->children
, op
->num_children
, space
,
253 slang_struct
*s
= slang_struct_scope_find (space
->structs
, op
->identifier
, 1);
256 ti
->spec
.type
= slang_spec_struct
;
257 ti
->spec
._struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
258 if (ti
->spec
._struct
== NULL
)
260 if (!slang_struct_construct (ti
->spec
._struct
))
262 slang_alloc_free (ti
->spec
._struct
);
263 ti
->spec
._struct
= NULL
;
266 if (!slang_struct_copy (ti
->spec
._struct
, s
))
271 slang_type_specifier_type type
= slang_type_specifier_type_from_string (
273 if (type
== slang_spec_void
)
275 ti
->spec
.type
= type
;
280 case slang_oper_field
:
282 slang_assembly_typeinfo _ti
;
283 slang_assembly_typeinfo_construct (&_ti
);
284 if (!_slang_typeof_operation (op
->children
, space
, &_ti
))
286 slang_assembly_typeinfo_destruct (&_ti
);
289 if (_ti
.spec
.type
== slang_spec_struct
)
291 slang_variable
*field
= _slang_locate_variable (_ti
.spec
._struct
->fields
,
295 slang_assembly_typeinfo_destruct (&_ti
);
298 if (!slang_type_specifier_copy (&ti
->spec
, &field
->type
.specifier
))
300 slang_assembly_typeinfo_destruct (&_ti
);
307 switch (_ti
.spec
.type
)
309 case slang_spec_vec2
:
310 case slang_spec_ivec2
:
311 case slang_spec_bvec2
:
314 case slang_spec_vec3
:
315 case slang_spec_ivec3
:
316 case slang_spec_bvec3
:
319 case slang_spec_vec4
:
320 case slang_spec_ivec4
:
321 case slang_spec_bvec4
:
325 slang_assembly_typeinfo_destruct (&_ti
);
328 if (!_slang_is_swizzle (op
->identifier
, rows
, &ti
->swz
))
331 ti
->can_be_referenced
= _ti
.can_be_referenced
&& _slang_is_swizzle_mask (&ti
->swz
,
336 _slang_multiply_swizzles (&swz
, &_ti
.swz
, &ti
->swz
);
339 switch (_ti
.spec
.type
)
341 case slang_spec_vec2
:
342 case slang_spec_vec3
:
343 case slang_spec_vec4
:
344 switch (ti
->swz
.num_components
)
347 ti
->spec
.type
= slang_spec_float
;
350 ti
->spec
.type
= slang_spec_vec2
;
353 ti
->spec
.type
= slang_spec_vec3
;
356 ti
->spec
.type
= slang_spec_vec4
;
360 case slang_spec_ivec2
:
361 case slang_spec_ivec3
:
362 case slang_spec_ivec4
:
363 switch (ti
->swz
.num_components
)
366 ti
->spec
.type
= slang_spec_int
;
369 ti
->spec
.type
= slang_spec_ivec2
;
372 ti
->spec
.type
= slang_spec_ivec3
;
375 ti
->spec
.type
= slang_spec_ivec4
;
379 case slang_spec_bvec2
:
380 case slang_spec_bvec3
:
381 case slang_spec_bvec4
:
382 switch (ti
->swz
.num_components
)
385 ti
->spec
.type
= slang_spec_bool
;
388 ti
->spec
.type
= slang_spec_bvec2
;
391 ti
->spec
.type
= slang_spec_bvec3
;
394 ti
->spec
.type
= slang_spec_bvec4
;
402 slang_assembly_typeinfo_destruct (&_ti
);
406 case slang_oper_postincrement
:
407 case slang_oper_postdecrement
:
408 if (!_slang_typeof_operation (op
->children
, space
, ti
))
410 ti
->can_be_referenced
= 0;
419 /* _slang_typeof_function() */
421 int _slang_typeof_function (const char *name
, slang_operation
*params
, unsigned int num_params
,
422 slang_assembly_name_space
*space
, slang_type_specifier
*spec
, int *exists
)
424 slang_function
*fun
= _slang_locate_function (name
, params
, num_params
, space
);
425 *exists
= fun
!= NULL
;
428 return slang_type_specifier_copy (spec
, &fun
->header
.type
.specifier
);