📄 error.c
字号:
case TREE_VEC: case UNION_TYPE: case UNKNOWN_TYPE: case VOID_TYPE: case TYPENAME_TYPE: case COMPLEX_TYPE: dump_type_real (t, v, canonical_name); break; default: sorry ("`%s' not supported by dump_type_prefix", tree_code_name[(int) TREE_CODE (t)]); }}static voiddump_type_suffix (t, v, canonical_name) tree t; int v; /* verbose? */ int canonical_name;{ if (TYPE_PTRMEMFUNC_P (t)) t = TYPE_PTRMEMFUNC_FN_TYPE (t); switch (TREE_CODE (t)) { case POINTER_TYPE: case REFERENCE_TYPE: case OFFSET_TYPE: if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) OB_PUTC (')'); dump_type_suffix (TREE_TYPE (t), v, canonical_name); break; /* Can only be reached through function pointer */ case FUNCTION_TYPE: case METHOD_TYPE: { tree arg; OB_PUTC (')'); arg = TYPE_ARG_TYPES (t); if (TREE_CODE (t) == METHOD_TYPE) arg = TREE_CHAIN (arg); /* Function pointers don't have default args. Not in standard C++, anyway; they may in g++, but we'll just pretend otherwise. */ dump_parameters (arg, 0, canonical_name); if (TREE_CODE (t) == METHOD_TYPE) dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); dump_type_suffix (TREE_TYPE (t), v, canonical_name); dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), canonical_name); break; } case ARRAY_TYPE: OB_PUTC ('['); if (TYPE_DOMAIN (t)) { if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST) OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1); else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0); else dump_expr (fold (build_binary_op (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), integer_one_node)), 0); } OB_PUTC (']'); dump_type_suffix (TREE_TYPE (t), v, canonical_name); break; case ENUMERAL_TYPE: case ERROR_MARK: case IDENTIFIER_NODE: case INTEGER_TYPE: case BOOLEAN_TYPE: case REAL_TYPE: case RECORD_TYPE: case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: case TREE_LIST: case TYPE_DECL: case TREE_VEC: case UNION_TYPE: case UNKNOWN_TYPE: case VOID_TYPE: case TYPENAME_TYPE: case COMPLEX_TYPE: break; default: sorry ("`%s' not supported by dump_type_suffix", tree_code_name[(int) TREE_CODE (t)]); }}/* Return a function declaration which corresponds to the IDENTIFIER_NODE argument. */static treeident_fndecl (t) tree t;{ tree n = lookup_name (t, 0); if (n == NULL_TREE) return NULL_TREE; if (TREE_CODE (n) == FUNCTION_DECL) return n; else if (TREE_CODE (n) == TREE_LIST && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL) return TREE_VALUE (n); my_friendly_abort (66); return NULL_TREE;}#ifndef NO_DOLLAR_IN_LABEL# define GLOBAL_THING "_GLOBAL_$"#else# ifndef NO_DOT_IN_LABEL# define GLOBAL_THING "_GLOBAL_."# else# define GLOBAL_THING "_GLOBAL__"# endif#endif#define GLOBAL_IORD_P(NODE) \ ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)static voiddump_global_iord (t) tree t;{ char *name = IDENTIFIER_POINTER (t); OB_PUTS ("(static "); if (name [sizeof (GLOBAL_THING) - 1] == 'I') OB_PUTS ("initializers"); else if (name [sizeof (GLOBAL_THING) - 1] == 'D') OB_PUTS ("destructors"); else my_friendly_abort (352); OB_PUTS (" for "); OB_PUTCP (input_filename); OB_PUTC (')');}static voiddump_simple_decl (t, type, v) tree t; tree type; int v;{ if (v > 0) { dump_type_prefix (type, v, 0); OB_PUTC (' '); } if (interesting_scope_p (DECL_CONTEXT (t))) { dump_decl (DECL_CONTEXT (t), 0); OB_PUTC2 (':',':'); } if (DECL_NAME (t)) dump_decl (DECL_NAME (t), v); else OB_PUTS ("{anon}"); if (v > 0) dump_type_suffix (type, v, 0);}static voiddump_decl (t, v) tree t; int v; /* verbosity */{ if (t == NULL_TREE) return; switch (TREE_CODE (t)) { case ERROR_MARK: OB_PUTS (" /* decl error */ "); break; case TYPE_DECL: { /* Don't say 'typedef class A' */ if (DECL_ARTIFICIAL (t)) { if (v > 0 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) /* Say `class T' not just `T'. */ OB_PUTS ("class "); dump_type (TREE_TYPE (t), v); break; } } if (v > 0) OB_PUTS ("typedef "); dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), v); break; case VAR_DECL: if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) { OB_PUTS ("vtable for "); if (TYPE_P (DECL_CONTEXT (t))) dump_type (DECL_CONTEXT (t), v); else /* This case can arise with -fno-vtable-thunks. See expand_upcast_fixups. It's not clear what to print here. */ OB_PUTS ("{unknown type}"); break; } /* else fall through */ case FIELD_DECL: case PARM_DECL: dump_simple_decl (t, TREE_TYPE (t), v); break; case NAMESPACE_DECL: if (CP_DECL_CONTEXT (t) != global_namespace) { dump_decl (DECL_CONTEXT (t), v); OB_PUTC2 (':',':'); } if (DECL_NAME (t) == anonymous_namespace_name) OB_PUTS ("{anonymous}"); else OB_PUTID (DECL_NAME (t)); break; case SCOPE_REF: dump_decl (TREE_OPERAND (t, 0), 0); OB_PUTS ("::"); dump_decl (TREE_OPERAND (t, 1), 0); break; case ARRAY_REF: dump_decl (TREE_OPERAND (t, 0), v); OB_PUTC ('['); dump_decl (TREE_OPERAND (t, 1), v); OB_PUTC (']'); break; /* So that we can do dump_decl in dump_aggr_type and have it work for both class and function scope. */ case RECORD_TYPE: case UNION_TYPE: case ENUMERAL_TYPE: dump_type (t, v); break; case TYPE_EXPR: my_friendly_abort (69); break; /* These special cases are duplicated here so that other functions can feed identifiers to cp_error and get them demangled properly. */ case IDENTIFIER_NODE: { tree f; if (DESTRUCTOR_NAME_P (t) && (f = ident_fndecl (t)) && DECL_LANGUAGE (f) == lang_cplusplus) { OB_PUTC ('~'); dump_decl (DECL_NAME (f), 0); } else if (IDENTIFIER_TYPENAME_P (t)) { OB_PUTS ("operator "); /* Not exactly IDENTIFIER_TYPE_VALUE. */ dump_type (TREE_TYPE (t), 0); break; } else if (IDENTIFIER_OPNAME_P (t)) { char *name_string = operator_name_string (t); OB_PUTS ("operator "); OB_PUTCP (name_string); } else OB_PUTID (t); } break; case OVERLOAD: t = OVL_CURRENT (t); /* Fall through. */ case FUNCTION_DECL: if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t))) dump_global_iord (DECL_ASSEMBLER_NAME (t)); else if (! DECL_LANG_SPECIFIC (t)) OB_PUTS ("{internal}"); else dump_function_decl (t, v); break; case TEMPLATE_DECL: { tree orig_args = DECL_TEMPLATE_PARMS (t); tree args; int i; for (args = orig_args = nreverse (orig_args); args; args = TREE_CHAIN (args)) { int len = TREE_VEC_LENGTH (TREE_VALUE (args)); OB_PUTS ("template <"); for (i = 0; i < len; i++) { tree arg = TREE_VEC_ELT (TREE_VALUE (args), i); tree defval = TREE_PURPOSE (arg); arg = TREE_VALUE (arg); if (TREE_CODE (arg) == TYPE_DECL) { if (DECL_NAME (arg)) { OB_PUTS ("class "); OB_PUTID (DECL_NAME (arg)); } else OB_PUTS ("class"); } else dump_decl (arg, 1); if (defval) { OB_PUTS (" = "); if (TREE_CODE (arg) == TYPE_DECL || TREE_CODE (arg) == TEMPLATE_DECL) dump_type (defval, 1); else dump_expr (defval, 1); } OB_PUTC2 (',', ' '); } if (len != 0) OB_UNPUT (2); OB_END_TEMPLATE_ID (); OB_PUTC (' '); } nreverse(orig_args); if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) dump_type (TREE_TYPE (t), v); else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) dump_decl (DECL_TEMPLATE_RESULT (t), v); else if (TREE_TYPE (t) == NULL_TREE) my_friendly_abort (353); else switch (NEXT_CODE (t)) { case METHOD_TYPE: case FUNCTION_TYPE: dump_function_decl (t, v); break; default: /* This case can occur with some illegal code. */ dump_type (TREE_TYPE (t), v); } } break; case TEMPLATE_ID_EXPR: { tree args; tree name = TREE_OPERAND (t, 0); if (is_overloaded_fn (name)) name = DECL_NAME (get_first_fn (name)); dump_decl (name, v); OB_PUTC ('<'); for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args)) { if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (args))) == 't' || TREE_CODE (TREE_VALUE (args)) == TEMPLATE_DECL) dump_type (TREE_VALUE (args), 0); else dump_expr (TREE_VALUE (args), 0); if (TREE_CHAIN (args)) OB_PUTC2 (',', ' '); } OB_END_TEMPLATE_ID (); } break; case LOOKUP_EXPR: dump_decl (TREE_OPERAND (t, 0), v); break; case LABEL_DECL: OB_PUTID (DECL_NAME (t)); break; case CONST_DECL: if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) || (DECL_INITIAL (t) && TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) dump_simple_decl (t, TREE_TYPE (t), v); else if (DECL_NAME (t)) dump_decl (DECL_NAME (t), v); else if (DECL_INITIAL (t)) dump_expr (DECL_INITIAL (t), 0); else OB_PUTS ("enumerator"); break; case USING_DECL: OB_PUTS ("using "); dump_type (DECL_INITIAL (t), 0); OB_PUTS ("::"); OB_PUTID (DECL_NAME (t)); break; default: sorry ("`%s' not supported by dump_decl", tree_code_name[(int) TREE_CODE (t)]); }}/* Pretty print a function decl. There are several ways we want to print a function declaration. We use V to tell us what. V - 01 23 args - ++ ++ retval - -+ ++ default- -+ -+ throw - -- ++ As cp_error can only apply the '#' flag once to give 0 and 1 for V, there is %D which doesn't print the throw specs, and %F which does. */static voiddump_function_decl (t, v) tree t; int v;{ tree name; tree fntype; tree parmtypes; tree cname = NULL_TREE; if (TREE_CODE (t) == TEMPLATE_DECL) t = DECL_TEMPLATE_RESULT (t); name = DECL_ASSEMBLER_NAME (t); fntype = TREE_TYPE (t); parmtypes = TYPE_ARG_TYPES (fntype); /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */ if (DECL_CLASS_SCOPE_P (t)) cname = DECL_CLASS_CONTEXT (t); /* this is for partially instantiated template methods */ else if (TREE_CODE (fntype) == METHOD_TYPE) cname = TREE_TYPE (TREE_VALUE (parmtypes)); /* Print the return type. */ if (v > 0) { if (DECL_STATIC_FUNCTION_P (t)) OB_PUTS ("static "); if (! DECL_CONV_FN_P (t) && ! DECL_CONSTRUCTOR_P (t) && ! DECL_DESTRUCTOR_P (t)) { dump_type_prefix (TREE_TYPE (fntype), 1, 0); OB_PUTC (' '); } } /* Print the function name. */ if (cname) { dump_type (cname, 0); OB_PUTC2 (':', ':'); if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes) parmtypes = TREE_CHAIN (parmtypes); if (DECL_CONSTRUCTOR_FOR_VBASE_P (t)) /* Skip past "in_charge" identifier. */ parmtypes = TREE_CHAIN (parmtypes); } else if (CP_DECL_CONTEXT (t) != global_namespace) { dump_decl (DECL_CONTEXT (t), 0); OB_PUTC2 (':',':'); } if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus) parmtypes = TREE_CHAIN (parmtypes); dump_function_name (t); /* If V is negative, we don't print the argument types. */ if (v < 0) return; dump_parameters (parmtypes, v & 1, 0); if (v && ! DECL_CONV_FN_P (t)) dump_type_suffix (TREE_TYPE (fntype), 1, 0); if (TREE_CODE (fntype) == METHOD_TYPE) { if (IS_SIGNATURE (cname)) /* We look at the type pointed to by the `optr' field of `this.' */ dump_qualifiers (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before); else dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before); } if (v >= 2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -