📄 c-typeck.c
字号:
if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1))) { TREE_VALUE (n) = TREE_VALUE (p1); if (pedantic) pedwarn ("function types not truly compatible in ANSI C"); goto parm_done; } } TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2)); parm_done: ; } t1 = build_function_type (valtype, newargs); /* ... falls through ... */ } default: return build_type_attribute_variant (t1, attributes); }}/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment or various other operations. Return 2 if they are compatible but a warning may be needed if you use them together. */intcomptypes (type1, type2) tree type1, type2;{ register tree t1 = type1; register tree t2 = type2; int attrval, val; /* Suppress errors caused by previously reported errors. */ if (t1 == t2 || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK) return 1; /* Treat an enum type as the integer type of the same width and signedness. */ if (TREE_CODE (t1) == ENUMERAL_TYPE) t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1)); if (TREE_CODE (t2) == ENUMERAL_TYPE) t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2)); if (t1 == t2) return 1; /* Different classes of types can't be compatible. */ if (TREE_CODE (t1) != TREE_CODE (t2)) return 0; /* Qualifiers must match. */ if (TYPE_READONLY (t1) != TYPE_READONLY (t2)) return 0; if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) return 0; /* Allow for two different type nodes which have essentially the same definition. Note that we already checked for equality of the type type qualifiers (just above). */ if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) return 1;#ifndef COMP_TYPE_ATTRIBUTES#define COMP_TYPE_ATTRIBUTES(t1,t2) 1#endif /* 1 if no need for warning yet, 2 if warning cause has been seen. */ if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2))) return 0; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ val = 0; switch (TREE_CODE (t1)) { case POINTER_TYPE: val = (TREE_TYPE (t1) == TREE_TYPE (t2) ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); break; case FUNCTION_TYPE: val = function_types_compatible_p (t1, t2); break; case ARRAY_TYPE: { tree d1 = TYPE_DOMAIN (t1); tree d2 = TYPE_DOMAIN (t2); val = 1; /* Target types must match incl. qualifiers. */ if (TREE_TYPE (t1) != TREE_TYPE (t2) && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))) return 0; /* Sizes must match unless one is missing or variable. */ if (d1 == 0 || d2 == 0 || d1 == d2 || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST) break; if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1)) == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2))) && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1)) == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2))) && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1)) == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2))) && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1)) == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2))))) val = 0; break; } case RECORD_TYPE: if (maybe_objc_comptypes (t1, t2, 0) == 1) val = 1; break; } return attrval == 2 && val == 1 ? 2 : val;}/* Return 1 if TTL and TTR are pointers to types that are equivalent, ignoring their qualifiers. */static intcomp_target_types (ttl, ttr) tree ttl, ttr;{ int val; /* Give maybe_objc_comptypes a crack at letting these types through. */ if (val = maybe_objc_comptypes (ttl, ttr, 1) >= 0) return val; val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)), TYPE_MAIN_VARIANT (TREE_TYPE (ttr))); if (val == 2 && pedantic) pedwarn ("types are not quite compatible"); return val;}/* Subroutines of `comptypes'. *//* Return 1 if two function types F1 and F2 are compatible. If either type specifies no argument types, the other must specify a fixed number of self-promoting arg types. Otherwise, if one type specifies only the number of arguments, the other must specify that number of self-promoting arg types. Otherwise, the argument types must match. */static intfunction_types_compatible_p (f1, f2) tree f1, f2;{ tree args1, args2; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ int val = 1; int val1; if (!(TREE_TYPE (f1) == TREE_TYPE (f2) || (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2))))) return 0; args1 = TYPE_ARG_TYPES (f1); args2 = TYPE_ARG_TYPES (f2); /* An unspecified parmlist matches any specified parmlist whose argument types don't need default promotions. */ if (args1 == 0) { if (!self_promoting_args_p (args2)) return 0; /* If one of these types comes from a non-prototype fn definition, compare that with the other type's arglist. If they don't match, ask for a warning (but no error). */ if (TYPE_ACTUAL_ARG_TYPES (f1) && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1))) val = 2; return val; } if (args2 == 0) { if (!self_promoting_args_p (args1)) return 0; if (TYPE_ACTUAL_ARG_TYPES (f2) && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2))) val = 2; return val; } /* Both types have argument lists: compare them and propagate results. */ val1 = type_lists_compatible_p (args1, args2); return val1 != 1 ? val1 : val;}/* Check two lists of types for compatibility, returning 0 for incompatible, 1 for compatible, or 2 for compatible with warning. */static inttype_lists_compatible_p (args1, args2) tree args1, args2;{ /* 1 if no need for warning yet, 2 if warning cause has been seen. */ int val = 1; int newval = 0; while (1) { if (args1 == 0 && args2 == 0) return val; /* If one list is shorter than the other, they fail to match. */ if (args1 == 0 || args2 == 0) return 0; /* A null pointer instead of a type means there is supposed to be an argument but nothing is specified about what type it has. So match anything that self-promotes. */ if (TREE_VALUE (args1) == 0) { if (! self_promoting_type_p (TREE_VALUE (args2))) return 0; } else if (TREE_VALUE (args2) == 0) { if (! self_promoting_type_p (TREE_VALUE (args1))) return 0; } else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2)))) { /* Allow wait (union {union wait *u; int *i} *) and wait (union wait *) to be compatible. */ if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE && (TYPE_NAME (TREE_VALUE (args1)) == 0 || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1))) && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)), TYPE_SIZE (TREE_VALUE (args2)))) { tree memb; for (memb = TYPE_FIELDS (TREE_VALUE (args1)); memb; memb = TREE_CHAIN (memb)) if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2))) break; if (memb == 0) return 0; } else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE && (TYPE_NAME (TREE_VALUE (args2)) == 0 || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2))) && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)), TYPE_SIZE (TREE_VALUE (args1)))) { tree memb; for (memb = TYPE_FIELDS (TREE_VALUE (args2)); memb; memb = TREE_CHAIN (memb)) if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1))) break; if (memb == 0) return 0; } else return 0; } /* comptypes said ok, but record if it said to warn. */ if (newval > val) val = newval; args1 = TREE_CHAIN (args1); args2 = TREE_CHAIN (args2); }}/* Return 1 if PARMS specifies a fixed number of parameters and none of their types is affected by default promotions. */intself_promoting_args_p (parms) tree parms;{ register tree t; for (t = parms; t; t = TREE_CHAIN (t)) { register tree type = TREE_VALUE (t); if (TREE_CHAIN (t) == 0 && type != void_type_node) return 0; if (type == 0) return 0; if (TYPE_MAIN_VARIANT (type) == float_type_node) return 0; if (C_PROMOTING_INTEGER_TYPE_P (type)) return 0; } return 1;}/* Return 1 if TYPE is not affected by default promotions. */static intself_promoting_type_p (type) tree type;{ if (TYPE_MAIN_VARIANT (type) == float_type_node) return 0; if (C_PROMOTING_INTEGER_TYPE_P (type)) return 0; return 1;}/* Return an unsigned type the same as TYPE in other respects. */treeunsigned_type (type) tree type;{ tree type1 = TYPE_MAIN_VARIANT (type); if (type1 == signed_char_type_node || type1 == char_type_node) return unsigned_char_type_node; if (type1 == integer_type_node) return unsigned_type_node; if (type1 == short_integer_type_node) return short_unsigned_type_node; if (type1 == long_integer_type_node) return long_unsigned_type_node; if (type1 == long_long_integer_type_node) return long_long_unsigned_type_node; if (type1 == intDI_type_node) return unsigned_intDI_type_node; if (type1 == intSI_type_node) return unsigned_intSI_type_node; if (type1 == intHI_type_node) return unsigned_intHI_type_node; if (type1 == intQI_type_node) return unsigned_intQI_type_node; return type;}/* Return a signed type the same as TYPE in other respects. */treesigned_type (type) tree type;{ tree type1 = TYPE_MAIN_VARIANT (type); if (type1 == unsigned_char_type_node || type1 == char_type_node) return signed_char_type_node; if (type1 == unsigned_type_node) return integer_type_node; if (type1 == short_unsigned_type_node) return short_integer_type_node; if (type1 == long_unsigned_type_node) return long_integer_type_node; if (type1 == long_long_unsigned_type_node) return long_long_integer_type_node; if (type1 == unsigned_intDI_type_node) return intDI_type_node; if (type1 == unsigned_intSI_type_node) return intSI_type_node; if (type1 == unsigned_intHI_type_node) return intHI_type_node; if (type1 == unsigned_intQI_type_node) return intQI_type_node; return type;}/* Return a type the same as TYPE except unsigned or signed according to UNSIGNEDP. */treesigned_or_unsigned_type (unsignedp, type) int unsignedp; tree type;{ if (! INTEGRAL_TYPE_P (type)) return type; if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) return unsignedp ? unsigned_char_type_node : signed_char_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) return unsignedp ? short_unsigned_type_node : short_integer_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) return unsignedp ? long_unsigned_type_node : long_integer_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); return type;}/* Compute the value of the `sizeof' operator. */treec_sizeof (type) tree type;{ enum tree_code code = TREE_CODE (type); tree t;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -