void cxx_print_decl (FILE *file, tree node, int indent) { if (TREE_CODE (node) == FIELD_DECL) { if (DECL_MUTABLE_P (node)) { indent_to (file, indent + 3); fprintf (file, " mutable "); } return; } if (!CODE_CONTAINS_STRUCT (TREE_CODE (node), TS_DECL_COMMON) || !DECL_LANG_SPECIFIC (node)) return; indent_to (file, indent + 3); if (TREE_CODE (node) == FUNCTION_DECL && DECL_PENDING_INLINE_INFO (node)) fprintf (file, " pending-inline-info %p", (void *) DECL_PENDING_INLINE_INFO (node)); if (TREE_CODE (node) == TYPE_DECL && DECL_SORTED_FIELDS (node)) fprintf (file, " sorted-fields %p", (void *) DECL_SORTED_FIELDS (node)); if ((TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL) && DECL_TEMPLATE_INFO (node)) fprintf (file, " template-info %p", (void *) DECL_TEMPLATE_INFO (node)); }
void cxx_print_decl (FILE *file, tree node, int indent) { if (TREE_CODE (node) == FIELD_DECL) { if (DECL_MUTABLE_P (node)) { indent_to (file, indent + 3); fprintf (file, " mutable "); } return; } if (!CODE_CONTAINS_STRUCT (TREE_CODE (node), TS_DECL_COMMON) || !DECL_LANG_SPECIFIC (node)) return; if (TREE_CODE (node) == FUNCTION_DECL) { int flags = TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE |TFF_FUNCTION_DEFAULT_ARGUMENTS|TFF_EXCEPTION_SPECIFICATION ; indent_to (file, indent + 3); fprintf (file, " full-name \"%s\"", decl_as_string (node, flags)); } else if (TREE_CODE (node) == TEMPLATE_DECL) { indent_to (file, indent + 3); fprintf (file, " full-name \"%s\"", decl_as_string (node, TFF_TEMPLATE_HEADER)); } indent_to (file, indent + 3); if (DECL_EXTERNAL (node) && DECL_NOT_REALLY_EXTERN (node)) fprintf (file, " not-really-extern"); if (TREE_CODE (node) == FUNCTION_DECL && DECL_PENDING_INLINE_INFO (node)) fprintf (file, " pending-inline-info %p", (void *) DECL_PENDING_INLINE_INFO (node)); if (VAR_OR_FUNCTION_DECL_P (node) && DECL_TEMPLATE_INFO (node)) fprintf (file, " template-info %p", (void *) DECL_TEMPLATE_INFO (node)); }
bool cp_dump_tree (void* dump_info, tree t) { enum tree_code code; dump_info_p di = (dump_info_p) dump_info; /* Figure out what kind of node this is. */ code = TREE_CODE (t); if (DECL_P (t)) { if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus) dump_string (di, language_to_string (DECL_LANGUAGE (t))); } switch (code) { case IDENTIFIER_NODE: if (IDENTIFIER_OPNAME_P (t)) { dump_string (di, "operator"); return true; } else if (IDENTIFIER_TYPENAME_P (t)) { dump_child ("tynm", TREE_TYPE (t)); return true; } break; case OFFSET_TYPE: dump_string (di, "ptrmem"); dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t)); dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t)); return true; case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (t)) { dump_string (di, "ptrmem"); dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t)); dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t)); return true; } /* Fall through. */ case UNION_TYPE: /* Is it a type used as a base? */ if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t) && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t) { dump_child ("bfld", TYPE_CONTEXT (t)); return true; } if (! IS_AGGR_TYPE (t)) break; dump_child ("vfld", TYPE_VFIELD (t)); if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t)) dump_string(di, "spec"); if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t)) { int i; tree binfo; tree base_binfo; for (binfo = TYPE_BINFO (t), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) { dump_child ("base", BINFO_TYPE (base_binfo)); if (BINFO_VIRTUAL_P (base_binfo)) dump_string (di, "virtual"); dump_access (di, base_binfo); } } break; case FIELD_DECL: dump_access (di, t); if (DECL_MUTABLE_P (t)) dump_string(di, "mutable"); break; case VAR_DECL: if (TREE_CODE (CP_DECL_CONTEXT (t)) == RECORD_TYPE) dump_access (di, t); if (TREE_STATIC (t) && !TREE_PUBLIC (t)) dump_string (di, "static"); break; case FUNCTION_DECL: if (!DECL_THUNK_P (t)) { if (DECL_OVERLOADED_OPERATOR_P (t)) { dump_string (di, "operator"); dump_op (di, t); } if (DECL_FUNCTION_MEMBER_P (t)) { dump_string (di, "member"); dump_access (di, t); } if (DECL_PURE_VIRTUAL_P (t)) dump_string (di, "pure"); if (DECL_VIRTUAL_P (t)) dump_string (di, "virtual"); if (DECL_CONSTRUCTOR_P (t)) dump_string (di, "constructor"); if (DECL_DESTRUCTOR_P (t)) dump_string (di, "destructor"); if (DECL_CONV_FN_P (t)) dump_string (di, "conversion"); if (DECL_GLOBAL_CTOR_P (t)) dump_string (di, "global init"); if (DECL_GLOBAL_DTOR_P (t)) dump_string (di, "global fini"); if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)) dump_string (di, "pseudo tmpl"); } else { tree virt = THUNK_VIRTUAL_OFFSET (t); dump_string (di, "thunk"); if (DECL_THIS_THUNK_P (t)) dump_string (di, "this adjusting"); else { dump_string (di, "result adjusting"); if (virt) virt = BINFO_VPTR_FIELD (virt); } dump_int (di, "fixd", THUNK_FIXED_OFFSET (t)); if (virt) dump_int (di, "virt", tree_low_cst (virt, 0)); dump_child ("fn", DECL_INITIAL (t)); } break; case NAMESPACE_DECL: if (DECL_NAMESPACE_ALIAS (t)) dump_child ("alis", DECL_NAMESPACE_ALIAS (t)); else if (!dump_flag (di, TDF_SLIM, t)) dump_child ("dcls", cp_namespace_decls (t)); break; case TEMPLATE_DECL: dump_child ("rslt", DECL_TEMPLATE_RESULT (t)); dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t)); dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t)); dump_child ("prms", DECL_TEMPLATE_PARMS (t)); break; case OVERLOAD: dump_child ("crnt", OVL_CURRENT (t)); dump_child ("chan", OVL_CHAIN (t)); break; case TRY_BLOCK: dump_stmt (di, t); if (CLEANUP_P (t)) dump_string (di, "cleanup"); dump_child ("body", TRY_STMTS (t)); dump_child ("hdlr", TRY_HANDLERS (t)); break; case EH_SPEC_BLOCK: dump_stmt (di, t); dump_child ("body", EH_SPEC_STMTS (t)); dump_child ("raises", EH_SPEC_RAISES (t)); break; case PTRMEM_CST: dump_child ("clas", PTRMEM_CST_CLASS (t)); dump_child ("mbr", PTRMEM_CST_MEMBER (t)); break; case THROW_EXPR: /* These nodes are unary, but do not have code class `1'. */ dump_child ("op 0", TREE_OPERAND (t, 0)); break; case AGGR_INIT_EXPR: dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t)); dump_child ("fn", TREE_OPERAND (t, 0)); dump_child ("args", TREE_OPERAND (t, 1)); dump_child ("decl", TREE_OPERAND (t, 2)); break; case HANDLER: dump_stmt (di, t); dump_child ("parm", HANDLER_PARMS (t)); dump_child ("body", HANDLER_BODY (t)); break; case MUST_NOT_THROW_EXPR: dump_stmt (di, t); dump_child ("body", TREE_OPERAND (t, 0)); break; case USING_STMT: dump_stmt (di, t); dump_child ("nmsp", USING_STMT_NAMESPACE (t)); break; case CLEANUP_STMT: dump_stmt (di, t); dump_child ("decl", CLEANUP_DECL (t)); dump_child ("expr", CLEANUP_EXPR (t)); dump_child ("body", CLEANUP_BODY (t)); break; case IF_STMT: dump_stmt (di, t); dump_child ("cond", IF_COND (t)); dump_child ("then", THEN_CLAUSE (t)); dump_child ("else", ELSE_CLAUSE (t)); break; default: break; } return c_dump_tree (di, t); }
static void do_build_assign_ref (tree fndecl) { tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); tree compound_stmt; compound_stmt = begin_compound_stmt (0); parm = convert_from_reference (parm); if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type) && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)) { tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm); finish_expr_stmt (t); } else { tree fields; int cvquals = cp_type_quals (TREE_TYPE (parm)); int i; tree binfo, base_binfo; /* Assign to each of the direct base classes. */ for (binfo = TYPE_BINFO (current_class_type), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) { tree converted_parm; /* We must convert PARM directly to the base class explicitly since the base class may be ambiguous. */ converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1); /* Call the base class assignment operator. */ finish_expr_stmt (build_special_member_call (current_class_ref, ansi_assopname (NOP_EXPR), build_tree_list (NULL_TREE, converted_parm), base_binfo, LOOKUP_NORMAL | LOOKUP_NONVIRTUAL)); } /* Assign to each of the non-static data members. */ for (fields = TYPE_FIELDS (current_class_type); fields; fields = TREE_CHAIN (fields)) { tree comp = current_class_ref; tree init = parm; tree field = fields; tree expr_type; int quals; if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) continue; expr_type = TREE_TYPE (field); if (CP_TYPE_CONST_P (expr_type)) { error ("non-static const member %q#D, can't use default " "assignment operator", field); continue; } else if (TREE_CODE (expr_type) == REFERENCE_TYPE) { error ("non-static reference member %q#D, can't use " "default assignment operator", field); continue; } if (DECL_NAME (field)) { if (VFIELD_NAME_P (DECL_NAME (field))) continue; } else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type) != NULL_TREE) /* Just use the field; anonymous types can't have nontrivial copy ctors or assignment ops. */; else continue; comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE); /* Compute the type of init->field */ quals = cvquals; if (DECL_MUTABLE_P (field)) quals &= ~TYPE_QUAL_CONST; expr_type = cp_build_qualified_type (expr_type, quals); init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE); if (DECL_NAME (field)) init = build_modify_expr (comp, NOP_EXPR, init); else init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init); finish_expr_stmt (init); } } finish_return_stmt (current_class_ref); finish_compound_stmt (compound_stmt); }
static void do_build_copy_constructor (tree fndecl) { tree parm = FUNCTION_FIRST_USER_PARM (fndecl); parm = convert_from_reference (parm); if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type) && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)) { tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm); finish_expr_stmt (t); } else { tree fields = TYPE_FIELDS (current_class_type); tree member_init_list = NULL_TREE; int cvquals = cp_type_quals (TREE_TYPE (parm)); int i; tree binfo, base_binfo; VEC(tree,gc) *vbases; /* Initialize all the base-classes with the parameter converted to their type so that we get their copy constructor and not another constructor that takes current_class_type. We must deal with the binfo's directly as a direct base might be inaccessible due to ambiguity. */ for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0; VEC_iterate (tree, vbases, i, binfo); i++) { member_init_list = tree_cons (binfo, build_tree_list (NULL_TREE, build_base_path (PLUS_EXPR, parm, binfo, 1)), member_init_list); } for (binfo = TYPE_BINFO (current_class_type), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) { if (BINFO_VIRTUAL_P (base_binfo)) continue; member_init_list = tree_cons (base_binfo, build_tree_list (NULL_TREE, build_base_path (PLUS_EXPR, parm, base_binfo, 1)), member_init_list); } for (; fields; fields = TREE_CHAIN (fields)) { tree init = parm; tree field = fields; tree expr_type; if (TREE_CODE (field) != FIELD_DECL) continue; expr_type = TREE_TYPE (field); if (DECL_NAME (field)) { if (VFIELD_NAME_P (DECL_NAME (field))) continue; } else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type)) /* Just use the field; anonymous types can't have nontrivial copy ctors or assignment ops. */; else continue; /* Compute the type of "init->field". If the copy-constructor parameter is, for example, "const S&", and the type of the field is "T", then the type will usually be "const T". (There are no cv-qualified variants of reference types.) */ if (TREE_CODE (expr_type) != REFERENCE_TYPE) { int quals = cvquals; if (DECL_MUTABLE_P (field)) quals &= ~TYPE_QUAL_CONST; expr_type = cp_build_qualified_type (expr_type, quals); } init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE); init = build_tree_list (NULL_TREE, init); member_init_list = tree_cons (field, init, member_init_list); } finish_mem_initializers (member_init_list); } }