/* Subroutines shared by all languages that are variants of C.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
int flag_signed_bitfields = 1;
-int explicit_flag_signed_bitfields;
/* Nonzero means warn about deprecated conversion from string constant to
`char *'. */
tree (*make_fname_decl) (tree, int);
-/* If non-NULL, the address of a language-specific function that
- returns 1 for language-specific statement codes. */
-int (*lang_statement_code_p) (enum tree_code);
-
-/* If non-NULL, the address of a language-specific function that takes
- any action required right before expand_function_end is called. */
-void (*lang_expand_function_end) (void);
-
/* Nonzero means the expression being parsed will never be evaluated.
This is a count, since unevaluated expressions can nest. */
int skip_evaluation;
static tree handle_no_instrument_function_attribute (tree *, tree,
tree, int, bool *);
static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
+static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
bool *);
static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
handle_no_instrument_function_attribute },
{ "malloc", 0, 0, true, false, false,
handle_malloc_attribute },
+ { "returns_twice", 0, 0, true, false, false,
+ handle_returns_twice_attribute },
{ "no_stack_limit", 0, 0, true, false, false,
handle_no_limit_stack_attribute },
{ "pure", 0, 0, true, false, false,
i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1));
a_type = build_array_type (e_type, i_type);
if (flag_const_strings)
- {
- /* bleah, c_build_qualified_type should set TYPE_MAIN_VARIANT. */
- tree qa_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
- TYPE_MAIN_VARIANT (qa_type) = a_type;
- a_type = qa_type;
- }
+ a_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
TREE_TYPE (value) = a_type;
TREE_CONSTANT (value) = 1;
return void_type_node;
if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
- return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
+ return (unsignedp
+ ? make_unsigned_type (GET_MODE_PRECISION (mode))
+ : make_signed_type (GET_MODE_PRECISION (mode)));
if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
- return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
+ return (unsignedp
+ ? make_unsigned_type (GET_MODE_PRECISION (mode))
+ : make_signed_type (GET_MODE_PRECISION (mode)));
+
+ if (COMPLEX_MODE_P (mode))
+ {
+ enum machine_mode inner_mode;
+ tree inner_type;
- if (VECTOR_MODE_P (mode))
+ if (mode == TYPE_MODE (complex_float_type_node))
+ return complex_float_type_node;
+ if (mode == TYPE_MODE (complex_double_type_node))
+ return complex_double_type_node;
+ if (mode == TYPE_MODE (complex_long_double_type_node))
+ return complex_long_double_type_node;
+
+ if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
+ return complex_integer_type_node;
+
+ inner_mode = GET_MODE_INNER (mode);
+ inner_type = c_common_type_for_mode (inner_mode, unsignedp);
+ if (inner_type != NULL_TREE)
+ return build_complex_type (inner_type);
+ }
+ else if (VECTOR_MODE_P (mode))
{
enum machine_mode inner_mode = GET_MODE_INNER (mode);
tree inner_type = c_common_type_for_mode (inner_mode, unsignedp);
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
- case TRUTH_NOT_EXPR:
if (TREE_TYPE (expr) != truthvalue_type_node)
return build2 (TREE_CODE (expr), truthvalue_type_node,
TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
return expr;
+ case TRUTH_NOT_EXPR:
+ if (TREE_TYPE (expr) != truthvalue_type_node)
+ return build1 (TREE_CODE (expr), truthvalue_type_node,
+ TREE_OPERAND (expr, 0));
+ return expr;
+
case ERROR_MARK:
return expr;
return type;
if (TREE_CODE (type) == ARRAY_TYPE)
- return build_array_type (c_build_qualified_type (TREE_TYPE (type),
- type_quals),
- TYPE_DOMAIN (type));
+ {
+ tree t;
+ tree element_type = c_build_qualified_type (TREE_TYPE (type),
+ type_quals);
+
+ /* See if we already have an identically qualified type. */
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ if (TYPE_QUALS (strip_array_types (t)) == type_quals
+ && TYPE_NAME (t) == TYPE_NAME (type)
+ && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+ && attribute_list_equal (TYPE_ATTRIBUTES (t),
+ TYPE_ATTRIBUTES (type)))
+ break;
+ }
+ if (!t)
+ {
+ t = build_variant_type_copy (type);
+ TREE_TYPE (t) = element_type;
+ }
+ return t;
+ }
/* A restrict-qualified pointer type must be a pointer to object or
incomplete type. Note that the use of POINTER_TYPE_P also allows
c_init_attributes ();
-#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, \
- BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT) \
- if (NAME) \
+#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
+ NONANSI_P, ATTRS, IMPLICIT, COND) \
+ if (NAME && COND) \
{ \
tree decl; \
\
#include "builtins.def"
#undef DEF_BUILTIN
+ build_common_builtin_nodes ();
+
targetm.init_builtins ();
if (flag_mudflap)
mudflap_init ();
/* Look up the function in built_in_decls that corresponds to DECL
and set ASMSPEC as its user assembler name. DECL must be a
- function decl that declares a builtin. */
+ function decl that declares a builtin. */
void
set_builtin_user_assembler_name (tree decl, const char *asmspec)
/* Handle -Wswitch*. Called from the front end after parsing the switch
construct. */
/* ??? Should probably be somewhere generic, since other languages besides
- C and C++ would want this. We'd want to agree on the datastructure,
+ C and C++ would want this. We'd want to agree on the data structure,
however, which is a problem. Alternately, we operate on gimplified
switch_exprs, which I don't especially like. At the moment, however,
C/C++ are the only tree-ssa languages that support enumerations at all,
else
switch_location = input_location;
- type = SWITCH_TYPE (switch_stmt);
+ type = SWITCH_STMT_TYPE (switch_stmt);
default_node = splay_tree_lookup (cases, (splay_tree_key) NULL);
if (warn_switch_default && !default_node)
default case, or when -Wswitch-enum was specified. */
if (((warn_switch && !default_node) || warn_switch_enum)
&& type && TREE_CODE (type) == ENUMERAL_TYPE
- && TREE_CODE (SWITCH_COND (switch_stmt)) != INTEGER_CST)
+ && TREE_CODE (SWITCH_STMT_COND (switch_stmt)) != INTEGER_CST)
{
tree chain;
return NULL_TREE;
}
+/* Handle a "returns_twice" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) == FUNCTION_DECL)
+ DECL_IS_RETURNS_TWICE (*node) = 1;
+ else
+ {
+ warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "no_limit_stack" attribute; arguments as in
struct attribute_spec.handler. */
}
}
+/* Convert a character from the host to the target execution character
+ set. cpplib handles this, mostly. */
+
+HOST_WIDE_INT
+c_common_to_target_charset (HOST_WIDE_INT c)
+{
+ /* Character constants in GCC proper are sign-extended under -fsigned-char,
+ zero-extended under -fno-signed-char. cpplib insists that characters
+ and character constants are always unsigned. Hence we must convert
+ back and forth. */
+ cppchar_t uc = ((cppchar_t)c) & ((((cppchar_t)1) << CHAR_BIT)-1);
+
+ uc = cpp_host_to_exec_charset (parse_in, uc);
+
+ if (flag_signed_char)
+ return ((HOST_WIDE_INT)uc) << (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE)
+ >> (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE);
+ else
+ return uc;
+}
+
/* Build the result of __builtin_offsetof. EXPR is a nested sequence of
component references, with an INDIRECT_REF at the bottom; much like
the traditional rendering of offsetof as a macro. Returns the folded