#include "config.h"
#include "system.h"
#include "tree.h"
#include "flags.h"
#include "output.h"
#include "c-tree.h"
#include "c-lex.h"
#include "toplev.h"
#if defined (_WIN32) && defined (NEXT_PDO)
extern char* exportNamesForDLL;
#endif
#if USE_CPPLIB
#include "cpplib.h"
extern cpp_reader parse_in;
#endif
enum decl_context
{ NORMAL,
FUNCDEF,
PARM,
FIELD,
BITFIELD,
TYPENAME};
#ifndef CHAR_TYPE_SIZE
#define CHAR_TYPE_SIZE BITS_PER_UNIT
#endif
#ifndef SHORT_TYPE_SIZE
#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2))
#endif
#ifndef INT_TYPE_SIZE
#define INT_TYPE_SIZE BITS_PER_WORD
#endif
#ifndef LONG_TYPE_SIZE
#define LONG_TYPE_SIZE BITS_PER_WORD
#endif
#ifndef LONG_LONG_TYPE_SIZE
#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
#endif
#ifndef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#endif
#ifndef FLOAT_TYPE_SIZE
#define FLOAT_TYPE_SIZE BITS_PER_WORD
#endif
#ifndef DOUBLE_TYPE_SIZE
#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
#endif
#ifndef LONG_DOUBLE_TYPE_SIZE
#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
#endif
#ifndef SIZE_TYPE
#define SIZE_TYPE "long unsigned int"
#endif
#ifndef PTRDIFF_TYPE
#define PTRDIFF_TYPE "long int"
#endif
#ifndef WCHAR_TYPE
#define WCHAR_TYPE "int"
#endif
tree error_mark_node;
tree short_integer_type_node;
tree integer_type_node;
tree long_integer_type_node;
tree long_long_integer_type_node;
tree short_unsigned_type_node;
tree unsigned_type_node;
tree long_unsigned_type_node;
tree long_long_unsigned_type_node;
tree boolean_type_node;
tree boolean_false_node;
tree boolean_true_node;
tree ptrdiff_type_node;
tree unsigned_char_type_node;
tree signed_char_type_node;
tree char_type_node;
tree wchar_type_node;
tree signed_wchar_type_node;
tree unsigned_wchar_type_node;
tree float_type_node;
tree double_type_node;
tree long_double_type_node;
tree complex_integer_type_node;
tree complex_float_type_node;
tree complex_double_type_node;
tree complex_long_double_type_node;
tree vector_unsigned_char_type_node;
tree vector_signed_char_type_node;
tree vector_boolean_char_type_node;
tree vector_unsigned_short_type_node;
tree vector_signed_short_type_node;
tree vector_boolean_short_type_node;
tree vector_unsigned_long_type_node;
tree vector_signed_long_type_node;
tree vector_boolean_long_type_node;
tree vector_float_type_node;
tree vector_pixel_type_node;
tree intQI_type_node;
tree intHI_type_node;
tree intSI_type_node;
tree intDI_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
tree intTI_type_node;
#endif
tree unsigned_intQI_type_node;
tree unsigned_intHI_type_node;
tree unsigned_intSI_type_node;
tree unsigned_intDI_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
tree unsigned_intTI_type_node;
#endif
tree void_type_node;
tree ptr_type_node, const_ptr_type_node;
tree string_type_node, const_string_type_node;
tree char_array_type_node;
#ifdef PASCAL_STRINGS
tree unsigned_char_array_type_node;
#endif
tree int_array_type_node;
tree wchar_array_type_node;
tree default_function_type;
tree double_ftype_double, double_ftype_double_double;
tree int_ftype_int, long_ftype_long;
tree float_ftype_float;
tree ldouble_ftype_ldouble;
tree void_ftype_ptr_ptr_int, int_ftype_ptr_ptr_int, void_ftype_ptr_int_int;
tree string_ftype_ptr_ptr, int_ftype_string_string;
tree int_ftype_cptr_cptr_sizet;
tree integer_zero_node;
tree null_pointer_node;
tree integer_one_node;
tree pending_invalid_xref;
char *pending_invalid_xref_file;
int pending_invalid_xref_line;
static tree enum_next_value;
static int enum_overflow;
static tree last_function_parms;
static tree last_function_parm_tags;
static tree current_function_parms;
static tree current_function_parm_tags;
static char *current_function_prototype_file;
static int current_function_prototype_line;
static tree named_labels;
static tree shadowed_labels;
static int c_function_varargs;
tree current_function_decl;
int current_function_returns_value;
int current_function_returns_null;
static int warn_about_return_type;
static int current_extern_inline;
struct binding_level
{
tree names;
tree tags;
tree shadowed;
tree blocks;
tree this_block;
struct binding_level *level_chain;
char parm_flag;
char tag_transparent;
char subblocks_tag_transparent;
char keep;
char keep_if_subblocks;
tree incomplete_list;
tree parm_order;
};
#define NULL_BINDING_LEVEL (struct binding_level *) NULL
static struct binding_level *current_binding_level;
static struct binding_level *free_binding_level;
static struct binding_level *global_binding_level;
static struct binding_level clear_binding_level
= {NULL, NULL, NULL, NULL, NULL, NULL_BINDING_LEVEL, 0, 0, 0, 0, 0, 0,
NULL};
static int keep_next_level_flag;
static int keep_next_if_subblocks;
static struct binding_level *label_level_chain;
tree static_ctors, static_dtors;
static struct binding_level * make_binding_level PROTO((void));
static void clear_limbo_values PROTO((tree));
static int duplicate_decls PROTO((tree, tree, int));
static int redeclaration_error_message PROTO((tree, tree));
static void storedecls PROTO((tree));
static void storetags PROTO((tree));
static tree lookup_tag PROTO((enum tree_code, tree,
struct binding_level *, int));
static tree lookup_tag_reverse PROTO((tree));
static tree grokdeclarator PROTO((tree, tree, enum decl_context,
int));
static tree grokparms PROTO((tree, int));
static int field_decl_cmp PROTO((const GENERIC_PTR, const GENERIC_PTR));
static void layout_array_type PROTO((tree));
int flag_cond_mismatch;
int flag_short_double;
int flag_no_asm;
int flag_no_builtin;
int flag_no_nonansi_builtin;
int flag_altivec;
int flag_traditional;
int flag_isoc9x = 0;
int flag_hosted = 1;
int flag_allow_single_precision = 0;
int flag_signed_bitfields = 1;
int explicit_flag_signed_bitfields = 0;
#ifdef ENABLE_NEWLINE_MAPPING
int flag_map_newline_to_cr;
#endif
#ifdef PASCAL_STRINGS
int flag_pascal_strings;
#endif
int warn_implicit_int;
int warn_long_long = 1;
int warn_long_double = 1;
int warned_about_long_double = 0;
int mesg_implicit_function_declaration;
int flag_const_strings;
#ifdef FOUR_CHAR_CONSTANTS
int warn_four_char_constants = 1;
#endif
int warn_cast_qual;
int warn_bad_function_cast;
int warn_missing_noreturn;
int warn_traditional;
int warn_pointer_arith;
int warn_strict_prototypes;
int warn_missing_prototypes;
int warn_missing_declarations;
int warn_redundant_decls = 0;
int warn_nested_externs = 0;
int warn_format;
int warn_char_subscripts = 0;
int warn_conversion;
int warn_parentheses;
int warn_missing_braces;
int warn_main;
int warn_unknown_pragmas = 0;
int warn_sign_compare = -1;
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
int warn_most = 0;
#endif
int warn_multichar = 1;
int c_language = clk_c;
#ifndef DOLLARS_IN_IDENTIFIERS
#define DOLLARS_IN_IDENTIFIERS 1
#endif
int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
int
c_decode_option (argc, argv)
int argc ATTRIBUTE_UNUSED;
char **argv;
{
int strings_processed;
char *p = argv[0];
#if USE_CPPLIB
strings_processed = cpp_handle_option (&parse_in, argc, argv);
#else
strings_processed = 0;
#endif
if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
{
flag_traditional = 1;
flag_writable_strings = 1;
}
else if (!strcmp (p, "-fallow-single-precision"))
flag_allow_single_precision = 1;
else if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding"))
{
flag_hosted = 1;
flag_no_builtin = 0;
}
else if (!strcmp (p, "-ffreestanding") || !strcmp (p, "-fno-hosted"))
{
flag_hosted = 0;
flag_no_builtin = 1;
if (warn_main == 2)
warn_main = 0;
}
else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional"))
{
flag_traditional = 0;
flag_writable_strings = 0;
}
else if (!strncmp (p, "-std=", 5))
{
const char *argstart = &p[5];
if (!strcmp (argstart, "iso9899:1990")
|| !strcmp (argstart, "c89"))
{
iso_1990:
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
flag_no_nonansi_builtin = 1;
flag_isoc9x = 0;
}
else if (!strcmp (argstart, "iso9899:199409"))
{
goto iso_1990;
}
else if (!strcmp (argstart, "iso9899:199x")
|| !strcmp (argstart, "c9x"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
flag_no_nonansi_builtin = 1;
flag_isoc9x = 1;
}
else if (!strcmp (argstart, "gnu89"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 0;
flag_no_nonansi_builtin = 0;
flag_isoc9x = 0;
}
else if (!strcmp (argstart, "gnu9x"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 0;
flag_no_nonansi_builtin = 0;
flag_isoc9x = 1;
}
else
error ("unknown C standard `%s'", argstart);
}
else if (!strcmp (p, "-fdollars-in-identifiers"))
dollars_in_ident = 1;
else if (!strcmp (p, "-fno-dollars-in-identifiers"))
dollars_in_ident = 0;
else if (!strcmp (p, "-fsigned-char"))
flag_signed_char = 1;
else if (!strcmp (p, "-funsigned-char"))
flag_signed_char = 0;
else if (!strcmp (p, "-fno-signed-char"))
flag_signed_char = 0;
else if (!strcmp (p, "-fno-unsigned-char"))
flag_signed_char = 1;
else if (!strcmp (p, "-fsigned-bitfields")
|| !strcmp (p, "-fno-unsigned-bitfields"))
{
flag_signed_bitfields = 1;
explicit_flag_signed_bitfields = 1;
}
else if (!strcmp (p, "-funsigned-bitfields")
|| !strcmp (p, "-fno-signed-bitfields"))
{
flag_signed_bitfields = 0;
explicit_flag_signed_bitfields = 1;
}
else if (!strcmp (p, "-fshort-enums"))
flag_short_enums = 1;
else if (!strcmp (p, "-fno-short-enums"))
flag_short_enums = 0;
else if (!strcmp (p, "-fcond-mismatch"))
flag_cond_mismatch = 1;
else if (!strcmp (p, "-fno-cond-mismatch"))
flag_cond_mismatch = 0;
else if (!strcmp (p, "-fshort-double"))
flag_short_double = 1;
else if (!strcmp (p, "-fno-short-double"))
flag_short_double = 0;
else if (!strcmp (p, "-fasm"))
flag_no_asm = 0;
else if (!strcmp (p, "-fno-asm"))
flag_no_asm = 1;
else if (!strcmp (p, "-fbuiltin"))
flag_no_builtin = 0;
else if (!strcmp (p, "-fno-builtin"))
flag_no_builtin = 1;
#ifdef NEXT_SEMANTICS
else if (!strcmp (p, "-faltivec"))
#else
else if (!strcmp (p, "-fvec"))
#endif
flag_altivec = 1;
#ifdef NEXT_SEMANTICS
else if (!strcmp (p, "-fno-altivec"))
#else
else if (!strcmp (p, "-fno-vec"))
#endif
flag_altivec = 0;
else if (!strcmp (p, "-fno-ident"))
flag_no_ident = 1;
else if (!strcmp (p, "-fident"))
flag_no_ident = 0;
else if (!strcmp (p, "-ansi"))
goto iso_1990;
#ifdef ENABLE_NEWLINE_MAPPING
else if (!strcmp (p, "-fmap-newline-to-cr"))
flag_map_newline_to_cr = 1;
else if (!strcmp (p, "-fno-map-newline-to-cr"))
flag_map_newline_to_cr = 0;
#endif
#ifdef PASCAL_STRINGS
else if (!strcmp (p, "-fpascal-strings"))
flag_pascal_strings = 1;
else if (!strcmp (p, "-fno-pascal-strings"))
flag_pascal_strings = 0;
#endif
#ifdef FOUR_CHAR_CONSTANTS
else if (!strcmp (p, "-Wfour-char-constants"))
warn_four_char_constants = 1;
else if (!strcmp (p, "-Wno-four-char-constants"))
warn_four_char_constants = 0;
#endif
else if (!strcmp (p, "-Werror-implicit-function-declaration"))
mesg_implicit_function_declaration = 2;
else if (!strcmp (p, "-Wimplicit-function-declaration"))
mesg_implicit_function_declaration = 1;
else if (!strcmp (p, "-Wno-implicit-function-declaration"))
mesg_implicit_function_declaration = 0;
else if (!strcmp (p, "-Wimplicit-int"))
warn_implicit_int = 1;
else if (!strcmp (p, "-Wno-implicit-int"))
warn_implicit_int = 0;
else if (!strcmp (p, "-Wimplicit"))
{
warn_implicit_int = 1;
if (mesg_implicit_function_declaration != 2)
mesg_implicit_function_declaration = 1;
}
else if (!strcmp (p, "-Wno-implicit"))
warn_implicit_int = 0, mesg_implicit_function_declaration = 0;
else if (!strcmp (p, "-Wlong-double"))
warn_long_double = 1;
else if (!strcmp (p, "-Wno-long-double"))
warn_long_double = 0;
else if (!strcmp (p, "-Wlong-long"))
warn_long_long = 1;
else if (!strcmp (p, "-Wno-long-long"))
warn_long_long = 0;
else if (!strcmp (p, "-Wwrite-strings"))
flag_const_strings = 1;
else if (!strcmp (p, "-Wno-write-strings"))
flag_const_strings = 0;
else if (!strcmp (p, "-Wcast-qual"))
warn_cast_qual = 1;
else if (!strcmp (p, "-Wno-cast-qual"))
warn_cast_qual = 0;
else if (!strcmp (p, "-Wbad-function-cast"))
warn_bad_function_cast = 1;
else if (!strcmp (p, "-Wno-bad-function-cast"))
warn_bad_function_cast = 0;
else if (!strcmp (p, "-Wmissing-noreturn"))
warn_missing_noreturn = 1;
else if (!strcmp (p, "-Wno-missing-noreturn"))
warn_missing_noreturn = 0;
else if (!strcmp (p, "-Wpointer-arith"))
warn_pointer_arith = 1;
else if (!strcmp (p, "-Wno-pointer-arith"))
warn_pointer_arith = 0;
else if (!strcmp (p, "-Wstrict-prototypes"))
warn_strict_prototypes = 1;
else if (!strcmp (p, "-Wno-strict-prototypes"))
warn_strict_prototypes = 0;
else if (!strcmp (p, "-Wmissing-prototypes"))
warn_missing_prototypes = 1;
else if (!strcmp (p, "-Wno-missing-prototypes"))
warn_missing_prototypes = 0;
else if (!strcmp (p, "-Wmissing-declarations"))
warn_missing_declarations = 1;
else if (!strcmp (p, "-Wno-missing-declarations"))
warn_missing_declarations = 0;
else if (!strcmp (p, "-Wredundant-decls"))
warn_redundant_decls = 1;
else if (!strcmp (p, "-Wno-redundant-decls"))
warn_redundant_decls = 0;
else if (!strcmp (p, "-Wnested-externs"))
warn_nested_externs = 1;
else if (!strcmp (p, "-Wno-nested-externs"))
warn_nested_externs = 0;
else if (!strcmp (p, "-Wtraditional"))
warn_traditional = 1;
else if (!strcmp (p, "-Wno-traditional"))
warn_traditional = 0;
else if (!strcmp (p, "-Wformat"))
warn_format = 1;
else if (!strcmp (p, "-Wno-format"))
warn_format = 0;
#if defined(OPENSTEP) || defined(NEXT_PDO)
else if (!strcmp (p, "-Wnoformat"))
warn_format = 0;
#endif
else if (!strcmp (p, "-Wchar-subscripts"))
warn_char_subscripts = 1;
else if (!strcmp (p, "-Wno-char-subscripts"))
warn_char_subscripts = 0;
else if (!strcmp (p, "-Wconversion"))
warn_conversion = 1;
else if (!strcmp (p, "-Wno-conversion"))
warn_conversion = 0;
else if (!strcmp (p, "-Wparentheses"))
warn_parentheses = 1;
else if (!strcmp (p, "-Wno-parentheses"))
warn_parentheses = 0;
else if (!strcmp (p, "-Wreturn-type"))
warn_return_type = 1;
else if (!strcmp (p, "-Wno-return-type"))
warn_return_type = 0;
else if (!strcmp (p, "-Wcomment"))
;
else if (!strcmp (p, "-Wno-comment"))
;
else if (!strcmp (p, "-Wcomments"))
;
else if (!strcmp (p, "-Wno-comments"))
;
else if (!strcmp (p, "-Wtrigraphs"))
;
else if (!strcmp (p, "-Wno-trigraphs"))
;
else if (!strcmp (p, "-Wundef"))
;
else if (!strcmp (p, "-Wno-undef"))
;
else if (!strcmp (p, "-Wimport"))
;
else if (!strcmp (p, "-Wno-import"))
;
else if (!strcmp (p, "-Wmissing-braces"))
warn_missing_braces = 1;
else if (!strcmp (p, "-Wno-missing-braces"))
warn_missing_braces = 0;
else if (!strcmp (p, "-Wmain"))
warn_main = 1;
else if (!strcmp (p, "-Wno-main"))
warn_main = -1;
else if (!strcmp (p, "-Wsign-compare"))
warn_sign_compare = 1;
else if (!strcmp (p, "-Wno-sign-compare"))
warn_sign_compare = 0;
else if (!strcmp (p, "-Wmultichar"))
warn_multichar = 1;
else if (!strcmp (p, "-Wno-multichar"))
warn_multichar = 0;
else if (!strcmp (p, "-Wunknown-pragmas"))
warn_unknown_pragmas = 2;
else if (!strcmp (p, "-Wno-unknown-pragmas"))
warn_unknown_pragmas = 0;
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
else if (!strcmp (p, "-Wall") || !strcmp (p, "-Wmost"))
#else
else if (!strcmp (p, "-Wall"))
#endif
{
if (warn_uninitialized != 1)
warn_uninitialized = 2;
warn_implicit_int = 1;
mesg_implicit_function_declaration = 1;
warn_return_type = 1;
warn_unused = 1;
warn_switch = 1;
warn_format = 1;
warn_char_subscripts = 1;
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
if (!strcmp (p, "-Wall"))
#endif
warn_parentheses = 1;
warn_missing_braces = 1;
warn_main = 2;
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
if (!strcmp (p, "-Wall"))
{
#endif
warn_unknown_pragmas = 1;
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
warn_most = 0;
}
else if (!strcmp (p, "-Wmost"))
{
warn_most = 1;
warn_unused = -1;
}
#endif
}
else
return strings_processed;
return 1;
}
void
print_lang_decl (file, node, indent)
FILE *file ATTRIBUTE_UNUSED;
tree node ATTRIBUTE_UNUSED;
int indent ATTRIBUTE_UNUSED;
{
}
void
print_lang_type (file, node, indent)
FILE *file ATTRIBUTE_UNUSED;
tree node ATTRIBUTE_UNUSED;
int indent ATTRIBUTE_UNUSED;
{
}
void
print_lang_identifier (file, node, indent)
FILE *file;
tree node;
int indent;
{
print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4);
}
void
finish_incomplete_decl (decl)
tree decl;
{
if (TREE_CODE (decl) == VAR_DECL)
{
tree type = TREE_TYPE (decl);
if (type != error_mark_node
&& TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == 0)
{
if (! DECL_EXTERNAL (decl))
warning_with_decl (decl, "array `%s' assumed to have one element");
complete_array_type (type, NULL_TREE, 1);
layout_decl (decl, 0);
}
}
}
static
struct binding_level *
make_binding_level ()
{
return (struct binding_level *) xmalloc (sizeof (struct binding_level));
}
int
global_bindings_p ()
{
return current_binding_level == global_binding_level;
}
void
keep_next_level ()
{
keep_next_level_flag = 1;
}
int
kept_level_p ()
{
return ((current_binding_level->keep_if_subblocks
&& current_binding_level->blocks != 0)
|| current_binding_level->keep
|| current_binding_level->names != 0
|| (current_binding_level->tags != 0
&& !current_binding_level->tag_transparent));
}
void
declare_parm_level (definition_flag)
int definition_flag ATTRIBUTE_UNUSED;
{
current_binding_level->parm_flag = 1;
}
int
in_parm_level_p ()
{
return current_binding_level->parm_flag;
}
void
pushlevel (tag_transparent)
int tag_transparent;
{
register struct binding_level *newlevel = NULL_BINDING_LEVEL;
if (current_binding_level == global_binding_level)
{
named_labels = 0;
}
if (free_binding_level)
{
newlevel = free_binding_level;
free_binding_level = free_binding_level->level_chain;
}
else
{
newlevel = make_binding_level ();
}
*newlevel = clear_binding_level;
newlevel->tag_transparent
= (tag_transparent
|| (current_binding_level
? current_binding_level->subblocks_tag_transparent
: 0));
newlevel->level_chain = current_binding_level;
current_binding_level = newlevel;
newlevel->keep = keep_next_level_flag;
keep_next_level_flag = 0;
newlevel->keep_if_subblocks = keep_next_if_subblocks;
keep_next_if_subblocks = 0;
}
static void
clear_limbo_values (block)
tree block;
{
tree tem;
for (tem = BLOCK_VARS (block); tem; tem = TREE_CHAIN (tem))
if (DECL_NAME (tem) != 0)
IDENTIFIER_LIMBO_VALUE (DECL_NAME (tem)) = 0;
for (tem = BLOCK_SUBBLOCKS (block); tem; tem = TREE_CHAIN (tem))
clear_limbo_values (tem);
}
tree
poplevel (keep, reverse, functionbody)
int keep;
int reverse;
int functionbody;
{
register tree link;
tree decls;
tree tags = current_binding_level->tags;
tree subblocks = current_binding_level->blocks;
tree block = 0;
tree decl;
int block_previously_created;
keep |= current_binding_level->keep;
#if 0
for (link = tags; link; link = TREE_CHAIN (link))
if (TYPE_SIZE (TREE_VALUE (link)) == 0)
{
tree type = TREE_VALUE (link);
tree type_name = TYPE_NAME (type);
char *id = IDENTIFIER_POINTER (TREE_CODE (type_name) == IDENTIFIER_NODE
? type_name
: DECL_NAME (type_name));
switch (TREE_CODE (type))
{
case RECORD_TYPE:
error ("`struct %s' incomplete in scope ending here", id);
break;
case UNION_TYPE:
error ("`union %s' incomplete in scope ending here", id);
break;
case ENUMERAL_TYPE:
error ("`enum %s' incomplete in scope ending here", id);
break;
}
}
#endif
if (reverse)
current_binding_level->names
= decls = nreverse (current_binding_level->names);
else
decls = current_binding_level->names;
for (decl = decls; decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == FUNCTION_DECL
&& ! TREE_ASM_WRITTEN (decl)
&& DECL_INITIAL (decl) != 0
&& TREE_ADDRESSABLE (decl))
{
if (DECL_ABSTRACT_ORIGIN (decl) != 0
&& DECL_ABSTRACT_ORIGIN (decl) != decl)
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
else if (DECL_SAVED_INSNS (decl) != 0)
{
push_function_context ();
output_inline_function (decl);
pop_function_context ();
}
}
block = 0;
block_previously_created = (current_binding_level->this_block != 0);
if (block_previously_created)
block = current_binding_level->this_block;
else if (keep || functionbody
|| (current_binding_level->keep_if_subblocks && subblocks != 0))
block = make_node (BLOCK);
if (block != 0)
{
BLOCK_VARS (block) = decls;
BLOCK_TYPE_TAGS (block) = tags;
BLOCK_SUBBLOCKS (block) = subblocks;
remember_end_note (block);
}
for (link = subblocks; link; link = TREE_CHAIN (link))
BLOCK_SUPERCONTEXT (link) = block;
for (link = decls; link; link = TREE_CHAIN (link))
{
if (DECL_NAME (link) != 0)
{
if (DECL_EXTERNAL (link))
{
if (TREE_USED (link))
TREE_USED (DECL_NAME (link)) = 1;
if (TREE_ADDRESSABLE (link))
TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
}
IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
}
}
for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
if (functionbody)
{
clear_limbo_values (block);
BLOCK_VARS (block) = 0;
for (link = named_labels; link; link = TREE_CHAIN (link))
{
register tree label = TREE_VALUE (link);
if (DECL_INITIAL (label) == 0)
{
error_with_decl (label, "label `%s' used but not defined");
define_label (input_filename, lineno,
DECL_NAME (label));
}
else if (warn_unused && !TREE_USED (label))
#ifdef NEXT_PDO
if (!warn_most)
#endif
warning_with_decl (label, "label `%s' defined but not used");
IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
TREE_CHAIN (label) = BLOCK_VARS (block);
BLOCK_VARS (block) = label;
}
}
{
register struct binding_level *level = current_binding_level;
current_binding_level = current_binding_level->level_chain;
level->level_chain = free_binding_level;
free_binding_level = level;
}
if (functionbody)
DECL_INITIAL (current_function_decl) = block;
else if (block)
{
if (!block_previously_created)
current_binding_level->blocks
= chainon (current_binding_level->blocks, block);
}
else if (subblocks)
current_binding_level->blocks
= chainon (current_binding_level->blocks, subblocks);
if (functionbody)
for (link = tags; link; link = TREE_CHAIN (link))
TYPE_CONTEXT (TREE_VALUE (link)) = current_function_decl;
else if (block)
for (link = tags; link; link = TREE_CHAIN (link))
TYPE_CONTEXT (TREE_VALUE (link)) = block;
if (block)
TREE_USED (block) = 1;
return block;
}
void
delete_block (block)
tree block;
{
tree t;
if (current_binding_level->blocks == block)
current_binding_level->blocks = TREE_CHAIN (block);
for (t = current_binding_level->blocks; t;)
{
if (TREE_CHAIN (t) == block)
TREE_CHAIN (t) = TREE_CHAIN (block);
else
t = TREE_CHAIN (t);
}
TREE_CHAIN (block) = NULL;
TREE_USED (block) = 0;
}
void
insert_block (block)
tree block;
{
TREE_USED (block) = 1;
current_binding_level->blocks
= chainon (current_binding_level->blocks, block);
}
void
set_block (block)
register tree block;
{
current_binding_level->this_block = block;
}
void
push_label_level ()
{
register struct binding_level *newlevel;
if (free_binding_level)
{
newlevel = free_binding_level;
free_binding_level = free_binding_level->level_chain;
}
else
{
newlevel = make_binding_level ();
}
newlevel->level_chain = label_level_chain;
label_level_chain = newlevel;
newlevel->names = named_labels;
newlevel->shadowed = shadowed_labels;
named_labels = 0;
shadowed_labels = 0;
}
void
pop_label_level ()
{
register struct binding_level *level = label_level_chain;
tree link, prev;
for (link = named_labels, prev = 0; link;)
{
if (C_DECLARED_LABEL_FLAG (TREE_VALUE (link)))
{
if (DECL_SOURCE_LINE (TREE_VALUE (link)) == 0)
{
error_with_decl (TREE_VALUE (link),
"label `%s' used but not defined");
define_label (input_filename, lineno,
DECL_NAME (TREE_VALUE (link)));
}
else if (warn_unused && !TREE_USED (TREE_VALUE (link)))
warning_with_decl (TREE_VALUE (link),
"label `%s' defined but not used");
IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;
link = TREE_CHAIN (link);
if (prev)
TREE_CHAIN (prev) = link;
else
named_labels = link;
}
else
{
prev = link;
link = TREE_CHAIN (link);
}
}
for (link = shadowed_labels; link; link = TREE_CHAIN (link))
if (DECL_NAME (TREE_VALUE (link)) != 0)
IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
= TREE_VALUE (link);
named_labels = chainon (named_labels, level->names);
shadowed_labels = level->shadowed;
label_level_chain = label_level_chain->level_chain;
level->level_chain = free_binding_level;
free_binding_level = level;
}
void
pushtag (name, type)
tree name, type;
{
register struct binding_level *b;
for (b = current_binding_level; b->tag_transparent; b = b->level_chain)
continue;
if (name)
{
if (TYPE_NAME (type) == 0)
TYPE_NAME (type) = name;
}
if (b == global_binding_level)
b->tags = perm_tree_cons (name, type, b->tags);
else
b->tags = saveable_tree_cons (name, type, b->tags);
TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));
TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
}
static int
duplicate_decls (newdecl, olddecl, different_binding_level)
register tree newdecl, olddecl;
int different_binding_level;
{
int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_INITIAL (newdecl) != 0);
tree oldtype = TREE_TYPE (olddecl);
tree newtype = TREE_TYPE (newdecl);
int errmsg = 0;
if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
DECL_MACHINE_ATTRIBUTES (newdecl)
= merge_machine_decl_attributes (olddecl, newdecl);
if (TREE_CODE (newtype) == ERROR_MARK
|| TREE_CODE (oldtype) == ERROR_MARK)
types_match = 0;
if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
{
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& (DECL_BUILT_IN (olddecl)
|| DECL_BUILT_IN_NONANSI (olddecl)))
{
if (!TREE_PUBLIC (newdecl))
{
if (!warn_shadow)
;
else if (DECL_BUILT_IN (olddecl))
warning_with_decl (newdecl, "shadowing built-in function `%s'");
else
warning_with_decl (newdecl, "shadowing library function `%s'");
}
else if (! DECL_BUILT_IN (olddecl))
warning_with_decl (newdecl,
"library function `%s' declared as non-function");
else if (DECL_BUILT_IN_NONANSI (olddecl))
warning_with_decl (newdecl,
"built-in function `%s' declared as non-function");
else
warning_with_decl (newdecl,
"built-in function `%s' declared as non-function");
}
else
{
error_with_decl (newdecl, "`%s' redeclared as different kind of symbol");
error_with_decl (olddecl, "previous declaration of `%s'");
}
return 0;
}
if (types_match && TREE_CODE (newdecl) == PARM_DECL
&& TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
return 1;
if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL
&& IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl
&& DECL_INITIAL (olddecl) == 0)
;
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_BUILT_IN (olddecl))
{
if (!TREE_PUBLIC (newdecl))
{
if (warn_shadow)
warning_with_decl (newdecl, "shadowing built-in function `%s'");
return 0;
}
else if (!types_match)
{
tree oldreturntype = TREE_TYPE (oldtype);
tree newreturntype = TREE_TYPE (newtype);
if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
else
{
push_obstacks_nochange ();
end_temporary_allocation ();
}
if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
{
tree trytype
= build_function_type (newreturntype,
TYPE_ARG_TYPES (oldtype));
types_match = comptypes (newtype, trytype);
if (types_match)
oldtype = trytype;
}
if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0
&& TYPE_ARG_TYPES (oldtype) != 0
&& TREE_VALUE (TYPE_ARG_TYPES (newtype)) != 0
&& TREE_VALUE (TYPE_ARG_TYPES (oldtype)) != 0
&& (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (newtype)))
== TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (oldtype)))))
{
tree trytype
= build_function_type (TREE_TYPE (oldtype),
tree_cons (NULL_TREE,
TREE_VALUE (TYPE_ARG_TYPES (newtype)),
TREE_CHAIN (TYPE_ARG_TYPES (oldtype))));
types_match = comptypes (newtype, trytype);
if (types_match)
oldtype = trytype;
}
if (! different_binding_level)
TREE_TYPE (olddecl) = oldtype;
pop_obstacks ();
}
if (!types_match)
{
warning_with_decl (newdecl, "conflicting types for built-in function `%s'");
return 0;
}
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_SOURCE_LINE (olddecl) == 0)
{
if (!TREE_PUBLIC (newdecl))
{
return 0;
}
else if (!types_match)
{
TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
}
}
else if (!types_match
&& TREE_CODE (olddecl) == FUNCTION_DECL
&& TREE_CODE (newdecl) == FUNCTION_DECL
&& TREE_CODE (TREE_TYPE (oldtype)) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (newtype)) == POINTER_TYPE
&& (DECL_IN_SYSTEM_HEADER (olddecl)
|| DECL_IN_SYSTEM_HEADER (newdecl))
&& ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (newtype))) == void_type_node
&& TYPE_ARG_TYPES (oldtype) == 0
&& self_promoting_args_p (TYPE_ARG_TYPES (newtype))
&& TREE_TYPE (TREE_TYPE (oldtype)) == char_type_node)
||
(TREE_TYPE (TREE_TYPE (newtype)) == char_type_node
&& TYPE_ARG_TYPES (newtype) == 0
&& self_promoting_args_p (TYPE_ARG_TYPES (oldtype))
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)))
{
if (pedantic)
pedwarn_with_decl (newdecl, "conflicting types for `%s'");
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)
TREE_TYPE (newdecl) = newtype = oldtype;
DECL_IN_SYSTEM_HEADER (newdecl) = 1;
}
else if (!types_match
&& ! (TREE_CODE (olddecl) == FUNCTION_DECL
&& ! pedantic
&& comptypes (TREE_TYPE (oldtype),
TREE_TYPE (newtype))
&& TYPE_ARG_TYPES (newtype) == 0))
{
error_with_decl (newdecl, "conflicting types for `%s'");
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& comptypes (TREE_TYPE (oldtype),
TREE_TYPE (newtype))
&& ((TYPE_ARG_TYPES (oldtype) == 0
&& DECL_INITIAL (olddecl) == 0)
||
(TYPE_ARG_TYPES (newtype) == 0
&& DECL_INITIAL (newdecl) == 0)))
{
register tree t = TYPE_ARG_TYPES (oldtype);
if (t == 0)
t = TYPE_ARG_TYPES (newtype);
for (; t; t = TREE_CHAIN (t))
{
register tree type = TREE_VALUE (t);
if (TREE_CHAIN (t) == 0
&& TYPE_MAIN_VARIANT (type) != void_type_node)
{
error ("A parameter list with an ellipsis can't match an empty parameter name list declaration.");
break;
}
if (TYPE_MAIN_VARIANT (type) == float_type_node
|| C_PROMOTING_INTEGER_TYPE_P (type))
{
error ("An argument type that has a default promotion can't match an empty parameter name list declaration.");
break;
}
}
}
error_with_decl (olddecl, "previous declaration of `%s'");
}
else
{
errmsg = redeclaration_error_message (newdecl, olddecl);
if (errmsg)
{
switch (errmsg)
{
case 1:
error_with_decl (newdecl, "redefinition of `%s'");
break;
case 2:
error_with_decl (newdecl, "redeclaration of `%s'");
break;
case 3:
error_with_decl (newdecl, "conflicting declarations of `%s'");
break;
default:
abort ();
}
error_with_decl (olddecl,
((DECL_INITIAL (olddecl)
&& current_binding_level == global_binding_level)
? "`%s' previously defined here"
: "`%s' previously declared here"));
}
else if (TREE_CODE (newdecl) == TYPE_DECL
&& (DECL_IN_SYSTEM_HEADER (olddecl)
|| DECL_IN_SYSTEM_HEADER (newdecl)))
{
warning_with_decl (newdecl, "redefinition of `%s'");
warning_with_decl
(olddecl,
((DECL_INITIAL (olddecl)
&& current_binding_level == global_binding_level)
? "`%s' previously defined here"
: "`%s' previously declared here"));
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_INITIAL (olddecl) != 0
&& TYPE_ARG_TYPES (oldtype) == 0
&& TYPE_ARG_TYPES (newtype) != 0
&& TYPE_ACTUAL_ARG_TYPES (oldtype) != 0)
{
register tree type, parm;
register int nargs;
for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype),
type = TYPE_ARG_TYPES (newtype),
nargs = 1;
;
parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++)
{
if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
warning_with_decl (newdecl, "prototype for `%s' follows");
warning_with_decl (olddecl, "non-prototype definition here");
break;
}
if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
error_with_decl (newdecl, "prototype for `%s' follows and number of arguments doesn't match");
error_with_decl (olddecl, "non-prototype definition here");
errmsg = 1;
break;
}
if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type))
&& (! (flag_traditional
&& TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))
{
error_with_decl (newdecl,
"prototype for `%s' follows and argument %d doesn't match",
nargs);
error_with_decl (olddecl, "non-prototype definition here");
errmsg = 1;
break;
}
}
}
else
{
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl)
&& TREE_USED (olddecl))
warning_with_decl (newdecl,
"`%s' declared inline after being called");
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl)
&& DECL_INITIAL (olddecl) != 0)
warning_with_decl (newdecl,
"`%s' declared inline after its definition");
if ((pedantic || TREE_CODE (olddecl) == FUNCTION_DECL)
&& TREE_PUBLIC (olddecl)
&& !TREE_PUBLIC (newdecl))
warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
if (warn_traditional
&& TREE_CODE (olddecl) == FUNCTION_DECL
&& !TREE_PUBLIC (olddecl)
&& TREE_PUBLIC (newdecl))
warning_with_decl (newdecl, "non-static declaration for `%s' follows static");
if (TREE_CODE (olddecl) != FUNCTION_DECL
&& !TREE_READONLY (olddecl)
&& TREE_READONLY (newdecl))
warning_with_decl (newdecl, "const declaration for `%s' follows non-const");
else if (pedantic && TREE_CODE (olddecl) != FUNCTION_DECL
&& (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
|| TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))
pedwarn_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");
}
}
if (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0
&& !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0
&& DECL_INITIAL (olddecl) == 0)
&& !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
{
warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope");
warning_with_decl (olddecl, "previous declaration of `%s'");
}
if (types_match)
{
tree write_olddecl = different_binding_level ? newdecl : olddecl;
if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
else
{
push_obstacks_nochange ();
end_temporary_allocation ();
}
if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
{
if (different_binding_level)
TREE_TYPE (newdecl)
= build_type_attribute_variant
(newtype,
merge_attributes (TYPE_ATTRIBUTES (newtype),
TYPE_ATTRIBUTES (oldtype)));
else
TREE_TYPE (newdecl)
= TREE_TYPE (olddecl)
= common_type (newtype, oldtype);
}
if (oldtype != TREE_TYPE (newdecl))
{
if (TREE_TYPE (newdecl) != error_mark_node)
layout_type (TREE_TYPE (newdecl));
if (TREE_CODE (newdecl) != FUNCTION_DECL
&& TREE_CODE (newdecl) != TYPE_DECL
&& TREE_CODE (newdecl) != CONST_DECL)
layout_decl (newdecl, 0);
}
else
{
DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
if (TREE_CODE (olddecl) != FUNCTION_DECL)
if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
}
DECL_RTL (newdecl) = DECL_RTL (olddecl);
if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
&& !TREE_THIS_VOLATILE (newdecl))
TREE_THIS_VOLATILE (write_olddecl) = 0;
if (TREE_READONLY (newdecl))
TREE_READONLY (write_olddecl) = 1;
if (TREE_THIS_VOLATILE (newdecl))
{
TREE_THIS_VOLATILE (write_olddecl) = 1;
if (TREE_CODE (newdecl) == VAR_DECL)
make_var_volatile (newdecl);
}
if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0
&& ! different_binding_level)
{
DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
}
if (DECL_IN_SYSTEM_HEADER (olddecl))
DECL_IN_SYSTEM_HEADER (newdecl) = 1;
else if (DECL_IN_SYSTEM_HEADER (newdecl))
DECL_IN_SYSTEM_HEADER (write_olddecl) = 1;
if (DECL_INITIAL (newdecl) == 0 && ! different_binding_level)
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
DECL_NO_CHECK_MEMORY_USAGE (newdecl)
|= DECL_NO_CHECK_MEMORY_USAGE (olddecl);
}
pop_obstacks ();
}
else if (! different_binding_level)
{
TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
}
DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
if (! TREE_PUBLIC (olddecl))
TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
}
if (DECL_EXTERNAL (newdecl))
{
TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
if (! DECL_EXTERNAL (newdecl))
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
}
else
{
TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
}
if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
DECL_INLINE (olddecl) = 1;
DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
if (DECL_BUILT_IN (olddecl))
{
if (! types_match || new_is_definition)
{
if (! different_binding_level)
{
TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
DECL_BUILT_IN (olddecl) = 0;
}
}
else
{
DECL_BUILT_IN (newdecl) = 1;
DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
}
}
else if (! new_is_definition)
DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
if (! new_is_definition)
{
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
if (! different_binding_level)
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
if (DECL_INLINE (newdecl))
DECL_ABSTRACT_ORIGIN (newdecl) = DECL_ORIGIN (olddecl);
}
}
if (different_binding_level)
{
if (TREE_CODE (newdecl) == FUNCTION_DECL)
DECL_IGNORED_P (newdecl) = 1;
else
TREE_ASM_WRITTEN (newdecl) = DECL_IGNORED_P (newdecl) = 1;
return 0;
}
#if defined (_WIN32) && defined (NEXT_PDO)
DECL_DLLIMPORT(newdecl) = DECL_DLLIMPORT(olddecl);
#endif
{
register unsigned olddecl_uid = DECL_UID (olddecl);
bcopy ((char *) newdecl + sizeof (struct tree_common),
(char *) olddecl + sizeof (struct tree_common),
sizeof (struct tree_decl) - sizeof (struct tree_common));
DECL_UID (olddecl) = olddecl_uid;
}
DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl);
return 1;
}
tree
pushdecl (x)
tree x;
{
register tree t;
register tree name = DECL_NAME (x);
register struct binding_level *b = current_binding_level;
DECL_CONTEXT (x) = current_function_decl;
if (TREE_CODE (x) == FUNCTION_DECL && DECL_INITIAL (x) == 0
&& DECL_EXTERNAL (x))
DECL_CONTEXT (x) = 0;
if (warn_nested_externs && DECL_EXTERNAL (x) && b != global_binding_level
&& x != IDENTIFIER_IMPLICIT_DECL (name)
&& !DECL_IN_SYSTEM_HEADER (x))
warning ("nested extern declaration of `%s'", IDENTIFIER_POINTER (name));
if (name)
{
char *file;
int line;
int different_binding_level = 0;
t = lookup_name_current_level (name);
if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
{
t = IDENTIFIER_GLOBAL_VALUE (name);
if (t && TREE_CODE (t) == TYPE_DECL)
t = 0;
different_binding_level = 1;
}
if (t != 0 && t == error_mark_node)
{
t = 0;
error_with_decl (x, "`%s' used prior to declaration");
}
if (t != 0)
{
file = DECL_SOURCE_FILE (t);
line = DECL_SOURCE_LINE (t);
}
if (! flag_traditional && TREE_PUBLIC (name)
&& ! TREE_PUBLIC (x)
&& (TREE_CODE (x) == FUNCTION_DECL || b == global_binding_level)
&& IDENTIFIER_IMPLICIT_DECL (name) != 0)
{
pedwarn ("`%s' was declared implicitly `extern' and later `static'",
IDENTIFIER_POINTER (name));
pedwarn_with_file_and_line
(DECL_SOURCE_FILE (IDENTIFIER_IMPLICIT_DECL (name)),
DECL_SOURCE_LINE (IDENTIFIER_IMPLICIT_DECL (name)),
"previous declaration of `%s'",
IDENTIFIER_POINTER (name));
TREE_THIS_VOLATILE (name) = 1;
}
if (t != 0 && duplicate_decls (x, t, different_binding_level))
{
if (TREE_CODE (t) == PARM_DECL)
{
TREE_ASM_WRITTEN (t) = TREE_ASM_WRITTEN (x);
return t;
}
return t;
}
if (TREE_CODE (x) == TYPE_DECL)
{
if (DECL_SOURCE_LINE (x) == 0)
{
if (TYPE_NAME (TREE_TYPE (x)) == 0)
TYPE_NAME (TREE_TYPE (x)) = x;
}
else if (TREE_TYPE (x) != error_mark_node
&& DECL_ORIGINAL_TYPE (x) == NULL_TREE)
{
tree tt = TREE_TYPE (x);
DECL_ORIGINAL_TYPE (x) = tt;
tt = build_type_copy (tt);
TYPE_NAME (tt) = x;
TREE_TYPE (x) = tt;
}
}
if (TREE_PUBLIC (x) && ! DECL_INLINE (x))
{
tree decl;
if (flag_traditional && IDENTIFIER_GLOBAL_VALUE (name) != 0
&& (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name))
|| TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))))
decl = IDENTIFIER_GLOBAL_VALUE (name);
else if (IDENTIFIER_LIMBO_VALUE (name) != 0)
decl = IDENTIFIER_LIMBO_VALUE (name);
else
decl = 0;
if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl))
&& !DECL_BUILT_IN (decl))
{
pedwarn_with_decl (x,
"type mismatch with previous external decl");
pedwarn_with_decl (decl, "previous external decl of `%s'");
}
}
if (IDENTIFIER_IMPLICIT_DECL (name) != 0
&& IDENTIFIER_GLOBAL_VALUE (name) == 0
&& TREE_CODE (x) == FUNCTION_DECL
&& ! comptypes (TREE_TYPE (x),
TREE_TYPE (IDENTIFIER_IMPLICIT_DECL (name))))
{
warning_with_decl (x, "type mismatch with previous implicit declaration");
warning_with_decl (IDENTIFIER_IMPLICIT_DECL (name),
"previous implicit declaration of `%s'");
}
if (flag_traditional && DECL_EXTERNAL (x)
&& lookup_name (name) == 0)
{
tree type = TREE_TYPE (x);
while (type)
{
if (type == error_mark_node)
break;
if (! TREE_PERMANENT (type))
{
warning_with_decl (x, "type of external `%s' is not global");
break;
}
else if (TREE_CODE (type) == FUNCTION_TYPE
&& TYPE_ARG_TYPES (type) != 0)
break;
type = TREE_TYPE (type);
}
if (type == 0)
b = global_binding_level;
}
if (b == global_binding_level)
{
if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x))
TREE_PUBLIC (name) = 1;
IDENTIFIER_GLOBAL_VALUE (name) = x;
IDENTIFIER_LIMBO_VALUE (name) = 0;
if (IDENTIFIER_IMPLICIT_DECL (name)
&& TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
TREE_USED (x) = 1, TREE_USED (name) = 1;
if (IDENTIFIER_IMPLICIT_DECL (name)
&& TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
TREE_ADDRESSABLE (x) = 1;
if (IDENTIFIER_IMPLICIT_DECL (name) != 0
&& ! (TREE_CODE (x) == FUNCTION_DECL
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (x)))
== integer_type_node)))
pedwarn ("`%s' was previously implicitly declared to return `int'",
IDENTIFIER_POINTER (name));
if (TREE_PUBLIC (name)
&& ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x))
{
if (t != 0 && DECL_BUILT_IN (t))
;
else if (t != 0 && DECL_BUILT_IN_NONANSI (t))
;
else if (TREE_CODE (x) == TYPE_DECL)
;
else if (IDENTIFIER_IMPLICIT_DECL (name))
{
if (! TREE_THIS_VOLATILE (name))
pedwarn ("`%s' was declared implicitly `extern' and later `static'",
IDENTIFIER_POINTER (name));
}
else
pedwarn ("`%s' was declared `extern' and later `static'",
IDENTIFIER_POINTER (name));
}
}
else
{
tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
IDENTIFIER_LOCAL_VALUE (name) = x;
if (oldlocal == 0
&& DECL_EXTERNAL (x) && !DECL_INLINE (x)
&& oldglobal != 0
&& TREE_CODE (x) == FUNCTION_DECL
&& TREE_CODE (oldglobal) == FUNCTION_DECL)
{
if (! comptypes (TREE_TYPE (x),
TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name))))
pedwarn_with_decl (x, "extern declaration of `%s' doesn't match global one");
else
{
if (DECL_INLINE (oldglobal))
{
DECL_INLINE (x) = DECL_INLINE (oldglobal);
DECL_INITIAL (x) = (current_function_decl == oldglobal
? 0 : DECL_INITIAL (oldglobal));
DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal);
DECL_FRAME_SIZE (x) = DECL_FRAME_SIZE (oldglobal);
DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
DECL_RESULT (x) = DECL_RESULT (oldglobal);
TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
DECL_ABSTRACT_ORIGIN (x) = DECL_ABSTRACT_ORIGIN (oldglobal);
}
if (DECL_BUILT_IN (oldglobal))
{
DECL_BUILT_IN (x) = DECL_BUILT_IN (oldglobal);
DECL_FUNCTION_CODE (x) = DECL_FUNCTION_CODE (oldglobal);
}
if (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0
&& DECL_INITIAL (oldglobal)
&& TYPE_ARG_TYPES (TREE_TYPE (x)) == 0)
TREE_TYPE (x) = TREE_TYPE (oldglobal);
}
}
#if 0
if (oldlocal == 0 && oldglobal != 0
&& !TREE_PUBLIC (oldglobal)
&& DECL_EXTERNAL (x) && TREE_PUBLIC (x))
warning ("`%s' locally external but globally static",
IDENTIFIER_POINTER (name));
#endif
if (oldlocal == 0
&& DECL_EXTERNAL (x)
&& TREE_PUBLIC (x))
{
if (oldglobal == 0)
TREE_PUBLIC (name) = 1;
if (IDENTIFIER_LIMBO_VALUE (name) == 0)
IDENTIFIER_LIMBO_VALUE (name) = x;
}
if (oldlocal != 0 && !DECL_EXTERNAL (x)
&& ! current_binding_level->parm_flag
&& current_binding_level->level_chain->parm_flag
&& chain_member (oldlocal, current_binding_level->level_chain->names))
{
if (TREE_CODE (oldlocal) == PARM_DECL)
pedwarn ("declaration of `%s' shadows a parameter",
IDENTIFIER_POINTER (name));
else
pedwarn ("declaration of `%s' shadows a symbol from the parameter list",
IDENTIFIER_POINTER (name));
}
else if (warn_shadow && !DECL_EXTERNAL (x)
&& DECL_SOURCE_LINE (x) != 0
&& ! DECL_FROM_INLINE (x))
{
char *id = IDENTIFIER_POINTER (name);
if (TREE_CODE (x) == PARM_DECL
&& current_binding_level->level_chain->parm_flag)
;
else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL)
warning ("declaration of `%s' shadows a parameter", id);
else if (oldlocal != 0)
warning ("declaration of `%s' shadows previous local", id);
else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
&& IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
warning ("declaration of `%s' shadows global declaration", id);
}
if (oldlocal != 0)
b->shadowed = tree_cons (name, oldlocal, b->shadowed);
}
if (TYPE_SIZE (TREE_TYPE (x)) == 0)
b->incomplete_list = tree_cons (NULL_TREE, x, b->incomplete_list);
}
TREE_CHAIN (x) = b->names;
b->names = x;
return x;
}
tree
pushdecl_top_level (x)
tree x;
{
register tree t;
register struct binding_level *b = current_binding_level;
#ifdef NEXT_SEMANTICS
register tree function_decl = current_function_decl;
#endif
current_binding_level = global_binding_level;
#ifdef NEXT_SEMANTICS
current_function_decl = 0;
#endif
t = pushdecl (x);
current_binding_level = b;
#ifdef NEXT_SEMANTICS
current_function_decl = function_decl;
#endif
return t;
}
tree
implicitly_declare (functionid)
tree functionid;
{
register tree decl;
int traditional_warning = 0;
int implicit_warning;
push_obstacks_nochange ();
end_temporary_allocation ();
decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
if (TREE_PUBLIC (functionid) && IDENTIFIER_GLOBAL_VALUE (functionid) == 0)
traditional_warning = 1;
implicit_warning = (IDENTIFIER_IMPLICIT_DECL (functionid) == 0);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
IDENTIFIER_IMPLICIT_DECL (functionid) = decl;
pushdecl (decl);
maybe_objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL_PTR, 0, 0);
if (mesg_implicit_function_declaration && implicit_warning)
{
if (mesg_implicit_function_declaration == 2)
error ("implicit declaration of function `%s'",
IDENTIFIER_POINTER (functionid));
else
warning ("implicit declaration of function `%s'",
IDENTIFIER_POINTER (functionid));
}
else if (warn_traditional && traditional_warning)
warning ("function `%s' was previously declared within a block",
IDENTIFIER_POINTER (functionid));
gen_aux_info_record (decl, 0, 1, 0);
pop_obstacks ();
return decl;
}
static int
redeclaration_error_message (newdecl, olddecl)
tree newdecl, olddecl;
{
if (TREE_CODE (newdecl) == TYPE_DECL)
{
if (flag_traditional && TREE_TYPE (newdecl) == TREE_TYPE (olddecl))
return 0;
if (flag_traditional
&& TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)) == TREE_TYPE (newdecl))
return 0;
if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
return 0;
return 1;
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
&& !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl)
&& !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl))))
return 1;
return 0;
}
else if (current_binding_level == global_binding_level)
{
if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
return 0;
if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0)
return 1;
if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
return 3;
return 0;
}
else if (current_binding_level->parm_flag
&& TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
return 0;
else
{
if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))
&& DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl))
return 2;
return 0;
}
}
tree
lookup_label (id)
tree id;
{
register tree decl = IDENTIFIER_LABEL_VALUE (id);
if (current_function_decl == 0)
{
error ("label %s referenced outside of any function",
IDENTIFIER_POINTER (id));
return 0;
}
if (decl != 0)
{
if (DECL_CONTEXT (decl) != current_function_decl
&& ! C_DECLARED_LABEL_FLAG (decl))
return shadow_label (id);
return decl;
}
decl = build_decl (LABEL_DECL, id, void_type_node);
label_rtx (decl);
DECL_CONTEXT (decl) = current_function_decl;
DECL_MODE (decl) = VOIDmode;
DECL_SOURCE_LINE (decl) = lineno;
DECL_SOURCE_FILE (decl) = input_filename;
IDENTIFIER_LABEL_VALUE (id) = decl;
named_labels = tree_cons (NULL_TREE, decl, named_labels);
return decl;
}
tree
shadow_label (name)
tree name;
{
register tree decl = IDENTIFIER_LABEL_VALUE (name);
if (decl != 0)
{
register tree dup;
for (dup = named_labels; dup; dup = TREE_CHAIN (dup))
if (TREE_VALUE (dup) == decl)
{
error ("duplicate label declaration `%s'",
IDENTIFIER_POINTER (name));
error_with_decl (TREE_VALUE (dup),
"this is a previous declaration");
return lookup_label (name);
}
shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
IDENTIFIER_LABEL_VALUE (name) = decl = 0;
}
return lookup_label (name);
}
tree
define_label (filename, line, name)
char *filename;
int line;
tree name;
{
tree decl = lookup_label (name);
if (decl != 0 && DECL_CONTEXT (decl) != current_function_decl)
{
shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
IDENTIFIER_LABEL_VALUE (name) = 0;
decl = lookup_label (name);
}
if (DECL_INITIAL (decl) != 0)
{
error ("duplicate label `%s'", IDENTIFIER_POINTER (name));
return 0;
}
else
{
DECL_INITIAL (decl) = error_mark_node;
DECL_SOURCE_FILE (decl) = filename;
DECL_SOURCE_LINE (decl) = line;
return decl;
}
}
tree
getdecls ()
{
return current_binding_level->names;
}
tree
gettags ()
{
return current_binding_level->tags;
}
static void
storedecls (decls)
tree decls;
{
current_binding_level->names = decls;
}
static void
storetags (tags)
tree tags;
{
current_binding_level->tags = tags;
}
static tree
lookup_tag (code, name, binding_level, thislevel_only)
enum tree_code code;
struct binding_level *binding_level;
tree name;
int thislevel_only;
{
register struct binding_level *level;
for (level = binding_level; level; level = level->level_chain)
{
register tree tail;
for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
{
if (TREE_PURPOSE (tail) == name)
{
if (TREE_CODE (TREE_VALUE (tail)) != code)
{
pending_invalid_xref = name;
pending_invalid_xref_file = input_filename;
pending_invalid_xref_line = lineno;
}
return TREE_VALUE (tail);
}
}
if (thislevel_only && ! level->tag_transparent)
return NULL_TREE;
}
return NULL_TREE;
}
void
pending_xref_error ()
{
if (pending_invalid_xref != 0)
error_with_file_and_line (pending_invalid_xref_file,
pending_invalid_xref_line,
"`%s' defined as wrong kind of tag",
IDENTIFIER_POINTER (pending_invalid_xref));
pending_invalid_xref = 0;
}
static tree
lookup_tag_reverse (type)
tree type;
{
register struct binding_level *level;
for (level = current_binding_level; level; level = level->level_chain)
{
register tree tail;
for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
{
if (TREE_VALUE (tail) == type)
return TREE_PURPOSE (tail);
}
}
return NULL_TREE;
}
tree
lookup_name (name)
tree name;
{
register tree val;
if (current_binding_level != global_binding_level
&& IDENTIFIER_LOCAL_VALUE (name))
val = IDENTIFIER_LOCAL_VALUE (name);
else
val = IDENTIFIER_GLOBAL_VALUE (name);
return val;
}
tree
lookup_name_current_level (name)
tree name;
{
register tree t;
if (current_binding_level == global_binding_level)
return IDENTIFIER_GLOBAL_VALUE (name);
if (IDENTIFIER_LOCAL_VALUE (name) == 0)
return 0;
for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
if (DECL_NAME (t) == name)
break;
return t;
}
void
init_decl_processing ()
{
register tree endlink;
tree traditional_ptr_type_node;
tree memcpy_ftype, memset_ftype, strlen_ftype;
tree void_ftype_any, ptr_ftype_void, ptr_ftype_ptr;
int wchar_type_size;
tree temp;
tree array_domain_type;
current_function_decl = NULL;
named_labels = NULL;
current_binding_level = NULL_BINDING_LEVEL;
free_binding_level = NULL_BINDING_LEVEL;
pushlevel (0);
global_binding_level = current_binding_level;
integer_type_node = make_signed_type (INT_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_INT],
integer_type_node));
char_type_node
= (flag_signed_char
? make_signed_type (CHAR_TYPE_SIZE)
: make_unsigned_type (CHAR_TYPE_SIZE));
pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
char_type_node));
long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
long_integer_type_node));
unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
unsigned_type_node));
long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
long_unsigned_type_node));
long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
long_long_integer_type_node));
long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
long_long_unsigned_type_node));
short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
short_integer_type_node));
short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
short_unsigned_type_node));
set_sizetype
(TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
if (flag_traditional && TREE_UNSIGNED (sizetype))
set_sizetype (signed_type (sizetype));
ptrdiff_type_node
= TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
error_mark_node = make_node (ERROR_MARK);
TREE_TYPE (error_mark_node) = error_mark_node;
signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
signed_char_type_node));
unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
unsigned_char_type_node));
intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node));
intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node));
#endif
unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node));
#endif
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_FLOAT],
float_type_node));
layout_type (float_type_node);
double_type_node = make_node (REAL_TYPE);
if (flag_short_double)
TYPE_PRECISION (double_type_node) = FLOAT_TYPE_SIZE;
else
TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_DOUBLE],
double_type_node));
layout_type (double_type_node);
long_double_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
long_double_type_node));
layout_type (long_double_type_node);
complex_integer_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
complex_integer_type_node));
TREE_TYPE (complex_integer_type_node) = integer_type_node;
layout_type (complex_integer_type_node);
complex_float_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
complex_float_type_node));
TREE_TYPE (complex_float_type_node) = float_type_node;
layout_type (complex_float_type_node);
complex_double_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
complex_double_type_node));
TREE_TYPE (complex_double_type_node) = double_type_node;
layout_type (complex_double_type_node);
complex_long_double_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
complex_long_double_type_node));
TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
layout_type (complex_long_double_type_node);
vector_unsigned_char_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_unsigned_char_type_node) = unsigned_char_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector unsigned char"),
vector_unsigned_char_type_node));
layout_type (vector_unsigned_char_type_node);
vector_signed_char_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_signed_char_type_node) = signed_char_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector signed char"),
vector_signed_char_type_node));
layout_type (vector_signed_char_type_node);
vector_boolean_char_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_boolean_char_type_node) = unsigned_char_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector bool char"),
vector_boolean_char_type_node));
layout_type (vector_boolean_char_type_node);
vector_unsigned_short_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_unsigned_short_type_node) = short_unsigned_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector unsigned short"),
vector_unsigned_short_type_node));
layout_type (vector_unsigned_short_type_node);
vector_signed_short_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_signed_short_type_node) = short_integer_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector signed short"),
vector_signed_short_type_node));
layout_type (vector_signed_short_type_node);
vector_boolean_short_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_boolean_short_type_node) = short_unsigned_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector bool short"),
vector_boolean_short_type_node));
layout_type (vector_boolean_short_type_node);
vector_unsigned_long_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_unsigned_long_type_node) = long_unsigned_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector unsigned long"),
vector_unsigned_long_type_node));
layout_type (vector_unsigned_long_type_node);
vector_signed_long_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_signed_long_type_node) = long_integer_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector signed long"),
vector_signed_long_type_node));
layout_type (vector_signed_long_type_node);
vector_boolean_long_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_boolean_long_type_node) = long_unsigned_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector bool long"),
vector_boolean_long_type_node));
layout_type (vector_boolean_long_type_node);
vector_float_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_float_type_node) = float_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector float"),
vector_float_type_node));
layout_type (vector_float_type_node);
vector_pixel_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (vector_pixel_type_node) = short_unsigned_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__vector pixel"),
vector_pixel_type_node));
layout_type (vector_pixel_type_node);
wchar_type_node
= TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WCHAR_TYPE)));
wchar_type_size = TYPE_PRECISION (wchar_type_node);
signed_wchar_type_node = signed_type (wchar_type_node);
unsigned_wchar_type_node = unsigned_type (wchar_type_node);
integer_zero_node = build_int_2 (0, 0);
TREE_TYPE (integer_zero_node) = integer_type_node;
integer_one_node = build_int_2 (1, 0);
TREE_TYPE (integer_one_node) = integer_type_node;
boolean_type_node = integer_type_node;
boolean_true_node = integer_one_node;
boolean_false_node = integer_zero_node;
size_zero_node = build_int_2 (0, 0);
TREE_TYPE (size_zero_node) = sizetype;
size_one_node = build_int_2 (1, 0);
TREE_TYPE (size_one_node) = sizetype;
void_type_node = make_node (VOID_TYPE);
pushdecl (build_decl (TYPE_DECL,
ridpointers[(int) RID_VOID], void_type_node));
layout_type (void_type_node);
TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
null_pointer_node = build_int_2 (0, 0);
TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node);
layout_type (TREE_TYPE (null_pointer_node));
string_type_node = build_pointer_type (char_type_node);
const_string_type_node
= build_pointer_type (build_type_variant (char_type_node, 1, 0));
array_domain_type = build_index_type (build_int_2 (200, 0));
char_array_type_node
= build_array_type (char_type_node, array_domain_type);
#ifdef PASCAL_STRINGS
unsigned_char_array_type_node
= build_array_type (unsigned_char_type_node, array_domain_type);
#endif
int_array_type_node
= build_array_type (integer_type_node, array_domain_type);
wchar_array_type_node
= build_array_type (wchar_type_node, array_domain_type);
default_function_type
= build_function_type (integer_type_node, NULL_TREE);
ptr_type_node = build_pointer_type (void_type_node);
const_ptr_type_node
= build_pointer_type (build_type_variant (void_type_node, 1, 0));
endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
void_ftype_any
= build_function_type (void_type_node, NULL_TREE);
float_ftype_float
= build_function_type (float_type_node,
tree_cons (NULL_TREE, float_type_node, endlink));
double_ftype_double
= build_function_type (double_type_node,
tree_cons (NULL_TREE, double_type_node, endlink));
ldouble_ftype_ldouble
= build_function_type (long_double_type_node,
tree_cons (NULL_TREE, long_double_type_node,
endlink));
double_ftype_double_double
= build_function_type (double_type_node,
tree_cons (NULL_TREE, double_type_node,
tree_cons (NULL_TREE,
double_type_node, endlink)));
int_ftype_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, integer_type_node, endlink));
long_ftype_long
= build_function_type (long_integer_type_node,
tree_cons (NULL_TREE,
long_integer_type_node, endlink));
void_ftype_ptr_ptr_int
= build_function_type (void_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
int_ftype_cptr_cptr_sizet
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, const_ptr_type_node,
tree_cons (NULL_TREE, const_ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink))));
void_ftype_ptr_int_int
= build_function_type (void_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
string_ftype_ptr_ptr
= build_function_type (string_type_node,
tree_cons (NULL_TREE, string_type_node,
tree_cons (NULL_TREE,
const_string_type_node,
endlink)));
int_ftype_string_string
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, const_string_type_node,
tree_cons (NULL_TREE,
const_string_type_node,
endlink)));
strlen_ftype
= build_function_type (flag_traditional ? integer_type_node : sizetype,
tree_cons (NULL_TREE, const_string_type_node,
endlink));
traditional_ptr_type_node
= (flag_traditional ? string_type_node : ptr_type_node);
memcpy_ftype
= build_function_type (traditional_ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, const_ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink))));
memset_ftype
= build_function_type (traditional_ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink))));
ptr_ftype_void = build_function_type (ptr_type_node, endlink);
ptr_ftype_ptr
= build_function_type (ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node, endlink));
builtin_function ("__builtin_constant_p", default_function_type,
BUILT_IN_CONSTANT_P, NULL_PTR);
builtin_function ("__builtin_return_address",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
unsigned_type_node,
endlink)),
BUILT_IN_RETURN_ADDRESS, NULL_PTR);
builtin_function ("__builtin_frame_address",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
unsigned_type_node,
endlink)),
BUILT_IN_FRAME_ADDRESS, NULL_PTR);
builtin_function ("__builtin_aggregate_incoming_address",
build_function_type (ptr_type_node, NULL_TREE),
BUILT_IN_AGGREGATE_INCOMING_ADDRESS, NULL_PTR);
builtin_function ("__builtin_unwind_init",
build_function_type (void_type_node, endlink),
BUILT_IN_UNWIND_INIT, NULL_PTR);
builtin_function ("__builtin_dwarf_cfa", ptr_ftype_void,
BUILT_IN_DWARF_CFA, NULL_PTR);
builtin_function ("__builtin_dwarf_fp_regnum",
build_function_type (unsigned_type_node, endlink),
BUILT_IN_DWARF_FP_REGNUM, NULL_PTR);
builtin_function ("__builtin_dwarf_reg_size", int_ftype_int,
BUILT_IN_DWARF_REG_SIZE, NULL_PTR);
builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr,
BUILT_IN_FROB_RETURN_ADDR, NULL_PTR);
builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr,
BUILT_IN_EXTRACT_RETURN_ADDR, NULL_PTR);
builtin_function
("__builtin_eh_return",
build_function_type (void_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE,
type_for_mode (ptr_mode, 0),
tree_cons (NULL_TREE,
ptr_type_node,
endlink)))),
BUILT_IN_EH_RETURN, NULL_PTR);
builtin_function ("__builtin_alloca",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink)),
BUILT_IN_ALLOCA, "alloca");
builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR);
if (! flag_no_builtin && !flag_no_nonansi_builtin)
{
temp = builtin_function ("alloca",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink)),
BUILT_IN_ALLOCA, NULL_PTR);
DECL_BUILT_IN_NONANSI (temp) = 1;
temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR);
DECL_BUILT_IN_NONANSI (temp) = 1;
temp = builtin_function ("_exit", void_ftype_any, NOT_BUILT_IN,
NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
DECL_BUILT_IN_NONANSI (temp) = 1;
}
builtin_function ("__builtin_abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR);
builtin_function ("__builtin_fabsf", float_ftype_float, BUILT_IN_FABS,
NULL_PTR);
builtin_function ("__builtin_fabs", double_ftype_double, BUILT_IN_FABS,
NULL_PTR);
builtin_function ("__builtin_fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS,
NULL_PTR);
builtin_function ("__builtin_labs", long_ftype_long, BUILT_IN_LABS,
NULL_PTR);
builtin_function ("__builtin_saveregs",
build_function_type (ptr_type_node, NULL_TREE),
BUILT_IN_SAVEREGS, NULL_PTR);
#if 0
builtin_function ("__builtin_varargs",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink)),
BUILT_IN_VARARGS, NULL_PTR);
#endif
builtin_function ("__builtin_classify_type", default_function_type,
BUILT_IN_CLASSIFY_TYPE, NULL_PTR);
builtin_function ("__builtin_next_arg",
build_function_type (ptr_type_node, NULL_TREE),
BUILT_IN_NEXT_ARG, NULL_PTR);
builtin_function ("__builtin_args_info",
build_function_type (integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink)),
BUILT_IN_ARGS_INFO, NULL_PTR);
builtin_function ("__builtin_apply_args",
build_function_type (ptr_type_node, NULL_TREE),
BUILT_IN_APPLY_ARGS, NULL_PTR);
temp = tree_cons (NULL_TREE,
build_pointer_type (build_function_type (void_type_node,
NULL_TREE)),
tree_cons (NULL_TREE,
ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink)));
builtin_function ("__builtin_apply",
build_function_type (ptr_type_node, temp),
BUILT_IN_APPLY, NULL_PTR);
builtin_function ("__builtin_return",
build_function_type (void_type_node,
tree_cons (NULL_TREE,
ptr_type_node,
endlink)),
BUILT_IN_RETURN, NULL_PTR);
builtin_function ("__builtin_memcpy", memcpy_ftype,
BUILT_IN_MEMCPY, "memcpy");
builtin_function ("__builtin_memcmp", int_ftype_cptr_cptr_sizet,
BUILT_IN_MEMCMP, "memcmp");
builtin_function ("__builtin_memset", memset_ftype,
BUILT_IN_MEMSET, "memset");
builtin_function ("__builtin_strcmp", int_ftype_string_string,
BUILT_IN_STRCMP, "strcmp");
builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr,
BUILT_IN_STRCPY, "strcpy");
builtin_function ("__builtin_strlen", strlen_ftype,
BUILT_IN_STRLEN, "strlen");
builtin_function ("__builtin_sqrtf", float_ftype_float,
BUILT_IN_FSQRT, "sqrtf");
builtin_function ("__builtin_fsqrt", double_ftype_double,
BUILT_IN_FSQRT, "sqrt");
builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
BUILT_IN_FSQRT, "sqrtl");
builtin_function ("__builtin_sinf", float_ftype_float,
BUILT_IN_SIN, "sinf");
builtin_function ("__builtin_sin", double_ftype_double,
BUILT_IN_SIN, "sin");
builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
BUILT_IN_SIN, "sinl");
builtin_function ("__builtin_cosf", float_ftype_float,
BUILT_IN_COS, "cosf");
builtin_function ("__builtin_cos", double_ftype_double,
BUILT_IN_COS, "cos");
builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
BUILT_IN_COS, "cosl");
builtin_function ("__builtin_setjmp",
build_function_type (integer_type_node,
tree_cons (NULL_TREE,
ptr_type_node, endlink)),
BUILT_IN_SETJMP, NULL_PTR);
builtin_function ("__builtin_longjmp",
build_function_type
(void_type_node,
tree_cons (NULL, ptr_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))),
BUILT_IN_LONGJMP, NULL_PTR);
builtin_function ("__builtin_trap",
build_function_type (void_type_node, endlink),
BUILT_IN_TRAP, NULL_PTR);
if (!flag_no_builtin)
{
builtin_function ("abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR);
builtin_function ("fabsf", float_ftype_float, BUILT_IN_FABS, NULL_PTR);
builtin_function ("fabs", double_ftype_double, BUILT_IN_FABS, NULL_PTR);
builtin_function ("fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS,
NULL_PTR);
builtin_function ("labs", long_ftype_long, BUILT_IN_LABS, NULL_PTR);
builtin_function ("memcpy", memcpy_ftype, BUILT_IN_MEMCPY, NULL_PTR);
builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP,
NULL_PTR);
builtin_function ("memset", memset_ftype, BUILT_IN_MEMSET, NULL_PTR);
builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP,
NULL_PTR);
builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY,
NULL_PTR);
builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN, NULL_PTR);
builtin_function ("sqrtf", float_ftype_float, BUILT_IN_FSQRT, NULL_PTR);
builtin_function ("sqrt", double_ftype_double, BUILT_IN_FSQRT, NULL_PTR);
builtin_function ("sqrtl", ldouble_ftype_ldouble, BUILT_IN_FSQRT,
NULL_PTR);
builtin_function ("sinf", float_ftype_float, BUILT_IN_SIN, NULL_PTR);
builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR);
builtin_function ("sinl", ldouble_ftype_ldouble, BUILT_IN_SIN, NULL_PTR);
builtin_function ("cosf", float_ftype_float, BUILT_IN_COS, NULL_PTR);
builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR);
builtin_function ("cosl", ldouble_ftype_ldouble, BUILT_IN_COS, NULL_PTR);
temp = builtin_function ("abort", void_ftype_any, NOT_BUILT_IN,
NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
temp = builtin_function ("exit", void_ftype_any, NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
}
#if 0
builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, NULL_PTR);
builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, NULL_PTR);
builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR,
NULL_PTR);
builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL,
NULL_PTR);
builtin_function ("__builtin_fmod", double_ftype_double_double,
BUILT_IN_FMOD, NULL_PTR);
builtin_function ("__builtin_frem", double_ftype_double_double,
BUILT_IN_FREM, NULL_PTR);
builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP,
NULL_PTR);
builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN,
NULL_PTR);
#endif
#ifdef INIT_TARGET_INTRINSIC
INIT_TARGET_INTRINSIC (endlink);
#endif
pedantic_lvalues = pedantic;
declare_function_name ();
start_identifier_warnings ();
init_function_format_info ();
init_iterators ();
incomplete_decl_finalize_hook = finish_incomplete_decl;
lang_get_alias_set = c_get_alias_set;
}
tree
builtin_function (name, type, function_code, library_name)
const char *name;
tree type;
enum built_in_function function_code;
const char *library_name;
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
if (flag_traditional && name[0] != '_')
DECL_BUILT_IN_NONANSI (decl) = 1;
if (library_name)
DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
make_decl_rtl (decl, NULL_PTR, 1);
pushdecl (decl);
if (function_code != NOT_BUILT_IN)
{
DECL_BUILT_IN (decl) = 1;
DECL_FUNCTION_CODE (decl) = function_code;
}
if (name[0] != '_' || name[1] != '_')
C_DECL_ANTICIPATED (decl) = 1;
return decl;
}
tree
lang_builtin_function (name, type, function_code, library_name)
char *name;
tree type;
enum built_in_function function_code;
char *library_name;
{
tree decl = builtin_function (name, type, function_code, library_name);
C_DECL_ANTICIPATED (decl) = 0;
return decl;
}
int
lang_comptypes (t1, t2)
tree t1, t2;
{
return comptypes (t1, t2);
}
tree
lang_build_type_variant (type, constp, volatilep)
tree type;
int constp, volatilep;
{
return c_build_type_variant (type, constp, volatilep);
}
void
shadow_tag (declspecs)
tree declspecs;
{
shadow_tag_warned (declspecs, 0);
}
void
shadow_tag_warned (declspecs, warned)
tree declspecs;
int warned;
{
int found_tag = 0;
register tree link;
tree specs, attrs;
pending_invalid_xref = 0;
split_specs_attrs (declspecs, &specs, &attrs);
for (link = specs; link; link = TREE_CHAIN (link))
{
register tree value = TREE_VALUE (link);
register enum tree_code code = TREE_CODE (value);
if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
{
register tree name = lookup_tag_reverse (value);
register tree t;
found_tag++;
if (name == 0)
{
if (warned != 1 && code != ENUMERAL_TYPE)
{
pedwarn ("unnamed struct/union that defines no instances");
warned = 1;
}
}
else
{
t = lookup_tag (code, name, current_binding_level, 1);
if (t == 0)
{
t = make_node (code);
pushtag (name, t);
}
}
}
else
{
if (!warned && ! in_system_header)
{
warning ("useless keyword or type name in empty declaration");
warned = 2;
}
}
}
if (found_tag > 1)
error ("two types specified in one empty declaration");
if (warned != 1)
{
if (found_tag == 0)
pedwarn ("empty declaration");
}
}
tree
groktypename (typename)
tree typename;
{
if (TREE_CODE (typename) != TREE_LIST)
return typename;
return grokdeclarator (TREE_VALUE (typename),
TREE_PURPOSE (typename),
TYPENAME, 0);
}
tree
groktypename_in_parm_context (typename)
tree typename;
{
if (TREE_CODE (typename) != TREE_LIST)
return typename;
return grokdeclarator (TREE_VALUE (typename),
TREE_PURPOSE (typename),
PARM, 0);
}
void
gen_decl_index (declarator, declspecs)
tree declarator;
tree declspecs;
{
switch (TREE_CODE (declarator))
{
case FUNCTION_DECL:
dump_symbol_info ("+fh ", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
case CONST_DECL:
dump_symbol_info ("+nh ", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
case VAR_DECL:
dump_symbol_info ("+vm ", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
case TYPE_DECL:
dump_symbol_info ("+th ", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
default:
break;
}
}
void
dump_decl (declarator, declspecs)
tree declarator;
tree declspecs;
{
switch (TREE_CODE (declarator))
{
case FUNCTION_DECL:
printf ("+fh %s %u\n", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
case CONST_DECL:
printf ("+nh %s %u\n", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
case VAR_DECL:
printf ("+vm %s %u\n", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
case TYPE_DECL:
printf ("+th %s %u\n", IDENTIFIER_POINTER (DECL_NAME (declarator)),
DECL_SOURCE_LINE (declarator));
break;
default:
break;
}
}
int debug_temp_inits = 1;
tree
start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
tree declarator, declspecs;
int initialized;
tree attributes, prefix_attributes;
{
register tree decl = grokdeclarator (declarator, declspecs,
NORMAL, initialized);
register tree tem;
int init_written = initialized;
if (flag_dump_symbols)
dump_decl (decl, declspecs);
if (flag_gen_index)
gen_decl_index (decl, declspecs);
push_obstacks_nochange ();
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
&& !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "main"))
warning_with_decl (decl, "`%s' is usually a function");
if (initialized)
switch (TREE_CODE (decl))
{
case TYPE_DECL:
if (pedantic || list_length (declspecs) > 1)
{
error ("typedef `%s' is initialized",
IDENTIFIER_POINTER (DECL_NAME (decl)));
initialized = 0;
}
break;
case FUNCTION_DECL:
error ("function `%s' is initialized like a variable",
IDENTIFIER_POINTER (DECL_NAME (decl)));
initialized = 0;
break;
case PARM_DECL:
error ("parameter `%s' is initialized",
IDENTIFIER_POINTER (DECL_NAME (decl)));
initialized = 0;
break;
default:
if (TYPE_SIZE (TREE_TYPE (decl)) != 0)
{
if (TREE_CODE (TYPE_SIZE (TREE_TYPE (decl))) != INTEGER_CST
|| C_DECL_VARIABLE_SIZE (decl))
{
error ("variable-sized object may not be initialized");
initialized = 0;
}
}
else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
{
error ("variable `%s' has initializer but incomplete type",
IDENTIFIER_POINTER (DECL_NAME (decl)));
initialized = 0;
}
else if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))) == 0)
{
error ("elements of array `%s' have incomplete type",
IDENTIFIER_POINTER (DECL_NAME (decl)));
initialized = 0;
}
}
if (initialized)
{
#if 0
if (current_binding_level != global_binding_level
&& DECL_EXTERNAL (decl)
&& TREE_CODE (decl) != FUNCTION_DECL)
warning ("declaration of `%s' has `extern' and is initialized",
IDENTIFIER_POINTER (DECL_NAME (decl)));
#endif
DECL_EXTERNAL (decl) = 0;
if (current_binding_level == global_binding_level)
TREE_STATIC (decl) = 1;
DECL_INITIAL (decl) = error_mark_node;
}
if (TREE_CODE (decl) == FUNCTION_DECL)
gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0);
if (! flag_no_common || ! TREE_PUBLIC (decl))
DECL_COMMON (decl) = 1;
#ifdef SET_DEFAULT_DECL_ATTRIBUTES
SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes);
#endif
decl_attributes (decl, attributes, prefix_attributes);
tem = pushdecl (decl);
if (current_binding_level != global_binding_level
&& DECL_RTL (tem) == 0)
{
if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
expand_decl (tem);
else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
&& DECL_INITIAL (tem) != 0)
expand_decl (tem);
}
if (init_written)
{
if (current_binding_level == global_binding_level && debug_temp_inits)
temporary_allocation ();
}
return tem;
}
void
finish_decl (decl, init, asmspec_tree)
tree decl, init;
tree asmspec_tree;
{
register tree type = TREE_TYPE (decl);
int was_incomplete = (DECL_SIZE (decl) == 0);
int temporary = allocation_temporary_p ();
char *asmspec = 0;
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
if (init != 0 && DECL_INITIAL (decl) == 0)
init = 0;
if (TREE_CODE (decl) == PARM_DECL)
init = 0;
if (ITERATOR_P (decl))
{
if (init == 0)
error_with_decl (decl, "iterator has no initial value");
else
init = save_expr (init);
}
if (init)
{
if (TREE_CODE (decl) != TYPE_DECL)
store_init_value (decl, init);
else
{
TREE_TYPE (decl) = TREE_TYPE (init);
DECL_INITIAL (decl) = init = 0;
}
}
pop_obstacks ();
#if 0
if (current_binding_level == global_binding_level && temporary)
end_temporary_allocation ();
#endif
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == 0
&& TREE_CODE (decl) != TYPE_DECL)
{
int do_default
= (TREE_STATIC (decl)
? pedantic && !TREE_PUBLIC (decl)
: !DECL_EXTERNAL (decl));
int failure
= complete_array_type (type, DECL_INITIAL (decl), do_default);
type = TREE_TYPE (decl);
if (failure == 1)
error_with_decl (decl, "initializer fails to determine size of `%s'");
if (failure == 2)
{
if (do_default)
error_with_decl (decl, "array size missing in `%s'");
else if (!pedantic && TREE_STATIC (decl) && ! TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
}
if (pedantic && TYPE_DOMAIN (type) != 0
&& tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
error_with_decl (decl, "zero or negative size array `%s'");
layout_decl (decl, 0);
}
if (TREE_CODE (decl) == VAR_DECL)
{
if (DECL_SIZE (decl) == 0
&& TYPE_SIZE (TREE_TYPE (decl)) != 0)
layout_decl (decl, 0);
if (DECL_SIZE (decl) == 0
&& (TREE_STATIC (decl)
?
(DECL_INITIAL (decl) != 0
|| (DECL_CONTEXT (decl) != 0 && ! TREE_ASM_WRITTEN (decl)))
:
!DECL_EXTERNAL (decl)))
{
error_with_decl (decl, "storage size of `%s' isn't known");
TREE_TYPE (decl) = error_mark_node;
}
if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
&& DECL_SIZE (decl) != 0)
{
if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
constant_expression_warning (DECL_SIZE (decl));
else
error_with_decl (decl, "storage size of `%s' isn't constant");
}
if (TREE_USED (type))
TREE_USED (decl) = 1;
}
if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
{
DECL_BUILT_IN (decl) = 0;
DECL_RTL (decl) = 0;
}
if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
{
if ((flag_traditional || TREE_PERMANENT (decl))
&& allocation_temporary_p ())
{
push_obstacks_nochange ();
end_temporary_allocation ();
maybe_objc_check_decl (decl);
rest_of_decl_compilation (decl, asmspec,
(DECL_CONTEXT (decl) == 0
|| TREE_ASM_WRITTEN (decl)),
0);
pop_obstacks ();
}
else
{
maybe_objc_check_decl (decl);
rest_of_decl_compilation (decl, asmspec, DECL_CONTEXT (decl) == 0,
0);
}
if (DECL_CONTEXT (decl) != 0)
{
if (was_incomplete
&& ! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
{
TREE_ADDRESSABLE (decl) = TREE_USED (decl);
if (DECL_SIZE (decl) == 0)
DECL_INITIAL (decl) = 0;
expand_decl (decl);
}
if (TREE_CODE (decl) != FUNCTION_DECL)
expand_decl_init (decl);
}
}
if (TREE_CODE (decl) == TYPE_DECL)
{
maybe_objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL_PTR, DECL_CONTEXT (decl) == 0,
0);
}
if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
&& temporary
&& TREE_CODE (decl) != PARM_DECL)
{
if (DECL_INITIAL (decl) != 0 && DECL_INITIAL (decl) != error_mark_node)
{
if (TREE_READONLY (decl) || ITERATOR_P (decl))
{
preserve_initializer ();
TREE_PERMANENT (DECL_INITIAL (decl)) = 1;
TREE_TYPE (DECL_INITIAL (decl)) = type;
}
else
DECL_INITIAL (decl) = error_mark_node;
}
}
if (warn_larger_than
&& (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
&& !DECL_EXTERNAL (decl))
{
register tree decl_size = DECL_SIZE (decl);
if (decl_size && TREE_CODE (decl_size) == INTEGER_CST)
{
unsigned units = TREE_INT_CST_LOW(decl_size) / BITS_PER_UNIT;
if (units > larger_than_size)
warning_with_decl (decl, "size of `%s' is %u bytes", units);
}
}
#if 0
pop_obstacks ();
#endif
if (temporary && !allocation_temporary_p ())
permanent_allocation (0);
if (current_binding_level == global_binding_level)
get_pending_sizes ();
}
tree
maybe_build_cleanup (decl)
tree decl ATTRIBUTE_UNUSED;
{
return NULL_TREE;
}
void
push_parm_decl (parm)
tree parm;
{
tree decl;
int old_immediate_size_expand = immediate_size_expand;
immediate_size_expand = 0;
push_obstacks_nochange ();
decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
decl_attributes (decl, TREE_VALUE (TREE_VALUE (parm)),
TREE_PURPOSE (TREE_VALUE (parm)));
#if 0
if (DECL_NAME (decl))
{
tree olddecl;
olddecl = lookup_name (DECL_NAME (decl));
if (pedantic && olddecl != 0 && TREE_CODE (olddecl) == TYPE_DECL)
pedwarn_with_decl (decl, "ANSI C forbids parameter `%s' shadowing typedef");
}
#endif
decl = pushdecl (decl);
immediate_size_expand = old_immediate_size_expand;
current_binding_level->parm_order
= tree_cons (NULL_TREE, decl, current_binding_level->parm_order);
finish_decl (decl, NULL_TREE, NULL_TREE);
}
void
clear_parm_order ()
{
current_binding_level->parm_order = NULL_TREE;
}
int
complete_array_type (type, initial_value, do_default)
tree type;
tree initial_value;
int do_default;
{
register tree maxindex = NULL_TREE;
int value = 0;
if (initial_value)
{
if (TREE_CODE (initial_value) == STRING_CST)
{
int eltsize
= int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
maxindex = build_int_2 ((TREE_STRING_LENGTH (initial_value)
/ eltsize) - 1, 0);
}
else if (TREE_CODE (initial_value) == CONSTRUCTOR)
{
tree elts = CONSTRUCTOR_ELTS (initial_value);
maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node);
for (; elts; elts = TREE_CHAIN (elts))
{
if (TREE_PURPOSE (elts))
maxindex = TREE_PURPOSE (elts);
else
maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node);
}
maxindex = copy_node (maxindex);
}
else
{
if (initial_value != error_mark_node)
value = 1;
maxindex = build_int_2 (0, 0);
}
}
if (!maxindex)
{
if (do_default)
maxindex = build_int_2 (0, 0);
value = 2;
}
if (maxindex)
{
TYPE_DOMAIN (type) = build_index_type (maxindex);
if (!TREE_TYPE (maxindex))
TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
}
layout_type (type);
return value;
}
static tree
grokdeclarator (declarator, declspecs, decl_context, initialized)
tree declspecs;
tree declarator;
enum decl_context decl_context;
int initialized;
{
#if defined(NEXT_SEMANTICS)
long long specbits = 0;
#else
int specbits = 0;
#endif
tree spec;
tree type = NULL_TREE;
int longlong = 0;
int constp;
int restrictp;
int volatilep;
#if defined (_WIN32) && defined (NEXT_PDO)
int stdcallp; #endif
int type_quals = TYPE_UNQUALIFIED;
int inlinep;
int explicit_int = 0;
int explicit_char = 0;
int explicit_bool = 0;
int defaulted_int = 0;
tree typedef_decl = 0;
const char *name;
tree typedef_type = 0;
int funcdef_flag = 0;
enum tree_code innermost_code = ERROR_MARK;
int bitfield = 0;
int size_varies = 0;
tree decl_machine_attr = NULL_TREE;
if (decl_context == BITFIELD)
bitfield = 1, decl_context = FIELD;
if (decl_context == FUNCDEF)
funcdef_flag = 1, decl_context = NORMAL;
push_obstacks_nochange ();
if (flag_traditional && allocation_temporary_p ())
end_temporary_allocation ();
{
register tree decl = declarator;
name = 0;
while (decl)
switch (TREE_CODE (decl))
{
case ARRAY_REF:
case INDIRECT_REF:
case CALL_EXPR:
innermost_code = TREE_CODE (decl);
decl = TREE_OPERAND (decl, 0);
break;
case IDENTIFIER_NODE:
name = IDENTIFIER_POINTER (decl);
decl = 0;
break;
default:
abort ();
}
if (name == 0)
name = "type name";
}
if (funcdef_flag && innermost_code != CALL_EXPR)
return 0;
if (decl_context == NORMAL && !funcdef_flag
&& current_binding_level->parm_flag)
decl_context = PARM;
for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
{
register int i;
register tree id = TREE_VALUE (spec);
if (id == ridpointers[(int) RID_INT])
{
explicit_int = 1;
goto skiploop;
}
if (id == ridpointers[(int) RID_CHAR])
{
explicit_char = 1;
goto skiploop;
}
if (id == ridpointers[(int) RID_BOOL])
{
explicit_bool = 1;
goto found;
}
if (TREE_CODE (id) == IDENTIFIER_NODE)
for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_MAX; i++)
{
if (ridpointers[i] == id)
{
if (i == (int) RID_LONG && specbits & (1<<i))
{
if (longlong)
error ("`long long long' is too long for GCC");
else
{
if (pedantic && ! in_system_header && warn_long_long)
pedwarn ("ANSI C does not support `long long'");
longlong = 1;
}
}
else if (specbits & (1 << i))
pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
specbits |= 1 << i;
goto found;
}
}
skiploop:
if (type)
error ("two or more data types in declaration of `%s'", name);
else if (TREE_CODE (id) == TYPE_DECL)
{
type = TREE_TYPE (id);
decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id);
typedef_decl = id;
}
else if (TREE_CODE (id) == IDENTIFIER_NODE)
{
register tree t = lookup_name (id);
if (TREE_TYPE (t) == error_mark_node)
;
else if (!t || TREE_CODE (t) != TYPE_DECL)
error ("`%s' fails to be a typedef or built in type",
IDENTIFIER_POINTER (id));
else
{
type = TREE_TYPE (t);
typedef_decl = t;
}
}
else if (TREE_CODE (id) != ERROR_MARK)
type = id;
found: {}
}
#if defined (_WIN32) && defined (NEXT_PDO)
if ((specbits & 1 << (int) RID_DLLIMPORT))
{
}
#endif
if (explicit_bool && specbits == 0 && type == 0) {
type = integer_type_node;
explicit_bool = 0;
explicit_int = 1;
}
typedef_type = type;
if (type)
size_varies = C_TYPE_VARIABLE_SIZE (type);
if (type == 0 && (specbits & (1 << (int)RID_VECTOR))
&& (specbits & (1 << (int)RID_PIXEL)))
type = integer_type_node;
if (type == 0)
{
if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
| (1 << (int) RID_SIGNED)
| (1 << (int) RID_UNSIGNED))))
&& ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
&& ! (in_system_header && ! allocation_temporary_p ()))
{
if ((warn_implicit_int || warn_return_type) && funcdef_flag)
warn_about_return_type = 1;
else if (warn_implicit_int || flag_isoc9x)
warning ("type defaults to `int' in declaration of `%s'", name);
}
defaulted_int = 1;
type = integer_type_node;
}
if ((specbits & 1 << (int) RID_LONG) && ! longlong
&& TYPE_MAIN_VARIANT (type) == double_type_node)
{
specbits &= ~ (1 << (int) RID_LONG);
type = long_double_type_node;
if (warn_long_double
&& ! warned_about_long_double
&& ! in_system_header
&& ! strstr (input_filename, "/System/Library/Frameworks/")
&& ! strstr (input_filename, "/usr/include/"))
{
warning ("use of `long double' type; its size may change in a future release");
warning ("(Long double usage is reported only once for each file.");
warning ("To disable this warning, use -Wno-long-double.)");
warned_about_long_double = 1;
}
}
if (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
| (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED)))
{
int ok = 0;
if ((specbits & 1 << (int) RID_LONG)
&& (specbits & 1 << (int) RID_SHORT))
error ("both long and short specified for `%s'", name);
else if (((specbits & 1 << (int) RID_LONG)
|| (specbits & 1 << (int) RID_SHORT))
&& explicit_char)
error ("long or short specified with char for `%s'", name);
else if (((specbits & 1 << (int) RID_LONG)
|| (specbits & 1 << (int) RID_SHORT))
&& TREE_CODE (type) == REAL_TYPE)
{
static int already = 0;
error ("long or short specified with floating type for `%s'", name);
if (! already && ! pedantic)
{
error ("the only valid combination is `long double'");
already = 1;
}
}
else if ((specbits & 1 << (int) RID_SIGNED)
&& (specbits & 1 << (int) RID_UNSIGNED))
error ("both signed and unsigned specified for `%s'", name);
else if (TREE_CODE (type) != INTEGER_TYPE)
error ("long, short, signed or unsigned invalid for `%s'", name);
else
{
ok = 1;
if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
{
pedwarn ("long, short, signed or unsigned used invalidly for `%s'",
name);
if (flag_pedantic_errors)
ok = 0;
}
}
if (! ok)
{
specbits &= ~((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
| (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED));
longlong = 0;
}
}
if ((specbits & (1 << (int) RID_COMPLEX))
&& TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
{
error ("complex invalid for `%s'", name);
specbits &= ~ (1 << (int) RID_COMPLEX);
}
if (specbits & 1 << (int) RID_UNSIGNED
|| (bitfield && flag_traditional
&& (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
|| (bitfield && ! flag_signed_bitfields
&& (explicit_int || defaulted_int || explicit_char
|| ! (typedef_decl != 0
&& C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
&& TREE_CODE (type) != ENUMERAL_TYPE
&& !(specbits & 1 << (int) RID_SIGNED)))
{
if (longlong)
type = long_long_unsigned_type_node;
else if (specbits & 1 << (int) RID_LONG)
type = long_unsigned_type_node;
else if (specbits & 1 << (int) RID_SHORT)
type = short_unsigned_type_node;
else if (type == char_type_node)
type = unsigned_char_type_node;
else if (typedef_decl)
type = unsigned_type (type);
else
type = unsigned_type_node;
}
else if ((specbits & 1 << (int) RID_SIGNED)
&& type == char_type_node)
type = signed_char_type_node;
else if (longlong)
type = long_long_integer_type_node;
else if (specbits & 1 << (int) RID_LONG)
type = long_integer_type_node;
else if (specbits & 1 << (int) RID_SHORT)
type = short_integer_type_node;
if (specbits & 1 << (int) RID_COMPLEX)
{
if (defaulted_int && ! longlong
&& ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
| (1 << (int) RID_SIGNED)
| (1 << (int) RID_UNSIGNED))))
type = complex_double_type_node;
else if (type == integer_type_node)
type = complex_integer_type_node;
else if (type == float_type_node)
type = complex_float_type_node;
else if (type == double_type_node)
type = complex_double_type_node;
else if (type == long_double_type_node)
type = complex_long_double_type_node;
else
type = build_complex_type (type);
}
if ((specbits & (1 << (int) RID_PIXEL))
&& !(specbits & (1 << (int) RID_VECTOR)))
{
error ("__pixel invalid for `%s'", name);
specbits &= ~ (1 << (int) RID_PIXEL);
}
if (explicit_bool
&& !(specbits & (1 << (int) RID_VECTOR)))
{
error ("bool invalid for `%s'", name);
explicit_bool = 0;
}
if (specbits & 1 << (int) RID_VECTOR)
{
if ((type == integer_type_node || type == long_integer_type_node)
&& !explicit_bool && !explicit_int
&& (specbits & (1 << (int) RID_PIXEL)))
type = vector_pixel_type_node;
else if (type == long_unsigned_type_node
|| (type == unsigned_type_node
&& explicit_int && !explicit_bool))
type = vector_unsigned_long_type_node;
else if ((type == long_integer_type_node && explicit_bool)
|| (type == integer_type_node && explicit_int
&& explicit_bool && !(specbits & 1 << (int) RID_SIGNED)))
type = vector_boolean_long_type_node;
else if ((type == long_integer_type_node && !explicit_bool)
|| (type == integer_type_node && explicit_int
&& !explicit_bool && (specbits & 1 << (int) RID_SIGNED)))
type = vector_signed_long_type_node;
else if (type == short_unsigned_type_node)
type = vector_unsigned_short_type_node;
else if (type == short_integer_type_node)
type = (explicit_bool
? vector_boolean_short_type_node
: vector_signed_short_type_node);
else if (type == unsigned_char_type_node)
type = vector_unsigned_char_type_node;
else if (type == signed_char_type_node)
type = vector_signed_char_type_node;
else if (type == char_type_node && explicit_bool)
type = vector_boolean_char_type_node;
else if (type == float_type_node)
type = vector_float_type_node;
else
{
error ("vector invalid for `%s'", name);
specbits &= ~ ((1 << (int) RID_VECTOR) | (1 << (int) RID_PIXEL));
}
if ((specbits & (1 << (int) RID_PIXEL))
&& type != vector_pixel_type_node)
{
error ("type modifiers do not apply to `vector pixel'");
type = vector_pixel_type_node;
}
}
constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
#if defined (_WIN32) && defined (NEXT_PDO)
stdcallp = !! (specbits & 1 << (int) RID_STDCALL);
#endif
inlinep = !! (specbits & (1 << (int) RID_INLINE));
if (constp > 1)
pedwarn ("duplicate `const'");
if (restrictp > 1)
pedwarn ("duplicate `restrict'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
if (! flag_gen_aux_info && (TYPE_QUALS (type)))
type = TYPE_MAIN_VARIANT (type);
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
{
int nclasses = 0;
if (specbits & 1 << (int) RID_AUTO) nclasses++;
if (specbits & 1 << (int) RID_STATIC) nclasses++;
if (specbits & 1 << (int) RID_EXTERN) nclasses++;
if (specbits & 1 << (int) RID_REGISTER) nclasses++;
if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
if (specbits & 1 << (int) RID_ITERATOR) nclasses++;
#ifdef NEXT_SEMANTICS
if (specbits & 1 << (int) RID_PRIVATE_EXTERN) nclasses++;
#endif
if (nclasses > 1)
error ("multiple storage classes in declaration of `%s'", name);
else if (funcdef_flag
&& (specbits
& ((1 << (int) RID_REGISTER)
| (1 << (int) RID_AUTO)
| (1 << (int) RID_TYPEDEF))))
{
if (specbits & 1 << (int) RID_AUTO
&& (pedantic || current_binding_level == global_binding_level))
pedwarn ("function definition declared `auto'");
if (specbits & 1 << (int) RID_REGISTER)
error ("function definition declared `register'");
if (specbits & 1 << (int) RID_TYPEDEF)
error ("function definition declared `typedef'");
specbits &= ~ ((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
| (1 << (int) RID_AUTO));
}
else if (decl_context != NORMAL && nclasses > 0)
{
if (decl_context == PARM && specbits & 1 << (int) RID_REGISTER)
;
else
{
error ((decl_context == FIELD
? "storage class specified for structure field `%s'"
: (decl_context == PARM
? "storage class specified for parameter `%s'"
: "storage class specified for typename")),
name);
specbits &= ~ ((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
| (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
| (1 << (int) RID_EXTERN));
}
}
else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
{
if (current_binding_level == global_binding_level)
warning ("`%s' initialized and declared `extern'", name);
else
error ("`%s' has both `extern' and initializer", name);
}
else if (specbits & 1 << (int) RID_EXTERN && funcdef_flag
&& current_binding_level != global_binding_level)
error ("nested function `%s' declared `extern'", name);
else if (current_binding_level == global_binding_level
&& specbits & (1 << (int) RID_AUTO))
error ("top-level declaration of `%s' specifies `auto'", name);
else if ((specbits & 1 << (int) RID_ITERATOR)
&& TREE_CODE (declarator) != IDENTIFIER_NODE)
{
error ("iterator `%s' has derived type", name);
type = error_mark_node;
}
else if ((specbits & 1 << (int) RID_ITERATOR)
&& TREE_CODE (type) != INTEGER_TYPE)
{
error ("iterator `%s' has noninteger type", name);
type = error_mark_node;
}
}
while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE)
{
if (type == error_mark_node)
{
declarator = TREE_OPERAND (declarator, 0);
continue;
}
if (TREE_CODE (declarator) == ARRAY_REF)
{
register tree itype = NULL_TREE;
register tree size = TREE_OPERAND (declarator, 1);
int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
tree index_type = signed_type (sizetype);
declarator = TREE_OPERAND (declarator, 0);
if (TYPE_MAIN_VARIANT (type) == void_type_node)
{
error ("declaration of `%s' as array of voids", name);
type = error_mark_node;
}
if (TREE_CODE (type) == FUNCTION_TYPE)
{
error ("declaration of `%s' as array of functions", name);
type = error_mark_node;
}
if (size == error_mark_node)
type = error_mark_node;
if (type == error_mark_node)
continue;
if (extern_ref && allocation_temporary_p ())
end_temporary_allocation ();
if (size)
{
STRIP_TYPE_NOPS (size);
if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE)
{
error ("size of array `%s' has non-integer type", name);
size = integer_one_node;
}
if (pedantic && integer_zerop (size))
pedwarn ("ANSI C forbids zero-size array `%s'", name);
if (TREE_CODE (size) == INTEGER_CST)
{
constant_expression_warning (size);
if (tree_int_cst_sgn (size) < 0)
{
error ("size of array `%s' is negative", name);
size = integer_one_node;
}
}
else
{
size_varies = 1;
if (pedantic)
{
if (TREE_CONSTANT (size))
pedwarn ("ANSI C forbids array `%s' whose size can't be evaluated", name);
else
pedwarn ("ANSI C forbids variable-size array `%s'", name);
}
}
itype = fold (build (MINUS_EXPR, index_type,
convert (index_type, size),
convert (index_type, size_one_node)));
if (TREE_OVERFLOW (itype))
{
error ("size of array `%s' is too large", name);
type = error_mark_node;
continue;
}
if (size_varies)
itype = variable_size (itype);
itype = build_index_type (itype);
}
#if 0
if (TYPE_SIZE (type) == 0
&& TREE_CODE (type) != ARRAY_TYPE
&& !(specbits & (1 << (int) RID_TYPEDEF))
&& !C_TYPE_BEING_DEFINED (type))
warning ("array type has incomplete element type");
#endif
#if 0
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& (constp || volatilep))
pedwarn ("ANSI C forbids const or volatile function types");
#endif
type = build_array_type (type, itype);
if (type_quals)
type = c_build_qualified_type (type, type_quals);
#if 0
type_quals = TYPE_UNQUALIFIED;
#endif
if (size_varies)
C_TYPE_VARIABLE_SIZE (type) = 1;
}
else if (TREE_CODE (declarator) == CALL_EXPR)
{
int extern_ref = (!(specbits & (1 << (int) RID_AUTO))
|| current_binding_level == global_binding_level);
tree arg_types;
if (type == error_mark_node)
continue;
size_varies = 0;
if (TREE_CODE (type) == FUNCTION_TYPE)
{
error ("`%s' declared as function returning a function", name);
type = integer_type_node;
}
if (TREE_CODE (type) == ARRAY_TYPE)
{
error ("`%s' declared as function returning an array", name);
type = integer_type_node;
}
#ifndef TRADITIONAL_RETURN_FLOAT
if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node)
type = double_type_node;
#endif
if (extern_ref && allocation_temporary_p ())
end_temporary_allocation ();
arg_types = grokparms (TREE_OPERAND (declarator, 1),
funcdef_flag
&& TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE);
#if 0
type = build_function_type (type,
flag_traditional
? NULL_TREE : arg_types);
#endif
#ifdef _WIN32
if( stdcallp )
{
type = build_type_copy( type );
}
#endif
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type_quals = TYPE_UNQUALIFIED;
type = build_function_type (type, arg_types);
declarator = TREE_OPERAND (declarator, 0);
#ifdef _WIN32
if( stdcallp )
{
TYPE_STDCALL( type ) = 1;
}
#endif
{
register tree link;
for (link = last_function_parm_tags;
link;
link = TREE_CHAIN (link))
TYPE_CONTEXT (TREE_VALUE (link)) = type;
}
}
else if (TREE_CODE (declarator) == INDIRECT_REF)
{
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
pedwarn ("ANSI C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
type = build_pointer_type (type);
if (TREE_TYPE (declarator))
{
register tree typemodlist;
int erred = 0;
constp = 0;
volatilep = 0;
restrictp = 0;
for (typemodlist = TREE_TYPE (declarator); typemodlist;
typemodlist = TREE_CHAIN (typemodlist))
{
tree qualifier = TREE_VALUE (typemodlist);
if (qualifier == ridpointers[(int) RID_CONST])
constp++;
else if (qualifier == ridpointers[(int) RID_VOLATILE])
volatilep++;
#ifdef _WIN32
else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_STDCALL])
{
stdcallp++;
type = build_type_copy( TREE_TYPE( type ) );
type = build_pointer_type( type );
TYPE_STDCALL( TREE_TYPE( type ) ) = 1;
}
#endif
else if (qualifier == ridpointers[(int) RID_RESTRICT])
restrictp++;
else if (!erred)
{
erred = 1;
error ("invalid type modifier within pointer declarator");
}
}
if (constp > 1)
pedwarn ("duplicate `const'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
#ifdef _WIN32
if (stdcallp > 1)
pedwarn ("duplicate `stdcall'");
#endif
if (restrictp > 1)
pedwarn ("duplicate `restrict'");
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
}
declarator = TREE_OPERAND (declarator, 0);
}
else
abort ();
}
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_SIZE (type)
&& TREE_OVERFLOW (TYPE_SIZE (type)))
error ("size of array `%s' is too large", name);
if (specbits & (1 << (int) RID_TYPEDEF))
{
tree decl;
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
pedwarn ("ANSI C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
decl = build_decl (TYPE_DECL, declarator, type);
if ((specbits & (1 << (int) RID_SIGNED))
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
#ifdef _WIN32
if( stdcallp )
TYPE_STDCALL( type ) = 1;
#endif
pop_obstacks ();
return decl;
}
if (type != 0 && typedef_type != 0
&& TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type)
&& TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0)
{
type = build_array_type (TREE_TYPE (type), 0);
if (size_varies)
C_TYPE_VARIABLE_SIZE (type) = 1;
}
if (decl_context == TYPENAME)
{
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
pedwarn ("ANSI C forbids const or volatile function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
pop_obstacks ();
return type;
}
if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM
&& ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
&& ((specbits & (1 << (int) RID_EXTERN))
|| (current_binding_level == global_binding_level
&& !(specbits
& ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
{
error ("variable or field `%s' declared void", name);
type = integer_type_node;
}
{
register tree decl;
if (decl_context == PARM)
{
tree type_as_written = type;
tree main_type;
if (TREE_CODE (type) == ARRAY_TYPE)
{
type = TREE_TYPE (type);
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
if (pedantic && type_quals)
pedwarn ("ANSI C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
type_quals = TYPE_UNQUALIFIED;
}
decl = build_decl (PARM_DECL, declarator, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
DECL_ARG_TYPE (decl) = type;
main_type = (type == error_mark_node
? error_mark_node
: TYPE_MAIN_VARIANT (type));
if (main_type == float_type_node)
DECL_ARG_TYPE (decl) = double_type_node;
else if (TREE_CODE (main_type) != ERROR_MARK
&& C_PROMOTING_INTEGER_TYPE_P (main_type))
{
if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)
&& TREE_UNSIGNED (type))
DECL_ARG_TYPE (decl) = unsigned_type_node;
else
DECL_ARG_TYPE (decl) = integer_type_node;
}
DECL_ARG_TYPE_AS_WRITTEN (decl) = type_as_written;
}
else if (decl_context == FIELD)
{
if (TREE_CODE (type) == FUNCTION_TYPE)
{
error ("field `%s' declared as a function", name);
type = build_pointer_type (type);
}
else if (TREE_CODE (type) != ERROR_MARK && TYPE_SIZE (type) == 0)
{
error ("field `%s' has incomplete type", name);
type = error_mark_node;
}
if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
{
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
type_quals),
TYPE_DOMAIN (type));
#if 0
type_quals = TYPE_UNQUALIFIED;
#endif
}
decl = build_decl (FIELD_DECL, declarator, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
int extern_ref = (!(specbits & (1 << (int) RID_AUTO))
|| current_binding_level == global_binding_level);
if (specbits & (1 << (int) RID_AUTO)
&& (pedantic || current_binding_level == global_binding_level))
pedwarn ("invalid storage class for function `%s'", name);
if (specbits & ((1 << (int) RID_REGISTER)
#ifdef NEXT_SEMANTICS
| (1 << (int) RID_DIRECT)
#endif
))
error ("invalid storage class for function `%s'", name);
if (current_binding_level != global_binding_level
&& (specbits & ( (1 << (int) RID_STATIC)
#ifdef NEXT_SEMANTICS
| (1 << (int) RID_PRIVATE_EXTERN)
#endif
| (1 << (int) RID_INLINE)))
&& pedantic)
pedwarn ("invalid storage class for function `%s'", name);
if (extern_ref && allocation_temporary_p ())
end_temporary_allocation ();
decl = build_decl (FUNCTION_DECL, declarator, type);
decl = build_decl_attribute_variant (decl, decl_machine_attr);
#ifdef _WIN32
if( stdcallp )
DECL_STDCALL( decl ) = stdcallp;
#endif
if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ANSI C forbids qualified function types");
if (pedantic && (constp || volatilep)
&& ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ANSI C forbids const or volatile functions");
if (pedantic
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
&& TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
&& ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ANSI C forbids qualified void function return type");
if ((type_quals & TYPE_QUAL_VOLATILE)
&& TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
warning ("`noreturn' function returns non-void value");
if (extern_ref)
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl)
= !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
#ifdef NEXT_SEMANTICS
DECL_PRIVATE_EXTERN (decl)
= !!(specbits & (1 << (int) RID_PRIVATE_EXTERN));
#endif
if (inlinep)
{
if (! strcmp (IDENTIFIER_POINTER (declarator), "main"))
warning ("cannot inline function `main'");
else
DECL_INLINE (decl) = 1;
if (specbits & (1 << (int) RID_EXTERN))
current_extern_inline = 1;
}
}
else
{
int extern_ref = !initialized && (specbits & ( (1 << (int) RID_EXTERN)
#ifdef NEXT_SEMANTICS
| (1 << (int) RID_PRIVATE_EXTERN)
#endif
));
if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
{
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
type_quals),
TYPE_DOMAIN (type));
#if 0
type_quals = TYPE_UNQUALIFIED;
#endif
}
if (extern_ref && allocation_temporary_p ())
end_temporary_allocation ();
decl = build_decl (VAR_DECL, declarator, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
if (inlinep)
pedwarn_with_decl (decl, "variable `%s' declared `inline'");
#ifdef NEXT_SEMANTICS
if (specbits & (1 << (int) RID_DIRECT))
error_with_decl (decl, "invalid storage class for variable `%s'");
#endif
DECL_EXTERNAL (decl) = extern_ref;
#ifdef NEXT_SEMANTICS
DECL_PRIVATE_EXTERN (decl)
= !!(specbits & (1 << (int) RID_PRIVATE_EXTERN));
if ( !initialized
&& !extern_ref
&& TREE_CODE (type) == ARRAY_TYPE
&& DECL_SIZE (decl) == NULL_TREE)
{
warning_with_decl (decl, "variable `%s' is implicitly extern");
DECL_EXTERNAL (decl) = 1;
}
#endif
if (current_binding_level == global_binding_level)
{
TREE_PUBLIC (decl)
= !(specbits
& ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)));
TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
}
else
{
TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
}
if (specbits & 1 << (int) RID_ITERATOR)
ITERATOR_P (decl) = 1;
}
#ifdef NEXT_SEMANTICS
if (specbits & 1 << (int) RID_RELATIVE)
{
if (TREE_CODE (type) != POINTER_TYPE)
pedwarn_with_decl (decl, "non-pointer declared __relative__");
else if (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == FIELD_DECL)
DECL_RELATIVE (decl) = 1;
}
#endif
if (specbits & (1 << (int) RID_REGISTER))
DECL_REGISTER (decl) = 1;
if (type_quals)
c_apply_type_quals_to_decl (type_quals, decl);
#if defined (_WIN32) && defined (NEXT_PDO)
if (stdcallp)
TYPE_STDCALL (decl) = 1;
if( (specbits & 1 << (int) RID_DLLIMPORT ) )
{
DECL_EXTERNAL (decl) = 1;
{
char* newName =
(char*)malloc(strlen( IDENTIFIER_POINTER(DECL_NAME(decl)) ) + 7 ); sprintf( newName, "_imp__%s", IDENTIFIER_POINTER(DECL_NAME(decl)) );
DECL_ASSEMBLER_NAME(decl) = get_identifier( newName );
DECL_DLLIMPORT(decl) = 1;
}
}
else if (specbits & 1 << (int) RID_DLLEXPORT)
{
char prependCharacter = '_';
char *tail = "";
char *gen_stdcall_suffix ();
char *ident_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
int length = 1;
if (TREE_CODE (decl) != FUNCTION_DECL)
tail = ",data";
if (exportNamesForDLL)
length += strlen (exportNamesForDLL);
length += strlen (" -export:");
if (strncmp (ident_name, "objc_class_name", 15) == 0)
{
prependCharacter = '.';
tail = "";
}
length += strlen (tail);
if (stdcallp)
ident_name = gen_stdcall_suffix (decl);
length += strlen (ident_name);
if (exportNamesForDLL)
exportNamesForDLL =
(char *) realloc ((void*)exportNamesForDLL, length + 1);
else
{
exportNamesForDLL = (char *) malloc (length + 1);
*exportNamesForDLL = '\0';
}
sprintf (exportNamesForDLL, "%s%s%c%s%s", exportNamesForDLL,
" -export:", prependCharacter, ident_name, tail);
}
#endif
if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)))
mark_addressable (decl);
pop_obstacks ();
#ifdef __MAYBE_FORCE_COALESCED
__MAYBE_FORCE_COALESCED (decl);
#endif
return decl;
}
}
static tree
grokparms (parms_info, funcdef_flag)
tree parms_info;
int funcdef_flag;
{
tree first_parm = TREE_CHAIN (parms_info);
last_function_parms = TREE_PURPOSE (parms_info);
last_function_parm_tags = TREE_VALUE (parms_info);
if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag
&& !in_system_header)
warning ("function declaration isn't a prototype");
if (first_parm != 0
&& TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
{
if (! funcdef_flag)
pedwarn ("parameter names (without types) in function declaration");
last_function_parms = first_parm;
return 0;
}
else
{
tree parm;
tree typelt;
#if 0
if (funcdef_flag)
#endif
for (parm = last_function_parms, typelt = first_parm;
parm;
parm = TREE_CHAIN (parm))
if (TREE_CODE (parm) == PARM_DECL)
{
tree type = TREE_VALUE (typelt);
if (TYPE_SIZE (type) == 0)
{
if (funcdef_flag && DECL_NAME (parm) != 0)
error ("parameter `%s' has incomplete type",
IDENTIFIER_POINTER (DECL_NAME (parm)));
else
warning ("parameter has incomplete type");
if (funcdef_flag)
{
TREE_VALUE (typelt) = error_mark_node;
TREE_TYPE (parm) = error_mark_node;
}
}
#if 0
else
{
while (TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
type = TYPE_MAIN_VARIANT (type);
if (TYPE_SIZE (type) == 0)
{
if (DECL_NAME (parm) != 0)
warning ("parameter `%s' points to incomplete type",
IDENTIFIER_POINTER (DECL_NAME (parm)));
else
warning ("parameter points to incomplete type");
}
}
#endif
typelt = TREE_CHAIN (typelt);
}
if (first_parm && ! TREE_PERMANENT (first_parm))
{
tree result = NULL;
for (typelt = first_parm; typelt; typelt = TREE_CHAIN (typelt))
result = saveable_tree_cons (NULL_TREE, TREE_VALUE (typelt),
result);
return nreverse (result);
}
else
return first_parm;
}
}
tree
get_parm_info (void_at_end)
int void_at_end;
{
register tree decl, t;
register tree types = 0;
int erred = 0;
tree tags = gettags ();
tree parms = getdecls ();
tree new_parms = 0;
tree order = current_binding_level->parm_order;
if (void_at_end && parms != 0
&& TREE_CHAIN (parms) == 0
&& TYPE_MAIN_VARIANT (TREE_TYPE (parms)) == void_type_node
&& DECL_NAME (parms) == 0)
{
parms = NULL_TREE;
storedecls (NULL_TREE);
return saveable_tree_cons (NULL_TREE, NULL_TREE,
saveable_tree_cons (NULL_TREE, void_type_node, NULL_TREE));
}
for (decl = parms; decl; )
{
tree next = TREE_CHAIN (decl);
if (TREE_CODE (decl) != PARM_DECL)
{
TREE_CHAIN (decl) = new_parms;
new_parms = decl;
}
else if (TREE_ASM_WRITTEN (decl))
{
error_with_decl (decl, "parameter `%s' has just a forward declaration");
TREE_CHAIN (decl) = new_parms;
new_parms = decl;
}
decl = next;
}
for (t = order; t; t = TREE_CHAIN (t))
{
if (TREE_CHAIN (t))
TREE_CHAIN (TREE_VALUE (t)) = TREE_VALUE (TREE_CHAIN (t));
else
TREE_CHAIN (TREE_VALUE (t)) = 0;
}
new_parms = chainon (order ? nreverse (TREE_VALUE (order)) : 0,
new_parms);
storedecls (new_parms);
for (decl = new_parms; decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == PARM_DECL)
{
tree type = TREE_TYPE (decl);
DECL_ARG_TYPE (decl) = type;
#ifdef PROMOTE_PROTOTYPES
if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE)
&& TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
DECL_ARG_TYPE (decl) = integer_type_node;
#endif
types = saveable_tree_cons (NULL_TREE, TREE_TYPE (decl), types);
if (TYPE_MAIN_VARIANT (TREE_VALUE (types)) == void_type_node && ! erred
&& DECL_NAME (decl) == 0)
{
error ("`void' in parameter list must be the entire list");
erred = 1;
}
}
if (void_at_end)
return saveable_tree_cons (new_parms, tags,
nreverse (saveable_tree_cons (NULL_TREE, void_type_node, types)));
return saveable_tree_cons (new_parms, tags, nreverse (types));
}
void
parmlist_tags_warning ()
{
tree elt;
static int already;
for (elt = current_binding_level->tags; elt; elt = TREE_CHAIN (elt))
{
enum tree_code code = TREE_CODE (TREE_VALUE (elt));
if (code == UNION_TYPE && TREE_PURPOSE (elt) == 0 && !pedantic)
continue;
if (TREE_PURPOSE (elt) != 0)
warning ("`%s %s' declared inside parameter list",
(code == RECORD_TYPE ? "struct"
: code == UNION_TYPE ? "union"
: "enum"),
IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
else
warning ("anonymous %s declared inside parameter list",
(code == RECORD_TYPE ? "struct"
: code == UNION_TYPE ? "union"
: "enum"));
if (! already)
{
warning ("its scope is only this definition or declaration, which is probably not what you want.");
already = 1;
}
}
}
tree
xref_tag (code, name)
enum tree_code code;
tree name;
{
int temporary = allocation_temporary_p ();
register tree ref = lookup_tag (code, name, current_binding_level, 0);
if (ref)
return ref;
push_obstacks_nochange ();
if (current_binding_level == global_binding_level && temporary)
end_temporary_allocation ();
ref = make_node (code);
if (code == ENUMERAL_TYPE)
{
if (pedantic)
pedwarn ("ANSI C forbids forward references to `enum' types");
TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
TREE_UNSIGNED (ref) = 1;
TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
}
pushtag (name, ref);
pop_obstacks ();
return ref;
}
tree
start_struct (code, name)
enum tree_code code;
tree name;
{
register tree ref = 0;
push_obstacks_nochange ();
if (current_binding_level == global_binding_level)
end_temporary_allocation ();
if (name != 0)
ref = lookup_tag (code, name, current_binding_level, 1);
if (ref && TREE_CODE (ref) == code)
{
C_TYPE_BEING_DEFINED (ref) = 1;
TYPE_PACKED (ref) = flag_pack_struct;
if (TYPE_FIELDS (ref))
#ifdef NEXT_SEMANTICS
{
tree fields = TYPE_FIELDS (ref);
#endif
error ((code == UNION_TYPE ? "redefinition of `union %s'"
: "redefinition of `struct %s'"),
IDENTIFIER_POINTER (name));
#ifdef NEXT_SEMANTICS
error_with_file_and_line (DECL_SOURCE_FILE (fields),
DECL_SOURCE_LINE (fields),
(code == UNION_TYPE
? "previous definition of `union %s'"
: "previous definition of `struct %s'"),
IDENTIFIER_POINTER (name));
}
#endif
return ref;
}
ref = make_node (code);
pushtag (name, ref);
C_TYPE_BEING_DEFINED (ref) = 1;
TYPE_PACKED (ref) = flag_pack_struct;
return ref;
}
tree
grokfield (filename, line, declarator, declspecs, width)
const char *filename ATTRIBUTE_UNUSED;
int line ATTRIBUTE_UNUSED;
tree declarator, declspecs, width;
{
tree value;
push_obstacks_nochange ();
value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
finish_decl (value, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width;
maybe_objc_check_decl (value);
return value;
}
static int
field_decl_cmp (xp, yp)
const GENERIC_PTR xp;
const GENERIC_PTR yp;
{
tree *x = (tree *)xp, *y = (tree *)yp;
if (DECL_NAME (*x) == DECL_NAME (*y))
return 0;
if (DECL_NAME (*x) == NULL)
return -1;
if (DECL_NAME (*y) == NULL)
return 1;
if (DECL_NAME (*x) < DECL_NAME (*y))
return -1;
return 1;
}
tree
finish_struct (t, fieldlist, attributes)
tree t;
tree fieldlist;
tree attributes;
{
register tree x;
int old_momentary;
int toplevel = global_binding_level == current_binding_level;
TYPE_SIZE (t) = 0;
decl_attributes (t, attributes, NULL_TREE);
if (! (TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) == 0) && !pedantic)
if (in_parm_level_p ())
{
if (pedantic)
pedwarn ((TREE_CODE (t) == UNION_TYPE ? "union defined inside parms"
: "structure defined inside parms"));
else if (! flag_traditional)
warning ((TREE_CODE (t) == UNION_TYPE ? "union defined inside parms"
: "structure defined inside parms"));
}
old_momentary = suspend_momentary ();
if (pedantic)
{
for (x = fieldlist; x; x = TREE_CHAIN (x))
if (DECL_NAME (x) != 0)
break;
if (x == 0)
pedwarn ((fieldlist
? "%s has no named members"
: "%s has no members"),
TREE_CODE (t) == UNION_TYPE ? "union" : "struct");
}
for (x = fieldlist; x; x = TREE_CHAIN (x))
{
DECL_CONTEXT (x) = t;
DECL_PACKED (x) |= TYPE_PACKED (t);
DECL_FIELD_SIZE (x) = 0;
if (TREE_READONLY (x))
C_TYPE_FIELDS_READONLY (t) = 1;
else
{
tree t1 = TREE_TYPE (x);
while (TREE_CODE (t1) == ARRAY_TYPE)
t1 = TREE_TYPE (t1);
if ((TREE_CODE (t1) == RECORD_TYPE || TREE_CODE (t1) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (t1))
C_TYPE_FIELDS_READONLY (t) = 1;
}
if (TREE_THIS_VOLATILE (x))
C_TYPE_FIELDS_VOLATILE (t) = 1;
if (C_DECL_VARIABLE_SIZE (x))
C_TYPE_VARIABLE_SIZE (t) = 1;
if (TREE_TYPE (x) == t)
error ("nested redefinition of `%s'",
IDENTIFIER_POINTER (TYPE_NAME (t)));
if (DECL_INITIAL (x))
STRIP_NOPS (DECL_INITIAL (x));
if (DECL_INITIAL (x))
{
if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
constant_expression_warning (DECL_INITIAL (x));
else
{
error_with_decl (x, "bit-field `%s' width not an integer constant");
DECL_INITIAL (x) = NULL;
}
}
if (DECL_INITIAL (x)
&& TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
{
error_with_decl (x, "bit-field `%s' has invalid type");
DECL_INITIAL (x) = NULL;
}
if (DECL_INITIAL (x) && pedantic
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
&& !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (x))
== TYPE_PRECISION (integer_type_node))))
pedwarn_with_decl (x, "bit-field `%s' type invalid in ANSI C");
if (DECL_INITIAL (x))
{
unsigned HOST_WIDE_INT width = TREE_INT_CST_LOW (DECL_INITIAL (x));
if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
{
DECL_INITIAL (x) = NULL;
error_with_decl (x, "negative width in bit-field `%s'");
}
else if (TREE_INT_CST_HIGH (DECL_INITIAL (x)) != 0
|| width > TYPE_PRECISION (TREE_TYPE (x)))
{
DECL_INITIAL (x) = NULL;
pedwarn_with_decl (x, "width of `%s' exceeds its type");
}
else if (width == 0 && DECL_NAME (x) != 0)
{
error_with_decl (x, "zero width for bit-field `%s'");
DECL_INITIAL (x) = NULL;
}
}
if (DECL_INITIAL (x))
{
register int width = TREE_INT_CST_LOW (DECL_INITIAL (x));
if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
&& (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
TREE_UNSIGNED (TREE_TYPE (x)))
|| width < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
TREE_UNSIGNED (TREE_TYPE (x)))))
warning_with_decl (x, "`%s' is narrower than values of its type");
DECL_FIELD_SIZE (x) = width;
DECL_BIT_FIELD (x) = DECL_C_BIT_FIELD (x) = 1;
DECL_INITIAL (x) = NULL;
if (width == 0)
{
#ifdef EMPTY_FIELD_BOUNDARY
DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
#endif
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS)
DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
TYPE_ALIGN (TREE_TYPE (x)));
#endif
}
}
else if (TREE_TYPE (x) != error_mark_node)
{
unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
: TYPE_ALIGN (TREE_TYPE (x)));
DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align);
}
}
for (x = fieldlist; x && TREE_CHAIN (x);)
if (DECL_NAME (TREE_CHAIN (x)) == 0)
x = TREE_CHAIN (x);
else
{
register 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'");
DECL_FIELD_BITPOS (TREE_CHAIN (x)) = integer_zero_node;
TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
}
else x = TREE_CHAIN (x);
}
TYPE_FIELDS (t) = fieldlist;
layout_type (t);
while (fieldlist
&& DECL_INITIAL (fieldlist))
fieldlist = TREE_CHAIN (fieldlist);
for (x = fieldlist; x;)
{
if (TREE_CHAIN (x) && DECL_INITIAL (TREE_CHAIN (x)))
TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
else x = TREE_CHAIN (x);
}
TYPE_FIELDS (t) = fieldlist;
{
int len = 0;
for (x = fieldlist; x; x = TREE_CHAIN (x))
{
if (len > 15)
break;
len += 1;
}
if (len > 15)
{
tree *field_array;
char *space;
len += list_length (x);
if (allocation_temporary_p ())
space = savealloc (sizeof (struct lang_type) + len * sizeof (tree));
else
space = oballoc (sizeof (struct lang_type) + len * sizeof (tree));
TYPE_LANG_SPECIFIC (t) = (struct lang_type *) space;
TYPE_LANG_SPECIFIC (t)->len = len;
field_array = &TYPE_LANG_SPECIFIC (t)->elts[0];
len = 0;
for (x = fieldlist; x; x = TREE_CHAIN (x))
field_array[len++] = x;
qsort (field_array, len, sizeof (tree), field_decl_cmp);
}
}
for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
{
TYPE_FIELDS (x) = TYPE_FIELDS (t);
TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
TYPE_ALIGN (x) = TYPE_ALIGN (t);
}
if (TREE_CODE (t) == UNION_TYPE
&& TYPE_TRANSPARENT_UNION (t)
&& TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))
{
TYPE_TRANSPARENT_UNION (t) = 0;
warning ("union cannot be made transparent");
}
if ((x = current_binding_level->incomplete_list) != NULL_TREE)
{
tree prev = 0;
do {
tree ty, decl = TREE_VALUE (x);
ty = TREE_TYPE (decl);
if (ty == t && TREE_CODE (decl) != TYPE_DECL)
{
layout_decl (decl, 0);
maybe_objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0);
if (! toplevel)
expand_decl (decl);
if (prev)
TREE_CHAIN (prev) = TREE_CHAIN (x);
else
current_binding_level->incomplete_list = TREE_CHAIN (x);
}
else if (TYPE_SIZE (ty) == 0
&& TREE_CODE (ty) == ARRAY_TYPE)
{
tree element = ty;
while (TREE_CODE (element) == ARRAY_TYPE)
element = TREE_TYPE (element);
if (element == t)
layout_array_type (ty);
}
prev = x;
} while ((x = TREE_CHAIN (x)) != NULL);
}
resume_momentary (old_momentary);
rest_of_type_compilation (t, toplevel);
pop_obstacks ();
return t;
}
static void
layout_array_type (t)
tree t;
{
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
layout_array_type (TREE_TYPE (t));
layout_type (t);
}
tree
start_enum (name)
tree name;
{
register tree enumtype = 0;
if (name != 0)
enumtype = lookup_tag (ENUMERAL_TYPE, name, current_binding_level, 1);
push_obstacks_nochange ();
if (current_binding_level == global_binding_level)
end_temporary_allocation ();
if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE)
{
enumtype = make_node (ENUMERAL_TYPE);
pushtag (name, enumtype);
}
C_TYPE_BEING_DEFINED (enumtype) = 1;
if (TYPE_VALUES (enumtype) != 0)
{
error ("redeclaration of `enum %s'", IDENTIFIER_POINTER (name));
TYPE_VALUES (enumtype) = 0;
}
enum_next_value = integer_zero_node;
enum_overflow = 0;
if (flag_short_enums)
TYPE_PACKED (enumtype) = 1;
return enumtype;
}
tree
finish_enum (enumtype, values, attributes)
tree enumtype;
tree values;
tree attributes;
{
register tree pair, tem;
tree minnode = 0, maxnode = 0;
int lowprec, highprec, precision;
int toplevel = global_binding_level == current_binding_level;
if (in_parm_level_p ())
warning ("enum defined inside parms");
decl_attributes (enumtype, attributes, NULL_TREE);
if (values == error_mark_node)
minnode = maxnode = integer_zero_node;
else
for (pair = values; pair; pair = TREE_CHAIN (pair))
{
tree value = TREE_VALUE (pair);
if (pair == values)
minnode = maxnode = TREE_VALUE (pair);
else
{
if (tree_int_cst_lt (maxnode, value))
maxnode = value;
if (tree_int_cst_lt (value, minnode))
minnode = value;
}
}
TYPE_MIN_VALUE (enumtype) = minnode;
TYPE_MAX_VALUE (enumtype) = maxnode;
TREE_UNSIGNED (enumtype) = tree_int_cst_sgn (minnode) >= 0;
lowprec = min_precision (minnode, TREE_UNSIGNED (enumtype));
highprec = min_precision (maxnode, TREE_UNSIGNED (enumtype));
precision = MAX (lowprec, highprec);
if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
{
tree narrowest = type_for_size (precision, 1);
if (narrowest == 0)
{
warning ("enumeration values exceed range of largest integer");
narrowest = long_long_integer_type_node;
}
TYPE_PRECISION (enumtype) = TYPE_PRECISION (narrowest);
}
else
TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
TYPE_SIZE (enumtype) = 0;
layout_type (enumtype);
if (values != error_mark_node)
{
for (pair = values; pair; pair = TREE_CHAIN (pair))
{
TREE_TYPE (TREE_PURPOSE (pair)) = enumtype;
DECL_SIZE (TREE_PURPOSE (pair)) = TYPE_SIZE (enumtype);
if (TREE_CODE (TREE_PURPOSE (pair)) != FUNCTION_DECL)
DECL_ALIGN (TREE_PURPOSE (pair)) = TYPE_ALIGN (enumtype);
}
for (pair = values; pair; pair = TREE_CHAIN (pair))
TREE_PURPOSE (pair) = DECL_NAME (TREE_PURPOSE (pair));
TYPE_VALUES (enumtype) = values;
}
for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem))
{
TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
TYPE_MODE (tem) = TYPE_MODE (enumtype);
TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
}
rest_of_type_compilation (enumtype, toplevel);
pop_obstacks ();
return enumtype;
}
tree
build_enumerator (name, value)
tree name, value;
{
register tree decl, type;
if (value)
STRIP_TYPE_NOPS (value);
if (value != 0)
{
if (TREE_CODE (value) == INTEGER_CST)
{
value = default_conversion (value);
constant_expression_warning (value);
}
else
{
error ("enumerator value for `%s' not integer constant",
IDENTIFIER_POINTER (name));
value = 0;
}
}
if (value == 0)
{
value = enum_next_value;
if (enum_overflow)
error ("overflow in enumeration values");
}
if (pedantic && ! int_fits_type_p (value, integer_type_node))
{
pedwarn ("ANSI C restricts enumerator values to range of `int'");
value = integer_zero_node;
}
enum_next_value = build_binary_op (PLUS_EXPR, value, integer_one_node, 0);
enum_overflow = tree_int_cst_lt (enum_next_value, value);
type = TREE_TYPE (value);
type = type_for_size (MAX (TYPE_PRECISION (type),
TYPE_PRECISION (integer_type_node)),
((flag_traditional
|| TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))
&& TREE_UNSIGNED (type)));
decl = build_decl (CONST_DECL, name, type);
DECL_INITIAL (decl) = value;
TREE_TYPE (value) = type;
pushdecl (decl);
if (flag_dump_symbols)
printf ("+vm %s %u\n", IDENTIFIER_POINTER (name), lineno);
if (flag_gen_index)
dump_symbol_info ("+vm ", IDENTIFIER_POINTER (name), lineno);
return saveable_tree_cons (decl, value, NULL_TREE);
}
int
start_function (declspecs, declarator, prefix_attributes, attributes, nested)
tree declarator, declspecs, prefix_attributes, attributes;
int nested;
{
tree decl1, old_decl;
tree restype;
int old_immediate_size_expand = immediate_size_expand;
current_function_returns_value = 0;
current_function_returns_null = 0;
warn_about_return_type = 0;
current_extern_inline = 0;
c_function_varargs = 0;
named_labels = 0;
shadowed_labels = 0;
immediate_size_expand = 0;
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
if (decl1 == 0)
{
immediate_size_expand = old_immediate_size_expand;
return 0;
}
decl_attributes (decl1, prefix_attributes, attributes);
announce_function (decl1);
if (flag_dump_symbols)
{
const char *name;
name = IDENTIFIER_POINTER (DECL_NAME (decl1));
if (name[1] != '[')
printf ("+fm %s %u\n", name, lineno);
}
if (flag_gen_index)
{
const char *name;
name = IDENTIFIER_POINTER (DECL_NAME (decl1));
if (name[1] != '[')
dump_symbol_info ("+fm ", name, lineno);
}
if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl1))) == 0)
{
error ("return-type is an incomplete type");
TREE_TYPE (decl1)
= build_function_type (void_type_node,
TYPE_ARG_TYPES (TREE_TYPE (decl1)));
}
if (warn_about_return_type)
warning ("return-type defaults to `int'");
current_function_parms = last_function_parms;
current_function_parm_tags = last_function_parm_tags;
DECL_INITIAL (decl1) = error_mark_node;
old_decl = lookup_name_current_level (DECL_NAME (decl1));
if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
&& !DECL_BUILT_IN (old_decl)
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
== TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (old_decl))))
&& 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);
}
if (old_decl == 0)
old_decl = IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1));
if (warn_strict_prototypes
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
&& !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0))
warning ("function declaration isn't a prototype");
else if (warn_missing_prototypes
&& TREE_PUBLIC (decl1)
&& !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0)
&& strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))))
warning_with_decl (decl1, "no previous prototype for `%s'");
else if (warn_missing_prototypes
&& old_decl != 0 && TREE_USED (old_decl)
&& TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
warning_with_decl (decl1,
"`%s' was used with no prototype before its definition");
else if (warn_missing_declarations
&& TREE_PUBLIC (decl1)
&& old_decl == 0
&& strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))))
warning_with_decl (decl1, "no previous declaration for `%s'");
else if (warn_missing_declarations
&& old_decl != 0 && TREE_USED (old_decl)
&& old_decl == IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)))
warning_with_decl (decl1,
"`%s' was used with no declaration before its definition");
DECL_EXTERNAL (decl1) = current_extern_inline;
#ifdef SET_DEFAULT_DECL_ATTRIBUTES
SET_DEFAULT_DECL_ATTRIBUTES (decl1, attributes);
#endif
TREE_STATIC (decl1) = 1;
if (current_function_decl != 0)
TREE_PUBLIC (decl1) = 0;
if (warn_main > 0
&& strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))) == 0)
{
tree args;
int argct = 0;
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
!= integer_type_node)
pedwarn_with_decl (decl1, "return type of `%s' is not `int'");
for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
args = TREE_CHAIN (args))
{
tree type = args ? TREE_VALUE (args) : 0;
if (type == void_type_node)
break;
++argct;
switch (argct)
{
case 1:
if (TYPE_MAIN_VARIANT (type) != integer_type_node)
pedwarn_with_decl (decl1,
"first argument of `%s' should be `int'");
break;
case 2:
if (TREE_CODE (type) != POINTER_TYPE
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
pedwarn_with_decl (decl1,
"second argument of `%s' should be `char **'");
break;
case 3:
if (TREE_CODE (type) != POINTER_TYPE
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
pedwarn_with_decl (decl1,
"third argument of `%s' should probably be `char **'");
break;
}
}
if (argct > 0 && (argct < 2 || argct > 3))
pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments");
if (argct == 3 && pedantic)
pedwarn_with_decl (decl1, "third argument of `%s' is deprecated");
if (! TREE_PUBLIC (decl1))
pedwarn_with_decl (decl1, "`%s' is normally a non-static function");
}
current_function_decl = pushdecl (decl1);
pushlevel (0);
declare_parm_level (1);
current_binding_level->subblocks_tag_transparent = 1;
make_function_rtl (current_function_decl);
restype = TREE_TYPE (TREE_TYPE (current_function_decl));
if (C_PROMOTING_INTEGER_TYPE_P (restype))
{
if (TREE_UNSIGNED (restype)
&& (flag_traditional
|| (TYPE_PRECISION (restype)
== TYPE_PRECISION (integer_type_node))))
restype = unsigned_type_node;
else
restype = integer_type_node;
}
DECL_RESULT (current_function_decl)
= build_decl (RESULT_DECL, NULL_TREE, restype);
if (!nested)
temporary_allocation ();
if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))
TREE_ADDRESSABLE (current_function_decl) = 1;
immediate_size_expand = old_immediate_size_expand;
return 1;
}
void
c_mark_varargs ()
{
c_function_varargs = 1;
}
void
store_parm_decls ()
{
register tree fndecl = current_function_decl;
register tree parm;
tree specparms = current_function_parms;
tree parmtags = current_function_parm_tags;
register tree parmdecls = getdecls ();
tree nonparms = 0;
int prototype = 0;
if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
{
register tree next;
tree others = 0;
prototype = 1;
if (parmdecls != 0)
{
tree decl, link;
error_with_decl (fndecl,
"parm types given both in parmlist and separately");
for (decl = current_binding_level->names;
decl; decl = TREE_CHAIN (decl))
if (DECL_NAME (decl))
IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) = 0;
for (link = current_binding_level->shadowed;
link; link = TREE_CHAIN (link))
IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
current_binding_level->names = 0;
current_binding_level->shadowed = 0;
}
specparms = nreverse (specparms);
for (parm = specparms; parm; parm = next)
{
next = TREE_CHAIN (parm);
if (TREE_CODE (parm) == PARM_DECL)
{
if (DECL_NAME (parm) == 0)
error_with_decl (parm, "parameter name omitted");
else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
{
error_with_decl (parm, "parameter `%s' declared void");
TREE_TYPE (parm) = error_mark_node;
}
pushdecl (parm);
}
else
{
TREE_CHAIN (parm) = 0;
others = chainon (others, parm);
}
}
DECL_ARGUMENTS (fndecl) = getdecls ();
#if 0
if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
!= void_type_node)
{
tree dummy = build_decl (PARM_DECL, NULL_TREE, void_type_node);
TREE_TYPE (dummy) = integer_type_node;
DECL_ARG_TYPE (dummy) = integer_type_node;
DECL_ARGUMENTS (fndecl)
= chainon (DECL_ARGUMENTS (fndecl), dummy);
}
#endif
for (parm = others; parm; parm = next)
{
next = TREE_CHAIN (parm);
if (DECL_NAME (parm) == 0)
;
else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
;
else if (TREE_CODE (parm) != PARM_DECL)
pushdecl (parm);
}
storetags (chainon (parmtags, gettags ()));
}
else
{
for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
DECL_RESULT (parm) = 0;
for (parm = specparms; parm; parm = TREE_CHAIN (parm))
{
register tree tail, found = NULL;
if (TREE_VALUE (parm) == 0)
{
error_with_decl (fndecl, "parameter name missing from parameter list");
TREE_PURPOSE (parm) = 0;
continue;
}
for (tail = parmdecls; tail; tail = TREE_CHAIN (tail))
if (DECL_NAME (tail) == TREE_VALUE (parm)
&& TREE_CODE (tail) == PARM_DECL)
{
found = tail;
break;
}
if (found && DECL_RESULT (found) != 0)
{
error_with_decl (found, "multiple parameters named `%s'");
found = 0;
}
if (found && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == void_type_node)
{
error_with_decl (found, "parameter `%s' declared void");
TREE_TYPE (found) = integer_type_node;
DECL_ARG_TYPE (found) = integer_type_node;
layout_decl (found, 0);
}
if (found && flag_traditional
&& TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node)
{
TREE_TYPE (found) = double_type_node;
DECL_ARG_TYPE (found) = double_type_node;
layout_decl (found, 0);
}
if (!found)
{
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);
if (extra_warnings)
warning_with_decl (found, "type of `%s' defaults to `int'");
pushdecl (found);
}
TREE_PURPOSE (parm) = found;
DECL_RESULT (found) = error_mark_node;
}
nonparms = 0;
for (parm = parmdecls; parm; )
{
tree next = TREE_CHAIN (parm);
TREE_CHAIN (parm) = 0;
if (TREE_CODE (parm) != PARM_DECL)
nonparms = chainon (nonparms, parm);
else
{
if (TYPE_SIZE (TREE_TYPE (parm)) == 0)
{
error_with_decl (parm, "parameter `%s' has incomplete type");
TREE_TYPE (parm) = error_mark_node;
}
if (DECL_RESULT (parm) == 0)
{
error_with_decl (parm,
"declaration for parameter `%s' but no such parameter");
specparms
= chainon (specparms,
tree_cons (parm, NULL_TREE, NULL_TREE));
}
}
parm = next;
}
parm = specparms;
DECL_ARGUMENTS (fndecl) = 0;
{
register tree last;
for (last = 0; parm; parm = TREE_CHAIN (parm))
if (TREE_PURPOSE (parm))
{
if (last == 0)
DECL_ARGUMENTS (fndecl) = TREE_PURPOSE (parm);
else
TREE_CHAIN (last) = TREE_PURPOSE (parm);
last = TREE_PURPOSE (parm);
TREE_CHAIN (last) = 0;
}
}
if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
{
register tree type;
for (parm = DECL_ARGUMENTS (fndecl),
type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type))
!= void_type_node));
parm = TREE_CHAIN (parm), type = TREE_CHAIN (type))
{
if (parm == 0 || type == 0
|| 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");
break;
}
if (! comptypes (DECL_ARG_TYPE (parm), TREE_VALUE (type)))
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
== TYPE_MAIN_VARIANT (TREE_VALUE (type)))
{
DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
#ifdef PROMOTE_PROTOTYPES
if ((TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE
|| TREE_CODE (TREE_TYPE (parm)) == ENUMERAL_TYPE)
&& TYPE_PRECISION (TREE_TYPE (parm))
< TYPE_PRECISION (integer_type_node))
DECL_ARG_TYPE (parm) = integer_type_node;
#endif
if (pedantic)
{
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");
}
}
else if (! (flag_traditional
&& TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == integer_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))
{
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");
}
}
}
TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = 0;
}
else
{
tree actual = 0, last = 0, type;
for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
{
type = perm_tree_cons (NULL_TREE, DECL_ARG_TYPE (parm),
NULL_TREE);
if (last)
TREE_CHAIN (last) = type;
else
actual = type;
last = type;
}
type = perm_tree_cons (NULL_TREE, void_type_node, NULL_TREE);
if (last)
TREE_CHAIN (last) = type;
else
actual = type;
TREE_TYPE (fndecl) = build_type_copy (TREE_TYPE (fndecl));
TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual;
}
storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
}
keep_next_if_subblocks = 1;
#if 0
keep_next_level_flag = 1;
#endif
gen_aux_info_record (fndecl, 1, 0, prototype);
init_function_start (fndecl, input_filename, lineno);
if (c_function_varargs)
mark_varargs ();
declare_function_name ();
expand_function_start (fndecl, 0);
if (DECL_NAME (fndecl)
#ifdef _WIN32
&& (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
|| strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "WinMain") == 0)
#else
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
#endif
&& DECL_CONTEXT (fndecl) == NULL_TREE)
expand_main_function ();
}
tree
combine_parm_decls (specparms, parmlist, void_at_end)
tree specparms, parmlist;
int void_at_end;
{
register tree fndecl = current_function_decl;
register tree parm;
tree parmdecls = TREE_PURPOSE (parmlist);
tree nonparms = TREE_VALUE (parmlist);
tree types = 0;
for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
DECL_RESULT (parm) = 0;
for (parm = specparms; parm; parm = TREE_CHAIN (parm))
{
register tree tail, found = NULL;
for (tail = parmdecls; tail; tail = TREE_CHAIN (tail))
if (DECL_NAME (tail) == TREE_VALUE (parm))
{
found = tail;
break;
}
if (found && DECL_RESULT (found) != 0)
{
error_with_decl (found, "multiple parameters named `%s'");
found = 0;
}
if (found && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == void_type_node)
{
error_with_decl (found, "parameter `%s' declared void");
TREE_TYPE (found) = integer_type_node;
DECL_ARG_TYPE (found) = integer_type_node;
layout_decl (found, 0);
}
if (found && flag_traditional
&& TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node)
{
TREE_TYPE (found) = double_type_node;
DECL_ARG_TYPE (found) = double_type_node;
layout_decl (found, 0);
}
if (!found)
{
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);
error_with_decl (found, "type of parameter `%s' is not declared");
pushdecl (found);
}
TREE_PURPOSE (parm) = found;
DECL_RESULT (found) = error_mark_node;
}
for (parm = parmdecls; parm; )
{
tree next = TREE_CHAIN (parm);
TREE_CHAIN (parm) = 0;
if (TYPE_SIZE (TREE_TYPE (parm)) == 0)
{
error_with_decl (parm, "parameter `%s' has incomplete type");
TREE_TYPE (parm) = error_mark_node;
}
if (DECL_RESULT (parm) == 0)
{
error_with_decl (parm,
"declaration for parameter `%s' but no such parameter");
specparms
= chainon (specparms,
tree_cons (parm, NULL_TREE, NULL_TREE));
}
parm = next;
}
parm = specparms;
parmdecls = 0;
{
register tree last;
for (last = 0; parm; parm = TREE_CHAIN (parm))
if (TREE_PURPOSE (parm))
{
if (last == 0)
parmdecls = TREE_PURPOSE (parm);
else
TREE_CHAIN (last) = TREE_PURPOSE (parm);
last = TREE_PURPOSE (parm);
TREE_CHAIN (last) = 0;
types = saveable_tree_cons (NULL_TREE, TREE_TYPE (parm), types);
}
}
if (void_at_end)
return saveable_tree_cons (parmdecls, nonparms,
nreverse (saveable_tree_cons (NULL_TREE,
void_type_node,
types)));
return saveable_tree_cons (parmdecls, nonparms, nreverse (types));
}
void
finish_function (nested)
int nested;
{
register tree fndecl = current_function_decl;
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
#if defined(NEXT_SEMANTICS) || defined(NEXT_PDO)
if (current_function_calls_setjmp)
#else
if (flag_traditional && current_function_calls_setjmp)
#endif
{
setjmp_protect (DECL_INITIAL (fndecl));
setjmp_protect_args ();
}
if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main"))
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
!= integer_type_node)
{
if (! warn_main)
pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
}
else
{
#ifdef DEFAULT_MAIN_RETURN
DEFAULT_MAIN_RETURN;
#endif
}
}
expand_function_end (input_filename, lineno, 0);
can_reach_end = 0;
rest_of_compilation (fndecl);
current_function_returns_null |= can_reach_end;
if (warn_missing_noreturn
&& !TREE_THIS_VOLATILE (fndecl)
&& !current_function_returns_null
&& !current_function_returns_value)
warning ("function might be possible candidate for attribute `noreturn'");
if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
warning ("`noreturn' function does return");
else if (warn_return_type && can_reach_end
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) != void_type_node)
warning ("control reaches end of non-void function");
else if (extra_warnings
&& current_function_returns_value && current_function_returns_null)
warning ("this function may return with or without a value");
if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
{
register tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
if (ret_type)
{
register tree ret_type_size = TYPE_SIZE (ret_type);
if (TREE_CODE (ret_type_size) == INTEGER_CST)
{
unsigned units
= TREE_INT_CST_LOW (ret_type_size) / BITS_PER_UNIT;
if (units > larger_than_size)
warning_with_decl (fndecl,
"size of return value of `%s' is %u bytes",
units);
}
}
}
if (! nested)
permanent_allocation (1);
if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested)
{
if (DECL_INITIAL (fndecl) != 0)
DECL_INITIAL (fndecl) = error_mark_node;
DECL_ARGUMENTS (fndecl) = 0;
}
if (DECL_STATIC_CONSTRUCTOR (fndecl))
{
#ifndef ASM_OUTPUT_CONSTRUCTOR
if (! flag_gnu_linker)
static_ctors = perm_tree_cons (NULL_TREE, fndecl, static_ctors);
else
#endif
assemble_constructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
}
if (DECL_STATIC_DESTRUCTOR (fndecl))
{
#ifndef ASM_OUTPUT_DESTRUCTOR
if (! flag_gnu_linker)
static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors);
else
#endif
assemble_destructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
}
if (! nested)
{
current_function_decl = NULL;
}
}
struct c_function
{
struct c_function *next;
tree named_labels;
tree shadowed_labels;
int returns_value;
int returns_null;
int warn_about_return_type;
int extern_inline;
struct binding_level *binding_level;
};
struct c_function *c_function_chain;
void
push_c_function_context ()
{
struct c_function *p
= (struct c_function *) xmalloc (sizeof (struct c_function));
if (pedantic)
pedwarn ("ANSI C forbids nested functions");
push_function_context ();
p->next = c_function_chain;
c_function_chain = p;
p->named_labels = named_labels;
p->shadowed_labels = shadowed_labels;
p->returns_value = current_function_returns_value;
p->returns_null = current_function_returns_null;
p->warn_about_return_type = warn_about_return_type;
p->extern_inline = current_extern_inline;
p->binding_level = current_binding_level;
}
void
pop_c_function_context ()
{
struct c_function *p = c_function_chain;
tree link;
for (link = shadowed_labels; link; link = TREE_CHAIN (link))
if (DECL_NAME (TREE_VALUE (link)) != 0)
IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
= TREE_VALUE (link);
if (DECL_SAVED_INSNS (current_function_decl) == 0)
{
DECL_INITIAL (current_function_decl) = error_mark_node;
DECL_ARGUMENTS (current_function_decl) = 0;
}
pop_function_context ();
c_function_chain = p->next;
named_labels = p->named_labels;
shadowed_labels = p->shadowed_labels;
current_function_returns_value = p->returns_value;
current_function_returns_null = p->returns_null;
warn_about_return_type = p->warn_about_return_type;
current_extern_inline = p->extern_inline;
current_binding_level = p->binding_level;
free (p);
}
void
copy_lang_decl (node)
tree node ATTRIBUTE_UNUSED;
{
}
#if defined(NEXT_SEMANTICS) && !defined(MACOSX)
#ifdef OBJCPLUS
#define builtin_function(NAME, TYPE, CODE, LIBNAME) \
define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME)
#endif
int
call_destructor_dynamically (dfndecl)
tree dfndecl;
{
tree parms;
tree call;
tree atexit_decl;
tree atexit_type;
extern tree default_function_type;
extern tree void_type_node;
atexit_type
= build_function_type (void_type_node,
tree_cons (NULL_TREE, default_function_type,
NULL_TREE));
atexit_decl =(tree) builtin_function ("atexit",
atexit_type,
NOT_BUILT_IN, 0);
parms = (tree) build_tree_list (NULL_TREE,
build1 (ADDR_EXPR,
default_function_type, dfndecl));
call = build_function_call (atexit_decl, parms);
expand_call (call, 0, 0);
}
#endif