static void lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, tree expr) { unsigned i; tree t; /* Note that the number of slots in EXPR was read in streamer_alloc_tree when instantiating EXPR. However, the vector is empty so we cannot rely on vec::length to know how many elements to read. So, this list is emitted as a 0-terminated list on the writer side. */ do { t = stream_read_tree (ib, data_in); if (t) BINFO_BASE_BINFOS (expr)->quick_push (t); } while (t); BINFO_OFFSET (expr) = stream_read_tree (ib, data_in); BINFO_VTABLE (expr) = stream_read_tree (ib, data_in); BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in); /* The vector of BINFO_BASE_ACCESSES is pre-allocated during unpacking the bitfield section. */ for (i = 0; i < vec_safe_length (BINFO_BASE_ACCESSES (expr)); i++) { tree a = stream_read_tree (ib, data_in); (*BINFO_BASE_ACCESSES (expr))[i] = a; } /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX and BINFO_VPTR_INDEX; these are used by C++ FE only. */ }
static void write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p) { unsigned i; tree t; /* Note that the number of BINFO slots has already been emitted in EXPR's header (see streamer_write_tree_header) because this length is needed to build the empty BINFO node on the reader side. */ FOR_EACH_VEC_ELT (tree, BINFO_BASE_BINFOS (expr), i, t) stream_write_tree (ob, t, ref_p); stream_write_tree (ob, NULL_TREE, false); stream_write_tree (ob, BINFO_OFFSET (expr), ref_p); stream_write_tree (ob, BINFO_VTABLE (expr), ref_p); stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p); streamer_write_uhwi (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr))); FOR_EACH_VEC_ELT (tree, BINFO_BASE_ACCESSES (expr), i, t) stream_write_tree (ob, t, ref_p); stream_write_tree (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p); stream_write_tree (ob, BINFO_SUBVTT_INDEX (expr), ref_p); stream_write_tree (ob, BINFO_VPTR_INDEX (expr), ref_p); }
static void write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p) { unsigned i; tree t; /* Note that the number of BINFO slots has already been emitted in EXPR's header (see streamer_write_tree_header) because this length is needed to build the empty BINFO node on the reader side. */ FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (expr), i, t) stream_write_tree (ob, t, ref_p); stream_write_tree (ob, NULL_TREE, false); stream_write_tree (ob, BINFO_OFFSET (expr), ref_p); stream_write_tree (ob, BINFO_VTABLE (expr), ref_p); stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p); /* The number of BINFO_BASE_ACCESSES has already been emitted in EXPR's bitfield section. */ FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (expr), i, t) stream_write_tree (ob, t, ref_p); /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX and BINFO_VPTR_INDEX; these are used by C++ FE only. */ }
void streamer_pack_tree_bitfields (struct output_block *ob, struct bitpack_d *bp, tree expr) { enum tree_code code; code = TREE_CODE (expr); /* Note that all these functions are highly sensitive to changes in the types and sizes of each of the fields being packed. */ pack_ts_base_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) pack_ts_int_cst_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) pack_ts_real_cst_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST)) pack_ts_fixed_cst_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) stream_output_location (ob, bp, DECL_SOURCE_LOCATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) pack_ts_decl_common_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)) pack_ts_decl_wrtl_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) pack_ts_decl_with_vis_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) pack_ts_function_decl_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON)) pack_ts_type_common_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_EXP)) stream_output_location (ob, bp, EXPR_LOCATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) pack_ts_block_value_fields (ob, bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) pack_ts_translation_unit_decl_value_fields (ob, bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)) pack_ts_target_option (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION)) pack_ts_optimization (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) bp_pack_var_len_unsigned (bp, vec_safe_length (BINFO_BASE_ACCESSES (expr))); if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr)); }
static void lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, tree expr) { unsigned i, len; tree t; /* Note that the number of slots in EXPR was read in streamer_alloc_tree when instantiating EXPR. However, the vector is empty so we cannot rely on VEC_length to know how many elements to read. So, this list is emitted as a 0-terminated list on the writer side. */ do { t = stream_read_tree (ib, data_in); if (t) VEC_quick_push (tree, BINFO_BASE_BINFOS (expr), t); } while (t); BINFO_OFFSET (expr) = stream_read_tree (ib, data_in); BINFO_VTABLE (expr) = stream_read_tree (ib, data_in); BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in); len = streamer_read_uhwi (ib); if (len > 0) { VEC_reserve_exact (tree, gc, BINFO_BASE_ACCESSES (expr), len); for (i = 0; i < len; i++) { tree a = stream_read_tree (ib, data_in); VEC_quick_push (tree, BINFO_BASE_ACCESSES (expr), a); } } BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in); BINFO_SUBVTT_INDEX (expr) = stream_read_tree (ib, data_in); BINFO_VPTR_INDEX (expr) = stream_read_tree (ib, data_in); }
static void dequeue_and_dump (dump_info_p di) { dump_queue_p dq; splay_tree_node stn; dump_node_info_p dni; tree t; unsigned int index; enum tree_code code; enum tree_code_class code_class; const char* code_name; /* Get the next node from the queue. */ dq = di->queue; stn = dq->node; t = (tree) stn->key; dni = (dump_node_info_p) stn->value; index = dni->index; /* Remove the node from the queue, and put it on the free list. */ di->queue = dq->next; if (!di->queue) di->queue_end = 0; dq->next = di->free_list; di->free_list = dq; /* Print the node index. */ dump_index (di, index); /* And the type of node this is. */ if (dni->binfo_p) code_name = "binfo"; else code_name = tree_code_name[(int) TREE_CODE (t)]; fprintf (di->stream, "%-16s ", code_name); di->column = 25; /* Figure out what kind of node this is. */ code = TREE_CODE (t); code_class = TREE_CODE_CLASS (code); /* Although BINFOs are TREE_VECs, we dump them specially so as to be more informative. */ if (dni->binfo_p) { unsigned ix; tree base; VEC(tree,gc) *accesses = BINFO_BASE_ACCESSES (t); dump_child ("type", BINFO_TYPE (t)); if (BINFO_VIRTUAL_P (t)) dump_string_field (di, "spec", "virt"); dump_int (di, "bases", BINFO_N_BASE_BINFOS (t)); for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++) { tree access = (accesses ? VEC_index (tree, accesses, ix) : access_public_node); const char *string = NULL; if (access == access_public_node) string = "pub"; else if (access == access_protected_node) string = "prot"; else if (access == access_private_node) string = "priv"; else gcc_unreachable (); dump_string_field (di, "accs", string); queue_and_dump_index (di, "binf", base, DUMP_BINFO); } goto done; } /* We can knock off a bunch of expression nodes in exactly the same way. */ if (IS_EXPR_CODE_CLASS (code_class)) { /* If we're dumping children, dump them now. */ queue_and_dump_type (di, t); switch (code_class) { case tcc_unary: dump_child ("op 0", TREE_OPERAND (t, 0)); break; case tcc_binary: case tcc_comparison: dump_child ("op 0", TREE_OPERAND (t, 0)); dump_child ("op 1", TREE_OPERAND (t, 1)); break; case tcc_expression: case tcc_reference: case tcc_statement: case tcc_vl_exp: /* These nodes are handled explicitly below. */ break; default: gcc_unreachable (); } } else if (DECL_P (t)) { expanded_location xloc; /* All declarations have names. */ if (DECL_NAME (t)) dump_child ("name", DECL_NAME (t)); if (DECL_ASSEMBLER_NAME_SET_P (t) && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t)) dump_child ("mngl", DECL_ASSEMBLER_NAME (t)); if (DECL_ABSTRACT_ORIGIN (t)) dump_child ("orig", DECL_ABSTRACT_ORIGIN (t)); /* And types. */ queue_and_dump_type (di, t); dump_child ("scpe", DECL_CONTEXT (t)); /* And a source position. */ xloc = expand_location (DECL_SOURCE_LOCATION (t)); if (xloc.file) { const char *filename = lbasename (xloc.file); dump_maybe_newline (di); fprintf (di->stream, "srcp: %s:%-6d ", filename, xloc.line); di->column += 6 + strlen (filename) + 8; } /* And any declaration can be compiler-generated. */ if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON) && DECL_ARTIFICIAL (t)) dump_string_field (di, "note", "artificial"); if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL)) dump_child ("chain", DECL_CHAIN (t)); } else if (code_class == tcc_type) { /* All types have qualifiers. */ int quals = lang_hooks.tree_dump.type_quals (t); if (quals != TYPE_UNQUALIFIED) { fprintf (di->stream, "qual: %c%c%c ", (quals & TYPE_QUAL_CONST) ? 'c' : ' ', (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ', (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' '); di->column += 14; } /* All types have associated declarations. */ dump_child ("name", TYPE_NAME (t)); /* All types have a main variant. */ if (TYPE_MAIN_VARIANT (t) != t) dump_child ("unql", TYPE_MAIN_VARIANT (t)); /* And sizes. */ dump_child ("size", TYPE_SIZE (t)); /* All types have alignments. */ dump_int (di, "algn", TYPE_ALIGN (t)); } else if (code_class == tcc_constant) /* All constants can have types. */ queue_and_dump_type (di, t); /* Give the language-specific code a chance to print something. If it's completely taken care of things, don't bother printing anything more ourselves. */ if (lang_hooks.tree_dump.dump_tree (di, t)) goto done; /* Now handle the various kinds of nodes. */ switch (code) { int i; case IDENTIFIER_NODE: dump_string_field (di, "strg", IDENTIFIER_POINTER (t)); dump_int (di, "lngt", IDENTIFIER_LENGTH (t)); break; case TREE_LIST: dump_child ("purp", TREE_PURPOSE (t)); dump_child ("valu", TREE_VALUE (t)); dump_child ("chan", TREE_CHAIN (t)); break; case STATEMENT_LIST: { tree_stmt_iterator it; for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++) { char buffer[32]; sprintf (buffer, "%u", i); dump_child (buffer, tsi_stmt (it)); } } break; case TREE_VEC: dump_int (di, "lngt", TREE_VEC_LENGTH (t)); for (i = 0; i < TREE_VEC_LENGTH (t); ++i) { char buffer[32]; sprintf (buffer, "%u", i); dump_child (buffer, TREE_VEC_ELT (t, i)); } break; case INTEGER_TYPE: case ENUMERAL_TYPE: dump_int (di, "prec", TYPE_PRECISION (t)); dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed"); dump_child ("min", TYPE_MIN_VALUE (t)); dump_child ("max", TYPE_MAX_VALUE (t)); if (code == ENUMERAL_TYPE) dump_child ("csts", TYPE_VALUES (t)); break; case REAL_TYPE: dump_int (di, "prec", TYPE_PRECISION (t)); break; case FIXED_POINT_TYPE: dump_int (di, "prec", TYPE_PRECISION (t)); dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed"); dump_string_field (di, "saturating", TYPE_SATURATING (t) ? "saturating": "non-saturating"); break; case POINTER_TYPE: dump_child ("ptd", TREE_TYPE (t)); break; case REFERENCE_TYPE: dump_child ("refd", TREE_TYPE (t)); break; case METHOD_TYPE: dump_child ("clas", TYPE_METHOD_BASETYPE (t)); /* Fall through. */ case FUNCTION_TYPE: dump_child ("retn", TREE_TYPE (t)); dump_child ("prms", TYPE_ARG_TYPES (t)); break; case ARRAY_TYPE: dump_child ("elts", TREE_TYPE (t)); dump_child ("domn", TYPE_DOMAIN (t)); break; case RECORD_TYPE: case UNION_TYPE: if (TREE_CODE (t) == RECORD_TYPE) dump_string_field (di, "tag", "struct"); else dump_string_field (di, "tag", "union"); dump_child ("flds", TYPE_FIELDS (t)); dump_child ("fncs", TYPE_METHODS (t)); queue_and_dump_index (di, "binf", TYPE_BINFO (t), DUMP_BINFO); break; case CONST_DECL: dump_child ("cnst", DECL_INITIAL (t)); break; case DEBUG_EXPR_DECL: dump_int (di, "-uid", DEBUG_TEMP_UID (t)); /* Fall through. */ case VAR_DECL: case PARM_DECL: case FIELD_DECL: case RESULT_DECL: if (TREE_CODE (t) == PARM_DECL) dump_child ("argt", DECL_ARG_TYPE (t)); else dump_child ("init", DECL_INITIAL (t)); dump_child ("size", DECL_SIZE (t)); dump_int (di, "algn", DECL_ALIGN (t)); if (TREE_CODE (t) == FIELD_DECL) { if (DECL_FIELD_OFFSET (t)) dump_child ("bpos", bit_position (t)); } else if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL) { dump_int (di, "used", TREE_USED (t)); if (DECL_REGISTER (t)) dump_string_field (di, "spec", "register"); } break; case FUNCTION_DECL: dump_child ("args", DECL_ARGUMENTS (t)); if (DECL_EXTERNAL (t)) dump_string_field (di, "body", "undefined"); if (TREE_PUBLIC (t)) dump_string_field (di, "link", "extern"); else dump_string_field (di, "link", "static"); if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t)) dump_child ("body", DECL_SAVED_TREE (t)); break; case INTEGER_CST: if (TREE_INT_CST_HIGH (t)) dump_int (di, "high", TREE_INT_CST_HIGH (t)); dump_int (di, "low", TREE_INT_CST_LOW (t)); break; case STRING_CST: fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t)); dump_int (di, "lngt", TREE_STRING_LENGTH (t)); break; case REAL_CST: dump_real (di, "valu", TREE_REAL_CST_PTR (t)); break; case FIXED_CST: dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t)); break; case TRUTH_NOT_EXPR: case ADDR_EXPR: case INDIRECT_REF: case CLEANUP_POINT_EXPR: case SAVE_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: /* These nodes are unary, but do not have code class `1'. */ dump_child ("op 0", TREE_OPERAND (t, 0)); break; case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: case INIT_EXPR: case MODIFY_EXPR: case COMPOUND_EXPR: case PREDECREMENT_EXPR: case PREINCREMENT_EXPR: case POSTDECREMENT_EXPR: case POSTINCREMENT_EXPR: /* These nodes are binary, but do not have code class `2'. */ dump_child ("op 0", TREE_OPERAND (t, 0)); dump_child ("op 1", TREE_OPERAND (t, 1)); break; case COMPONENT_REF: dump_child ("op 0", TREE_OPERAND (t, 0)); dump_child ("op 1", TREE_OPERAND (t, 1)); dump_child ("op 2", TREE_OPERAND (t, 2)); break; case ARRAY_REF: case ARRAY_RANGE_REF: dump_child ("op 0", TREE_OPERAND (t, 0)); dump_child ("op 1", TREE_OPERAND (t, 1)); dump_child ("op 2", TREE_OPERAND (t, 2)); dump_child ("op 3", TREE_OPERAND (t, 3)); break; case COND_EXPR: dump_child ("op 0", TREE_OPERAND (t, 0)); dump_child ("op 1", TREE_OPERAND (t, 1)); dump_child ("op 2", TREE_OPERAND (t, 2)); break; case TRY_FINALLY_EXPR: dump_child ("op 0", TREE_OPERAND (t, 0)); dump_child ("op 1", TREE_OPERAND (t, 1)); break; case CALL_EXPR: { int i = 0; tree arg; call_expr_arg_iterator iter; dump_child ("fn", CALL_EXPR_FN (t)); FOR_EACH_CALL_EXPR_ARG (arg, iter, t) { char buffer[32]; sprintf (buffer, "%u", i); dump_child (buffer, arg); i++; } } break; case CONSTRUCTOR: { unsigned HOST_WIDE_INT cnt; tree index, value; dump_int (di, "lngt", VEC_length (constructor_elt, CONSTRUCTOR_ELTS (t))); FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value) { dump_child ("idx", index); dump_child ("val", value); } }
void streamer_read_tree_bitfields (struct lto_input_block *ib, struct data_in *data_in, tree expr) { enum tree_code code; struct bitpack_d bp; /* Read the bitpack of non-pointer values from IB. */ bp = streamer_read_bitpack (ib); /* The first word in BP contains the code of the tree that we are about to read. */ code = (enum tree_code) bp_unpack_value (&bp, 16); lto_tag_check (lto_tree_code_to_tag (code), lto_tree_code_to_tag (TREE_CODE (expr))); /* Note that all these functions are highly sensitive to changes in the types and sizes of each of the fields being packed. */ unpack_ts_base_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) unpack_ts_int_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) unpack_ts_real_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST)) unpack_ts_fixed_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) stream_input_location (&DECL_SOURCE_LOCATION (expr), &bp, data_in); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) unpack_ts_decl_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)) unpack_ts_decl_wrtl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) unpack_ts_decl_with_vis_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) unpack_ts_function_decl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON)) unpack_ts_type_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_EXP)) { stream_input_location (&EXPR_CHECK (expr)->exp.locus, &bp, data_in); if (code == MEM_REF || code == TARGET_MEM_REF) { MR_DEPENDENCE_CLIQUE (expr) = (unsigned)bp_unpack_value (&bp, sizeof (short) * 8); if (MR_DEPENDENCE_CLIQUE (expr) != 0) MR_DEPENDENCE_BASE (expr) = (unsigned)bp_unpack_value (&bp, sizeof (short) * 8); } } if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) unpack_ts_block_value_fields (data_in, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) unpack_ts_translation_unit_decl_value_fields (data_in, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION)) cl_optimization_stream_in (&bp, TREE_OPTIMIZATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) { unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (&bp); if (length > 0) vec_safe_grow (BINFO_BASE_ACCESSES (expr), length); } if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) { unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (&bp); if (length > 0) vec_safe_grow (CONSTRUCTOR_ELTS (expr), length); } #ifndef ACCEL_COMPILER if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)) { cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr)); if (targetm.target_option.post_stream_in) targetm.target_option.post_stream_in (TREE_TARGET_OPTION (expr)); } #endif if (code == OMP_CLAUSE) unpack_ts_omp_clause_value_fields (data_in, &bp, expr); }
void streamer_write_tree_bitfields (struct output_block *ob, tree expr) { bitpack_d bp = bitpack_create (ob->main_stream); enum tree_code code; code = TREE_CODE (expr); /* Note that all these functions are highly sensitive to changes in the types and sizes of each of the fields being packed. */ pack_ts_base_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) pack_ts_int_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) pack_ts_real_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST)) pack_ts_fixed_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) stream_output_location (ob, &bp, DECL_SOURCE_LOCATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) pack_ts_decl_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)) pack_ts_decl_wrtl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) pack_ts_decl_with_vis_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) pack_ts_function_decl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON)) pack_ts_type_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_EXP)) { stream_output_location (ob, &bp, EXPR_LOCATION (expr)); if (code == MEM_REF || code == TARGET_MEM_REF) { bp_pack_value (&bp, MR_DEPENDENCE_CLIQUE (expr), sizeof (short) * 8); if (MR_DEPENDENCE_CLIQUE (expr) != 0) bp_pack_value (&bp, MR_DEPENDENCE_BASE (expr), sizeof (short) * 8); } } if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) pack_ts_block_value_fields (ob, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) pack_ts_translation_unit_decl_value_fields (ob, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION)) cl_optimization_stream_out (&bp, TREE_OPTIMIZATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) bp_pack_var_len_unsigned (&bp, vec_safe_length (BINFO_BASE_ACCESSES (expr))); if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) bp_pack_var_len_unsigned (&bp, CONSTRUCTOR_NELTS (expr)); if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION) /* Don't stream these when passing things to a different target. */ && !lto_stream_offload_p) cl_target_option_stream_out (ob, &bp, TREE_TARGET_OPTION (expr)); if (code == OMP_CLAUSE) pack_ts_omp_clause_value_fields (ob, &bp, expr); streamer_write_bitpack (&bp); }
static tree get_pseudo_ti_init (tree type, tree var_desc) { gcc_assert (at_eof); switch (TREE_CODE (type)) { case OFFSET_TYPE: return ptm_initializer (var_desc, type); case POINTER_TYPE: return ptr_initializer (var_desc, type); case ENUMERAL_TYPE: return generic_initializer (var_desc, type); break; case FUNCTION_TYPE: return generic_initializer (var_desc, type); break; case ARRAY_TYPE: return generic_initializer (var_desc, type); break; case UNION_TYPE: case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (type)) return ptm_initializer (var_desc, type); else if (var_desc == class_desc_type_node) return class_initializer (var_desc, type, NULL_TREE); else if (var_desc == si_class_desc_type_node) { tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0); tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE); return class_initializer (var_desc, type, base_inits); } else { int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0) | (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1)); tree binfo = TYPE_BINFO (type); int nbases = BINFO_N_BASE_BINFOS (binfo); VEC (tree) *base_accesses = BINFO_BASE_ACCESSES (binfo); tree base_inits = NULL_TREE; int ix; /* Generate the base information initializer. */ for (ix = nbases; ix--;) { tree base_binfo = BINFO_BASE_BINFO (binfo, ix); tree base_init = NULL_TREE; int flags = 0; tree tinfo; tree offset; if (VEC_index (tree, base_accesses, ix) == access_public_node) flags |= 2; tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); if (BINFO_VIRTUAL_P (base_binfo)) { /* We store the vtable offset at which the virtual base offset can be found. */ offset = BINFO_VPTR_FIELD (base_binfo); offset = convert (sizetype, offset); flags |= 1; } else offset = BINFO_OFFSET (base_binfo); /* Combine offset and flags into one field. */ offset = cp_build_binary_op (LSHIFT_EXPR, offset, build_int_cst (NULL_TREE, 8)); offset = cp_build_binary_op (BIT_IOR_EXPR, offset, build_int_cst (NULL_TREE, flags)); base_init = tree_cons (NULL_TREE, offset, base_init); base_init = tree_cons (NULL_TREE, tinfo, base_init); base_init = build_constructor (NULL_TREE, base_init); base_inits = tree_cons (NULL_TREE, base_init, base_inits); } base_inits = build_constructor (NULL_TREE, base_inits); base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE); /* Prepend the number of bases. */ base_inits = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, nbases), base_inits); /* Prepend the hint flags. */ base_inits = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, hint), base_inits); return class_initializer (var_desc, type, base_inits); } break; default: return generic_initializer (var_desc, type); } }
static tree get_pseudo_ti_desc (tree type) { switch (TREE_CODE (type)) { case OFFSET_TYPE: return ptm_desc_type_node; case POINTER_TYPE: return ptr_desc_type_node; case ENUMERAL_TYPE: return enum_desc_type_node; case FUNCTION_TYPE: return func_desc_type_node; case ARRAY_TYPE: return ary_desc_type_node; case UNION_TYPE: case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (type)) return ptm_desc_type_node; else if (!COMPLETE_TYPE_P (type)) { if (!at_eof) cxx_incomplete_type_error (NULL_TREE, type); return class_desc_type_node; } else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type))) return class_desc_type_node; else { tree binfo = TYPE_BINFO (type); VEC (tree) *base_accesses = BINFO_BASE_ACCESSES (binfo); tree base_binfo = BINFO_BASE_BINFO (binfo, 0); int num_bases = BINFO_N_BASE_BINFOS (binfo); if (num_bases == 1 && VEC_index (tree, base_accesses, 0) == access_public_node && !BINFO_VIRTUAL_P (base_binfo) && integer_zerop (BINFO_OFFSET (base_binfo))) /* single non-virtual public. */ return si_class_desc_type_node; else { tree var_desc; tree array_domain, base_array; if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases) { int ix; tree extend = make_tree_vec (num_bases + 5); for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;) TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix); vmi_class_desc_type_node = extend; } var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases); if (var_desc) return var_desc; /* Create the array of __base_class_type_info entries. G++ 3.2 allocated an array that had one too many entries, and then filled that extra entries with zeros. */ if (abi_version_at_least (2)) array_domain = build_index_type (size_int (num_bases - 1)); else array_domain = build_index_type (size_int (num_bases)); base_array = build_array_type (base_desc_type_node, array_domain); push_nested_namespace (abi_node); var_desc = create_pseudo_type_info ("__vmi_class_type_info", num_bases, build_decl (FIELD_DECL, NULL_TREE, integer_type_node), build_decl (FIELD_DECL, NULL_TREE, integer_type_node), build_decl (FIELD_DECL, NULL_TREE, base_array), NULL); pop_nested_namespace (abi_node); TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc; return var_desc; } } default: return bltn_desc_type_node; } }
static void unpack_value_fields (struct data_in *data_in, struct bitpack_d *bp, tree expr) { enum tree_code code; code = TREE_CODE (expr); /* Note that all these functions are highly sensitive to changes in the types and sizes of each of the fields being packed. */ unpack_ts_base_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) unpack_ts_int_cst_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) unpack_ts_real_cst_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST)) unpack_ts_fixed_cst_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) DECL_SOURCE_LOCATION (expr) = stream_input_location (bp, data_in); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) unpack_ts_decl_common_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)) unpack_ts_decl_wrtl_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) unpack_ts_decl_with_vis_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) unpack_ts_function_decl_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON)) unpack_ts_type_common_value_fields (bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_EXP)) { SET_EXPR_LOCATION (expr, stream_input_location (bp, data_in)); if (code == MEM_REF || code == TARGET_MEM_REF) { MR_DEPENDENCE_CLIQUE (expr) = (unsigned)bp_unpack_value (bp, sizeof (short) * 8); if (MR_DEPENDENCE_CLIQUE (expr) != 0) MR_DEPENDENCE_BASE (expr) = (unsigned)bp_unpack_value (bp, sizeof (short) * 8); } } if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) unpack_ts_block_value_fields (data_in, bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION)) cl_optimization_stream_in (bp, TREE_OPTIMIZATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) { unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp); if (length > 0) vec_safe_grow (BINFO_BASE_ACCESSES (expr), length); } if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) { unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp); if (length > 0) vec_safe_grow (CONSTRUCTOR_ELTS (expr), length); } #ifndef ACCEL_COMPILER if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)) cl_target_option_stream_in (data_in, bp, TREE_TARGET_OPTION (expr)); #endif if (code == OMP_CLAUSE) unpack_ts_omp_clause_value_fields (data_in, bp, expr); }