📄 data.c
字号:
symbol = lvalue->symtree->n.sym; init = symbol->value; last_ts = &symbol->ts; last_con = NULL; mpz_init_set_si (offset, 0); /* Find/create the parent expressions for subobject references. */ for (ref = lvalue->ref; ref; ref = ref->next) { /* Use the existing initializer expression if it exists. Otherwise create a new one. */ if (init == NULL) expr = gfc_get_expr (); else expr = init; /* Find or create this element. */ switch (ref->type) { case REF_ARRAY: if (init == NULL) { /* The element typespec will be the same as the array typespec. */ expr->ts = *last_ts; /* Setup the expression to hold the constructor. */ expr->expr_type = EXPR_ARRAY; expr->rank = ref->u.ar.as->rank; } else gcc_assert (expr->expr_type == EXPR_ARRAY); if (ref->u.ar.type == AR_ELEMENT) { get_array_index (&ref->u.ar, &offset); /* This had better not be the bottom of the reference. We can still get to a full array via a component. */ gcc_assert (ref->next != NULL); } else { mpz_set (offset, index); /* We're at a full array or an array section. This means that we've better have found a full array, and that we're at the bottom of the reference. */ gcc_assert (ref->u.ar.type == AR_FULL); gcc_assert (ref->next == NULL); } /* Find the same element in the existing constructor. */ con = expr->value.constructor; con = find_con_by_offset (offset, con); /* Create a new constructor. */ if (con == NULL) { con = gfc_get_constructor (); mpz_set (con->n.offset, offset); if (ref->next == NULL) mpz_set (con->repeat, repeat); gfc_insert_constructor (expr, con); } else gcc_assert (ref->next != NULL); break; case REF_COMPONENT: if (init == NULL) { /* Setup the expression to hold the constructor. */ expr->expr_type = EXPR_STRUCTURE; expr->ts.type = BT_DERIVED; expr->ts.derived = ref->u.c.sym; } else gcc_assert (expr->expr_type == EXPR_STRUCTURE); last_ts = &ref->u.c.component->ts; /* Find the same element in the existing constructor. */ con = expr->value.constructor; con = find_con_by_component (ref->u.c.component, con); if (con == NULL) { /* Create a new constructor. */ con = gfc_get_constructor (); con->n.component = ref->u.c.component; con->next = expr->value.constructor; expr->value.constructor = con; } /* Since we're only intending to initialize arrays here, there better be an inner reference. */ gcc_assert (ref->next != NULL); break; case REF_SUBSTRING: default: gcc_unreachable (); } if (init == NULL) { /* Point the container at the new expression. */ if (last_con == NULL) symbol->value = expr; else last_con->expr = expr; } init = con->expr; last_con = con; } if (last_ts->type == BT_CHARACTER) expr = create_character_intializer (init, last_ts, NULL, rvalue); else { /* We should never be overwriting an existing initializer. */ gcc_assert (!init); expr = gfc_copy_expr (rvalue); if (!gfc_compare_types (&lvalue->ts, &expr->ts)) gfc_convert_type (expr, &lvalue->ts, 0); } if (last_con == NULL) symbol->value = expr; else last_con->expr = expr;}/* Modify the index of array section and re-calculate the array offset. */void gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar, mpz_t *offset_ret){ int i; mpz_t delta; mpz_t tmp; bool forwards; int cmp; for (i = 0; i < ar->dimen; i++) { if (ar->dimen_type[i] != DIMEN_RANGE) continue; if (ar->stride[i]) { mpz_add (section_index[i], section_index[i], ar->stride[i]->value.integer); if (mpz_cmp_si (ar->stride[i]->value.integer, 0) >= 0) forwards = true; else forwards = false; } else { mpz_add_ui (section_index[i], section_index[i], 1); forwards = true; } if (ar->end[i]) cmp = mpz_cmp (section_index[i], ar->end[i]->value.integer); else cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer); if ((cmp > 0 && forwards) || (cmp < 0 && ! forwards)) { /* Reset index to start, then loop to advance the next index. */ if (ar->start[i]) mpz_set (section_index[i], ar->start[i]->value.integer); else mpz_set (section_index[i], ar->as->lower[i]->value.integer); } else break; } mpz_set_si (*offset_ret, 0); mpz_init_set_si (delta, 1); mpz_init (tmp); for (i = 0; i < ar->dimen; i++) { mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer); mpz_mul (tmp, tmp, delta); mpz_add (*offset_ret, tmp, *offset_ret); mpz_sub (tmp, ar->as->upper[i]->value.integer, ar->as->lower[i]->value.integer); mpz_add_ui (tmp, tmp, 1); mpz_mul (delta, tmp, delta); } mpz_clear (tmp); mpz_clear (delta);}/* Rearrange a structure constructor so the elements are in the specified order. Also insert NULL entries if necessary. */static voidformalize_structure_cons (gfc_expr * expr){ gfc_constructor *head; gfc_constructor *tail; gfc_constructor *cur; gfc_constructor *last; gfc_constructor *c; gfc_component *order; c = expr->value.constructor; /* Constructor is already formalized. */ if (c->n.component == NULL) return; head = tail = NULL; for (order = expr->ts.derived->components; order; order = order->next) { /* Find the next component. */ last = NULL; cur = c; while (cur != NULL && cur->n.component != order) { last = cur; cur = cur->next; } if (cur == NULL) { /* Create a new one. */ cur = gfc_get_constructor (); } else { /* Remove it from the chain. */ if (last == NULL) c = cur->next; else last->next = cur->next; cur->next = NULL; formalize_init_expr (cur->expr); } /* Add it to the new constructor. */ if (head == NULL) head = tail = cur; else { tail->next = cur; tail = tail->next; } } gcc_assert (c == NULL); expr->value.constructor = head;}/* Make sure an initialization expression is in normalized form. Ie. all elements of the constructors are in the correct order. */static voidformalize_init_expr (gfc_expr * expr){ expr_t type; gfc_constructor *c; if (expr == NULL) return; type = expr->expr_type; switch (type) { case EXPR_ARRAY: c = expr->value.constructor; while (c) { formalize_init_expr (c->expr); c = c->next; } break; case EXPR_STRUCTURE: formalize_structure_cons (expr); break; default: break; }}/* Resolve symbol's initial value after all data statement. */voidgfc_formalize_init_value (gfc_symbol *sym){ formalize_init_expr (sym->value);}/* Get the integer value into RET_AS and SECTION from AS and AR, and return offset. */ voidgfc_get_section_index (gfc_array_ref *ar, mpz_t *section_index, mpz_t *offset){ int i; mpz_t delta; mpz_t tmp; mpz_set_si (*offset, 0); mpz_init (tmp); mpz_init_set_si (delta, 1); for (i = 0; i < ar->dimen; i++) { mpz_init (section_index[i]); switch (ar->dimen_type[i]) { case DIMEN_ELEMENT: case DIMEN_RANGE: if (ar->start[i]) { mpz_sub (tmp, ar->start[i]->value.integer, ar->as->lower[i]->value.integer); mpz_mul (tmp, tmp, delta); mpz_add (*offset, tmp, *offset); mpz_set (section_index[i], ar->start[i]->value.integer); } else mpz_set (section_index[i], ar->as->lower[i]->value.integer); break; case DIMEN_VECTOR: gfc_internal_error ("TODO: Vector sections in data statements"); default: gcc_unreachable (); } mpz_sub (tmp, ar->as->upper[i]->value.integer, ar->as->lower[i]->value.integer); mpz_add_ui (tmp, tmp, 1); mpz_mul (delta, tmp, delta); } mpz_clear (tmp); mpz_clear (delta);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -