X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=parser.c;h=eb7eb9c46482e61cf3af8fa8af119c53488d096a;hb=1d5d9fdf8c4e3771529cd9ab6dbfc1055cffcda6;hp=16410fdba519b6d15ee3e34c94cc233489e082c8;hpb=863f26fe96754bb16052065afb3e777493aad50c;p=cparser diff --git a/parser.c b/parser.c index 16410fd..eb7eb9c 100644 --- a/parser.c +++ b/parser.c @@ -45,6 +45,7 @@ static type_t *type_float = NULL; static type_t *type_const_char = NULL; static type_t *type_string = NULL; static type_t *type_void = NULL; +static type_t *type_void_ptr = NULL; static type_t *type_size_t = NULL; static type_t *type_ptrdiff_t = NULL; @@ -2354,7 +2355,7 @@ static expression_t *parse_int_const(void) const_t *cnst = allocate_ast_zero(sizeof(cnst[0])); cnst->expression.type = EXPR_CONST; - cnst->expression.datatype = type_int; + cnst->expression.datatype = token.datatype; cnst->v.int_value = token.v.intvalue; next_token(); @@ -2367,7 +2368,7 @@ static expression_t *parse_float_const(void) const_t *cnst = allocate_ast_zero(sizeof(cnst[0])); cnst->expression.type = EXPR_CONST; - cnst->expression.datatype = type_double; + cnst->expression.datatype = token.datatype; cnst->v.float_value = token.v.floatvalue; next_token(); @@ -2656,18 +2657,42 @@ static expression_t *parse_va_arg(void) return (expression_t*) expression; } +static type_t *make_function_1_type(type_t *result_type, type_t *argument_type) +{ + function_parameter_t *parameter = allocate_type_zero(sizeof(parameter[0])); + parameter->type = argument_type; + + function_type_t *type = allocate_type_zero(sizeof(type[0])); + type->type.type = TYPE_FUNCTION; + type->result_type = result_type; + type->parameters = parameter; + + type_t *result = typehash_insert((type_t*) type); + if(result != (type_t*) type) { + free_type(type); + } + + return result; +} + static expression_t *parse_builtin_symbol(void) { builtin_symbol_expression_t *expression = allocate_ast_zero(sizeof(expression[0])); expression->expression.type = EXPR_BUILTIN_SYMBOL; - /* TODO: set datatype */ - expression->symbol = token.v.symbol; + type_t *type; + switch(token.type) { + case T___builtin_alloca: + type = make_function_1_type(type_void_ptr, type_size_t); + break; + } + next_token(); + expression->expression.datatype = type; return (expression_t*) expression; } @@ -2691,6 +2716,7 @@ static expression_t *parse_primary_expression(void) return parse_offsetof(); case T___builtin_va_arg: return parse_va_arg(); + case T___builtin_alloca: case T___builtin_expect: case T___builtin_va_start: case T___builtin_va_end: @@ -2716,25 +2742,37 @@ static expression_t *parse_array_expression(unsigned precedence, eat('['); + expression_t *index = parse_expression(); + array_access_expression_t *array_access = allocate_ast_zero(sizeof(array_access[0])); - array_access->expression.type = EXPR_ARRAY_ACCESS; - array_access->array_ref = array_ref; - array_access->index = parse_expression(); + array_access->expression.type = EXPR_ARRAY_ACCESS; + array_access->array_ref = array_ref; + array_access->index = index; - type_t *type = array_ref->datatype; - if(type != NULL) { - if(type->type == TYPE_POINTER) { - pointer_type_t *pointer = (pointer_type_t*) type; + type_t *type_left = skip_typeref(array_ref->datatype); + type_t *type_right = skip_typeref(index->datatype); + + if(type_left != NULL && type_right != NULL) { + if(type_left->type == TYPE_POINTER) { + pointer_type_t *pointer = (pointer_type_t*) type_left; + array_access->expression.datatype = pointer->points_to; + } else if(type_left->type == TYPE_ARRAY) { + array_type_t *array_type = (array_type_t*) type_left; + array_access->expression.datatype = array_type->element_type; + } else if(type_right->type == TYPE_POINTER) { + pointer_type_t *pointer = (pointer_type_t*) type_right; array_access->expression.datatype = pointer->points_to; - } else if(type->type == TYPE_ARRAY) { - array_type_t *array_type = (array_type_t*) type; + } else if(type_right->type == TYPE_ARRAY) { + array_type_t *array_type = (array_type_t*) type_right; array_access->expression.datatype = array_type->element_type; } else { parser_print_error_prefix(); - fprintf(stderr, "array access on object with non-pointer type "); - print_type_quoted(type); + fprintf(stderr, "array access on object with non-pointer types "); + print_type_quoted(type_left); + fprintf(stderr, ", "); + print_type_quoted(type_right); fprintf(stderr, "\n"); } } @@ -3766,7 +3804,7 @@ static statement_t *parse_case_statement(void) label->expression = parse_expression(); expect(':'); - label->statement.next = parse_statement(); + label->label_statement = parse_statement(); return (statement_t*) label; } @@ -3780,7 +3818,7 @@ static statement_t *parse_default_statement(void) label->statement.source_position = token.source_position; expect(':'); - label->statement.next = parse_statement(); + label->label_statement = parse_statement(); return (statement_t*) label; } @@ -4292,6 +4330,7 @@ void init_parser(void) type_ptrdiff_t = make_atomic_type(ATOMIC_TYPE_LONG, 0); type_const_char = make_atomic_type(ATOMIC_TYPE_CHAR, TYPE_QUALIFIER_CONST); type_void = make_atomic_type(ATOMIC_TYPE_VOID, 0); + type_void_ptr = make_pointer_type(type_void, 0); type_string = make_pointer_type(type_const_char, 0); }