void cxx_print_type (FILE *file, tree node, int indent) { switch (TREE_CODE (node)) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: indent_to (file, indent + 3); fprintf (file, "index " HOST_WIDE_INT_PRINT_DEC " level " HOST_WIDE_INT_PRINT_DEC " orig_level " HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_IDX (node), TEMPLATE_TYPE_LEVEL (node), TEMPLATE_TYPE_ORIG_LEVEL (node)); return; case FUNCTION_TYPE: case METHOD_TYPE: if (TYPE_RAISES_EXCEPTIONS (node)) print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4); return; case RECORD_TYPE: case UNION_TYPE: break; default: return; } if (TYPE_PTRMEMFUNC_P (node)) print_node (file, "ptrmemfunc fn type", TYPE_PTRMEMFUNC_FN_TYPE (node), indent + 4); if (! CLASS_TYPE_P (node)) return; indent_to (file, indent + 3); if (TYPE_NEEDS_CONSTRUCTING (node)) fputs ( "needs-constructor", file); if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (node)) fputs (" needs-destructor", file); if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node)) fputs (" X()", file); if (TYPE_HAS_CONVERSION (node)) fputs (" has-type-conversion", file); if (TYPE_HAS_INIT_REF (node)) { if (TYPE_HAS_CONST_INIT_REF (node)) fputs (" X(constX&)", file); else fputs (" X(X&)", file); } if (TYPE_HAS_NEW_OPERATOR (node)) fputs (" new", file); if (TYPE_HAS_ARRAY_NEW_OPERATOR (node)) fputs (" new[]", file); if (TYPE_GETS_DELETE (node) & 1) fputs (" delete", file); if (TYPE_GETS_DELETE (node) & 2) fputs (" delete[]", file); if (TYPE_HAS_ASSIGN_REF (node)) fputs (" this=(X&)", file); if (TREE_CODE (node) == RECORD_TYPE) { if (TYPE_BINFO (node)) fprintf (file, " n_parents=%d", BINFO_N_BASE_BINFOS (TYPE_BINFO (node))); else fprintf (file, " no-binfo"); fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node)); if (CLASSTYPE_INTERFACE_ONLY (node)) fprintf (file, " interface-only"); if (CLASSTYPE_INTERFACE_UNKNOWN (node)) fprintf (file, " interface-unknown"); } }
tree build_expr_type_conversion (int desires, tree expr, bool complain) { tree basetype = TREE_TYPE (expr); tree conv = NULL_TREE; tree winner = NULL_TREE; if (expr == null_node && (desires & WANT_INT) && !(desires & WANT_NULL)) warning (OPT_Wconversion, "converting NULL to non-pointer type"); basetype = TREE_TYPE (expr); if (basetype == error_mark_node) return error_mark_node; if (! MAYBE_CLASS_TYPE_P (basetype)) switch (TREE_CODE (basetype)) { case INTEGER_TYPE: if ((desires & WANT_NULL) && null_ptr_cst_p (expr)) return expr; /* else fall through... */ case BOOLEAN_TYPE: return (desires & WANT_INT) ? expr : NULL_TREE; case ENUMERAL_TYPE: return (desires & WANT_ENUM) ? expr : NULL_TREE; case REAL_TYPE: return (desires & WANT_FLOAT) ? expr : NULL_TREE; case POINTER_TYPE: return (desires & WANT_POINTER) ? expr : NULL_TREE; case FUNCTION_TYPE: case ARRAY_TYPE: return (desires & WANT_POINTER) ? decay_conversion (expr) : NULL_TREE; case VECTOR_TYPE: if ((desires & WANT_VECTOR) == 0) return NULL_TREE; switch (TREE_CODE (TREE_TYPE (basetype))) { case INTEGER_TYPE: case BOOLEAN_TYPE: return (desires & WANT_INT) ? expr : NULL_TREE; case ENUMERAL_TYPE: return (desires & WANT_ENUM) ? expr : NULL_TREE; case REAL_TYPE: return (desires & WANT_FLOAT) ? expr : NULL_TREE; default: return NULL_TREE; } default: return NULL_TREE; } /* The code for conversions from class type is currently only used for delete expressions. Other expressions are handled by build_new_op. */ if (!complete_type_or_else (basetype, expr)) return error_mark_node; if (!TYPE_HAS_CONVERSION (basetype)) return NULL_TREE; for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv)) { int win = 0; tree candidate; tree cand = TREE_VALUE (conv); if (winner && winner == cand) continue; candidate = non_reference (TREE_TYPE (TREE_TYPE (cand))); switch (TREE_CODE (candidate)) { case BOOLEAN_TYPE: case INTEGER_TYPE: win = (desires & WANT_INT); break; case ENUMERAL_TYPE: win = (desires & WANT_ENUM); break; case REAL_TYPE: win = (desires & WANT_FLOAT); break; case POINTER_TYPE: win = (desires & WANT_POINTER); break; case VECTOR_TYPE: if ((desires & WANT_VECTOR) == 0) break; switch (TREE_CODE (TREE_TYPE (candidate))) { case BOOLEAN_TYPE: case INTEGER_TYPE: win = (desires & WANT_INT); break; case ENUMERAL_TYPE: win = (desires & WANT_ENUM); break; case REAL_TYPE: win = (desires & WANT_FLOAT); break; default: break; } break; default: break; } if (win) { if (winner) { if (complain) { error ("ambiguous default type conversion from %qT", basetype); error (" candidate conversions include %qD and %qD", winner, cand); } return error_mark_node; } else winner = cand; } } if (winner) { tree type = non_reference (TREE_TYPE (TREE_TYPE (winner))); return build_user_type_conversion (type, expr, LOOKUP_NORMAL); } return NULL_TREE; }
void cxx_print_type (FILE *file, tree node, int indent) { switch (TREE_CODE (node)) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: indent_to (file, indent + 3); fprintf (file, "index %d level %d orig_level %d", TEMPLATE_TYPE_IDX (node), TEMPLATE_TYPE_LEVEL (node), TEMPLATE_TYPE_ORIG_LEVEL (node)); return; case FUNCTION_TYPE: case METHOD_TYPE: if (TYPE_RAISES_EXCEPTIONS (node)) print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4); return; case RECORD_TYPE: case UNION_TYPE: break; case DECLTYPE_TYPE: print_node (file, "expr", DECLTYPE_TYPE_EXPR (node), indent + 4); return; case TYPENAME_TYPE: print_node (file, "fullname", TYPENAME_TYPE_FULLNAME (node), indent + 4); return; case TYPE_PACK_EXPANSION: print_node (file, "args", PACK_EXPANSION_EXTRA_ARGS (node), indent + 4); return; default: return; } if (TYPE_PTRMEMFUNC_P (node)) print_node (file, "ptrmemfunc fn type", TYPE_PTRMEMFUNC_FN_TYPE (node), indent + 4); if (! CLASS_TYPE_P (node)) return; indent_to (file, indent + 4); fprintf (file, "full-name \"%s\"", type_as_string (node, TFF_CLASS_KEY_OR_ENUM)); indent_to (file, indent + 3); if (TYPE_NEEDS_CONSTRUCTING (node)) fputs ( " needs-constructor", file); if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (node)) fputs (" needs-destructor", file); if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node)) fputs (" X()", file); if (TYPE_HAS_CONVERSION (node)) fputs (" has-type-conversion", file); if (TYPE_HAS_COPY_CTOR (node)) { if (TYPE_HAS_CONST_COPY_CTOR (node)) fputs (" X(constX&)", file); else fputs (" X(X&)", file); } if (TYPE_HAS_NEW_OPERATOR (node)) fputs (" new", file); if (TYPE_HAS_ARRAY_NEW_OPERATOR (node)) fputs (" new[]", file); if (TYPE_GETS_DELETE (node) & 1) fputs (" delete", file); if (TYPE_GETS_DELETE (node) & 2) fputs (" delete[]", file); if (TYPE_HAS_COPY_ASSIGN (node)) fputs (" this=(X&)", file); if (CLASSTYPE_SORTED_FIELDS (node)) fprintf (file, " sorted-fields %p", (void *) CLASSTYPE_SORTED_FIELDS (node)); if (TREE_CODE (node) == RECORD_TYPE) { if (TYPE_BINFO (node)) fprintf (file, " n_parents=%d", BINFO_N_BASE_BINFOS (TYPE_BINFO (node))); else fprintf (file, " no-binfo"); fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node)); if (CLASSTYPE_INTERFACE_ONLY (node)) fprintf (file, " interface-only"); if (CLASSTYPE_INTERFACE_UNKNOWN (node)) fprintf (file, " interface-unknown"); } }