int warn_format_security;
-
+/* Zero means that faster, ...NonNil variants of objc_msgSend...
+ calls will be used in ObjC; passing nil receivers to such calls
+ will most likely result in crashes. */
+int flag_nil_receivers = 1;
+
+/* Nonzero means that we will allow new ObjC exception syntax (@throw,
+ @try, etc.) in source code. */
+int flag_objc_exceptions = 0;
+
+/* Nonzero means that code generation will be altered to support
+ "zero-link" execution. This currently affects ObjC only, but may
+ affect other languages in the future. */
+int flag_zero_link = 0;
+
+/* Nonzero means emit an '__OBJC, __image_info' for the current translation
+ unit. It will inform the ObjC runtime that class definition(s) herein
+ contained are to replace one(s) previously loaded. */
+int flag_replace_objc_classes = 0;
+
/* C/ObjC language option variables. */
input_line = saved_lineno;
}
if (!ix && !current_function_decl)
- pedwarn ("%H'%D' is not defined outside of function scope",
- &DECL_SOURCE_LOCATION (decl), decl);
+ pedwarn ("%J'%D' is not defined outside of function scope", decl, decl);
return decl;
}
return 0;
}
+/* Used for communication between c_common_type_for_mode and
+ c_register_builtin_type. */
+static GTY(()) tree registered_builtin_types;
+
/* Return a data type that has machine mode MODE.
If the mode is an integer,
then UNSIGNEDP selects between signed and unsigned types. */
tree
c_common_type_for_mode (enum machine_mode mode, int unsignedp)
{
+ tree t;
+
if (mode == TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
if (mode == TYPE_MODE (long_double_type_node))
return long_double_type_node;
+ if (mode == TYPE_MODE (void_type_node))
+ return void_type_node;
+
if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
break;
}
+ for (t = registered_builtin_types; t; t = TREE_CHAIN (t))
+ if (TYPE_MODE (TREE_VALUE (t)) == mode)
+ return TREE_VALUE (t);
+
return 0;
}
|| TREE_UNSIGNED (type) == unsignedp)
return type;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
+ /* Must check the mode of the types, not the precision. Enumeral types
+ in C++ have precision set to match their range, but may use a wider
+ mode to match an ABI. If we change modes, we may wind up with bad
+ conversions. */
+
+ if (TYPE_MODE (type) == TYPE_MODE (signed_char_type_node))
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (short_integer_type_node))
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (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))
+ if (TYPE_MODE (type) == TYPE_MODE (long_long_integer_type_node))
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
- if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (widest_integer_literal_type_node))
return (unsignedp ? widest_unsigned_literal_type_node
: widest_integer_literal_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intTI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intDI_type_node))
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intSI_type_node))
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intHI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intHI_type_node))
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intQI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intQI_type_node))
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
return type;
if (!TYPE_NAME (type))
TYPE_NAME (type) = decl;
pushdecl (decl);
+
+ registered_builtin_types = tree_cons (0, type, registered_builtin_types);
}
\f
if (TREE_CODE (expr) == ERROR_MARK)
return expr;
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ expr = build_unary_op (ADDR_EXPR, expr, 0);
+
#if 0 /* This appears to be wrong for C++. */
/* These really should return error_mark_node after 2.4 is stable.
But not all callers handle ERROR_MARK properly. */
return real_zerop (expr) ? truthvalue_false_node : truthvalue_true_node;
case ADDR_EXPR:
- /* If we are taking the address of an external decl, it might be zero
- if it is weak, so we cannot optimize. */
- if (DECL_P (TREE_OPERAND (expr, 0))
- && DECL_EXTERNAL (TREE_OPERAND (expr, 0)))
- break;
+ {
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL
+ && ! DECL_WEAK (TREE_OPERAND (expr, 0)))
+ {
+ /* Common Ada/Pascal programmer's mistake. We always warn
+ about this since it is so bad. */
+ warning ("the address of `%D', will always evaluate as `true'",
+ TREE_OPERAND (expr, 0));
+ return truthvalue_true_node;
+ }
- if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
- return build (COMPOUND_EXPR, truthvalue_type_node,
- TREE_OPERAND (expr, 0), truthvalue_true_node);
- else
- return truthvalue_true_node;
+ /* If we are taking the address of an external decl, it might be
+ zero if it is weak, so we cannot optimize. */
+ if (DECL_P (TREE_OPERAND (expr, 0))
+ && DECL_EXTERNAL (TREE_OPERAND (expr, 0)))
+ break;
+
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
+ return build (COMPOUND_EXPR, truthvalue_type_node,
+ TREE_OPERAND (expr, 0), truthvalue_true_node);
+ else
+ return truthvalue_true_node;
+ }
case COMPLEX_EXPR:
return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
tree
c_build_qualified_type (tree type, int type_quals)
{
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ return build_array_type (c_build_qualified_type (TREE_TYPE (type),
+ type_quals),
+ TYPE_DOMAIN (type));
+
/* A restrict-qualified pointer type must be a pointer to object or
incomplete type. Note that the use of POINTER_TYPE_P also allows
- REFERENCE_TYPEs, which is appropriate for C++. Unfortunately,
- the C++ front-end also use POINTER_TYPE for pointer-to-member
- values, so even though it should be illegal to use `restrict'
- with such an entity we don't flag that here. Thus, special case
- code for that case is required in the C++ front-end. */
+ REFERENCE_TYPEs, which is appropriate for C++. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& (!POINTER_TYPE_P (type)
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
type_quals &= ~TYPE_QUAL_RESTRICT;
}
- if (TREE_CODE (type) == ARRAY_TYPE)
- return build_array_type (c_build_qualified_type (TREE_TYPE (type),
- type_quals),
- TYPE_DOMAIN (type));
return build_qualified_type (type, type_quals);
}
void
c_apply_type_quals_to_decl (int type_quals, tree decl)
{
- if ((type_quals & TYPE_QUAL_CONST)
- || (TREE_TYPE (decl)
- && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE))
+ tree type = TREE_TYPE (decl);
+
+ if (((type_quals & TYPE_QUAL_CONST)
+ || (type && TREE_CODE (type) == REFERENCE_TYPE))
+ /* An object declared 'const' is only readonly after it is
+ initialized. We don't have any way of expressing this currently,
+ so we need to be conservative and unset TREE_READONLY for types
+ with constructors. Otherwise aliasing code will ignore stores in
+ an inline constructor. */
+ && !(type && TYPE_NEEDS_CONSTRUCTING (type)))
TREE_READONLY (decl) = 1;
if (type_quals & TYPE_QUAL_VOLATILE)
{
}
if (type_quals & TYPE_QUAL_RESTRICT)
{
- if (!TREE_TYPE (decl)
- || !POINTER_TYPE_P (TREE_TYPE (decl))
- || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl))))
+ while (type && TREE_CODE (type) == ARRAY_TYPE)
+ /* Allow 'restrict' on arrays of pointers.
+ FIXME currently we just ignore it. */
+ type = TREE_TYPE (type);
+ if (!type
+ || !POINTER_TYPE_P (type)
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))
error ("invalid use of `restrict'");
- else if (flag_strict_aliasing)
+ else if (flag_strict_aliasing && type == TREE_TYPE (decl))
/* Indicate we need to make a unique alias set for this pointer.
We can't do it here because it might be pointing to an
incomplete type. */
case BUILT_IN_CREALL:
if (coerced_params == 0)
return integer_zero_node;
- return build_unary_op (REALPART_EXPR, TREE_VALUE (coerced_params), 0);
+ return non_lvalue (build_unary_op (REALPART_EXPR,
+ TREE_VALUE (coerced_params), 0));
case BUILT_IN_CIMAG:
case BUILT_IN_CIMAGF:
case BUILT_IN_CIMAGL:
if (coerced_params == 0)
return integer_zero_node;
- return build_unary_op (IMAGPART_EXPR, TREE_VALUE (coerced_params), 0);
+ return non_lvalue (build_unary_op (IMAGPART_EXPR,
+ TREE_VALUE (coerced_params), 0));
case BUILT_IN_ISGREATER:
return expand_unordered_cmp (function, params, UNLE_EXPR, LE_EXPR);
if (high_value)
{
error ("duplicate (or overlapping) case value");
- error ("%Hthis is the first entry overlapping that value",
- &DECL_SOURCE_LOCATION (duplicate));
+ error ("%Jthis is the first entry overlapping that value", duplicate);
}
else if (low_value)
{
error ("duplicate case value") ;
- error ("%Hpreviously used here", &DECL_SOURCE_LOCATION (duplicate));
+ error ("%Jpreviously used here", duplicate);
}
else
{
error ("multiple default labels in one switch");
- error ("%Hthis is the first default label",
- &DECL_SOURCE_LOCATION (duplicate));
+ error ("%Jthis is the first default label", duplicate);
}
if (!cases->root)
add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
};
warning (msgs[msgcode], name);
- warning ("%Hshadowed declaration is here", &DECL_SOURCE_LOCATION (decl));
+ warning ("%Jshadowed declaration is here", decl);
}
/* Attribute handlers common to C front ends. */
&& current_function_decl != NULL_TREE
&& ! TREE_STATIC (decl))
{
- error ("%Hsection attribute cannot be specified for "
- "local variables", &DECL_SOURCE_LOCATION (decl));
+ error ("%Jsection attribute cannot be specified for "
+ "local variables", decl);
*no_add_attrs = true;
}
&& strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
{
- error ("%Hsection of '%D' conflicts with previous declaration",
- &DECL_SOURCE_LOCATION (*node), *node);
+ error ("%Jsection of '%D' conflicts with previous declaration",
+ *node, *node);
*no_add_attrs = true;
}
else
}
else
{
- error ("%Hsection attribute not allowed for '%D'",
- &DECL_SOURCE_LOCATION (*node), *node);
+ error ("%Jsection attribute not allowed for '%D'", *node, *node);
*no_add_attrs = true;
}
}
else
{
- error ("%Hsection attributes are not supported for this target",
- &DECL_SOURCE_LOCATION (*node));
+ error ("%Jsection attributes are not supported for this target", *node);
*no_add_attrs = true;
}
else if (TREE_CODE (decl) != VAR_DECL
&& TREE_CODE (decl) != FIELD_DECL)
{
- error ("%Halignment may not be specified for '%D'",
- &DECL_SOURCE_LOCATION (decl), decl);
+ error ("%Jalignment may not be specified for '%D'", decl, decl);
*no_add_attrs = true;
}
else
if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
|| (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
{
- error ("%H'%D' defined both normally and as an alias",
- &DECL_SOURCE_LOCATION (decl), decl);
+ error ("%J'%D' defined both normally and as an alias", decl, decl);
*no_add_attrs = true;
}
else if (decl_function_context (decl) == 0)
bool *no_add_attrs)
{
tree decl = *node;
+ tree id = TREE_VALUE (args);
+
+ *no_add_attrs = true;
if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
- *no_add_attrs = true;
+ return NULL_TREE;
}
- else
- {
- tree id;
- id = TREE_VALUE (args);
- if (TREE_CODE (id) != STRING_CST)
- {
- error ("visibility arg not a string");
- *no_add_attrs = true;
- return NULL_TREE;
- }
- if (strcmp (TREE_STRING_POINTER (id), "hidden")
- && strcmp (TREE_STRING_POINTER (id), "protected")
- && strcmp (TREE_STRING_POINTER (id), "internal")
- && strcmp (TREE_STRING_POINTER (id), "default"))
- {
- error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("visibility arg not a string");
+ return NULL_TREE;
}
+ if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
+ else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED;
+ else
+ error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+
return NULL_TREE;
}
if (TREE_CODE (decl) != FUNCTION_DECL)
{
- error ("%H'%E' attribute applies only to functions",
- &DECL_SOURCE_LOCATION (decl), name);
+ error ("%J'%E' attribute applies only to functions", decl, name);
*no_add_attrs = true;
}
else if (DECL_INITIAL (decl))
{
- error ("%Hcan't set '%E' attribute after definition",
- &DECL_SOURCE_LOCATION (decl), name);
+ error ("%Jcan't set '%E' attribute after definition", decl, name);
*no_add_attrs = true;
}
else
if (TREE_CODE (decl) != FUNCTION_DECL)
{
- error ("%H'%E' attribute applies only to functions",
- &DECL_SOURCE_LOCATION (decl), name);
+ error ("%J'%E' attribute applies only to functions", decl, name);
*no_add_attrs = true;
}
else if (DECL_INITIAL (decl))
{
- error ("%Hcan't set '%E' attribute after definition",
- &DECL_SOURCE_LOCATION (decl), name);
+ error ("%Jcan't set '%E' attribute after definition", decl, name);
*no_add_attrs = true;
}
else
return NULL;
switch (TREE_CODE (x))
{
- /* Reconginze assignments of large structures and constructors of
+ /* Recognize assignments of large structures and constructors of
big arrays. */
case MODIFY_EXPR:
case CONSTRUCTOR:
return false;
}
+/* Issue the error given by MSGID, indicating that it occurred before
+ TOKEN, which had the associated VALUE. */
+
+void
+c_parse_error (const char *msgid, enum cpp_ttype token, tree value)
+{
+ const char *string = _(msgid);
+
+ if (token == CPP_EOF)
+ error ("%s at end of input", string);
+ else if (token == CPP_CHAR || token == CPP_WCHAR)
+ {
+ unsigned int val = TREE_INT_CST_LOW (value);
+ const char *const ell = (token == CPP_CHAR) ? "" : "L";
+ if (val <= UCHAR_MAX && ISGRAPH (val))
+ error ("%s before %s'%c'", string, ell, val);
+ else
+ error ("%s before %s'\\x%x'", string, ell, val);
+ }
+ else if (token == CPP_STRING
+ || token == CPP_WSTRING)
+ error ("%s before string constant", string);
+ else if (token == CPP_NUMBER)
+ error ("%s before numeric constant", string);
+ else if (token == CPP_NAME)
+ error ("%s before \"%s\"", string, IDENTIFIER_POINTER (value));
+ else if (token < N_TTYPES)
+ error ("%s before '%s' token", string, cpp_type2name (token));
+ else
+ error ("%s", string);
+}
+
#include "gt-c-common.h"