📄 satisfy.c
字号:
#if 0 if (!UNSATISFIED (exp)) return exp;#endif switch (TREE_CODE_CLASS (TREE_CODE (exp))) { case 'd': if (!LOOKUP_ONLY) return safe_satisfy_decl (exp, chain); break; case 'r': case 's': case '<': case 'e': switch ((enum chill_tree_code)TREE_CODE (exp)) { case REPLICATE_EXPR: goto binary_op; case TRUTH_NOT_EXPR: goto unary_op; case COMPONENT_REF: SATISFY (TREE_OPERAND (exp, 0)); if (!LOOKUP_ONLY && TREE_TYPE (exp) == NULL_TREE) return resolve_component_ref (exp); return exp; case CALL_EXPR: SATISFY (TREE_OPERAND (exp, 0)); SATISFY (TREE_OPERAND (exp, 1)); if (!LOOKUP_ONLY && TREE_TYPE (exp) == NULL_TREE) return build_generalized_call (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1)); return exp; case CONSTRUCTOR: { tree link = TREE_OPERAND (exp, 1); int expand_needed = TREE_TYPE (exp) && TREE_CODE_CLASS (TREE_CODE (TREE_TYPE (exp))) != 't'; for (; link != NULL_TREE; link = TREE_CHAIN (link)) { SATISFY (TREE_VALUE (link)); if (!TUPLE_NAMED_FIELD (link)) SATISFY (TREE_PURPOSE (link)); } SATISFY (TREE_TYPE (exp)); if (expand_needed && !LOOKUP_ONLY) { tree type = TREE_TYPE (exp); TREE_TYPE (exp) = NULL_TREE; /* To force expansion. */ return chill_expand_tuple (type, exp); } return exp; } default: ; } arg_length = tree_code_length[TREE_CODE (exp)]; for (i = 0; i < arg_length; i++) SATISFY (TREE_OPERAND (exp, i)); return exp; case '1': unary_op: SATISFY (TREE_OPERAND (exp, 0)); if ((enum chill_tree_code)TREE_CODE (exp) == PAREN_EXPR) return TREE_OPERAND (exp, 0); if (!LOOKUP_ONLY) return finish_chill_unary_op (exp); break; case '2': binary_op: SATISFY (TREE_OPERAND (exp, 0)); SATISFY (TREE_OPERAND (exp, 1)); if (!LOOKUP_ONLY && TREE_CODE (exp) != RANGE_EXPR) return finish_chill_binary_op (exp); break; case 'x': switch ((enum chill_tree_code)TREE_CODE (exp)) { case IDENTIFIER_NODE: decl = lookup_name (exp); if (decl == NULL) { if (LOOKUP_ONLY) return exp; error ("undeclared identifier `%s'", IDENTIFIER_POINTER (exp)); return error_mark_node; } if (LOOKUP_ONLY) return decl; return safe_satisfy_decl (decl, chain); case TREE_LIST: satisfy_list (exp, chain); break; default: ; } break; case 't': /* If TYPE_SIZE is non-NULL, exp and its subfields has already been satified and laid out. The exception is pointer and reference types, which we layout before we lay out their TREE_TYPE. */ if (TYPE_SIZE (exp) && TREE_CODE (exp) != POINTER_TYPE && TREE_CODE (exp) != REFERENCE_TYPE) return exp; if (TYPE_MAIN_VARIANT (exp) != exp) SATISFY (TYPE_MAIN_VARIANT (exp)); switch ((enum chill_tree_code)TREE_CODE (exp)) { case LANG_TYPE: { tree d = TYPE_DOMAIN (exp); tree t = satisfy (TREE_TYPE (exp), chain); SATISFY (d); /* It is possible that one of the above satisfy calls recursively caused exp to be satisfied, in which case we're done. */ if (TREE_CODE (exp) != LANG_TYPE) return exp; TREE_TYPE (exp) = t; TYPE_DOMAIN (exp) = d; if (!LOOKUP_ONLY) exp = smash_dummy_type (exp); } break; case ARRAY_TYPE: SATISFY (TREE_TYPE (exp)); SATISFY (TYPE_DOMAIN (exp)); SATISFY (TYPE_ATTRIBUTES (exp)); if (!LOOKUP_ONLY) CH_TYPE_NONVALUE_P (exp) = CH_TYPE_NONVALUE_P (TREE_TYPE (exp)); if (!TYPE_SIZE (exp) && !LOOKUP_ONLY) exp = layout_chill_array_type (exp); break; case FUNCTION_TYPE: SATISFY (TREE_TYPE (exp)); if (TREE_CODE_CLASS (TREE_CODE (TREE_TYPE (exp))) != 't' && !LOOKUP_ONLY && TREE_CODE (TREE_TYPE (exp)) != ERROR_MARK) { error ("RETURNS spec with invalid mode"); TREE_TYPE (exp) = error_mark_node; } satisfy_list_values (TYPE_ARG_TYPES (exp), chain); if (!TYPE_SIZE (exp) && !LOOKUP_ONLY) layout_type (exp); break; case ENUMERAL_TYPE: if (TYPE_SIZE (exp) == NULL_TREE && !LOOKUP_ONLY) { tree pair; /* FIXME: Should this use satisfy_decl? */ for (pair = TYPE_VALUES (exp); pair; pair = TREE_CHAIN (pair)) SATISFY (DECL_INITIAL (TREE_VALUE (pair))); layout_enum (exp); } break; case INTEGER_TYPE: SATISFY (TYPE_MIN_VALUE (exp)); SATISFY (TYPE_MAX_VALUE (exp)); if (TREE_TYPE (exp) != NULL_TREE) { /* A range type */ if (TREE_TYPE (exp) != ridpointers[(int) RID_RANGE] && TREE_TYPE (exp) != ridpointers[(int) RID_BIN] && TREE_TYPE (exp) != string_index_type_dummy) SATISFY (TREE_TYPE (exp)); if (!TYPE_SIZE (exp) && !LOOKUP_ONLY) exp = layout_chill_range_type (exp, 1); } break; case POINTER_TYPE: case REFERENCE_TYPE: if (LOOKUP_ONLY) SATISFY (TREE_TYPE (exp)); else { struct decl_chain *link; int already_seen = 0; for (link = chain; ; link = link->prev) { if (link == NULL) { struct decl_chain new_link; new_link.decl = exp; new_link.prev = chain; TREE_TYPE (exp) = satisfy (TREE_TYPE (exp), &new_link); break; } else if (link->decl == exp) { already_seen = 1; break; } } if (!TYPE_SIZE (exp)) { layout_type (exp); if (TREE_CODE (exp) == REFERENCE_TYPE) CH_NOVELTY (exp) = CH_NOVELTY (TREE_TYPE (exp)); if (! already_seen) { tree valtype = TREE_TYPE (exp); if (TREE_CODE_CLASS (TREE_CODE (valtype)) != 't') { if (TREE_CODE (valtype) != ERROR_MARK) error ("operand to REF is not a mode"); TREE_TYPE (exp) = error_mark_node; return error_mark_node; } else if (TREE_CODE (exp) == POINTER_TYPE && TYPE_POINTER_TO (valtype) == NULL) TYPE_POINTER_TO (valtype) = exp; } } } break; case RECORD_TYPE: { /* FIXME: detected errors in here will be printed as often as this sequence runs. Find another way or place to print the errors. */ /* if we have an ACCESS or TEXT mode we have to set maximum_field_alignment to 0 to fit with runtime system, even when we compile with -fpack. */ extern int maximum_field_alignment; int save_maximum_field_alignment = maximum_field_alignment; if (CH_IS_ACCESS_MODE (exp) || CH_IS_TEXT_MODE (exp)) maximum_field_alignment = 0; for (decl = TYPE_FIELDS (exp); decl; decl = TREE_CHAIN (decl)) { SATISFY (TREE_TYPE (decl)); if (!LOOKUP_ONLY) { /* if we have a UNION_TYPE here (variant structure), check for non-value mode in it. This is not allowed (Z.200/pg. 33) */ if (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE && CH_TYPE_NONVALUE_P (TREE_TYPE (decl))) { error ("field with non-value mode in variant structure not allowed"); TREE_TYPE (decl) = error_mark_node; } /* RECORD_TYPE gets the non-value property if one of the fields has the non-value property */ CH_TYPE_NONVALUE_P (exp) |= CH_TYPE_NONVALUE_P (TREE_TYPE (decl)); } if (TREE_CODE (decl) == CONST_DECL) { SATISFY (DECL_INITIAL (decl)); if (!LOOKUP_ONLY) { if (CH_IS_BUFFER_MODE (exp) || CH_IS_EVENT_MODE (exp)) DECL_INITIAL (decl) = check_queue_size (DECL_INITIAL (decl)); else if (CH_IS_TEXT_MODE (exp) && DECL_NAME (decl) == get_identifier ("__textlength")) DECL_INITIAL (decl) = check_text_length (DECL_INITIAL (decl)); } } else if (TREE_CODE (decl) == FIELD_DECL) { SATISFY (DECL_INITIAL (decl)); } } satisfy_list (TYPE_TAG_VALUES (exp), chain); if (!TYPE_SIZE (exp) && !LOOKUP_ONLY) exp = layout_chill_struct_type (exp); maximum_field_alignment = save_maximum_field_alignment; /* perform some checks on nonvalue modes, they are record_mode's */ if (!LOOKUP_ONLY) { if (CH_IS_BUFFER_MODE (exp)) { tree elemmode = buffer_element_mode (exp); if (elemmode != NULL_TREE && CH_TYPE_NONVALUE_P (elemmode)) { error ("buffer element mode must not have non-value property"); invalidate_buffer_element_mode (exp); } } else if (CH_IS_ACCESS_MODE (exp)) { tree recordmode = access_recordmode (exp); if (recordmode != NULL_TREE && CH_TYPE_NONVALUE_P (recordmode)) { error ("recordmode must not have the non-value property"); invalidate_access_recordmode (exp); } } } } break; case SET_TYPE: SATISFY (TYPE_DOMAIN (exp)); if (!TYPE_SIZE (exp) && !LOOKUP_ONLY) exp = layout_powerset_type (exp); break; case UNION_TYPE: for (decl = TYPE_FIELDS (exp); decl; decl = TREE_CHAIN (decl)) { SATISFY (TREE_TYPE (decl)); if (!LOOKUP_ONLY) CH_TYPE_NONVALUE_P (exp) |= CH_TYPE_NONVALUE_P (TREE_TYPE (decl)); } if (!TYPE_SIZE (exp) && !LOOKUP_ONLY) exp = layout_chill_variants (exp); break; default: ; } } return exp;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -