#include "c-common.h"
#include "c-pragma.h"
#include "cgraph.h"
+#include "hashtab.h"
+#include "libfuncs.h"
+#include "except.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
/* Similar, for the file and line that the prototype came from if this is
an old-style definition. */
-static const char *current_function_prototype_file;
-static int current_function_prototype_line;
+static location_t current_function_prototype_locus;
/* The current statement tree. */
/* Forward declarations. */
-static struct binding_level *make_binding_level PARAMS ((void));
-static void pop_binding_level PARAMS ((struct binding_level **));
-static int duplicate_decls PARAMS ((tree, tree, int));
-static int redeclaration_error_message PARAMS ((tree, tree));
-static void implicit_decl_warning PARAMS ((tree));
-static void storedecls PARAMS ((tree));
-static void storetags PARAMS ((tree));
-static tree lookup_tag PARAMS ((enum tree_code, tree, int));
-static tree lookup_name_current_level PARAMS ((tree));
-static tree grokdeclarator PARAMS ((tree, tree, enum decl_context,
- int));
-static tree grokparms PARAMS ((tree, int));
-static void layout_array_type PARAMS ((tree));
-static tree c_make_fname_decl PARAMS ((tree, int));
-static void c_expand_body_1 PARAMS ((tree, int));
-static tree any_external_decl PARAMS ((tree));
-static void record_external_decl PARAMS ((tree));
-static void warn_if_shadowing PARAMS ((tree, tree));
-static void clone_underlying_type PARAMS ((tree));
-static bool flexible_array_type_p PARAMS ((tree));
+static struct binding_level *make_binding_level (void);
+static void pop_binding_level (struct binding_level **);
+static int duplicate_decls (tree, tree, int);
+static int redeclaration_error_message (tree, tree);
+static void implicit_decl_warning (tree);
+static void storedecls (tree);
+static void storetags (tree);
+static tree lookup_tag (enum tree_code, tree, int);
+static tree lookup_name_current_level (tree);
+static tree grokdeclarator (tree, tree, enum decl_context, int);
+static tree grokparms (tree, int);
+static void layout_array_type (tree);
+static tree c_make_fname_decl (tree, int);
+static void c_expand_body_1 (tree, int);
+static tree any_external_decl (tree);
+static void record_external_decl (tree);
+static void warn_if_shadowing (tree, tree);
+static void clone_underlying_type (tree);
+static bool flexible_array_type_p (tree);
\f
/* States indicating how grokdeclarator() should handle declspecs marked
with __attribute__((deprecated)). An object declared as
__attribute__((deprecated)) suppresses warnings of uses of other
deprecated items. */
-
+
enum deprecated_states {
DEPRECATED_NORMAL,
DEPRECATED_SUPPRESS
static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
void
-c_print_identifier (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+c_print_identifier (FILE *file, tree node, int indent)
{
print_node (file, "symbol", IDENTIFIER_SYMBOL_VALUE (node), indent + 4);
print_node (file, "tag", IDENTIFIER_TAG_VALUE (node), indent + 4);
{
tree rid = ridpointers[C_RID_CODE (node)];
indent_to (file, indent + 4);
- fprintf (file, "rid ");
- fprintf (file, HOST_PTR_PRINTF, (void *)rid);
- fprintf (file, " \"%s\"", IDENTIFIER_POINTER (rid));
+ fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
+ (void *) rid, IDENTIFIER_POINTER (rid));
}
}
\f
for a top-level tentative array defn that wasn't complete before. */
void
-c_finish_incomplete_decl (decl)
- tree decl;
+c_finish_incomplete_decl (tree decl)
{
if (TREE_CODE (decl) == VAR_DECL)
{
/* Reuse or create a struct for this binding level. */
static struct binding_level *
-make_binding_level ()
+make_binding_level (void)
{
struct binding_level *result;
if (free_binding_level)
/* Remove a binding level from a list and add it to the level chain. */
static void
-pop_binding_level (lp)
- struct binding_level **lp;
+pop_binding_level (struct binding_level **lp)
{
struct binding_level *l = *lp;
*lp = l->level_chain;
-
+
memset (l, 0, sizeof (struct binding_level));
l->level_chain = free_binding_level;
free_binding_level = l;
/* Nonzero if we are currently in the global binding level. */
int
-global_bindings_p ()
+global_bindings_p (void)
{
return current_binding_level == global_binding_level;
}
void
-keep_next_level ()
+keep_next_level (void)
{
keep_next_level_flag = 1;
}
/* Nonzero if the current level needs to have a BLOCK made. */
int
-kept_level_p ()
+kept_level_p (void)
{
return ((current_binding_level->keep_if_subblocks
&& current_binding_level->blocks != 0)
DEFINITION_FLAG, so we ignore it. */
void
-declare_parm_level (definition_flag)
- int definition_flag ATTRIBUTE_UNUSED;
+declare_parm_level (int definition_flag ATTRIBUTE_UNUSED)
{
current_binding_level->parm_flag = 1;
}
/* Nonzero if currently making parm declarations. */
int
-in_parm_level_p ()
+in_parm_level_p (void)
{
return current_binding_level->parm_flag;
}
/* Enter a new binding level. */
void
-pushlevel (dummy)
- int dummy ATTRIBUTE_UNUSED;
+pushlevel (int dummy ATTRIBUTE_UNUSED)
{
/* If this is the top level of a function, make sure that
NAMED_LABELS is 0. */
them into the BLOCK. */
tree
-poplevel (keep, reverse, functionbody)
- int keep;
- int reverse;
- int functionbody;
+poplevel (int keep, int reverse, int functionbody)
{
tree link;
tree block;
{
error_with_decl (label, "label `%s' used but not defined");
/* Avoid crashing later. */
- define_label (input_filename, input_line,
- DECL_NAME (label));
+ define_label (input_location, DECL_NAME (label));
}
else if (warn_unused_label && !TREE_USED (label))
warning_with_decl (label, "label `%s' defined but not used");
to handle the BLOCK node inside the BIND_EXPR. */
void
-insert_block (block)
- tree block;
+insert_block (tree block)
{
TREE_USED (block) = 1;
current_binding_level->blocks
this hook, but it is not useful in function-at-a-time mode. */
void
-set_block (block)
- tree block ATTRIBUTE_UNUSED;
+set_block (tree block ATTRIBUTE_UNUSED)
{
}
\f
void
-push_label_level ()
+push_label_level (void)
{
struct binding_level *newlevel;
}
void
-pop_label_level ()
+pop_label_level (void)
{
struct binding_level *level = label_level_chain;
tree link, prev;
error_with_decl (TREE_VALUE (link),
"label `%s' used but not defined");
/* Avoid crashing later. */
- define_label (input_filename, input_line,
- DECL_NAME (TREE_VALUE (link)));
+ define_label (input_location, DECL_NAME (TREE_VALUE (link)));
}
else if (warn_unused_label && !TREE_USED (TREE_VALUE (link)))
warning_with_decl (TREE_VALUE (link),
In that case, the TYPE_SIZE will be zero. */
void
-pushtag (name, type)
- tree name, type;
+pushtag (tree name, tree type)
{
struct binding_level *b = current_binding_level;
and OLDDECL is in an outer binding level and should thus not be changed. */
static int
-duplicate_decls (newdecl, olddecl, different_binding_level)
- tree newdecl, olddecl;
- int different_binding_level;
+duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
{
int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
Update OLDDECL to be the same. */
DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
+ /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
+ so that encode_section_info has a chance to look at the new decl
+ flags and attributes. */
+ if (DECL_RTL_SET_P (olddecl)
+ && (TREE_CODE (olddecl) == FUNCTION_DECL
+ || (TREE_CODE (olddecl) == VAR_DECL
+ && TREE_STATIC (olddecl))))
+ make_decl_rtl (olddecl, NULL);
+
return 1;
}
/* Return any external DECL associated with ID, whether or not it is
currently in scope. */
+
static tree
-any_external_decl (id)
- tree id;
+any_external_decl (tree id)
{
tree decl = IDENTIFIER_SYMBOL_VALUE (id);
tree t;
- if (decl && TREE_CODE (decl) != TYPE_DECL && DECL_EXTERNAL (decl))
+ if (decl == 0 || TREE_CODE (decl) == ERROR_MARK)
+ return 0;
+ else if (TREE_CODE (decl) != TYPE_DECL && DECL_EXTERNAL (decl))
return decl;
t = purpose_member (id, truly_local_externals);
/* Record an external decl DECL. This only does something if a
shadowing decl already exists. */
static void
-record_external_decl (decl)
- tree decl;
+record_external_decl (tree decl)
{
tree name = DECL_NAME (decl);
if (!IDENTIFIER_SYMBOL_VALUE (name))
OLD is the old IDENTIFIER_SYMBOL_VALUE of the DECL_NAME of X,
which might be a NULL_TREE. */
static void
-warn_if_shadowing (x, old)
- tree x, old;
+warn_if_shadowing (tree x, tree old)
{
const char *name;
on a standard type by checking the current value of lineno. */
static void
-clone_underlying_type (x)
- tree x;
+clone_underlying_type (tree x)
{
if (DECL_SOURCE_LINE (x) == 0)
{
to agree with what X says. */
tree
-pushdecl (x)
- tree x;
+pushdecl (tree x)
{
tree name = DECL_NAME (x);
struct binding_level *scope = current_binding_level;
else
record_external_decl (x);
}
-
+
if (TREE_CODE (x) == TYPE_DECL)
clone_underlying_type (x);
}
/* Record X as belonging to the global scope (C99 "file scope").
- This is used only internally by the Objective C front end,
+ This is used only internally by the Objective-C front end,
and is limited to its needs. It will hork if there is _any_
visible binding for X (not just a global one). */
tree
-pushdecl_top_level (x)
- tree x;
+pushdecl_top_level (tree x)
{
tree name, old;
called; if there is any preexisting decl for this identifier, it is
an ICE. */
tree
-pushdecl_function_level (x, name)
- tree x;
- tree name;
+pushdecl_function_level (tree x, tree name)
{
struct binding_level *scope;
function of type int (). */
tree
-implicitly_declare (functionid)
- tree functionid;
+implicitly_declare (tree functionid)
{
tree decl = any_external_decl (functionid);
}
static void
-implicit_decl_warning (id)
- tree id;
+implicit_decl_warning (tree id)
{
const char *name = IDENTIFIER_POINTER (id);
if (mesg_implicit_function_declaration == 2)
and 3 if it is a conflicting declaration. */
static int
-redeclaration_error_message (newdecl, olddecl)
- tree newdecl, olddecl;
+redeclaration_error_message (tree newdecl, tree olddecl)
{
if (TREE_CODE (newdecl) == TYPE_DECL)
{
This function is called for both label definitions and label references. */
tree
-lookup_label (id)
- tree id;
+lookup_label (tree id)
{
tree decl = IDENTIFIER_LABEL_VALUE (id);
requires calling declare_nonlocal_label right away. */
tree
-shadow_label (name)
- tree name;
+shadow_label (tree name)
{
tree decl = IDENTIFIER_LABEL_VALUE (name);
Otherwise return 0. */
tree
-define_label (filename, line, name)
- const char *filename;
- int line;
- tree name;
+define_label (location_t location, tree name)
{
tree decl = lookup_label (name);
}
if (warn_traditional && !in_system_header && lookup_name (name))
- warning_with_file_and_line (filename, line,
- "traditional C lacks a separate namespace for labels, identifier `%s' conflicts",
- IDENTIFIER_POINTER (name));
+ warning ("%Htraditional C lacks a separate namespace for labels, "
+ "identifier `%s' conflicts", &location, IDENTIFIER_POINTER (name));
if (DECL_INITIAL (decl) != 0)
{
- error_with_file_and_line (filename, line, "duplicate label `%s'",
- IDENTIFIER_POINTER (name));
+ error ("%Hduplicate label `%s'", &location, IDENTIFIER_POINTER (name));
return 0;
}
else
/* Mark label as having been defined. */
DECL_INITIAL (decl) = error_mark_node;
/* Say where in the source. */
- DECL_SOURCE_FILE (decl) = filename;
- DECL_SOURCE_LINE (decl) = line;
+ DECL_SOURCE_LOCATION (decl) = location;
return decl;
}
}
store the result back using `storedecls' or you will lose. */
tree
-getdecls ()
+getdecls (void)
{
return current_binding_level->names;
}
/* Return the list of type-tags (for structs, etc) of the current level. */
tree
-gettags ()
+gettags (void)
{
return current_binding_level->tags;
}
after they are modified in the light of any missing parameters. */
static void
-storedecls (decls)
- tree decls;
+storedecls (tree decls)
{
current_binding_level->names = decls;
}
/* Similarly, store the list of tags of the current level. */
static void
-storetags (tags)
- tree tags;
+storetags (tree tags)
{
current_binding_level->tags = tags;
}
If the wrong kind of type is found, an error is reported. */
static tree
-lookup_tag (code, name, thislevel_only)
- enum tree_code code;
- tree name;
- int thislevel_only;
+lookup_tag (enum tree_code code, tree name, int thislevel_only)
{
tree tag = IDENTIFIER_TAG_VALUE (name);
int thislevel = 0;
when used in the `struct foo;' construct for shadowing. */
void
-pending_xref_error ()
+pending_xref_error (void)
{
if (pending_invalid_xref != 0)
- error_with_file_and_line (pending_invalid_xref_location.file,
- pending_invalid_xref_location.line,
- "`%s' defined as wrong kind of tag",
- IDENTIFIER_POINTER (pending_invalid_xref));
+ error ("%H`%s' defined as wrong kind of tag",
+ &pending_invalid_xref_location,
+ IDENTIFIER_POINTER (pending_invalid_xref));
pending_invalid_xref = 0;
}
or return 0 if it is undefined. */
tree
-lookup_name (name)
- tree name;
+lookup_name (tree name)
{
tree decl = IDENTIFIER_SYMBOL_VALUE (name);
if (decl == 0 || decl == error_mark_node)
/* Similar to `lookup_name' but look only at the current binding level. */
static tree
-lookup_name_current_level (name)
- tree name;
+lookup_name_current_level (tree name)
{
tree decl = IDENTIFIER_SYMBOL_VALUE (name);
Make definitions for built-in primitive functions. */
void
-c_init_decl_processing ()
+c_init_decl_processing (void)
{
tree endlink;
tree ptr_ftype_void, ptr_ftype_ptr;
-
+ location_t save_loc = input_location;
+
/* Adds some ggc roots, and reserved words for c-parse.in. */
c_parse_init ();
/* Make the binding_level structure for global names. */
pushlevel (0);
global_binding_level = current_binding_level;
+ /* Declarations from c_common_nodes_and_builtins must not be associated
+ with this input file, lest we get differences between using and not
+ using preprocessed headers. */
+ input_location.file = "<internal>";
+ input_location.line = 0;
build_common_tree_nodes (flag_signed_char);
= build_function_type (ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node, endlink));
+ input_location = save_loc;
+
pedantic_lvalues = pedantic;
make_fname_decl = c_make_fname_decl;
are string merging candidates, which is wrong for C99's __func__. FIXME. */
static tree
-c_make_fname_decl (id, type_dep)
- tree id;
- int type_dep;
+c_make_fname_decl (tree id, int type_dep)
{
const char *name = fname_as_string (type_dep);
tree decl, type, init;
build_index_type (size_int (length)));
decl = build_decl (VAR_DECL, id, type);
-
+
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
-
+
init = build_string (length + 1, name);
TREE_TYPE (init) = type;
DECL_INITIAL (decl) = init;
ATTRS is nonzero, use that for the function's attribute list. */
tree
-builtin_function (name, type, function_code, class, library_name, attrs)
- const char *name;
- tree type;
- int function_code;
- enum built_in_class class;
- const char *library_name;
- tree attrs;
+builtin_function (const char *name, tree type, int function_code,
+ enum built_in_class class, const char *library_name,
+ tree attrs)
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
attributes. */
void
-c_insert_default_attributes (decl)
- tree decl;
+c_insert_default_attributes (tree decl)
{
if (!TREE_PUBLIC (decl))
return;
Otherwise, it is an error. */
void
-shadow_tag (declspecs)
- tree declspecs;
+shadow_tag (tree declspecs)
{
shadow_tag_warned (declspecs, 0);
}
void
-shadow_tag_warned (declspecs, warned)
- tree declspecs;
- int warned;
+shadow_tag_warned (tree declspecs, int warned)
+
+
/* 1 => we have done a pedwarn. 2 => we have done a warning, but
no pedwarn. */
{
which has TREE_STATIC set if "static" is used. */
tree
-build_array_declarator (expr, quals, static_p, vla_unspec_p)
- tree expr;
- tree quals;
- int static_p;
- int vla_unspec_p;
+build_array_declarator (tree expr, tree quals, int static_p, int vla_unspec_p)
{
tree decl;
decl = build_nt (ARRAY_REF, NULL_TREE, expr);
C99 grammar. */
tree
-set_array_declarator_type (decl, type, abstract_p)
- tree decl;
- tree type;
- int abstract_p;
+set_array_declarator_type (tree decl, tree type, int abstract_p)
{
TREE_OPERAND (decl, 0) = type;
if (abstract_p && (TREE_TYPE (decl) != NULL_TREE || TREE_STATIC (decl)))
/* Decode a "typename", such as "int **", returning a ..._TYPE node. */
tree
-groktypename (typename)
- tree typename;
+groktypename (tree typename)
{
tree specs, attrs;
/* Return a PARM_DECL node for a given pair of specs and declarator. */
tree
-groktypename_in_parm_context (typename)
- tree typename;
+groktypename_in_parm_context (tree typename)
{
if (TREE_CODE (typename) != TREE_LIST)
return typename;
grokfield and not through here. */
tree
-start_decl (declarator, declspecs, initialized, attributes)
- tree declarator, declspecs;
- int initialized;
- tree attributes;
+start_decl (tree declarator, tree declspecs, int initialized, tree attributes)
{
tree decl;
tree tem;
-
+
/* An object declared as __attribute__((deprecated)) suppresses
warnings of uses of other deprecated items. */
if (lookup_attribute ("deprecated", attributes))
decl = grokdeclarator (declarator, declspecs,
NORMAL, initialized);
-
+
deprecated_state = DEPRECATED_NORMAL;
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
it must be determined now, from the initial value, or it is an error. */
void
-finish_decl (decl, init, asmspec_tree)
- tree decl, init;
- tree asmspec_tree;
+finish_decl (tree decl, tree init, tree asmspec_tree)
{
tree type = TREE_TYPE (decl);
int was_incomplete = (DECL_SIZE (decl) == 0);
/* If `start_decl' didn't like having an initialization, ignore it now. */
if (init != 0 && DECL_INITIAL (decl) == 0)
init = 0;
-
+
/* Don't crash if parm is initialized. */
if (TREE_CODE (decl) == PARM_DECL)
init = 0;
was a normal built-in. */
if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
{
+ /* ASMSPEC is given, and not the name of a register. Mark the
+ name with a star so assemble_name won't munge it. */
+ char *starred = alloca (strlen (asmspec) + 2);
+ starred[0] = '*';
+ strcpy (starred + 1, asmspec);
+
if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
{
tree builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
SET_DECL_RTL (builtin, NULL_RTX);
- SET_DECL_ASSEMBLER_NAME (builtin, get_identifier (asmspec));
+ SET_DECL_ASSEMBLER_NAME (builtin, get_identifier (starred));
#ifdef TARGET_MEM_FUNCTIONS
if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
- init_block_move_fn (asmspec);
+ init_block_move_fn (starred);
else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
- init_block_clear_fn (asmspec);
+ init_block_clear_fn (starred);
#else
if (DECL_FUNCTION_CODE (decl) == BUILT_IN_BCOPY)
- init_block_move_fn (asmspec);
+ init_block_move_fn (starred);
else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_BZERO)
- init_block_clear_fn (asmspec);
+ init_block_clear_fn (starred);
#endif
}
SET_DECL_RTL (decl, NULL_RTX);
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (starred));
}
/* Output the assembler code and/or RTL code for variables and functions,
if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
{
/* This is a no-op in c-lang.c or something real in objc-act.c. */
- if (flag_objc)
+ if (c_dialect_objc ())
objc_check_decl (decl);
if (!DECL_CONTEXT (decl))
ordinary, non-register local variable. Historically,
GCC has accepted -- but ignored -- the ASMSPEC in
this case. */
- if (TREE_CODE (decl) == VAR_DECL
+ if (TREE_CODE (decl) == VAR_DECL
&& !DECL_REGISTER (decl)
&& !TREE_STATIC (decl))
warning_with_decl (decl,
if (TREE_CODE (decl) == TYPE_DECL)
{
/* This is a no-op in c-lang.c or something real in objc-act.c. */
- if (flag_objc)
+ if (c_dialect_objc ())
objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL, DECL_CONTEXT (decl) == 0, 0);
}
computing them in the following function definition. */
if (current_binding_level == global_binding_level)
get_pending_sizes ();
+
+ /* Install a cleanup (aka destructor) if one was given. */
+ if (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))
+ {
+ tree attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
+ if (attr)
+ {
+ static bool eh_initialized_p;
+
+ tree cleanup_id = TREE_VALUE (TREE_VALUE (attr));
+ tree cleanup_decl = lookup_name (cleanup_id);
+ tree cleanup;
+
+ /* Build "cleanup(&decl)" for the destructor. */
+ cleanup = build_unary_op (ADDR_EXPR, decl, 0);
+ cleanup = build_tree_list (NULL_TREE, cleanup);
+ cleanup = build_function_call (cleanup_decl, cleanup);
+
+ /* Don't warn about decl unused; the cleanup uses it. */
+ TREE_USED (decl) = 1;
+
+ /* Initialize EH, if we've been told to do so. */
+ if (flag_exceptions && !eh_initialized_p)
+ {
+ eh_initialized_p = true;
+ eh_personality_libfunc
+ = init_one_libfunc (USING_SJLJ_EXCEPTIONS
+ ? "__gcc_personality_sj0"
+ : "__gcc_personality_v0");
+ using_eh_for_cleanups ();
+ }
+
+ add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
+ }
+ }
}
/* Given a parsed parameter declaration,
record the given order of parms in `parm_order'. */
void
-push_parm_decl (parm)
- tree parm;
+push_parm_decl (tree parm)
{
tree decl;
int old_immediate_size_expand = immediate_size_expand;
and also at semicolon terminating forward decls. */
void
-clear_parm_order ()
+clear_parm_order (void)
{
current_binding_level->parm_order = NULL_TREE;
}
literal. */
tree
-build_compound_literal (type, init)
- tree type;
- tree init;
+build_compound_literal (tree type, tree init)
{
/* We do not use start_decl here because we have a type, not a declarator;
and do not use finish_decl because the decl should be stored inside
a unique suffix to be added to the name. */
char *name;
- ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal",
+ ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal",
compound_literal_number);
compound_literal_number++;
DECL_NAME (decl) = get_identifier (name);
2 if there was no information (in which case assume 1 if DO_DEFAULT). */
int
-complete_array_type (type, initial_value, do_default)
- tree type;
- tree initial_value;
- int do_default;
+complete_array_type (tree type, tree initial_value, int do_default)
{
tree maxindex = NULL_TREE;
int value = 0;
or a union containing such a structure (possibly recursively). */
static bool
-flexible_array_type_p (type)
- tree type;
+flexible_array_type_p (tree type)
{
tree x;
switch (TREE_CODE (type))
and `extern' are interpreted. */
static tree
-grokdeclarator (declarator, declspecs, decl_context, initialized)
- tree declspecs;
- tree declarator;
- enum decl_context decl_context;
- int initialized;
+grokdeclarator (tree declarator, tree declspecs,
+ enum decl_context decl_context, int initialized)
{
int specbits = 0;
tree spec;
}
else if (type_quals)
type = c_build_qualified_type (type, type_quals);
-
+
type_as_written = type;
decl = build_decl (PARM_DECL, declarator, type);
tree global_decl;
global_decl = identifier_global_value (declarator);
- if (global_decl
+ if (global_decl
&& TREE_CODE (global_decl) == VAR_DECL
&& !TREE_PUBLIC (global_decl))
error ("variable previously declared `static' redeclared "
when FUNCDEF_FLAG is zero. */
static tree
-grokparms (parms_info, funcdef_flag)
- tree parms_info;
- int funcdef_flag;
+grokparms (tree parms_info, int funcdef_flag)
{
tree first_parm = TREE_CHAIN (parms_info);
Zero means the parmlist ended with an ellipsis so don't append `void'. */
tree
-get_parm_info (void_at_end)
- int void_at_end;
+get_parm_info (int void_at_end)
{
tree decl, t;
tree types = 0;
defined within. Do so because these types cannot ever become complete. */
void
-parmlist_tags_warning ()
+parmlist_tags_warning (void)
{
tree elt;
static int already;
Define the tag as a forward-reference if it is not defined. */
tree
-xref_tag (code, name)
- enum tree_code code;
- tree name;
+xref_tag (enum tree_code code, tree name)
{
/* If a cross reference is requested, look up the type
already defined for this tag and return it. */
CODE says which kind of tag NAME ought to be. */
tree
-start_struct (code, name)
- enum tree_code code;
- tree name;
+start_struct (enum tree_code code, tree name)
{
/* If there is already a tag defined at this binding level
(as a forward reference), just return it. */
error ("redefinition of `union %s'", IDENTIFIER_POINTER (name));
else
error ("redefinition of `struct %s'", IDENTIFIER_POINTER (name));
- }
+ }
}
else
{
ref = make_node (code);
pushtag (name, ref);
}
-
+
C_TYPE_BEING_DEFINED (ref) = 1;
TYPE_PACKED (ref) = flag_pack_struct;
return ref;
are ultimately passed to `build_struct' to make the RECORD_TYPE node. */
tree
-grokfield (filename, line, declarator, declspecs, width)
- const char *filename ATTRIBUTE_UNUSED;
- int line ATTRIBUTE_UNUSED;
- tree declarator, declspecs, width;
+grokfield (tree declarator, tree declspecs, tree width)
{
tree value;
finish_decl (value, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width;
- if (flag_objc)
+ if (c_dialect_objc ())
objc_check_decl (value);
return value;
}
\f
+/* Generate an error for any duplicate field names in FIELDLIST. Munge
+ the list such that this does not present a problem later. */
+
+static void
+detect_field_duplicates (tree fieldlist)
+{
+ tree x, y;
+ int timeout = 10;
+
+ /* First, see if there are more than "a few" fields.
+ This is trivially true if there are zero or one fields. */
+ if (!fieldlist)
+ return;
+ x = TREE_CHAIN (fieldlist);
+ if (!x)
+ return;
+ do {
+ timeout--;
+ x = TREE_CHAIN (x);
+ } while (timeout > 0 && x);
+
+ /* If there were "few" fields, avoid the overhead of allocating
+ a hash table. Instead just do the nested traversal thing. */
+ if (timeout > 0)
+ {
+ for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x))
+ if (DECL_NAME (x))
+ {
+ for (y = fieldlist; y != x; y = TREE_CHAIN (y))
+ if (DECL_NAME (y) == DECL_NAME (x))
+ {
+ error_with_decl (x, "duplicate member `%s'");
+ DECL_NAME (x) = NULL_TREE;
+ }
+ }
+ }
+ else
+ {
+ htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+ void **slot;
+
+ for (x = fieldlist; x ; x = TREE_CHAIN (x))
+ if ((y = DECL_NAME (x)) != 0)
+ {
+ slot = htab_find_slot (htab, y, INSERT);
+ if (*slot)
+ {
+ error_with_decl (x, "duplicate member `%s'");
+ DECL_NAME (x) = NULL_TREE;
+ }
+ *slot = y;
+ }
+
+ htab_delete (htab);
+ }
+}
+
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
ATTRIBUTES are attributes to be applied to the structure. */
tree
-finish_struct (t, fieldlist, attributes)
- tree t;
- tree fieldlist;
- tree attributes;
+finish_struct (tree t, tree fieldlist, tree attributes)
{
tree x;
int toplevel = global_binding_level == current_binding_level;
saw_named_field = 1;
}
- /* Delete all duplicate fields from the fieldlist */
- for (x = fieldlist; x && TREE_CHAIN (x);)
- /* Anonymous fields aren't duplicates. */
- if (DECL_NAME (TREE_CHAIN (x)) == 0)
- x = TREE_CHAIN (x);
- else
- {
- tree y = fieldlist;
-
- while (1)
- {
- if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
- break;
- if (y == x)
- break;
- y = TREE_CHAIN (y);
- }
- if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
- {
- error_with_decl (TREE_CHAIN (x), "duplicate member `%s'");
- TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
- }
- else
- x = TREE_CHAIN (x);
- }
+ detect_field_duplicates (fieldlist);
/* Now we have the nearly final fieldlist. Record it,
then lay out the structure or union (including the fields). */
{
layout_decl (decl, 0);
/* This is a no-op in c-lang.c or something real in objc-act.c. */
- if (flag_objc)
+ if (c_dialect_objc ())
objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL, toplevel, 0);
if (! toplevel)
if (TREE_CODE (decl) != TYPE_DECL)
{
layout_decl (decl, 0);
- if (flag_objc)
+ if (c_dialect_objc ())
objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL, toplevel, 0);
if (! toplevel)
/* Lay out the type T, and its element type, and so on. */
static void
-layout_array_type (t)
- tree t;
+layout_array_type (tree t)
{
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
layout_array_type (TREE_TYPE (t));
may be used to declare the individual values as they are read. */
tree
-start_enum (name)
- tree name;
+start_enum (tree name)
{
tree enumtype = 0;
Returns ENUMTYPE. */
tree
-finish_enum (enumtype, values, attributes)
- tree enumtype;
- tree values;
- tree attributes;
+finish_enum (tree enumtype, tree values, tree attributes)
{
tree pair, tem;
tree minnode = 0, maxnode = 0, enum_value_type;
Assignment of sequential values by default is handled here. */
tree
-build_enumerator (name, value)
- tree name, value;
+build_enumerator (tree name, tree value)
{
tree decl, type;
yyparse to report a parse error. */
int
-start_function (declspecs, declarator, attributes)
- tree declarator, declspecs, attributes;
+start_function (tree declspecs, tree declarator, tree attributes)
{
tree decl1, old_decl;
tree restype;
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
{
TREE_TYPE (decl1) = TREE_TYPE (old_decl);
- current_function_prototype_file = DECL_SOURCE_FILE (old_decl);
- current_function_prototype_line = DECL_SOURCE_LINE (old_decl);
+ current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
}
/* Optionally warn of old-fashioned def with no previous prototype. */
immediate_size_expand = old_immediate_size_expand;
start_fname_decls ();
-
+
return 1;
}
\f
to specify at least the number of arguments. */
void
-store_parm_decls ()
+store_parm_decls (void)
{
tree fndecl = current_function_decl;
tree parm;
/* Nonzero if this definition is written with a prototype. */
int prototype = 0;
- int saved_warn_shadow = warn_shadow;
+ bool saved_warn_shadow = warn_shadow;
/* Don't re-emit shadow warnings. */
- warn_shadow = 0;
+ warn_shadow = false;
if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
{
found = build_decl (PARM_DECL, TREE_VALUE (parm),
integer_type_node);
DECL_ARG_TYPE (found) = TREE_TYPE (found);
- DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl);
- DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl);
+ DECL_SOURCE_LOCATION (found) = DECL_SOURCE_LOCATION (fndecl);
if (flag_isoc99)
pedwarn_with_decl (found, "type of `%s' defaults to `int'");
else if (extra_warnings)
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
error ("number of arguments doesn't match prototype");
- error_with_file_and_line (current_function_prototype_file,
- current_function_prototype_line,
- "prototype declaration");
+ error ("%Hprototype declaration",
+ ¤t_function_prototype_locus);
break;
}
/* Type for passing arg must be consistent with that
{
pedwarn ("promoted argument `%s' doesn't match prototype",
IDENTIFIER_POINTER (DECL_NAME (parm)));
- warning_with_file_and_line
- (current_function_prototype_file,
- current_function_prototype_line,
- "prototype declaration");
+ warning ("%Hprototype declaration",
+ ¤t_function_prototype_locus);
}
}
else
{
error ("argument `%s' doesn't match prototype",
IDENTIFIER_POINTER (DECL_NAME (parm)));
- error_with_file_and_line (current_function_prototype_file,
- current_function_prototype_line,
- "prototype declaration");
+ error ("%Hprototype declaration",
+ ¤t_function_prototype_locus);
}
}
}
gen_aux_info_record (fndecl, 1, 0, prototype);
/* Initialize the RTL code for the function. */
- init_function_start (fndecl, input_filename, input_line);
+ init_function_start (fndecl);
/* Begin the statement tree for this function. */
begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl));
{
tree t;
- DECL_LANG_SPECIFIC (fndecl)->pending_sizes
+ DECL_LANG_SPECIFIC (fndecl)->pending_sizes
= nreverse (get_pending_sizes ());
for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
t;
CAN_DEFER_P is nonzero if the function may be deferred. */
void
-finish_function (nested, can_defer_p)
- int nested;
- int can_defer_p;
+finish_function (int nested, int can_defer_p)
{
tree fndecl = current_function_decl;
#endif
}
}
-
+
finish_fname_decls ();
/* Tie off the statement tree for this function. */
current_function_decl = NULL;
return;
}
-
+
/* Then, inline any functions called in it. */
optimize_inline_calls (fndecl);
timevar_pop (TV_INTEGRATION);
/* Generate the RTL for a deferred function FNDECL. */
void
-c_expand_deferred_function (fndecl)
- tree fndecl;
+c_expand_deferred_function (tree fndecl)
{
/* DECL_INLINE or DECL_RESULT might got cleared after the inline
function was deferred, e.g. in duplicate_decls. */
nested FUNCTION_DECL. */
static tree
-set_save_expr_context (tree *tp,
+set_save_expr_context (tree *tp,
int *walk_subtrees,
void *data)
{
generation of RTL. */
static void
-c_expand_body_1 (fndecl, nested_p)
- tree fndecl;
- int nested_p;
+c_expand_body_1 (tree fndecl, int nested_p)
{
timevar_push (TV_EXPAND);
/* Initialize the RTL code for the function. */
current_function_decl = fndecl;
input_location = DECL_SOURCE_LOCATION (fndecl);
- init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
+ init_function_start (fndecl);
/* This function is being processed in whole-function mode. */
cfun->x_whole_function_mode_p = 1;
&& variably_modified_type_p (TREE_TYPE (fndecl)))
walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl,
NULL);
-
+
/* If this function is `main', emit a call to `__main'
to run global initializers, etc. */
if (DECL_NAME (fndecl)
(*lang_expand_function_end) ();
/* Generate rtl for function exit. */
- expand_function_end (input_filename, input_line, 0);
+ expand_function_end ();
/* If this is a nested function, protect the local variables in the stack
above us from being collected while we're compiling this function. */
/* Like c_expand_body_1 but only for unnested functions. */
void
-c_expand_body (fndecl)
- tree fndecl;
+c_expand_body (tree fndecl)
{
c_expand_body_1 (fndecl, 0);
}
/* Check the declarations given in a for-loop for satisfying the C99
constraints. */
void
-check_for_loop_decls ()
+check_for_loop_decls (void)
{
tree t;
if (TREE_PURPOSE (t) != 0)
{
enum tree_code code = TREE_CODE (TREE_VALUE (t));
-
+
if (code == RECORD_TYPE)
error ("`struct %s' declared in `for' loop initial declaration",
IDENTIFIER_POINTER (TREE_PURPOSE (t)));
used during compilation of a C function. */
void
-c_push_function_context (f)
- struct function *f;
+c_push_function_context (struct function *f)
{
struct language_function *p;
p = ((struct language_function *)
/* Restore the variables used during compilation of a C function. */
void
-c_pop_function_context (f)
- struct function *f;
+c_pop_function_context (struct function *f)
{
struct language_function *p = f->language;
tree link;
/* Copy the DECL_LANG_SPECIFIC data associated with DECL. */
void
-c_dup_lang_specific_decl (decl)
- tree decl;
+c_dup_lang_specific_decl (tree decl)
{
struct lang_decl *ld;
at the end of the statement. */
int
-stmts_are_full_exprs_p ()
+stmts_are_full_exprs_p (void)
{
return 0;
}
returned. */
stmt_tree
-current_stmt_tree ()
+current_stmt_tree (void)
{
return &c_stmt_tree;
}
/* Returns the stack of SCOPE_STMTs for the current function. */
tree *
-current_scope_stmt_stack ()
+current_scope_stmt_stack (void)
{
return &c_scope_stmt_stack;
}
C. */
int
-anon_aggr_type_p (node)
- tree node ATTRIBUTE_UNUSED;
+anon_aggr_type_p (tree node ATTRIBUTE_UNUSED)
{
return 0;
}
/* Dummy function in place of callback used by C++. */
void
-extract_interface_info ()
+extract_interface_info (void)
{
}
statement tree. */
tree
-c_begin_compound_stmt ()
+c_begin_compound_stmt (void)
{
tree stmt;
common code. */
void
-c_expand_decl_stmt (t)
- tree t;
+c_expand_decl_stmt (tree t)
{
tree decl = DECL_STMT_DECL (t);
/* Return the global value of T as a symbol. */
tree
-identifier_global_value (t)
- tree t;
+identifier_global_value (tree t)
{
tree decl = IDENTIFIER_SYMBOL_VALUE (t);
if (decl == 0 || DECL_CONTEXT (decl) == 0)
otherwise the name is found in ridpointers from RID_INDEX. */
void
-record_builtin_type (rid_index, name, type)
- enum rid rid_index;
- const char *name;
- tree type;
+record_builtin_type (enum rid rid_index, const char *name, tree type)
{
tree id;
if (name == 0)
/* Build the void_list_node (void_type_node having been created). */
tree
-build_void_list_node ()
+build_void_list_node (void)
{
tree t = build_tree_list (NULL_TREE, void_type_node);
return t;
if attributes are present) and whose type is the modifier list. */
tree
-make_pointer_declarator (type_quals_attrs, target)
- tree type_quals_attrs, target;
+make_pointer_declarator (tree type_quals_attrs, tree target)
{
tree quals, attrs;
tree itarget = target;