📄 gcc-func.c
字号:
case NEGATE_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE)) errstring = "wrong type argument to unary minus"; else if (!noconvert) arg = default_conversion (arg); break; case BIT_NOT_EXPR: if (typecode != INTEGER_TYPE) errstring = "wrong type argument to bit-complement"; else if (!noconvert) arg = default_conversion (arg); break; case ABS_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE)) errstring = "wrong type argument to abs"; else if (!noconvert) arg = default_conversion (arg); break; case TRUTH_NOT_EXPR: if (typecode != INTEGER_TYPE && typecode != REAL_TYPE && typecode != POINTER_TYPE /* These will convert to a pointer. */ && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE) { errstring = "wrong type argument to unary exclamation mark"; break; } arg = truthvalue_conversion (arg); return invert_truthvalue (arg); case NOP_EXPR: break; case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: case PREDECREMENT_EXPR: case POSTDECREMENT_EXPR: /* Handle complex lvalues (when permitted) by reduction to simpler cases. */ val = unary_complex_lvalue (code, arg); if (val != 0) return val; /* Report invalid types. */ if (typecode != POINTER_TYPE && typecode != INTEGER_TYPE && typecode != REAL_TYPE) { if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) errstring ="wrong type argument to increment"; else errstring ="wrong type argument to decrement"; break; } { register tree inc; tree result_type = TREE_TYPE (arg); arg = get_unwidened (arg, 0); argtype = TREE_TYPE (arg); /* Compute the increment. */ if (typecode == POINTER_TYPE) { if (pedantic && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)) pedwarn ("wrong type argument to %s", ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) ? "increment" : "decrement")); inc = c_sizeof_nowarn (TREE_TYPE (result_type)); } else inc = integer_one_node; inc = convert (argtype, inc); /* Handle incrementing a cast-expression. */ while (1) switch (TREE_CODE (arg)) { case NOP_EXPR: case CONVERT_EXPR: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: /* If the real type has the same machine representation as the type it is cast to, we can make better output by adding directly to the inside of the cast. */ if ((TREE_CODE (TREE_TYPE (arg)) == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0)))) && (TYPE_MODE (TREE_TYPE (arg)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0))))) arg = TREE_OPERAND (arg, 0); else { tree incremented, modify, value; pedantic_lvalue_warning (CONVERT_EXPR); arg = stabilize_reference (arg); if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) value = arg; else value = save_expr (arg); incremented = build (((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) ? PLUS_EXPR : MINUS_EXPR), argtype, value, inc); TREE_SIDE_EFFECTS (incremented) = 1; modify = build_modify_expr (arg, NOP_EXPR, incremented); value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); TREE_USED (value) = 1; return value; } break; default: goto give_up; } give_up: /* Complain about anything else that is not a true lvalue. */ if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) ? "increment" : "decrement"))) return error_mark_node; /* Report a read-only lvalue. */ if (TYPE_READONLY (TREE_TYPE (arg))) readonly_warning (arg, ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) ? "increment" : "decrement")); val = build (code, TREE_TYPE (arg), arg, inc); TREE_SIDE_EFFECTS (val) = 1; val = convert (result_type, val); if (TREE_CODE (val) != code) TREE_NO_UNUSED_WARNING (val) = 1; return val; } case ADDR_EXPR: /* Note that this operation never does default_conversion regardless of NOCONVERT. */ /* Let &* cancel out to simplify resulting code. */ if (TREE_CODE (arg) == INDIRECT_REF) { /* Don't let this be an lvalue. */ if (lvalue_p (TREE_OPERAND (arg, 0))) return non_lvalue (TREE_OPERAND (arg, 0)); return TREE_OPERAND (arg, 0); } /* For &x[y], return x+y */ if (TREE_CODE (arg) == ARRAY_REF) { if (mark_addressable (TREE_OPERAND (arg, 0)) == 0) return error_mark_node; return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), 1); } /* Handle complex lvalues (when permitted) by reduction to simpler cases. */ val = unary_complex_lvalue (code, arg); if (val != 0) return val;#if 0 /* Turned off because inconsistent; float f; *&(int)f = 3.4 stores in int format whereas (int)f = 3.4 stores in float format. */ /* Address of a cast is just a cast of the address of the operand of the cast. */ switch (TREE_CODE (arg)) { case NOP_EXPR: case CONVERT_EXPR: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: if (pedantic) pedwarn ("ANSI C forbids the address of a cast expression"); return convert (build_pointer_type (TREE_TYPE (arg)), build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0)); }#endif /* Allow the address of a constructor if all the elements are constant. */ if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg)) ; /* Anything not already handled and not a true memory reference is an error. */ else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'")) return error_mark_node; /* Ordinary case; arg is a COMPONENT_REF or a decl. */ argtype = TREE_TYPE (arg); /* If the lvalue is const or volatile, merge that into the type that the address will point to. */ if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd' || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r') { if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)) argtype = c_build_type_variant (argtype, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg)); } argtype = build_pointer_type (argtype); if (mark_addressable (arg) == 0) return error_mark_node; { tree addr; if (TREE_CODE (arg) == COMPONENT_REF) { tree field = TREE_OPERAND (arg, 1); addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0); if (DECL_BIT_FIELD (field)) { error ("attempt to take address of bit-field structure member `%s'", IDENTIFIER_POINTER (DECL_NAME (field))); return error_mark_node; } addr = convert (argtype, addr); if (! integer_zerop (DECL_FIELD_BITPOS (field))) { tree offset = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT)); int flag = TREE_CONSTANT (addr); addr = fold (build (PLUS_EXPR, argtype, addr, convert (argtype, offset))); TREE_CONSTANT (addr) = flag; } } else addr = build1 (code, argtype, arg); /* Address of a static or external variable or function counts as a constant */ TREE_CONSTANT (addr) = staticp (arg); return addr; } } if (!errstring) { if (argtype == 0) argtype = TREE_TYPE (arg); return fold (build1 (code, argtype, arg)); } error (errstring); return error_mark_node;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -