1f08c3bdfSopenharmony_ci#ifndef EXPRESSION_H 2f08c3bdfSopenharmony_ci#define EXPRESSION_H 3f08c3bdfSopenharmony_ci/* 4f08c3bdfSopenharmony_ci * sparse/expression.h 5f08c3bdfSopenharmony_ci * 6f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp. 7f08c3bdfSopenharmony_ci * 2003 Linus Torvalds 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 10f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 11f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights 12f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 14f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions: 15f08c3bdfSopenharmony_ci * 16f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in 17f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software. 18f08c3bdfSopenharmony_ci * 19f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25f08c3bdfSopenharmony_ci * THE SOFTWARE. 26f08c3bdfSopenharmony_ci * 27f08c3bdfSopenharmony_ci * Declarations and helper functions for expression parsing. 28f08c3bdfSopenharmony_ci */ 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_ci#include "allocate.h" 31f08c3bdfSopenharmony_ci#include "lib.h" 32f08c3bdfSopenharmony_ci#include "symbol.h" 33f08c3bdfSopenharmony_ci 34f08c3bdfSopenharmony_cistruct expression_list; 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_cienum expression_type { 37f08c3bdfSopenharmony_ci EXPR_VALUE = 1, 38f08c3bdfSopenharmony_ci EXPR_STRING, 39f08c3bdfSopenharmony_ci EXPR_SYMBOL, 40f08c3bdfSopenharmony_ci EXPR_TYPE, 41f08c3bdfSopenharmony_ci EXPR_BINOP, 42f08c3bdfSopenharmony_ci EXPR_ASSIGNMENT, 43f08c3bdfSopenharmony_ci EXPR_LOGICAL, 44f08c3bdfSopenharmony_ci EXPR_DEREF, 45f08c3bdfSopenharmony_ci EXPR_PREOP, 46f08c3bdfSopenharmony_ci EXPR_POSTOP, 47f08c3bdfSopenharmony_ci EXPR_CAST, 48f08c3bdfSopenharmony_ci EXPR_FORCE_CAST, 49f08c3bdfSopenharmony_ci EXPR_IMPLIED_CAST, 50f08c3bdfSopenharmony_ci EXPR_SIZEOF, 51f08c3bdfSopenharmony_ci EXPR_ALIGNOF, 52f08c3bdfSopenharmony_ci EXPR_PTRSIZEOF, 53f08c3bdfSopenharmony_ci EXPR_CONDITIONAL, 54f08c3bdfSopenharmony_ci EXPR_SELECT, // a "safe" conditional expression 55f08c3bdfSopenharmony_ci EXPR_STATEMENT, 56f08c3bdfSopenharmony_ci EXPR_CALL, 57f08c3bdfSopenharmony_ci EXPR_COMMA, 58f08c3bdfSopenharmony_ci EXPR_COMPARE, 59f08c3bdfSopenharmony_ci EXPR_LABEL, 60f08c3bdfSopenharmony_ci EXPR_INITIALIZER, // initializer list 61f08c3bdfSopenharmony_ci EXPR_IDENTIFIER, // identifier in initializer 62f08c3bdfSopenharmony_ci EXPR_INDEX, // index in initializer 63f08c3bdfSopenharmony_ci EXPR_POS, // position in initializer 64f08c3bdfSopenharmony_ci EXPR_FVALUE, 65f08c3bdfSopenharmony_ci EXPR_SLICE, 66f08c3bdfSopenharmony_ci EXPR_OFFSETOF, 67f08c3bdfSopenharmony_ci EXPR_GENERIC, 68f08c3bdfSopenharmony_ci}; 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci/* 72f08c3bdfSopenharmony_ci * Flags for tracking the promotion of constness related attributes 73f08c3bdfSopenharmony_ci * from subexpressions to their parents. 74f08c3bdfSopenharmony_ci * 75f08c3bdfSopenharmony_ci * The flags are not independent as one might imply another. 76f08c3bdfSopenharmony_ci * The implications are as follows: 77f08c3bdfSopenharmony_ci * - CEF_INT, CEF_ENUM and 78f08c3bdfSopenharmony_ci * CEF_CHAR imply CEF_ICE. 79f08c3bdfSopenharmony_ci * 80f08c3bdfSopenharmony_ci * Use the CEF_*_SET_MASK and CEF_*_CLEAR_MASK 81f08c3bdfSopenharmony_ci * helper macros defined below to set or clear one of these flags. 82f08c3bdfSopenharmony_ci */ 83f08c3bdfSopenharmony_cienum constexpr_flag { 84f08c3bdfSopenharmony_ci CEF_NONE = 0, 85f08c3bdfSopenharmony_ci /* 86f08c3bdfSopenharmony_ci * A constant in the sense of [6.4.4]: 87f08c3bdfSopenharmony_ci * - Integer constant [6.4.4.1] 88f08c3bdfSopenharmony_ci * - Floating point constant [6.4.4.2] 89f08c3bdfSopenharmony_ci * - Enumeration constant [6.4.4.3] 90f08c3bdfSopenharmony_ci * - Character constant [6.4.4.4] 91f08c3bdfSopenharmony_ci */ 92f08c3bdfSopenharmony_ci CEF_INT = (1 << 0), 93f08c3bdfSopenharmony_ci CEF_FLOAT = (1 << 1), 94f08c3bdfSopenharmony_ci CEF_ENUM = (1 << 2), 95f08c3bdfSopenharmony_ci CEF_CHAR = (1 << 3), 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci /* 98f08c3bdfSopenharmony_ci * A constant expression in the sense of [6.6]: 99f08c3bdfSopenharmony_ci * - integer constant expression [6.6(6)] 100f08c3bdfSopenharmony_ci * - arithmetic constant expression [6.6(8)] 101f08c3bdfSopenharmony_ci * - address constant [6.6(9)] 102f08c3bdfSopenharmony_ci */ 103f08c3bdfSopenharmony_ci CEF_ICE = (1 << 4), 104f08c3bdfSopenharmony_ci CEF_ACE = (1 << 5), 105f08c3bdfSopenharmony_ci CEF_ADDR = (1 << 6), 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci /* integer constant expression => arithmetic constant expression */ 108f08c3bdfSopenharmony_ci CEF_SET_ICE = (CEF_ICE | CEF_ACE), 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci /* integer constant => integer constant expression */ 111f08c3bdfSopenharmony_ci CEF_SET_INT = (CEF_INT | CEF_SET_ICE), 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci /* floating point constant => arithmetic constant expression */ 114f08c3bdfSopenharmony_ci CEF_SET_FLOAT = (CEF_FLOAT | CEF_ACE), 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_ci /* enumeration constant => integer constant expression */ 117f08c3bdfSopenharmony_ci CEF_SET_ENUM = (CEF_ENUM | CEF_SET_ICE), 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ci /* character constant => integer constant expression */ 120f08c3bdfSopenharmony_ci CEF_SET_CHAR = (CEF_CHAR | CEF_SET_ICE), 121f08c3bdfSopenharmony_ci 122f08c3bdfSopenharmony_ci /* 123f08c3bdfSopenharmony_ci * Remove any "Constant" [6.4.4] flag, but retain the "constant 124f08c3bdfSopenharmony_ci * expression" [6.6] flags. 125f08c3bdfSopenharmony_ci */ 126f08c3bdfSopenharmony_ci CEF_CONST_MASK = (CEF_INT | CEF_FLOAT | CEF_CHAR), 127f08c3bdfSopenharmony_ci 128f08c3bdfSopenharmony_ci /* 129f08c3bdfSopenharmony_ci * not an integer constant expression => neither of integer, 130f08c3bdfSopenharmony_ci * enumeration and character constant 131f08c3bdfSopenharmony_ci */ 132f08c3bdfSopenharmony_ci CEF_CLR_ICE = (CEF_ICE | CEF_INT | CEF_ENUM | CEF_CHAR), 133f08c3bdfSopenharmony_ci}; 134f08c3bdfSopenharmony_ci 135f08c3bdfSopenharmony_cienum { 136f08c3bdfSopenharmony_ci Taint_comma = 1, 137f08c3bdfSopenharmony_ci}; /* for expr->taint */ 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_cistruct asm_operand { 140f08c3bdfSopenharmony_ci struct ident *name; 141f08c3bdfSopenharmony_ci struct expression *constraint; 142f08c3bdfSopenharmony_ci struct expression *expr; 143f08c3bdfSopenharmony_ci unsigned int is_assign:1; 144f08c3bdfSopenharmony_ci unsigned int is_modify:1; 145f08c3bdfSopenharmony_ci unsigned int is_earlyclobber:1; 146f08c3bdfSopenharmony_ci unsigned int is_commutative:1; 147f08c3bdfSopenharmony_ci unsigned int is_register:1; 148f08c3bdfSopenharmony_ci unsigned int is_memory:1; 149f08c3bdfSopenharmony_ci}; 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_cistruct type_expression { 152f08c3bdfSopenharmony_ci struct symbol *type; 153f08c3bdfSopenharmony_ci struct expression *expr; 154f08c3bdfSopenharmony_ci struct type_expression *next; 155f08c3bdfSopenharmony_ci}; 156f08c3bdfSopenharmony_ci 157f08c3bdfSopenharmony_ciDECLARE_ALLOCATOR(type_expression); 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_cistruct expression { 160f08c3bdfSopenharmony_ci enum expression_type type:8; 161f08c3bdfSopenharmony_ci unsigned flags:8; 162f08c3bdfSopenharmony_ci unsigned zero_init:1; 163f08c3bdfSopenharmony_ci int op; 164f08c3bdfSopenharmony_ci struct position pos; 165f08c3bdfSopenharmony_ci struct symbol *ctype; 166f08c3bdfSopenharmony_ci union { 167f08c3bdfSopenharmony_ci // EXPR_VALUE 168f08c3bdfSopenharmony_ci struct { 169f08c3bdfSopenharmony_ci unsigned long long value; 170f08c3bdfSopenharmony_ci unsigned taint; 171f08c3bdfSopenharmony_ci }; 172f08c3bdfSopenharmony_ci 173f08c3bdfSopenharmony_ci // EXPR_FVALUE 174f08c3bdfSopenharmony_ci long double fvalue; 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ci // EXPR_STRING 177f08c3bdfSopenharmony_ci struct { 178f08c3bdfSopenharmony_ci int wide; 179f08c3bdfSopenharmony_ci struct string *string; 180f08c3bdfSopenharmony_ci }; 181f08c3bdfSopenharmony_ci 182f08c3bdfSopenharmony_ci // EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP 183f08c3bdfSopenharmony_ci struct /* unop */ { 184f08c3bdfSopenharmony_ci struct expression *unop; 185f08c3bdfSopenharmony_ci unsigned long op_value; 186f08c3bdfSopenharmony_ci }; 187f08c3bdfSopenharmony_ci 188f08c3bdfSopenharmony_ci // EXPR_SYMBOL, EXPR_TYPE 189f08c3bdfSopenharmony_ci struct /* symbol_arg */ { 190f08c3bdfSopenharmony_ci struct symbol *symbol; 191f08c3bdfSopenharmony_ci struct ident *symbol_name; 192f08c3bdfSopenharmony_ci }; 193f08c3bdfSopenharmony_ci 194f08c3bdfSopenharmony_ci // EXPR_STATEMENT 195f08c3bdfSopenharmony_ci struct statement *statement; 196f08c3bdfSopenharmony_ci 197f08c3bdfSopenharmony_ci // EXPR_BINOP, EXPR_COMMA, EXPR_COMPARE, EXPR_LOGICAL and EXPR_ASSIGNMENT 198f08c3bdfSopenharmony_ci struct /* binop_arg */ { 199f08c3bdfSopenharmony_ci struct expression *left, *right; 200f08c3bdfSopenharmony_ci }; 201f08c3bdfSopenharmony_ci // EXPR_DEREF 202f08c3bdfSopenharmony_ci struct /* deref_arg */ { 203f08c3bdfSopenharmony_ci struct expression *deref; 204f08c3bdfSopenharmony_ci struct ident *member; 205f08c3bdfSopenharmony_ci }; 206f08c3bdfSopenharmony_ci // EXPR_SLICE 207f08c3bdfSopenharmony_ci struct /* slice */ { 208f08c3bdfSopenharmony_ci struct expression *base; 209f08c3bdfSopenharmony_ci unsigned r_bitpos; 210f08c3bdfSopenharmony_ci }; 211f08c3bdfSopenharmony_ci // EXPR_CAST, EXPR_FORCE_CAST, EXPR_IMPLIED_CAST, 212f08c3bdfSopenharmony_ci // EXPR_SIZEOF, EXPR_ALIGNOF and EXPR_PTRSIZEOF 213f08c3bdfSopenharmony_ci struct /* cast_arg */ { 214f08c3bdfSopenharmony_ci struct symbol *cast_type; 215f08c3bdfSopenharmony_ci struct expression *cast_expression; 216f08c3bdfSopenharmony_ci }; 217f08c3bdfSopenharmony_ci // EXPR_CONDITIONAL 218f08c3bdfSopenharmony_ci // EXPR_SELECT 219f08c3bdfSopenharmony_ci struct /* conditional_expr */ { 220f08c3bdfSopenharmony_ci struct expression *conditional, *cond_true, *cond_false; 221f08c3bdfSopenharmony_ci }; 222f08c3bdfSopenharmony_ci // EXPR_CALL 223f08c3bdfSopenharmony_ci struct /* call_expr */ { 224f08c3bdfSopenharmony_ci struct expression *fn; 225f08c3bdfSopenharmony_ci struct expression_list *args; 226f08c3bdfSopenharmony_ci }; 227f08c3bdfSopenharmony_ci // EXPR_LABEL 228f08c3bdfSopenharmony_ci struct /* label_expr */ { 229f08c3bdfSopenharmony_ci struct symbol *label_symbol; 230f08c3bdfSopenharmony_ci }; 231f08c3bdfSopenharmony_ci // EXPR_INITIALIZER 232f08c3bdfSopenharmony_ci struct expression_list *expr_list; 233f08c3bdfSopenharmony_ci // EXPR_IDENTIFIER 234f08c3bdfSopenharmony_ci struct /* ident_expr */ { 235f08c3bdfSopenharmony_ci int offset; 236f08c3bdfSopenharmony_ci struct ident *expr_ident; 237f08c3bdfSopenharmony_ci struct symbol *field; 238f08c3bdfSopenharmony_ci struct expression *ident_expression; 239f08c3bdfSopenharmony_ci }; 240f08c3bdfSopenharmony_ci // EXPR_INDEX 241f08c3bdfSopenharmony_ci struct /* index_expr */ { 242f08c3bdfSopenharmony_ci unsigned int idx_from, idx_to; 243f08c3bdfSopenharmony_ci struct expression *idx_expression; 244f08c3bdfSopenharmony_ci }; 245f08c3bdfSopenharmony_ci // EXPR_POS 246f08c3bdfSopenharmony_ci struct /* initpos_expr */ { 247f08c3bdfSopenharmony_ci unsigned int init_offset, init_nr; 248f08c3bdfSopenharmony_ci struct expression *init_expr; 249f08c3bdfSopenharmony_ci }; 250f08c3bdfSopenharmony_ci // EXPR_OFFSETOF 251f08c3bdfSopenharmony_ci struct { 252f08c3bdfSopenharmony_ci struct symbol *in; 253f08c3bdfSopenharmony_ci struct expression *down; 254f08c3bdfSopenharmony_ci union { 255f08c3bdfSopenharmony_ci struct ident *ident; 256f08c3bdfSopenharmony_ci struct expression *index; 257f08c3bdfSopenharmony_ci }; 258f08c3bdfSopenharmony_ci }; 259f08c3bdfSopenharmony_ci // EXPR_GENERIC 260f08c3bdfSopenharmony_ci struct { 261f08c3bdfSopenharmony_ci struct expression *control; 262f08c3bdfSopenharmony_ci struct expression *def; 263f08c3bdfSopenharmony_ci struct type_expression *map; 264f08c3bdfSopenharmony_ci }; 265f08c3bdfSopenharmony_ci }; 266f08c3bdfSopenharmony_ci}; 267f08c3bdfSopenharmony_ci 268f08c3bdfSopenharmony_ci/// 269f08c3bdfSopenharmony_ci// Constant expression values 270f08c3bdfSopenharmony_ci// -------------------------- 271f08c3bdfSopenharmony_ci 272f08c3bdfSopenharmony_ci/// 273f08c3bdfSopenharmony_ci// test if an expression evaluates to the constant ``0``. 274f08c3bdfSopenharmony_ci// @return: ``1`` if @expr evaluate to ``0``, 275f08c3bdfSopenharmony_ci// ``0`` otherwise. 276f08c3bdfSopenharmony_ciint is_zero_constant(struct expression *expr); 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_ci/// 279f08c3bdfSopenharmony_ci// test the compile time truth value of an expression 280f08c3bdfSopenharmony_ci// @return: 281f08c3bdfSopenharmony_ci// * ``-1`` if @expr is not constant, 282f08c3bdfSopenharmony_ci// * ``0`` or ``1`` depending on the truth value of @expr. 283f08c3bdfSopenharmony_ciint expr_truth_value(struct expression *expr); 284f08c3bdfSopenharmony_ci 285f08c3bdfSopenharmony_cilong long get_expression_value(struct expression *); 286f08c3bdfSopenharmony_cilong long const_expression_value(struct expression *); 287f08c3bdfSopenharmony_cilong long get_expression_value_silent(struct expression *expr); 288f08c3bdfSopenharmony_ci 289f08c3bdfSopenharmony_ci/* Expression parsing */ 290f08c3bdfSopenharmony_cistruct token *parse_expression(struct token *token, struct expression **tree); 291f08c3bdfSopenharmony_cistruct token *conditional_expression(struct token *token, struct expression **tree); 292f08c3bdfSopenharmony_cistruct token *primary_expression(struct token *token, struct expression **tree); 293f08c3bdfSopenharmony_cistruct token *parens_expression(struct token *token, struct expression **expr, const char *where); 294f08c3bdfSopenharmony_cistruct token *string_expression(struct token *token, struct expression **expr, const char *where); 295f08c3bdfSopenharmony_cistruct token *assignment_expression(struct token *token, struct expression **tree); 296f08c3bdfSopenharmony_ci 297f08c3bdfSopenharmony_ciextern int expand_symbol(struct symbol *); 298f08c3bdfSopenharmony_ci 299f08c3bdfSopenharmony_cistatic inline struct expression *alloc_expression(struct position pos, int type) 300f08c3bdfSopenharmony_ci{ 301f08c3bdfSopenharmony_ci struct expression *expr = __alloc_expression(0); 302f08c3bdfSopenharmony_ci expr->type = type; 303f08c3bdfSopenharmony_ci expr->pos = pos; 304f08c3bdfSopenharmony_ci expr->flags = CEF_NONE; 305f08c3bdfSopenharmony_ci return expr; 306f08c3bdfSopenharmony_ci} 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_cistatic inline struct expression *alloc_const_expression(struct position pos, int value) 309f08c3bdfSopenharmony_ci{ 310f08c3bdfSopenharmony_ci struct expression *expr = __alloc_expression(0); 311f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 312f08c3bdfSopenharmony_ci expr->pos = pos; 313f08c3bdfSopenharmony_ci expr->value = value; 314f08c3bdfSopenharmony_ci expr->ctype = &int_ctype; 315f08c3bdfSopenharmony_ci expr->flags = CEF_SET_INT; 316f08c3bdfSopenharmony_ci return expr; 317f08c3bdfSopenharmony_ci} 318f08c3bdfSopenharmony_ci 319f08c3bdfSopenharmony_ci/* Type name parsing */ 320f08c3bdfSopenharmony_cistruct token *typename(struct token *, struct symbol **, int *); 321f08c3bdfSopenharmony_ci 322f08c3bdfSopenharmony_cistatic inline int lookup_type(struct token *token) 323f08c3bdfSopenharmony_ci{ 324f08c3bdfSopenharmony_ci if (token->pos.type == TOKEN_IDENT) { 325f08c3bdfSopenharmony_ci struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF); 326f08c3bdfSopenharmony_ci return sym && (sym->namespace & NS_TYPEDEF); 327f08c3bdfSopenharmony_ci } 328f08c3bdfSopenharmony_ci return 0; 329f08c3bdfSopenharmony_ci} 330f08c3bdfSopenharmony_ci 331f08c3bdfSopenharmony_ci/* Statement parsing */ 332f08c3bdfSopenharmony_cistruct statement *alloc_statement(struct position pos, int type); 333f08c3bdfSopenharmony_cistruct token *initializer(struct expression **tree, struct token *token); 334f08c3bdfSopenharmony_cistruct token *compound_statement(struct token *, struct statement *); 335f08c3bdfSopenharmony_ci 336f08c3bdfSopenharmony_ci/* The preprocessor calls this 'constant_expression()' */ 337f08c3bdfSopenharmony_ci#define constant_expression(token,tree) conditional_expression(token, tree) 338f08c3bdfSopenharmony_ci 339f08c3bdfSopenharmony_ci/* Cast folding of constant values.. */ 340f08c3bdfSopenharmony_civoid cast_value(struct expression *expr, struct symbol *newtype, 341f08c3bdfSopenharmony_ci struct expression *old, struct symbol *oldtype); 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_ci#endif 344