ReactOS 0.4.16-dev-1946-g52006dd
expr.c File Reference
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include "widl.h"
#include "utils.h"
#include "expr.h"
#include "header.h"
#include "typetree.h"
#include "typegen.h"
Include dependency graph for expr.c:

Go to the source code of this file.

Classes

struct  expression_type
 

Functions

static int is_integer_type (const type_t *type)
 
static int is_signed_integer_type (const type_t *type)
 
static int is_float_type (const type_t *type)
 
expr_tmake_expr (enum expr_type type)
 
expr_tmake_exprl (enum expr_type type, const struct integer *integer)
 
expr_tmake_exprd (enum expr_type type, double val)
 
expr_tmake_exprs (enum expr_type type, char *val)
 
expr_tmake_exprt (enum expr_type type, var_t *var, expr_t *expr)
 
expr_tmake_expr1 (enum expr_type type, expr_t *expr)
 
expr_tmake_expr2 (enum expr_type type, expr_t *expr1, expr_t *expr2)
 
expr_tmake_expr3 (enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
 
static void check_scalar_type (const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
 
static void check_arithmetic_type (const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
 
static void check_integer_type (const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
 
static type_tfind_identifier (const char *identifier, const type_t *cont_type, int *found_in_cont_type)
 
static int is_valid_member_operand (const type_t *type)
 
static struct expression_type resolve_expression (const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *e)
 
const type_texpr_resolve_type (const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
 
void write_expr (FILE *h, const expr_t *e, int brackets, int toplevel, const char *toplevel_prefix, const type_t *cont_type, const char *local_var_prefix)
 
static int compare_type (const type_t *a, const type_t *b)
 
int compare_expr (const expr_t *a, const expr_t *b)
 

Function Documentation

◆ check_arithmetic_type()

static void check_arithmetic_type ( const struct expr_loc expr_loc,
const type_t cont_type,
const type_t type 
)
static

Definition at line 409 of file expr.c.

411{
412 if (!cont_type || (!is_integer_type( type ) && !is_float_type( type )))
413 error_at( &expr_loc->v->where, "arithmetic type required in expression%s%s\n",
414 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
415}
static int is_float_type(const type_t *type)
Definition: expr.c:105
static int is_integer_type(const type_t *type)
Definition: expr.c:38
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void error_at(const struct location *where, const char *s,...)
Definition: utils.c:35
struct location where
Definition: widltypes.h:551
Definition: expr.h:23
const var_t * v
Definition: expr.h:24
const char * attr
Definition: expr.h:25

Referenced by resolve_expression().

◆ check_integer_type()

static void check_integer_type ( const struct expr_loc expr_loc,
const type_t cont_type,
const type_t type 
)
static

Definition at line 417 of file expr.c.

419{
420 if (!cont_type || !is_integer_type( type ))
421 error_at( &expr_loc->v->where, "integer type required in expression%s%s\n",
422 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
423}

Referenced by resolve_expression().

◆ check_scalar_type()

static void check_scalar_type ( const struct expr_loc expr_loc,
const type_t cont_type,
const type_t type 
)
static

Definition at line 401 of file expr.c.

403{
404 if (!cont_type || (!is_integer_type( type ) && !is_ptr( type ) && !is_float_type( type )))
405 error_at( &expr_loc->v->where, "scalar type required in expression%s%s\n",
406 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
407}
static int is_ptr(const type_t *t)
Definition: header.h:55

Referenced by resolve_expression().

◆ compare_expr()

int compare_expr ( const expr_t a,
const expr_t b 
)

Definition at line 860 of file expr.c.

861{
862 int ret;
863
864 if (a->type != b->type)
865 return a->type - b->type;
866
867 switch (a->type)
868 {
869 case EXPR_NUM:
870 case EXPR_TRUEFALSE:
871 return a->u.integer.value - b->u.integer.value;
872 case EXPR_DOUBLE:
873 return a->u.dval - b->u.dval;
874 case EXPR_IDENTIFIER:
875 case EXPR_STRLIT:
876 case EXPR_WSTRLIT:
877 case EXPR_CHARCONST:
878 return strcmp(a->u.sval, b->u.sval);
879 case EXPR_COND:
880 ret = compare_expr(a->ref, b->ref);
881 if (ret != 0)
882 return ret;
883 ret = compare_expr(a->u.ext, b->u.ext);
884 if (ret != 0)
885 return ret;
886 return compare_expr(a->ext2, b->ext2);
887 case EXPR_OR:
888 case EXPR_AND:
889 case EXPR_ADD:
890 case EXPR_SUB:
891 case EXPR_MOD:
892 case EXPR_MUL:
893 case EXPR_DIV:
894 case EXPR_SHL:
895 case EXPR_SHR:
896 case EXPR_MEMBER:
897 case EXPR_ARRAY:
898 case EXPR_LOGOR:
899 case EXPR_LOGAND:
900 case EXPR_XOR:
901 case EXPR_EQUALITY:
902 case EXPR_INEQUALITY:
903 case EXPR_GTR:
904 case EXPR_LESS:
905 case EXPR_GTREQL:
906 case EXPR_LESSEQL:
907 ret = compare_expr(a->ref, b->ref);
908 if (ret != 0)
909 return ret;
910 return compare_expr(a->u.ext, b->u.ext);
911 case EXPR_CAST:
912 ret = compare_type(a->u.tref.type, b->u.tref.type);
913 if (ret != 0)
914 return ret;
915 /* Fall through. */
916 case EXPR_NOT:
917 case EXPR_NEG:
918 case EXPR_PPTR:
919 case EXPR_ADDRESSOF:
920 case EXPR_LOGNOT:
921 case EXPR_POS:
922 return compare_expr(a->ref, b->ref);
923 case EXPR_SIZEOF:
924 return compare_type(a->u.tref.type, b->u.tref.type);
925 case EXPR_VOID:
926 return 0;
927 }
928 return -1;
929}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
@ EXPR_MEMBER
Definition: parser.h:266
@ EXPR_LESS
Definition: parser.h:243
@ EXPR_ARRAY
Definition: parser.h:265
@ EXPR_MOD
Definition: parser.h:229
@ EXPR_VOID
Definition: parser.h:231
@ EXPR_DIV
Definition: parser.h:228
@ EXPR_ADD
Definition: parser.h:225
@ EXPR_MUL
Definition: parser.h:227
@ EXPR_COND
Definition: parser.h:264
@ EXPR_OR
Definition: parser.h:218
@ EXPR_SUB
Definition: parser.h:226
@ EXPR_AND
Definition: parser.h:219
@ EXPR_DOUBLE
Definition: parse.h:28
@ EXPR_NEG
Definition: parse.h:45
@ EXPR_NOT
Definition: parse.h:49
@ EXPR_XOR
Definition: parse.h:55
return ret
Definition: mutex.c:146
int compare_expr(const expr_t *a, const expr_t *b)
Definition: expr.c:860
static int compare_type(const type_t *a, const type_t *b)
Definition: expr.c:849
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
@ EXPR_CAST
Definition: widltypes.h:199
@ EXPR_LOGOR
Definition: widltypes.h:215
@ EXPR_LOGAND
Definition: widltypes.h:216
@ EXPR_TRUEFALSE
Definition: widltypes.h:210
@ EXPR_CHARCONST
Definition: widltypes.h:228
@ EXPR_IDENTIFIER
Definition: widltypes.h:195
@ EXPR_SHR
Definition: widltypes.h:202
@ EXPR_LOGNOT
Definition: widltypes.h:224
@ EXPR_SHL
Definition: widltypes.h:201
@ EXPR_GTR
Definition: widltypes.h:220
@ EXPR_EQUALITY
Definition: widltypes.h:218
@ EXPR_INEQUALITY
Definition: widltypes.h:219
@ EXPR_POS
Definition: widltypes.h:225
@ EXPR_LESSEQL
Definition: widltypes.h:223
@ EXPR_WSTRLIT
Definition: widltypes.h:227
@ EXPR_STRLIT
Definition: widltypes.h:226
@ EXPR_NUM
Definition: widltypes.h:193
@ EXPR_PPTR
Definition: widltypes.h:198
@ EXPR_SIZEOF
Definition: widltypes.h:200
@ EXPR_GTREQL
Definition: widltypes.h:222
@ EXPR_ADDRESSOF
Definition: widltypes.h:211

Referenced by compare_expr(), and write_conf_or_var_desc().

◆ compare_type()

static int compare_type ( const type_t a,
const type_t b 
)
static

Definition at line 849 of file expr.c.

850{
851 if (a == b
852 || (a->name
853 && b->name
854 && strcmp(a->name, b->name) == 0))
855 return 0;
856 /* Ordering doesn't need to be implemented yet. */
857 return 1;
858}

Referenced by compare_expr().

◆ expr_resolve_type()

const type_t * expr_resolve_type ( const struct expr_loc expr_loc,
const type_t cont_type,
const expr_t expr 
)

Definition at line 673 of file expr.c.

674{
677 return expr_type.type;
678}
static struct expression_type resolve_expression(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *e)
Definition: expr.c:500
Definition: query.h:86
expr_type

Referenced by write_conf_or_var_desc(), and write_descriptors().

◆ find_identifier()

static type_t * find_identifier ( const char identifier,
const type_t cont_type,
int found_in_cont_type 
)
static

Definition at line 425 of file expr.c.

426{
427 type_t *type = NULL;
428 const var_t *field;
429 const var_list_t *fields = NULL;
430
431 *found_in_cont_type = 0;
432
433 if (cont_type)
434 {
435 switch (type_get_type(cont_type))
436 {
437 case TYPE_FUNCTION:
438 fields = type_function_get_args(cont_type);
439 break;
440 case TYPE_STRUCT:
441 fields = type_struct_get_fields(cont_type);
442 break;
443 case TYPE_UNION:
445 fields = type_union_get_cases(cont_type);
446 break;
447 case TYPE_VOID:
448 case TYPE_BASIC:
449 case TYPE_ENUM:
450 case TYPE_MODULE:
451 case TYPE_COCLASS:
452 case TYPE_INTERFACE:
453 case TYPE_POINTER:
454 case TYPE_ARRAY:
455 case TYPE_BITFIELD:
456 case TYPE_APICONTRACT:
459 case TYPE_PARAMETER:
460 case TYPE_DELEGATE:
461 /* nothing to do */
462 break;
463 case TYPE_ALIAS:
464 /* shouldn't get here because of using type_get_type above */
465 assert(0);
466 break;
467 }
468 }
469
471 if (field->name && !strcmp(identifier, field->name))
472 {
473 type = field->declspec.type;
474 *found_in_cont_type = 1;
475 break;
476 }
477
478 if (!type)
479 {
480 var_t *const_var = find_const(identifier, 0);
481 if (const_var) type = const_var->declspec.type;
482 }
483
484 return type;
485}
Definition: list.h:37
#define NULL
Definition: types.h:112
#define assert(x)
Definition: debug.h:53
uint32_t entry
Definition: isohybrid.c:63
const char * fields[10]
Definition: parser.c:313
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
type_t * type
Definition: widltypes.h:334
decl_spec_t declspec
Definition: widltypes.h:542
Definition: parser.c:44
static enum type_type type_get_type(const type_t *type)
Definition: typetree.h:113
static var_list_t * type_union_get_cases(const type_t *type)
Definition: typetree.h:184
static var_list_t * type_struct_get_fields(const type_t *type)
Definition: typetree.h:132
static var_list_t * type_function_get_args(const type_t *type)
Definition: typetree.h:139
@ TYPE_PARAMETER
Definition: widltypes.h:495
@ TYPE_ENUM
Definition: widltypes.h:480
@ TYPE_BITFIELD
Definition: widltypes.h:491
@ TYPE_BASIC
Definition: widltypes.h:479
@ TYPE_UNION
Definition: widltypes.h:483
@ TYPE_ALIAS
Definition: widltypes.h:484
@ TYPE_PARAMETERIZED_TYPE
Definition: widltypes.h:494
@ TYPE_POINTER
Definition: widltypes.h:489
@ TYPE_VOID
Definition: widltypes.h:478
@ TYPE_ENCAPSULATED_UNION
Definition: widltypes.h:482
@ TYPE_COCLASS
Definition: widltypes.h:486
@ TYPE_STRUCT
Definition: widltypes.h:481
@ TYPE_MODULE
Definition: widltypes.h:485
@ TYPE_DELEGATE
Definition: widltypes.h:496
@ TYPE_RUNTIMECLASS
Definition: widltypes.h:493
@ TYPE_INTERFACE
Definition: widltypes.h:488
@ TYPE_ARRAY
Definition: widltypes.h:490
@ TYPE_FUNCTION
Definition: widltypes.h:487
@ TYPE_APICONTRACT
Definition: widltypes.h:492
var_t * find_const(const char *name, int f)

Referenced by resolve_expression(), and write_expr().

◆ is_float_type()

static int is_float_type ( const type_t type)
static

Definition at line 105 of file expr.c.

106{
107 return (type_get_type(type) == TYPE_BASIC &&
110}
static enum type_basic_type type_basic_get_type(const type_t *type)
Definition: typetree.h:118
@ TYPE_BASIC_DOUBLE
Definition: widltypes.h:308
@ TYPE_BASIC_FLOAT
Definition: widltypes.h:307

Referenced by check_arithmetic_type(), check_scalar_type(), and make_exprt().

◆ is_integer_type()

static int is_integer_type ( const type_t type)
static

Definition at line 38 of file expr.c.

39{
40 switch (type_get_type(type))
41 {
42 case TYPE_ENUM:
43 return TRUE;
44 case TYPE_BASIC:
46 {
47 case TYPE_BASIC_INT8:
51 case TYPE_BASIC_INT:
53 case TYPE_BASIC_LONG:
54 case TYPE_BASIC_CHAR:
56 case TYPE_BASIC_BYTE:
59 return TRUE;
63 return FALSE;
64 }
65 return FALSE;
66 default:
67 return FALSE;
68 }
69}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ TYPE_BASIC_INT32
Definition: widltypes.h:298
@ TYPE_BASIC_ERROR_STATUS_T
Definition: widltypes.h:309
@ TYPE_BASIC_CHAR
Definition: widltypes.h:303
@ TYPE_BASIC_WCHAR
Definition: widltypes.h:306
@ TYPE_BASIC_INT16
Definition: widltypes.h:297
@ TYPE_BASIC_HYPER
Definition: widltypes.h:304
@ TYPE_BASIC_HANDLE
Definition: widltypes.h:310
@ TYPE_BASIC_INT8
Definition: widltypes.h:296
@ TYPE_BASIC_INT3264
Definition: widltypes.h:301
@ TYPE_BASIC_LONG
Definition: widltypes.h:302
@ TYPE_BASIC_INT64
Definition: widltypes.h:299
@ TYPE_BASIC_BYTE
Definition: widltypes.h:305
@ TYPE_BASIC_INT
Definition: widltypes.h:300

Referenced by check_arithmetic_type(), check_integer_type(), check_scalar_type(), make_exprt(), and resolve_expression().

◆ is_signed_integer_type()

static int is_signed_integer_type ( const type_t type)
static

Definition at line 71 of file expr.c.

72{
73 switch (type_get_type(type))
74 {
75 case TYPE_ENUM:
76 return FALSE;
77 case TYPE_BASIC:
79 {
80 case TYPE_BASIC_INT8:
84 case TYPE_BASIC_INT:
86 case TYPE_BASIC_LONG:
87 return type_basic_get_sign(type) < 0;
88 case TYPE_BASIC_CHAR:
89 return TRUE;
91 case TYPE_BASIC_BYTE:
97 return FALSE;
98 }
99 /* FALLTHROUGH */
100 default:
101 return FALSE;
102 }
103}
static int type_basic_get_sign(const type_t *type)
Definition: typetree.h:125

Referenced by make_exprt().

◆ is_valid_member_operand()

static int is_valid_member_operand ( const type_t type)
static

Definition at line 487 of file expr.c.

488{
489 switch (type_get_type(type))
490 {
491 case TYPE_STRUCT:
492 case TYPE_UNION:
493 case TYPE_ENUM:
494 return TRUE;
495 default:
496 return FALSE;
497 }
498}

Referenced by resolve_expression().

◆ make_expr()

expr_t * make_expr ( enum expr_type  type)

Definition at line 112 of file expr.c.

113{
114 expr_t *e = xmalloc(sizeof(expr_t));
115 memset(e, 0, sizeof(*e));
116 e->type = type;
117 return e;
118}
void * xmalloc(int size)
Definition: uimain.c:747
#define e
Definition: ke_i.h:82
#define memset(x, y, z)
Definition: compat.h:39

◆ make_expr1()

expr_t * make_expr1 ( enum expr_type  type,
expr_t expr 
)

Definition at line 247 of file expr.c.

248{
249 expr_t *e;
250 e = xmalloc(sizeof(expr_t));
251 memset(e, 0, sizeof(*e));
252 e->type = type;
253 e->ref = expr;
254 /* check for compile-time optimization */
255 if (expr->is_const)
256 {
257 e->is_const = TRUE;
258 switch (type)
259 {
260 case EXPR_LOGNOT:
261 e->cval = !expr->cval;
262 break;
263 case EXPR_POS:
264 e->cval = +expr->cval;
265 break;
266 case EXPR_NEG:
267 e->cval = -expr->cval;
268 break;
269 case EXPR_NOT:
270 e->cval = ~expr->cval;
271 break;
272 default:
273 e->is_const = FALSE;
274 break;
275 }
276 }
277 return e;
278}

◆ make_expr2()

expr_t * make_expr2 ( enum expr_type  type,
expr_t expr1,
expr_t expr2 
)

Definition at line 280 of file expr.c.

281{
282 expr_t *e;
283 e = xmalloc(sizeof(expr_t));
284 e->type = type;
285 e->ref = expr1;
286 e->u.ext = expr2;
287 e->is_const = FALSE;
288 /* check for compile-time optimization */
289 if (expr1->is_const && expr2->is_const)
290 {
291 e->is_const = TRUE;
292 switch (type)
293 {
294 case EXPR_ADD:
295 e->cval = expr1->cval + expr2->cval;
296 break;
297 case EXPR_SUB:
298 e->cval = expr1->cval - expr2->cval;
299 break;
300 case EXPR_MOD:
301 if (expr2->cval == 0)
302 {
303 error_loc("divide by zero in expression\n");
304 e->cval = 0;
305 }
306 else
307 e->cval = expr1->cval % expr2->cval;
308 break;
309 case EXPR_MUL:
310 e->cval = expr1->cval * expr2->cval;
311 break;
312 case EXPR_DIV:
313 if (expr2->cval == 0)
314 {
315 error_loc("divide by zero in expression\n");
316 e->cval = 0;
317 }
318 else
319 e->cval = expr1->cval / expr2->cval;
320 break;
321 case EXPR_OR:
322 e->cval = expr1->cval | expr2->cval;
323 break;
324 case EXPR_AND:
325 e->cval = expr1->cval & expr2->cval;
326 break;
327 case EXPR_SHL:
328 e->cval = expr1->cval << expr2->cval;
329 break;
330 case EXPR_SHR:
331 e->cval = expr1->cval >> expr2->cval;
332 break;
333 case EXPR_LOGOR:
334 e->cval = expr1->cval || expr2->cval;
335 break;
336 case EXPR_LOGAND:
337 e->cval = expr1->cval && expr2->cval;
338 break;
339 case EXPR_XOR:
340 e->cval = expr1->cval ^ expr2->cval;
341 break;
342 case EXPR_EQUALITY:
343 e->cval = expr1->cval == expr2->cval;
344 break;
345 case EXPR_INEQUALITY:
346 e->cval = expr1->cval != expr2->cval;
347 break;
348 case EXPR_GTR:
349 e->cval = expr1->cval > expr2->cval;
350 break;
351 case EXPR_LESS:
352 e->cval = expr1->cval < expr2->cval;
353 break;
354 case EXPR_GTREQL:
355 e->cval = expr1->cval >= expr2->cval;
356 break;
357 case EXPR_LESSEQL:
358 e->cval = expr1->cval <= expr2->cval;
359 break;
360 default:
361 e->is_const = FALSE;
362 break;
363 }
364 }
365 return e;
366}
#define error_loc(...)
Definition: utils.h:29
int is_const
Definition: widltypes.h:370
int cval
Definition: widltypes.h:371

◆ make_expr3()

expr_t * make_expr3 ( enum expr_type  type,
expr_t expr1,
expr_t expr2,
expr_t expr3 
)

Definition at line 368 of file expr.c.

369{
370 expr_t *e;
371 e = xmalloc(sizeof(expr_t));
372 e->type = type;
373 e->ref = expr1;
374 e->u.ext = expr2;
375 e->ext2 = expr3;
376 e->is_const = FALSE;
377 /* check for compile-time optimization */
378 if (expr1->is_const && expr2->is_const && expr3->is_const)
379 {
380 e->is_const = TRUE;
381 switch (type)
382 {
383 case EXPR_COND:
384 e->cval = expr1->cval ? expr2->cval : expr3->cval;
385 break;
386 default:
387 e->is_const = FALSE;
388 break;
389 }
390 }
391 return e;
392}

◆ make_exprd()

expr_t * make_exprd ( enum expr_type  type,
double  val 
)

Definition at line 137 of file expr.c.

138{
139 expr_t *e = xmalloc(sizeof(expr_t));
140 e->type = type;
141 e->ref = NULL;
142 e->u.dval = val;
143 e->is_const = TRUE;
144 e->cval = val;
145 return e;
146}
GLuint GLfloat * val
Definition: glext.h:7180

◆ make_exprl()

expr_t * make_exprl ( enum expr_type  type,
const struct integer integer 
)

Definition at line 120 of file expr.c.

121{
122 expr_t *e = xmalloc(sizeof(expr_t));
123 memset(e, 0, sizeof(*e));
124 e->type = type;
125 e->u.integer = *integer;
126 /* check for numeric constant */
127 if (type == EXPR_NUM || type == EXPR_TRUEFALSE)
128 {
129 /* make sure true/false value is valid */
130 assert(type != EXPR_TRUEFALSE || integer->value == 0 || integer->value == 1);
131 e->is_const = TRUE;
132 e->cval = integer->value;
133 }
134 return e;
135}
int value
Definition: widltypes.h:353

◆ make_exprs()

expr_t * make_exprs ( enum expr_type  type,
char val 
)

Definition at line 148 of file expr.c.

149{
150 expr_t *e;
151 e = xmalloc(sizeof(expr_t));
152 e->type = type;
153 e->ref = NULL;
154 e->u.sval = val;
155 e->is_const = FALSE;
156 /* check for predefined constants */
157 switch (type)
158 {
159 case EXPR_IDENTIFIER:
160 {
161 var_t *c = find_const(val, 0);
162 if (c)
163 {
164 e->u.sval = c->name;
165 free(val);
166 e->is_const = TRUE;
167 e->cval = c->eval->cval;
168 }
169 break;
170 }
171 case EXPR_CHARCONST:
172 if (!val[0])
173 error_loc("empty character constant\n");
174 else if (val[1])
175 error_loc("multi-character constants are endian dependent\n");
176 else
177 {
178 e->is_const = TRUE;
179 e->cval = *val;
180 }
181 break;
182 default:
183 break;
184 }
185 return e;
186}
#define free
Definition: debug_ros.c:5
const GLubyte * c
Definition: glext.h:8905
char * name
Definition: compiler.c:66

◆ make_exprt()

expr_t * make_exprt ( enum expr_type  type,
var_t var,
expr_t expr 
)

Definition at line 188 of file expr.c.

189{
190 expr_t *e;
191 type_t *tref;
192
193 if (var->declspec.stgclass != STG_NONE && var->declspec.stgclass != STG_REGISTER)
194 error_loc("invalid storage class for type expression\n");
195
196 tref = var->declspec.type;
197
198 e = xmalloc(sizeof(expr_t));
199 e->type = type;
200 e->ref = expr;
201 e->u.tref = var->declspec;
202 e->is_const = FALSE;
203 if (type == EXPR_SIZEOF)
204 {
205 /* only do this for types that should be the same on all platforms */
206 if (is_integer_type(tref) || is_float_type(tref))
207 {
208 e->is_const = TRUE;
209 e->cval = type_memsize(tref);
210 }
211 }
212 /* check for cast of constant expression */
213 if (type == EXPR_CAST && expr->is_const)
214 {
215 if (is_integer_type(tref))
216 {
217 unsigned int cast_type_bits = type_memsize(tref) * 8;
218 unsigned int cast_mask;
219
220 e->is_const = TRUE;
221 if (is_signed_integer_type(tref))
222 {
223 cast_mask = (1u << (cast_type_bits - 1)) - 1;
224 if (expr->cval & (1u << (cast_type_bits - 1)))
225 e->cval = -((-expr->cval) & cast_mask);
226 else
227 e->cval = expr->cval & cast_mask;
228 }
229 else
230 {
231 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
232 cast_mask = ((1u << (cast_type_bits - 1)) - 1) |
233 1u << (cast_type_bits - 1);
234 e->cval = expr->cval & cast_mask;
235 }
236 }
237 else
238 {
239 e->is_const = TRUE;
240 e->cval = expr->cval;
241 }
242 }
243 free(var);
244 return e;
245}
static int is_signed_integer_type(const type_t *type)
Definition: expr.c:71
const char * var
Definition: shader.c:5666
static unsigned int type_memsize(ITypeInfo *typeinfo, TYPEDESC *desc, unsigned int *align_ret)
Definition: ndr_typelib.c:152
@ STG_REGISTER
Definition: widltypes.h:250
@ STG_NONE
Definition: widltypes.h:247

◆ resolve_expression()

static struct expression_type resolve_expression ( const struct expr_loc expr_loc,
const type_t cont_type,
const expr_t e 
)
static

Definition at line 500 of file expr.c.

503{
504 struct expression_type result;
506 result.is_temporary = FALSE;
507 result.type = NULL;
508 switch (e->type)
509 {
510 case EXPR_VOID:
511 break;
512 case EXPR_NUM:
513 case EXPR_TRUEFALSE:
514 result.is_temporary = FALSE;
515 result.type = type_new_int(e->u.integer.is_long ? TYPE_BASIC_LONG : TYPE_BASIC_INT, e->u.integer.is_unsigned);
516 break;
517 case EXPR_STRLIT:
518 result.is_temporary = TRUE;
520 break;
521 case EXPR_WSTRLIT:
522 result.is_temporary = TRUE;
524 break;
525 case EXPR_CHARCONST:
526 result.is_temporary = TRUE;
528 break;
529 case EXPR_DOUBLE:
530 result.is_temporary = TRUE;
532 break;
533 case EXPR_IDENTIFIER:
534 {
535 int found_in_cont_type;
536 result.is_variable = TRUE;
537 result.is_temporary = FALSE;
538 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
539 if (!result.type)
540 error_at( &expr_loc->v->where, "identifier %s cannot be resolved in expression%s%s\n", e->u.sval,
541 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
542 break;
543 }
544 case EXPR_LOGNOT:
545 result = resolve_expression(expr_loc, cont_type, e->ref);
546 check_scalar_type(expr_loc, cont_type, result.type);
547 result.is_variable = FALSE;
548 result.is_temporary = FALSE;
550 break;
551 case EXPR_NOT:
552 result = resolve_expression(expr_loc, cont_type, e->ref);
553 check_integer_type(expr_loc, cont_type, result.type);
554 result.is_variable = FALSE;
555 break;
556 case EXPR_POS:
557 case EXPR_NEG:
558 result = resolve_expression(expr_loc, cont_type, e->ref);
559 check_arithmetic_type(expr_loc, cont_type, result.type);
560 result.is_variable = FALSE;
561 break;
562 case EXPR_ADDRESSOF:
563 result = resolve_expression(expr_loc, cont_type, e->ref);
564 if (!result.is_variable)
565 error_at( &expr_loc->v->where, "address-of operator applied to non-variable type in expression%s%s\n",
566 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
567 result.is_variable = FALSE;
568 result.is_temporary = TRUE;
569 result.type = type_new_pointer(result.type);
570 break;
571 case EXPR_PPTR:
572 result = resolve_expression(expr_loc, cont_type, e->ref);
573 if (result.type && is_ptr(result.type))
575 else if(result.type && is_array(result.type)
578 else
579 error_at( &expr_loc->v->where, "dereference operator applied to non-pointer type in expression%s%s\n",
580 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
581 break;
582 case EXPR_CAST:
583 result = resolve_expression(expr_loc, cont_type, e->ref);
584 result.type = e->u.tref.type;
585 break;
586 case EXPR_SIZEOF:
587 result.is_temporary = FALSE;
589 break;
590 case EXPR_SHL:
591 case EXPR_SHR:
592 case EXPR_MOD:
593 case EXPR_MUL:
594 case EXPR_DIV:
595 case EXPR_ADD:
596 case EXPR_SUB:
597 case EXPR_AND:
598 case EXPR_OR:
599 case EXPR_XOR:
600 {
601 struct expression_type result_right;
602 result = resolve_expression(expr_loc, cont_type, e->ref);
603 result.is_variable = FALSE;
604 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
605 /* FIXME: these checks aren't strict enough for some of the operators */
606 check_scalar_type(expr_loc, cont_type, result.type);
607 check_scalar_type(expr_loc, cont_type, result_right.type);
608 break;
609 }
610 case EXPR_LOGOR:
611 case EXPR_LOGAND:
612 case EXPR_EQUALITY:
613 case EXPR_INEQUALITY:
614 case EXPR_GTR:
615 case EXPR_LESS:
616 case EXPR_GTREQL:
617 case EXPR_LESSEQL:
618 {
619 struct expression_type result_left, result_right;
620 result_left = resolve_expression(expr_loc, cont_type, e->ref);
621 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
622 check_scalar_type(expr_loc, cont_type, result_left.type);
623 check_scalar_type(expr_loc, cont_type, result_right.type);
624 result.is_temporary = FALSE;
626 break;
627 }
628 case EXPR_MEMBER:
629 result = resolve_expression(expr_loc, cont_type, e->ref);
630 if (result.type && is_valid_member_operand(result.type))
631 result = resolve_expression(expr_loc, result.type, e->u.ext);
632 else
633 error_at( &expr_loc->v->where, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",
634 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
635 break;
636 case EXPR_COND:
637 {
638 struct expression_type result_first, result_second, result_third;
639 result_first = resolve_expression(expr_loc, cont_type, e->ref);
640 check_scalar_type(expr_loc, cont_type, result_first.type);
641 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
642 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
643 check_scalar_type(expr_loc, cont_type, result_second.type);
644 check_scalar_type(expr_loc, cont_type, result_third.type);
645 if (!is_ptr( result_second.type ) ^ !is_ptr( result_third.type ))
646 error_at( &expr_loc->v->where, "type mismatch in ?: expression\n" );
647 /* FIXME: determine the correct return type */
648 result = result_second;
649 result.is_variable = FALSE;
650 break;
651 }
652 case EXPR_ARRAY:
653 result = resolve_expression(expr_loc, cont_type, e->ref);
654 if (result.type && is_array(result.type))
655 {
656 struct expression_type index_result;
658 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
659 if (!index_result.type || !is_integer_type( index_result.type ))
660 error_at( &expr_loc->v->where, "array subscript not of integral type in expression%s%s\n",
661 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
662 }
663 else
664 {
665 error_at( &expr_loc->v->where, "array subscript operator applied to non-array type in expression%s%s\n",
666 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
667 }
668 break;
669 }
670 return result;
671}
static void check_integer_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:417
static void check_scalar_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:401
static void check_arithmetic_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:409
static int is_valid_member_operand(const type_t *type)
Definition: expr.c:487
static type_t * find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
Definition: expr.c:425
GLuint64EXT * result
Definition: glext.h:11304
static int is_array(const type_t *t)
Definition: header.h:60
type_t * type
Definition: expr.c:398
int is_variable
Definition: expr.c:396
type_t * type_new_basic(enum type_basic_type basic_type)
Definition: typetree.c:505
type_t * type_new_pointer(type_t *ref)
Definition: typetree.c:470
type_t * type_new_int(enum type_basic_type basic_type, int sign)
Definition: typetree.c:513
static int type_array_is_decl_as_ptr(const type_t *type)
Definition: typetree.h:350
static type_t * type_array_get_element_type(const type_t *type)
Definition: typetree.h:345
static type_t * type_pointer_get_ref_type(const type_t *type)
Definition: typetree.h:424

Referenced by expr_resolve_type(), and resolve_expression().

◆ write_expr()

void write_expr ( FILE h,
const expr_t e,
int  brackets,
int  toplevel,
const char toplevel_prefix,
const type_t cont_type,
const char local_var_prefix 
)

Definition at line 680 of file expr.c.

683{
684 switch (e->type)
685 {
686 case EXPR_VOID:
687 break;
688 case EXPR_NUM:
689 if (e->u.integer.is_hex)
690 fprintf(h, "0x%x", e->u.integer.value);
691 else
692 fprintf(h, "%u", e->u.integer.value);
693 if (e->u.integer.is_unsigned)
694 fprintf(h, "u");
695 if (e->u.integer.is_long)
696 fprintf(h, "l");
697 break;
698 case EXPR_DOUBLE:
699 fprintf(h, "%#.15g", e->u.dval);
700 break;
701 case EXPR_TRUEFALSE:
702 if (e->u.integer.value == 0)
703 fprintf(h, "FALSE");
704 else
705 fprintf(h, "TRUE");
706 break;
707 case EXPR_IDENTIFIER:
708 if (toplevel && toplevel_prefix && cont_type)
709 {
710 int found_in_cont_type;
711 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
712 if (found_in_cont_type)
713 {
714 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
715 break;
716 }
717 }
718 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
719 break;
720 case EXPR_STRLIT:
721 fprintf(h, "\"%s\"", e->u.sval);
722 break;
723 case EXPR_WSTRLIT:
724 fprintf(h, "L\"%s\"", e->u.sval);
725 break;
726 case EXPR_CHARCONST:
727 fprintf(h, "'%s'", e->u.sval);
728 break;
729 case EXPR_LOGNOT:
730 fprintf(h, "!");
731 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
732 break;
733 case EXPR_NOT:
734 fprintf(h, "~");
735 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
736 break;
737 case EXPR_POS:
738 fprintf(h, "+");
739 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
740 break;
741 case EXPR_NEG:
742 fprintf(h, "-");
743 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
744 break;
745 case EXPR_ADDRESSOF:
746 fprintf(h, "&");
747 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
748 break;
749 case EXPR_PPTR:
750 fprintf(h, "*");
751 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
752 break;
753 case EXPR_CAST:
754 fprintf(h, "(");
755 write_type_decl(h, &e->u.tref, NULL);
756 fprintf(h, ")");
757 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
758 break;
759 case EXPR_SIZEOF:
760 fprintf(h, "sizeof(");
761 write_type_decl(h, &e->u.tref, NULL);
762 fprintf(h, ")");
763 break;
764 case EXPR_SHL:
765 case EXPR_SHR:
766 case EXPR_MOD:
767 case EXPR_MUL:
768 case EXPR_DIV:
769 case EXPR_ADD:
770 case EXPR_SUB:
771 case EXPR_AND:
772 case EXPR_OR:
773 case EXPR_LOGOR:
774 case EXPR_LOGAND:
775 case EXPR_XOR:
776 case EXPR_EQUALITY:
777 case EXPR_INEQUALITY:
778 case EXPR_GTR:
779 case EXPR_LESS:
780 case EXPR_GTREQL:
781 case EXPR_LESSEQL:
782 if (brackets) fprintf(h, "(");
783 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
784 switch (e->type)
785 {
786 case EXPR_SHL: fprintf(h, " << "); break;
787 case EXPR_SHR: fprintf(h, " >> "); break;
788 case EXPR_MOD: fprintf(h, " %% "); break;
789 case EXPR_MUL: fprintf(h, " * "); break;
790 case EXPR_DIV: fprintf(h, " / "); break;
791 case EXPR_ADD: fprintf(h, " + "); break;
792 case EXPR_SUB: fprintf(h, " - "); break;
793 case EXPR_AND: fprintf(h, " & "); break;
794 case EXPR_OR: fprintf(h, " | "); break;
795 case EXPR_LOGOR: fprintf(h, " || "); break;
796 case EXPR_LOGAND: fprintf(h, " && "); break;
797 case EXPR_XOR: fprintf(h, " ^ "); break;
798 case EXPR_EQUALITY: fprintf(h, " == "); break;
799 case EXPR_INEQUALITY: fprintf(h, " != "); break;
800 case EXPR_GTR: fprintf(h, " > "); break;
801 case EXPR_LESS: fprintf(h, " < "); break;
802 case EXPR_GTREQL: fprintf(h, " >= "); break;
803 case EXPR_LESSEQL: fprintf(h, " <= "); break;
804 default: break;
805 }
806 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
807 if (brackets) fprintf(h, ")");
808 break;
809 case EXPR_MEMBER:
810 if (brackets) fprintf(h, "(");
811 if (e->ref->type == EXPR_PPTR)
812 {
813 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
814 fprintf(h, "->");
815 }
816 else
817 {
818 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
819 fprintf(h, ".");
820 }
821 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
822 if (brackets) fprintf(h, ")");
823 break;
824 case EXPR_COND:
825 if (brackets) fprintf(h, "(");
826 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
827 fprintf(h, " ? ");
828 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
829 fprintf(h, " : ");
830 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
831 if (brackets) fprintf(h, ")");
832 break;
833 case EXPR_ARRAY:
834 if (brackets) fprintf(h, "(");
835 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
836 fprintf(h, "[");
837 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
838 fprintf(h, "]");
839 if (brackets) fprintf(h, ")");
840 break;
841 }
842}
void write_expr(FILE *h, const expr_t *e, int brackets, int toplevel, const char *toplevel_prefix, const type_t *cont_type, const char *local_var_prefix)
Definition: expr.c:680
jmp_buf toplevel
Definition: main.c:95
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name)
Definition: header.c:588
char * value
Definition: compiler.c:67

Referenced by assign_stub_out_args(), clear_output_vars(), write_args(), write_declaration(), write_enums(), write_expr(), write_expr_eval_routines(), and write_parameter_conf_or_var_exprs().