📄 typeck.c
字号:
push_super_field (t, object_type_node); layout_type (t); return t;}/* Promote TYPE to the type actually used for fields and parameters. */treepromote_type (type) tree type;{ switch (TREE_CODE (type)) { case RECORD_TYPE: return build_pointer_type (CLASS_TO_HANDLE_TYPE (type)); case BOOLEAN_TYPE: if (type == boolean_type_node) return promoted_boolean_type_node; goto handle_int; case CHAR_TYPE: if (type == char_type_node) return promoted_char_type_node; goto handle_int; case INTEGER_TYPE: handle_int: if (TYPE_PRECISION (type) < TYPE_PRECISION (int_type_node)) { if (type == short_type_node) return promoted_short_type_node; if (type == byte_type_node) return promoted_byte_type_node; return int_type_node; } /* ... else fall through ... */ default: return type; }}/* Parse a signature string, starting at *PTR and ending at LIMIT. Return the seen TREE_TYPE, updating *PTR. */static treeparse_signature_type (ptr, limit) const unsigned char **ptr, *limit;{ tree type; if ((*ptr) >= limit) fatal ("bad signature string"); switch (*(*ptr)) { case 'B': (*ptr)++; return byte_type_node; case 'C': (*ptr)++; return char_type_node; case 'D': (*ptr)++; return double_type_node; case 'F': (*ptr)++; return float_type_node; case 'S': (*ptr)++; return short_type_node; case 'I': (*ptr)++; return int_type_node; case 'J': (*ptr)++; return long_type_node; case 'Z': (*ptr)++; return boolean_type_node; case 'V': (*ptr)++; return void_type_node; case '[': for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); ) (*ptr)++; type = parse_signature_type (ptr, limit); type = build_java_array_type (type, -1); break; case 'L': { const unsigned char *start = ++(*ptr); register const unsigned char *str = start; for ( ; ; str++) { if (str >= limit) fatal ("bad signature string"); if (*str == ';') break; } *ptr = str+1; type = lookup_class (unmangle_classname (start, str - start)); break; } default: fatal ("unrecognized signature string"); } return promote_type (type);}/* Parse a Java "mangled" signature string, starting at SIG_STRING, and SIG_LENGTH bytes long. Return a gcc type node. */treeparse_signature_string (sig_string, sig_length) const unsigned char *sig_string; int sig_length;{ tree result_type; const unsigned char *str = sig_string; const unsigned char *limit = str + sig_length; push_obstacks (&permanent_obstack, &permanent_obstack); if (str < limit && str[0] == '(') { tree argtype_list = NULL_TREE; str++; while (str < limit && str[0] != ')') { tree argtype = parse_signature_type (&str, limit); argtype_list = tree_cons (NULL_TREE, argtype, argtype_list); } if (str++, str >= limit) fatal ("bad signature string"); result_type = parse_signature_type (&str, limit); argtype_list = chainon (nreverse (argtype_list), end_params_node); result_type = build_function_type (result_type, argtype_list); } else result_type = parse_signature_type (&str, limit); if (str != limit) error ("junk at end of signature string"); pop_obstacks (); return result_type;}/* Convert a signature to its type. * Uses IDENTIFIER_SIGNATURE_TYPE as a cache (except for primitive types). */treeget_type_from_signature (tree signature){ unsigned char *sig = (unsigned char *) IDENTIFIER_POINTER (signature); int len = IDENTIFIER_LENGTH (signature); tree type; /* Primitive types aren't cached. */ if (len <= 1) return parse_signature_string (sig, len); type = IDENTIFIER_SIGNATURE_TYPE (signature); if (type == NULL_TREE) { type = parse_signature_string (sig, len); IDENTIFIER_SIGNATURE_TYPE (signature) = type; } return type;}/* Return the signature string for the arguments of method type TYPE. */treebuild_java_argument_signature (type) tree type;{ extern struct obstack temporary_obstack; tree sig = TYPE_ARGUMENT_SIGNATURE (type); if (sig == NULL_TREE) { tree args = TYPE_ARG_TYPES (type); if (TREE_CODE (type) == METHOD_TYPE) args = TREE_CHAIN (args); /* Skip "this" argument. */ for (; args != end_params_node; args = TREE_CHAIN (args)) { tree t = build_java_signature (TREE_VALUE (args)); obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); } obstack_1grow (&temporary_obstack, '\0'); sig = get_identifier (obstack_base (&temporary_obstack)); TYPE_ARGUMENT_SIGNATURE (type) = sig; obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); } return sig;}/* Return the signature of the given TYPE. */treebuild_java_signature (type) tree type;{ tree sig, t; push_obstacks (&permanent_obstack, &permanent_obstack); while (TREE_CODE (type) == POINTER_TYPE) type = TREE_TYPE (type); if (TYPE_LANG_SPECIFIC (type) == NULL) { TYPE_LANG_SPECIFIC (type) = (struct lang_type *) perm_calloc (1, sizeof (struct lang_type)); } sig = TYPE_LANG_SPECIFIC (type)->signature; if (sig == NULL_TREE) { char sg[2]; switch (TREE_CODE (type)) { case BOOLEAN_TYPE: sg[0] = 'Z'; goto native; case CHAR_TYPE: sg[0] = 'C'; goto native; case VOID_TYPE: sg[0] = 'V'; goto native; case INTEGER_TYPE: switch (TYPE_PRECISION (type)) { case 8: sg[0] = 'B'; goto native; case 16: sg[0] = 'S'; goto native; case 32: sg[0] = 'I'; goto native; case 64: sg[0] = 'J'; goto native; default: goto bad_type; } case REAL_TYPE: switch (TYPE_PRECISION (type)) { case 32: sg[0] = 'F'; goto native; case 64: sg[0] = 'D'; goto native; default: goto bad_type; } native: sg[1] = 0; sig = get_identifier (sg); break; case RECORD_TYPE: if (TYPE_ARRAY_P (type)) { t = build_java_signature (TYPE_ARRAY_ELEMENT (type)); sig = ident_subst (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t), "[", 0, 0, ""); } else { t = DECL_NAME (TYPE_NAME (type)); sig = ident_subst (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t), "L", '.', '/', ";"); } break; case METHOD_TYPE: case FUNCTION_TYPE: { extern struct obstack temporary_obstack; sig = build_java_argument_signature (type); obstack_1grow (&temporary_obstack, '('); obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (sig), IDENTIFIER_LENGTH (sig)); obstack_1grow (&temporary_obstack, ')'); t = build_java_signature (TREE_TYPE (type)); obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); sig = get_identifier (obstack_base (&temporary_obstack)); obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); } break; bad_type: default: fatal ("internal error - build_java_signature passed invalid type"); } TYPE_LANG_SPECIFIC (type)->signature = sig; } pop_obstacks (); return sig;}/* Save signature string SIG (an IDENTIFIER_NODE) in TYPE for future use. */voidset_java_signature (type, sig) tree type; tree sig;{ tree old_sig; while (TREE_CODE (type) == POINTER_TYPE) type = TREE_TYPE (type); if (TYPE_LANG_SPECIFIC (type) == NULL) { TYPE_LANG_SPECIFIC (type) = (struct lang_type *) perm_calloc (1, sizeof (struct lang_type)); } old_sig = TYPE_LANG_SPECIFIC (type)->signature; if (old_sig != NULL_TREE && old_sig != sig) fatal ("internal error - set_java_signature"); TYPE_LANG_SPECIFIC (type)->signature = sig;#if 0 /* careful about METHOD_TYPE */ if (IDENTIFIER_SIGNATURE_TYPE (sig) == NULL_TREE && TREE_PERMANENT (type)) IDENTIFIER_SIGNATURE_TYPE (sig) = type;#endif}/* Search in class CLAS (and its superclasses) for a method matching METHOD_NAME and argument signature METHOD_SIGNATURE. Return a FUNCTION_DECL on success, or NULL_TREE if none found. (Contrast lookup_java_method, which takes into account return type.) */treelookup_argument_method (clas, method_name, method_signature) tree clas, method_name, method_signature;{ tree method; while (clas != NULL_TREE) { for (method = TYPE_METHODS (clas); method != NULL_TREE; method = TREE_CHAIN (method)) { tree method_sig = build_java_argument_signature (TREE_TYPE (method)); tree name = DECL_NAME (method); if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? EXPR_WFL_NODE (name) : name) == method_name && method_sig == method_signature) return method; } clas = CLASSTYPE_SUPER (clas); } return NULL_TREE;}/* Search in class CLAS (and its superclasses) for a method matching METHOD_NAME and signature METHOD_SIGNATURE. Return a FUNCTION_DECL on success, or NULL_TREE if none found. (Contrast lookup_argument_method, which ignores return type.) */treelookup_java_method (clas, method_name, method_signature) tree clas, method_name, method_signature;{ tree method; while (clas != NULL_TREE) { for (method = TYPE_METHODS (clas); method != NULL_TREE; method = TREE_CHAIN (method)) { tree method_sig = build_java_signature (TREE_TYPE (method)); if (DECL_NAME (method) == method_name && method_sig == method_signature) return method; } clas = CLASSTYPE_SUPER (clas); } return NULL_TREE;}/* Search in class CLAS for a constructor matching METHOD_SIGNATURE. Return a FUNCTION_DECL on success, or NULL_TREE if none found. */treelookup_java_constructor (clas, method_signature) tree clas, method_signature;{ tree method = TYPE_METHODS (clas); for ( ; method != NULL_TREE; method = TREE_CHAIN (method)) { tree method_sig = build_java_signature (TREE_TYPE (method)); if (DECL_CONSTRUCTOR_P (method) && method_sig == method_signature) return method; } return NULL_TREE;}/* Return a type which is the Binary Numeric Promotion of the pair T1, T2 and convert EXP1 and/or EXP2. See 5.6.2 Binary Numeric Promotion. It assumes that both T1 and T2 are elligible to BNP. */treebinary_numeric_promotion (t1, t2, exp1, exp2) tree t1; tree t2; tree *exp1; tree *exp2;{ if (t1 == double_type_node || t2 == double_type_node) { if (t1 != double_type_node) *exp1 = convert (double_type_node, *exp1); if (t2 != double_type_node) *exp2 = convert (double_type_node, *exp2); return double_type_node; } if (t1 == float_type_node || t2 == float_type_node) { if (t1 != float_type_node) *exp1 = convert (float_type_node, *exp1); if (t2 != float_type_node) *exp2 = convert (float_type_node, *exp2); return float_type_node; } if (t1 == long_type_node || t2 == long_type_node) { if (t1 != long_type_node) *exp1 = convert (long_type_node, *exp1); if (t2 != long_type_node) *exp2 = convert (long_type_node, *exp2); return long_type_node; } if (t1 != int_type_node) *exp1 = convert (int_type_node, *exp1); if (t2 != int_type_node) *exp2 = convert (int_type_node, *exp2); return int_type_node;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -