aboutsummaryrefslogtreecommitdiff
blob: 2cc05e575f30aa9b42d0b2338e0eb65a26356724 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef EXPRESSION_H
#define EXPRESSION_H
/*
 * sparse/expression.h
 *
 * Copyright (C) 2003 Linus Torvalds, all rights reserved
 *
 * Declarations and helper functions for expression parsing.
 */

struct expression_list;

enum expression_type {
	EXPR_VALUE,
	EXPR_STRING,
	EXPR_SYMBOL,
	EXPR_BINOP,
	EXPR_ASSIGNMENT,
	EXPR_DEREF,
	EXPR_PREOP,
	EXPR_POSTOP,
	EXPR_CAST,
	EXPR_SIZEOF,
	EXPR_CONDITIONAL,
	EXPR_STATEMENT,
	EXPR_CALL,
	EXPR_COMMA,
	EXPR_COMPARE,
	EXPR_BITFIELD,
	EXPR_INITIALIZER,	// initializer list
	EXPR_IDENTIFIER,	// identifier in initializer
	EXPR_INDEX,		// index in initializer
};

struct expression {
	enum expression_type type;
	int op;
	struct position pos;
	struct symbol *ctype;
	union {
		// EXPR_VALUE
		unsigned long long value;

		// EXPR_STRING
		struct string *string;

		// EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP
		struct expression *unop;

		// EXPR_SYMBOL
		struct symbol_arg {
			struct symbol *symbol;
			struct ident *symbol_name;
		};

		// EXPR_STATEMENT
		struct statement *statement;

		// EXPR_BINOP, EXPR_COMMA, EXPR_COMPARE and EXPR_ASSIGNMENT
		struct binop_arg {
			struct expression *left, *right;
		};
		// EXPR_DEREF
		struct deref_arg {
			struct expression *deref;
			struct ident *member;
		};
		// EXPR_CAST and EXPR_SIZEOF
		struct cast_arg {
			struct symbol *cast_type;
			struct expression *cast_expression;
		};
		// EXPR_CONDITIONAL
		struct conditional_expr {
			struct expression *conditional, *cond_true, *cond_false;
		};
		// EXPR_CALL
		struct call_expr {
			struct expression *fn;
			struct expression_list *args;
		};
		// EXPR_BITFIELD
		struct bitfield_expr {
			unsigned char bitpos, nrbits;
			struct expression *address;
		};
		// EXPR_INITIALIZER
		struct expression_list *expr_list;
		// EXPR_IDENTIFIER
		struct ident *expr_ident;
		// EXPR_INDEX
		struct index_expr {
			unsigned int idx_from, idx_to;
		};
	};
};

/* Constant expression values */
long long get_expression_value(struct expression *);

/* Expression parsing */
struct token *parse_expression(struct token *token, struct expression **tree);
struct token *conditional_expression(struct token *token, struct expression **tree);
struct token *primary_expression(struct token *token, struct expression **tree);
struct token *parens_expression(struct token *token, struct expression **expr, const char *where);
struct token *assignment_expression(struct token *token, struct expression **tree);

extern int evaluate_symbol(struct symbol *sym);
extern int evaluate_statement(struct statement *stmt);
extern int evaluate_expression(struct expression *);
extern int evaluate_initializer(struct symbol *, struct expression *);

static inline struct expression *alloc_expression(struct position pos, int type)
{
	struct expression *expr = __alloc_expression(0);
	expr->type = type;
	expr->pos = pos;
	return expr;
}

/* Type name parsing */
struct token *typename(struct token *, struct symbol **);

static inline int lookup_type(struct token *token)
{
	if (token->pos.type == TOKEN_IDENT)
		return lookup_symbol(token->ident, NS_TYPEDEF) != NULL;
	return 0;
}

/* Statement parsing */
struct statement *alloc_statement(struct position pos, int type);
struct token *initializer(struct expression **tree, struct token *token);
struct token *compound_statement(struct token *, struct statement *);

extern void clean_up_statement(struct statement *stmt, void *_parent, int flags);
extern void clean_up_symbol(struct symbol *sym, void *_parent, int flags);

/* The preprocessor calls this 'constant_expression()' */
#define constant_expression(token,tree) conditional_expression(token, tree)

#endif