1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * sparse/expression.c 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp. 5f08c3bdfSopenharmony_ci * 2003-2004 Linus Torvalds 6f08c3bdfSopenharmony_ci * 7f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 8f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 9f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights 10f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 12f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions: 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in 15f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23f08c3bdfSopenharmony_ci * THE SOFTWARE. 24f08c3bdfSopenharmony_ci * 25f08c3bdfSopenharmony_ci * This is the expression parsing part of parsing C. 26f08c3bdfSopenharmony_ci */ 27f08c3bdfSopenharmony_ci#include <stdarg.h> 28f08c3bdfSopenharmony_ci#include <stdlib.h> 29f08c3bdfSopenharmony_ci#include <stdio.h> 30f08c3bdfSopenharmony_ci#include <string.h> 31f08c3bdfSopenharmony_ci#include <ctype.h> 32f08c3bdfSopenharmony_ci#include <unistd.h> 33f08c3bdfSopenharmony_ci#include <fcntl.h> 34f08c3bdfSopenharmony_ci#include <errno.h> 35f08c3bdfSopenharmony_ci#include <limits.h> 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci#include "lib.h" 38f08c3bdfSopenharmony_ci#include "allocate.h" 39f08c3bdfSopenharmony_ci#include "token.h" 40f08c3bdfSopenharmony_ci#include "parse.h" 41f08c3bdfSopenharmony_ci#include "symbol.h" 42f08c3bdfSopenharmony_ci#include "scope.h" 43f08c3bdfSopenharmony_ci#include "expression.h" 44f08c3bdfSopenharmony_ci#include "target.h" 45f08c3bdfSopenharmony_ci#include "char.h" 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ciALLOCATOR(type_expression, "type-expr-maps"); 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_cistatic int match_oplist(int op, ...) 50f08c3bdfSopenharmony_ci{ 51f08c3bdfSopenharmony_ci va_list args; 52f08c3bdfSopenharmony_ci int nextop; 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ci va_start(args, op); 55f08c3bdfSopenharmony_ci do { 56f08c3bdfSopenharmony_ci nextop = va_arg(args, int); 57f08c3bdfSopenharmony_ci } while (nextop != 0 && nextop != op); 58f08c3bdfSopenharmony_ci va_end(args); 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci return nextop != 0; 61f08c3bdfSopenharmony_ci} 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic struct token *comma_expression(struct token *, struct expression **); 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_cistruct token *parens_expression(struct token *token, struct expression **expr, const char *where) 66f08c3bdfSopenharmony_ci{ 67f08c3bdfSopenharmony_ci struct token *p; 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci token = expect(token, '(', where); 70f08c3bdfSopenharmony_ci p = token; 71f08c3bdfSopenharmony_ci if (match_op(token, '{')) { 72f08c3bdfSopenharmony_ci struct expression *e = alloc_expression(token->pos, EXPR_STATEMENT); 73f08c3bdfSopenharmony_ci struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND); 74f08c3bdfSopenharmony_ci *expr = e; 75f08c3bdfSopenharmony_ci e->statement = stmt; 76f08c3bdfSopenharmony_ci start_label_scope(); 77f08c3bdfSopenharmony_ci token = compound_statement(token->next, stmt); 78f08c3bdfSopenharmony_ci end_label_scope(); 79f08c3bdfSopenharmony_ci token = expect(token, '}', "at end of statement expression"); 80f08c3bdfSopenharmony_ci } else 81f08c3bdfSopenharmony_ci token = parse_expression(token, expr); 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci if (token == p) 84f08c3bdfSopenharmony_ci sparse_error(token->pos, "an expression is expected before ')'"); 85f08c3bdfSopenharmony_ci return expect(token, ')', where); 86f08c3bdfSopenharmony_ci} 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_cistruct token *string_expression(struct token *token, struct expression **expr, const char *where) 89f08c3bdfSopenharmony_ci{ 90f08c3bdfSopenharmony_ci struct token *next = primary_expression(token, expr); 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci if (!*expr || (*expr)->type != EXPR_STRING) { 93f08c3bdfSopenharmony_ci sparse_error(token->pos, "string literal expected for %s", where); 94f08c3bdfSopenharmony_ci *expr = NULL; 95f08c3bdfSopenharmony_ci } 96f08c3bdfSopenharmony_ci return next; 97f08c3bdfSopenharmony_ci} 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci/* 100f08c3bdfSopenharmony_ci * Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ token 101f08c3bdfSopenharmony_ci * conversion 102f08c3bdfSopenharmony_ci */ 103f08c3bdfSopenharmony_cistatic struct symbol *handle_func(struct token *token) 104f08c3bdfSopenharmony_ci{ 105f08c3bdfSopenharmony_ci struct ident *ident = token->ident; 106f08c3bdfSopenharmony_ci struct symbol *decl, *array; 107f08c3bdfSopenharmony_ci struct string *string; 108f08c3bdfSopenharmony_ci int len; 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci if (ident != &__func___ident && 111f08c3bdfSopenharmony_ci ident != &__FUNCTION___ident && 112f08c3bdfSopenharmony_ci ident != &__PRETTY_FUNCTION___ident) 113f08c3bdfSopenharmony_ci return NULL; 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci if (!current_fn || !current_fn->ident) 116f08c3bdfSopenharmony_ci return NULL; 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci /* OK, it's one of ours */ 119f08c3bdfSopenharmony_ci array = alloc_symbol(token->pos, SYM_ARRAY); 120f08c3bdfSopenharmony_ci array->ctype.base_type = &char_ctype; 121f08c3bdfSopenharmony_ci array->ctype.alignment = 1; 122f08c3bdfSopenharmony_ci array->endpos = token->pos; 123f08c3bdfSopenharmony_ci decl = alloc_symbol(token->pos, SYM_NODE); 124f08c3bdfSopenharmony_ci decl->ctype.base_type = array; 125f08c3bdfSopenharmony_ci decl->ctype.alignment = 1; 126f08c3bdfSopenharmony_ci decl->ctype.modifiers = MOD_STATIC; 127f08c3bdfSopenharmony_ci decl->endpos = token->pos; 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ci /* NS_SYMBOL but in function-scope */ 130f08c3bdfSopenharmony_ci bind_symbol_with_scope(decl, ident, NS_SYMBOL, function_scope); 131f08c3bdfSopenharmony_ci 132f08c3bdfSopenharmony_ci len = current_fn->ident->len; 133f08c3bdfSopenharmony_ci string = __alloc_string(len + 1); 134f08c3bdfSopenharmony_ci memcpy(string->data, current_fn->ident->name, len); 135f08c3bdfSopenharmony_ci string->data[len] = 0; 136f08c3bdfSopenharmony_ci string->length = len + 1; 137f08c3bdfSopenharmony_ci 138f08c3bdfSopenharmony_ci decl->initializer = alloc_expression(token->pos, EXPR_STRING); 139f08c3bdfSopenharmony_ci decl->initializer->string = string; 140f08c3bdfSopenharmony_ci decl->initializer->ctype = decl; 141f08c3bdfSopenharmony_ci decl->array_size = alloc_const_expression(token->pos, len + 1); 142f08c3bdfSopenharmony_ci array->array_size = decl->array_size; 143f08c3bdfSopenharmony_ci decl->bit_size = array->bit_size = bytes_to_bits(len + 1); 144f08c3bdfSopenharmony_ci 145f08c3bdfSopenharmony_ci return decl; 146f08c3bdfSopenharmony_ci} 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_cistatic struct token *parse_type(struct token *token, struct expression **tree) 149f08c3bdfSopenharmony_ci{ 150f08c3bdfSopenharmony_ci struct symbol *sym; 151f08c3bdfSopenharmony_ci *tree = alloc_expression(token->pos, EXPR_TYPE); 152f08c3bdfSopenharmony_ci token = typename(token, &sym, NULL); 153f08c3bdfSopenharmony_ci if (sym->ident) 154f08c3bdfSopenharmony_ci sparse_error(token->pos, 155f08c3bdfSopenharmony_ci "type expression should not include identifier " 156f08c3bdfSopenharmony_ci "\"%s\"", sym->ident->name); 157f08c3bdfSopenharmony_ci (*tree)->symbol = sym; 158f08c3bdfSopenharmony_ci return token; 159f08c3bdfSopenharmony_ci} 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_cistatic struct token *builtin_types_compatible_p_expr(struct token *token, 162f08c3bdfSopenharmony_ci struct expression **tree) 163f08c3bdfSopenharmony_ci{ 164f08c3bdfSopenharmony_ci struct expression *expr = alloc_expression( 165f08c3bdfSopenharmony_ci token->pos, EXPR_COMPARE); 166f08c3bdfSopenharmony_ci expr->op = SPECIAL_EQUAL; 167f08c3bdfSopenharmony_ci token = token->next; 168f08c3bdfSopenharmony_ci if (!match_op(token, '(')) 169f08c3bdfSopenharmony_ci return expect(token, '(', 170f08c3bdfSopenharmony_ci "after __builtin_types_compatible_p"); 171f08c3bdfSopenharmony_ci token = token->next; 172f08c3bdfSopenharmony_ci token = parse_type(token, &expr->left); 173f08c3bdfSopenharmony_ci if (!match_op(token, ',')) 174f08c3bdfSopenharmony_ci return expect(token, ',', 175f08c3bdfSopenharmony_ci "in __builtin_types_compatible_p"); 176f08c3bdfSopenharmony_ci token = token->next; 177f08c3bdfSopenharmony_ci token = parse_type(token, &expr->right); 178f08c3bdfSopenharmony_ci if (!match_op(token, ')')) 179f08c3bdfSopenharmony_ci return expect(token, ')', 180f08c3bdfSopenharmony_ci "at end of __builtin_types_compatible_p"); 181f08c3bdfSopenharmony_ci token = token->next; 182f08c3bdfSopenharmony_ci 183f08c3bdfSopenharmony_ci *tree = expr; 184f08c3bdfSopenharmony_ci return token; 185f08c3bdfSopenharmony_ci} 186f08c3bdfSopenharmony_ci 187f08c3bdfSopenharmony_cistatic struct token *builtin_offsetof_expr(struct token *token, 188f08c3bdfSopenharmony_ci struct expression **tree) 189f08c3bdfSopenharmony_ci{ 190f08c3bdfSopenharmony_ci struct expression *expr = NULL; 191f08c3bdfSopenharmony_ci struct expression **p = &expr; 192f08c3bdfSopenharmony_ci struct symbol *sym; 193f08c3bdfSopenharmony_ci int op = '.'; 194f08c3bdfSopenharmony_ci 195f08c3bdfSopenharmony_ci token = token->next; 196f08c3bdfSopenharmony_ci if (!match_op(token, '(')) 197f08c3bdfSopenharmony_ci return expect(token, '(', "after __builtin_offset"); 198f08c3bdfSopenharmony_ci 199f08c3bdfSopenharmony_ci token = token->next; 200f08c3bdfSopenharmony_ci token = typename(token, &sym, NULL); 201f08c3bdfSopenharmony_ci if (sym->ident) 202f08c3bdfSopenharmony_ci sparse_error(token->pos, 203f08c3bdfSopenharmony_ci "type expression should not include identifier " 204f08c3bdfSopenharmony_ci "\"%s\"", sym->ident->name); 205f08c3bdfSopenharmony_ci 206f08c3bdfSopenharmony_ci if (!match_op(token, ',')) 207f08c3bdfSopenharmony_ci return expect(token, ',', "in __builtin_offset"); 208f08c3bdfSopenharmony_ci 209f08c3bdfSopenharmony_ci while (1) { 210f08c3bdfSopenharmony_ci struct expression *e; 211f08c3bdfSopenharmony_ci switch (op) { 212f08c3bdfSopenharmony_ci case ')': 213f08c3bdfSopenharmony_ci expr->in = sym; 214f08c3bdfSopenharmony_ci *tree = expr; 215f08c3bdfSopenharmony_ci default: 216f08c3bdfSopenharmony_ci return expect(token, ')', "at end of __builtin_offset"); 217f08c3bdfSopenharmony_ci case SPECIAL_DEREFERENCE: 218f08c3bdfSopenharmony_ci e = alloc_expression(token->pos, EXPR_OFFSETOF); 219f08c3bdfSopenharmony_ci e->op = '['; 220f08c3bdfSopenharmony_ci *p = e; 221f08c3bdfSopenharmony_ci p = &e->down; 222f08c3bdfSopenharmony_ci /* fall through */ 223f08c3bdfSopenharmony_ci case '.': 224f08c3bdfSopenharmony_ci token = token->next; 225f08c3bdfSopenharmony_ci e = alloc_expression(token->pos, EXPR_OFFSETOF); 226f08c3bdfSopenharmony_ci e->op = '.'; 227f08c3bdfSopenharmony_ci if (token_type(token) != TOKEN_IDENT) { 228f08c3bdfSopenharmony_ci sparse_error(token->pos, "Expected member name"); 229f08c3bdfSopenharmony_ci return token; 230f08c3bdfSopenharmony_ci } 231f08c3bdfSopenharmony_ci e->ident = token->ident; 232f08c3bdfSopenharmony_ci token = token->next; 233f08c3bdfSopenharmony_ci break; 234f08c3bdfSopenharmony_ci case '[': 235f08c3bdfSopenharmony_ci token = token->next; 236f08c3bdfSopenharmony_ci e = alloc_expression(token->pos, EXPR_OFFSETOF); 237f08c3bdfSopenharmony_ci e->op = '['; 238f08c3bdfSopenharmony_ci token = parse_expression(token, &e->index); 239f08c3bdfSopenharmony_ci token = expect(token, ']', 240f08c3bdfSopenharmony_ci "at end of array dereference"); 241f08c3bdfSopenharmony_ci if (!e->index) 242f08c3bdfSopenharmony_ci return token; 243f08c3bdfSopenharmony_ci } 244f08c3bdfSopenharmony_ci *p = e; 245f08c3bdfSopenharmony_ci p = &e->down; 246f08c3bdfSopenharmony_ci op = token_type(token) == TOKEN_SPECIAL ? token->special : 0; 247f08c3bdfSopenharmony_ci } 248f08c3bdfSopenharmony_ci} 249f08c3bdfSopenharmony_ci 250f08c3bdfSopenharmony_ci#ifndef ULLONG_MAX 251f08c3bdfSopenharmony_ci#define ULLONG_MAX (~0ULL) 252f08c3bdfSopenharmony_ci#endif 253f08c3bdfSopenharmony_ci 254f08c3bdfSopenharmony_cistatic unsigned long long parse_num(const char *nptr, char **end) 255f08c3bdfSopenharmony_ci{ 256f08c3bdfSopenharmony_ci if (nptr[0] == '0' && tolower((unsigned char)nptr[1]) == 'b') 257f08c3bdfSopenharmony_ci return strtoull(&nptr[2], end, 2); 258f08c3bdfSopenharmony_ci return strtoull(nptr, end, 0); 259f08c3bdfSopenharmony_ci} 260f08c3bdfSopenharmony_ci 261f08c3bdfSopenharmony_cistatic void get_number_value(struct expression *expr, struct token *token) 262f08c3bdfSopenharmony_ci{ 263f08c3bdfSopenharmony_ci const char *str = token->number; 264f08c3bdfSopenharmony_ci unsigned long long value; 265f08c3bdfSopenharmony_ci char *end; 266f08c3bdfSopenharmony_ci int size = 0, want_unsigned = 0; 267f08c3bdfSopenharmony_ci int overflow = 0, do_warn = 0; 268f08c3bdfSopenharmony_ci int try_unsigned = 1; 269f08c3bdfSopenharmony_ci int bits; 270f08c3bdfSopenharmony_ci 271f08c3bdfSopenharmony_ci errno = 0; 272f08c3bdfSopenharmony_ci value = parse_num(str, &end); 273f08c3bdfSopenharmony_ci if (end == str) 274f08c3bdfSopenharmony_ci goto Float; 275f08c3bdfSopenharmony_ci if (value == ULLONG_MAX && errno == ERANGE) 276f08c3bdfSopenharmony_ci overflow = 1; 277f08c3bdfSopenharmony_ci while (1) { 278f08c3bdfSopenharmony_ci char c = *end++; 279f08c3bdfSopenharmony_ci if (!c) { 280f08c3bdfSopenharmony_ci break; 281f08c3bdfSopenharmony_ci } else if (c == 'u' || c == 'U') { 282f08c3bdfSopenharmony_ci if (want_unsigned) 283f08c3bdfSopenharmony_ci goto Enoint; 284f08c3bdfSopenharmony_ci want_unsigned = 1; 285f08c3bdfSopenharmony_ci } else if (c == 'l' || c == 'L') { 286f08c3bdfSopenharmony_ci if (size) 287f08c3bdfSopenharmony_ci goto Enoint; 288f08c3bdfSopenharmony_ci size = 1; 289f08c3bdfSopenharmony_ci if (*end == c) { 290f08c3bdfSopenharmony_ci size = 2; 291f08c3bdfSopenharmony_ci end++; 292f08c3bdfSopenharmony_ci } 293f08c3bdfSopenharmony_ci } else 294f08c3bdfSopenharmony_ci goto Float; 295f08c3bdfSopenharmony_ci } 296f08c3bdfSopenharmony_ci if (overflow) 297f08c3bdfSopenharmony_ci goto Eoverflow; 298f08c3bdfSopenharmony_ci /* OK, it's a valid integer */ 299f08c3bdfSopenharmony_ci /* decimals can be unsigned only if directly specified as such */ 300f08c3bdfSopenharmony_ci if (str[0] != '0' && !want_unsigned) 301f08c3bdfSopenharmony_ci try_unsigned = 0; 302f08c3bdfSopenharmony_ci if (!size) { 303f08c3bdfSopenharmony_ci bits = bits_in_int - 1; 304f08c3bdfSopenharmony_ci if (!(value & (~1ULL << bits))) { 305f08c3bdfSopenharmony_ci if (!(value & (1ULL << bits))) { 306f08c3bdfSopenharmony_ci goto got_it; 307f08c3bdfSopenharmony_ci } else if (try_unsigned) { 308f08c3bdfSopenharmony_ci want_unsigned = 1; 309f08c3bdfSopenharmony_ci goto got_it; 310f08c3bdfSopenharmony_ci } 311f08c3bdfSopenharmony_ci } 312f08c3bdfSopenharmony_ci size = 1; 313f08c3bdfSopenharmony_ci do_warn = 1; 314f08c3bdfSopenharmony_ci } 315f08c3bdfSopenharmony_ci if (size < 2) { 316f08c3bdfSopenharmony_ci bits = bits_in_long - 1; 317f08c3bdfSopenharmony_ci if (!(value & (~1ULL << bits))) { 318f08c3bdfSopenharmony_ci if (!(value & (1ULL << bits))) { 319f08c3bdfSopenharmony_ci goto got_it; 320f08c3bdfSopenharmony_ci } else if (try_unsigned) { 321f08c3bdfSopenharmony_ci want_unsigned = 1; 322f08c3bdfSopenharmony_ci goto got_it; 323f08c3bdfSopenharmony_ci } 324f08c3bdfSopenharmony_ci do_warn |= 2; 325f08c3bdfSopenharmony_ci } 326f08c3bdfSopenharmony_ci size = 2; 327f08c3bdfSopenharmony_ci do_warn |= 1; 328f08c3bdfSopenharmony_ci } 329f08c3bdfSopenharmony_ci bits = bits_in_longlong - 1; 330f08c3bdfSopenharmony_ci if (value & (~1ULL << bits)) 331f08c3bdfSopenharmony_ci goto Eoverflow; 332f08c3bdfSopenharmony_ci if (!(value & (1ULL << bits))) 333f08c3bdfSopenharmony_ci goto got_it; 334f08c3bdfSopenharmony_ci if (!try_unsigned) 335f08c3bdfSopenharmony_ci warning(expr->pos, "decimal constant %s is too big for long long", 336f08c3bdfSopenharmony_ci show_token(token)); 337f08c3bdfSopenharmony_ci want_unsigned = 1; 338f08c3bdfSopenharmony_cigot_it: 339f08c3bdfSopenharmony_ci if (do_warn && Wconstant_suffix) 340f08c3bdfSopenharmony_ci warning(expr->pos, "constant %s is so big it is%s%s%s", 341f08c3bdfSopenharmony_ci show_token(token), 342f08c3bdfSopenharmony_ci want_unsigned ? " unsigned":"", 343f08c3bdfSopenharmony_ci size > 0 ? " long":"", 344f08c3bdfSopenharmony_ci size > 1 ? " long":""); 345f08c3bdfSopenharmony_ci if (do_warn & 2) 346f08c3bdfSopenharmony_ci warning(expr->pos, 347f08c3bdfSopenharmony_ci "decimal constant %s is between LONG_MAX and ULONG_MAX." 348f08c3bdfSopenharmony_ci " For C99 that means long long, C90 compilers are very " 349f08c3bdfSopenharmony_ci "likely to produce unsigned long (and a warning) here", 350f08c3bdfSopenharmony_ci show_token(token)); 351f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 352f08c3bdfSopenharmony_ci expr->flags = CEF_SET_INT; 353f08c3bdfSopenharmony_ci expr->ctype = ctype_integer(size, want_unsigned); 354f08c3bdfSopenharmony_ci expr->value = value; 355f08c3bdfSopenharmony_ci return; 356f08c3bdfSopenharmony_ciEoverflow: 357f08c3bdfSopenharmony_ci error_die(expr->pos, "constant %s is too big even for unsigned long long", 358f08c3bdfSopenharmony_ci show_token(token)); 359f08c3bdfSopenharmony_ci return; 360f08c3bdfSopenharmony_ciFloat: 361f08c3bdfSopenharmony_ci expr->fvalue = string_to_ld(str, &end); 362f08c3bdfSopenharmony_ci if (str == end) 363f08c3bdfSopenharmony_ci goto Enoint; 364f08c3bdfSopenharmony_ci 365f08c3bdfSopenharmony_ci if (*end && end[1]) 366f08c3bdfSopenharmony_ci goto Enoint; 367f08c3bdfSopenharmony_ci 368f08c3bdfSopenharmony_ci if (*end == 'f' || *end == 'F') 369f08c3bdfSopenharmony_ci expr->ctype = &float_ctype; 370f08c3bdfSopenharmony_ci else if (*end == 'l' || *end == 'L') 371f08c3bdfSopenharmony_ci expr->ctype = &ldouble_ctype; 372f08c3bdfSopenharmony_ci else if (!*end) 373f08c3bdfSopenharmony_ci expr->ctype = &double_ctype; 374f08c3bdfSopenharmony_ci else 375f08c3bdfSopenharmony_ci goto Enoint; 376f08c3bdfSopenharmony_ci 377f08c3bdfSopenharmony_ci expr->flags = CEF_SET_FLOAT; 378f08c3bdfSopenharmony_ci expr->type = EXPR_FVALUE; 379f08c3bdfSopenharmony_ci return; 380f08c3bdfSopenharmony_ci 381f08c3bdfSopenharmony_ciEnoint: 382f08c3bdfSopenharmony_ci sparse_error(expr->pos, "constant %s is not a valid number", show_token(token)); 383f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 384f08c3bdfSopenharmony_ci expr->value = 0; 385f08c3bdfSopenharmony_ci expr->ctype = &int_ctype; 386f08c3bdfSopenharmony_ci} 387f08c3bdfSopenharmony_ci 388f08c3bdfSopenharmony_cistatic struct token *generic_selection(struct token *token, struct expression **tree) 389f08c3bdfSopenharmony_ci{ 390f08c3bdfSopenharmony_ci struct expression *expr = alloc_expression(token->pos, EXPR_GENERIC); 391f08c3bdfSopenharmony_ci struct type_expression **last = &expr->map; 392f08c3bdfSopenharmony_ci 393f08c3bdfSopenharmony_ci token = expect(token, '(', "after '_Generic'"); 394f08c3bdfSopenharmony_ci token = assignment_expression(token, &expr->control); 395f08c3bdfSopenharmony_ci if (!match_op(token, ',')) { 396f08c3bdfSopenharmony_ci goto end; 397f08c3bdfSopenharmony_ci } 398f08c3bdfSopenharmony_ci while (match_op(token, ',')) { 399f08c3bdfSopenharmony_ci token = token->next; 400f08c3bdfSopenharmony_ci if (lookup_type(token)) { 401f08c3bdfSopenharmony_ci struct type_expression *map = __alloc_type_expression(0); 402f08c3bdfSopenharmony_ci token = typename(token, &map->type, NULL); 403f08c3bdfSopenharmony_ci token = expect(token, ':', "after typename"); 404f08c3bdfSopenharmony_ci token = assignment_expression(token, &map->expr); 405f08c3bdfSopenharmony_ci *last = map; 406f08c3bdfSopenharmony_ci last = &map->next; 407f08c3bdfSopenharmony_ci } else if (match_ident(token, &default_ident)) { 408f08c3bdfSopenharmony_ci if (expr->def) { 409f08c3bdfSopenharmony_ci warning(token->pos, "multiple default in generic expression"); 410f08c3bdfSopenharmony_ci info(expr->def->pos, "note: previous was here"); 411f08c3bdfSopenharmony_ci } 412f08c3bdfSopenharmony_ci token = token->next; 413f08c3bdfSopenharmony_ci token = expect(token, ':', "after typename"); 414f08c3bdfSopenharmony_ci token = assignment_expression(token, &expr->def); 415f08c3bdfSopenharmony_ci } 416f08c3bdfSopenharmony_ci } 417f08c3bdfSopenharmony_ciend: 418f08c3bdfSopenharmony_ci *tree = expr; 419f08c3bdfSopenharmony_ci return expect(token, ')', "after expression"); 420f08c3bdfSopenharmony_ci} 421f08c3bdfSopenharmony_ci 422f08c3bdfSopenharmony_cistruct token *primary_expression(struct token *token, struct expression **tree) 423f08c3bdfSopenharmony_ci{ 424f08c3bdfSopenharmony_ci struct expression *expr = NULL; 425f08c3bdfSopenharmony_ci 426f08c3bdfSopenharmony_ci switch (token_type(token)) { 427f08c3bdfSopenharmony_ci case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3: 428f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_VALUE); 429f08c3bdfSopenharmony_ci expr->flags = CEF_SET_CHAR; 430f08c3bdfSopenharmony_ci expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype; 431f08c3bdfSopenharmony_ci get_char_constant(token, &expr->value); 432f08c3bdfSopenharmony_ci token = token->next; 433f08c3bdfSopenharmony_ci break; 434f08c3bdfSopenharmony_ci 435f08c3bdfSopenharmony_ci case TOKEN_NUMBER: 436f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_VALUE); 437f08c3bdfSopenharmony_ci get_number_value(expr, token); /* will see if it's an integer */ 438f08c3bdfSopenharmony_ci token = token->next; 439f08c3bdfSopenharmony_ci break; 440f08c3bdfSopenharmony_ci 441f08c3bdfSopenharmony_ci case TOKEN_ZERO_IDENT: { 442f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_SYMBOL); 443f08c3bdfSopenharmony_ci expr->flags = CEF_SET_INT; 444f08c3bdfSopenharmony_ci expr->ctype = &int_ctype; 445f08c3bdfSopenharmony_ci expr->symbol = &zero_int; 446f08c3bdfSopenharmony_ci expr->symbol_name = token->ident; 447f08c3bdfSopenharmony_ci token = token->next; 448f08c3bdfSopenharmony_ci break; 449f08c3bdfSopenharmony_ci } 450f08c3bdfSopenharmony_ci 451f08c3bdfSopenharmony_ci case TOKEN_IDENT: { 452f08c3bdfSopenharmony_ci struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF); 453f08c3bdfSopenharmony_ci struct token *next = token->next; 454f08c3bdfSopenharmony_ci 455f08c3bdfSopenharmony_ci if (!sym) { 456f08c3bdfSopenharmony_ci sym = handle_func(token); 457f08c3bdfSopenharmony_ci if (token->ident == &__builtin_types_compatible_p_ident) { 458f08c3bdfSopenharmony_ci token = builtin_types_compatible_p_expr(token, &expr); 459f08c3bdfSopenharmony_ci break; 460f08c3bdfSopenharmony_ci } 461f08c3bdfSopenharmony_ci if (token->ident == &__builtin_offsetof_ident) { 462f08c3bdfSopenharmony_ci token = builtin_offsetof_expr(token, &expr); 463f08c3bdfSopenharmony_ci break; 464f08c3bdfSopenharmony_ci } 465f08c3bdfSopenharmony_ci if (token->ident == &_Generic_ident) { 466f08c3bdfSopenharmony_ci token = generic_selection(token->next, &expr); 467f08c3bdfSopenharmony_ci break; 468f08c3bdfSopenharmony_ci } 469f08c3bdfSopenharmony_ci } else if (sym->enum_member) { 470f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_VALUE); 471f08c3bdfSopenharmony_ci *expr = *sym->initializer; 472f08c3bdfSopenharmony_ci /* we want the right position reported, thus the copy */ 473f08c3bdfSopenharmony_ci expr->pos = token->pos; 474f08c3bdfSopenharmony_ci expr->flags = CEF_SET_ENUM; 475f08c3bdfSopenharmony_ci token = next; 476f08c3bdfSopenharmony_ci break; 477f08c3bdfSopenharmony_ci } 478f08c3bdfSopenharmony_ci 479f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_SYMBOL); 480f08c3bdfSopenharmony_ci 481f08c3bdfSopenharmony_ci /* 482f08c3bdfSopenharmony_ci * We support types as real first-class citizens, with type 483f08c3bdfSopenharmony_ci * comparisons etc: 484f08c3bdfSopenharmony_ci * 485f08c3bdfSopenharmony_ci * if (typeof(a) == int) .. 486f08c3bdfSopenharmony_ci */ 487f08c3bdfSopenharmony_ci if (sym && sym->namespace == NS_TYPEDEF) { 488f08c3bdfSopenharmony_ci sparse_error(token->pos, "typename in expression"); 489f08c3bdfSopenharmony_ci sym = NULL; 490f08c3bdfSopenharmony_ci } 491f08c3bdfSopenharmony_ci expr->symbol_name = token->ident; 492f08c3bdfSopenharmony_ci expr->symbol = sym; 493f08c3bdfSopenharmony_ci 494f08c3bdfSopenharmony_ci /* 495f08c3bdfSopenharmony_ci * A pointer to an lvalue designating a static storage 496f08c3bdfSopenharmony_ci * duration object is an address constant [6.6(9)]. 497f08c3bdfSopenharmony_ci */ 498f08c3bdfSopenharmony_ci if (sym && (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC))) 499f08c3bdfSopenharmony_ci expr->flags = CEF_ADDR; 500f08c3bdfSopenharmony_ci 501f08c3bdfSopenharmony_ci token = next; 502f08c3bdfSopenharmony_ci break; 503f08c3bdfSopenharmony_ci } 504f08c3bdfSopenharmony_ci 505f08c3bdfSopenharmony_ci case TOKEN_STRING: 506f08c3bdfSopenharmony_ci case TOKEN_WIDE_STRING: 507f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_STRING); 508f08c3bdfSopenharmony_ci token = get_string_constant(token, expr); 509f08c3bdfSopenharmony_ci break; 510f08c3bdfSopenharmony_ci 511f08c3bdfSopenharmony_ci case TOKEN_SPECIAL: 512f08c3bdfSopenharmony_ci if (token->special == '(') { 513f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_PREOP); 514f08c3bdfSopenharmony_ci expr->op = '('; 515f08c3bdfSopenharmony_ci token = parens_expression(token, &expr->unop, "in expression"); 516f08c3bdfSopenharmony_ci break; 517f08c3bdfSopenharmony_ci } 518f08c3bdfSopenharmony_ci if (token->special == '[' && lookup_type(token->next)) { 519f08c3bdfSopenharmony_ci expr = alloc_expression(token->pos, EXPR_TYPE); 520f08c3bdfSopenharmony_ci token = typename(token->next, &expr->symbol, NULL); 521f08c3bdfSopenharmony_ci token = expect(token, ']', "in type expression"); 522f08c3bdfSopenharmony_ci break; 523f08c3bdfSopenharmony_ci } 524f08c3bdfSopenharmony_ci 525f08c3bdfSopenharmony_ci default: 526f08c3bdfSopenharmony_ci ; 527f08c3bdfSopenharmony_ci } 528f08c3bdfSopenharmony_ci *tree = expr; 529f08c3bdfSopenharmony_ci return token; 530f08c3bdfSopenharmony_ci} 531f08c3bdfSopenharmony_ci 532f08c3bdfSopenharmony_cistatic struct token *expression_list(struct token *token, struct expression_list **list) 533f08c3bdfSopenharmony_ci{ 534f08c3bdfSopenharmony_ci while (!match_op(token, ')')) { 535f08c3bdfSopenharmony_ci struct expression *expr = NULL; 536f08c3bdfSopenharmony_ci token = assignment_expression(token, &expr); 537f08c3bdfSopenharmony_ci if (!expr) 538f08c3bdfSopenharmony_ci break; 539f08c3bdfSopenharmony_ci add_expression(list, expr); 540f08c3bdfSopenharmony_ci if (!match_op(token, ',')) 541f08c3bdfSopenharmony_ci break; 542f08c3bdfSopenharmony_ci token = token->next; 543f08c3bdfSopenharmony_ci } 544f08c3bdfSopenharmony_ci return token; 545f08c3bdfSopenharmony_ci} 546f08c3bdfSopenharmony_ci 547f08c3bdfSopenharmony_ci/* 548f08c3bdfSopenharmony_ci * extend to deal with the ambiguous C grammar for parsing 549f08c3bdfSopenharmony_ci * a cast expressions followed by an initializer. 550f08c3bdfSopenharmony_ci */ 551f08c3bdfSopenharmony_cistatic struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr) 552f08c3bdfSopenharmony_ci{ 553f08c3bdfSopenharmony_ci struct expression *expr = cast_init_expr; 554f08c3bdfSopenharmony_ci 555f08c3bdfSopenharmony_ci if (!expr) 556f08c3bdfSopenharmony_ci token = primary_expression(token, &expr); 557f08c3bdfSopenharmony_ci 558f08c3bdfSopenharmony_ci while (expr && token_type(token) == TOKEN_SPECIAL) { 559f08c3bdfSopenharmony_ci switch (token->special) { 560f08c3bdfSopenharmony_ci case '[': { /* Array dereference */ 561f08c3bdfSopenharmony_ci struct expression *deref = alloc_expression(token->pos, EXPR_PREOP); 562f08c3bdfSopenharmony_ci struct expression *add = alloc_expression(token->pos, EXPR_BINOP); 563f08c3bdfSopenharmony_ci 564f08c3bdfSopenharmony_ci deref->op = '*'; 565f08c3bdfSopenharmony_ci deref->unop = add; 566f08c3bdfSopenharmony_ci 567f08c3bdfSopenharmony_ci add->op = '+'; 568f08c3bdfSopenharmony_ci add->left = expr; 569f08c3bdfSopenharmony_ci token = parse_expression(token->next, &add->right); 570f08c3bdfSopenharmony_ci token = expect(token, ']', "at end of array dereference"); 571f08c3bdfSopenharmony_ci expr = deref; 572f08c3bdfSopenharmony_ci continue; 573f08c3bdfSopenharmony_ci } 574f08c3bdfSopenharmony_ci case SPECIAL_INCREMENT: /* Post-increment */ 575f08c3bdfSopenharmony_ci case SPECIAL_DECREMENT: { /* Post-decrement */ 576f08c3bdfSopenharmony_ci struct expression *post = alloc_expression(token->pos, EXPR_POSTOP); 577f08c3bdfSopenharmony_ci post->op = token->special; 578f08c3bdfSopenharmony_ci post->unop = expr; 579f08c3bdfSopenharmony_ci expr = post; 580f08c3bdfSopenharmony_ci token = token->next; 581f08c3bdfSopenharmony_ci continue; 582f08c3bdfSopenharmony_ci } 583f08c3bdfSopenharmony_ci case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */ 584f08c3bdfSopenharmony_ci /* "x->y" is just shorthand for "(*x).y" */ 585f08c3bdfSopenharmony_ci struct expression *inner = alloc_expression(token->pos, EXPR_PREOP); 586f08c3bdfSopenharmony_ci inner->op = '*'; 587f08c3bdfSopenharmony_ci inner->unop = expr; 588f08c3bdfSopenharmony_ci expr = inner; 589f08c3bdfSopenharmony_ci } 590f08c3bdfSopenharmony_ci /* Fall through!! */ 591f08c3bdfSopenharmony_ci case '.': { /* Structure member dereference */ 592f08c3bdfSopenharmony_ci struct expression *deref = alloc_expression(token->pos, EXPR_DEREF); 593f08c3bdfSopenharmony_ci deref->op = '.'; 594f08c3bdfSopenharmony_ci deref->deref = expr; 595f08c3bdfSopenharmony_ci token = token->next; 596f08c3bdfSopenharmony_ci if (token_type(token) != TOKEN_IDENT) { 597f08c3bdfSopenharmony_ci sparse_error(token->pos, "Expected member name"); 598f08c3bdfSopenharmony_ci break; 599f08c3bdfSopenharmony_ci } 600f08c3bdfSopenharmony_ci deref->member = token->ident; 601f08c3bdfSopenharmony_ci token = token->next; 602f08c3bdfSopenharmony_ci expr = deref; 603f08c3bdfSopenharmony_ci continue; 604f08c3bdfSopenharmony_ci } 605f08c3bdfSopenharmony_ci 606f08c3bdfSopenharmony_ci case '(': { /* Function call */ 607f08c3bdfSopenharmony_ci struct expression *call = alloc_expression(token->pos, EXPR_CALL); 608f08c3bdfSopenharmony_ci call->op = '('; 609f08c3bdfSopenharmony_ci call->fn = expr; 610f08c3bdfSopenharmony_ci token = expression_list(token->next, &call->args); 611f08c3bdfSopenharmony_ci token = expect(token, ')', "in function call"); 612f08c3bdfSopenharmony_ci expr = call; 613f08c3bdfSopenharmony_ci continue; 614f08c3bdfSopenharmony_ci } 615f08c3bdfSopenharmony_ci 616f08c3bdfSopenharmony_ci default: 617f08c3bdfSopenharmony_ci break; 618f08c3bdfSopenharmony_ci } 619f08c3bdfSopenharmony_ci break; 620f08c3bdfSopenharmony_ci } 621f08c3bdfSopenharmony_ci *tree = expr; 622f08c3bdfSopenharmony_ci return token; 623f08c3bdfSopenharmony_ci} 624f08c3bdfSopenharmony_ci 625f08c3bdfSopenharmony_cistatic struct token *cast_expression(struct token *token, struct expression **tree); 626f08c3bdfSopenharmony_cistatic struct token *unary_expression(struct token *token, struct expression **tree); 627f08c3bdfSopenharmony_ci 628f08c3bdfSopenharmony_cistatic struct token *type_info_expression(struct token *token, 629f08c3bdfSopenharmony_ci struct expression **tree, int type) 630f08c3bdfSopenharmony_ci{ 631f08c3bdfSopenharmony_ci struct expression *expr = alloc_expression(token->pos, type); 632f08c3bdfSopenharmony_ci struct token *p; 633f08c3bdfSopenharmony_ci 634f08c3bdfSopenharmony_ci *tree = expr; 635f08c3bdfSopenharmony_ci expr->flags = CEF_SET_ICE; /* XXX: VLA support will need that changed */ 636f08c3bdfSopenharmony_ci token = token->next; 637f08c3bdfSopenharmony_ci if (!match_op(token, '(') || !lookup_type(token->next)) 638f08c3bdfSopenharmony_ci return unary_expression(token, &expr->cast_expression); 639f08c3bdfSopenharmony_ci p = token; 640f08c3bdfSopenharmony_ci token = typename(token->next, &expr->cast_type, NULL); 641f08c3bdfSopenharmony_ci 642f08c3bdfSopenharmony_ci if (!match_op(token, ')')) { 643f08c3bdfSopenharmony_ci static const char * error[] = { 644f08c3bdfSopenharmony_ci [EXPR_SIZEOF] = "at end of sizeof", 645f08c3bdfSopenharmony_ci [EXPR_ALIGNOF] = "at end of __alignof__", 646f08c3bdfSopenharmony_ci [EXPR_PTRSIZEOF] = "at end of __sizeof_ptr__" 647f08c3bdfSopenharmony_ci }; 648f08c3bdfSopenharmony_ci return expect(token, ')', error[type]); 649f08c3bdfSopenharmony_ci } 650f08c3bdfSopenharmony_ci 651f08c3bdfSopenharmony_ci token = token->next; 652f08c3bdfSopenharmony_ci /* 653f08c3bdfSopenharmony_ci * C99 ambiguity: the typename might have been the beginning 654f08c3bdfSopenharmony_ci * of a typed initializer expression.. 655f08c3bdfSopenharmony_ci */ 656f08c3bdfSopenharmony_ci if (match_op(token, '{')) { 657f08c3bdfSopenharmony_ci struct expression *cast = alloc_expression(p->pos, EXPR_CAST); 658f08c3bdfSopenharmony_ci cast->cast_type = expr->cast_type; 659f08c3bdfSopenharmony_ci expr->cast_type = NULL; 660f08c3bdfSopenharmony_ci expr->cast_expression = cast; 661f08c3bdfSopenharmony_ci token = initializer(&cast->cast_expression, token); 662f08c3bdfSopenharmony_ci token = postfix_expression(token, &expr->cast_expression, cast); 663f08c3bdfSopenharmony_ci } 664f08c3bdfSopenharmony_ci return token; 665f08c3bdfSopenharmony_ci} 666f08c3bdfSopenharmony_ci 667f08c3bdfSopenharmony_cistatic struct token *unary_expression(struct token *token, struct expression **tree) 668f08c3bdfSopenharmony_ci{ 669f08c3bdfSopenharmony_ci if (token_type(token) == TOKEN_IDENT) { 670f08c3bdfSopenharmony_ci struct ident *ident = token->ident; 671f08c3bdfSopenharmony_ci if (ident->reserved) { 672f08c3bdfSopenharmony_ci static const struct { 673f08c3bdfSopenharmony_ci struct ident *id; 674f08c3bdfSopenharmony_ci int type; 675f08c3bdfSopenharmony_ci } type_information[] = { 676f08c3bdfSopenharmony_ci { &sizeof_ident, EXPR_SIZEOF }, 677f08c3bdfSopenharmony_ci { &__alignof___ident, EXPR_ALIGNOF }, 678f08c3bdfSopenharmony_ci { &__alignof_ident, EXPR_ALIGNOF }, 679f08c3bdfSopenharmony_ci { &_Alignof_ident, EXPR_ALIGNOF }, 680f08c3bdfSopenharmony_ci { &__sizeof_ptr___ident, EXPR_PTRSIZEOF }, 681f08c3bdfSopenharmony_ci }; 682f08c3bdfSopenharmony_ci int i; 683f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(type_information); i++) { 684f08c3bdfSopenharmony_ci if (ident == type_information[i].id) 685f08c3bdfSopenharmony_ci return type_info_expression(token, tree, type_information[i].type); 686f08c3bdfSopenharmony_ci } 687f08c3bdfSopenharmony_ci } 688f08c3bdfSopenharmony_ci } 689f08c3bdfSopenharmony_ci 690f08c3bdfSopenharmony_ci if (token_type(token) == TOKEN_SPECIAL) { 691f08c3bdfSopenharmony_ci if (match_oplist(token->special, 692f08c3bdfSopenharmony_ci SPECIAL_INCREMENT, SPECIAL_DECREMENT, 693f08c3bdfSopenharmony_ci '&', '*', 0)) { 694f08c3bdfSopenharmony_ci struct expression *unop; 695f08c3bdfSopenharmony_ci struct expression *unary; 696f08c3bdfSopenharmony_ci struct token *next; 697f08c3bdfSopenharmony_ci 698f08c3bdfSopenharmony_ci next = cast_expression(token->next, &unop); 699f08c3bdfSopenharmony_ci if (!unop) { 700f08c3bdfSopenharmony_ci sparse_error(token->pos, "Syntax error in unary expression"); 701f08c3bdfSopenharmony_ci *tree = NULL; 702f08c3bdfSopenharmony_ci return next; 703f08c3bdfSopenharmony_ci } 704f08c3bdfSopenharmony_ci unary = alloc_expression(token->pos, EXPR_PREOP); 705f08c3bdfSopenharmony_ci unary->op = token->special; 706f08c3bdfSopenharmony_ci unary->unop = unop; 707f08c3bdfSopenharmony_ci *tree = unary; 708f08c3bdfSopenharmony_ci return next; 709f08c3bdfSopenharmony_ci } 710f08c3bdfSopenharmony_ci /* possibly constant ones */ 711f08c3bdfSopenharmony_ci if (match_oplist(token->special, '+', '-', '~', '!', 0)) { 712f08c3bdfSopenharmony_ci struct expression *unop; 713f08c3bdfSopenharmony_ci struct expression *unary; 714f08c3bdfSopenharmony_ci struct token *next; 715f08c3bdfSopenharmony_ci 716f08c3bdfSopenharmony_ci next = cast_expression(token->next, &unop); 717f08c3bdfSopenharmony_ci if (!unop) { 718f08c3bdfSopenharmony_ci sparse_error(token->pos, "Syntax error in unary expression"); 719f08c3bdfSopenharmony_ci *tree = NULL; 720f08c3bdfSopenharmony_ci return next; 721f08c3bdfSopenharmony_ci } 722f08c3bdfSopenharmony_ci unary = alloc_expression(token->pos, EXPR_PREOP); 723f08c3bdfSopenharmony_ci unary->op = token->special; 724f08c3bdfSopenharmony_ci unary->unop = unop; 725f08c3bdfSopenharmony_ci *tree = unary; 726f08c3bdfSopenharmony_ci return next; 727f08c3bdfSopenharmony_ci } 728f08c3bdfSopenharmony_ci /* Gcc extension: &&label gives the address of a label */ 729f08c3bdfSopenharmony_ci if (match_op(token, SPECIAL_LOGICAL_AND) && 730f08c3bdfSopenharmony_ci token_type(token->next) == TOKEN_IDENT) { 731f08c3bdfSopenharmony_ci struct expression *label = alloc_expression(token->pos, EXPR_LABEL); 732f08c3bdfSopenharmony_ci struct symbol *sym = label_symbol(token->next, 1); 733f08c3bdfSopenharmony_ci if (!(sym->ctype.modifiers & MOD_ADDRESSABLE)) { 734f08c3bdfSopenharmony_ci sym->ctype.modifiers |= MOD_ADDRESSABLE; 735f08c3bdfSopenharmony_ci add_symbol(&function_computed_target_list, sym); 736f08c3bdfSopenharmony_ci } 737f08c3bdfSopenharmony_ci check_label_usage(sym, token->pos); 738f08c3bdfSopenharmony_ci label->flags = CEF_ADDR; 739f08c3bdfSopenharmony_ci label->label_symbol = sym; 740f08c3bdfSopenharmony_ci *tree = label; 741f08c3bdfSopenharmony_ci return token->next->next; 742f08c3bdfSopenharmony_ci } 743f08c3bdfSopenharmony_ci 744f08c3bdfSopenharmony_ci } 745f08c3bdfSopenharmony_ci 746f08c3bdfSopenharmony_ci return postfix_expression(token, tree, NULL); 747f08c3bdfSopenharmony_ci} 748f08c3bdfSopenharmony_ci 749f08c3bdfSopenharmony_ci/* 750f08c3bdfSopenharmony_ci * Ambiguity: a '(' can be either a cast-expression or 751f08c3bdfSopenharmony_ci * a primary-expression depending on whether it is followed 752f08c3bdfSopenharmony_ci * by a type or not. 753f08c3bdfSopenharmony_ci * 754f08c3bdfSopenharmony_ci * additional ambiguity: a "cast expression" followed by 755f08c3bdfSopenharmony_ci * an initializer is really a postfix-expression. 756f08c3bdfSopenharmony_ci */ 757f08c3bdfSopenharmony_cistatic struct token *cast_expression(struct token *token, struct expression **tree) 758f08c3bdfSopenharmony_ci{ 759f08c3bdfSopenharmony_ci if (match_op(token, '(')) { 760f08c3bdfSopenharmony_ci struct token *next = token->next; 761f08c3bdfSopenharmony_ci if (lookup_type(next)) { 762f08c3bdfSopenharmony_ci struct expression *cast = alloc_expression(next->pos, EXPR_CAST); 763f08c3bdfSopenharmony_ci struct expression *v; 764f08c3bdfSopenharmony_ci struct symbol *sym; 765f08c3bdfSopenharmony_ci int is_force; 766f08c3bdfSopenharmony_ci 767f08c3bdfSopenharmony_ci token = typename(next, &sym, &is_force); 768f08c3bdfSopenharmony_ci cast->cast_type = sym; 769f08c3bdfSopenharmony_ci token = expect(token, ')', "at end of cast operator"); 770f08c3bdfSopenharmony_ci if (match_op(token, '{')) { 771f08c3bdfSopenharmony_ci if (toplevel(block_scope)) 772f08c3bdfSopenharmony_ci sym->ctype.modifiers |= MOD_TOPLEVEL; 773f08c3bdfSopenharmony_ci if (is_force) 774f08c3bdfSopenharmony_ci warning(sym->pos, 775f08c3bdfSopenharmony_ci "[force] in compound literal"); 776f08c3bdfSopenharmony_ci token = initializer(&cast->cast_expression, token); 777f08c3bdfSopenharmony_ci return postfix_expression(token, tree, cast); 778f08c3bdfSopenharmony_ci } 779f08c3bdfSopenharmony_ci *tree = cast; 780f08c3bdfSopenharmony_ci if (is_force) 781f08c3bdfSopenharmony_ci cast->type = EXPR_FORCE_CAST; 782f08c3bdfSopenharmony_ci token = cast_expression(token, &v); 783f08c3bdfSopenharmony_ci if (!v) 784f08c3bdfSopenharmony_ci return token; 785f08c3bdfSopenharmony_ci cast->cast_expression = v; 786f08c3bdfSopenharmony_ci return token; 787f08c3bdfSopenharmony_ci } 788f08c3bdfSopenharmony_ci } 789f08c3bdfSopenharmony_ci return unary_expression(token, tree); 790f08c3bdfSopenharmony_ci} 791f08c3bdfSopenharmony_ci 792f08c3bdfSopenharmony_ci/* 793f08c3bdfSopenharmony_ci * Generic left-to-right binop parsing 794f08c3bdfSopenharmony_ci * 795f08c3bdfSopenharmony_ci * This _really_ needs to be inlined, because that makes the inner 796f08c3bdfSopenharmony_ci * function call statically deterministic rather than a totally 797f08c3bdfSopenharmony_ci * unpredictable indirect call. But gcc-3 is so "clever" that it 798f08c3bdfSopenharmony_ci * doesn't do so by default even when you tell it to inline it. 799f08c3bdfSopenharmony_ci * 800f08c3bdfSopenharmony_ci * Making it a macro avoids the inlining problem, and also means 801f08c3bdfSopenharmony_ci * that we can pass in the op-comparison as an expression rather 802f08c3bdfSopenharmony_ci * than create a data structure for it. 803f08c3bdfSopenharmony_ci */ 804f08c3bdfSopenharmony_ci 805f08c3bdfSopenharmony_ci#define LR_BINOP_EXPRESSION(__token, tree, type, inner, compare) \ 806f08c3bdfSopenharmony_ci struct expression *left = NULL; \ 807f08c3bdfSopenharmony_ci struct token * next = inner(__token, &left); \ 808f08c3bdfSopenharmony_ci \ 809f08c3bdfSopenharmony_ci if (left) { \ 810f08c3bdfSopenharmony_ci while (token_type(next) == TOKEN_SPECIAL) { \ 811f08c3bdfSopenharmony_ci struct expression *top, *right = NULL; \ 812f08c3bdfSopenharmony_ci int op = next->special; \ 813f08c3bdfSopenharmony_ci \ 814f08c3bdfSopenharmony_ci if (!(compare)) \ 815f08c3bdfSopenharmony_ci goto out; \ 816f08c3bdfSopenharmony_ci top = alloc_expression(next->pos, type); \ 817f08c3bdfSopenharmony_ci next = inner(next->next, &right); \ 818f08c3bdfSopenharmony_ci if (!right) { \ 819f08c3bdfSopenharmony_ci sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op)); \ 820f08c3bdfSopenharmony_ci break; \ 821f08c3bdfSopenharmony_ci } \ 822f08c3bdfSopenharmony_ci top->op = op; \ 823f08c3bdfSopenharmony_ci top->left = left; \ 824f08c3bdfSopenharmony_ci top->right = right; \ 825f08c3bdfSopenharmony_ci left = top; \ 826f08c3bdfSopenharmony_ci } \ 827f08c3bdfSopenharmony_ci } \ 828f08c3bdfSopenharmony_ciout: \ 829f08c3bdfSopenharmony_ci *tree = left; \ 830f08c3bdfSopenharmony_ci return next; \ 831f08c3bdfSopenharmony_ci 832f08c3bdfSopenharmony_cistatic struct token *multiplicative_expression(struct token *token, struct expression **tree) 833f08c3bdfSopenharmony_ci{ 834f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 835f08c3bdfSopenharmony_ci token, tree, EXPR_BINOP, cast_expression, 836f08c3bdfSopenharmony_ci (op == '*') || (op == '/') || (op == '%') 837f08c3bdfSopenharmony_ci ); 838f08c3bdfSopenharmony_ci} 839f08c3bdfSopenharmony_ci 840f08c3bdfSopenharmony_cistatic struct token *additive_expression(struct token *token, struct expression **tree) 841f08c3bdfSopenharmony_ci{ 842f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 843f08c3bdfSopenharmony_ci token, tree, EXPR_BINOP, multiplicative_expression, 844f08c3bdfSopenharmony_ci (op == '+') || (op == '-') 845f08c3bdfSopenharmony_ci ); 846f08c3bdfSopenharmony_ci} 847f08c3bdfSopenharmony_ci 848f08c3bdfSopenharmony_cistatic struct token *shift_expression(struct token *token, struct expression **tree) 849f08c3bdfSopenharmony_ci{ 850f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 851f08c3bdfSopenharmony_ci token, tree, EXPR_BINOP, additive_expression, 852f08c3bdfSopenharmony_ci (op == SPECIAL_LEFTSHIFT) || (op == SPECIAL_RIGHTSHIFT) 853f08c3bdfSopenharmony_ci ); 854f08c3bdfSopenharmony_ci} 855f08c3bdfSopenharmony_ci 856f08c3bdfSopenharmony_cistatic struct token *relational_expression(struct token *token, struct expression **tree) 857f08c3bdfSopenharmony_ci{ 858f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 859f08c3bdfSopenharmony_ci token, tree, EXPR_COMPARE, shift_expression, 860f08c3bdfSopenharmony_ci (op == '<') || (op == '>') || 861f08c3bdfSopenharmony_ci (op == SPECIAL_LTE) || (op == SPECIAL_GTE) 862f08c3bdfSopenharmony_ci ); 863f08c3bdfSopenharmony_ci} 864f08c3bdfSopenharmony_ci 865f08c3bdfSopenharmony_cistatic struct token *equality_expression(struct token *token, struct expression **tree) 866f08c3bdfSopenharmony_ci{ 867f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 868f08c3bdfSopenharmony_ci token, tree, EXPR_COMPARE, relational_expression, 869f08c3bdfSopenharmony_ci (op == SPECIAL_EQUAL) || (op == SPECIAL_NOTEQUAL) 870f08c3bdfSopenharmony_ci ); 871f08c3bdfSopenharmony_ci} 872f08c3bdfSopenharmony_ci 873f08c3bdfSopenharmony_cistatic struct token *bitwise_and_expression(struct token *token, struct expression **tree) 874f08c3bdfSopenharmony_ci{ 875f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 876f08c3bdfSopenharmony_ci token, tree, EXPR_BINOP, equality_expression, 877f08c3bdfSopenharmony_ci (op == '&') 878f08c3bdfSopenharmony_ci ); 879f08c3bdfSopenharmony_ci} 880f08c3bdfSopenharmony_ci 881f08c3bdfSopenharmony_cistatic struct token *bitwise_xor_expression(struct token *token, struct expression **tree) 882f08c3bdfSopenharmony_ci{ 883f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 884f08c3bdfSopenharmony_ci token, tree, EXPR_BINOP, bitwise_and_expression, 885f08c3bdfSopenharmony_ci (op == '^') 886f08c3bdfSopenharmony_ci ); 887f08c3bdfSopenharmony_ci} 888f08c3bdfSopenharmony_ci 889f08c3bdfSopenharmony_cistatic struct token *bitwise_or_expression(struct token *token, struct expression **tree) 890f08c3bdfSopenharmony_ci{ 891f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 892f08c3bdfSopenharmony_ci token, tree, EXPR_BINOP, bitwise_xor_expression, 893f08c3bdfSopenharmony_ci (op == '|') 894f08c3bdfSopenharmony_ci ); 895f08c3bdfSopenharmony_ci} 896f08c3bdfSopenharmony_ci 897f08c3bdfSopenharmony_cistatic struct token *logical_and_expression(struct token *token, struct expression **tree) 898f08c3bdfSopenharmony_ci{ 899f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 900f08c3bdfSopenharmony_ci token, tree, EXPR_LOGICAL, bitwise_or_expression, 901f08c3bdfSopenharmony_ci (op == SPECIAL_LOGICAL_AND) 902f08c3bdfSopenharmony_ci ); 903f08c3bdfSopenharmony_ci} 904f08c3bdfSopenharmony_ci 905f08c3bdfSopenharmony_cistatic struct token *logical_or_expression(struct token *token, struct expression **tree) 906f08c3bdfSopenharmony_ci{ 907f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 908f08c3bdfSopenharmony_ci token, tree, EXPR_LOGICAL, logical_and_expression, 909f08c3bdfSopenharmony_ci (op == SPECIAL_LOGICAL_OR) 910f08c3bdfSopenharmony_ci ); 911f08c3bdfSopenharmony_ci} 912f08c3bdfSopenharmony_ci 913f08c3bdfSopenharmony_cistruct token *conditional_expression(struct token *token, struct expression **tree) 914f08c3bdfSopenharmony_ci{ 915f08c3bdfSopenharmony_ci token = logical_or_expression(token, tree); 916f08c3bdfSopenharmony_ci if (*tree && match_op(token, '?')) { 917f08c3bdfSopenharmony_ci struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL); 918f08c3bdfSopenharmony_ci expr->op = token->special; 919f08c3bdfSopenharmony_ci expr->conditional = *tree; 920f08c3bdfSopenharmony_ci *tree = expr; 921f08c3bdfSopenharmony_ci token = parse_expression(token->next, &expr->cond_true); 922f08c3bdfSopenharmony_ci token = expect(token, ':', "in conditional expression"); 923f08c3bdfSopenharmony_ci token = conditional_expression(token, &expr->cond_false); 924f08c3bdfSopenharmony_ci } 925f08c3bdfSopenharmony_ci return token; 926f08c3bdfSopenharmony_ci} 927f08c3bdfSopenharmony_ci 928f08c3bdfSopenharmony_cistruct token *assignment_expression(struct token *token, struct expression **tree) 929f08c3bdfSopenharmony_ci{ 930f08c3bdfSopenharmony_ci token = conditional_expression(token, tree); 931f08c3bdfSopenharmony_ci if (*tree && token_type(token) == TOKEN_SPECIAL) { 932f08c3bdfSopenharmony_ci static const int assignments[] = { 933f08c3bdfSopenharmony_ci '=', 934f08c3bdfSopenharmony_ci SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN, 935f08c3bdfSopenharmony_ci SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN, 936f08c3bdfSopenharmony_ci SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN, 937f08c3bdfSopenharmony_ci SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN, 938f08c3bdfSopenharmony_ci SPECIAL_OR_ASSIGN, SPECIAL_XOR_ASSIGN }; 939f08c3bdfSopenharmony_ci int i, op = token->special; 940f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(assignments); i++) 941f08c3bdfSopenharmony_ci if (assignments[i] == op) { 942f08c3bdfSopenharmony_ci struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT); 943f08c3bdfSopenharmony_ci struct token *next = token->next; 944f08c3bdfSopenharmony_ci expr->left = *tree; 945f08c3bdfSopenharmony_ci expr->op = op; 946f08c3bdfSopenharmony_ci *tree = expr; 947f08c3bdfSopenharmony_ci token = assignment_expression(next, &expr->right); 948f08c3bdfSopenharmony_ci if (token == next) 949f08c3bdfSopenharmony_ci expression_error(expr, "expression expected before '%s'", show_token(token)); 950f08c3bdfSopenharmony_ci return token; 951f08c3bdfSopenharmony_ci } 952f08c3bdfSopenharmony_ci } 953f08c3bdfSopenharmony_ci return token; 954f08c3bdfSopenharmony_ci} 955f08c3bdfSopenharmony_ci 956f08c3bdfSopenharmony_cistatic struct token *comma_expression(struct token *token, struct expression **tree) 957f08c3bdfSopenharmony_ci{ 958f08c3bdfSopenharmony_ci LR_BINOP_EXPRESSION( 959f08c3bdfSopenharmony_ci token, tree, EXPR_COMMA, assignment_expression, 960f08c3bdfSopenharmony_ci (op == ',') 961f08c3bdfSopenharmony_ci ); 962f08c3bdfSopenharmony_ci} 963f08c3bdfSopenharmony_ci 964f08c3bdfSopenharmony_cistruct token *parse_expression(struct token *token, struct expression **tree) 965f08c3bdfSopenharmony_ci{ 966f08c3bdfSopenharmony_ci return comma_expression(token,tree); 967f08c3bdfSopenharmony_ci} 968f08c3bdfSopenharmony_ci 969f08c3bdfSopenharmony_ci 970