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