aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--evaluate.c29
-rw-r--r--expression.h7
-rw-r--r--show-parse.c48
3 files changed, 65 insertions, 19 deletions
diff --git a/evaluate.c b/evaluate.c
index 1d5073e6..b3fd1628 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1177,8 +1177,8 @@ static int evaluate_arguments(struct symbol *fn, struct expression_list *head)
return 1;
}
-static int evaluate_initializer(struct symbol *ctype, struct expression **ep);
-static int evaluate_array_initializer(struct symbol *ctype, struct expression *expr)
+static int evaluate_initializer(struct symbol *ctype, struct expression **ep, unsigned long offset);
+static int evaluate_array_initializer(struct symbol *ctype, struct expression *expr, unsigned long offset)
{
struct expression *entry;
int current = 0;
@@ -1191,7 +1191,7 @@ static int evaluate_array_initializer(struct symbol *ctype, struct expression *e
current = entry->idx_to;
continue;
}
- evaluate_initializer(ctype, p);
+ evaluate_initializer(ctype, p, offset + current*(ctype->bit_size>>3));
current++;
if (current > max)
max = current;
@@ -1199,7 +1199,7 @@ static int evaluate_array_initializer(struct symbol *ctype, struct expression *e
return max;
}
-static int evaluate_struct_or_union_initializer(struct symbol *ctype, struct expression *expr, int multiple)
+static int evaluate_struct_or_union_initializer(struct symbol *ctype, struct expression *expr, int multiple, unsigned long offset)
{
struct expression *entry;
struct symbol *sym;
@@ -1231,7 +1231,7 @@ static int evaluate_struct_or_union_initializer(struct symbol *ctype, struct exp
return 0;
}
- evaluate_initializer(sym, p);
+ evaluate_initializer(sym, p, offset + sym->offset);
NEXT_PTR_LIST(sym);
} END_FOR_EACH_PTR;
@@ -1244,7 +1244,7 @@ static int evaluate_struct_or_union_initializer(struct symbol *ctype, struct exp
* Initializers are kind of like assignments. Except
* they can be a hell of a lot more complex.
*/
-static int evaluate_initializer(struct symbol *ctype, struct expression **ep)
+static int evaluate_initializer(struct symbol *ctype, struct expression **ep, unsigned long offset)
{
struct expression *expr = *ep;
@@ -1256,10 +1256,16 @@ static int evaluate_initializer(struct symbol *ctype, struct expression **ep)
int size = 0;
struct symbol *rtype = evaluate_expression(expr);
if (rtype) {
+ struct expression *pos;
compatible_assignment_types(expr, ctype, ep, rtype, "initializer");
/* strings are special: char arrays */
if (rtype->type == SYM_ARRAY)
size = rtype->array_size;
+ pos = alloc_expression(expr->pos, EXPR_POS);
+ pos->init_offset = offset;
+ pos->init_sym = ctype;
+ pos->init_expr = *ep;
+ *ep = pos;
}
return size;
}
@@ -1271,11 +1277,11 @@ static int evaluate_initializer(struct symbol *ctype, struct expression **ep)
switch (ctype->type) {
case SYM_ARRAY:
case SYM_PTR:
- return evaluate_array_initializer(ctype->ctype.base_type, expr);
+ return evaluate_array_initializer(ctype->ctype.base_type, expr, offset);
case SYM_UNION:
- return evaluate_struct_or_union_initializer(ctype, expr, 0);
+ return evaluate_struct_or_union_initializer(ctype, expr, 0, offset);
case SYM_STRUCT:
- return evaluate_struct_or_union_initializer(ctype, expr, 1);
+ return evaluate_struct_or_union_initializer(ctype, expr, 1, offset);
default:
break;
}
@@ -1298,7 +1304,7 @@ static struct symbol *evaluate_cast(struct expression *expr)
* than trying to evaluate it as an expression
*/
if (target->type == EXPR_INITIALIZER) {
- evaluate_initializer(ctype, &expr->cast_expression);
+ evaluate_initializer(ctype, &expr->cast_expression, 0);
return ctype;
}
@@ -1424,6 +1430,7 @@ struct symbol *evaluate_expression(struct expression *expr)
case EXPR_INITIALIZER:
case EXPR_IDENTIFIER:
case EXPR_INDEX:
+ case EXPR_POS:
warn(expr->pos, "internal front-end error: initializer in expression");
return NULL;
}
@@ -1474,7 +1481,7 @@ struct symbol *evaluate_symbol(struct symbol *sym)
/* Evaluate the initializers */
if (sym->initializer) {
- int count = evaluate_initializer(sym, &sym->initializer);
+ int count = evaluate_initializer(sym, &sym->initializer, 0);
if (base_type->type == SYM_ARRAY && base_type->array_size < 0) {
int bit_size = count * base_type->ctype.base_type->bit_size;
base_type->array_size = count;
diff --git a/expression.h b/expression.h
index 8c6c6079..0b907c3b 100644
--- a/expression.h
+++ b/expression.h
@@ -31,6 +31,7 @@ enum expression_type {
EXPR_INITIALIZER, // initializer list
EXPR_IDENTIFIER, // identifier in initializer
EXPR_INDEX, // index in initializer
+ EXPR_POS, // position in initializer
};
struct expression {
@@ -93,6 +94,12 @@ struct expression {
struct index_expr {
unsigned int idx_from, idx_to;
};
+ // EXPR_POS
+ struct initpos_expr {
+ unsigned int init_offset;
+ struct symbol *init_sym;
+ struct expression *init_expr;
+ };
};
};
diff --git a/show-parse.c b/show-parse.c
index 94735899..4c798f34 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -300,7 +300,7 @@ void show_symbol(struct symbol *sym)
}
if (sym->initializer) {
- printf(" = ");
+ printf(" = \n");
show_expression(sym->initializer);
}
}
@@ -775,9 +775,35 @@ static int show_statement_expr(struct expression *expr)
return show_statement(expr->statement);
}
-static int show_initializer_expr(struct expression *expr)
+static int show_position_expr(struct expression *expr, struct symbol *base)
{
- printf("\t// initializer goes here\n");
+ int new = show_expression(expr->init_expr);
+ struct symbol *ctype = expr->init_sym;
+
+ printf("\tinsert v%d at [%d:%d] of %s\n", new,
+ expr->init_offset, ctype->bit_offset,
+ show_ident(base->ident));
+ return 0;
+}
+
+static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
+{
+ struct expression *entry;
+
+ FOR_EACH_PTR(expr->expr_list, entry) {
+ // Nested initializers have their positions already
+ // recursively calculated - just output them too
+ if (entry->type == EXPR_INITIALIZER) {
+ show_initializer_expr(entry, ctype);
+ continue;
+ }
+
+ // Ignore initializer indexes and identifiers - the
+ // evaluator has taken them into account
+ if (entry->type != EXPR_POS)
+ continue;
+ show_position_expr(entry, ctype);
+ } END_FOR_EACH_PTR;
return 0;
}
@@ -829,17 +855,23 @@ int show_expression(struct expression *expr)
case EXPR_BITFIELD:
return show_bitfield_expr(expr);
case EXPR_INITIALIZER:
- return show_initializer_expr(expr);
+ return show_initializer_expr(expr, expr->ctype);
+ case EXPR_CONDITIONAL:
+ return show_conditional_expr(expr);
+ case EXPR_STATEMENT:
+ return show_statement_expr(expr);
+
+ // None of these should exist as direct expressions: they are only
+ // valid as sub-expressions of initializers.
+ case EXPR_POS:
+ warn(expr->pos, "unable to show plain initializer position expression");
+ return 0;
case EXPR_IDENTIFIER:
warn(expr->pos, "unable to show identifier expression");
return 0;
case EXPR_INDEX:
warn(expr->pos, "unable to show index expression");
return 0;
- case EXPR_CONDITIONAL:
- return show_conditional_expr(expr);
- case EXPR_STATEMENT:
- return show_statement_expr(expr);
}
return 0;
}