diff options
author | peter <peter@FreeBSD.org> | 1996-09-19 15:53:53 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-09-19 15:53:53 +0000 |
commit | 091fc15006d29ea89428d3a2e70f88036e5e8384 (patch) | |
tree | dde8c3c6cc96fffa0ab7be0605216c2b88a75739 /gnu/usr.bin/cc/cc1 | |
parent | f44d436f84da49b642b4ab474f05862ec45e3336 (diff) | |
download | FreeBSD-src-091fc15006d29ea89428d3a2e70f88036e5e8384.zip FreeBSD-src-091fc15006d29ea89428d3a2e70f88036e5e8384.tar.gz |
Man the lifeboats! Tie down the hatches! Red alert! Activate gcc-2.7.2.1!
(the old cc has been tagged with "gcc_2_6_3_final" so we have a reference
point in case of unforseen disasters...)
This has the objc backend active, and I think I've managed to get the
f77 f2c support through in one piece, but I don't know fortran to test it.
A 'make world' change and libobjc commit will follow.
If you normally do 'make -DNOCLEAN world', do not do so this time, I know
it can fail with groff.
This version of gcc makes a **LOT** more warnings on our kernel.
Diffstat (limited to 'gnu/usr.bin/cc/cc1')
-rw-r--r-- | gnu/usr.bin/cc/cc1/Makefile | 8 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-aux-info.c | 639 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-convert.c | 95 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-decl.c | 6799 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-iterate.c | 595 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-lang.c | 129 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-lex.c | 1983 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-parse.c | 3535 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-pragma.c | 188 | ||||
-rw-r--r-- | gnu/usr.bin/cc/cc1/c-typeck.c | 6414 |
10 files changed, 5 insertions, 20380 deletions
diff --git a/gnu/usr.bin/cc/cc1/Makefile b/gnu/usr.bin/cc/cc1/Makefile index 0266f86..00c970a 100644 --- a/gnu/usr.bin/cc/cc1/Makefile +++ b/gnu/usr.bin/cc/cc1/Makefile @@ -1,9 +1,11 @@ # -# $Id: Makefile,v 1.6 1995/09/22 14:14:21 phk Exp $ +# $Id$ # - + PROG = cc1 -SRCS = c-aux-info.c c-convert.c c-decl.c c-iterate.c c-lang.c c-lex.c c-parse.c c-pragma.c c-typeck.c +SRCS = c-parse.c \ + c-aux-info.c c-convert.c c-decl.c c-iterate.c c-lang.c c-lex.c \ + c-typeck.c BINDIR= /usr/libexec NOMAN= 1 NOSHARED= true diff --git a/gnu/usr.bin/cc/cc1/c-aux-info.c b/gnu/usr.bin/cc/cc1/c-aux-info.c deleted file mode 100644 index 669e39f..0000000 --- a/gnu/usr.bin/cc/cc1/c-aux-info.c +++ /dev/null @@ -1,639 +0,0 @@ -/* Generate information regarding function declarations and definitions based - on information stored in GCC's tree structure. This code implements the - -aux-info option. - Copyright (C) 1989, 1991, 1994 Free Software Foundation, Inc. - Contributed by Ron Guilmette (rfg@netcom.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <stdio.h> -#include "config.h" -#include "flags.h" -#include "tree.h" -#include "c-tree.h" - -extern char* xmalloc (); - -enum formals_style_enum { - ansi, - k_and_r_names, - k_and_r_decls -}; -typedef enum formals_style_enum formals_style; - - -static char* data_type; - -static char * concat (); -static char * concat3 (); -static char * gen_formal_list_for_type (); -static int deserves_ellipsis (); -static char * gen_formal_list_for_func_def (); -static char * gen_type (); -static char * gen_decl (); -void gen_aux_info_record (); - -/* Take two strings and mash them together into a newly allocated area. */ - -static char* -concat (s1, s2) - char* s1; - char* s2; -{ - int size1, size2; - char* ret_val; - - if (!s1) - s1 = ""; - if (!s2) - s2 = ""; - - size1 = strlen (s1); - size2 = strlen (s2); - ret_val = xmalloc (size1 + size2 + 1); - strcpy (ret_val, s1); - strcpy (&ret_val[size1], s2); - return ret_val; -} - -/* Take three strings and mash them together into a newly allocated area. */ - -static char* -concat3 (s1, s2, s3) - char* s1; - char* s2; - char* s3; -{ - int size1, size2, size3; - char* ret_val; - - if (!s1) - s1 = ""; - if (!s2) - s2 = ""; - if (!s3) - s3 = ""; - - size1 = strlen (s1); - size2 = strlen (s2); - size3 = strlen (s3); - ret_val = xmalloc (size1 + size2 + size3 + 1); - strcpy (ret_val, s1); - strcpy (&ret_val[size1], s2); - strcpy (&ret_val[size1+size2], s3); - return ret_val; -} - -/* Given a string representing an entire type or an entire declaration - which only lacks the actual "data-type" specifier (at its left end), - affix the data-type specifier to the left end of the given type - specification or object declaration. - - Because of C language weirdness, the data-type specifier (which normally - goes in at the very left end) may have to be slipped in just to the - right of any leading "const" or "volatile" qualifiers (there may be more - than one). Actually this may not be strictly necessary because it seems - that GCC (at least) accepts `<data-type> const foo;' and treats it the - same as `const <data-type> foo;' but people are accustomed to seeing - `const char *foo;' and *not* `char const *foo;' so we try to create types - that look as expected. */ - -static char* -affix_data_type (type_or_decl) - char *type_or_decl; -{ - char *p = type_or_decl; - char *qualifiers_then_data_type; - char saved; - - /* Skip as many leading const's or volatile's as there are. */ - - for (;;) - { - if (!strncmp (p, "volatile ", 9)) - { - p += 9; - continue; - } - if (!strncmp (p, "const ", 6)) - { - p += 6; - continue; - } - break; - } - - /* p now points to the place where we can insert the data type. We have to - add a blank after the data-type of course. */ - - if (p == type_or_decl) - return concat3 (data_type, " ", type_or_decl); - - saved = *p; - *p = '\0'; - qualifiers_then_data_type = concat (type_or_decl, data_type); - *p = saved; - return concat3 (qualifiers_then_data_type, " ", p); -} - -/* Given a tree node which represents some "function type", generate the - source code version of a formal parameter list (of some given style) for - this function type. Return the whole formal parameter list (including - a pair of surrounding parens) as a string. Note that if the style - we are currently aiming for is non-ansi, then we just return a pair - of empty parens here. */ - -static char* -gen_formal_list_for_type (fntype, style) - tree fntype; - formals_style style; -{ - char* formal_list = ""; - tree formal_type; - - if (style != ansi) - return "()"; - - formal_type = TYPE_ARG_TYPES (fntype); - while (formal_type && TREE_VALUE (formal_type) != void_type_node) - { - char* this_type; - - if (*formal_list) - formal_list = concat (formal_list, ", "); - - this_type = gen_type ("", TREE_VALUE (formal_type), ansi); - formal_list = - (strlen (this_type)) - ? concat (formal_list, affix_data_type (this_type)) - : concat (formal_list, data_type); - - formal_type = TREE_CHAIN (formal_type); - } - - /* If we got to here, then we are trying to generate an ANSI style formal - parameters list. - - New style prototyped ANSI formal parameter lists should in theory always - contain some stuff between the opening and closing parens, even if it is - only "void". - - The brutal truth though is that there is lots of old K&R code out there - which contains declarations of "pointer-to-function" parameters and - these almost never have fully specified formal parameter lists associated - with them. That is, the pointer-to-function parameters are declared - with just empty parameter lists. - - In cases such as these, protoize should really insert *something* into - the vacant parameter lists, but what? It has no basis on which to insert - anything in particular. - - Here, we make life easy for protoize by trying to distinguish between - K&R empty parameter lists and new-style prototyped parameter lists - that actually contain "void". In the latter case we (obviously) want - to output the "void" verbatim, and that what we do. In the former case, - we do our best to give protoize something nice to insert. - - This "something nice" should be something that is still legal (when - re-compiled) but something that can clearly indicate to the user that - more typing information (for the parameter list) should be added (by - hand) at some convenient moment. - - The string chosen here is a comment with question marks in it. */ - - if (!*formal_list) - { - if (TYPE_ARG_TYPES (fntype)) - /* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */ - formal_list = "void"; - else - formal_list = "/* ??? */"; - } - else - { - /* If there were at least some parameters, and if the formals-types-list - petered out to a NULL (i.e. without being terminated by a - void_type_node) then we need to tack on an ellipsis. */ - if (!formal_type) - formal_list = concat (formal_list, ", ..."); - } - - return concat3 (" (", formal_list, ")"); -} - -/* For the generation of an ANSI prototype for a function definition, we have - to look at the formal parameter list of the function's own "type" to - determine if the function's formal parameter list should end with an - ellipsis. Given a tree node, the following function will return non-zero - if the "function type" parameter list should end with an ellipsis. */ - -static int -deserves_ellipsis (fntype) - tree fntype; -{ - tree formal_type; - - formal_type = TYPE_ARG_TYPES (fntype); - while (formal_type && TREE_VALUE (formal_type) != void_type_node) - formal_type = TREE_CHAIN (formal_type); - - /* If there were at least some parameters, and if the formals-types-list - petered out to a NULL (i.e. without being terminated by a void_type_node) - then we need to tack on an ellipsis. */ - - return (!formal_type && TYPE_ARG_TYPES (fntype)); -} - -/* Generate a parameter list for a function definition (in some given style). - - Note that this routine has to be separate (and different) from the code that - generates the prototype parameter lists for function declarations, because - in the case of a function declaration, all we have to go on is a tree node - representing the function's own "function type". This can tell us the types - of all of the formal parameters for the function, but it cannot tell us the - actual *names* of each of the formal parameters. We need to output those - parameter names for each function definition. - - This routine gets a pointer to a tree node which represents the actual - declaration of the given function, and this DECL node has a list of formal - parameter (variable) declarations attached to it. These formal parameter - (variable) declaration nodes give us the actual names of the formal - parameters for the given function definition. - - This routine returns a string which is the source form for the entire - function formal parameter list. */ - -static char* -gen_formal_list_for_func_def (fndecl, style) - tree fndecl; - formals_style style; -{ - char* formal_list = ""; - tree formal_decl; - - formal_decl = DECL_ARGUMENTS (fndecl); - while (formal_decl) - { - char *this_formal; - - if (*formal_list && ((style == ansi) || (style == k_and_r_names))) - formal_list = concat (formal_list, ", "); - this_formal = gen_decl (formal_decl, 0, style); - if (style == k_and_r_decls) - formal_list = concat3 (formal_list, this_formal, "; "); - else - formal_list = concat (formal_list, this_formal); - formal_decl = TREE_CHAIN (formal_decl); - } - if (style == ansi) - { - if (!DECL_ARGUMENTS (fndecl)) - formal_list = concat (formal_list, "void"); - if (deserves_ellipsis (TREE_TYPE (fndecl))) - formal_list = concat (formal_list, ", ..."); - } - if ((style == ansi) || (style == k_and_r_names)) - formal_list = concat3 (" (", formal_list, ")"); - return formal_list; -} - -/* Generate a string which is the source code form for a given type (t). This - routine is ugly and complex because the C syntax for declarations is ugly - and complex. This routine is straightforward so long as *no* pointer types, - array types, or function types are involved. - - In the simple cases, this routine will return the (string) value which was - passed in as the "ret_val" argument. Usually, this starts out either as an - empty string, or as the name of the declared item (i.e. the formal function - parameter variable). - - This routine will also return with the global variable "data_type" set to - some string value which is the "basic" data-type of the given complete type. - This "data_type" string can be concatenated onto the front of the returned - string after this routine returns to its caller. - - In complicated cases involving pointer types, array types, or function - types, the C declaration syntax requires an "inside out" approach, i.e. if - you have a type which is a "pointer-to-function" type, you need to handle - the "pointer" part first, but it also has to be "innermost" (relative to - the declaration stuff for the "function" type). Thus, is this case, you - must prepend a "(*" and append a ")" to the name of the item (i.e. formal - variable). Then you must append and prepend the other info for the - "function type" part of the overall type. - - To handle the "innermost precedence" rules of complicated C declarators, we - do the following (in this routine). The input parameter called "ret_val" - is treated as a "seed". Each time gen_type is called (perhaps recursively) - some additional strings may be appended or prepended (or both) to the "seed" - string. If yet another (lower) level of the GCC tree exists for the given - type (as in the case of a pointer type, an array type, or a function type) - then the (wrapped) seed is passed to a (recursive) invocation of gen_type() - this recursive invocation may again "wrap" the (new) seed with yet more - declarator stuff, by appending, prepending (or both). By the time the - recursion bottoms out, the "seed value" at that point will have a value - which is (almost) the complete source version of the declarator (except - for the data_type info). Thus, this deepest "seed" value is simply passed - back up through all of the recursive calls until it is given (as the return - value) to the initial caller of the gen_type() routine. All that remains - to do at this point is for the initial caller to prepend the "data_type" - string onto the returned "seed". */ - -static char* -gen_type (ret_val, t, style) - char* ret_val; - tree t; - formals_style style; -{ - tree chain_p; - - if (TYPE_NAME (t) && DECL_NAME (TYPE_NAME (t))) - data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); - else - { - switch (TREE_CODE (t)) - { - case POINTER_TYPE: - if (TYPE_READONLY (t)) - ret_val = concat ("const ", ret_val); - if (TYPE_VOLATILE (t)) - ret_val = concat ("volatile ", ret_val); - - ret_val = concat ("*", ret_val); - - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) - ret_val = concat3 ("(", ret_val, ")"); - - ret_val = gen_type (ret_val, TREE_TYPE (t), style); - - return ret_val; - - case ARRAY_TYPE: - if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST) - ret_val = gen_type (concat (ret_val, "[]"), TREE_TYPE (t), style); - else if (int_size_in_bytes (t) == 0) - ret_val = gen_type (concat (ret_val, "[0]"), TREE_TYPE (t), style); - else - { - int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t))); - char buff[10]; - sprintf (buff, "[%d]", size); - ret_val = gen_type (concat (ret_val, buff), - TREE_TYPE (t), style); - } - break; - - case FUNCTION_TYPE: - ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style)), TREE_TYPE (t), style); - break; - - case IDENTIFIER_NODE: - data_type = IDENTIFIER_POINTER (t); - break; - - /* The following three cases are complicated by the fact that a - user may do something really stupid, like creating a brand new - "anonymous" type specification in a formal argument list (or as - part of a function return type specification). For example: - - int f (enum { red, green, blue } color); - - In such cases, we have no name that we can put into the prototype - to represent the (anonymous) type. Thus, we have to generate the - whole darn type specification. Yuck! */ - - case RECORD_TYPE: - if (TYPE_NAME (t)) - data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); - else - { - data_type = ""; - chain_p = TYPE_FIELDS (t); - while (chain_p) - { - data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); - chain_p = TREE_CHAIN (chain_p); - data_type = concat (data_type, "; "); - } - data_type = concat3 ("{ ", data_type, "}"); - } - data_type = concat ("struct ", data_type); - break; - - case UNION_TYPE: - if (TYPE_NAME (t)) - data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); - else - { - data_type = ""; - chain_p = TYPE_FIELDS (t); - while (chain_p) - { - data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); - chain_p = TREE_CHAIN (chain_p); - data_type = concat (data_type, "; "); - } - data_type = concat3 ("{ ", data_type, "}"); - } - data_type = concat ("union ", data_type); - break; - - case ENUMERAL_TYPE: - if (TYPE_NAME (t)) - data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); - else - { - data_type = ""; - chain_p = TYPE_VALUES (t); - while (chain_p) - { - data_type = concat (data_type, - IDENTIFIER_POINTER (TREE_PURPOSE (chain_p))); - chain_p = TREE_CHAIN (chain_p); - if (chain_p) - data_type = concat (data_type, ", "); - } - data_type = concat3 ("{ ", data_type, " }"); - } - data_type = concat ("enum ", data_type); - break; - - case TYPE_DECL: - data_type = IDENTIFIER_POINTER (DECL_NAME (t)); - break; - - case INTEGER_TYPE: - data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); - /* Normally, `unsigned' is part of the deal. Not so if it comes - with `const' or `volatile'. */ - if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t))) - data_type = concat ("unsigned ", data_type); - break; - - case REAL_TYPE: - data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); - break; - - case VOID_TYPE: - data_type = "void"; - break; - - default: - abort (); - } - } - if (TYPE_READONLY (t)) - ret_val = concat ("const ", ret_val); - if (TYPE_VOLATILE (t)) - ret_val = concat ("volatile ", ret_val); - return ret_val; -} - -/* Generate a string (source) representation of an entire entity declaration - (using some particular style for function types). - - The given entity may be either a variable or a function. - - If the "is_func_definition" parameter is non-zero, assume that the thing - we are generating a declaration for is a FUNCTION_DECL node which is - associated with a function definition. In this case, we can assume that - an attached list of DECL nodes for function formal arguments is present. */ - -static char* -gen_decl (decl, is_func_definition, style) - tree decl; - int is_func_definition; - formals_style style; -{ - char* ret_val; - - if (DECL_NAME (decl)) - ret_val = IDENTIFIER_POINTER (DECL_NAME (decl)); - else - ret_val = ""; - - /* If we are just generating a list of names of formal parameters, we can - simply return the formal parameter name (with no typing information - attached to it) now. */ - - if (style == k_and_r_names) - return ret_val; - - /* Note that for the declaration of some entity (either a function or a - data object, like for instance a parameter) if the entity itself was - declared as either const or volatile, then const and volatile properties - are associated with just the declaration of the entity, and *not* with - the `type' of the entity. Thus, for such declared entities, we have to - generate the qualifiers here. */ - - if (TREE_THIS_VOLATILE (decl)) - ret_val = concat ("volatile ", ret_val); - if (TREE_READONLY (decl)) - ret_val = concat ("const ", ret_val); - - data_type = ""; - - /* For FUNCTION_DECL nodes, there are two possible cases here. First, if - this FUNCTION_DECL node was generated from a function "definition", then - we will have a list of DECL_NODE's, one for each of the function's formal - parameters. In this case, we can print out not only the types of each - formal, but also each formal's name. In the second case, this - FUNCTION_DECL node came from an actual function declaration (and *not* - a definition). In this case, we do nothing here because the formal - argument type-list will be output later, when the "type" of the function - is added to the string we are building. Note that the ANSI-style formal - parameter list is considered to be a (suffix) part of the "type" of the - function. */ - - if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition) - { - ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi)); - - /* Since we have already added in the formals list stuff, here we don't - add the whole "type" of the function we are considering (which - would include its parameter-list info), rather, we only add in - the "type" of the "type" of the function, which is really just - the return-type of the function (and does not include the parameter - list info). */ - - ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style); - } - else - ret_val = gen_type (ret_val, TREE_TYPE (decl), style); - - ret_val = affix_data_type (ret_val); - - if (DECL_REGISTER (decl)) - ret_val = concat ("register ", ret_val); - if (TREE_PUBLIC (decl)) - ret_val = concat ("extern ", ret_val); - if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl)) - ret_val = concat ("static ", ret_val); - - return ret_val; -} - -extern FILE* aux_info_file; - -/* Generate and write a new line of info to the aux-info (.X) file. This - routine is called once for each function declaration, and once for each - function definition (even the implicit ones). */ - -void -gen_aux_info_record (fndecl, is_definition, is_implicit, is_prototyped) - tree fndecl; - int is_definition; - int is_implicit; - int is_prototyped; -{ - if (flag_gen_aux_info) - { - static int compiled_from_record = 0; - - /* Each output .X file must have a header line. Write one now if we - have not yet done so. */ - - if (! compiled_from_record++) - { - /* The first line tells which directory file names are relative to. - Currently, -aux-info works only for files in the working - directory, so just use a `.' as a placeholder for now. */ - fprintf (aux_info_file, "/* compiled from: . */\n"); - } - - /* Write the actual line of auxiliary info. */ - - fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;", - DECL_SOURCE_FILE (fndecl), - DECL_SOURCE_LINE (fndecl), - (is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O', - (is_definition) ? 'F' : 'C', - gen_decl (fndecl, is_definition, ansi)); - - /* If this is an explicit function declaration, we need to also write - out an old-style (i.e. K&R) function header, just in case the user - wants to run unprotoize. */ - - if (is_definition) - { - fprintf (aux_info_file, " /*%s %s*/", - gen_formal_list_for_func_def (fndecl, k_and_r_names), - gen_formal_list_for_func_def (fndecl, k_and_r_decls)); - } - - fprintf (aux_info_file, "\n"); - } -} diff --git a/gnu/usr.bin/cc/cc1/c-convert.c b/gnu/usr.bin/cc/cc1/c-convert.c deleted file mode 100644 index cfa590c..0000000 --- a/gnu/usr.bin/cc/cc1/c-convert.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Language-level data type conversion for GNU C. - Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* This file contains the functions for converting C expressions - to different data types. The only entry point is `convert'. - Every language front end must have a `convert' function - but what kind of conversions it does will depend on the language. */ - -#include "config.h" -#include "tree.h" -#include "flags.h" -#include "convert.h" - -/* Change of width--truncation and extension of integers or reals-- - is represented with NOP_EXPR. Proper functioning of many things - assumes that no other conversions can be NOP_EXPRs. - - Conversion between integer and pointer is represented with CONVERT_EXPR. - Converting integer to real uses FLOAT_EXPR - and real to integer uses FIX_TRUNC_EXPR. - - Here is a list of all the functions that assume that widening and - narrowing is always done with a NOP_EXPR: - In convert.c, convert_to_integer. - In c-typeck.c, build_binary_op (boolean ops), and truthvalue_conversion. - In expr.c: expand_expr, for operands of a MULT_EXPR. - In fold-const.c: fold. - In tree.c: get_narrower and get_unwidened. */ - -/* Subroutines of `convert'. */ - - - -/* Create an expression whose value is that of EXPR, - converted to type TYPE. The TREE_TYPE of the value - is always TYPE. This function implements all reasonable - conversions; callers should filter out those that are - not permitted by the language being compiled. */ - -tree -convert (type, expr) - tree type, expr; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (type == TREE_TYPE (expr) - || TREE_CODE (expr) == ERROR_MARK) - return expr; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold (build1 (NOP_EXPR, type, expr)); - if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK) - return error_mark_node; - if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - if (code == VOID_TYPE) - return build1 (CONVERT_EXPR, type, e); -#if 0 - /* This is incorrect. A truncation can't be stripped this way. - Extensions will be stripped by the use of get_unwidened. */ - if (TREE_CODE (expr) == NOP_EXPR) - return convert (type, TREE_OPERAND (expr, 0)); -#endif - if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) - return fold (convert_to_integer (type, e)); - if (code == POINTER_TYPE) - return fold (convert_to_pointer (type, e)); - if (code == REAL_TYPE) - return fold (convert_to_real (type, e)); - if (code == COMPLEX_TYPE) - return fold (convert_to_complex (type, e)); - - error ("conversion to non-scalar type requested"); - return error_mark_node; -} diff --git a/gnu/usr.bin/cc/cc1/c-decl.c b/gnu/usr.bin/cc/cc1/c-decl.c deleted file mode 100644 index afdd1d6..0000000 --- a/gnu/usr.bin/cc/cc1/c-decl.c +++ /dev/null @@ -1,6799 +0,0 @@ -/* Process declarations and variables for C compiler. - Copyright (C) 1988, 1992, 1993, 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* Process declarations and symbol lookup for C front end. - Also constructs types; the standard scalar types at initialization, - and structure, union, array and enum types when they are declared. */ - -/* ??? not all decl nodes are given the most useful possible - line numbers. For example, the CONST_DECLs for enum values. */ - -#include "config.h" -#include "tree.h" -#include "flags.h" -#include "c-tree.h" -#include "c-lex.h" -#include <stdio.h> - -/* In grokdeclarator, distinguish syntactic contexts of declarators. */ -enum decl_context -{ NORMAL, /* Ordinary declaration */ - FUNCDEF, /* Function definition */ - PARM, /* Declaration of parm before function body */ - FIELD, /* Declaration inside struct or union */ - BITFIELD, /* Likewise but with specified width */ - TYPENAME}; /* Typename (inside cast or sizeof) */ - -#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 - -/* We let tm.h override the types used here, to handle trivial differences - such as the choice of unsigned int or long unsigned int for size_t. - When machines start needing nontrivial differences in the size type, - it would be best to do something here to figure out automatically - from other information what type to use. */ - -#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 - -/* a node which has tree code ERROR_MARK, and whose type is itself. - All erroneous expressions are replaced with this node. All functions - that accept nodes as arguments should avoid generating error messages - if this node is one of the arguments, since it is undesirable to get - multiple error messages from one error in the input. */ - -tree error_mark_node; - -/* INTEGER_TYPE and REAL_TYPE nodes for the standard data types */ - -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 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 intQI_type_node; -tree intHI_type_node; -tree intSI_type_node; -tree intDI_type_node; - -tree unsigned_intQI_type_node; -tree unsigned_intHI_type_node; -tree unsigned_intSI_type_node; -tree unsigned_intDI_type_node; - -/* a VOID_TYPE node. */ - -tree void_type_node; - -/* Nodes for types `void *' and `const void *'. */ - -tree ptr_type_node, const_ptr_type_node; - -/* Nodes for types `char *' and `const char *'. */ - -tree string_type_node, const_string_type_node; - -/* Type `char[SOMENUMBER]'. - Used when an array of char is needed and the size is irrelevant. */ - -tree char_array_type_node; - -/* Type `int[SOMENUMBER]' or something like it. - Used when an array of int needed and the size is irrelevant. */ - -tree int_array_type_node; - -/* Type `wchar_t[SOMENUMBER]' or something like it. - Used when a wide string literal is created. */ - -tree wchar_array_type_node; - -/* type `int ()' -- used for implicit declaration of functions. */ - -tree default_function_type; - -/* function types `double (double)' and `double (double, double)', etc. */ - -tree double_ftype_double, double_ftype_double_double; -tree int_ftype_int, long_ftype_long; - -/* Function type `void (void *, void *, int)' and similar ones */ - -tree void_ftype_ptr_ptr_int, int_ftype_ptr_ptr_int, void_ftype_ptr_int_int; - -/* Function type `char *(char *, char *)' and similar ones */ -tree string_ftype_ptr_ptr, int_ftype_string_string; - -/* Function type `int (const void *, const void *, size_t)' */ -tree int_ftype_cptr_cptr_sizet; - -/* Two expressions that are constants with value zero. - The first is of type `int', the second of type `void *'. */ - -tree integer_zero_node; -tree null_pointer_node; - -/* A node for the integer constant 1. */ - -tree integer_one_node; - -/* Nonzero if we have seen an invalid cross reference - to a struct, union, or enum, but not yet printed the message. */ - -tree pending_invalid_xref; -/* File and line to appear in the eventual error message. */ -char *pending_invalid_xref_file; -int pending_invalid_xref_line; - -/* While defining an enum type, this is 1 plus the last enumerator - constant value. Note that will do not have to save this or `enum_overflow' - around nested function definition since such a definition could only - occur in an enum value expression and we don't use these variables in - that case. */ - -static tree enum_next_value; - -/* Nonzero means that there was overflow computing enum_next_value. */ - -static int enum_overflow; - -/* Parsing a function declarator leaves a list of parameter names - or a chain or parameter decls here. */ - -static tree last_function_parms; - -/* Parsing a function declarator leaves here a chain of structure - and enum types declared in the parmlist. */ - -static tree last_function_parm_tags; - -/* After parsing the declarator that starts a function definition, - `start_function' puts here the list of parameter names or chain of decls. - `store_parm_decls' finds it here. */ - -static tree current_function_parms; - -/* Similar, for last_function_parm_tags. */ -static tree current_function_parm_tags; - -/* Similar, for the file and line that the prototype came from if this is - an old-style definition. */ -static char *current_function_prototype_file; -static int current_function_prototype_line; - -/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function - that have names. Here so we can clear out their names' definitions - at the end of the function. */ - -static tree named_labels; - -/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ - -static tree shadowed_labels; - -/* Nonzero when store_parm_decls is called indicates a varargs function. - Value not meaningful after store_parm_decls. */ - -static int c_function_varargs; - -/* The FUNCTION_DECL for the function currently being compiled, - or 0 if between functions. */ -tree current_function_decl; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement that specifies a return value is seen. */ - -int current_function_returns_value; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement with no argument is seen. */ - -int current_function_returns_null; - -/* Set to nonzero by `grokdeclarator' for a function - whose return type is defaulted, if warnings for this are desired. */ - -static int warn_about_return_type; - -/* Nonzero when starting a function declared `extern inline'. */ - -static int current_extern_inline; - -/* For each binding contour we allocate a binding_level structure - * which records the names defined in that contour. - * Contours include: - * 0) the global one - * 1) one for each function definition, - * where internal declarations of the parameters appear. - * 2) one for each compound statement, - * to record its declarations. - * - * The current meaning of a name can be found by searching the levels from - * the current one out to the global one. - */ - -/* Note that the information in the `names' component of the global contour - is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ - -struct binding_level - { - /* A chain of _DECL nodes for all variables, constants, functions, - and typedef types. These are in the reverse of the order supplied. - */ - tree names; - - /* A list of structure, union and enum definitions, - * for looking up tag names. - * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name, - * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE, - * or ENUMERAL_TYPE node. - */ - tree tags; - - /* For each level, a list of shadowed outer-level local definitions - to be restored when this level is popped. - Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and - whose TREE_VALUE is its old definition (a kind of ..._DECL node). */ - tree shadowed; - - /* For each level (except not the global one), - a chain of BLOCK nodes for all the levels - that were entered and exited one level down. */ - tree blocks; - - /* The BLOCK node for this level, if one has been preallocated. - If 0, the BLOCK is allocated (if needed) when the level is popped. */ - tree this_block; - - /* The binding level which this one is contained in (inherits from). */ - struct binding_level *level_chain; - - /* Nonzero for the level that holds the parameters of a function. */ - char parm_flag; - - /* Nonzero if this level "doesn't exist" for tags. */ - char tag_transparent; - - /* Nonzero if sublevels of this level "don't exist" for tags. - This is set in the parm level of a function definition - while reading the function body, so that the outermost block - of the function body will be tag-transparent. */ - char subblocks_tag_transparent; - - /* Nonzero means make a BLOCK for this level regardless of all else. */ - char keep; - - /* Nonzero means make a BLOCK if this level has any subblocks. */ - char keep_if_subblocks; - - /* Number of decls in `names' that have incomplete - structure or union types. */ - int n_incomplete; - - /* A list of decls giving the (reversed) specified order of parms, - not including any forward-decls in the parmlist. - This is so we can put the parms in proper order for assign_parms. */ - tree parm_order; - }; - -#define NULL_BINDING_LEVEL (struct binding_level *) NULL - -/* The binding level currently in effect. */ - -static struct binding_level *current_binding_level; - -/* A chain of binding_level structures awaiting reuse. */ - -static struct binding_level *free_binding_level; - -/* The outermost binding level, for names of file scope. - This is created when the compiler is started and exists - through the entire run. */ - -static struct binding_level *global_binding_level; - -/* Binding level structures are initialized by copying this one. */ - -static struct binding_level clear_binding_level - = {NULL, NULL, NULL, NULL, NULL, NULL_BINDING_LEVEL, 0, 0, 0, 0, 0, 0, - NULL}; - -/* Nonzero means unconditionally make a BLOCK for the next level pushed. */ - -static int keep_next_level_flag; - -/* Nonzero means make a BLOCK for the next level pushed - if it has subblocks. */ - -static int keep_next_if_subblocks; - -/* The chain of outer levels of label scopes. - This uses the same data structure used for binding levels, - but it works differently: each link in the chain records - saved values of named_labels and shadowed_labels for - a label binding level outside the current one. */ - -static struct binding_level *label_level_chain; - -/* Forward declarations. */ - -static tree grokparms (), grokdeclarator (); -tree pushdecl (); -tree builtin_function (); -void shadow_tag_warned (); - -static tree lookup_tag (); -static tree lookup_tag_reverse (); -tree lookup_name_current_level (); -static char *redeclaration_error_message (); -static void layout_array_type (); - -/* C-specific option variables. */ - -/* Nonzero means allow type mismatches in conditional expressions; - just make their values `void'. */ - -int flag_cond_mismatch; - -/* Nonzero means give `double' the same size as `float'. */ - -int flag_short_double; - -/* Nonzero means don't recognize the keyword `asm'. */ - -int flag_no_asm; - -/* Nonzero means don't recognize any builtin functions. */ - -int flag_no_builtin; - -/* Nonzero means don't recognize the non-ANSI builtin functions. - -ansi sets this. */ - -int flag_no_nonansi_builtin; - -/* Nonzero means do some things the same way PCC does. */ - -int flag_traditional; - -/* Nonzero means to allow single precision math even if we're generally - being traditional. */ -int flag_allow_single_precision = 0; - -/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */ - -int flag_signed_bitfields = 1; -int explicit_flag_signed_bitfields = 0; - -/* Nonzero means handle `#ident' directives. 0 means ignore them. */ - -int flag_no_ident = 0; - -/* Nonzero means warn about implicit declarations. */ - -int warn_implicit; - -/* Nonzero means give string constants the type `const char *' - to get extra warnings from them. These warnings will be too numerous - to be useful, except in thoroughly ANSIfied programs. */ - -int warn_write_strings; - -/* Nonzero means warn about pointer casts that can drop a type qualifier - from the pointer target type. */ - -int warn_cast_qual; - -/* Nonzero means warn when casting a function call to a type that does - not match the return type (e.g. (float)sqrt() or (anything*)malloc() - when there is no previous declaration of sqrt or malloc. */ - -int warn_bad_function_cast; - -/* Warn about traditional constructs whose meanings changed in ANSI C. */ - -int warn_traditional; - -/* Nonzero means warn about sizeof(function) or addition/subtraction - of function pointers. */ - -int warn_pointer_arith; - -/* Nonzero means warn for non-prototype function decls - or non-prototyped defs without previous prototype. */ - -int warn_strict_prototypes; - -/* Nonzero means warn for any global function def - without separate previous prototype decl. */ - -int warn_missing_prototypes; - -/* Nonzero means warn for any global function def - without separate previous decl. */ - -int warn_missing_declarations; - -/* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - -int warn_redundant_decls = 0; - -/* Nonzero means warn about extern declarations of objects not at - file-scope level and about *all* declarations of functions (whether - extern or static) not at file-scope level. Note that we exclude - implicit function declarations. To get warnings about those, use - -Wimplicit. */ - -int warn_nested_externs = 0; - -/* Warn about *printf or *scanf format/argument anomalies. */ - -int warn_format; - -/* Warn about a subscript that has type char. */ - -int warn_char_subscripts = 0; - -/* Warn if a type conversion is done that might have confusing results. */ - -int warn_conversion; - -/* Warn if adding () is suggested. */ - -int warn_parentheses; - -/* Warn if initializer is not completely bracketed. */ - -int warn_missing_braces; - -/* Nonzero means `$' can be in an identifier. - See cccp.c for reasons why this breaks some obscure ANSI C programs. */ - -#ifndef DOLLARS_IN_IDENTIFIERS -#define DOLLARS_IN_IDENTIFIERS 1 -#endif -int dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 1; - -/* Decode the string P as a language-specific option for C. - Return 1 if it is recognized (and handle it); - return 0 if not recognized. */ - -int -c_decode_option (p) - char *p; -{ - if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) - { - flag_traditional = 1; - flag_writable_strings = 1; -#if DOLLARS_IN_IDENTIFIERS > 0 - dollars_in_ident = 1; -#endif - } - else if (!strcmp (p, "-fallow-single-precision")) - flag_allow_single_precision = 1; - else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional")) - { - flag_traditional = 0; - flag_writable_strings = 0; - dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 1; - } - else if (!strcmp (p, "-fdollars-in-identifiers")) - { -#if DOLLARS_IN_IDENTIFIERS > 0 - dollars_in_ident = 1; -#endif - } - 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; - else if (!strcmp (p, "-fno-ident")) - flag_no_ident = 1; - else if (!strcmp (p, "-fident")) - flag_no_ident = 0; - else if (!strcmp (p, "-ansi")) - flag_no_asm = 1, flag_no_nonansi_builtin = 1, dollars_in_ident = 0; - else if (!strcmp (p, "-Wimplicit")) - warn_implicit = 1; - else if (!strcmp (p, "-Wno-implicit")) - warn_implicit = 0; - else if (!strcmp (p, "-Wwrite-strings")) - warn_write_strings = 1; - else if (!strcmp (p, "-Wno-write-strings")) - warn_write_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, "-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; - 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")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-comment")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wcomments")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-comments")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wtrigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-trigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wimport")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-import")) - ; /* cpp handles this one. */ - 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, "-Wall")) - { - extra_warnings = 1; - /* We save the value of warn_uninitialized, since if they put - -Wuninitialized on the command line, we need to generate a - warning about not using it without also specifying -O. */ - if (warn_uninitialized != 1) - warn_uninitialized = 2; - warn_implicit = 1; - warn_return_type = 1; - warn_unused = 1; - warn_switch = 1; - warn_format = 1; - warn_char_subscripts = 1; - warn_parentheses = 1; - warn_missing_braces = 1; - } - else - return 0; - - return 1; -} - -/* Hooks for print_node. */ - -void -print_lang_decl (file, node, indent) - FILE *file; - tree node; - int indent; -{ -} - -void -print_lang_type (file, node, indent) - FILE *file; - tree node; - int indent; -{ -} - -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); -} - -/* Hook called at end of compilation to assume 1 elt - for a top-level array decl that wasn't complete before. */ - -void -finish_incomplete_decl (decl) - tree decl; -{ - if (TREE_CODE (decl) == VAR_DECL && TREE_TYPE (decl) != error_mark_node) - { - tree type = TREE_TYPE (decl); - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == 0 - && TREE_CODE (decl) != TYPE_DECL) - { - complete_array_type (type, NULL_TREE, 1); - - layout_decl (decl, 0); - } - } -} - -/* Create a new `struct binding_level'. */ - -static -struct binding_level * -make_binding_level () -{ - /* NOSTRICT */ - return (struct binding_level *) xmalloc (sizeof (struct binding_level)); -} - -/* Nonzero if we are currently in the global binding level. */ - -int -global_bindings_p () -{ - return current_binding_level == global_binding_level; -} - -void -keep_next_level () -{ - keep_next_level_flag = 1; -} - -/* Nonzero if the current level needs to have a BLOCK made. */ - -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)); -} - -/* Identify this binding level as a level of parameters. - DEFINITION_FLAG is 1 for a definition, 0 for a declaration. - But it turns out there is no way to pass the right value for - DEFINITION_FLAG, so we ignore it. */ - -void -declare_parm_level (definition_flag) - int definition_flag; -{ - current_binding_level->parm_flag = 1; -} - -/* Nonzero if currently making parm declarations. */ - -int -in_parm_level_p () -{ - return current_binding_level->parm_flag; -} - -/* Enter a new binding level. - If TAG_TRANSPARENT is nonzero, do so only for the name space of variables, - not for that of tags. */ - -void -pushlevel (tag_transparent) - int tag_transparent; -{ - register struct binding_level *newlevel = NULL_BINDING_LEVEL; - - /* If this is the top level of a function, - just make sure that NAMED_LABELS is 0. */ - - if (current_binding_level == global_binding_level) - { - named_labels = 0; - } - - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } - - /* Add this level to the front of the chain (stack) of levels that - are active. */ - - *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; -} - -/* Exit a binding level. - Pop the level off, and restore the state of the identifier-decl mappings - that were in effect when this level was entered. - - If KEEP is nonzero, this level had explicit declarations, so - and create a "block" (a BLOCK node) for the level - to record its declarations and subblocks for symbol table output. - - If FUNCTIONBODY is nonzero, this level is the body of a function, - so create a block as if KEEP were set and also clear out all - label names. - - If REVERSE is nonzero, reverse the order of decls before putting - them into the BLOCK. */ - -tree -poplevel (keep, reverse, functionbody) - int keep; - int reverse; - int functionbody; -{ - register tree link; - /* The chain of decls was accumulated in reverse order. - Put it into forward order, just for cleanliness. */ - 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; - - /* This warning is turned off because it causes warnings for - declarations like `extern struct foo *x'. */ -#if 0 - /* Warn about incomplete structure types in this level. */ - for (link = tags; link; link = TREE_CHAIN (link)) - if (TYPE_SIZE (TREE_VALUE (link)) == 0) - { - tree type = TREE_VALUE (link); - char *errmsg; - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - errmsg = "`struct %s' incomplete in scope ending here"; - break; - case UNION_TYPE: - errmsg = "`union %s' incomplete in scope ending here"; - break; - case ENUMERAL_TYPE: - errmsg = "`enum %s' incomplete in scope ending here"; - break; - } - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); - else - /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error (errmsg, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); - } -#endif /* 0 */ - - /* Get the decls in the order they were written. - Usually current_binding_level->names is in reverse order. - But parameter decls were previously put in forward order. */ - - if (reverse) - current_binding_level->names - = decls = nreverse (current_binding_level->names); - else - decls = current_binding_level->names; - - /* Output any nested inline functions within this block - if they weren't already output. */ - - 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 this decl was copied from a file-scope decl - on account of a block-scope extern decl, - propagate TREE_ADDRESSABLE to the file-scope decl. */ - if (DECL_ABSTRACT_ORIGIN (decl) != 0) - TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; - else - { - push_function_context (); - output_inline_function (decl); - pop_function_context (); - } - } - - /* If there were any declarations or structure tags in that level, - or if this level is a function body, - create a BLOCK to record them for the life of this function. */ - - 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); - } - - /* In each subblock, record that this is its superior. */ - - for (link = subblocks; link; link = TREE_CHAIN (link)) - BLOCK_SUPERCONTEXT (link) = block; - - /* Clear out the meanings of the local variables of this level. */ - - for (link = decls; link; link = TREE_CHAIN (link)) - { - if (DECL_NAME (link) != 0) - { - /* If the ident. was used or addressed via a local extern decl, - don't forget that fact. */ - 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; - } - } - - /* Restore all name-meanings of the outer levels - that were shadowed by this level. */ - - for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) - IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - - /* If the level being exited is the top level of a function, - check over all the labels, and clear out the current - (function local) meanings of their names. */ - - if (functionbody) - { - /* If this is the top level block of a function, - the vars are the function's parameters. - Don't leave them in the BLOCK because they are - found in the FUNCTION_DECL instead. */ - - BLOCK_VARS (block) = 0; - - /* Clear out the definitions of all label names, - since their scopes end here, - and add them to BLOCK_VARS. */ - - 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"); - /* Avoid crashing later. */ - define_label (input_filename, lineno, - DECL_NAME (label)); - } - else if (warn_unused && !TREE_USED (label)) - warning_with_decl (label, "label `%s' defined but not used"); - IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0; - - /* Put the labels into the "variables" of the - top-level block, so debugger can see them. */ - TREE_CHAIN (label) = BLOCK_VARS (block); - BLOCK_VARS (block) = label; - } - } - - /* Pop the current level, and free the structure for reuse. */ - - { - 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; - } - - /* Dispose of the block that we just made inside some higher 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); - } - /* If we did not make a block for the level just exited, - any blocks made for inner levels - (since they cannot be recorded as subblocks in that level) - must be carried forward so they will later become subblocks - of something else. */ - else if (subblocks) - current_binding_level->blocks - = chainon (current_binding_level->blocks, subblocks); - - /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this - binding contour so that they point to the appropriate construct, i.e. - either to the current FUNCTION_DECL node, or else to the BLOCK node - we just constructed. - - Note that for tagged types whose scope is just the formal parameter - list for some function type specification, we can't properly set - their TYPE_CONTEXTs here, because we don't have a pointer to the - appropriate FUNCTION_TYPE node readily available to us. For those - cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set - in `grokdeclarator' as soon as we have created the FUNCTION_TYPE - node which will represent the "scope" for these "parameter list local" - tagged types. - */ - - 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; -} - -/* Delete the node BLOCK from the current binding level. - This is used for the block inside a stmt expr ({...}) - so that the block can be reinserted where appropriate. */ - -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; - /* Clear TREE_USED which is always set by poplevel. - The flag is set again if insert_block is called. */ - TREE_USED (block) = 0; -} - -/* Insert BLOCK at the end of the list of subblocks of the - current binding level. This is used when a BIND_EXPR is expanded, - to handle the BLOCK node inside the BIND_EXPR. */ - -void -insert_block (block) - tree block; -{ - TREE_USED (block) = 1; - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); -} - -/* Set the BLOCK node for the innermost scope - (the one we are currently in). */ - -void -set_block (block) - register tree block; -{ - current_binding_level->this_block = block; -} - -void -push_label_level () -{ - register struct binding_level *newlevel; - - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } - - /* Add this level to the front of the chain (stack) of label levels. */ - - 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; - - /* Clear out the definitions of the declared labels in this level. - Leave in the list any ordinary, non-declared labels. */ - 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"); - /* Avoid crashing later. */ - 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; - - /* Delete this element from the list. */ - link = TREE_CHAIN (link); - if (prev) - TREE_CHAIN (prev) = link; - else - named_labels = link; - } - else - { - prev = link; - link = TREE_CHAIN (link); - } - } - - /* Bring back all the labels that were shadowed. */ - 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; - - /* Pop the current level, and free the structure for reuse. */ - label_level_chain = label_level_chain->level_chain; - level->level_chain = free_binding_level; - free_binding_level = level; -} - -/* Push a definition or a declaration of struct, union or enum tag "name". - "type" should be the type node. - We assume that the tag "name" is not already defined. - - Note that the definition may really be just a forward reference. - In that case, the TYPE_SIZE will be zero. */ - -void -pushtag (name, type) - tree name, type; -{ - register struct binding_level *b; - - /* Find the proper binding level for this type tag. */ - - for (b = current_binding_level; b->tag_transparent; b = b->level_chain) - continue; - - if (name) - { - /* Record the identifier as the type's name if it has none. */ - - 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); - - /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the - tagged type we just added to the current binding level. This fake - NULL-named TYPE_DECL node helps dwarfout.c to know when it needs - to output a representation of a tagged type, and it also gives - us a convenient place to record the "scope start" address for the - tagged type. */ - - TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type)); -} - -/* Handle when a new declaration NEWDECL - has the same name as an old one OLDDECL - in the same binding contour. - Prints an error message if appropriate. - - If safely possible, alter OLDDECL to look like NEWDECL, and return 1. - Otherwise, return 0. */ - -static int -duplicate_decls (newdecl, olddecl) - register tree newdecl, olddecl; -{ - 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); - char *errmsg = 0; - - if (TREE_CODE (newtype) == ERROR_MARK - || TREE_CODE (oldtype) == ERROR_MARK) - types_match = 0; - - /* New decl is completely inconsistent with the old one => - tell caller to replace the old one. - This is always an error except in the case of shadowing a builtin. */ - if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) - { - if (TREE_CODE (olddecl) == FUNCTION_DECL - && (DECL_BUILT_IN (olddecl) - || DECL_BUILT_IN_NONANSI (olddecl))) - { - /* If you declare a built-in or predefined function name as static, - the old definition is overridden, - but optionally warn this was a bad choice of name. */ - 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'"); - } - /* Likewise, if the built-in is not ansi, then programs can - override it even globally without an error. */ - 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; - } - - /* For real parm decl following a forward decl, - return 1 so old decl will be reused. */ - if (types_match && TREE_CODE (newdecl) == PARM_DECL - && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl)) - return 1; - - /* The new declaration is the same kind of object as the old one. - The declarations may partially match. Print warnings if they don't - match enough. Ultimately, copy most of the information from the new - decl to the old one, and keep using the old one. */ - - if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL - && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl - && DECL_INITIAL (olddecl) == 0) - /* If -traditional, avoid error for redeclaring fcn - after implicit decl. */ - ; - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl)) - { - /* A function declaration for a built-in function. */ - if (!TREE_PUBLIC (newdecl)) - { - /* If you declare a built-in function name as static, the - built-in definition is overridden, - but optionally warn this was a bad choice of name. */ - if (warn_shadow) - warning_with_decl (newdecl, "shadowing built-in function `%s'"); - /* Discard the old built-in function. */ - return 0; - } - else if (!types_match) - { - /* Accept the return type of the new declaration if same modes. */ - tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl)); - tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl)); - if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype)) - { - /* Function types may be shared, so we can't just modify - the return type of olddecl's function type. */ - tree newtype - = build_function_type (newreturntype, - TYPE_ARG_TYPES (TREE_TYPE (olddecl))); - - types_match = comptypes (TREE_TYPE (newdecl), newtype); - if (types_match) - TREE_TYPE (olddecl) = newtype; - } - /* Accept harmless mismatch in first argument type also. - This is for ffs. */ - if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0 - && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0 - && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl))) != 0 - && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (olddecl))) != 0 - && (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl)))) - == - TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (olddecl)))))) - { - /* Function types may be shared, so we can't just modify - the return type of olddecl's function type. */ - tree newtype - = build_function_type (TREE_TYPE (TREE_TYPE (olddecl)), - tree_cons (NULL_TREE, - TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl))), - TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (olddecl))))); - - types_match = comptypes (TREE_TYPE (newdecl), newtype); - if (types_match) - TREE_TYPE (olddecl) = newtype; - } - } - if (!types_match) - { - /* If types don't match for a built-in, throw away the built-in. */ - 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) - { - /* A function declaration for a predeclared function - that isn't actually built in. */ - if (!TREE_PUBLIC (newdecl)) - { - /* If you declare it as static, the - default definition is overridden. */ - return 0; - } - else if (!types_match) - { - /* If the types don't match, preserve volatility indication. - Later on, we will discard everything else about the - default declaration. */ - TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); - } - } - /* Permit char *foo () to match void *foo (...) if not pedantic, - if one of them came from a system header file. */ - 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'"); - /* Make sure we keep void * as ret type, not char *. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node) - TREE_TYPE (newdecl) = newtype = oldtype; - - /* Set DECL_IN_SYSTEM_HEADER, so that if we see another declaration - we will come back here again. */ - DECL_IN_SYSTEM_HEADER (newdecl) = 1; - } - else if (!types_match - /* Permit char *foo (int, ...); followed by char *foo (); - if not pedantic. */ - && ! (TREE_CODE (olddecl) == FUNCTION_DECL - && ! pedantic - /* Return types must still match. */ - && comptypes (TREE_TYPE (oldtype), - TREE_TYPE (newtype)) - && TYPE_ARG_TYPES (newtype) == 0)) - { - error_with_decl (newdecl, "conflicting types for `%s'"); - /* Check for function type mismatch - involving an empty arglist vs a nonempty one. */ - 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))) - { - /* Classify the problem further. */ - 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"); - error ("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"); - error ("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) - { - error_with_decl (newdecl, errmsg); - 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 (olddecl) == FUNCTION_DECL - && DECL_INITIAL (olddecl) != 0 - && TYPE_ARG_TYPES (oldtype) == 0 - && TYPE_ARG_TYPES (newtype) != 0) - { - register tree type, parm; - register int nargs; - /* Prototype decl follows defn w/o prototype. */ - - for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype), - type = TYPE_ARG_TYPES (newtype), - nargs = 1; - (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) != void_type_node - || TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node); - 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) - { - errmsg = "prototype for `%s' follows and number of arguments"; - break; - } - /* Type for passing arg must be consistent - with that declared for the arg. */ - if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type)) - /* If -traditional, allow `unsigned int' instead of `int' - in the prototype. */ - && (! (flag_traditional - && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node - && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))) - { - errmsg = "prototype for `%s' follows and argument %d"; - break; - } - } - if (errmsg) - { - error_with_decl (newdecl, errmsg, nargs); - error_with_decl (olddecl, - "doesn't match non-prototype definition here"); - } - else - { - warning_with_decl (newdecl, "prototype for `%s' follows"); - warning_with_decl (olddecl, "non-prototype definition here"); - } - } - /* Warn about mismatches in various flags. */ - else - { - /* Warn if function is now inline - but was previously declared not inline and has been called. */ - 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, warn when static declaration follows a non-static - declaration. Otherwise, do so only for functions. */ - if ((pedantic || TREE_CODE (olddecl) == FUNCTION_DECL) - && TREE_PUBLIC (olddecl) - && !TREE_PUBLIC (newdecl)) - warning_with_decl (newdecl, "static declaration for `%s' follows non-static"); - - /* Warn when const declaration follows a non-const - declaration, but not for functions. */ - if (TREE_CODE (olddecl) != FUNCTION_DECL - && !TREE_READONLY (olddecl) - && TREE_READONLY (newdecl)) - warning_with_decl (newdecl, "const declaration for `%s' follows non-const"); - /* These bits are logically part of the type, for variables. - But not for functions - (where qualifiers are not valid ANSI anyway). */ - 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"); - } - } - - /* Optionally warn about more than one declaration for the same name. */ - if (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0 - /* Dont warn about a function declaration - followed by a definition. */ - && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0 - && DECL_INITIAL (olddecl) == 0) - /* Don't warn about extern decl followed by (tentative) definition. */ - && !(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'"); - } - - /* Copy all the DECL_... slots specified in the new decl - except for any that we copy here from the old type. - - Past this point, we don't change OLDTYPE and NEWTYPE - even if we change the types of NEWDECL and OLDDECL. */ - - if (types_match) - { - /* Make sure we put the new type in the same obstack as the old ones. - If the old types are not both in the same obstack, use the permanent - one. */ - if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype)) - push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype)); - else - { - push_obstacks_nochange (); - end_temporary_allocation (); - } - - /* Merge the data types specified in the two decls. */ - if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl)) - TREE_TYPE (newdecl) - = TREE_TYPE (olddecl) - = common_type (newtype, oldtype); - - /* Lay the type out, unless already done. */ - 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 - { - /* Since the type is OLDDECL's, make OLDDECL's size go with. */ - 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); - } - - /* Keep the old rtl since we can safely use it. */ - DECL_RTL (newdecl) = DECL_RTL (olddecl); - - /* Merge the type qualifiers. */ - if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl) - && !TREE_THIS_VOLATILE (newdecl)) - TREE_THIS_VOLATILE (olddecl) = 0; - if (TREE_READONLY (newdecl)) - TREE_READONLY (olddecl) = 1; - if (TREE_THIS_VOLATILE (newdecl)) - { - TREE_THIS_VOLATILE (olddecl) = 1; - if (TREE_CODE (newdecl) == VAR_DECL) - make_var_volatile (newdecl); - } - - /* Keep source location of definition rather than declaration. - Likewise, keep decl at outer scope. */ - if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0) - || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0)) - { - DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); - DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); - - if (DECL_CONTEXT (olddecl) == 0) - DECL_CONTEXT (newdecl) = 0; - } - - /* Merge the unused-warning information. */ - if (DECL_IN_SYSTEM_HEADER (olddecl)) - DECL_IN_SYSTEM_HEADER (newdecl) = 1; - else if (DECL_IN_SYSTEM_HEADER (newdecl)) - DECL_IN_SYSTEM_HEADER (olddecl) = 1; - - /* Merge the initialization information. */ - if (DECL_INITIAL (newdecl) == 0) - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - - /* Merge the section attribute. - We want to issue an error if the sections conflict but that must be - done later in decl_attributes since we are called before attributes - are assigned. */ - if (DECL_SECTION_NAME (newdecl) == NULL_TREE) - DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - - pop_obstacks (); - } - /* If cannot merge, then use the new type and qualifiers, - and don't preserve the old rtl. */ - else - { - 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); - } - - /* Merge the storage class information. */ - /* For functions, static overrides non-static. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); - /* This is since we don't automatically - copy the attributes of NEWDECL into OLDDECL. */ - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - /* If this clears `static', clear it in the identifier too. */ - 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); - /* An extern decl does not override previous storage class. */ - TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); - } - else - { - TREE_STATIC (olddecl) = TREE_STATIC (newdecl); - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - } - - /* If either decl says `inline', this fn is inline, - unless its definition was passed already. */ - if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) - DECL_INLINE (olddecl) = 1; - DECL_INLINE (newdecl) = DECL_INLINE (olddecl); - - /* Get rid of any built-in function if new arg types don't match it - or if we have a function definition. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl) - && (!types_match || new_is_definition)) - { - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); - DECL_BUILT_IN (olddecl) = 0; - } - - /* If redeclaring a builtin function, and not a definition, - it stays built in. - Also preserve various other info from the definition. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition) - { - if (DECL_BUILT_IN (olddecl)) - { - DECL_BUILT_IN (newdecl) = 1; - DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); - } - else - DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); - - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); - DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); - } - - /* Copy most of the decl-specific fields of NEWDECL into OLDDECL. - But preserve OLDdECL's DECL_UID. */ - { - 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; - } - - return 1; -} - -/* Record a decl-node X as belonging to the current lexical scope. - Check for errors (such as an incompatible declaration for the same - name already seen in the same scope). - - Returns either X or an old decl for the same name. - If an old decl is returned, it may have been smashed - to agree with what X says. */ - -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; - /* A local extern declaration for a function doesn't constitute nesting. - A local auto declaration does, since it's a forward decl - for a nested function coming later. */ - 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) - /* Don't print error messages for __FUNCTION__ and __PRETTY_FUNCTION__ */ - && !DECL_IN_SYSTEM_HEADER (x)) - warning ("nested extern declaration of `%s'", IDENTIFIER_POINTER (name)); - - if (name) - { - char *file; - int line; - - /* Don't type check externs here when -traditional. This is so that - code with conflicting declarations inside blocks will get warnings - not errors. X11 for instance depends on this. */ - if (DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional) - t = lookup_name_current_level_global (name); - else - t = lookup_name_current_level (name); - if (t != 0 && t == error_mark_node) - /* error_mark_node is 0 for a while during initialization! */ - { - 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 (t != 0 && duplicate_decls (x, t)) - { - if (TREE_CODE (t) == PARM_DECL) - { - /* Don't allow more than one "real" duplicate - of a forward parm decl. */ - TREE_ASM_WRITTEN (t) = TREE_ASM_WRITTEN (x); - return t; - } - /* If this decl is `static' and an implicit decl was seen previously, - warn. But don't complain if -traditional, - since traditional compilers don't complain. */ - if (!flag_traditional && TREE_PUBLIC (name) - && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x) - /* We used to warn also for explicit extern followed by static, - but sometimes you need to do it that way. */ - && IDENTIFIER_IMPLICIT_DECL (name) != 0) - { - pedwarn ("`%s' was declared implicitly `extern' and later `static'", - IDENTIFIER_POINTER (name)); - pedwarn_with_file_and_line (file, line, - "previous declaration of `%s'", - IDENTIFIER_POINTER (name)); - } - - /* If this is a global decl, and there exists a conflicting local - decl in a parent block, then we can't return as yet, because we - need to register this decl in the current binding block. */ - if (! DECL_EXTERNAL (x) || ! TREE_PUBLIC (x) - || lookup_name (name) == t) - return t; - } - - /* If we are processing a typedef statement, generate a whole new - ..._TYPE node (which will be just an variant of the existing - ..._TYPE node with identical properties) and then install the - TYPE_DECL node generated to represent the typedef name as the - TYPE_NAME of this brand new (duplicate) ..._TYPE node. - - The whole point here is to end up with a situation where each - and every ..._TYPE node the compiler creates will be uniquely - associated with AT MOST one node representing a typedef name. - This way, even though the compiler substitutes corresponding - ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very - early on, later parts of the compiler can always do the reverse - translation and get back the corresponding typedef name. For - example, given: - - typedef struct S MY_TYPE; - MY_TYPE object; - - Later parts of the compiler might only know that `object' was of - type `struct S' if if were not for code just below. With this - code however, later parts of the compiler see something like: - - struct S' == struct S - typedef struct S' MY_TYPE; - struct S' object; - - And they can then deduce (from the node for type struct S') that - the original object declaration was: - - MY_TYPE object; - - Being able to do this is important for proper support of protoize, - and also for generating precise symbolic debugging information - which takes full account of the programmer's (typedef) vocabulary. - - Obviously, we don't want to generate a duplicate ..._TYPE node if - the TYPE_DECL node that we are now processing really represents a - standard built-in type. - - Since all standard types are effectively declared at line zero - in the source file, we can easily check to see if we are working - on a standard type by checking the current value of lineno. */ - - 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) - { - tree tt = TREE_TYPE (x); - - tt = build_type_copy (tt); - TYPE_NAME (tt) = x; - TREE_TYPE (x) = tt; - } - } - - /* Multiple external decls of the same identifier ought to match. - Check against both global declarations (when traditional) and out of - scope (limbo) block level declarations. - - We get warnings about inline functions where they are defined. - Avoid duplicate warnings where they are used. */ - 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) - /* Decls in limbo are always extern, so no need to check that. */ - decl = IDENTIFIER_LIMBO_VALUE (name); - else - decl = 0; - - if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl)) - /* If old decl is built-in, we already warned if we should. */ - && !DECL_BUILT_IN (decl)) - { - pedwarn_with_decl (x, - "type mismatch with previous external decl"); - pedwarn_with_decl (decl, "previous external decl of `%s'"); - } - } - - /* If a function has had an implicit declaration, and then is defined, - make sure they are compatible. */ - - 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'"); - } - - /* In PCC-compatibility mode, extern decls of vars with no current decl - take effect at top level no matter where they are. */ - if (flag_traditional && DECL_EXTERNAL (x) - && lookup_name (name) == 0) - { - tree type = TREE_TYPE (x); - - /* But don't do this if the type contains temporary nodes. */ - while (type) - { - if (type == error_mark_node) - break; - if (! TREE_PERMANENT (type)) - { - warning_with_decl (x, "type of external `%s' is not global"); - /* By exiting the loop early, we leave TYPE nonzero, - and thus prevent globalization of the decl. */ - break; - } - else if (TREE_CODE (type) == FUNCTION_TYPE - && TYPE_ARG_TYPES (type) != 0) - /* The types might not be truly local, - but the list of arg types certainly is temporary. - Since prototypes are nontraditional, - ok not to do the traditional thing. */ - break; - type = TREE_TYPE (type); - } - - if (type == 0) - b = global_binding_level; - } - - /* This name is new in its binding level. - Install the new declaration and return it. */ - if (b == global_binding_level) - { - /* Install a global value. */ - - /* If the first global decl has external linkage, - warn if we later see static one. */ - if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x)) - TREE_PUBLIC (name) = 1; - - IDENTIFIER_GLOBAL_VALUE (name) = x; - - /* We no longer care about any previous block level declarations. */ - IDENTIFIER_LIMBO_VALUE (name) = 0; - - /* Don't forget if the function was used via an implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_USED (x) = 1, TREE_USED (name) = 1; - - /* Don't forget if its address was taken in that way. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_ADDRESSABLE (x) = 1; - - /* Warn about mismatches against previous implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) != 0 - /* If this real decl matches the implicit, don't complain. */ - && ! (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 this decl is `static' and an `extern' was seen previously, - that is erroneous. */ - if (TREE_PUBLIC (name) - && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x)) - { - /* Okay to redeclare an ANSI built-in as static. */ - if (t != 0 && DECL_BUILT_IN (t)) - ; - /* Okay to declare a non-ANSI built-in as anything. */ - else if (t != 0 && DECL_BUILT_IN_NONANSI (t)) - ; - else if (IDENTIFIER_IMPLICIT_DECL (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 - { - /* Here to install a non-global value. */ - tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); - tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name); - IDENTIFIER_LOCAL_VALUE (name) = x; - - /* If this is an extern function declaration, see if we - have a global definition or declaration for the function. */ - if (oldlocal == 0 - && DECL_EXTERNAL (x) && !DECL_INLINE (x) - && oldglobal != 0 - && TREE_CODE (x) == FUNCTION_DECL - && TREE_CODE (oldglobal) == FUNCTION_DECL) - { - /* We have one. Their types must agree. */ - 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 - { - /* Inner extern decl is inline if global one is. - Copy enough to really inline it. */ - 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) = oldglobal; - } - /* Inner extern decl is built-in if global one is. */ - if (DECL_BUILT_IN (oldglobal)) - { - DECL_BUILT_IN (x) = DECL_BUILT_IN (oldglobal); - DECL_FUNCTION_CODE (x) = DECL_FUNCTION_CODE (oldglobal); - } - /* Keep the arg types from a file-scope fcn defn. */ - 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 /* This case is probably sometimes the right thing to do. */ - /* If we have a local external declaration, - then any file-scope declaration should not - have been static. */ - 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 we have a local external declaration, - and no file-scope declaration has yet been seen, - then if we later have a file-scope decl it must not be static. */ - if (oldlocal == 0 - && oldglobal == 0 - && DECL_EXTERNAL (x) - && TREE_PUBLIC (x)) - { - TREE_PUBLIC (name) = 1; - - /* Save this decl, so that we can do type checking against - other decls after it falls out of scope. - - Only save it once. This prevents temporary decls created in - expand_inline_function from being used here, since this - will have been set when the inline function was parsed. - It also helps give slightly better warnings. */ - if (IDENTIFIER_LIMBO_VALUE (name) == 0) - IDENTIFIER_LIMBO_VALUE (name) = x; - } - - /* Warn if shadowing an argument at the top level of the body. */ - if (oldlocal != 0 && !DECL_EXTERNAL (x) - /* This warning doesn't apply to the parms of a nested fcn. */ - && ! current_binding_level->parm_flag - /* Check that this is one level down from the parms. */ - && current_binding_level->level_chain->parm_flag - /* Check that the decl being shadowed - comes from the parm level, one level up. */ - && 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)); - } - - /* Maybe warn if shadowing something else. */ - else if (warn_shadow && !DECL_EXTERNAL (x) - /* No shadow warnings for internally generated vars. */ - && DECL_SOURCE_LINE (x) != 0 - /* No shadow warnings for vars made for inlining. */ - && ! DECL_FROM_INLINE (x)) - { - char *warnstring = 0; - - if (TREE_CODE (x) == PARM_DECL - && current_binding_level->level_chain->parm_flag) - /* Don't warn about the parm names in function declarator - within a function declarator. - It would be nice to avoid warning in any function - declarator in a declaration, as opposed to a definition, - but there is no way to tell it's not a definition. */ - ; - else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL) - warnstring = "declaration of `%s' shadows a parameter"; - else if (oldlocal != 0) - warnstring = "declaration of `%s' shadows previous local"; - else if (IDENTIFIER_GLOBAL_VALUE (name) != 0 - && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node) - warnstring = "declaration of `%s' shadows global declaration"; - - if (warnstring) - warning (warnstring, IDENTIFIER_POINTER (name)); - } - - /* If storing a local value, there may already be one (inherited). - If so, record it for restoration when this binding level ends. */ - if (oldlocal != 0) - b->shadowed = tree_cons (name, oldlocal, b->shadowed); - } - - /* Keep count of variables in this level with incomplete type. */ - if (TYPE_SIZE (TREE_TYPE (x)) == 0) - ++b->n_incomplete; - } - - /* Put decls on list in reverse order. - We will reverse them later if necessary. */ - TREE_CHAIN (x) = b->names; - b->names = x; - - return x; -} - -/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */ - -tree -pushdecl_top_level (x) - tree x; -{ - register tree t; - register struct binding_level *b = current_binding_level; - - current_binding_level = global_binding_level; - t = pushdecl (x); - current_binding_level = b; - return t; -} - -/* Generate an implicit declaration for identifier FUNCTIONID - as a function of type int (). Print a warning if appropriate. */ - -tree -implicitly_declare (functionid) - tree functionid; -{ - register tree decl; - int traditional_warning = 0; - /* Only one "implicit declaration" warning per identifier. */ - int implicit_warning; - - /* Save the decl permanently so we can warn if definition follows. */ - push_obstacks_nochange (); - end_temporary_allocation (); - - /* We used to reuse an old implicit decl here, - but this loses with inline functions because it can clobber - the saved decl chains. */ -/* if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0) - decl = IDENTIFIER_IMPLICIT_DECL (functionid); - else */ - decl = build_decl (FUNCTION_DECL, functionid, default_function_type); - - /* Warn of implicit decl following explicit local extern decl. - This is probably a program designed for traditional C. */ - if (TREE_PUBLIC (functionid) && IDENTIFIER_GLOBAL_VALUE (functionid) == 0) - traditional_warning = 1; - - /* Warn once of an implicit declaration. */ - implicit_warning = (IDENTIFIER_IMPLICIT_DECL (functionid) == 0); - - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - /* Record that we have an implicit decl and this is it. */ - IDENTIFIER_IMPLICIT_DECL (functionid) = decl; - - /* ANSI standard says implicit declarations are in the innermost block. - So we record the decl in the standard fashion. - If flag_traditional is set, pushdecl does it top-level. */ - pushdecl (decl); - - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - - rest_of_decl_compilation (decl, NULL_PTR, 0, 0); - - if (warn_implicit && implicit_warning) - 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)); - - /* Write a record describing this implicit function declaration to the - prototypes file (if requested). */ - - gen_aux_info_record (decl, 0, 1, 0); - - pop_obstacks (); - - return decl; -} - -/* Return zero if the declaration NEWDECL is valid - when the declaration OLDDECL (assumed to be for the same name) - has already been seen. - Otherwise return an error message format string with a %s - where the identifier should go. */ - -static char * -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; - return "redefinition of `%s'"; - } - else if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* Declarations of functions can insist on internal linkage - but they can't be inconsistent with internal linkage, - so there can be no error on that account. - However defining the same name twice is no good. */ - if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0 - /* However, defining once as extern inline and a second - time in another way is ok. */ - && !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl) - && !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl)))) - return "redefinition of `%s'"; - return 0; - } - else if (current_binding_level == global_binding_level) - { - /* Objects declared at top level: */ - /* If at least one is a reference, it's ok. */ - if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl)) - return 0; - /* Reject two definitions. */ - if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0) - return "redefinition of `%s'"; - /* Now we have two tentative defs, or one tentative and one real def. */ - /* Insist that the linkage match. */ - if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl)) - return "conflicting declarations of `%s'"; - return 0; - } - else if (current_binding_level->parm_flag - && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)) - return 0; - else - { - /* Newdecl has block scope. If olddecl has block scope also, then - reject two definitions, and reject a definition together with an - external reference. Otherwise, it is OK, because newdecl must - be an extern reference to olddecl. */ - if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)) - && DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl)) - return "redeclaration of `%s'"; - return 0; - } -} - -/* Get the LABEL_DECL corresponding to identifier ID as a label. - Create one if none exists so far for the current function. - This function is called for both label definitions and label references. */ - -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; - } - - /* Use a label already defined or ref'd with this name. */ - if (decl != 0) - { - /* But not if it is inherited and wasn't declared to be inheritable. */ - 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); - - /* Make sure every label has an rtx. */ - label_rtx (decl); - - /* A label not explicitly declared must be local to where it's ref'd. */ - DECL_CONTEXT (decl) = current_function_decl; - - DECL_MODE (decl) = VOIDmode; - - /* Say where one reference is to the label, - for the sake of the error if it is not defined. */ - 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; -} - -/* Make a label named NAME in the current function, - shadowing silently any that may be inherited from containing functions - or containing scopes. - - Note that valid use, if the label being shadowed - comes from another scope in the same function, - requires calling declare_nonlocal_label right away. */ - -tree -shadow_label (name) - tree name; -{ - register tree decl = IDENTIFIER_LABEL_VALUE (name); - - if (decl != 0) - { - register tree dup; - - /* Check to make sure that the label hasn't already been declared - at this label scope */ - 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"); - /* Just use the 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); -} - -/* Define a label, specifying the location in the source file. - Return the LABEL_DECL node for the label, if the definition is valid. - Otherwise return 0. */ - -tree -define_label (filename, line, name) - char *filename; - int line; - tree name; -{ - tree decl = lookup_label (name); - - /* If label with this name is known from an outer context, shadow it. */ - 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 - { - /* Mark label as having been defined. */ - DECL_INITIAL (decl) = error_mark_node; - /* Say where in the source. */ - DECL_SOURCE_FILE (decl) = filename; - DECL_SOURCE_LINE (decl) = line; - return decl; - } -} - -/* Return the list of declarations of the current level. - Note that this list is in reverse order unless/until - you nreverse it; and when you do nreverse it, you must - store the result back using `storedecls' or you will lose. */ - -tree -getdecls () -{ - return current_binding_level->names; -} - -/* Return the list of type-tags (for structs, etc) of the current level. */ - -tree -gettags () -{ - return current_binding_level->tags; -} - -/* Store the list of declarations of the current level. - This is done for the parameter declarations of a function being defined, - after they are modified in the light of any missing parameters. */ - -static void -storedecls (decls) - tree decls; -{ - current_binding_level->names = decls; -} - -/* Similarly, store the list of tags of the current level. */ - -static void -storetags (tags) - tree tags; -{ - current_binding_level->tags = tags; -} - -/* Given NAME, an IDENTIFIER_NODE, - return the structure (or union or enum) definition for that name. - Searches binding levels from BINDING_LEVEL up to the global level. - If THISLEVEL_ONLY is nonzero, searches only the specified context - (but skips any tag-transparent contexts to find one that is - meaningful for tags). - CODE says which kind of type the caller wants; - it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. - If the wrong kind of type is found, an error is reported. */ - -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) - { - /* Definition isn't the kind we were looking for. */ - 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; -} - -/* Print an error message now - for a recent invalid struct, union or enum cross reference. - We don't print them immediately because they are not invalid - when used in the `struct foo;' construct for shadowing. */ - -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; -} - -/* Given a type, find the tag that was defined for it and return the tag name. - Otherwise return 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; -} - -/* Look up NAME in the current binding level and its superiors - in the namespace of variables, functions and typedefs. - Return a ..._DECL node of some kind representing its definition, - or return 0 if it is undefined. */ - -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; -} - -/* Similar to `lookup_name' but look only at current binding level. */ - -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; -} - -/* Similar to `lookup_name_current_level' but also look at the global binding - level. */ - -tree -lookup_name_current_level_global (name) - tree name; -{ - register tree t = 0; - - if (current_binding_level == global_binding_level) - return IDENTIFIER_GLOBAL_VALUE (name); - - if (IDENTIFIER_LOCAL_VALUE (name) != 0) - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) - if (DECL_NAME (t) == name) - break; - - if (t == 0) - t = IDENTIFIER_GLOBAL_VALUE (name); - - return t; -} - -/* Create the predefined scalar types of C, - and some nodes representing standard constants (0, 1, (void *)0). - Initialize the global binding level. - Make definitions for built-in primitive functions. */ - -void -init_decl_processing () -{ - register tree endlink; - /* Either char* or void*. */ - tree traditional_ptr_type_node; - /* Data types of memcpy and strlen. */ - tree memcpy_ftype, strlen_ftype; - tree void_ftype_any; - 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); /* make the binding_level structure for global names */ - global_binding_level = current_binding_level; - - /* Define `int' and `char' first so that dbx will output them first. */ - - integer_type_node = make_signed_type (INT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_INT], - integer_type_node)); - - /* Define `char', which is like either `signed char' or `unsigned char' - but not the same as either. */ - - 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)); - - /* `unsigned long' is the standard type for sizeof. - Traditionally, use a signed type. - Note that stddef.h uses `unsigned long', - and this must agree, even of long and int are the same size. */ - sizetype - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); - if (flag_traditional && TREE_UNSIGNED (sizetype)) - sizetype = signed_type (sizetype); - - ptrdiff_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE))); - - TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (char_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype; - - error_mark_node = make_node (ERROR_MARK); - TREE_TYPE (error_mark_node) = error_mark_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)); - - /* Define both `signed char' and `unsigned char'. */ - 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)); - - 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)); - - 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); - - 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; - - 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); /* Uses integer_zero_node */ - /* We are not going to have real types in C with less than byte alignment, - so we might as well not have any types that claim to have it. */ - 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)); - - /* Make a type to be the domain of a few array types - whose domains don't really matter. - 200 is small enough that it always fits in size_t - and large enough that it can hold most function names for the - initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ - array_domain_type = build_index_type (build_int_2 (200, 0)); - - /* make a type for arrays of characters. - With luck nothing will ever really depend on the length of this - array type. */ - char_array_type_node - = build_array_type (char_type_node, array_domain_type); - /* Likewise for arrays of ints. */ - int_array_type_node - = build_array_type (integer_type_node, array_domain_type); - /* This is for wide string constants. */ - 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); - - double_ftype_double - = build_function_type (double_type_node, - tree_cons (NULL_TREE, 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 /* strcpy prototype */ - = 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 /* strcmp prototype */ - = 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 /* strlen prototype */ - = 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 /* memcpy prototype */ - = 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)))); - - builtin_function ("__builtin_constant_p", int_ftype_int, - 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_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); - /* Define alloca, ffs as builtins. - Declare _exit just to mark it as volatile. */ - 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); - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); - /* Suppress error if redefined as a non-function. */ - 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; - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - } - - builtin_function ("__builtin_abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); - builtin_function ("__builtin_fabs", double_ftype_double, 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); -/* EXPAND_BUILTIN_VARARGS is obsolete. */ -#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); - - /* Untyped call and return. */ - 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); - - /* Currently under experimentation. */ - 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_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_fsqrt", double_ftype_double, - BUILT_IN_FSQRT, "sqrt"); - builtin_function ("__builtin_sin", double_ftype_double, - BUILT_IN_SIN, "sin"); - builtin_function ("__builtin_cos", double_ftype_double, - BUILT_IN_COS, "cos"); - - /* In an ANSI C program, it is okay to supply built-in meanings - for these functions, since applications cannot validly use them - with any other meaning. - However, honor the -fno-builtin option. */ - if (!flag_no_builtin) - { - builtin_function ("abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); - builtin_function ("fabs", double_ftype_double, 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 ("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 ("sqrt", double_ftype_double, BUILT_IN_FSQRT, NULL_PTR); - builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR); - builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR); - - /* Declare these functions volatile - to avoid spurious "control drops through" warnings. */ - /* Don't specify the argument types, to avoid errors - from certain code which isn't valid in ANSI but which exists. */ - 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 - /* Support for these has not been written in either expand_builtin - or build_function_call. */ - 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_memset", ptr_ftype_ptr_int_int, - BUILT_IN_MEMSET, 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 - - /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ - declare_function_name (); - - start_identifier_warnings (); - - /* Prepare to check format strings against argument lists. */ - init_function_format_info (); - - init_iterators (); - - incomplete_decl_finalize_hook = finish_incomplete_decl; -} - -/* Return a definition for a builtin function named NAME and whose data type - is TYPE. TYPE should be a function type with argument types. - FUNCTION_CODE tells later passes how to compile calls to this function. - See tree.h for its possible values. - - If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, - the name to be called if we can't opencode the function. */ - -tree -builtin_function (name, type, function_code, library_name) - char *name; - tree type; - enum built_in_function function_code; - char *library_name; -{ - tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - /* If -traditional, permit redefining a builtin function any way you like. - (Though really, if the program redefines these functions, - it probably won't work right unless compiled with -fno-builtin.) */ - 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; - } - /* Warn if a function in the namespace for users - is used without an occasion to consider it declared. */ - if (name[0] != '_' || name[1] != '_') - C_DECL_ANTICIPATED (decl) = 1; - - return decl; -} - -/* Called when a declaration is seen that contains no names to declare. - If its type is a reference to a structure, union or enum inherited - from a containing scope, shadow that tag name for the current scope - with a forward reference. - If its type defines a new named structure or union - or defines an enum, it is valid but we need not do anything here. - Otherwise, it is an error. */ - -void -shadow_tag (declspecs) - tree declspecs; -{ - shadow_tag_warned (declspecs, 0); -} - -void -shadow_tag_warned (declspecs, warned) - tree declspecs; - int warned; - /* 1 => we have done a pedwarn. 2 => we have done a warning, but - no pedwarn. */ -{ - int found_tag = 0; - register tree link; - - pending_invalid_xref = 0; - - for (link = declspecs; 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) - /* Used to test also that TYPE_SIZE (value) != 0. - That caused warning for `struct foo;' at top level in the file. */ - { - register tree name = lookup_tag_reverse (value); - register tree t; - - found_tag++; - - if (name == 0) - { - if (warned != 1 && code != ENUMERAL_TYPE) - /* Empty unnamed enum OK */ - { - 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) - { - 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"); - } -} - -/* Decode a "typename", such as "int **", returning a ..._TYPE node. */ - -tree -groktypename (typename) - tree typename; -{ - if (TREE_CODE (typename) != TREE_LIST) - return typename; - return grokdeclarator (TREE_VALUE (typename), - TREE_PURPOSE (typename), - TYPENAME, 0); -} - -/* Return a PARM_DECL node for a given pair of specs and declarator. */ - -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); -} - -/* Decode a declarator in an ordinary declaration or data definition. - This is called as soon as the type information and variable name - have been parsed, before parsing the initializer if any. - Here we create the ..._DECL node, fill in its type, - and put it on the list of decls for the current context. - The ..._DECL node is returned as the value. - - Exception: for arrays where the length is not specified, - the type is left null, to be filled in by `finish_decl'. - - Function definitions do not come here; they go to start_function - instead. However, external and forward declarations of functions - do go through here. Structure field declarations are done by - grokfield and not through here. */ - -/* Set this to zero to debug not using the temporary obstack - to parse initializers. */ -int debug_temp_inits = 1; - -tree -start_decl (declarator, declspecs, initialized) - tree declarator, declspecs; - int initialized; -{ - register tree decl = grokdeclarator (declarator, declspecs, - NORMAL, initialized); - register tree tem; - int init_written = initialized; - - /* The corresponding pop_obstacks is in finish_decl. */ - push_obstacks_nochange (); - - if (initialized) - /* Is it valid for this decl to have an initializer at all? - If not, set INITIALIZED to zero, which will indirectly - tell `finish_decl' to ignore the initializer once it is parsed. */ - switch (TREE_CODE (decl)) - { - case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `finish_decl' will fix that up. - Any other case of an initialization in a TYPE_DECL is an error. */ - 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: - /* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE. */ - error ("parameter `%s' is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - break; - - default: - /* Don't allow initializations for incomplete types - except for arrays which might be completed by the initialization. */ - if (TYPE_SIZE (TREE_TYPE (decl)) != 0) - { - /* A complete type is ok if size is fixed. */ - - 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 /* Seems redundant with grokdeclarator. */ - 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; - - /* Tell `pushdecl' this is an initialized decl - even though we don't yet have the initializer expression. - Also tell `finish_decl' it may store the real initializer. */ - DECL_INITIAL (decl) = error_mark_node; - } - - /* If this is a function declaration, write a record describing it to the - prototypes file (if requested). */ - - if (TREE_CODE (decl) == FUNCTION_DECL) - gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0); - - /* Add this decl to the current binding level. - TEM may equal DECL or it may be a previous decl of the same name. */ - tem = pushdecl (decl); - - /* For C and Obective-C, we by default put things in .common when - possible. */ - DECL_COMMON (tem) = 1; - - /* For a local variable, define the RTL now. */ - if (current_binding_level != global_binding_level - /* But not if this is a duplicate decl - and we preserved the rtl from the previous one - (which may or may not happen). */ - && 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) - { - /* When parsing and digesting the initializer, - use temporary storage. Do this even if we will ignore the value. */ - if (current_binding_level == global_binding_level && debug_temp_inits) - temporary_allocation (); - } - - return tem; -} - -/* Finish processing of a declaration; - install its initial value. - If the length of an array type is not known before, - it must be determined now, from the initial value, or it is an error. */ - -void -finish_decl (decl, init, asmspec_tree) - tree decl, init; - tree asmspec_tree; -{ - register tree type = TREE_TYPE (decl); - int was_incomplete = (DECL_SIZE (decl) == 0); - int temporary = allocation_temporary_p (); - char *asmspec = 0; - - /* If a name was specified, get the string. */ - if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); - - /* If `start_decl' didn't like having an initialization, ignore it now. */ - - if (init != 0 && DECL_INITIAL (decl) == 0) - init = 0; - /* Don't crash if parm is initialized. */ - if (TREE_CODE (decl) == PARM_DECL) - init = 0; - - 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 - { - /* typedef foo = bar; store the type of bar as the type of foo. */ - TREE_TYPE (decl) = TREE_TYPE (init); - DECL_INITIAL (decl) = init = 0; - } - } - - /* Pop back to the obstack that is current for this binding level. - This is because MAXINDEX, rtl, etc. to be made below - must go in the permanent obstack. But don't discard the - temporary data yet. */ - pop_obstacks (); -#if 0 /* pop_obstacks was near the end; this is what was here. */ - if (current_binding_level == global_binding_level && temporary) - end_temporary_allocation (); -#endif - - /* Deduce size of array from initialization, if not already known */ - - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == 0 - && TREE_CODE (decl) != TYPE_DECL) - { - int do_default - = (TREE_STATIC (decl) - /* Even if pedantic, an external linkage array - may have incomplete type at first. */ - ? pedantic && !TREE_PUBLIC (decl) - : !DECL_EXTERNAL (decl)); - int failure - = complete_array_type (type, DECL_INITIAL (decl), do_default); - - /* Get the completed type made by complete_array_type. */ - 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'"); - /* If a `static' var's size isn't known, - make it extern as well as static, so it does not get - allocated. - If it is not `static', then do not mark extern; - finish_incomplete_decl will give it a default size - and it will get allocated. */ - else if (!pedantic && TREE_STATIC (decl) && ! TREE_PUBLIC (decl)) - DECL_EXTERNAL (decl) = 1; - } - - /* TYPE_MAX_VALUE is always one less than the number of elements - in the array, because we start counting at zero. Therefore, - warn only if the value is less than zero. */ - 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) - ? - /* A static variable with an incomplete type - is an error if it is initialized. - Also if it is not file scope. - Otherwise, let it through, but if it is not `extern' - then it may cause an error message later. */ - (DECL_INITIAL (decl) != 0 - || current_binding_level != global_binding_level) - : - /* An automatic variable with an incomplete type - is an error. */ - !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 this is a function and an assembler name is specified, it isn't - builtin any more. Also reset DECL_RTL so we can give it its new - name. */ - if (TREE_CODE (decl) == FUNCTION_DECL && asmspec) - { - DECL_BUILT_IN (decl) = 0; - DECL_RTL (decl) = 0; - } - - /* Output the assembler code and/or RTL code for variables and functions, - unless the type is an undefined structure or union. - If not, it will get done when the type is completed. */ - - 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 (); - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, asmspec, - current_binding_level == global_binding_level, - 0); - pop_obstacks (); - } - else - { - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, asmspec, - current_binding_level == global_binding_level, - 0); - } - if (current_binding_level != global_binding_level) - { - /* Recompute the RTL of a local array now - if it used to be an incomplete type. */ - if (was_incomplete - && ! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)) - { - /* If we used it already as memory, it must stay in memory. */ - TREE_ADDRESSABLE (decl) = TREE_USED (decl); - /* If it's still incomplete now, no init will save it. */ - if (DECL_SIZE (decl) == 0) - DECL_INITIAL (decl) = 0; - expand_decl (decl); - } - /* Compute and store the initial value. */ - if (TREE_CODE (decl) != FUNCTION_DECL) - expand_decl_init (decl); - } - } - - if (TREE_CODE (decl) == TYPE_DECL) - { - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL_PTR, - current_binding_level == global_binding_level, - 0); - } - - /* ??? After 2.3, test (init != 0) instead of TREE_CODE. */ - /* This test used to include TREE_PERMANENT, however, we have the same - problem with initializers at the function level. Such initializers get - saved until the end of the function on the momentary_obstack. */ - if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)) - && temporary - /* DECL_INITIAL is not defined in PARM_DECLs, since it shares - space with DECL_ARG_TYPE. */ - && TREE_CODE (decl) != PARM_DECL) - { - /* We need to remember that this array HAD an initialization, - but discard the actual temporary nodes, - since we can't have a permanent node keep pointing to them. */ - /* We make an exception for inline functions, since it's - normal for a local extern redeclaration of an inline function - to have a copy of the top-level decl's DECL_INLINE. */ - if (DECL_INITIAL (decl) != 0 && DECL_INITIAL (decl) != error_mark_node) - { - /* If this is a const variable, then preserve the - initializer instead of discarding it so that we can optimize - references to it. */ - /* This test used to include TREE_STATIC, but this won't be set - for function level initializers. */ - if (TREE_READONLY (decl) || ITERATOR_P (decl)) - { - preserve_initializer (); - /* Hack? Set the permanent bit for something that is permanent, - but not on the permenent obstack, so as to convince - output_constant_def to make its rtl on the permanent - obstack. */ - TREE_PERMANENT (DECL_INITIAL (decl)) = 1; - - /* The initializer and DECL must have the same (or equivalent - types), but if the initializer is a STRING_CST, its type - might not be on the right obstack, so copy the type - of DECL. */ - TREE_TYPE (DECL_INITIAL (decl)) = type; - } - else - DECL_INITIAL (decl) = error_mark_node; - } - } - - /* If requested, warn about definitions of large data objects. */ - - 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 - /* Resume permanent allocation, if not within a function. */ - /* The corresponding push_obstacks_nochange is in start_decl, - and in push_parm_decl and in grokfield. */ - pop_obstacks (); -#endif - - /* If we have gone back from temporary to permanent allocation, - actually free the temporary space that we no longer need. */ - if (temporary && !allocation_temporary_p ()) - permanent_allocation (0); - - /* At the end of a declaration, throw away any variable type sizes - of types defined inside that declaration. There is no use - computing them in the following function definition. */ - if (current_binding_level == global_binding_level) - get_pending_sizes (); -} - -/* If DECL has a cleanup, build and return that cleanup here. - This is a callback called by expand_expr. */ - -tree -maybe_build_cleanup (decl) - tree decl; -{ - /* There are no cleanups in C. */ - return NULL_TREE; -} - -/* Given a parsed parameter declaration, - decode it into a PARM_DECL and push that on the current binding level. - Also, for the sake of forward parm decls, - record the given order of parms in `parm_order'. */ - -void -push_parm_decl (parm) - tree parm; -{ - tree decl; - int old_immediate_size_expand = immediate_size_expand; - /* Don't try computing parm sizes now -- wait till fn is called. */ - immediate_size_expand = 0; - - /* The corresponding pop_obstacks is in finish_decl. */ - push_obstacks_nochange (); - - decl = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm), PARM, 0); - -#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); - - /* Add this decl to the current binding level. */ - finish_decl (decl, NULL_TREE, NULL_TREE); -} - -/* Clear the given order of parms in `parm_order'. - Used at start of parm list, - and also at semicolon terminating forward decls. */ - -void -clear_parm_order () -{ - current_binding_level->parm_order = NULL_TREE; -} - -/* Make TYPE a complete type based on INITIAL_VALUE. - Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 1 if DO_DEFAULT). */ - -int -complete_array_type (type, initial_value, do_default) - tree type; - tree initial_value; - int do_default; -{ - register tree maxindex = NULL_TREE; - int value = 0; - - if (initial_value) - { - /* Note MAXINDEX is really the maximum index, - one less than the size. */ - 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 - { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - value = 1; - - /* Prevent further error messages. */ - 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); -#if 0 /* I took out this change - together with the change in build_array_type. --rms */ - change_main_variant (type, - build_array_type (TREE_TYPE (type), - TYPE_DOMAIN (type))); -#endif - } - - /* Lay out the type now that we can get the real answer. */ - - layout_type (type); - - return value; -} - -/* Given declspecs and a declarator, - determine the name and type of the object declared - and construct a ..._DECL node for it. - (In one case we can return a ..._TYPE node instead. - For invalid input we sometimes return 0.) - - DECLSPECS is a chain of tree_list nodes whose value fields - are the storage classes and type specifiers. - - DECL_CONTEXT says which syntactic context this declaration is in: - NORMAL for most contexts. Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL. - FUNCDEF for a function definition. Like NORMAL but a few different - error messages in each case. Return value may be zero meaning - this definition is too screwy to try to parse. - PARM for a parameter declaration (either within a function prototype - or before a function body). Make a PARM_DECL, or return void_type_node. - TYPENAME if for a typename (in a cast or sizeof). - Don't make a DECL node; just return the ..._TYPE node. - FIELD for a struct or union field; make a FIELD_DECL. - BITFIELD for a field with specified width. - INITIALIZED is 1 if the decl has an initializer. - - In the TYPENAME case, DECLARATOR is really an absolute declarator. - It may also be so in the PARM case, for a prototype where the - argument type is specified but not the name. - - This function is where the complicated C meanings of `static' - and `extern' are interpreted. */ - -static tree -grokdeclarator (declarator, declspecs, decl_context, initialized) - tree declspecs; - tree declarator; - enum decl_context decl_context; - int initialized; -{ - int specbits = 0; - tree spec; - tree type = NULL_TREE; - int longlong = 0; - int constp; - int volatilep; - int inlinep; - int explicit_int = 0; - int explicit_char = 0; - int defaulted_int = 0; - tree typedef_decl = 0; - char *name; - tree typedef_type = 0; - int funcdef_flag = 0; - enum tree_code innermost_code = ERROR_MARK; - int bitfield = 0; - int size_varies = 0; - - 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 (); - - /* Look inside a declarator for the name being declared - and get it as a string, for an error message. */ - { - 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"; - } - - /* A function definition's declarator must have the form of - a function declarator. */ - - if (funcdef_flag && innermost_code != CALL_EXPR) - return 0; - - /* Anything declared one level down from the top level - must be one of the parameters of a function - (because the body is at least two levels down). */ - - /* If this looks like a function definition, make it one, - even if it occurs where parms are expected. - Then store_parm_decls will reject it and not use it as a parm. */ - if (decl_context == NORMAL && !funcdef_flag - && current_binding_level->level_chain == global_binding_level) - decl_context = PARM; - - /* Look through the decl specs and record which ones appear. - Some typespecs are defined as built-in typenames. - Others, the ones that are modifiers of other types, - are represented by bits in SPECBITS: set the bits for - the modifiers that appear. Storage class keywords are also in SPECBITS. - - If there is a typedef name or a type, store the type in TYPE. - This includes builtin typedefs such as `int'. - - Set EXPLICIT_INT or EXPLICIT_CHAR if the type is `int' or `char' - and did not come from a user typedef. - - Set LONGLONG if `long' is mentioned twice. */ - - 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; - if (id == ridpointers[(int) RID_CHAR]) - explicit_char = 1; - - 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) - 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; - } - } - if (type) - error ("two or more data types in declaration of `%s'", name); - /* Actual typedefs come to us as TYPE_DECL nodes. */ - else if (TREE_CODE (id) == TYPE_DECL) - { - type = TREE_TYPE (id); - typedef_decl = id; - } - /* Built-in types come as identifiers. */ - 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: {} - } - - typedef_type = type; - if (type) - size_varies = C_TYPE_VARIABLE_SIZE (type); - - /* No type at all: default to `int', and set DEFAULTED_INT - because it was not a user-defined typedef. */ - - if (type == 0) - { - if (funcdef_flag && warn_return_type - && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT) - | (1 << (int) RID_SIGNED) | (1 << (int) RID_UNSIGNED)))) - warn_about_return_type = 1; - defaulted_int = 1; - type = integer_type_node; - } - - /* Now process the modifiers that were specified - and check for invalid combinations. */ - - /* Long double is a special combination. */ - - if ((specbits & 1 << (int) RID_LONG) - && TYPE_MAIN_VARIANT (type) == double_type_node) - { - specbits &= ~ (1 << (int) RID_LONG); - type = long_double_type_node; - } - - /* Check all other uses of type modifiers. */ - - if (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT) - | (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED))) - { - int ok = 0; - - if (TREE_CODE (type) != INTEGER_TYPE) - error ("long, short, signed or unsigned invalid for `%s'", name); - else if ((specbits & 1 << (int) RID_LONG) - && (specbits & 1 << (int) RID_SHORT)) - error ("long and short specified together 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) - error ("long or short specified with floating type for `%s'", name); - else if ((specbits & 1 << (int) RID_SIGNED) - && (specbits & 1 << (int) RID_UNSIGNED)) - error ("signed and unsigned given together 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; - } - } - - /* Discard the type modifiers if they are invalid. */ - 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); - } - - /* Decide whether an integer type is signed or not. - Optionally treat bitfields as signed by default. */ - if (specbits & 1 << (int) RID_UNSIGNED - /* Traditionally, all bitfields are unsigned. */ - || (bitfield && flag_traditional - && (! explicit_flag_signed_bitfields || !flag_signed_bitfields)) - || (bitfield && ! flag_signed_bitfields - && (explicit_int || defaulted_int || explicit_char - /* A typedef for plain `int' without `signed' - can be controlled just like plain `int'. */ - || ! (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 we just have "complex", it is equivalent to - "complex double", but if any modifiers at all are specified it is - the complex form of TYPE. E.g, "complex short" is - "complex short int". */ - - 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); - } - - /* Set CONSTP if this declaration is `const', whether by - explicit specification or via a typedef. - Likewise for VOLATILEP. */ - - constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type); - volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type); - inlinep = !! (specbits & (1 << (int) RID_INLINE)); - if (constp > 1) - pedwarn ("duplicate `const'"); - if (volatilep > 1) - pedwarn ("duplicate `volatile'"); - if (! flag_gen_aux_info && (TYPE_READONLY (type) || TYPE_VOLATILE (type))) - type = TYPE_MAIN_VARIANT (type); - - /* Warn if two storage classes are given. Default to `auto'. */ - - { - 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++; - - /* Warn about storage classes that are invalid for certain - kinds of declarations (parameters, typenames, etc.). */ - - 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) - { - /* `extern' with initialization is invalid if not at top level. */ - 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; - } - } - - /* Now figure out the structure of the declarator proper. - Descend through it, creating more complex types, until we reach - the declared identifier (or NULL_TREE, in an absolute declarator). */ - - while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE) - { - if (type == error_mark_node) - { - declarator = TREE_OPERAND (declarator, 0); - continue; - } - - /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]), - an INDIRECT_REF (for *...), - a CALL_EXPR (for ...(...)), - an identifier (for the name being declared) - or a null pointer (for the place in an absolute declarator - where the name was omitted). - For the last two cases, we have just exited the loop. - - At this point, TYPE is the type of elements of an array, - or for a function to return, or for a pointer to point to. - After this sequence of ifs, TYPE is the type of the - array or function or pointer, and DECLARATOR has had its - outermost layer removed. */ - - if (TREE_CODE (declarator) == ARRAY_REF) - { - register tree itype = NULL_TREE; - register tree size = TREE_OPERAND (declarator, 1); - /* An uninitialized decl with `extern' is a reference. */ - int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN)); - /* The index is a signed object `sizetype' bits wide. */ - tree index_type = signed_type (sizetype); - - declarator = TREE_OPERAND (declarator, 0); - - /* Check for some types that there cannot be arrays of. */ - - 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 this is a block level extern, it must live past the end - of the function so that we can check it against other extern - declarations (IDENTIFIER_LIMBO_VALUE). */ - if (extern_ref && allocation_temporary_p ()) - end_temporary_allocation (); - - /* If size was specified, set ITYPE to a range-type for that size. - Otherwise, ITYPE remains null. finish_decl may figure it out - from an initial value. */ - - if (size) - { - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - 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 - { - /* Make sure the array size remains visibly nonconstant - even if it is (eg) a const variable with known value. */ - 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); - } - } - - /* Convert size to index_type, so that if it is a variable - the computations will be done in the proper mode. */ - itype = fold (build (MINUS_EXPR, index_type, - convert (index_type, size), - convert (index_type, size_one_node))); - - if (size_varies) - itype = variable_size (itype); - itype = build_index_type (itype); - } - -#if 0 /* This had bad results for pointers to arrays, as in - union incomplete (*foo)[4]; */ - /* Complain about arrays of incomplete types, except in typedefs. */ - - if (TYPE_SIZE (type) == 0 - /* Avoid multiple warnings for nested array types. */ - && 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 /* We shouldn't have a function type here at all! - Functions aren't allowed as array elements. */ - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); -#endif - - /* Build the array type itself, then merge any constancy or - volatility into the target type. We must do it in this order - to ensure that the TYPE_MAIN_VARIANT field of the array type - is set correctly. */ - - type = build_array_type (type, itype); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - -#if 0 /* don't clear these; leave them set so that the array type - or the variable is itself const or volatile. */ - constp = 0; - volatilep = 0; -#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; - - /* Declaring a function type. - Make sure we have a valid type for the function to return. */ - if (type == error_mark_node) - continue; - - size_varies = 0; - - /* Warn about some types functions can't return. */ - - 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 - /* Traditionally, declaring return type float means double. */ - - if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node) - type = double_type_node; -#endif /* TRADITIONAL_RETURN_FLOAT */ - - /* If this is a block level extern, it must live past the end - of the function so that we can check it against other extern - declarations (IDENTIFIER_LIMBO_VALUE). */ - if (extern_ref && allocation_temporary_p ()) - end_temporary_allocation (); - - /* Construct the function type and go to the next - inner layer of declarator. */ - - arg_types = grokparms (TREE_OPERAND (declarator, 1), - funcdef_flag - /* Say it's a definition - only for the CALL_EXPR - closest to the identifier. */ - && TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE); -#if 0 /* This seems to be false. We turn off temporary allocation - above in this function if -traditional. - And this code caused inconsistent results with prototypes: - callers would ignore them, and pass arguments wrong. */ - - /* Omit the arg types if -traditional, since the arg types - and the list links might not be permanent. */ - type = build_function_type (type, - flag_traditional - ? NULL_TREE : arg_types); -#endif - /* ANSI seems to say that `const int foo ();' - does not make the function foo const. */ - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - constp = 0; - volatilep = 0; - - type = build_function_type (type, arg_types); - declarator = TREE_OPERAND (declarator, 0); - - /* Set the TYPE_CONTEXTs for each tagged type which is local to - the formal parameter list of this FUNCTION_TYPE to point to - the FUNCTION_TYPE node itself. */ - - { - register tree link; - - for (link = current_function_parm_tags; - link; - link = TREE_CHAIN (link)) - TYPE_CONTEXT (TREE_VALUE (link)) = type; - } - } - else if (TREE_CODE (declarator) == INDIRECT_REF) - { - /* Merge any constancy or volatility into the target type - for the pointer. */ - - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - constp = 0; - volatilep = 0; - size_varies = 0; - - type = build_pointer_type (type); - - /* Process a list of type modifier keywords - (such as const or volatile) that were given inside the `*'. */ - - if (TREE_TYPE (declarator)) - { - register tree typemodlist; - int erred = 0; - for (typemodlist = TREE_TYPE (declarator); typemodlist; - typemodlist = TREE_CHAIN (typemodlist)) - { - if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST]) - constp++; - else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE]) - volatilep++; - else if (!erred) - { - erred = 1; - error ("invalid type modifier within pointer declarator"); - } - } - if (constp > 1) - pedwarn ("duplicate `const'"); - if (volatilep > 1) - pedwarn ("duplicate `volatile'"); - } - - declarator = TREE_OPERAND (declarator, 0); - } - else - abort (); - - } - - /* Now TYPE has the actual type. */ - - /* If this is declaring a typedef name, return a TYPE_DECL. */ - - if (specbits & (1 << (int) RID_TYPEDEF)) - { - tree decl; - /* Note that the grammar rejects storage classes - in typenames, fields or parameters */ - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - pop_obstacks (); - 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; - return decl; - } - - /* Detect the case of an array type of unspecified size - which came, as such, direct from a typedef name. - We must copy the type, so that each identifier gets - a distinct type, so that each identifier's size can be - controlled separately by its own initializer. */ - - 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 this is a type name (such as, in a cast or sizeof), - compute the type and return it now. */ - - if (decl_context == TYPENAME) - { - /* Note that the grammar rejects storage classes - in typenames, fields or parameters */ - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - pop_obstacks (); - return type; - } - - /* Aside from typedefs and type names (handle above), - `void' at top level (not within pointer) - is allowed only in public variables. - We don't complain about parms either, but that is because - a better error message can be made later. */ - - 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", - IDENTIFIER_POINTER (declarator)); - type = integer_type_node; - } - - /* Now create the decl, which may be a VAR_DECL, a PARM_DECL - or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ - - { - register tree decl; - - if (decl_context == PARM) - { - tree type_as_written = type; - tree main_type; - - /* A parameter declared as an array of T is really a pointer to T. - One declared as a function is really a pointer to a function. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Transfer const-ness of array into that of type pointed to. */ - type = TREE_TYPE (type); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - type = build_pointer_type (type); - volatilep = constp = 0; - size_varies = 0; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - if (pedantic && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - type = build_pointer_type (type); - volatilep = constp = 0; - } - - decl = build_decl (PARM_DECL, declarator, type); - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; - - /* Compute the type actually passed in the parmlist, - for the case where there is no prototype. - (For example, shorts and chars are passed as ints.) - When there is a prototype, this is overridden later. */ - - 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; - /* Don't use TYPE_PRECISION to decide whether to promote, - because we should convert short if it's the same size as int, - but we should not convert long if it's the same size as int. */ - 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) - { - /* Structure field. It may not be a function. */ - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("field `%s' declared as a function", - IDENTIFIER_POINTER (declarator)); - type = build_pointer_type (type); - } - else if (TREE_CODE (type) != ERROR_MARK && TYPE_SIZE (type) == 0) - { - error ("field `%s' has incomplete type", - IDENTIFIER_POINTER (declarator)); - type = error_mark_node; - } - /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep)) - { - type = build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), - TYPE_DOMAIN (type)); -#if 0 /* Leave the field const or volatile as well. */ - constp = volatilep = 0; -#endif - } - decl = build_decl (FIELD_DECL, declarator, type); - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - /* Every function declaration is "external" - except for those which are inside a function body - in which `auto' is used. - That is a case not specified by ANSI C, - and we use it for forward declarations for nested functions. */ - 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'", - IDENTIFIER_POINTER (declarator)); - if (specbits & (1 << (int) RID_REGISTER)) - error ("invalid storage class for function `%s'", - IDENTIFIER_POINTER (declarator)); - /* Function declaration not at top level. - Storage classes other than `extern' are not allowed - and `extern' makes no difference. */ - if (current_binding_level != global_binding_level - && (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE))) - && pedantic) - pedwarn ("invalid storage class for function `%s'", - IDENTIFIER_POINTER (declarator)); - - /* If this is a block level extern, it must live past the end - of the function so that we can check it against other - extern declarations (IDENTIFIER_LIMBO_VALUE). */ - if (extern_ref && allocation_temporary_p ()) - end_temporary_allocation (); - - decl = build_decl (FUNCTION_DECL, declarator, type); - - if (pedantic && (constp || volatilep) - && ! DECL_IN_SYSTEM_HEADER (decl)) - pedwarn ("ANSI C forbids const or volatile functions"); - - if (volatilep - && TREE_TYPE (TREE_TYPE (decl)) != void_type_node) - warning ("`noreturn' function returns non-void value"); - - if (extern_ref) - DECL_EXTERNAL (decl) = 1; - /* Record absence of global scope for `static' or `auto'. */ - TREE_PUBLIC (decl) - = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO))); - /* Record presence of `inline', if it is reasonable. */ - if (inlinep) - { - tree last = tree_last (TYPE_ARG_TYPES (type)); - - if (! strcmp (IDENTIFIER_POINTER (declarator), "main")) - warning ("cannot inline function `main'"); - else if (last && (TYPE_MAIN_VARIANT (TREE_VALUE (last)) - != void_type_node)) - warning ("inline declaration ignored for function with `...'"); - else - /* Assume that otherwise the function can be inlined. */ - DECL_INLINE (decl) = 1; - - if (specbits & (1 << (int) RID_EXTERN)) - current_extern_inline = 1; - } - } - else - { - /* It's a variable. */ - /* An uninitialized decl with `extern' is a reference. */ - int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN)); - - /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep)) - { - type = build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), - TYPE_DOMAIN (type)); -#if 0 /* Leave the variable const or volatile as well. */ - constp = volatilep = 0; -#endif - } - - /* If this is a block level extern, it must live past the end - of the function so that we can check it against other - extern declarations (IDENTIFIER_LIMBO_VALUE). */ - 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'"); - - DECL_EXTERNAL (decl) = extern_ref; - /* At top level, the presence of a `static' or `register' storage - class specifier, or the absence of all storage class specifiers - makes this declaration a definition (perhaps tentative). Also, - the absence of both `static' and `register' makes it public. */ - 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); - } - /* Not at top level, only `static' makes a static definition. */ - 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; - } - - /* Record `register' declaration for warnings on & - and in case doing stupid register allocation. */ - - if (specbits & (1 << (int) RID_REGISTER)) - DECL_REGISTER (decl) = 1; - - /* Record constancy and volatility. */ - - if (constp) - TREE_READONLY (decl) = 1; - if (volatilep) - { - TREE_SIDE_EFFECTS (decl) = 1; - TREE_THIS_VOLATILE (decl) = 1; - } - /* If a type has volatile components, it should be stored in memory. - Otherwise, the fact that those components are volatile - will be ignored, and would even crash the compiler. */ - if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl))) - mark_addressable (decl); - - pop_obstacks (); - - return decl; - } -} - -/* Decode the parameter-list info for a function type or function definition. - The argument is the value returned by `get_parm_info' (or made in parse.y - if there is an identifier list instead of a parameter decl list). - These two functions are separate because when a function returns - or receives functions then each is called multiple times but the order - of calls is different. The last call to `grokparms' is always the one - that contains the formal parameter names of a function definition. - - Store in `last_function_parms' a chain of the decls of parms. - Also store in `last_function_parm_tags' a chain of the struct, union, - and enum tags declared among the parms. - - Return a list of arg types to use in the FUNCTION_TYPE for this function. - - FUNCDEF_FLAG is nonzero for a function definition, 0 for - a mere declaration. A nonempty identifier-list gets an error message - when FUNCDEF_FLAG is zero. */ - -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; - /* We no longer test FUNCDEF_FLAG. - If the arg types are incomplete in a declaration, - they must include undefined tags. - These tags can never be defined in the scope of the declaration, - so the types can never be completed, - and no call can be compiled successfully. */ -#if 0 - /* In a fcn definition, arg types must be complete. */ - if (funcdef_flag) -#endif - for (parm = last_function_parms, typelt = first_parm; - parm; - parm = TREE_CHAIN (parm)) - /* Skip over any enumeration constants declared here. */ - if (TREE_CODE (parm) == PARM_DECL) - { - /* Barf if the parameter itself has an incomplete type. */ - 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 /* This has been replaced by parm_tags_warning - which uses a more accurate criterion for what to warn about. */ - else - { - /* Now warn if is a pointer to an incomplete type. */ - 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); - } - - /* Allocate the list of types the way we allocate a type. */ - if (first_parm && ! TREE_PERMANENT (first_parm)) - { - /* Construct a copy of the list of types - on the saveable obstack. */ - 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 - /* The list we have is permanent already. */ - return first_parm; - } -} - - -/* Return a tree_list node with info on a parameter list just parsed. - The TREE_PURPOSE is a chain of decls of those parms. - The TREE_VALUE is a list of structure, union and enum tags defined. - The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE. - This tree_list node is later fed to `grokparms'. - - VOID_AT_END nonzero means append `void' to the end of the type-list. - Zero means the parmlist ended with an ellipsis so don't append `void'. */ - -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; - - /* Just `void' (and no ellipsis) is special. There are really no parms. */ - 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)); - } - - /* Extract enumerator values and other non-parms declared with the parms. - Likewise any forward parm decls that didn't have real parm decls. */ - 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; - } - - /* Put the parm decls back in the order they were in in the parm list. */ - 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); - - /* Store the parmlist in the binding level since the old one - is no longer a valid list. (We have changed the chain pointers.) */ - storedecls (new_parms); - - for (decl = new_parms; decl; decl = TREE_CHAIN (decl)) - /* There may also be declarations for enumerators if an enumeration - type is declared among the parms. Ignore them here. */ - if (TREE_CODE (decl) == PARM_DECL) - { - /* Since there is a prototype, - args are passed in their declared types. */ - 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)); -} - -/* At end of parameter list, warn about any struct, union or enum tags - defined within. Do so because these types cannot ever become complete. */ - -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)); - /* An anonymous union parm type is meaningful as a GNU extension. - So don't warn for that. */ - if (code == UNION_TYPE && !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,"); - warning ("which is probably not what you want."); - already = 1; - } - } -} - -/* Get the struct, enum or union (CODE says which) with tag NAME. - Define the tag as a forward-reference if it is not defined. */ - -tree -xref_tag (code, name) - enum tree_code code; - tree name; -{ - int temporary = allocation_temporary_p (); - - /* If a cross reference is requested, look up the type - already defined for this tag and return it. */ - - register tree ref = lookup_tag (code, name, current_binding_level, 0); - /* Even if this is the wrong type of tag, return what we found. - There will be an error message anyway, from pending_xref_error. - If we create an empty xref just for an invalid use of the type, - the main result is to create lots of superfluous error messages. */ - if (ref) - return ref; - - push_obstacks_nochange (); - - if (current_binding_level == global_binding_level && temporary) - end_temporary_allocation (); - - /* If no such tag is yet defined, create a forward-reference node - and record it as the "definition". - When a real declaration of this type is found, - the forward-reference will be altered into a real type. */ - - ref = make_node (code); - if (code == ENUMERAL_TYPE) - { - /* (In ANSI, Enums can be referred to only if already defined.) */ - if (pedantic) - pedwarn ("ANSI C forbids forward references to `enum' types"); - /* Give the type a default layout like unsigned int - to avoid crashing if it does not get defined. */ - 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; -} - -/* Make sure that the tag NAME is defined *in the current binding level* - at least as a forward reference. - CODE says which kind of tag NAME ought to be. - - We also do a push_obstacks_nochange - whose matching pop is in finish_struct. */ - -tree -start_struct (code, name) - enum tree_code code; - tree name; -{ - /* If there is already a tag defined at this binding level - (as a forward reference), just return it. */ - - 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; - if (TYPE_FIELDS (ref)) - error ((code == UNION_TYPE ? "redefinition of `union %s'" - : "redefinition of `struct %s'"), - IDENTIFIER_POINTER (name)); - - return ref; - } - - /* Otherwise create a forward-reference just so the tag is in scope. */ - - ref = make_node (code); - pushtag (name, ref); - C_TYPE_BEING_DEFINED (ref) = 1; - return ref; -} - -/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) - of a structure component, returning a FIELD_DECL node. - WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. - - This is done during the parsing of the struct declaration. - The FIELD_DECL nodes are chained together and the lot of them - are ultimately passed to `build_struct' to make the RECORD_TYPE node. */ - -tree -grokfield (filename, line, declarator, declspecs, width) - char *filename; - int line; - tree declarator, declspecs, width; -{ - tree value; - - /* The corresponding pop_obstacks is in finish_decl. */ - 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; -} - -/* Function to help qsort sort FIELD_DECLs by name order. */ - -static int -field_decl_cmp (x, y) - tree *x, *y; -{ - return (long)DECL_NAME (*x) - (long)DECL_NAME (*y); -} - -/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. - FIELDLIST is a chain of FIELD_DECL nodes for the fields. - - We also do a pop_obstacks to match the push in start_struct. */ - -tree -finish_struct (t, fieldlist) - register tree t, fieldlist; -{ - register tree x; - int old_momentary; - int toplevel = global_binding_level == current_binding_level; - - /* If this type was previously laid out as a forward reference, - make sure we lay it out again. */ - - TYPE_SIZE (t) = 0; - - /* Nameless union parm types are useful as GCC extension. */ - if (! (TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) == 0) && !pedantic) - /* Otherwise, warn about any struct or union def. in parmlist. */ - 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 (fieldlist == 0 && pedantic) - pedwarn ((TREE_CODE (t) == UNION_TYPE ? "union has no members" - : "structure has no members")); - - /* Install struct as DECL_CONTEXT of each field decl. - Also process specified field sizes. - Set DECL_FIELD_SIZE to the specified size, or 0 if none specified. - The specified size is found in the DECL_INITIAL. - Store 0 there, except for ": 0" fields (so we can find them - and delete them, below). */ - - for (x = fieldlist; x; x = TREE_CHAIN (x)) - { - DECL_CONTEXT (x) = t; - DECL_FIELD_SIZE (x) = 0; - - /* If any field is const, the structure type is pseudo-const. */ - if (TREE_READONLY (x)) - C_TYPE_FIELDS_READONLY (t) = 1; - else - { - /* A field that is pseudo-const makes the structure likewise. */ - 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; - } - - /* Any field that is volatile means variables of this type must be - treated in some ways as volatile. */ - if (TREE_THIS_VOLATILE (x)) - C_TYPE_FIELDS_VOLATILE (t) = 1; - - /* Any field of nominal variable size implies structure is too. */ - if (C_DECL_VARIABLE_SIZE (x)) - C_TYPE_VARIABLE_SIZE (t) = 1; - - /* Detect invalid nested redefinition. */ - if (TREE_TYPE (x) == t) - error ("nested redefinition of `%s'", - IDENTIFIER_POINTER (TYPE_NAME (t))); - - /* Detect invalid bit-field size. */ - 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; - } - } - - /* Detect invalid bit-field type. */ - 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 - /* Accept an enum that's equivalent to int or unsigned int. */ - && !(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"); - - /* Detect and ignore out of range field width. */ - 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; - } - } - - /* Process valid field width. */ - if (DECL_INITIAL (x)) - { - register int width = TREE_INT_CST_LOW (DECL_INITIAL (x)); - - DECL_FIELD_SIZE (x) = width; - DECL_BIT_FIELD (x) = 1; - DECL_INITIAL (x) = NULL; - - if (width == 0) - { - /* field size 0 => force desired amount of alignment. */ -#ifdef EMPTY_FIELD_BOUNDARY - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY); -#endif -#ifdef 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) - { - int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT - : TYPE_ALIGN (TREE_TYPE (x))); - /* Non-bit-fields are aligned for their type, except packed - fields which require only BITS_PER_UNIT alignment. */ - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align); - } - } - - /* Now DECL_INITIAL is null on all members. */ - - /* Delete all duplicate fields from the fieldlist */ - for (x = fieldlist; x && TREE_CHAIN (x);) - /* Anonymous fields aren't duplicates. */ - if (DECL_NAME (TREE_CHAIN (x)) == 0) - x = TREE_CHAIN (x); - else - { - 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'"); - TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); - } - else x = TREE_CHAIN (x); - } - - /* Now we have the nearly final fieldlist. Record it, - then lay out the structure or union (including the fields). */ - - TYPE_FIELDS (t) = fieldlist; - - layout_type (t); - - /* Delete all zero-width bit-fields from the front of the fieldlist */ - while (fieldlist - && DECL_INITIAL (fieldlist)) - fieldlist = TREE_CHAIN (fieldlist); - /* Delete all such members from the rest of the 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); - } - - /* Now we have the truly final field list. - Store it in this type and in the variants. */ - - TYPE_FIELDS (t) = fieldlist; - - /* If there are lots of fields, sort so we can look through them fast. - We arbitrarily consider 16 or more elts to be "a lot". */ - { - 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); - /* Use the same allocation policy here that make_node uses, to - ensure that this lives as long as the rest of the struct decl. - All decls in an inline function need to be saved. */ - 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); - } - - /* Promote each bit-field's type to int if it is narrower than that. */ - for (x = fieldlist; x; x = TREE_CHAIN (x)) - if (DECL_BIT_FIELD (x) - && (C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (x)) - || DECL_FIELD_SIZE (x) < TYPE_PRECISION (integer_type_node))) - { - tree type = TREE_TYPE (x); - - /* Preserve unsignedness if traditional - or if not really getting any wider. */ - if (TREE_UNSIGNED (type) - && (flag_traditional - || - (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node) - && - DECL_FIELD_SIZE (x) == TYPE_PRECISION (integer_type_node)))) - TREE_TYPE (x) = unsigned_type_node; - else - TREE_TYPE (x) = integer_type_node; - } - - /* If this structure or union completes the type of any previous - variable declaration, lay it out and output its rtl. */ - - if (current_binding_level->n_incomplete != 0) - { - tree decl; - for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl)) - { - if (TREE_TYPE (decl) == t - && TREE_CODE (decl) != TYPE_DECL) - { - layout_decl (decl, 0); - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0); - if (! toplevel) - expand_decl (decl); - --current_binding_level->n_incomplete; - } - else if (TYPE_SIZE (TREE_TYPE (decl)) == 0 - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - { - tree element = TREE_TYPE (decl); - while (TREE_CODE (element) == ARRAY_TYPE) - element = TREE_TYPE (element); - if (element == t) - layout_array_type (TREE_TYPE (decl)); - } - } - } - - resume_momentary (old_momentary); - - /* Finish debugging output for this type. */ - rest_of_type_compilation (t, toplevel); - - /* The matching push is in start_struct. */ - pop_obstacks (); - - return t; -} - -/* Lay out the type T, and its element type, and so on. */ - -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); -} - -/* Begin compiling the definition of an enumeration type. - NAME is its name (or null if anonymous). - Returns the type object, as yet incomplete. - Also records info about it so that build_enumerator - may be used to declare the individual values as they are read. */ - -tree -start_enum (name) - tree name; -{ - register tree enumtype = 0; - - /* If this is the real definition for a previous forward reference, - fill in the contents in the same object that used to be the - forward reference. */ - - if (name != 0) - enumtype = lookup_tag (ENUMERAL_TYPE, name, current_binding_level, 1); - - /* The corresponding pop_obstacks is in finish_enum. */ - push_obstacks_nochange (); - /* If these symbols and types are global, make them permanent. */ - 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) - { - /* This enum is a named one that has been declared already. */ - error ("redeclaration of `enum %s'", IDENTIFIER_POINTER (name)); - - /* Completely replace its old definition. - The old enumerators remain defined, however. */ - TYPE_VALUES (enumtype) = 0; - } - - enum_next_value = integer_zero_node; - enum_overflow = 0; - - return enumtype; -} - -/* After processing and defining all the values of an enumeration type, - install their decls in the enumeration type and finish it off. - ENUMTYPE is the type object and VALUES a list of decl-value pairs. - Returns ENUMTYPE. */ - -tree -finish_enum (enumtype, values) - register tree enumtype, values; -{ - 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"); - - /* Calculate the maximum value of any enumerator in this type. */ - - 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; - - /* An enum can have some negative values; then it is signed. */ - TREE_UNSIGNED (enumtype) = tree_int_cst_sgn (minnode) >= 0; - - /* Determine the precision this type needs. */ - - lowprec = min_precision (minnode, TREE_UNSIGNED (enumtype)); - highprec = min_precision (maxnode, TREE_UNSIGNED (enumtype)); - precision = MAX (lowprec, highprec); - - if (flag_short_enums || precision > TYPE_PRECISION (integer_type_node)) - /* Use the width of the narrowest normal C type which is wide enough. */ - TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size (precision, 1)); - else - TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); - - TYPE_SIZE (enumtype) = 0; - layout_type (enumtype); - - if (values != error_mark_node) - { - /* Change the type of the enumerators to be the enum type. - Formerly this was done only for enums that fit in an int, - but the comment said it was done only for enums wider than int. - It seems necessary to do this for wide enums, - and best not to change what's done for ordinary narrower ones. */ - 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); - } - - /* Replace the decl nodes in VALUES with their names. */ - for (pair = values; pair; pair = TREE_CHAIN (pair)) - TREE_PURPOSE (pair) = DECL_NAME (TREE_PURPOSE (pair)); - - TYPE_VALUES (enumtype) = values; - } - - /* Fix up all variant types of this enum type. */ - 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_MODE (tem) = TYPE_MODE (enumtype); - TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); - TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); - TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); - } - - /* Finish debugging output for this type. */ - rest_of_type_compilation (enumtype, toplevel); - - /* This matches a push in start_enum. */ - pop_obstacks (); - - return enumtype; -} - -/* Build and install a CONST_DECL for one value of the - current enumeration type (one that was begun with start_enum). - Return a tree-list containing the CONST_DECL and its value. - Assignment of sequential values by default is handled here. */ - -tree -build_enumerator (name, value) - tree name, value; -{ - register tree decl, type; - - /* Validate and default VALUE. */ - - /* Remove no-op casts from the value. */ - 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; - } - } - - /* Default based on previous value. */ - /* It should no longer be possible to have NON_LVALUE_EXPR - in the default. */ - 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; - } - - /* Set basis for default for next value. */ - enum_next_value = build_binary_op (PLUS_EXPR, value, integer_one_node, 0); - enum_overflow = tree_int_cst_lt (enum_next_value, value); - - /* Now create a declaration for the enum value name. */ - - 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); - - return saveable_tree_cons (decl, value, NULL_TREE); -} - -/* Create the FUNCTION_DECL for a function definition. - DECLSPECS and DECLARATOR are the parts of the declaration; - they describe the function's name and the type it returns, - but twisted together in a fashion that parallels the syntax of C. - - This function creates a binding context for the function body - as well as setting up the FUNCTION_DECL in current_function_decl. - - Returns 1 on success. If the DECLARATOR is not suitable for a function - (it defines a datum instead), we return 0, which tells - yyparse to report a parse error. - - NESTED is nonzero for a function nested within another function. */ - -int -start_function (declspecs, declarator, nested) - tree declarator, declspecs; - int nested; -{ - tree decl1, old_decl; - tree restype; - int old_immediate_size_expand = immediate_size_expand; - - current_function_returns_value = 0; /* Assume, until we see it does. */ - current_function_returns_null = 0; - warn_about_return_type = 0; - current_extern_inline = 0; - c_function_varargs = 0; - named_labels = 0; - shadowed_labels = 0; - - /* Don't expand any sizes in the return type of the function. */ - immediate_size_expand = 0; - - decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1); - - /* If the declarator is not suitable for a function definition, - cause a syntax error. */ - if (decl1 == 0) - return 0; - - announce_function (decl1); - - if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl1))) == 0) - { - error ("return-type is an incomplete type"); - /* Make it return void instead. */ - 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'"); - - /* Save the parm names or decls from this function's declarator - where store_parm_decls will find them. */ - current_function_parms = last_function_parms; - current_function_parm_tags = last_function_parm_tags; - - /* Make the init_value nonzero so pushdecl knows this is not tentative. - error_mark_node is replaced below (in poplevel) with the BLOCK. */ - DECL_INITIAL (decl1) = error_mark_node; - - /* If this definition isn't a prototype and we had a prototype declaration - before, copy the arg type info from that prototype. - But not if what we had before was a builtin function. */ - 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 there is no explicit declaration, look for any out-of-scope implicit - declarations. */ - if (old_decl == 0) - old_decl = IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)); - - /* Optionally warn of old-fashioned def with no previous prototype. */ - 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"); - /* Optionally warn of any global def with no previous 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'"); - /* Optionally warn of any def with no previous prototype - if the function has already been used. */ - 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"); - /* Optionally warn of any global def with no previous declaration. */ - 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'"); - /* Optionally warn of any def with no previous declaration - if the function has already been used. */ - 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"); - - /* This is a definition, not a reference. - So normally clear DECL_EXTERNAL. - However, `extern inline' acts like a declaration - except for defining how to inline. So set DECL_EXTERNAL in that case. */ - DECL_EXTERNAL (decl1) = current_extern_inline; - - /* This function exists in static storage. - (This does not mean `static' in the C sense!) */ - TREE_STATIC (decl1) = 1; - - /* A nested function is not global. */ - if (current_function_decl != 0) - TREE_PUBLIC (decl1) = 0; - - /* Record the decl so that the function name is defined. - If we already have a decl for this name, and it is a FUNCTION_DECL, - use the old decl. */ - - 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)); - /* Promote the value to int before returning it. */ - if (C_PROMOTING_INTEGER_TYPE_P (restype)) - { - /* It retains unsignedness if traditional - or if not really getting wider. */ - 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) - /* Allocate further tree nodes temporarily during compilation - of this function only. */ - temporary_allocation (); - - /* If this fcn was already referenced via a block-scope `extern' decl - (or an implicit decl), propagate certain information about the usage. */ - if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl))) - TREE_ADDRESSABLE (current_function_decl) = 1; - - immediate_size_expand = old_immediate_size_expand; - - return 1; -} - -/* Record that this function is going to be a varargs function. - This is called before store_parm_decls, which is too early - to call mark_varargs directly. */ - -void -c_mark_varargs () -{ - c_function_varargs = 1; -} - -/* Store the parameter declarations into the current function declaration. - This is called after parsing the parameter declarations, before - digesting the body of the function. - - For an old-style definition, modify the function's type - to specify at least the number of arguments. */ - -void -store_parm_decls () -{ - register tree fndecl = current_function_decl; - register tree parm; - - /* This is either a chain of PARM_DECLs (if a prototype was used) - or a list of IDENTIFIER_NODEs (for an old-fashioned C definition). */ - tree specparms = current_function_parms; - - /* This is a list of types declared among parms in a prototype. */ - tree parmtags = current_function_parm_tags; - - /* This is a chain of PARM_DECLs from old-style parm declarations. */ - register tree parmdecls = getdecls (); - - /* This is a chain of any other decls that came in among the parm - declarations. If a parm is declared with enum {foo, bar} x; - then CONST_DECLs for foo and bar are put here. */ - tree nonparms = 0; - - /* Nonzero if this definition is written with a prototype. */ - int prototype = 0; - - if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST) - { - /* This case is when the function was defined with an ANSI prototype. - The parms already have decls, so we need not do anything here - except record them as in effect - and complain if any redundant old-style parm decls were written. */ - - 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"); - /* Get rid of the erroneous decls; don't keep them on - the list of parms, since they might not be PARM_DECLs. */ - 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"); - /* Change the type to error_mark_node so this parameter - will be ignored by assign_parms. */ - TREE_TYPE (parm) = error_mark_node; - } - pushdecl (parm); - } - else - { - /* If we find an enum constant or a type tag, - put it aside for the moment. */ - TREE_CHAIN (parm) = 0; - others = chainon (others, parm); - } - } - - /* Get the decls in their original chain order - and record in the function. */ - DECL_ARGUMENTS (fndecl) = getdecls (); - -#if 0 - /* If this function takes a variable number of arguments, - add a phony parameter to the end of the parm list, - to represent the position of the first unnamed argument. */ - 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); - /* Let's hope the address of the unnamed parm - won't depend on its type. */ - TREE_TYPE (dummy) = integer_type_node; - DECL_ARG_TYPE (dummy) = integer_type_node; - DECL_ARGUMENTS (fndecl) - = chainon (DECL_ARGUMENTS (fndecl), dummy); - } -#endif - - /* Now pushdecl the enum constants. */ - 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 - { - /* SPECPARMS is an identifier list--a chain of TREE_LIST nodes - each with a parm name as the TREE_VALUE. - - PARMDECLS is a chain of declarations for parameters. - Warning! It can also contain CONST_DECLs which are not parameters - but are names of enumerators of any enum types - declared among the parameters. - - First match each formal parameter name with its declaration. - Associate decls with the names and store the decls - into the TREE_PURPOSE slots. */ - - 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; - } - - /* See if any of the parmdecls specifies this parm by name. - Ignore any enumerator decls. */ - for (tail = parmdecls; tail; tail = TREE_CHAIN (tail)) - if (DECL_NAME (tail) == TREE_VALUE (parm) - && TREE_CODE (tail) == PARM_DECL) - { - found = tail; - break; - } - - /* If declaration already marked, we have a duplicate name. - Complain, and don't use this decl twice. */ - if (found && DECL_RESULT (found) != 0) - { - error_with_decl (found, "multiple parameters named `%s'"); - found = 0; - } - - /* If the declaration says "void", complain and ignore it. */ - 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); - } - - /* Traditionally, a parm declared float is actually a double. */ - 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 no declaration found, default to int. */ - 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; - - /* Mark this decl as "already found" -- see test, above. - It is safe to use DECL_RESULT for this - since it is not used in PARM_DECLs or CONST_DECLs. */ - DECL_RESULT (found) = error_mark_node; - } - - /* Put anything which is on the parmdecls chain and which is - not a PARM_DECL onto the list NONPARMS. (The types of - non-parm things which might appear on the list include - enumerators and NULL-named TYPE_DECL nodes.) Complain about - any actual PARM_DECLs not matched with any names. */ - - 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 - { - /* Complain about args with incomplete types. */ - 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"); - /* Pretend the parameter was not missing. - This gets us to a standard state and minimizes - further error messages. */ - specparms - = chainon (specparms, - tree_cons (parm, NULL_TREE, NULL_TREE)); - } - } - - parm = next; - } - - /* Chain the declarations together in the order of the list of names. */ - /* Store that chain in the function decl, replacing the list of names. */ - 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 there was a previous prototype, - set the DECL_ARG_TYPE of each argument according to - the type previously specified, and report any mismatches. */ - - 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; - } - /* Type for passing arg must be consistent - with that declared for the arg. */ - if (! comptypes (DECL_ARG_TYPE (parm), TREE_VALUE (type))) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) - == TYPE_MAIN_VARIANT (TREE_VALUE (type))) - { - /* Adjust argument to match prototype. E.g. a previous - `int foo(float);' prototype causes - `int foo(x) float x; {...}' to be treated like - `int foo(float x) {...}'. This is particularly - useful for argument types like uid_t. */ - 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"); - } - } - /* If -traditional, allow `int' argument to match - `unsigned' prototype. */ - 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; - } - - /* Otherwise, create a prototype that would match. */ - - 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; - - /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES - of the type of this function, but we need to avoid having this - affect the types of other similarly-typed functions, so we must - first force the generation of an identical (but separate) type - node for the relevant function type. The new node we create - will be a variant of the main variant of the original function - type. */ - - TREE_TYPE (fndecl) = build_type_copy (TREE_TYPE (fndecl)); - - TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual; - } - - /* Now store the final chain of decls for the arguments - as the decl-chain of the current lexical scope. - Put the enumerators in as well, at the front so that - DECL_ARGUMENTS is not modified. */ - - storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl))); - } - - /* Make sure the binding level for the top of the function body - gets a BLOCK if there are any in the function. - Otherwise, the dbx output is wrong. */ - - keep_next_if_subblocks = 1; - - /* ??? This might be an improvement, - but needs to be thought about some more. */ -#if 0 - keep_next_level_flag = 1; -#endif - - /* Write a record describing this function definition to the prototypes - file (if requested). */ - - gen_aux_info_record (fndecl, 1, 0, prototype); - - /* Initialize the RTL code for the function. */ - - init_function_start (fndecl, input_filename, lineno); - - /* If this is a varargs function, inform function.c. */ - - if (c_function_varargs) - mark_varargs (); - - /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */ - - declare_function_name (); - - /* Set up parameters and prepare for return, for the function. */ - - expand_function_start (fndecl, 0); - - /* If this function is `main', emit a call to `__main' - to run global initializers, etc. */ - if (DECL_NAME (fndecl) - && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0 - && DECL_CONTEXT (fndecl) == NULL_TREE) - expand_main_function (); -} - -/* SPECPARMS is an identifier list--a chain of TREE_LIST nodes - each with a parm name as the TREE_VALUE. A null pointer as TREE_VALUE - stands for an ellipsis in the identifier list. - - PARMLIST is the data returned by get_parm_info for the - parmlist that follows the semicolon. - - We return a value of the same sort that get_parm_info returns, - except that it describes the combination of identifiers and parmlist. */ - -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); - - /* This is a chain of any other decls that came in among the parm - declarations. They were separated already by get_parm_info, - so we just need to keep them separate. */ - 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; - - /* See if any of the parmdecls specifies this parm by name. */ - for (tail = parmdecls; tail; tail = TREE_CHAIN (tail)) - if (DECL_NAME (tail) == TREE_VALUE (parm)) - { - found = tail; - break; - } - - /* If declaration already marked, we have a duplicate name. - Complain, and don't use this decl twice. */ - if (found && DECL_RESULT (found) != 0) - { - error_with_decl (found, "multiple parameters named `%s'"); - found = 0; - } - - /* If the declaration says "void", complain and ignore it. */ - 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); - } - - /* Traditionally, a parm declared float is actually a double. */ - 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 no declaration found, default to int. */ - 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; - - /* Mark this decl as "already found" -- see test, above. - It is safe to use DECL_RESULT for this - since it is not used in PARM_DECLs or CONST_DECLs. */ - DECL_RESULT (found) = error_mark_node; - } - - /* Complain about any actual PARM_DECLs not matched with any names. */ - - for (parm = parmdecls; parm; ) - { - tree next = TREE_CHAIN (parm); - TREE_CHAIN (parm) = 0; - - /* Complain about args with incomplete types. */ - 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"); - /* Pretend the parameter was not missing. - This gets us to a standard state and minimizes - further error messages. */ - specparms - = chainon (specparms, - tree_cons (parm, NULL_TREE, NULL_TREE)); - } - - parm = next; - } - - /* Chain the declarations together in the order of the list of names. - At the same time, build up a list of their types, in reverse order. */ - - 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)); -} - -/* Finish up a function declaration and compile that function - all the way to assembler language output. The free the storage - for the function definition. - - This is called after parsing the body of the function definition. - - NESTED is nonzero if the function being finished is nested in another. */ - -void -finish_function (nested) - int nested; -{ - register tree fndecl = current_function_decl; - -/* TREE_READONLY (fndecl) = 1; - This caused &foo to be of type ptr-to-const-function - which then got a warning when stored in a ptr-to-function variable. */ - - poplevel (1, 0, 1); - BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - - /* Must mark the RESULT_DECL as being in this function. */ - - DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; - - /* Obey `register' declarations if `setjmp' is called in this fn. */ - if (flag_traditional && current_function_calls_setjmp) - { - setjmp_protect (DECL_INITIAL (fndecl)); - setjmp_protect_args (); - } - -#ifdef DEFAULT_MAIN_RETURN - if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main")) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) - != integer_type_node) - warning_with_decl (fndecl, "return type of `%s' is not `int'"); - else - { - /* Make it so that `main' always returns success by default. */ - DEFAULT_MAIN_RETURN; - } - } -#endif - - /* Generate rtl for function exit. */ - expand_function_end (input_filename, lineno, 0); - - /* So we can tell if jump_optimize sets it to 1. */ - can_reach_end = 0; - - /* Run the optimizers and output the assembler code for this function. */ - rest_of_compilation (fndecl); - - current_function_returns_null |= can_reach_end; - - 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) - /* If this function returns non-void and control can drop through, - complain. */ - warning ("control reaches end of non-void function"); - /* With just -W, complain only if function returns both with - and without a value. */ - else if (extra_warnings - && current_function_returns_value && current_function_returns_null) - warning ("this function may return with or without a value"); - - /* If requested, warn about function definitions where the function will - return a value (usually of some struct or union type) which itself will - take up a lot of stack space. */ - - 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); - } - } - } - - /* Free all the tree nodes making up this function. */ - /* Switch back to allocating nodes permanently - until we start another function. */ - if (! nested) - permanent_allocation (1); - - if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested) - { - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this - was an actual function definition. */ - /* For a nested function, this is done in pop_c_function_context. */ - /* If rest_of_compilation set this to 0, leave it 0. */ - if (DECL_INITIAL (fndecl) != 0) - DECL_INITIAL (fndecl) = error_mark_node; - DECL_ARGUMENTS (fndecl) = 0; - } - - if (! nested) - { - /* Let the error reporting routines know that we're outside a - function. For a nested function, this value is used in - pop_c_function_context and then reset via pop_function_context. */ - current_function_decl = NULL; - } -} - -/* Save and restore the variables in this file and elsewhere - that keep track of the progress of compilation of the current function. - Used for nested functions. */ - -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; - -/* Save and reinitialize the variables - used during compilation of a C function. */ - -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; -} - -/* Restore the variables used during compilation of a C function. */ - -void -pop_c_function_context () -{ - struct c_function *p = c_function_chain; - tree link; - - /* Bring back all the labels that were shadowed. */ - 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) - { - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this - was an actual function definition. */ - 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); -} - -/* integrate_decl_tree calls this function, but since we don't use the - DECL_LANG_SPECIFIC field, this is a no-op. */ - -void -copy_lang_decl (node) - tree node; -{ -} diff --git a/gnu/usr.bin/cc/cc1/c-iterate.c b/gnu/usr.bin/cc/cc1/c-iterate.c deleted file mode 100644 index 14d4bab..0000000 --- a/gnu/usr.bin/cc/cc1/c-iterate.c +++ /dev/null @@ -1,595 +0,0 @@ -/* Build expressions with type checking for C compiler. - Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* This file is part of the C front end. - It is responsible for implementing iterators, - both their declarations and the expansion of statements using them. */ - -#include "config.h" -#include <stdio.h> -#include "tree.h" -#include "c-tree.h" -#include "flags.h" -#include "obstack.h" -#include "rtl.h" - -static void expand_stmt_with_iterators_1 (); -static tree collect_iterators (); -static void iterator_loop_prologue (); -static void iterator_loop_epilogue (); -static void add_ixpansion (); -static void delete_ixpansion(); -static int top_level_ixpansion_p (); -static void istack_sublevel_to_current (); - -/* A special obstack, and a pointer to the start of - all the data in it (so we can free everything easily). */ -static struct obstack ixp_obstack; -static char *ixp_firstobj; - -/* - KEEPING TRACK OF EXPANSIONS - - In order to clean out expansions corresponding to statements inside - "{(...)}" constructs we have to keep track of all expansions. The - cleanup is needed when an automatic, or implicit, expansion on - iterator, say X, happens to a statement which contains a {(...)} - form with a statement already expanded on X. In this case we have - to go back and cleanup the inner expansion. This can be further - complicated by the fact that {(...)} can be nested. - - To make this cleanup possible, we keep lists of all expansions, and - to make it work for nested constructs, we keep a stack. The list at - the top of the stack (ITER_STACK.CURRENT_LEVEL) corresponds to the - currently parsed level. All expansions of the levels below the - current one are kept in one list whose head is pointed to by - ITER_STACK.SUBLEVEL_FIRST (SUBLEVEL_LAST is there for making merges - easy). The process works as follows: - - -- On "({" a new node is added to the stack by PUSH_ITERATOR_STACK. - The sublevel list is not changed at this point. - - -- On "})" the list for the current level is appended to the sublevel - list. - - -- On ";" sublevel lists are appended to the current level lists. - The reason is this: if they have not been superseded by the - expansion at the current level, they still might be - superseded later by the expansion on the higher level. - The levels do not have to distinguish levels below, so we - can merge the lists together. */ - -struct ixpansion -{ - tree ixdecl; /* Iterator decl */ - rtx ixprologue_start; /* First insn of epilogue. NULL means */ - /* explicit (FOR) expansion*/ - rtx ixprologue_end; - rtx ixepilogue_start; - rtx ixepilogue_end; - struct ixpansion *next; /* Next in the list */ -}; - -struct iter_stack_node -{ - struct ixpansion *first; /* Head of list of ixpansions */ - struct ixpansion *last; /* Last node in list of ixpansions */ - struct iter_stack_node *next; /* Next level iterator stack node */ -}; - -struct iter_stack_node *iter_stack; - -struct iter_stack_node sublevel_ixpansions; - -/* During collect_iterators, a list of SAVE_EXPRs already scanned. */ -static tree save_exprs; - -/* Initialize our obstack once per compilation. */ - -void -init_iterators () -{ - gcc_obstack_init (&ixp_obstack); - ixp_firstobj = (char *) obstack_alloc (&ixp_obstack, 0); -} - -/* Handle the start of an explicit `for' loop for iterator IDECL. */ - -void -iterator_for_loop_start (idecl) - tree idecl; -{ - ITERATOR_BOUND_P (idecl) = 1; - add_ixpansion (idecl, 0, 0, 0, 0); - iterator_loop_prologue (idecl, 0, 0); -} - -/* Handle the end of an explicit `for' loop for iterator IDECL. */ - -void -iterator_for_loop_end (idecl) - tree idecl; -{ - iterator_loop_epilogue (idecl, 0, 0); - ITERATOR_BOUND_P (idecl) = 0; -} - -/* - ITERATOR RTL EXPANSIONS - - Expanding simple statements with iterators is straightforward: - collect the list of all free iterators in the statement, and - generate a loop for each of them. - - An iterator is "free" if it has not been "bound" by a FOR - operator. The DECL_RTL of the iterator is the loop counter. */ - -/* Expand a statement STMT, possibly containing iterator usage, into RTL. */ - -void -iterator_expand (stmt) - tree stmt; -{ - tree iter_list; - save_exprs = NULL_TREE; - iter_list = collect_iterators (stmt, NULL_TREE); - expand_stmt_with_iterators_1 (stmt, iter_list); - istack_sublevel_to_current (); -} - - -static void -expand_stmt_with_iterators_1 (stmt, iter_list) - tree stmt, iter_list; -{ - if (iter_list == 0) - expand_expr_stmt (stmt); - else - { - tree current_iterator = TREE_VALUE (iter_list); - tree iter_list_tail = TREE_CHAIN (iter_list); - rtx p_start, p_end, e_start, e_end; - - iterator_loop_prologue (current_iterator, &p_start, &p_end); - expand_stmt_with_iterators_1 (stmt, iter_list_tail); - iterator_loop_epilogue (current_iterator, &e_start, &e_end); - - /** Delete all inner expansions based on current_iterator **/ - /** before adding the outer one. **/ - - delete_ixpansion (current_iterator); - add_ixpansion (current_iterator, p_start, p_end, e_start, e_end); - } -} - - -/* Return a list containing all the free (i.e. not bound by a - containing `for' statement) iterators mentioned in EXP, plus those - in LIST. Do not add duplicate entries to the list. */ - -static tree -collect_iterators (exp, list) - tree exp, list; -{ - if (exp == 0) return list; - - switch (TREE_CODE (exp)) - { - case VAR_DECL: - if (! ITERATOR_P (exp) || ITERATOR_BOUND_P (exp)) - return list; - if (value_member (exp, list)) - return list; - return tree_cons (NULL_TREE, exp, list); - - case TREE_LIST: - { - tree tail; - for (tail = exp; tail; tail = TREE_CHAIN (tail)) - list = collect_iterators (TREE_VALUE (tail), list); - return list; - } - - case SAVE_EXPR: - /* In each scan, scan a given save_expr only once. */ - if (value_member (exp, save_exprs)) - return list; - - save_exprs = tree_cons (NULL_TREE, exp, save_exprs); - return collect_iterators (TREE_OPERAND (exp, 0), list); - - /* we do not automatically iterate blocks -- one must */ - /* use the FOR construct to do that */ - - case BLOCK: - return list; - - default: - switch (TREE_CODE_CLASS (TREE_CODE (exp))) - { - case '1': - return collect_iterators (TREE_OPERAND (exp, 0), list); - - case '2': - case '<': - return collect_iterators (TREE_OPERAND (exp, 0), - collect_iterators (TREE_OPERAND (exp, 1), - list)); - - case 'e': - case 'r': - { - int num_args = tree_code_length[(int) TREE_CODE (exp)]; - int i; - - /* Some tree codes have RTL, not trees, as operands. */ - switch (TREE_CODE (exp)) - { - case CALL_EXPR: - num_args = 2; - break; - case METHOD_CALL_EXPR: - num_args = 3; - break; - case WITH_CLEANUP_EXPR: - num_args = 1; - break; - case RTL_EXPR: - return list; - } - - for (i = 0; i < num_args; i++) - list = collect_iterators (TREE_OPERAND (exp, i), list); - return list; - } - default: - return list; - } - } -} - -/* Emit rtl for the start of a loop for iterator IDECL. - - If necessary, create loop counter rtx and store it as DECL_RTL of IDECL. - - The prologue normally starts and ends with notes, which are returned - by this function in *START_NOTE and *END_NODE. - If START_NOTE and END_NODE are 0, we don't make those notes. */ - -static void -iterator_loop_prologue (idecl, start_note, end_note) - tree idecl; - rtx *start_note, *end_note; -{ - tree expr; - - /* Force the save_expr in DECL_INITIAL to be calculated - if it hasn't been calculated yet. */ - expand_expr (DECL_INITIAL (idecl), const0_rtx, VOIDmode, 0); - - if (DECL_RTL (idecl) == 0) - expand_decl (idecl); - - if (start_note) - *start_note = emit_note (0, NOTE_INSN_DELETED); - - /* Initialize counter. */ - expr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, integer_zero_node); - TREE_SIDE_EFFECTS (expr) = 1; - expand_expr (expr, const0_rtx, VOIDmode, 0); - - expand_start_loop_continue_elsewhere (1); - - ITERATOR_BOUND_P (idecl) = 1; - - if (end_note) - *end_note = emit_note (0, NOTE_INSN_DELETED); -} - -/* Similar to the previous function, but for the end of the loop. - - DECL_RTL is zeroed unless we are inside "({...})". The reason for that is - described below. - - When we create two (or more) loops based on the same IDECL, and - both inside the same "({...})" construct, we must be prepared to - delete both of the loops and create a single one on the level - above, i.e. enclosing the "({...})". The new loop has to use the - same counter rtl because the references to the iterator decl - (IDECL) have already been expanded as references to the counter - rtl. - - It is incorrect to use the same counter reg in different functions, - and it is desirable to use different counters in disjoint loops - when we know there's no need to combine them (because then they can - get allocated separately). */ - -static void -iterator_loop_epilogue (idecl, start_note, end_note) - tree idecl; - rtx *start_note, *end_note; -{ - tree test, incr; - - if (start_note) - *start_note = emit_note (0, NOTE_INSN_DELETED); - expand_loop_continue_here (); - incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0); - incr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr); - TREE_SIDE_EFFECTS (incr) = 1; - expand_expr (incr, const0_rtx, VOIDmode, 0); - test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0); - expand_exit_loop_if_false (0, test); - expand_end_loop (); - - ITERATOR_BOUND_P (idecl) = 0; - /* we can reset rtl since there is not chance that this expansion */ - /* would be superceded by a higher level one */ - if (top_level_ixpansion_p ()) - DECL_RTL (idecl) = 0; - if (end_note) - *end_note = emit_note (0, NOTE_INSN_DELETED); -} - -/* Return true if we are not currently inside a "({...})" construct. */ - -static int -top_level_ixpansion_p () -{ - return iter_stack == 0; -} - -/* Given two chains of iter_stack_nodes, - append the nodes in X into Y. */ - -static void -isn_append (x, y) - struct iter_stack_node *x, *y; -{ - if (x->first == 0) - return; - - if (y->first == 0) - { - y->first = x->first; - y->last = x->last; - } - else - { - y->last->next = x->first; - y->last = x->last; - } -} - -/** Make X empty **/ - -#define ISN_ZERO(X) (X).first=(X).last=0 - -/* Move the ixpansions in sublevel_ixpansions into the current - node on the iter_stack, or discard them if the iter_stack is empty. - We do this at the end of a statement. */ - -static void -istack_sublevel_to_current () -{ - /* At the top level we can throw away sublevel's expansions **/ - /* because there is nobody above us to ask for a cleanup **/ - if (iter_stack != 0) - /** Merging with empty sublevel list is a no-op **/ - if (sublevel_ixpansions.last) - isn_append (&sublevel_ixpansions, iter_stack); - - if (iter_stack == 0) - obstack_free (&ixp_obstack, ixp_firstobj); - - ISN_ZERO (sublevel_ixpansions); -} - -/* Push a new node on the iter_stack, when we enter a ({...}). */ - -void -push_iterator_stack () -{ - struct iter_stack_node *new_top - = (struct iter_stack_node*) - obstack_alloc (&ixp_obstack, sizeof (struct iter_stack_node)); - - new_top->first = 0; - new_top->last = 0; - new_top->next = iter_stack; - iter_stack = new_top; -} - -/* Pop iter_stack, moving the ixpansions in the node being popped - into sublevel_ixpansions. */ - -void -pop_iterator_stack () -{ - if (iter_stack == 0) - abort (); - - isn_append (iter_stack, &sublevel_ixpansions); - /** Pop current level node: */ - iter_stack = iter_stack->next; -} - - -/* Record an iterator expansion ("ixpansion") for IDECL. - The remaining paramters are the notes in the loop entry - and exit rtl. */ - -static void -add_ixpansion (idecl, pro_start, pro_end, epi_start, epi_end) - tree idecl; - rtx pro_start, pro_end, epi_start, epi_end; -{ - struct ixpansion* newix; - - /* Do nothing if we are not inside "({...})", - as in that case this expansion can't need subsequent RTL modification. */ - if (iter_stack == 0) - return; - - newix = (struct ixpansion*) obstack_alloc (&ixp_obstack, - sizeof (struct ixpansion)); - newix->ixdecl = idecl; - newix->ixprologue_start = pro_start; - newix->ixprologue_end = pro_end; - newix->ixepilogue_start = epi_start; - newix->ixepilogue_end = epi_end; - - newix->next = iter_stack->first; - iter_stack->first = newix; - if (iter_stack->last == 0) - iter_stack->last = newix; -} - -/* Delete the RTL for all ixpansions for iterator IDECL - in our sublevels. We do this when we make a larger - containing expansion for IDECL. */ - -static void -delete_ixpansion (idecl) - tree idecl; -{ - struct ixpansion* previx = 0, *ix; - - for (ix = sublevel_ixpansions.first; ix; ix = ix->next) - if (ix->ixdecl == idecl) - { - /** zero means that this is a mark for FOR -- **/ - /** we do not delete anything, just issue an error. **/ - - if (ix->ixprologue_start == 0) - error_with_decl (idecl, - "`for (%s)' appears within implicit iteration"); - else - { - rtx insn; - /* We delete all insns, including notes because leaving loop */ - /* notes and barriers produced by iterator expansion would */ - /* be misleading to other phases */ - - for (insn = NEXT_INSN (ix->ixprologue_start); - insn != ix->ixprologue_end; - insn = NEXT_INSN (insn)) - delete_insn (insn); - for (insn = NEXT_INSN (ix->ixepilogue_start); - insn != ix->ixepilogue_end; - insn = NEXT_INSN (insn)) - delete_insn (insn); - } - - /* Delete this ixpansion from sublevel_ixpansions. */ - if (previx) - previx->next = ix->next; - else - sublevel_ixpansions.first = ix->next; - if (sublevel_ixpansions.last == ix) - sublevel_ixpansions.last = previx; - } - else - previx = ix; -} - -#ifdef DEBUG_ITERATORS - -/* The functions below are for use from source level debugger. - They print short forms of iterator lists and the iterator stack. */ - -/* Print the name of the iterator D. */ - -void -prdecl (d) - tree d; -{ - if (d) - { - if (TREE_CODE (d) == VAR_DECL) - { - tree tname = DECL_NAME (d); - char *dname = IDENTIFIER_POINTER (tname); - fprintf (stderr, dname); - } - else - fprintf (stderr, "<<Not a Decl!!!>>"); - } - else - fprintf (stderr, "<<NULL!!>>"); -} - -/* Print Iterator List -- names only */ - -tree -pil (head) - tree head; -{ - tree current, next; - for (current = head; current; current = next) - { - tree node = TREE_VALUE (current); - prdecl (node); - next = TREE_CHAIN (current); - if (next) fprintf (stderr, ","); - } - fprintf (stderr, "\n"); -} - -/* Print IXpansion List */ - -struct ixpansion * -pixl (head) - struct ixpansion *head; -{ - struct ixpansion *current, *next; - fprintf (stderr, "> "); - if (head == 0) - fprintf (stderr, "(empty)"); - - for (current=head; current; current = next) - { - tree node = current->ixdecl; - prdecl (node); - next = current->next; - if (next) - fprintf (stderr, ","); - } - fprintf (stderr, "\n"); - return head; -} - -/* Print Iterator Stack*/ - -void -pis () -{ - struct iter_stack_node *stack_node; - - fprintf (stderr, "--SubLevel: "); - pixl (sublevel_ixpansions.first); - fprintf (stderr, "--Stack:--\n"); - for (stack_node = iter_stack; - stack_node; - stack_node = stack_node->next) - pixl (stack_node->first); -} - -#endif /* DEBUG_ITERATORS */ diff --git a/gnu/usr.bin/cc/cc1/c-lang.c b/gnu/usr.bin/cc/cc1/c-lang.c deleted file mode 100644 index eb3ce7b..0000000 --- a/gnu/usr.bin/cc/cc1/c-lang.c +++ /dev/null @@ -1,129 +0,0 @@ -/* Language-specific hook definitions for C front end. - Copyright (C) 1991 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include "config.h" -#include "tree.h" -#include <stdio.h> -#include "input.h" - -/* Each of the functions defined here - is an alternative to a function in objc-actions.c. */ - -int -lang_decode_option (p) - char *p; -{ - return c_decode_option (p); -} - -void -lang_init () -{ - /* the beginning of the file is a new line; check for # */ - /* With luck, we discover the real source file's name from that - and put it in input_filename. */ - ungetc (check_newline (), finput); -} - -void -lang_finish () -{ -} - -char * -lang_identify () -{ - return "c"; -} - -void -print_lang_statistics () -{ -} - -/* Used by c-lex.c, but only for objc. */ - -tree -lookup_interface (arg) - tree arg; -{ - return 0; -} - -tree -is_class_name (arg) - tree arg; -{ - return 0; -} - -void -maybe_objc_check_decl (decl) - tree decl; -{ -} - -int -maybe_objc_comptypes (lhs, rhs, reflexive) - tree lhs, rhs; - int reflexive; -{ - return -1; -} - -tree -maybe_objc_method_name (decl) - tree decl; -{ - return 0; -} - -tree -maybe_building_objc_message_expr () -{ - return 0; -} - -int -recognize_objc_keyword () -{ - return 0; -} - -tree -build_objc_string (len, str) - int len; - char *str; -{ - abort (); - return NULL_TREE; -} - -void -GNU_xref_begin () -{ - fatal ("GCC does not yet support XREF"); -} - -void -GNU_xref_end () -{ - fatal ("GCC does not yet support XREF"); -} diff --git a/gnu/usr.bin/cc/cc1/c-lex.c b/gnu/usr.bin/cc/cc1/c-lex.c deleted file mode 100644 index 6806b6f..0000000 --- a/gnu/usr.bin/cc/cc1/c-lex.c +++ /dev/null @@ -1,1983 +0,0 @@ -/* Lexical analyzer for C and Objective C. - Copyright (C) 1987, 1988, 1989, 1992, 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include <stdio.h> -#include <errno.h> -#include <setjmp.h> - -#include "config.h" -#include "rtl.h" -#include "tree.h" -#include "input.h" -#include "c-lex.h" -#include "c-tree.h" -#include "flags.h" -#include "c-parse.h" - -#include <ctype.h> - -#ifdef MULTIBYTE_CHARS -#include <stdlib.h> -#include <locale.h> -#endif - -#ifndef errno -extern int errno; -#endif - -/* The elements of `ridpointers' are identifier nodes - for the reserved type names and storage classes. - It is indexed by a RID_... value. */ -tree ridpointers[(int) RID_MAX]; - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -tree lastiddecl; - -/* Nonzero enables objc features. */ - -int doing_objc_thang; - -extern tree is_class_name (); - -extern int yydebug; - -/* File used for outputting assembler code. */ -extern FILE *asm_out_file; - -#ifndef WCHAR_TYPE_SIZE -#ifdef INT_TYPE_SIZE -#define WCHAR_TYPE_SIZE INT_TYPE_SIZE -#else -#define WCHAR_TYPE_SIZE BITS_PER_WORD -#endif -#endif - -/* Number of bytes in a wide character. */ -#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - -static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. - This is not static because objc-parse.y uses it. */ - -/* Nonzero if end-of-file has been seen on input. */ -static int end_of_file; - -/* Buffered-back input character; faster than using ungetc. */ -static int nextchar = -1; - -int check_newline (); - -/* Do not insert generated code into the source, instead, include it. - This allows us to build gcc automatically even for targets that - need to add or modify the reserved keyword lists. */ -#include "c-gperf.h" - -/* Return something to represent absolute declarators containing a *. - TARGET is the absolute declarator that the * contains. - TYPE_QUALS is a list of modifiers such as const or volatile - to apply to the pointer type, represented as identifiers. - - We return an INDIRECT_REF whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_pointer_declarator (type_quals, target) - tree type_quals, target; -{ - return build1 (INDIRECT_REF, type_quals, target); -} - -void -forget_protocol_qualifiers () -{ - int i, n = sizeof wordlist / sizeof (struct resword); - - for (i = 0; i < n; i++) - if ((int) wordlist[i].rid >= (int) RID_IN - && (int) wordlist[i].rid <= (int) RID_ONEWAY) - wordlist[i].name = ""; -} - -void -remember_protocol_qualifiers () -{ - int i, n = sizeof wordlist / sizeof (struct resword); - - for (i = 0; i < n; i++) - if (wordlist[i].rid == RID_IN) - wordlist[i].name = "in"; - else if (wordlist[i].rid == RID_OUT) - wordlist[i].name = "out"; - else if (wordlist[i].rid == RID_INOUT) - wordlist[i].name = "inout"; - else if (wordlist[i].rid == RID_BYCOPY) - wordlist[i].name = "bycopy"; - else if (wordlist[i].rid == RID_ONEWAY) - wordlist[i].name = "oneway"; -} - -void -init_lex () -{ - /* Make identifier nodes long enough for the language-specific slots. */ - set_identifier_size (sizeof (struct lang_identifier)); - - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - -#ifdef MULTIBYTE_CHARS - /* Change to the native locale for multibyte conversions. */ - setlocale (LC_CTYPE, ""); -#endif - - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - ridpointers[(int) RID_INT] = get_identifier ("int"); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - ridpointers[(int) RID_ITERATOR] = get_identifier ("iterator"); - ridpointers[(int) RID_COMPLEX] = get_identifier ("complex"); - ridpointers[(int) RID_ID] = get_identifier ("id"); - ridpointers[(int) RID_IN] = get_identifier ("in"); - ridpointers[(int) RID_OUT] = get_identifier ("out"); - ridpointers[(int) RID_INOUT] = get_identifier ("inout"); - ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy"); - ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway"); - forget_protocol_qualifiers(); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - - if (! doing_objc_thang) - UNSET_RESERVED_WORD ("id"); - - if (flag_traditional) - { - UNSET_RESERVED_WORD ("const"); - UNSET_RESERVED_WORD ("volatile"); - UNSET_RESERVED_WORD ("typeof"); - UNSET_RESERVED_WORD ("signed"); - UNSET_RESERVED_WORD ("inline"); - UNSET_RESERVED_WORD ("iterator"); - UNSET_RESERVED_WORD ("complex"); - } - if (flag_no_asm) - { - UNSET_RESERVED_WORD ("asm"); - UNSET_RESERVED_WORD ("typeof"); - UNSET_RESERVED_WORD ("inline"); - UNSET_RESERVED_WORD ("iterator"); - UNSET_RESERVED_WORD ("complex"); - } -} - -void -reinit_parse_for_function () -{ -} - -/* Function used when yydebug is set, to print a token in more detail. */ - -void -yyprint (file, yychar, yylval) - FILE *file; - int yychar; - YYSTYPE yylval; -{ - tree t; - switch (yychar) - { - case IDENTIFIER: - case TYPENAME: - case OBJECTNAME: - t = yylval.ttype; - if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); - break; - - case CONSTANT: - t = yylval.ttype; - if (TREE_CODE (t) == INTEGER_CST) - fprintf (file, -#if HOST_BITS_PER_WIDE_INT == 64 -#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT - " 0x%lx%016lx", -#else - " 0x%x%016x", -#endif -#else -#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT - " 0x%lx%08lx", -#else - " 0x%x%08x", -#endif -#endif - TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t)); - break; - } -} - - -/* If C is not whitespace, return C. - Otherwise skip whitespace and return first nonwhite char read. */ - -static int -skip_white_space (c) - register int c; -{ - static int newline_warning = 0; - - for (;;) - { - switch (c) - { - /* We don't recognize comments here, because - cpp output can include / and * consecutively as operators. - Also, there's no need, since cpp removes all comments. */ - - case '\n': - c = check_newline (); - break; - - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': - c = getc (finput); - break; - - case '\r': - /* ANSI C says the effects of a carriage return in a source file - are undefined. */ - if (pedantic && !newline_warning) - { - warning ("carriage return in source file"); - warning ("(we only warn about the first carriage return)"); - newline_warning = 1; - } - c = getc (finput); - break; - - case '\\': - c = getc (finput); - if (c == '\n') - lineno++; - else - error ("stray '\\' in program"); - c = getc (finput); - break; - - default: - return (c); - } - } -} - -/* Skips all of the white space at the current location in the input file. - Must use and reset nextchar if it has the next character. */ - -void -position_after_white_space () -{ - register int c; - - if (nextchar != -1) - c = nextchar, nextchar = -1; - else - c = getc (finput); - - ungetc (skip_white_space (c), finput); -} - -/* Make the token buffer longer, preserving the data in it. - P should point to just beyond the last valid character in the old buffer. - The value we return is a pointer to the new buffer - at a place corresponding to P. */ - -static char * -extend_token_buffer (p) - char *p; -{ - int offset = p - token_buffer; - - maxtoken = maxtoken * 2 + 10; - token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); - - return token_buffer + offset; -} - -/* At the beginning of a line, increment the line number - and process any #-directive on this line. - If the line is a #-directive, read the entire line and return a newline. - Otherwise, return the line's first non-whitespace character. */ - -int -check_newline () -{ - register int c; - register int token; - - lineno++; - - /* Read first nonwhite char on the line. */ - - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - - if (c != '#') - { - /* If not #, return it so caller will use it. */ - return c; - } - - /* Read first nonwhite char after the `#'. */ - - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - - /* If a letter follows, then if the word here is `line', skip - it and ignore it; otherwise, ignore the line, with an error - if the word isn't `pragma', `ident', `define', or `undef'. */ - - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - if (c == 'p') - { - if (getc (finput) == 'r' - && getc (finput) == 'a' - && getc (finput) == 'g' - && getc (finput) == 'm' - && getc (finput) == 'a' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) - { -#ifdef HANDLE_SYSV_PRAGMA - return handle_sysv_pragma (finput, c); -#else /* !HANDLE_SYSV_PRAGMA */ -#ifdef HANDLE_PRAGMA - HANDLE_PRAGMA (finput); -#endif /* HANDLE_PRAGMA */ - goto skipline; -#endif /* !HANDLE_SYSV_PRAGMA */ - } - } - - else if (c == 'd') - { - if (getc (finput) == 'e' - && getc (finput) == 'f' - && getc (finput) == 'i' - && getc (finput) == 'n' - && getc (finput) == 'e' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) - { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_define (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ - goto skipline; - } - } - else if (c == 'u') - { - if (getc (finput) == 'n' - && getc (finput) == 'd' - && getc (finput) == 'e' - && getc (finput) == 'f' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) - { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_undef (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ - goto skipline; - } - } - else if (c == 'l') - { - if (getc (finput) == 'i' - && getc (finput) == 'n' - && getc (finput) == 'e' - && ((c = getc (finput)) == ' ' || c == '\t')) - goto linenum; - } - else if (c == 'i') - { - if (getc (finput) == 'd' - && getc (finput) == 'e' - && getc (finput) == 'n' - && getc (finput) == 't' - && ((c = getc (finput)) == ' ' || c == '\t')) - { - /* #ident. The pedantic warning is now in cccp.c. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - - while (c == ' ' || c == '\t') - c = getc (finput); - - /* If no argument, ignore the line. */ - if (c == '\n') - return c; - - ungetc (c, finput); - token = yylex (); - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #ident"); - goto skipline; - } - - if (!flag_no_ident) - { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype)); -#endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - } - - error ("undefined or invalid # directive"); - goto skipline; - } - -linenum: - /* Here we have either `#line' or `# <nonletter>'. - In either case, it should be a line number; a digit should follow. */ - - while (c == ' ' || c == '\t') - c = getc (finput); - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (c == '\n') - return c; - - /* Something follows the #; read a token. */ - - ungetc (c, finput); - token = yylex (); - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - int old_lineno = lineno; - int used_up = 0; - /* subtract one, because it is the following line that - gets the specified number */ - - int l = TREE_INT_CST_LOW (yylval.ttype) - 1; - - /* Is this the last nonwhite stuff on the line? */ - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n') - { - /* No more: store the line number and check following line. */ - lineno = l; - return c; - } - ungetc (c, finput); - - /* More follows: it must be a string constant (filename). */ - - /* Read the string constant. */ - token = yylex (); - - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #line"); - goto skipline; - } - - input_filename - = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1); - strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype)); - lineno = l; - - /* Each change of file name - reinitializes whether we are now in a system header. */ - in_system_header = 0; - - if (main_input_filename == 0) - main_input_filename = input_filename; - - /* Is this the last nonwhite stuff on the line? */ - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n') - { - /* Update the name in the top element of input_file_stack. */ - if (input_file_stack) - input_file_stack->name = input_filename; - - return c; - } - ungetc (c, finput); - - token = yylex (); - used_up = 0; - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - if (TREE_INT_CST_LOW (yylval.ttype) == 1) - { - /* Pushing to a new file. */ - struct file_stack *p - = (struct file_stack *) xmalloc (sizeof (struct file_stack)); - input_file_stack->line = old_lineno; - p->next = input_file_stack; - p->name = input_filename; - input_file_stack = p; - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_start_new_source_file (input_filename); -#endif /* DWARF_DEBUGGING_INFO */ - - used_up = 1; - } - else if (TREE_INT_CST_LOW (yylval.ttype) == 2) - { - /* Popping out of a file. */ - if (input_file_stack->next) - { - struct file_stack *p = input_file_stack; - input_file_stack = p->next; - free (p); - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_resume_previous_source_file (input_file_stack->line); -#endif /* DWARF_DEBUGGING_INFO */ - } - else - error ("#-lines for entering and leaving files don't match"); - - used_up = 1; - } - } - - /* Now that we've pushed or popped the input stack, - update the name in the top element. */ - if (input_file_stack) - input_file_stack->name = input_filename; - - /* If we have handled a `1' or a `2', - see if there is another number to read. */ - if (used_up) - { - /* Is this the last nonwhite stuff on the line? */ - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n') - return c; - ungetc (c, finput); - - token = yylex (); - used_up = 0; - } - - /* `3' after file name means this is a system header file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST - && TREE_INT_CST_LOW (yylval.ttype) == 3) - in_system_header = 1; - } - else - error ("invalid #-line"); - - /* skip the rest of this line. */ - skipline: - if (c == '\n') - return c; - while ((c = getc (finput)) != EOF && c != '\n'); - return c; -} - -#ifdef HANDLE_SYSV_PRAGMA - -/* Handle a #pragma directive. INPUT is the current input stream, - and C is a character to reread. Processes the entire input line - and returns a character for the caller to reread: either \n or EOF. */ - -/* This function has to be in this file, in order to get at - the token types. */ - -int -handle_sysv_pragma (input, c) - FILE *input; - int c; -{ - for (;;) - { - while (c == ' ' || c == '\t') - c = getc (input); - if (c == '\n' || c == EOF) - { - handle_pragma_token (0, 0); - return c; - } - ungetc (c, input); - switch (yylex ()) - { - case IDENTIFIER: - case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); - break; - default: - handle_pragma_token (token_buffer, 0); - } - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getc (input); - } -} - -#endif /* HANDLE_SYSV_PRAGMA */ - -#define ENDFILE -1 /* token that represents end-of-file */ - -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ - -static int -readescape (ignore_ptr) - int *ignore_ptr; -{ - register int c = getc (finput); - register int code; - register unsigned count; - unsigned firstdig = 0; - int nonnull; - - switch (c) - { - case 'x': - if (warn_traditional) - warning ("the meaning of `\\x' varies with -traditional"); - - if (flag_traditional) - return c; - - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getc (finput); - if (!(c >= 'a' && c <= 'f') - && !(c >= 'A' && c <= 'F') - && !(c >= '0' && c <= '9')) - { - ungetc (c, finput); - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) - <= firstdig))) - pedwarn ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getc (finput); - } - ungetc (c, finput); - return code; - - case '\\': case '\'': case '"': - return c; - - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - if (warn_traditional) - warning ("the meaning of `\\a' varies with -traditional"); - - if (flag_traditional) - return c; - return TARGET_BELL; - - case 'v': -#if 0 /* Vertical tab is present in common usage compilers. */ - if (flag_traditional) - return c; -#endif - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': - if (pedantic) - pedwarn ("non-ANSI escape sequence `\\%c'", c); - return c; - } - if (c >= 040 && c < 0177) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -void -yyerror (string) - char *string; -{ - char buf[200]; - - strcpy (buf, string); - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - strcat (buf, " at end of input"); - else if (token_buffer[0] == 0) - strcat (buf, " at null character"); - else if (token_buffer[0] == '"') - strcat (buf, " before string constant"); - else if (token_buffer[0] == '\'') - strcat (buf, " before character constant"); - else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177) - sprintf (buf + strlen (buf), " before character 0%o", - (unsigned char) token_buffer[0]); - else - strcat (buf, " before `%s'"); - - error (buf, token_buffer); -} - -#if 0 - -struct try_type -{ - tree *node_var; - char unsigned_flag; - char long_flag; - char long_long_flag; -}; - -struct try_type type_sequence[] = -{ - { &integer_type_node, 0, 0, 0}, - { &unsigned_type_node, 1, 0, 0}, - { &long_integer_type_node, 0, 1, 0}, - { &long_unsigned_type_node, 1, 1, 0}, - { &long_long_integer_type_node, 0, 1, 1}, - { &long_long_unsigned_type_node, 1, 1, 1} -}; -#endif /* 0 */ - -int -yylex () -{ - register int c; - register char *p; - register int value; - int wide_flag = 0; - int objc_flag = 0; - - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getc (finput); - - /* Effectively do c = skip_white_space (c) - but do it faster in the usual cases. */ - while (1) - switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': - c = getc (finput); - break; - - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - - case '\n': - case '/': - case '\\': - c = skip_white_space (c); - default: - goto found_nonwhite; - } - found_nonwhite: - - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ - - switch (c) - { - case EOF: - end_of_file = 1; - token_buffer[0] = 0; - value = ENDFILE; - break; - - case '$': - if (dollars_in_ident) - goto letter; - return '$'; - - case 'L': - /* Capital L may start a wide-string or wide-character constant. */ - { - register int c = getc (finput); - if (c == '\'') - { - wide_flag = 1; - goto char_constant; - } - if (c == '"') - { - wide_flag = 1; - goto string_constant; - } - ungetc (c, finput); - } - goto letter; - - case '@': - if (!doing_objc_thang) - { - value = c; - break; - } - else - { - /* '@' may start a constant string object. */ - register int c = getc(finput); - if (c == '"') - { - objc_flag = 1; - goto string_constant; - } - ungetc(c, finput); - /* Fall through to treat '@' as the start of an indentifier. */ - } - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - case '_': - letter: - p = token_buffer; - while (isalnum (c) || c == '_' || c == '$' || c == '@') - { - /* Make sure this char really belongs in an identifier. */ - if (c == '@' && ! doing_objc_thang) - break; - if (c == '$' && ! dollars_in_ident) - break; - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - c = getc (finput); - } - - *p = 0; - nextchar = c; - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if (ptr = is_reserved_word (token_buffer, p - token_buffer)) - { - if (ptr->rid) - yylval.ttype = ridpointers[(int) ptr->rid]; - value = (int) ptr->token; - - /* Only return OBJECTNAME if it is a typedef. */ - if (doing_objc_thang && value == OBJECTNAME) - { - lastiddecl = lookup_name(yylval.ttype); - - if (lastiddecl == NULL_TREE - || TREE_CODE (lastiddecl) != TYPE_DECL) - value = IDENTIFIER; - } - - /* Even if we decided to recognize asm, still perhaps warn. */ - if (pedantic - && (value == ASM_KEYWORD || value == TYPEOF - || ptr->rid == RID_INLINE) - && token_buffer[0] != '_') - pedwarn ("ANSI does not permit the keyword `%s'", - token_buffer); - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ - - if (value == IDENTIFIER) - { - if (token_buffer[0] == '@') - error("invalid identifier `%s'", token_buffer); - - yylval.ttype = get_identifier (token_buffer); - lastiddecl = lookup_name (yylval.ttype); - - if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL) - value = TYPENAME; - /* A user-invisible read-only initialized variable - should be replaced by its value. - We handle only strings since that's the only case used in C. */ - else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL - && DECL_IGNORED_P (lastiddecl) - && TREE_READONLY (lastiddecl) - && DECL_INITIAL (lastiddecl) != 0 - && TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST) - { - tree stringval = DECL_INITIAL (lastiddecl); - - /* Copy the string value so that we won't clobber anything - if we put something in the TREE_CHAIN of this one. */ - yylval.ttype = build_string (TREE_STRING_LENGTH (stringval), - TREE_STRING_POINTER (stringval)); - value = STRING; - } - else if (doing_objc_thang) - { - tree objc_interface_decl = is_class_name (yylval.ttype); - - if (objc_interface_decl) - { - value = CLASSNAME; - yylval.ttype = objc_interface_decl; - } - } - } - - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '.': - { - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - /* for multi-precision arithmetic, - we actually store only HOST_BITS_PER_CHAR bits in each part. - The number of parts is chosen so as to be sufficient to hold - the enough bits to fit into the two HOST_WIDE_INTs that contain - the integer value (this is always at least as many bits as are - in a target `long long' value, but may be wider). */ -#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2) - int parts[TOTAL_PARTS]; - int overflow = 0; - - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag - = NOT_FLOAT; - - for (count = 0; count < TOTAL_PARTS; count++) - parts[count] = 0; - - p = token_buffer; - *p++ = c; - - if (c == '0') - { - *p++ = (c = getc (finput)); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = getc (finput)); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } - - /* Read all the digits-and-decimal-points. */ - - while (c == '.' - || (isalnum (c) && c != 'l' && c != 'L' - && c != 'u' && c != 'U' - && c != 'i' && c != 'I' && c != 'j' && c != 'J' - && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) - { - if (c == '.') - { - if (base == 16) - error ("floating constant may not be in radix 16"); - if (floatflag == TOO_MANY_POINTS) - /* We have already emitted an error. Don't need another. */ - ; - else if (floatflag == AFTER_POINT) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - /* Avoid another error from atof by forcing all characters - from here on to be ignored. */ - p[-1] = '\0'; - } - else - floatflag = AFTER_POINT; - - base = 10; - *p++ = c = getc (finput); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. - Otherwise, unread the following non-digit - and use the '.' as a structural token. */ - if (p == token_buffer + 2 && !isdigit (c)) - { - if (c == '.') - { - c = getc (finput); - if (c == '.') - { - *p++ = c; - *p = 0; - return ELLIPSIS; - } - error ("parse error at `..'"); - } - ungetc (c, finput); - token_buffer[1] = 0; - value = '.'; - goto done; - } - } - else - { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (isdigit (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_POINT; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (c >= 'a') - { - c = c - 'a' + 10; - } - else - { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; - - for (count = 0; count < TOTAL_PARTS; count++) - { - parts[count] *= base; - if (count) - { - parts[count] - += (parts[count-1] >> HOST_BITS_PER_CHAR); - parts[count-1] - &= (1 << HOST_BITS_PER_CHAR) - 1; - } - else - parts[0] += c; - } - - /* If the extra highest-order part ever gets anything in it, - the number is certainly too big. */ - if (parts[TOTAL_PARTS - 1] != 0) - overflow = 1; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = getc (finput)); - } - } - - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); - - /* Remove terminating char from the token buffer and delimit the string */ - *--p = 0; - - if (floatflag != NOT_FLOAT) - { - tree type = double_type_node; - int garbage_chars = 0, exceeds_double = 0; - int imag = 0; - REAL_VALUE_TYPE value; - jmp_buf handler; - - /* Read explicit exponent if any, and put it in tokenbuf. */ - - if ((c == 'e') || (c == 'E')) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = getc (finput); - } - if (! isdigit (c)) - error ("floating constant exponent has no digits"); - while (isdigit (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - } - } - - *p = 0; - errno = 0; - - /* Convert string to a double, checking for overflow. */ - if (setjmp (handler)) - { - error ("floating constant out of range"); - value = dconst0; - } - else - { - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (p - token_buffer + 1); - bcopy (token_buffer, copy, p - token_buffer + 1); - - set_float_handler (handler); - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - lflag = 1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C forbids imaginary numeric constants"); - imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - *p = 0; - c = getc (finput); - } - - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result - of decimal-to-binary conversion. */ - - if (fflag) - { - if (lflag) - error ("both `f' and `l' in floating constant"); - - type = float_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `float'"); - } - else if (lflag) - { - type = long_double_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `long double'"); - } - else - { - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `double'"); - } - - set_float_handler (NULL_PTR); - } -#ifdef ERANGE - if (errno == ERANGE && !flag_traditional && pedantic) - { - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1))) - { - pedwarn ("floating point number exceeds range of `double'"); - exceeds_double = 1; - } - } -#endif - garbage_chars = 0; - while (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - garbage_chars++; - } - if (garbage_chars > 0) - error ("garbage at end of number"); - - /* If the result is not a number, assume it must have been - due to some error message above, so silently convert - it to a zero. */ - if (REAL_VALUE_ISNAN (value)) - value = dconst0; - - /* Create a node with determined type and value. */ - if (imag) - yylval.ttype = build_complex (convert (type, integer_zero_node), - build_real (type, value)); - else - yylval.ttype = build_real (type, value); - - ungetc (c, finput); - *p = 0; - } - else - { - tree traditional_type, ansi_type, type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - int spec_imag = 0; - int bytes, warn, i; - - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - spec_unsigned = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (pedantic) - pedwarn ("ANSI C forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = 1; - } - else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') - { - if (spec_imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C forbids imaginary numeric constants"); - spec_imag = 1; - } - else - { - if (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - error ("garbage at end of number"); - while (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - } - } - break; - } - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - } - - ungetc (c, finput); - - /* If the constant is not long long and it won't fit in an - unsigned long, or if the constant is long long and won't fit - in an unsigned long long, then warn that the constant is out - of range. */ - - /* ??? This assumes that long long and long integer types are - a multiple of 8 bits. This better than the original code - though which assumed that long was exactly 32 bits and long - long was exactly 64 bits. */ - - if (spec_long_long) - bytes = TYPE_PRECISION (long_long_integer_type_node) / 8; - else - bytes = TYPE_PRECISION (long_integer_type_node) / 8; - - warn = overflow; - for (i = bytes; i < TOTAL_PARTS; i++) - if (parts[i]) - warn = 1; - if (warn) - pedwarn ("integer constant out of range"); - - /* This is simplified by the fact that our constant - is always positive. */ - - high = low = 0; - - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) - { - high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT - / HOST_BITS_PER_CHAR)] - << (i * HOST_BITS_PER_CHAR)); - low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); - } - - yylval.ttype = build_int_2 (low, high); - TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; - - /* If warn_traditional, calculate both the ANSI type and the - traditional type, then see if they disagree. - Otherwise, calculate only the type for the dialect in use. */ - if (warn_traditional || flag_traditional) - { - /* Calculate the traditional type. */ - /* Traditionally, any constant is signed; - but if unsigned is specified explicitly, obey that. - Use the smallest size with the right number of bits, - except for one special case with decimal constants. */ - if (! spec_long && base != 10 - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - traditional_type = (spec_unsigned ? unsigned_type_node - : integer_type_node); - /* A decimal constant must be long - if it does not fit in type int. - I think this is independent of whether - the constant is signed. */ - else if (! spec_long && base == 10 - && int_fits_type_p (yylval.ttype, integer_type_node)) - traditional_type = (spec_unsigned ? unsigned_type_node - : integer_type_node); - else if (! spec_long_long) - traditional_type = (spec_unsigned ? long_unsigned_type_node - : long_integer_type_node); - else - traditional_type = (spec_unsigned - ? long_long_unsigned_type_node - : long_long_integer_type_node); - } - if (warn_traditional || ! flag_traditional) - { - /* Calculate the ANSI type. */ - if (! spec_long && ! spec_unsigned - && int_fits_type_p (yylval.ttype, integer_type_node)) - ansi_type = integer_type_node; - else if (! spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - ansi_type = unsigned_type_node; - else if (! spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - ansi_type = long_integer_type_node; - else if (! spec_long_long) - ansi_type = long_unsigned_type_node; - else if (! spec_unsigned - /* Verify value does not overflow into sign bit. */ - && TREE_INT_CST_HIGH (yylval.ttype) >= 0 - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - ansi_type = long_long_integer_type_node; - else - ansi_type = long_long_unsigned_type_node; - } - - type = flag_traditional ? traditional_type : ansi_type; - - if (warn_traditional && traditional_type != ansi_type) - { - if (TYPE_PRECISION (traditional_type) - != TYPE_PRECISION (ansi_type)) - warning ("width of integer constant changes with -traditional"); - else if (TREE_UNSIGNED (traditional_type) - != TREE_UNSIGNED (ansi_type)) - warning ("integer constant is unsigned in ANSI C, signed with -traditional"); - else - warning ("width of integer constant may change on other systems with -traditional"); - } - - if (!flag_traditional && !int_fits_type_p (yylval.ttype, type) - && !warn) - pedwarn ("integer constant out of range"); - - if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) - warning ("decimal constant is so large that it is unsigned"); - - if (spec_imag) - { - if (TYPE_PRECISION (type) - <= TYPE_PRECISION (integer_type_node)) - yylval.ttype - = build_complex (integer_zero_node, - convert (integer_type_node, yylval.ttype)); - else - error ("complex integer constant is too wide for `complex int'"); - } - else if (flag_traditional && !int_fits_type_p (yylval.ttype, type)) - /* The traditional constant 0x80000000 is signed - but doesn't fit in the range of int. - This will change it to -0x80000000, which does fit. */ - { - TREE_TYPE (yylval.ttype) = unsigned_type (type); - yylval.ttype = convert (type, yylval.ttype); - TREE_OVERFLOW (yylval.ttype) - = TREE_CONSTANT_OVERFLOW (yylval.ttype) = 0; - } - else - TREE_TYPE (yylval.ttype) = type; - - *p = 0; - } - - value = CONSTANT; break; - } - - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; - - if (wide_flag) - { - width = WCHAR_TYPE_SIZE; -#ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; -#endif - } - else - max_chars = TYPE_PRECISION (integer_type_node) / width; - - while (1) - { - tryagain: - - c = getc (finput); - - if (c == '\'' || c == EOF) - break; - - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= (1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (isprint (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C forbids newline in character constant"); - lineno++; - } -#ifdef MAP_CHARACTER - else - c = MAP_CHARACTER (c); -#endif - - num_chars++; - if (num_chars > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[num_chars] = c; - - /* Merge character into result; ignore excess chars. */ - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - } - } - - token_buffer[num_chars + 1] = '\''; - token_buffer[num_chars + 2] = 0; - - if (c != '\'') - error ("malformatted character constant"); - else if (num_chars == 0) - error ("empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - error ("character constant too long"); - } - else if (num_chars != 1 && ! flag_traditional) - warning ("multi-character character constant"); - - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; - if (num_bits == 0) - /* We already got an error; avoid invalid shift. */ - yylval.ttype = build_int_2 (0, 0); - else if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - -1); - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[1] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL_PTR, NULL_PTR, 0); - if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars) - result = wc; - else - warning ("Ignoring invalid multibyte character"); - } -#endif - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } - - case '"': - string_constant: - { - c = getc (finput); - p = token_buffer + 1; - - while (c != '"' && c >= 0) - { - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (!wide_flag - && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT - && c >= (1 << TYPE_PRECISION (char_type_node))) - pedwarn ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C forbids newline in string constant"); - lineno++; - } - - if (p == token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - - skipnewline: - c = getc (finput); - } - *p = 0; - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ - - if (wide_flag) - { - /* If this is a L"..." wide-string, convert the multibyte string - to a wide character string. */ - char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES); - int len; - -#ifdef MULTIBYTE_CHARS - len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer); - if (len < 0 || len >= (p - token_buffer)) - { - warning ("Ignoring invalid multibyte string"); - len = 0; - } - bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES); -#else - { - union { long l; char c[sizeof (long)]; } u; - int big_endian; - char *wp, *cp; - - /* Determine whether host is little or big endian. */ - u.l = 1; - big_endian = u.c[sizeof (long) - 1]; - wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0); - - bzero (widep, (p - token_buffer) * WCHAR_BYTES); - for (cp = token_buffer + 1; cp < p; cp++) - *wp = *cp, wp += WCHAR_BYTES; - len = p - token_buffer - 1; - } -#endif - yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep); - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - value = STRING; - } - else if (objc_flag) - { - extern tree build_objc_string(); - /* Return an Objective-C @"..." constant string object. */ - yylval.ttype = build_objc_string (p - token_buffer, - token_buffer + 1); - TREE_TYPE (yylval.ttype) = char_array_type_node; - value = OBJC_STRING; - } - else - { - yylval.ttype = build_string (p - token_buffer, token_buffer + 1); - TREE_TYPE (yylval.ttype) = char_array_type_node; - value = STRING; - } - - *p++ = '"'; - *p = 0; - - break; - } - - case '+': - case '-': - case '&': - case '|': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; - - combine: - - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } - - token_buffer[1] = c1 = getc (finput); - token_buffer[2] = 0; - - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - } - else if ((c == '-') && (c1 == '>')) - { value = POINTSAT; goto done; } - ungetc (c1, finput); - token_buffer[1] = 0; - - if ((c == '<') || (c == '>')) - value = ARITHCOMPARE; - else value = c; - goto done; - } - - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; - - default: - value = c; - } - -done: -/* yylloc.last_line = lineno; */ - - return value; -} - -/* Sets the value of the 'yydebug' variable to VALUE. - This is a function so we don't have to have YYDEBUG defined - in order to build the compiler. */ - -void -set_yydebug (value) - int value; -{ -#if YYDEBUG != 0 - yydebug = value; -#else - warning ("YYDEBUG not defined."); -#endif -} diff --git a/gnu/usr.bin/cc/cc1/c-parse.c b/gnu/usr.bin/cc/cc1/c-parse.c deleted file mode 100644 index 19b7718..0000000 --- a/gnu/usr.bin/cc/cc1/c-parse.c +++ /dev/null @@ -1,3535 +0,0 @@ - -/* A Bison parser, made from c-parse.y with Bison version GNU Bison version 1.22 - */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define IDENTIFIER 258 -#define TYPENAME 259 -#define SCSPEC 260 -#define TYPESPEC 261 -#define TYPE_QUAL 262 -#define CONSTANT 263 -#define STRING 264 -#define ELLIPSIS 265 -#define SIZEOF 266 -#define ENUM 267 -#define STRUCT 268 -#define UNION 269 -#define IF 270 -#define ELSE 271 -#define WHILE 272 -#define DO 273 -#define FOR 274 -#define SWITCH 275 -#define CASE 276 -#define DEFAULT 277 -#define BREAK 278 -#define CONTINUE 279 -#define RETURN 280 -#define GOTO 281 -#define ASM_KEYWORD 282 -#define TYPEOF 283 -#define ALIGNOF 284 -#define ALIGN 285 -#define ATTRIBUTE 286 -#define EXTENSION 287 -#define LABEL 288 -#define REALPART 289 -#define IMAGPART 290 -#define ASSIGN 291 -#define OROR 292 -#define ANDAND 293 -#define EQCOMPARE 294 -#define ARITHCOMPARE 295 -#define LSHIFT 296 -#define RSHIFT 297 -#define UNARY 298 -#define PLUSPLUS 299 -#define MINUSMINUS 300 -#define HYPERUNARY 301 -#define POINTSAT 302 -#define INTERFACE 303 -#define IMPLEMENTATION 304 -#define END 305 -#define SELECTOR 306 -#define DEFS 307 -#define ENCODE 308 -#define CLASSNAME 309 -#define PUBLIC 310 -#define PRIVATE 311 -#define PROTECTED 312 -#define PROTOCOL 313 -#define OBJECTNAME 314 -#define CLASS 315 -#define ALIAS 316 -#define OBJC_STRING 317 - -#line 45 "c-parse.y" - -#include <stdio.h> -#include <errno.h> -#include <setjmp.h> - -#include "config.h" -#include "tree.h" -#include "input.h" -#include "c-lex.h" -#include "c-tree.h" -#include "flags.h" - -#ifdef MULTIBYTE_CHARS -#include <stdlib.h> -#include <locale.h> -#endif - - -/* Since parsers are distinct for each language, put the language string - definition here. */ -char *language_string = "GNU C"; - -#ifndef errno -extern int errno; -#endif - -void yyerror (); - -/* Like YYERROR but do call yyerror. */ -#define YYERROR1 { yyerror ("syntax error"); YYERROR; } - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#line 82 "c-parse.y" -typedef union {long itype; tree ttype; enum tree_code code; - char *filename; int lineno; } YYSTYPE; -#line 194 "c-parse.y" - -/* Number of statements (loosely speaking) seen so far. */ -static int stmt_count; - -/* Input file and line number of the end of the body of last simple_if; - used by the stmt-rule immediately after simple_if returns. */ -static char *if_stmt_file; -static int if_stmt_line; - -/* List of types and structure classes of the current declaration. */ -static tree current_declspecs; - -/* Stack of saved values of current_declspecs. */ -static tree declspec_stack; - -/* 1 if we explained undeclared var errors. */ -static int undeclared_variable_notice; - - -/* Tell yyparse how to print a token's value, if yydebug is set. */ - -#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint (); - -#ifndef YYLTYPE -typedef - struct yyltype - { - int timestamp; - int first_line; - int first_column; - int last_line; - int last_column; - char *text; - } - yyltype; - -#define YYLTYPE yyltype -#endif - -#include <stdio.h> - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 626 -#define YYFLAG -32768 -#define YYNTBASE 85 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 317 ? yytranslate[x] : 225) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 81, 2, 2, 2, 53, 44, 2, 60, - 77, 51, 49, 82, 50, 59, 52, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 39, 78, 2, - 37, 2, 38, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 61, 2, 84, 43, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 83, 42, 79, 80, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 40, 41, 45, 46, 47, 48, 54, 55, 56, - 57, 58, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 1, 3, 4, 7, 8, 12, 14, 16, 22, - 26, 31, 36, 39, 42, 45, 48, 50, 51, 52, - 60, 65, 66, 67, 75, 80, 81, 82, 89, 93, - 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, - 114, 116, 118, 122, 124, 127, 128, 132, 135, 138, - 141, 146, 149, 154, 157, 160, 162, 167, 168, 176, - 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, - 218, 222, 226, 230, 234, 240, 244, 248, 250, 252, - 254, 258, 262, 263, 268, 273, 278, 282, 286, 289, - 292, 294, 297, 298, 300, 303, 307, 309, 311, 314, - 317, 322, 327, 330, 333, 337, 339, 341, 344, 347, - 348, 353, 358, 362, 366, 369, 372, 375, 379, 380, - 383, 386, 388, 390, 393, 396, 399, 403, 404, 407, - 409, 411, 413, 418, 423, 425, 427, 429, 431, 435, - 437, 441, 442, 447, 448, 455, 459, 460, 467, 471, - 472, 474, 476, 479, 486, 488, 492, 493, 495, 500, - 507, 512, 514, 516, 518, 520, 522, 523, 528, 530, - 531, 534, 536, 540, 542, 543, 548, 550, 551, 560, - 561, 568, 569, 575, 576, 581, 582, 588, 589, 593, - 594, 598, 600, 602, 606, 610, 615, 619, 623, 625, - 629, 634, 638, 642, 644, 648, 652, 656, 661, 665, - 667, 668, 675, 680, 683, 684, 691, 696, 699, 700, - 708, 709, 716, 719, 720, 722, 723, 725, 727, 730, - 731, 735, 738, 742, 744, 748, 750, 752, 754, 758, - 763, 770, 776, 778, 782, 784, 786, 790, 793, 796, - 797, 799, 801, 804, 805, 808, 812, 816, 819, 823, - 828, 832, 835, 839, 842, 844, 847, 850, 851, 853, - 856, 857, 858, 860, 862, 865, 869, 871, 874, 877, - 884, 890, 896, 899, 902, 907, 908, 913, 914, 915, - 919, 924, 928, 930, 932, 934, 936, 939, 940, 945, - 947, 951, 952, 953, 961, 967, 970, 971, 972, 973, - 986, 987, 994, 997, 1000, 1003, 1007, 1014, 1023, 1034, - 1047, 1051, 1056, 1058, 1060, 1061, 1068, 1072, 1078, 1081, - 1084, 1085, 1087, 1088, 1090, 1091, 1093, 1095, 1099, 1104, - 1106, 1110, 1111, 1114, 1117, 1118, 1123, 1126, 1127, 1129, - 1131, 1135, 1137, 1141, 1144, 1147, 1150, 1153, 1156, 1157, - 1160, 1162, 1165, 1167, 1171, 1173 -}; - -static const short yyrhs[] = { -1, - 86, 0, 0, 87, 89, 0, 0, 86, 88, 89, - 0, 91, 0, 90, 0, 27, 60, 100, 77, 78, - 0, 117, 127, 78, 0, 121, 117, 127, 78, 0, - 119, 117, 126, 78, 0, 121, 78, 0, 119, 78, - 0, 1, 78, 0, 1, 79, 0, 78, 0, 0, - 0, 119, 117, 154, 92, 111, 93, 184, 0, 119, - 117, 154, 1, 0, 0, 0, 121, 117, 157, 94, - 111, 95, 184, 0, 121, 117, 157, 1, 0, 0, - 0, 117, 157, 96, 111, 97, 184, 0, 117, 157, - 1, 0, 3, 0, 4, 0, 44, 0, 50, 0, - 49, 0, 55, 0, 56, 0, 80, 0, 81, 0, - 102, 0, 0, 102, 0, 107, 0, 102, 82, 107, - 0, 108, 0, 51, 105, 0, 0, 32, 104, 105, - 0, 99, 105, 0, 41, 98, 0, 11, 103, 0, - 11, 60, 172, 77, 0, 29, 103, 0, 29, 60, - 172, 77, 0, 34, 105, 0, 35, 105, 0, 103, - 0, 60, 172, 77, 105, 0, 0, 60, 172, 77, - 83, 106, 141, 79, 0, 105, 0, 107, 49, 107, - 0, 107, 50, 107, 0, 107, 51, 107, 0, 107, - 52, 107, 0, 107, 53, 107, 0, 107, 47, 107, - 0, 107, 48, 107, 0, 107, 46, 107, 0, 107, - 45, 107, 0, 107, 44, 107, 0, 107, 42, 107, - 0, 107, 43, 107, 0, 107, 41, 107, 0, 107, - 40, 107, 0, 107, 38, 208, 39, 107, 0, 107, - 37, 107, 0, 107, 36, 107, 0, 3, 0, 8, - 0, 110, 0, 60, 100, 77, 0, 60, 1, 77, - 0, 0, 60, 109, 185, 77, 0, 108, 60, 101, - 77, 0, 108, 61, 100, 84, 0, 108, 59, 98, - 0, 108, 58, 98, 0, 108, 55, 0, 108, 56, - 0, 9, 0, 110, 9, 0, 0, 113, 0, 113, - 10, 0, 190, 191, 114, 0, 112, 0, 179, 0, - 113, 112, 0, 112, 179, 0, 119, 117, 126, 78, - 0, 121, 117, 127, 78, 0, 119, 78, 0, 121, - 78, 0, 190, 191, 118, 0, 115, 0, 179, 0, - 116, 115, 0, 115, 179, 0, 0, 119, 117, 126, - 78, 0, 121, 117, 127, 78, 0, 119, 117, 150, - 0, 121, 117, 152, 0, 119, 78, 0, 121, 78, - 0, 124, 120, 0, 121, 124, 120, 0, 0, 120, - 125, 0, 120, 5, 0, 7, 0, 5, 0, 121, - 7, 0, 121, 5, 0, 124, 123, 0, 174, 124, - 123, 0, 0, 123, 125, 0, 6, 0, 158, 0, - 4, 0, 28, 60, 100, 77, 0, 28, 60, 172, - 77, 0, 6, 0, 7, 0, 158, 0, 129, 0, - 126, 82, 129, 0, 131, 0, 127, 82, 129, 0, - 0, 27, 60, 110, 77, 0, 0, 154, 128, 133, - 37, 130, 139, 0, 154, 128, 133, 0, 0, 157, - 128, 133, 37, 132, 139, 0, 157, 128, 133, 0, - 0, 134, 0, 135, 0, 134, 135, 0, 31, 60, - 60, 136, 77, 77, 0, 137, 0, 136, 82, 137, - 0, 0, 138, 0, 138, 60, 3, 77, 0, 138, - 60, 3, 82, 102, 77, 0, 138, 60, 102, 77, - 0, 98, 0, 5, 0, 6, 0, 7, 0, 107, - 0, 0, 83, 140, 141, 79, 0, 1, 0, 0, - 142, 163, 0, 143, 0, 142, 82, 143, 0, 107, - 0, 0, 83, 144, 141, 79, 0, 1, 0, 0, - 61, 107, 10, 107, 84, 37, 145, 143, 0, 0, - 61, 107, 84, 37, 146, 143, 0, 0, 61, 107, - 84, 147, 143, 0, 0, 98, 39, 148, 143, 0, - 0, 59, 98, 37, 149, 143, 0, 0, 154, 151, - 185, 0, 0, 157, 153, 185, 0, 155, 0, 157, - 0, 60, 155, 77, 0, 155, 60, 220, 0, 155, - 61, 100, 84, 0, 155, 61, 84, 0, 51, 175, - 155, 0, 4, 0, 156, 60, 220, 0, 156, 61, - 100, 84, 0, 156, 61, 84, 0, 51, 175, 156, - 0, 4, 0, 157, 60, 220, 0, 60, 157, 77, - 0, 51, 175, 157, 0, 157, 61, 100, 84, 0, - 157, 61, 84, 0, 3, 0, 0, 13, 98, 83, - 159, 165, 79, 0, 13, 83, 165, 79, 0, 13, - 98, 0, 0, 14, 98, 83, 160, 165, 79, 0, - 14, 83, 165, 79, 0, 14, 98, 0, 0, 12, - 98, 83, 161, 170, 164, 79, 0, 0, 12, 83, - 162, 170, 164, 79, 0, 12, 98, 0, 0, 82, - 0, 0, 82, 0, 166, 0, 166, 167, 0, 0, - 166, 167, 78, 0, 166, 78, 0, 122, 117, 168, - 0, 122, 0, 174, 117, 168, 0, 174, 0, 1, - 0, 169, 0, 168, 82, 169, 0, 190, 191, 154, - 133, 0, 190, 191, 154, 39, 107, 133, 0, 190, - 191, 39, 107, 133, 0, 171, 0, 170, 82, 171, - 0, 1, 0, 98, 0, 98, 37, 107, 0, 122, - 173, 0, 174, 173, 0, 0, 176, 0, 7, 0, - 174, 7, 0, 0, 175, 7, 0, 60, 176, 77, - 0, 51, 175, 176, 0, 51, 175, 0, 176, 60, - 213, 0, 176, 61, 100, 84, 0, 176, 61, 84, - 0, 60, 213, 0, 61, 100, 84, 0, 61, 84, - 0, 193, 0, 177, 193, 0, 177, 179, 0, 0, - 177, 0, 1, 78, 0, 0, 0, 182, 0, 183, - 0, 182, 183, 0, 33, 224, 78, 0, 185, 0, - 1, 185, 0, 83, 79, 0, 83, 180, 181, 116, - 178, 79, 0, 83, 180, 181, 1, 79, 0, 83, - 180, 181, 177, 79, 0, 187, 192, 0, 187, 1, - 0, 15, 60, 100, 77, 0, 0, 18, 189, 192, - 17, 0, 0, 0, 190, 191, 195, 0, 190, 191, - 206, 192, 0, 190, 191, 194, 0, 195, 0, 206, - 0, 185, 0, 203, 0, 100, 78, 0, 0, 186, - 16, 196, 192, 0, 186, 0, 186, 16, 1, 0, - 0, 0, 17, 197, 60, 100, 77, 198, 192, 0, - 188, 60, 100, 77, 78, 0, 188, 1, 0, 0, - 0, 0, 19, 60, 208, 78, 199, 208, 78, 200, - 208, 77, 201, 192, 0, 0, 20, 60, 100, 77, - 202, 192, 0, 23, 78, 0, 24, 78, 0, 25, - 78, 0, 25, 100, 78, 0, 27, 207, 60, 100, - 77, 78, 0, 27, 207, 60, 100, 39, 209, 77, - 78, 0, 27, 207, 60, 100, 39, 209, 39, 209, - 77, 78, 0, 27, 207, 60, 100, 39, 209, 39, - 209, 39, 212, 77, 78, 0, 26, 98, 78, 0, - 26, 51, 100, 78, 0, 78, 0, 204, 0, 0, - 19, 60, 108, 77, 205, 192, 0, 21, 107, 39, - 0, 21, 107, 10, 107, 39, 0, 22, 39, 0, - 98, 39, 0, 0, 7, 0, 0, 100, 0, 0, - 210, 0, 211, 0, 210, 82, 211, 0, 9, 60, - 100, 77, 0, 110, 0, 212, 82, 110, 0, 0, - 214, 215, 0, 217, 77, 0, 0, 218, 78, 216, - 215, 0, 1, 77, 0, 0, 10, 0, 218, 0, - 218, 82, 10, 0, 219, 0, 218, 82, 219, 0, - 119, 156, 0, 119, 157, 0, 119, 173, 0, 121, - 157, 0, 121, 173, 0, 0, 221, 222, 0, 215, - 0, 223, 77, 0, 3, 0, 223, 82, 3, 0, - 98, 0, 224, 82, 98, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 220, 224, 237, 239, 239, 240, 242, 244, 245, 255, - 261, 263, 265, 267, 269, 270, 271, 276, 282, 284, - 285, 287, 292, 294, 295, 297, 302, 304, 305, 309, - 311, 314, 316, 318, 320, 322, 324, 326, 330, 334, - 337, 340, 343, 347, 349, 352, 355, 358, 362, 388, - 393, 395, 397, 399, 401, 405, 407, 410, 414, 441, - 443, 445, 447, 449, 451, 453, 455, 457, 459, 461, - 463, 465, 467, 469, 471, 473, 476, 482, 581, 582, - 584, 590, 592, 606, 629, 631, 633, 637, 643, 645, - 650, 652, 657, 659, 660, 670, 675, 677, 678, 679, - 682, 687, 691, 694, 702, 707, 709, 710, 711, 718, - 726, 731, 735, 739, 743, 745, 753, 756, 760, 762, - 764, 775, 779, 781, 784, 797, 800, 804, 806, 814, - 815, 816, 820, 822, 828, 829, 830, 833, 835, 838, - 840, 843, 846, 852, 859, 862, 868, 875, 878, 885, - 888, 892, 895, 899, 904, 907, 911, 914, 916, 919, - 922, 929, 931, 932, 933, 938, 940, 945, 953, 958, - 962, 965, 967, 972, 975, 977, 979, 983, 986, 986, - 989, 989, 992, 992, 995, 995, 998, 1000, 1017, 1021, - 1038, 1045, 1047, 1052, 1055, 1060, 1062, 1064, 1066, 1074, - 1080, 1082, 1084, 1086, 1092, 1098, 1100, 1102, 1104, 1106, - 1109, 1114, 1118, 1121, 1123, 1125, 1127, 1130, 1132, 1135, - 1138, 1141, 1144, 1148, 1150, 1153, 1155, 1159, 1162, 1167, - 1169, 1171, 1185, 1191, 1196, 1201, 1206, 1210, 1212, 1216, - 1220, 1224, 1234, 1236, 1238, 1243, 1246, 1250, 1253, 1257, - 1260, 1263, 1266, 1270, 1273, 1277, 1281, 1283, 1285, 1287, - 1289, 1291, 1293, 1295, 1303, 1305, 1306, 1309, 1311, 1314, - 1317, 1328, 1330, 1335, 1337, 1340, 1354, 1357, 1360, 1362, - 1370, 1378, 1389, 1394, 1397, 1410, 1418, 1422, 1426, 1430, - 1436, 1440, 1445, 1447, 1458, 1461, 1462, 1479, 1484, 1487, - 1499, 1501, 1511, 1521, 1522, 1530, 1533, 1545, 1549, 1566, - 1576, 1585, 1590, 1595, 1600, 1604, 1608, 1619, 1626, 1633, - 1640, 1651, 1655, 1658, 1663, 1686, 1720, 1745, 1774, 1789, - 1800, 1804, 1808, 1811, 1816, 1818, 1821, 1823, 1827, 1832, - 1835, 1841, 1846, 1851, 1853, 1862, 1863, 1869, 1871, 1881, - 1883, 1887, 1890, 1896, 1899, 1901, 1903, 1905, 1912, 1917, - 1922, 1924, 1933, 1936, 1941, 1944 -}; - -static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", -"TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", -"ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", -"BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ALIGN", -"ATTRIBUTE","EXTENSION","LABEL","REALPART","IMAGPART","ASSIGN","'='","'?'","':'", -"OROR","ANDAND","'|'","'^'","'&'","EQCOMPARE","ARITHCOMPARE","LSHIFT","RSHIFT", -"'+'","'-'","'*'","'/'","'%'","UNARY","PLUSPLUS","MINUSMINUS","HYPERUNARY","POINTSAT", -"'.'","'('","'['","INTERFACE","IMPLEMENTATION","END","SELECTOR","DEFS","ENCODE", -"CLASSNAME","PUBLIC","PRIVATE","PROTECTED","PROTOCOL","OBJECTNAME","CLASS","ALIAS", -"OBJC_STRING","')'","';'","'}'","'~'","'!'","','","'{'","']'","program","extdefs", -"@1","@2","extdef","datadef","fndef","@3","@4","@5","@6","@7","@8","identifier", -"unop","expr","exprlist","nonnull_exprlist","unary_expr","@9","cast_expr","@10", -"expr_no_commas","primary","@11","string","xdecls","lineno_datadecl","datadecls", -"datadecl","lineno_decl","decls","setspecs","decl","typed_declspecs","reserved_declspecs", -"declmods","typed_typespecs","reserved_typespecquals","typespec","typespecqual_reserved", -"initdecls","notype_initdecls","maybeasm","initdcl","@12","notype_initdcl","@13", -"maybe_attribute","attributes","attribute","attribute_list","attrib","any_word", -"init","@14","initlist_maybe_comma","initlist1","initelt","@15","@16","@17", -"@18","@19","@20","nested_function","@21","notype_nested_function","@22","declarator", -"after_type_declarator","parm_declarator","notype_declarator","structsp","@23", -"@24","@25","@26","maybecomma","maybecomma_warn","component_decl_list","component_decl_list2", -"component_decl","components","component_declarator","enumlist","enumerator", -"typename","absdcl","nonempty_type_quals","type_quals","absdcl1","stmts","xstmts", -"errstmt","pushlevel","maybe_label_decls","label_decls","label_decl","compstmt_or_error", -"compstmt","simple_if","if_prefix","do_stmt_start","@27","save_filename","save_lineno", -"lineno_labeled_stmt","lineno_stmt_or_label","stmt_or_label","stmt","@28","@29", -"@30","@31","@32","@33","@34","all_iter_stmt","all_iter_stmt_simple","@35","label", -"maybe_type_qual","xexpr","asm_operands","nonnull_asm_operands","asm_operand", -"asm_clobbers","parmlist","@36","parmlist_1","@37","parmlist_2","parms","parm", -"parmlist_or_identifiers","@38","parmlist_or_identifiers_1","identifiers","identifiers_or_typenames", -"" -}; -#endif - -static const short yyr1[] = { 0, - 85, 85, 87, 86, 88, 86, 89, 89, 89, 90, - 90, 90, 90, 90, 90, 90, 90, 92, 93, 91, - 91, 94, 95, 91, 91, 96, 97, 91, 91, 98, - 98, 99, 99, 99, 99, 99, 99, 99, 100, 101, - 101, 102, 102, 103, 103, 104, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 105, 105, 106, 105, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 108, 108, 108, - 108, 108, 109, 108, 108, 108, 108, 108, 108, 108, - 110, 110, 111, 111, 111, 112, 113, 113, 113, 113, - 114, 114, 114, 114, 115, 116, 116, 116, 116, 117, - 118, 118, 118, 118, 118, 118, 119, 119, 120, 120, - 120, 121, 121, 121, 121, 122, 122, 123, 123, 124, - 124, 124, 124, 124, 125, 125, 125, 126, 126, 127, - 127, 128, 128, 130, 129, 129, 132, 131, 131, 133, - 133, 134, 134, 135, 136, 136, 137, 137, 137, 137, - 137, 138, 138, 138, 138, 139, 140, 139, 139, 141, - 141, 142, 142, 143, 144, 143, 143, 145, 143, 146, - 143, 147, 143, 148, 143, 149, 143, 151, 150, 153, - 152, 154, 154, 155, 155, 155, 155, 155, 155, 156, - 156, 156, 156, 156, 157, 157, 157, 157, 157, 157, - 159, 158, 158, 158, 160, 158, 158, 158, 161, 158, - 162, 158, 158, 163, 163, 164, 164, 165, 165, 166, - 166, 166, 167, 167, 167, 167, 167, 168, 168, 169, - 169, 169, 170, 170, 170, 171, 171, 172, 172, 173, - 173, 174, 174, 175, 175, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 177, 177, 177, 178, 178, 179, - 180, 181, 181, 182, 182, 183, 184, 184, 185, 185, - 185, 185, 186, 186, 187, 189, 188, 190, 191, 192, - 192, 193, 194, 194, 195, 195, 195, 196, 195, 195, - 195, 197, 198, 195, 195, 195, 199, 200, 201, 195, - 202, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 203, 205, 204, 206, 206, 206, 206, - 207, 207, 208, 208, 209, 209, 210, 210, 211, 212, - 212, 214, 213, 215, 216, 215, 215, 217, 217, 217, - 217, 218, 218, 219, 219, 219, 219, 219, 221, 220, - 222, 222, 223, 223, 224, 224 -}; - -static const short yyr2[] = { 0, - 0, 1, 0, 2, 0, 3, 1, 1, 5, 3, - 4, 4, 2, 2, 2, 2, 1, 0, 0, 7, - 4, 0, 0, 7, 4, 0, 0, 6, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 3, 1, 2, 0, 3, 2, 2, 2, - 4, 2, 4, 2, 2, 1, 4, 0, 7, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 5, 3, 3, 1, 1, 1, - 3, 3, 0, 4, 4, 4, 3, 3, 2, 2, - 1, 2, 0, 1, 2, 3, 1, 1, 2, 2, - 4, 4, 2, 2, 3, 1, 1, 2, 2, 0, - 4, 4, 3, 3, 2, 2, 2, 3, 0, 2, - 2, 1, 1, 2, 2, 2, 3, 0, 2, 1, - 1, 1, 4, 4, 1, 1, 1, 1, 3, 1, - 3, 0, 4, 0, 6, 3, 0, 6, 3, 0, - 1, 1, 2, 6, 1, 3, 0, 1, 4, 6, - 4, 1, 1, 1, 1, 1, 0, 4, 1, 0, - 2, 1, 3, 1, 0, 4, 1, 0, 8, 0, - 6, 0, 5, 0, 4, 0, 5, 0, 3, 0, - 3, 1, 1, 3, 3, 4, 3, 3, 1, 3, - 4, 3, 3, 1, 3, 3, 3, 4, 3, 1, - 0, 6, 4, 2, 0, 6, 4, 2, 0, 7, - 0, 6, 2, 0, 1, 0, 1, 1, 2, 0, - 3, 2, 3, 1, 3, 1, 1, 1, 3, 4, - 6, 5, 1, 3, 1, 1, 3, 2, 2, 0, - 1, 1, 2, 0, 2, 3, 3, 2, 3, 4, - 3, 2, 3, 2, 1, 2, 2, 0, 1, 2, - 0, 0, 1, 1, 2, 3, 1, 2, 2, 6, - 5, 5, 2, 2, 4, 0, 4, 0, 0, 3, - 4, 3, 1, 1, 1, 1, 2, 0, 4, 1, - 3, 0, 0, 7, 5, 2, 0, 0, 0, 12, - 0, 6, 2, 2, 2, 3, 6, 8, 10, 12, - 3, 4, 1, 1, 0, 6, 3, 5, 2, 2, - 0, 1, 0, 1, 0, 1, 1, 3, 4, 1, - 3, 0, 2, 2, 0, 4, 2, 0, 1, 1, - 3, 1, 3, 2, 2, 2, 2, 2, 0, 2, - 1, 2, 1, 3, 1, 3 -}; - -static const short yydefact[] = { 3, - 5, 0, 0, 0, 132, 123, 130, 122, 0, 0, - 0, 0, 0, 17, 4, 8, 7, 0, 110, 110, - 119, 131, 6, 15, 16, 30, 31, 221, 223, 230, - 214, 230, 218, 0, 0, 210, 254, 0, 0, 140, - 0, 14, 0, 125, 124, 13, 0, 119, 117, 0, - 219, 0, 0, 211, 0, 215, 78, 79, 91, 0, - 0, 46, 0, 0, 0, 32, 34, 33, 0, 35, - 36, 0, 37, 38, 0, 0, 39, 56, 60, 42, - 44, 80, 252, 0, 250, 128, 0, 250, 0, 0, - 10, 0, 29, 0, 359, 0, 0, 150, 199, 254, - 0, 0, 138, 0, 192, 193, 0, 0, 118, 121, - 135, 136, 120, 137, 245, 246, 226, 243, 0, 213, - 237, 232, 110, 229, 110, 230, 217, 230, 0, 50, - 0, 52, 0, 54, 55, 49, 45, 0, 0, 0, - 0, 48, 0, 0, 0, 0, 333, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 89, 90, 0, 0, 40, 0, 92, 133, 254, - 342, 0, 248, 251, 126, 134, 253, 128, 249, 255, - 207, 206, 141, 142, 0, 205, 0, 209, 0, 0, - 27, 0, 288, 98, 289, 0, 149, 151, 152, 0, - 0, 12, 0, 21, 0, 150, 359, 0, 11, 25, - 0, 0, 227, 0, 226, 288, 231, 288, 0, 0, - 0, 0, 47, 82, 81, 271, 0, 0, 9, 43, - 77, 76, 334, 0, 74, 73, 71, 72, 70, 69, - 68, 66, 67, 61, 62, 63, 64, 65, 88, 87, - 0, 41, 0, 258, 0, 262, 0, 264, 0, 342, - 0, 129, 127, 0, 0, 363, 349, 250, 250, 361, - 0, 350, 352, 360, 0, 208, 270, 0, 100, 95, - 99, 0, 0, 147, 153, 198, 194, 139, 19, 146, - 195, 197, 0, 23, 247, 244, 222, 0, 233, 238, - 289, 235, 212, 216, 51, 53, 279, 272, 84, 58, - 57, 0, 85, 86, 257, 256, 343, 263, 259, 261, - 0, 143, 347, 204, 254, 342, 354, 355, 356, 254, - 357, 358, 344, 345, 0, 362, 0, 0, 28, 277, - 96, 110, 110, 157, 0, 0, 144, 196, 0, 220, - 288, 0, 0, 0, 273, 274, 0, 75, 260, 258, - 359, 0, 258, 0, 351, 353, 364, 278, 103, 0, - 104, 0, 163, 164, 165, 162, 0, 155, 158, 169, - 167, 166, 148, 20, 0, 24, 239, 0, 150, 365, - 0, 0, 0, 288, 0, 107, 289, 265, 275, 177, - 78, 0, 0, 175, 0, 174, 0, 224, 172, 203, - 200, 202, 0, 346, 0, 0, 142, 0, 157, 0, - 0, 145, 150, 0, 240, 276, 0, 281, 109, 108, - 0, 0, 282, 267, 289, 266, 0, 0, 0, 0, - 184, 59, 0, 171, 201, 101, 102, 154, 156, 78, - 0, 0, 242, 150, 366, 280, 0, 132, 0, 302, - 286, 0, 0, 0, 0, 0, 0, 0, 0, 331, - 323, 0, 0, 105, 110, 110, 295, 300, 0, 0, - 292, 293, 296, 324, 294, 186, 0, 182, 0, 0, - 173, 159, 0, 161, 168, 241, 0, 0, 288, 333, - 0, 0, 329, 313, 314, 315, 0, 0, 0, 332, - 0, 330, 297, 115, 0, 116, 0, 0, 284, 289, - 283, 306, 0, 0, 0, 180, 0, 176, 185, 0, - 0, 0, 0, 44, 0, 0, 0, 327, 316, 0, - 321, 0, 0, 113, 142, 0, 114, 142, 301, 288, - 0, 0, 187, 0, 0, 183, 160, 285, 0, 287, - 325, 307, 311, 0, 322, 0, 111, 0, 112, 0, - 299, 290, 288, 0, 178, 181, 303, 288, 333, 288, - 328, 335, 0, 189, 191, 291, 305, 0, 288, 326, - 0, 312, 0, 0, 336, 337, 317, 179, 304, 308, - 0, 335, 0, 0, 333, 0, 0, 318, 338, 0, - 339, 0, 0, 309, 340, 0, 319, 288, 0, 0, - 310, 320, 341, 0, 0, 0 -}; - -static const short yydefgoto[] = { 624, - 1, 2, 3, 15, 16, 17, 205, 346, 211, 349, - 97, 278, 405, 75, 233, 251, 77, 78, 133, 79, - 357, 80, 81, 140, 82, 191, 192, 193, 341, 393, - 394, 18, 474, 268, 49, 269, 85, 175, 21, 113, - 102, 39, 98, 103, 385, 40, 345, 197, 198, 199, - 377, 378, 379, 383, 421, 407, 408, 409, 440, 588, - 555, 527, 490, 524, 544, 568, 547, 570, 184, 105, - 327, 106, 22, 126, 128, 119, 50, 444, 214, 52, - 53, 124, 299, 300, 117, 118, 87, 173, 88, 89, - 174, 395, 432, 194, 308, 354, 355, 356, 339, 340, - 478, 479, 480, 499, 520, 282, 521, 398, 481, 482, - 550, 498, 589, 579, 605, 618, 580, 483, 484, 578, - 485, 511, 234, 594, 595, 596, 616, 256, 257, 270, - 364, 271, 272, 273, 186, 187, 274, 275, 391 -}; - -static const short yypact[] = { 61, - 79, 401, 401, 192,-32768,-32768,-32768,-32768, 56, 63, - 67, 3, 36,-32768,-32768,-32768,-32768, 96, 20, 488, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 40,-32768, - 66,-32768, 76, 1775, 1691,-32768,-32768, 96, 156,-32768, - 762,-32768, 69,-32768,-32768,-32768, 96,-32768, 404, 393, --32768, 109, 293,-32768, 111,-32768,-32768,-32768,-32768, 1788, - 1838,-32768, 1775, 1775, 330,-32768,-32768,-32768, 1775,-32768, --32768, 528,-32768,-32768, 1775, 98, 118,-32768,-32768, 1983, - 451, 193,-32768, 134, 172,-32768, 141, 1050, 258, 4, --32768, 69,-32768, 165,-32768, 1317, 236, 204,-32768,-32768, - 69, 191,-32768, 362, 331, 361, 232, 924, 404,-32768, --32768,-32768,-32768,-32768,-32768, 210, 162,-32768, 393,-32768, --32768,-32768, 360, 182, 1005,-32768,-32768,-32768, 528,-32768, - 528,-32768, 1775,-32768,-32768,-32768,-32768, 180, 200, 219, - 216,-32768, 233, 1775, 1775, 1775, 1775, 1775, 1775, 1775, - 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, - 1775,-32768,-32768, 330, 330, 1775, 1775,-32768,-32768,-32768, - 172, 1330,-32768, 388, 419,-32768,-32768,-32768,-32768,-32768, - 361,-32768,-32768, 314, 311,-32768, 586,-32768, 264, 292, --32768, 179, 44,-32768,-32768, 322, 363, 204,-32768, 194, - 33,-32768, 69,-32768, 236, 204,-32768, 1384,-32768,-32768, - 236, 1775, 330, 319, 162,-32768,-32768,-32768, 340, 345, - 350, 359,-32768,-32768,-32768, 367, 364, 1633,-32768, 1983, - 1983, 1983,-32768, 416, 2012, 2024, 1877, 475, 2033, 1423, - 433, 496, 496, 406, 406,-32768,-32768,-32768,-32768,-32768, - 383, 118, 380, 265, 235,-32768, 846,-32768, 386,-32768, - 1397,-32768, 419, 31, 399,-32768,-32768, 148, 684,-32768, - 411, 249,-32768,-32768, 83,-32768,-32768, 48,-32768,-32768, --32768, 1484, 436,-32768,-32768, 331,-32768,-32768,-32768, 460, --32768,-32768, 415,-32768, 1983,-32768,-32768, 424, 423,-32768, --32768, 423,-32768,-32768,-32768,-32768,-32768, 480,-32768,-32768, --32768, 1775,-32768,-32768, 388,-32768,-32768,-32768,-32768,-32768, - 446,-32768,-32768,-32768,-32768, 161, 405, 361,-32768,-32768, - 361,-32768,-32768,-32768, 373,-32768, 511, 219,-32768,-32768, --32768, 465, 1278, 598, 1267, 48,-32768,-32768, 48,-32768, --32768, 53, 330, 702, 480,-32768, 1084, 1999,-32768, 102, --32768, 1451, 207, 846,-32768,-32768,-32768,-32768,-32768, 69, --32768, 96,-32768,-32768,-32768,-32768, 149,-32768, 478,-32768, --32768, 1983,-32768,-32768, 1267,-32768,-32768, 1775, 138,-32768, - 271, 390, 621, 471, 783,-32768,-32768,-32768,-32768,-32768, - 513, 330, 1775,-32768, 514, 1983, 476, 477,-32768, 405, --32768,-32768, 474,-32768, 280, 282, 26, 484, 598, 1851, - 1084,-32768, 1943, 1775,-32768,-32768, 330,-32768,-32768,-32768, - 864, 485,-32768,-32768,-32768,-32768, 1533, 531, 1898, 1084, --32768,-32768, 1145,-32768,-32768,-32768,-32768,-32768,-32768, 226, - 240, 486,-32768, 1943,-32768,-32768, 1583, 532, 515,-32768, --32768, 516, 520, 1775, 535, 503, 504, 1725, 168, 578, --32768, 547, 517,-32768, 519, 1643,-32768, 590, 945, 51, --32768,-32768,-32768,-32768,-32768,-32768, 1775, 570, 533, 1206, --32768,-32768, 1775,-32768,-32768,-32768, 1775, 550,-32768, 1775, - 1775, 1477,-32768,-32768,-32768,-32768, 537, 1775, 538,-32768, - 553,-32768,-32768,-32768, 69,-32768, 96, 1026,-32768,-32768, --32768,-32768, 1775, 1206, 1916,-32768, 1206,-32768,-32768, 247, - 541, 1775, 602, 296, 543, 546, 1775,-32768,-32768, 559, --32768, 1775, 283,-32768, 41, 306,-32768, 169,-32768,-32768, - 1583, 554,-32768, 614, 1206,-32768,-32768,-32768, 575,-32768, --32768,-32768,-32768, 1965,-32768, 38,-32768, 219,-32768, 219, --32768,-32768,-32768, 580,-32768,-32768,-32768,-32768, 1775,-32768, --32768, 650, 582,-32768,-32768,-32768,-32768, 1206,-32768,-32768, - 583,-32768, 604, 128, 584,-32768,-32768,-32768,-32768,-32768, - 1775, 650, 591, 650, 1775, 596, 143,-32768,-32768, 597, --32768, 311, 600,-32768, 193, 253,-32768,-32768, 601, 311, --32768,-32768, 193, 668, 675,-32768 -}; - -static const short yypgoto[] = {-32768, --32768,-32768,-32768, 677,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768, -7,-32768, -34,-32768, -157, 430,-32768, -33, --32768, 130, 183,-32768, -177, -122, 489,-32768,-32768, 290, --32768, -4,-32768, 10, 638, 16, 639, 555, -3, -129, - -342, -40, -94, -63,-32768,-32768,-32768, -195,-32768, 495, --32768, 275,-32768, 310,-32768, -366,-32768, -410,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -37, -64, - 372, -13, -27,-32768,-32768,-32768,-32768,-32768, 523, 9, --32768,-32768, 521, 389, 622, 529, -28, -65, 694, -79, - -147, 354,-32768, -178,-32768,-32768,-32768, 394, -271, -114, --32768,-32768,-32768,-32768, -50, -281, -448, -347,-32768, 199, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 203,-32768, -461, 153,-32768, 152,-32768, 499,-32768, -222, --32768,-32768,-32768, 425, -180,-32768,-32768,-32768,-32768 -}; - - -#define YYLAST 2086 - - -static const short yytable[] = { 76, - 84, 29, 31, 33, 41, 104, 107, 264, 252, 206, - 290, 19, 19, 279, 43, 47, 48, 20, 20, 352, - 200, 114, 179, 255, 90, 227, 291, 415, 183, 134, - 135, 86, 491, 108, 317, 137, 201, 139, 535, 168, - 55, 142, 116, 141, -94, 262, 195, 436, 338, 86, - 533, 522, 94, 280, 452, 36, 99, 136, 26, 27, - -1, 189, 34, 95, 96, 26, 27, 94, 86, 26, - 27, 36, 99, 489, 384, 181, 582, 386, -2, 529, - 182, 114, 289, 436, 178, 95, 96, 90, 294, 206, - 254, 388, 207, 208, 139, 35, 139, 42, 36, 223, - 221, 571, 222, 100, 36, 324, 315, 322, 180, 287, - 523, 116, 101, 553, 583, 437, 556, 591, 216, 100, - 218, 178, 51, -188, 586, 86, -94, 86, 101, 590, - 226, 592, 253, 262, 219, 286, 220, 259, 28, 288, - 599, 414, 195, 610, 576, 30, 37, 114, 54, 32, - 36, 324, 325, 457, 195, 38, 249, 250, 56, 336, - 195, 326, 172, 36, 337, 301, 602, 301, 196, 621, - 26, 27, 543, 293, 143, 396, 424, 598, 255, 190, - 411, 612, -97, -97, -97, -97, 181, 120, -97, 127, - -97, -97, -97, 425, 311, 94, 36, 99, 325, 144, - 180, 168, 329, 332, 603, 116, -97, 326, 172, 36, - 169, 330, 315, 180, 429, 315, 434, 176, 508, 613, - 326, 172, 170, 368, 185, 418, 321, 453, 95, 96, - 419, 171, 172, 91, 196, 114, 190, 92, 551, -288, - -288, -288, -288, 213, 100, 360, 212, -288, -288, -288, - 363, -190, 434, 101, 328, 331, 224, 330, 496, 217, - 36, -97, 451, -288, 180, 48, 326, 172, 202, 24, - 25, 180, 203, 230, 231, 232, 225, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 342, 228, 121, 260, 261, 5, 343, 7, 83, - 301, 226, 492, 397, 9, 10, 11, 493, 37, 209, - 229, 316, 90, 92, 389, 170, 494, 38, -93, 59, - 13, 144, 477, 557, 171, 172, 334, 413, 144, 619, - 335, 416, 26, 27, 620, 530, 376, 370, 372, 48, - 94, 295, 477, 397, 435, 390, 181, 276, 426, 181, - 162, 163, 427, 164, 165, 166, 167, 446, 417, 447, - 567, 203, 204, 92, 203, -18, -18, -18, -18, 277, - 122, -228, 561, -18, -18, -18, 5, 6, 7, 8, - 435, 283, 365, 569, 9, 10, 11, 92, 94, -18, - 207, 208, -142, 115, 438, 26, 27, 297, -142, 284, - 13, 4, 473, -110, 5, 6, 7, 8, 110, 111, - 112, 376, 9, 10, 11, 9, 10, 11, 303, 455, - 95, 96, 473, 304, 111, 112, 305, 12, 13, 472, - 9, 10, 11, 507, 615, 306, 477, -234, -234, -142, - 309, 358, 623, -142, -18, 307, 475, 260, 261, 472, - 206, -110, 476, 584, 312, 585, 159, 160, 161, 313, - -110, 509, 531, 314, 361, 362, 536, 277, 428, 318, - 515, 517, 48, 540, 382, 323, 546, 545, 14, 155, - 156, 157, 158, 159, 160, 161, 406, 333, 552, 130, - 132, 5, 44, 7, 45, 344, 347, 559, 348, 9, - 10, 11, 350, 548, 351, 162, 163, 566, 164, 165, - 166, 167, 353, 367, 382, 13, 473, 423, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 138, 359, - 57, 5, 439, 7, 83, 58, 59, 420, 60, 9, - 10, 11, 369, 472, 157, 158, 159, 160, 161, -268, - 406, -30, 441, 454, 442, 13, 61, 445, 443, 62, - 448, 63, 64, 456, 495, 46, 606, 486, 65, 406, - -31, 66, 406, 503, 497, 500, 67, 68, 69, 501, - 504, 505, 70, 71, 510, 512, 265, 72, 266, 5, - 6, 7, 8, 502, 513, 267, 514, 9, 10, 11, - 26, 27, 373, 374, 375, 518, 526, 73, 74, 532, - -83, 528, 542, 13, 539, 541, 525, 558, 560, 406, - 562, 190, 563, -106, -106, -106, -106, -106, -106, -106, - 574, -106, -106, -106, -106, -106, 565, -106, -106, -106, - -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, - 575, 577, -106, 406, -106, -106, 406, 587, 593, 597, - 600, -106, -348, 601, -106, 604, 564, 625, 608, -106, - -106, -106, 611, 614, 626, -106, -106, 617, 622, 23, - -106, 281, 534, 430, 406, 109, 36, 5, 44, 7, - 45, 123, 285, 449, 422, 9, 10, 11, -106, -106, - -106, -106, 392, -106, -288, -288, -288, -288, -288, -288, - -288, 13, -288, -288, -288, -288, -288, 406, -288, -288, - -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, - -288, 410, 263, -288, 330, -288, -288, 298, 302, 387, - 215, 296, -288, 326, 172, -288, 125, 431, 399, 572, - -288, -288, -288, 573, 607, 609, -288, -288, 319, 366, - 0, -288, 93, 0, 0, -26, -26, -26, -26, 0, - 0, 0, 0, -26, -26, -26, 0, 0, 0, -288, - 0, -288, -288, 190, -288, -288, -288, 0, 94, -26, - -288, -288, -142, -288, 0, 0, 0, -288, -142, -288, - -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, - 0, -288, 0, 0, -288, 0, -288, -288, 0, 0, - 0, 95, 96, -288, 0, 0, -288, 0, 0, 0, - 0, -288, -288, -288, 0, 0, 0, -288, -288, -142, - 0, 0, -288, -142, -26, 0, 265, 0, 0, 5, - 6, 7, 8, 0, 0, 267, 0, 9, 10, 11, - -288, 433, -288, -288, 190, -288, -288, -288, 0, 0, - 0, -288, -288, 13, -288, 0, 0, 0, -288, 0, - -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, - -288, 0, -288, 0, 0, -288, 0, -288, -288, 0, - 0, 0, 0, 0, -288, 0, 0, -288, 0, 0, - 0, 0, -288, -288, -288, 0, 0, 0, -288, -288, - 0, 0, -348, -288, 210, 0, 0, -22, -22, -22, - -22, 0, 0, 0, 0, -22, -22, -22, 0, 0, - 0, -288, -269, -288, -288, 519, -288, -288, -288, 0, - 94, -22, -288, -288, -142, -288, 0, 0, 0, -288, - -142, -288, -288, -288, -288, -288, -288, -288, -288, -288, - -288, -288, 0, -288, 0, 0, -288, 0, -288, -288, - 0, 0, 0, 95, 96, -288, 0, 0, -288, 0, - 0, 0, 0, -288, -288, -288, 0, 0, 0, -288, - -288, -142, 0, 0, -288, -142, -22, 0, 5, 0, - 7, 177, 0, 0, 0, 0, 9, 10, 11, 0, - 0, 0, -288, 0, -288, -288, 549, -288, -298, -298, - 0, 0, 13, -298, -298, 0, -298, 0, 0, 0, - -298, 0, -298, -298, -298, -298, -298, -298, -298, -298, - -298, -298, -298, 5, -298, 7, 177, -298, 0, -298, - -298, 9, 10, 11, 0, 0, -298, 0, 0, -298, - 0, 0, 0, 0, -298, -298, -298, 13, 0, 0, - -298, -298, -236, -236, 400, -298, 401, 27, 0, 0, - 0, 58, 59, 0, 60, 0, 0, 0, 0, 0, - 170, 0, 0, -298, 0, -298, -298, 0, -298, 171, - 172, 0, 61, 0, 0, 62, 0, 63, 64, 0, - 0, 0, 0, 0, 65, 0, 0, 66, 0, 0, - 0, 0, 67, 68, 69, 0, 0, 0, 70, 71, - 0, 0, 402, 72, 403, 400, 0, 401, 27, 0, - 0, 0, 58, 59, 0, 60, 0, 0, 0, 0, - 0, 0, -170, 73, 74, 0, 404, 0, 0, 0, - 0, 0, 0, 61, 0, 0, 62, 0, 63, 64, - 0, 0, 0, 0, 0, 65, 0, 0, 66, 0, - 0, 0, 0, 67, 68, 69, 0, 0, 0, 70, - 71, 0, 0, 402, 72, 403, 400, 0, 401, 27, - 0, 0, 0, 58, 59, 0, 60, 0, 0, 0, - 0, 0, 0, -225, 73, 74, 0, 404, 0, 0, - 0, 0, 0, 0, 61, 0, 0, 62, 0, 63, - 64, 0, 0, 0, 0, 0, 65, 0, 0, 66, - 0, 0, 0, 0, 67, 68, 69, 0, 0, 0, - 70, 71, 0, 0, 402, 72, 403, 380, 0, 57, - 0, 0, 0, 0, 58, 59, 0, 60, 0, 0, - 0, 5, 44, 7, 45, 73, 74, 0, 404, 9, - 10, 11, 0, 0, 0, 61, 0, 0, 62, 0, - 63, 64, 0, 0, 0, 13, 0, 65, 0, 0, - 66, 0, 0, 0, 0, 67, 68, 69, 0, 57, - 0, 70, 71, 0, 58, 59, 72, 60, 0, 0, - 0, 0, 57, 0, 0, 0, 0, 58, 59, 0, - 60, 0, 0, 0, 0, 61, 73, 74, 62, 381, - 63, 64, 0, 0, 0, 371, 0, 65, 61, 0, - 66, 62, 0, 63, 64, 67, 68, 69, 0, 0, - 65, 70, 71, 66, 0, 0, 72, 0, 67, 68, - 69, 0, 0, 0, 70, 71, 57, 0, 0, 72, - 0, 58, 59, 0, 60, 0, 73, 74, 0, 57, - 188, 0, 0, 0, 58, 59, 0, 60, 0, 73, - 74, 0, 61, 258, 0, 62, 0, 63, 64, 0, - 0, 0, 0, 0, 65, 61, 0, 66, 62, 0, - 63, 64, 67, 68, 69, 0, 0, 65, 70, 71, - 66, 0, 0, 72, 0, 67, 68, 69, 0, 0, - 0, 70, 71, 57, 0, 0, 72, 0, 58, 59, - 0, 60, 0, 73, 74, 0, 0, 292, 154, 155, - 156, 157, 158, 159, 160, 161, 73, 74, 0, 61, - 320, 0, 62, 0, 63, 64, 537, 5, 6, 7, - 8, 65, 0, 0, 66, 9, 10, 11, 0, 67, - 68, 69, 0, 0, 0, 70, 71, 0, 0, 0, - 72, 13, 145, 146, 147, 538, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 73, 74, 0, 0, 412, 401, 458, 6, 7, 8, - 58, 59, 0, 60, 9, 10, 11, 459, 0, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 13, 61, 0, 0, 62, 0, 63, 64, 0, 0, - 0, 0, 0, 65, 0, 0, 66, 0, 0, 0, - 0, 67, 68, 69, 0, 401, 27, 70, 71, 0, - 58, 59, 72, 60, 0, 0, 0, 459, 0, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 61, 73, 74, 62, 226, 63, 64, 0, 0, - 0, 0, 0, 65, 0, 0, 66, 0, 0, 0, - 0, 67, 68, 69, 0, 57, 0, 70, 71, 0, - 58, 59, 72, 60, 0, 0, 5, 44, 7, 45, - 0, 0, 0, 0, 9, 10, 11, 0, 0, 0, - 471, 61, 73, 74, 62, 226, 63, 64, 0, 0, - 13, 0, 0, 65, 0, 0, 66, 0, 0, 0, - 0, 67, 68, 69, 0, 0, 0, 70, 71, 0, - 0, 0, 72, 57, 5, 0, 7, 83, 58, 59, - 0, 60, 9, 10, 11, 0, 0, 0, 0, 0, - 0, 0, 73, 74, 0, 310, 0, 0, 13, 61, - 516, 0, 62, 0, 63, 64, 0, 57, 0, 0, - 0, 65, 58, 59, 66, 60, 0, 0, 0, 67, - 68, 69, 0, 0, 0, 70, 71, 0, 0, 0, - 72, 0, 0, 61, 0, 0, 62, 0, 63, 64, - 0, 0, 0, 0, 0, 65, 0, 0, 66, 0, - 73, 74, 0, 67, 68, 69, 0, 57, 0, 70, - 71, 0, 58, 59, 72, 60, 0, 0, 0, 0, - 57, 0, 0, 0, 0, 58, 59, 0, 60, 0, - 0, 0, 506, 61, 73, 74, 62, 0, 63, 64, - 0, 0, 0, 0, 0, 65, 61, 0, 66, 62, - 0, 63, 64, 67, 68, 69, 0, 0, 65, 70, - 71, 66, 0, 0, 72, 0, 67, 68, 69, 0, - 57, 0, 70, 71, 0, 58, 59, 129, 60, 0, - 0, 0, 0, 450, 73, 74, 0, 0, 58, 59, - 0, 60, 0, 0, 0, 0, 61, 73, 74, 62, - 0, 63, 64, 0, 0, 0, 0, 0, 65, 61, - 0, 66, 62, 0, 63, 64, 67, 68, 69, 0, - 0, 65, 70, 71, 66, 0, 0, 131, 0, 67, - 68, 69, 0, 0, 0, 70, 71, 487, 0, 0, - 72, 0, 0, 0, 0, 0, 0, 73, 74, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 73, 74, 0, 145, 146, 147, 0, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 145, 146, 147, 0, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 0, - 0, 0, 0, 196, 0, 0, 0, 0, 145, 146, - 147, 488, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 0, 0, 0, 554, - 145, 146, 147, 581, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 145, 146, - 147, 0, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 147, 0, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 153, 154, 155, - 156, 157, 158, 159, 160, 161 -}; - -static const short yycheck[] = { 34, - 35, 9, 10, 11, 18, 43, 47, 185, 166, 104, - 206, 2, 3, 192, 19, 20, 20, 2, 3, 301, - 100, 49, 88, 171, 38, 140, 207, 370, 92, 63, - 64, 35, 443, 47, 257, 69, 101, 72, 500, 9, - 32, 75, 50, 72, 1, 175, 97, 395, 1, 53, - 499, 1, 27, 10, 421, 3, 4, 65, 3, 4, - 0, 96, 60, 60, 61, 3, 4, 27, 72, 3, - 4, 3, 4, 440, 346, 89, 39, 349, 0, 490, - 77, 109, 205, 431, 88, 60, 61, 101, 211, 184, - 170, 39, 60, 61, 129, 60, 131, 78, 3, 133, - 129, 550, 131, 51, 3, 4, 254, 77, 7, 77, - 60, 119, 60, 524, 77, 397, 527, 579, 123, 51, - 125, 125, 83, 83, 573, 129, 83, 131, 60, 578, - 83, 580, 167, 263, 126, 200, 128, 172, 83, 203, - 589, 364, 193, 605, 555, 83, 51, 175, 83, 83, - 3, 4, 51, 435, 205, 60, 164, 165, 83, 77, - 211, 60, 61, 3, 82, 216, 39, 218, 31, 618, - 3, 4, 515, 208, 77, 354, 39, 588, 326, 1, - 361, 39, 4, 5, 6, 7, 200, 79, 10, 79, - 12, 13, 14, 389, 228, 27, 3, 4, 51, 82, - 7, 9, 268, 269, 77, 213, 28, 60, 61, 3, - 77, 51, 360, 7, 393, 363, 395, 77, 51, 77, - 60, 61, 51, 338, 60, 77, 261, 423, 60, 61, - 82, 60, 61, 78, 31, 263, 1, 82, 520, 4, - 5, 6, 7, 82, 51, 325, 37, 12, 13, 14, - 330, 83, 431, 60, 268, 269, 77, 51, 454, 78, - 3, 83, 420, 28, 7, 269, 60, 61, 78, 78, - 79, 7, 82, 144, 145, 146, 77, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 282, 77, 1, 60, 61, 4, 282, 6, 7, - 351, 83, 77, 354, 12, 13, 14, 82, 51, 78, - 78, 77, 326, 82, 352, 51, 77, 60, 83, 9, - 28, 82, 437, 77, 60, 61, 78, 362, 82, 77, - 82, 372, 3, 4, 82, 493, 344, 342, 343, 343, - 27, 212, 457, 394, 395, 353, 360, 84, 78, 363, - 55, 56, 82, 58, 59, 60, 61, 78, 372, 78, - 78, 82, 1, 82, 82, 4, 5, 6, 7, 78, - 78, 79, 77, 12, 13, 14, 4, 5, 6, 7, - 431, 60, 10, 78, 12, 13, 14, 82, 27, 28, - 60, 61, 31, 1, 402, 3, 4, 79, 37, 37, - 28, 1, 437, 3, 4, 5, 6, 7, 5, 6, - 7, 419, 12, 13, 14, 12, 13, 14, 79, 427, - 60, 61, 457, 79, 6, 7, 77, 27, 28, 437, - 12, 13, 14, 468, 612, 77, 551, 78, 79, 78, - 77, 312, 620, 82, 83, 79, 437, 60, 61, 457, - 545, 51, 437, 568, 39, 570, 51, 52, 53, 77, - 60, 469, 497, 84, 60, 61, 501, 78, 79, 84, - 475, 476, 476, 508, 345, 77, 517, 515, 78, 47, - 48, 49, 50, 51, 52, 53, 357, 77, 523, 60, - 61, 4, 5, 6, 7, 60, 37, 532, 84, 12, - 13, 14, 79, 517, 82, 55, 56, 542, 58, 59, - 60, 61, 33, 3, 385, 28, 551, 388, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 1, 84, - 3, 4, 403, 6, 7, 8, 9, 60, 11, 12, - 13, 14, 78, 551, 49, 50, 51, 52, 53, 79, - 421, 39, 39, 424, 79, 28, 29, 84, 82, 32, - 77, 34, 35, 79, 79, 78, 601, 37, 41, 440, - 39, 44, 443, 39, 60, 60, 49, 50, 51, 60, - 78, 78, 55, 56, 7, 39, 1, 60, 3, 4, - 5, 6, 7, 464, 78, 10, 78, 12, 13, 14, - 3, 4, 5, 6, 7, 16, 37, 80, 81, 60, - 83, 79, 60, 28, 78, 78, 487, 77, 17, 490, - 78, 1, 77, 3, 4, 5, 6, 7, 8, 9, - 77, 11, 12, 13, 14, 15, 78, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 37, 77, 32, 524, 34, 35, 527, 78, 9, 78, - 78, 41, 77, 60, 44, 82, 537, 0, 78, 49, - 50, 51, 77, 77, 0, 55, 56, 78, 78, 3, - 60, 193, 500, 394, 555, 48, 3, 4, 5, 6, - 7, 53, 198, 419, 385, 12, 13, 14, 78, 79, - 80, 81, 1, 83, 3, 4, 5, 6, 7, 8, - 9, 28, 11, 12, 13, 14, 15, 588, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 360, 178, 32, 51, 34, 35, 215, 218, 351, - 119, 213, 41, 60, 61, 44, 53, 394, 355, 551, - 49, 50, 51, 551, 602, 604, 55, 56, 260, 335, - -1, 60, 1, -1, -1, 4, 5, 6, 7, -1, - -1, -1, -1, 12, 13, 14, -1, -1, -1, 78, - -1, 80, 81, 1, 83, 3, 4, -1, 27, 28, - 8, 9, 31, 11, -1, -1, -1, 15, 37, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - -1, 29, -1, -1, 32, -1, 34, 35, -1, -1, - -1, 60, 61, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, -1, -1, 55, 56, 78, - -1, -1, 60, 82, 83, -1, 1, -1, -1, 4, - 5, 6, 7, -1, -1, 10, -1, 12, 13, 14, - 78, 79, 80, 81, 1, 83, 3, 4, -1, -1, - -1, 8, 9, 28, 11, -1, -1, -1, 15, -1, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, -1, 29, -1, -1, 32, -1, 34, 35, -1, - -1, -1, -1, -1, 41, -1, -1, 44, -1, -1, - -1, -1, 49, 50, 51, -1, -1, -1, 55, 56, - -1, -1, 77, 60, 1, -1, -1, 4, 5, 6, - 7, -1, -1, -1, -1, 12, 13, 14, -1, -1, - -1, 78, 79, 80, 81, 1, 83, 3, 4, -1, - 27, 28, 8, 9, 31, 11, -1, -1, -1, 15, - 37, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, -1, 29, -1, -1, 32, -1, 34, 35, - -1, -1, -1, 60, 61, 41, -1, -1, 44, -1, - -1, -1, -1, 49, 50, 51, -1, -1, -1, 55, - 56, 78, -1, -1, 60, 82, 83, -1, 4, -1, - 6, 7, -1, -1, -1, -1, 12, 13, 14, -1, - -1, -1, 78, -1, 80, 81, 1, 83, 3, 4, - -1, -1, 28, 8, 9, -1, 11, -1, -1, -1, - 15, -1, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 4, 29, 6, 7, 32, -1, 34, - 35, 12, 13, 14, -1, -1, 41, -1, -1, 44, - -1, -1, -1, -1, 49, 50, 51, 28, -1, -1, - 55, 56, 78, 79, 1, 60, 3, 4, -1, -1, - -1, 8, 9, -1, 11, -1, -1, -1, -1, -1, - 51, -1, -1, 78, -1, 80, 81, -1, 83, 60, - 61, -1, 29, -1, -1, 32, -1, 34, 35, -1, - -1, -1, -1, -1, 41, -1, -1, 44, -1, -1, - -1, -1, 49, 50, 51, -1, -1, -1, 55, 56, - -1, -1, 59, 60, 61, 1, -1, 3, 4, -1, - -1, -1, 8, 9, -1, 11, -1, -1, -1, -1, - -1, -1, 79, 80, 81, -1, 83, -1, -1, -1, - -1, -1, -1, 29, -1, -1, 32, -1, 34, 35, - -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, - -1, -1, -1, 49, 50, 51, -1, -1, -1, 55, - 56, -1, -1, 59, 60, 61, 1, -1, 3, 4, - -1, -1, -1, 8, 9, -1, 11, -1, -1, -1, - -1, -1, -1, 79, 80, 81, -1, 83, -1, -1, - -1, -1, -1, -1, 29, -1, -1, 32, -1, 34, - 35, -1, -1, -1, -1, -1, 41, -1, -1, 44, - -1, -1, -1, -1, 49, 50, 51, -1, -1, -1, - 55, 56, -1, -1, 59, 60, 61, 1, -1, 3, - -1, -1, -1, -1, 8, 9, -1, 11, -1, -1, - -1, 4, 5, 6, 7, 80, 81, -1, 83, 12, - 13, 14, -1, -1, -1, 29, -1, -1, 32, -1, - 34, 35, -1, -1, -1, 28, -1, 41, -1, -1, - 44, -1, -1, -1, -1, 49, 50, 51, -1, 3, - -1, 55, 56, -1, 8, 9, 60, 11, -1, -1, - -1, -1, 3, -1, -1, -1, -1, 8, 9, -1, - 11, -1, -1, -1, -1, 29, 80, 81, 32, 83, - 34, 35, -1, -1, -1, 78, -1, 41, 29, -1, - 44, 32, -1, 34, 35, 49, 50, 51, -1, -1, - 41, 55, 56, 44, -1, -1, 60, -1, 49, 50, - 51, -1, -1, -1, 55, 56, 3, -1, -1, 60, - -1, 8, 9, -1, 11, -1, 80, 81, -1, 3, - 84, -1, -1, -1, 8, 9, -1, 11, -1, 80, - 81, -1, 29, 84, -1, 32, -1, 34, 35, -1, - -1, -1, -1, -1, 41, 29, -1, 44, 32, -1, - 34, 35, 49, 50, 51, -1, -1, 41, 55, 56, - 44, -1, -1, 60, -1, 49, 50, 51, -1, -1, - -1, 55, 56, 3, -1, -1, 60, -1, 8, 9, - -1, 11, -1, 80, 81, -1, -1, 84, 46, 47, - 48, 49, 50, 51, 52, 53, 80, 81, -1, 29, - 84, -1, 32, -1, 34, 35, 10, 4, 5, 6, - 7, 41, -1, -1, 44, 12, 13, 14, -1, 49, - 50, 51, -1, -1, -1, 55, 56, -1, -1, -1, - 60, 28, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 80, 81, -1, -1, 84, 3, 4, 5, 6, 7, - 8, 9, -1, 11, 12, 13, 14, 15, -1, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, -1, -1, 32, -1, 34, 35, -1, -1, - -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, 3, 4, 55, 56, -1, - 8, 9, 60, 11, -1, -1, -1, 15, -1, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 78, 29, 80, 81, 32, 83, 34, 35, -1, -1, - -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, 3, -1, 55, 56, -1, - 8, 9, 60, 11, -1, -1, 4, 5, 6, 7, - -1, -1, -1, -1, 12, 13, 14, -1, -1, -1, - 78, 29, 80, 81, 32, 83, 34, 35, -1, -1, - 28, -1, -1, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, -1, -1, 55, 56, -1, - -1, -1, 60, 3, 4, -1, 6, 7, 8, 9, - -1, 11, 12, 13, 14, -1, -1, -1, -1, -1, - -1, -1, 80, 81, -1, 83, -1, -1, 28, 29, - 78, -1, 32, -1, 34, 35, -1, 3, -1, -1, - -1, 41, 8, 9, 44, 11, -1, -1, -1, 49, - 50, 51, -1, -1, -1, 55, 56, -1, -1, -1, - 60, -1, -1, 29, -1, -1, 32, -1, 34, 35, - -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, - 80, 81, -1, 49, 50, 51, -1, 3, -1, 55, - 56, -1, 8, 9, 60, 11, -1, -1, -1, -1, - 3, -1, -1, -1, -1, 8, 9, -1, 11, -1, - -1, -1, 78, 29, 80, 81, 32, -1, 34, 35, - -1, -1, -1, -1, -1, 41, 29, -1, 44, 32, - -1, 34, 35, 49, 50, 51, -1, -1, 41, 55, - 56, 44, -1, -1, 60, -1, 49, 50, 51, -1, - 3, -1, 55, 56, -1, 8, 9, 60, 11, -1, - -1, -1, -1, 3, 80, 81, -1, -1, 8, 9, - -1, 11, -1, -1, -1, -1, 29, 80, 81, 32, - -1, 34, 35, -1, -1, -1, -1, -1, 41, 29, - -1, 44, 32, -1, 34, 35, 49, 50, 51, -1, - -1, 41, 55, 56, 44, -1, -1, 60, -1, 49, - 50, 51, -1, -1, -1, 55, 56, 10, -1, -1, - 60, -1, -1, -1, -1, -1, -1, 80, 81, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 80, 81, -1, 36, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 36, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, - -1, -1, -1, 31, -1, -1, -1, -1, 36, 37, - 38, 84, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, -1, -1, -1, 84, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 36, 37, - 38, -1, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 38, -1, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 45, 46, 47, - 48, 49, 50, 51, 52, 53 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/local/lib/bison.simple" - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#ifndef alloca -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) -#include <alloca.h> -#else /* not sparc */ -#if defined (MSDOS) && !defined (__TURBOC__) -#include <malloc.h> -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -#include <malloc.h> - #pragma alloca -#else /* not MSDOS, __TURBOC__, or _AIX */ -#ifdef __hpux -#ifdef __cplusplus -extern "C" { -void *alloca (unsigned int); -}; -#else /* not __cplusplus */ -void *alloca (); -#endif /* not __cplusplus */ -#endif /* __hpux */ -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc. */ -#endif /* not GNU C. */ -#endif /* alloca not defined. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#define YYLEX yylex(&yylval, &yylloc) -#else -#define YYLEX yylex(&yylval) -#endif -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -int yyparse (void); -#endif - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_bcopy (from, to, count) - char *from; - char *to; - int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_bcopy (char *from, char *to, int count) -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 184 "/usr/local/lib/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#else -#define YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#endif - -int -yyparse(YYPARSE_PARAM) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); - __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); - __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); - __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 1: -#line 221 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids an empty source file"); - ; - break;} -case 2: -#line 225 "c-parse.y" -{ - /* In case there were missing closebraces, - get us back to the global binding level. */ - while (! global_bindings_p ()) - poplevel (0, 0, 0); - ; - break;} -case 3: -#line 238 "c-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 5: -#line 239 "c-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 9: -#line 246 "c-parse.y" -{ STRIP_NOPS (yyvsp[-2].ttype); - if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST) - || TREE_CODE (yyvsp[-2].ttype) == STRING_CST) - assemble_asm (yyvsp[-2].ttype); - else - error ("argument of `asm' is not a constant string"); ; - break;} -case 10: -#line 257 "c-parse.y" -{ if (pedantic) - error ("ANSI C forbids data definition with no type or storage class"); - else if (!flag_traditional) - warning ("data definition has no type or storage class"); ; - break;} -case 11: -#line 262 "c-parse.y" -{; - break;} -case 12: -#line 264 "c-parse.y" -{; - break;} -case 13: -#line 266 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 14: -#line 268 "c-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 17: -#line 272 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C does not allow extra `;' outside of a function"); ; - break;} -case 18: -#line 278 "c-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 19: -#line 282 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 20: -#line 284 "c-parse.y" -{ finish_function (0); ; - break;} -case 21: -#line 286 "c-parse.y" -{ ; - break;} -case 22: -#line 288 "c-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 23: -#line 292 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 24: -#line 294 "c-parse.y" -{ finish_function (0); ; - break;} -case 25: -#line 296 "c-parse.y" -{ ; - break;} -case 26: -#line 298 "c-parse.y" -{ if (! start_function (NULL_TREE, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 27: -#line 302 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 28: -#line 304 "c-parse.y" -{ finish_function (0); ; - break;} -case 29: -#line 306 "c-parse.y" -{ ; - break;} -case 32: -#line 315 "c-parse.y" -{ yyval.code = ADDR_EXPR; ; - break;} -case 33: -#line 317 "c-parse.y" -{ yyval.code = NEGATE_EXPR; ; - break;} -case 34: -#line 319 "c-parse.y" -{ yyval.code = CONVERT_EXPR; ; - break;} -case 35: -#line 321 "c-parse.y" -{ yyval.code = PREINCREMENT_EXPR; ; - break;} -case 36: -#line 323 "c-parse.y" -{ yyval.code = PREDECREMENT_EXPR; ; - break;} -case 37: -#line 325 "c-parse.y" -{ yyval.code = BIT_NOT_EXPR; ; - break;} -case 38: -#line 327 "c-parse.y" -{ yyval.code = TRUTH_NOT_EXPR; ; - break;} -case 39: -#line 331 "c-parse.y" -{ yyval.ttype = build_compound_expr (yyvsp[0].ttype); ; - break;} -case 40: -#line 336 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 42: -#line 342 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 43: -#line 344 "c-parse.y" -{ chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 45: -#line 350 "c-parse.y" -{ yyval.ttype = build_indirect_ref (yyvsp[0].ttype, "unary *"); ; - break;} -case 46: -#line 353 "c-parse.y" -{ yyvsp[0].itype = pedantic; - pedantic = 0; ; - break;} -case 47: -#line 356 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - pedantic = yyvsp[-2].itype; ; - break;} -case 48: -#line 359 "c-parse.y" -{ yyval.ttype = build_unary_op (yyvsp[-1].code, yyvsp[0].ttype, 0); - overflow_warning (yyval.ttype); ; - break;} -case 49: -#line 363 "c-parse.y" -{ tree label = lookup_label (yyvsp[0].ttype); - if (label == 0) - yyval.ttype = null_pointer_node; - else - { - TREE_USED (label) = 1; - yyval.ttype = build1 (ADDR_EXPR, ptr_type_node, label); - TREE_CONSTANT (yyval.ttype) = 1; - } - ; - break;} -case 50: -#line 389 "c-parse.y" -{ if (TREE_CODE (yyvsp[0].ttype) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (yyvsp[0].ttype, 1))) - error ("`sizeof' applied to a bit-field"); - yyval.ttype = c_sizeof (TREE_TYPE (yyvsp[0].ttype)); ; - break;} -case 51: -#line 394 "c-parse.y" -{ yyval.ttype = c_sizeof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 52: -#line 396 "c-parse.y" -{ yyval.ttype = c_alignof_expr (yyvsp[0].ttype); ; - break;} -case 53: -#line 398 "c-parse.y" -{ yyval.ttype = c_alignof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 54: -#line 400 "c-parse.y" -{ yyval.ttype = build_unary_op (REALPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 55: -#line 402 "c-parse.y" -{ yyval.ttype = build_unary_op (IMAGPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 57: -#line 408 "c-parse.y" -{ tree type = groktypename (yyvsp[-2].ttype); - yyval.ttype = build_c_cast (type, yyvsp[0].ttype); ; - break;} -case 58: -#line 411 "c-parse.y" -{ start_init (NULL_TREE, NULL, 0); - yyvsp[-2].ttype = groktypename (yyvsp[-2].ttype); - really_start_incremental_init (yyvsp[-2].ttype); ; - break;} -case 59: -#line 415 "c-parse.y" -{ char *name; - tree result = pop_init_level (0); - tree type = yyvsp[-5].ttype; - finish_init (); - - if (pedantic) - pedwarn ("ANSI C forbids constructor expressions"); - if (TYPE_NAME (type) != 0) - { - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - name = IDENTIFIER_POINTER (TYPE_NAME (type)); - else - name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - } - else - name = ""; - yyval.ttype = result; - if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) - { - int failure = complete_array_type (type, yyval.ttype, 1); - if (failure) - abort (); - } - ; - break;} -case 61: -#line 444 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 62: -#line 446 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 63: -#line 448 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 64: -#line 450 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 65: -#line 452 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 66: -#line 454 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 67: -#line 456 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 68: -#line 458 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 69: -#line 460 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 70: -#line 462 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 71: -#line 464 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 72: -#line 466 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 73: -#line 468 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ANDIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 74: -#line 470 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ORIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 75: -#line 472 "c-parse.y" -{ yyval.ttype = build_conditional_expr (yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 76: -#line 474 "c-parse.y" -{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, NOP_EXPR, yyvsp[0].ttype); - C_SET_EXP_ORIGINAL_CODE (yyval.ttype, MODIFY_EXPR); ; - break;} -case 77: -#line 477 "c-parse.y" -{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, yyvsp[-1].code, yyvsp[0].ttype); - /* This inhibits warnings in truthvalue_conversion. */ - C_SET_EXP_ORIGINAL_CODE (yyval.ttype, ERROR_MARK); ; - break;} -case 78: -#line 484 "c-parse.y" -{ - yyval.ttype = lastiddecl; - if (!yyval.ttype || yyval.ttype == error_mark_node) - { - if (yychar == YYEMPTY) - yychar = YYLEX; - if (yychar == '(') - { - { - /* Ordinary implicit function declaration. */ - yyval.ttype = implicitly_declare (yyvsp[0].ttype); - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - } - else if (current_function_decl == 0) - { - error ("`%s' undeclared here (not in a function)", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = error_mark_node; - } - else - { - { - if (IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) != current_function_decl) - { - error ("`%s' undeclared (first use this function)", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once"); - error ("for each function it appears in.)"); - undeclared_variable_notice = 1; - } - } - yyval.ttype = error_mark_node; - /* Prevent repeated error messages. */ - IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) = error_mark_node; - IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) = current_function_decl; - } - } - } - else if (TREE_TYPE (yyval.ttype) == error_mark_node) - yyval.ttype = error_mark_node; - else if (C_DECL_ANTICIPATED (yyval.ttype)) - { - /* The first time we see a build-in function used, - if it has not been declared. */ - C_DECL_ANTICIPATED (yyval.ttype) = 0; - if (yychar == YYEMPTY) - yychar = YYLEX; - if (yychar == '(') - { - /* Omit the implicit declaration we - would ordinarily do, so we don't lose - the actual built in type. - But print a diagnostic for the mismatch. */ - if (TREE_CODE (yyval.ttype) != FUNCTION_DECL) - error ("`%s' implicitly declared as function", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE (yyval.ttype))) - != TYPE_MODE (integer_type_node)) - && (TREE_TYPE (TREE_TYPE (yyval.ttype)) - != void_type_node)) - pedwarn ("type mismatch in implicit declaration for built-in function `%s'", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - /* If it really returns void, change that to int. */ - if (TREE_TYPE (TREE_TYPE (yyval.ttype)) == void_type_node) - TREE_TYPE (yyval.ttype) - = build_function_type (integer_type_node, - TYPE_ARG_TYPES (TREE_TYPE (yyval.ttype))); - } - else - pedwarn ("built-in function `%s' used without declaration", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - - /* Do what we would ordinarily do when a fn is used. */ - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - else - { - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - - if (TREE_CODE (yyval.ttype) == CONST_DECL) - { - yyval.ttype = DECL_INITIAL (yyval.ttype); - /* This is to prevent an enum whose value is 0 - from being considered a null pointer constant. */ - yyval.ttype = build1 (NOP_EXPR, TREE_TYPE (yyval.ttype), yyval.ttype); - TREE_CONSTANT (yyval.ttype) = 1; - } - ; - break;} -case 80: -#line 583 "c-parse.y" -{ yyval.ttype = combine_strings (yyvsp[0].ttype); ; - break;} -case 81: -#line 585 "c-parse.y" -{ char class = TREE_CODE_CLASS (TREE_CODE (yyvsp[-1].ttype)); - if (class == 'e' || class == '1' - || class == '2' || class == '<') - C_SET_EXP_ORIGINAL_CODE (yyvsp[-1].ttype, ERROR_MARK); - yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 82: -#line 591 "c-parse.y" -{ yyval.ttype = error_mark_node; ; - break;} -case 83: -#line 593 "c-parse.y" -{ if (current_function_decl == 0) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - /* We must force a BLOCK for this level - so that, if it is not expanded later, - there is a way to turn off the entire subtree of blocks - that are contained in it. */ - keep_next_level (); - push_iterator_stack (); - push_label_level (); - yyval.ttype = expand_start_stmt_expr (); ; - break;} -case 84: -#line 607 "c-parse.y" -{ tree rtl_exp; - if (pedantic) - pedwarn ("ANSI C forbids braced-groups within expressions"); - pop_iterator_stack (); - pop_label_level (); - rtl_exp = expand_end_stmt_expr (yyvsp[-2].ttype); - /* The statements have side effects, so the group does. */ - TREE_SIDE_EFFECTS (rtl_exp) = 1; - - if (TREE_CODE (yyvsp[-1].ttype) == BLOCK) - { - /* Make a BIND_EXPR for the BLOCK already made. */ - yyval.ttype = build (BIND_EXPR, TREE_TYPE (rtl_exp), - NULL_TREE, rtl_exp, yyvsp[-1].ttype); - /* Remove the block from the tree at this point. - It gets put back at the proper place - when the BIND_EXPR is expanded. */ - delete_block (yyvsp[-1].ttype); - } - else - yyval.ttype = yyvsp[-1].ttype; - ; - break;} -case 85: -#line 630 "c-parse.y" -{ yyval.ttype = build_function_call (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 86: -#line 632 "c-parse.y" -{ yyval.ttype = build_array_ref (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 87: -#line 634 "c-parse.y" -{ - yyval.ttype = build_component_ref (yyvsp[-2].ttype, yyvsp[0].ttype); - ; - break;} -case 88: -#line 638 "c-parse.y" -{ - tree expr = build_indirect_ref (yyvsp[-2].ttype, "->"); - - yyval.ttype = build_component_ref (expr, yyvsp[0].ttype); - ; - break;} -case 89: -#line 644 "c-parse.y" -{ yyval.ttype = build_unary_op (POSTINCREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 90: -#line 646 "c-parse.y" -{ yyval.ttype = build_unary_op (POSTDECREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 92: -#line 653 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 95: -#line 662 "c-parse.y" -{ c_mark_varargs (); - if (pedantic) - pedwarn ("ANSI C does not permit use of `varargs.h'"); ; - break;} -case 96: -#line 672 "c-parse.y" -{ ; - break;} -case 101: -#line 684 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 102: -#line 688 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 103: -#line 692 "c-parse.y" -{ shadow_tag_warned (yyvsp[-1].ttype, 1); - pedwarn ("empty declaration"); ; - break;} -case 104: -#line 695 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 105: -#line 704 "c-parse.y" -{ ; - break;} -case 110: -#line 719 "c-parse.y" -{ yyval.itype = suspend_momentary (); - pending_xref_error (); - declspec_stack = tree_cons (NULL_TREE, current_declspecs, - declspec_stack); - current_declspecs = yyvsp[0].ttype; ; - break;} -case 111: -#line 728 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 112: -#line 732 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 113: -#line 736 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 114: -#line 740 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 115: -#line 744 "c-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 116: -#line 746 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 117: -#line 755 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 118: -#line 757 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 119: -#line 761 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 120: -#line 763 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 121: -#line 765 "c-parse.y" -{ if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 122: -#line 777 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 123: -#line 780 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 124: -#line 782 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 125: -#line 785 "c-parse.y" -{ if (extra_warnings && TREE_STATIC (yyvsp[-1].ttype)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); - TREE_STATIC (yyval.ttype) = TREE_STATIC (yyvsp[-1].ttype); ; - break;} -case 126: -#line 799 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 127: -#line 801 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 128: -#line 805 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 129: -#line 807 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 132: -#line 817 "c-parse.y" -{ /* For a typedef name, record the meaning, not the name. - In case of `foo foo, bar;'. */ - yyval.ttype = lookup_name (yyvsp[0].ttype); ; - break;} -case 133: -#line 821 "c-parse.y" -{ yyval.ttype = TREE_TYPE (yyvsp[-1].ttype); ; - break;} -case 134: -#line 823 "c-parse.y" -{ yyval.ttype = groktypename (yyvsp[-1].ttype); ; - break;} -case 142: -#line 845 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 143: -#line 847 "c-parse.y" -{ if (TREE_CHAIN (yyvsp[-1].ttype)) yyvsp[-1].ttype = combine_strings (yyvsp[-1].ttype); - yyval.ttype = yyvsp[-1].ttype; - ; - break;} -case 144: -#line 854 "c-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); - decl_attributes (yyval.ttype, yyvsp[-1].ttype); - start_init (yyval.ttype, yyvsp[-2].ttype, global_bindings_p ()); ; - break;} -case 145: -#line 859 "c-parse.y" -{ finish_init (); - decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 146: -#line 863 "c-parse.y" -{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0); - decl_attributes (d, yyvsp[0].ttype); - finish_decl (d, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 147: -#line 870 "c-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); - decl_attributes (yyval.ttype, yyvsp[-1].ttype); - start_init (yyval.ttype, yyvsp[-2].ttype, global_bindings_p ()); ; - break;} -case 148: -#line 875 "c-parse.y" -{ finish_init (); - decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 149: -#line 879 "c-parse.y" -{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0); - decl_attributes (d, yyvsp[0].ttype); - finish_decl (d, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 150: -#line 887 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 151: -#line 889 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 152: -#line 894 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 153: -#line 896 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 154: -#line 901 "c-parse.y" -{ yyval.ttype = yyvsp[-2].ttype; ; - break;} -case 155: -#line 906 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 156: -#line 908 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 157: -#line 913 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 158: -#line 915 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 159: -#line 917 "c-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-3].ttype, NULL_TREE, - build_tree_list (NULL_TREE, yyvsp[-1].ttype)); ; - break;} -case 160: -#line 920 "c-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-5].ttype, NULL_TREE, - tree_cons (NULL_TREE, yyvsp[-3].ttype, yyvsp[-1].ttype)); ; - break;} -case 161: -#line 923 "c-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-3].ttype, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 167: -#line 941 "c-parse.y" -{ really_start_incremental_init (NULL_TREE); - /* Note that the call to clear_momentary - is in process_init_element. */ - push_momentary (); ; - break;} -case 168: -#line 946 "c-parse.y" -{ yyval.ttype = pop_init_level (0); - if (yyval.ttype == error_mark_node - && ! (yychar == STRING || yychar == CONSTANT)) - pop_momentary (); - else - pop_momentary_nofree (); ; - break;} -case 169: -#line 954 "c-parse.y" -{ yyval.ttype = error_mark_node; ; - break;} -case 170: -#line 960 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids empty initializer braces"); ; - break;} -case 174: -#line 974 "c-parse.y" -{ process_init_element (yyvsp[0].ttype); ; - break;} -case 175: -#line 976 "c-parse.y" -{ push_init_level (0); ; - break;} -case 176: -#line 978 "c-parse.y" -{ process_init_element (pop_init_level (0)); ; - break;} -case 178: -#line 984 "c-parse.y" -{ set_init_index (yyvsp[-4].ttype, yyvsp[-2].ttype); ; - break;} -case 180: -#line 987 "c-parse.y" -{ set_init_index (yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 182: -#line 990 "c-parse.y" -{ set_init_index (yyvsp[-1].ttype, NULL_TREE); ; - break;} -case 184: -#line 993 "c-parse.y" -{ set_init_label (yyvsp[-1].ttype); ; - break;} -case 186: -#line 996 "c-parse.y" -{ set_init_label (yyvsp[-1].ttype); ; - break;} -case 188: -#line 1002 "c-parse.y" -{ push_c_function_context (); - if (! start_function (current_declspecs, yyvsp[0].ttype, 1)) - { - pop_c_function_context (); - YYERROR1; - } - reinit_parse_for_function (); - store_parm_decls (); ; - break;} -case 189: -#line 1017 "c-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 190: -#line 1023 "c-parse.y" -{ push_c_function_context (); - if (! start_function (current_declspecs, yyvsp[0].ttype, 1)) - { - pop_c_function_context (); - YYERROR1; - } - reinit_parse_for_function (); - store_parm_decls (); ; - break;} -case 191: -#line 1038 "c-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 194: -#line 1054 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 195: -#line 1056 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 196: -#line 1061 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 197: -#line 1063 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 198: -#line 1065 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 200: -#line 1076 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 201: -#line 1081 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 202: -#line 1083 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 203: -#line 1085 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 205: -#line 1094 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 206: -#line 1099 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 207: -#line 1101 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 208: -#line 1103 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 209: -#line 1105 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 211: -#line 1111 "c-parse.y" -{ yyval.ttype = start_struct (RECORD_TYPE, yyvsp[-1].ttype); - /* Start scope of tag before parsing components. */ - ; - break;} -case 212: -#line 1115 "c-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); - /* Really define the structure. */ - ; - break;} -case 213: -#line 1119 "c-parse.y" -{ yyval.ttype = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 214: -#line 1122 "c-parse.y" -{ yyval.ttype = xref_tag (RECORD_TYPE, yyvsp[0].ttype); ; - break;} -case 215: -#line 1124 "c-parse.y" -{ yyval.ttype = start_struct (UNION_TYPE, yyvsp[-1].ttype); ; - break;} -case 216: -#line 1126 "c-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 217: -#line 1128 "c-parse.y" -{ yyval.ttype = finish_struct (start_struct (UNION_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 218: -#line 1131 "c-parse.y" -{ yyval.ttype = xref_tag (UNION_TYPE, yyvsp[0].ttype); ; - break;} -case 219: -#line 1133 "c-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (yyvsp[-1].ttype); ; - break;} -case 220: -#line 1136 "c-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 221: -#line 1139 "c-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (NULL_TREE); ; - break;} -case 222: -#line 1142 "c-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 223: -#line 1145 "c-parse.y" -{ yyval.ttype = xref_tag (ENUMERAL_TYPE, yyvsp[0].ttype); ; - break;} -case 227: -#line 1156 "c-parse.y" -{ if (pedantic) pedwarn ("comma at end of enumerator list"); ; - break;} -case 228: -#line 1161 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 229: -#line 1163 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); - pedwarn ("no semicolon at end of struct or union"); ; - break;} -case 230: -#line 1168 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 231: -#line 1170 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 232: -#line 1172 "c-parse.y" -{ if (pedantic) - pedwarn ("extra semicolon in struct or union specified"); ; - break;} -case 233: -#line 1187 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 234: -#line 1192 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids member declarations with no members"); - shadow_tag(yyvsp[0].ttype); - yyval.ttype = NULL_TREE; ; - break;} -case 235: -#line 1197 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 236: -#line 1202 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids member declarations with no members"); - shadow_tag(yyvsp[0].ttype); - yyval.ttype = NULL_TREE; ; - break;} -case 237: -#line 1207 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 239: -#line 1213 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 240: -#line 1218 "c-parse.y" -{ yyval.ttype = grokfield (yyvsp[-3].filename, yyvsp[-2].lineno, yyvsp[-1].ttype, current_declspecs, NULL_TREE); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 241: -#line 1222 "c-parse.y" -{ yyval.ttype = grokfield (yyvsp[-5].filename, yyvsp[-4].lineno, yyvsp[-3].ttype, current_declspecs, yyvsp[-1].ttype); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 242: -#line 1225 "c-parse.y" -{ yyval.ttype = grokfield (yyvsp[-4].filename, yyvsp[-3].lineno, NULL_TREE, current_declspecs, yyvsp[-1].ttype); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 244: -#line 1237 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 245: -#line 1239 "c-parse.y" -{ yyval.ttype = error_mark_node; ; - break;} -case 246: -#line 1245 "c-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 247: -#line 1247 "c-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 248: -#line 1252 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 249: -#line 1254 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 250: -#line 1259 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 252: -#line 1265 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 253: -#line 1267 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 254: -#line 1272 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 255: -#line 1274 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 256: -#line 1279 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 257: -#line 1282 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 258: -#line 1284 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 259: -#line 1286 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 260: -#line 1288 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 261: -#line 1290 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 262: -#line 1292 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 263: -#line 1294 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 264: -#line 1296 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); ; - break;} -case 271: -#line 1318 "c-parse.y" -{ emit_line_note (input_filename, lineno); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - ; - break;} -case 273: -#line 1331 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids label declarations"); ; - break;} -case 276: -#line 1342 "c-parse.y" -{ tree link; - for (link = yyvsp[-1].ttype; link; link = TREE_CHAIN (link)) - { - tree label = shadow_label (TREE_VALUE (link)); - C_DECLARED_LABEL_FLAG (label) = 1; - declare_nonlocal_label (label); - } - ; - break;} -case 277: -#line 1356 "c-parse.y" -{; - break;} -case 279: -#line 1361 "c-parse.y" -{ yyval.ttype = convert (void_type_node, integer_zero_node); ; - break;} -case 280: -#line 1363 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), 1, 0); - yyval.ttype = poplevel (1, 1, 0); - if (yychar == CONSTANT || yychar == STRING) - pop_momentary_nofree (); - else - pop_momentary (); ; - break;} -case 281: -#line 1371 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), kept_level_p (), 0); - yyval.ttype = poplevel (kept_level_p (), 0, 0); - if (yychar == CONSTANT || yychar == STRING) - pop_momentary_nofree (); - else - pop_momentary (); ; - break;} -case 282: -#line 1379 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), kept_level_p (), 0); - yyval.ttype = poplevel (kept_level_p (), 0, 0); - if (yychar == CONSTANT || yychar == STRING) - pop_momentary_nofree (); - else - pop_momentary (); ; - break;} -case 285: -#line 1399 "c-parse.y" -{ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - expand_start_cond (truthvalue_conversion (yyvsp[-1].ttype), 0); - yyval.itype = stmt_count; - if_stmt_file = yyvsp[-5].filename; - if_stmt_line = yyvsp[-4].lineno; - position_after_white_space (); ; - break;} -case 286: -#line 1412 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno); - /* See comment in `while' alternative, above. */ - emit_nop (); - expand_start_loop_continue_elsewhere (1); - position_after_white_space (); ; - break;} -case 287: -#line 1419 "c-parse.y" -{ expand_loop_continue_here (); ; - break;} -case 288: -#line 1423 "c-parse.y" -{ yyval.filename = input_filename; ; - break;} -case 289: -#line 1427 "c-parse.y" -{ yyval.lineno = lineno; ; - break;} -case 290: -#line 1432 "c-parse.y" -{ ; - break;} -case 291: -#line 1437 "c-parse.y" -{ ; - break;} -case 292: -#line 1442 "c-parse.y" -{ ; - break;} -case 294: -#line 1448 "c-parse.y" -{ int next; - position_after_white_space (); - next = getc (finput); - ungetc (next, finput); - if (pedantic && next == '}') - pedwarn ("ANSI C forbids label at end of compound statement"); - ; - break;} -case 295: -#line 1460 "c-parse.y" -{ stmt_count++; ; - break;} -case 297: -#line 1463 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); -/* It appears that this should not be done--that a non-lvalue array - shouldn't get an error if the value isn't used. - Section 3.2.2.1 says that an array lvalue gets converted to a pointer - if it appears as a top-level expression, - but says nothing about non-lvalue arrays. */ -#if 0 - /* Call default_conversion to get an error - on referring to a register array if pedantic. */ - if (TREE_CODE (TREE_TYPE (yyvsp[-1].ttype)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (yyvsp[-1].ttype)) == FUNCTION_TYPE) - yyvsp[-1].ttype = default_conversion (yyvsp[-1].ttype); -#endif - iterator_expand (yyvsp[-1].ttype); - clear_momentary (); ; - break;} -case 298: -#line 1480 "c-parse.y" -{ expand_start_else (); - yyvsp[-1].itype = stmt_count; - position_after_white_space (); ; - break;} -case 299: -#line 1484 "c-parse.y" -{ expand_end_cond (); - if (extra_warnings && stmt_count == yyvsp[-3].itype) - warning ("empty body in an else-statement"); ; - break;} -case 300: -#line 1488 "c-parse.y" -{ expand_end_cond (); - /* This warning is here instead of in simple_if, because we - do not want a warning if an empty if is followed by an - else statement. Increment stmt_count so we don't - give a second error if this is a nested `if'. */ - if (extra_warnings && stmt_count++ == yyvsp[0].itype) - warning_with_file_and_line (if_stmt_file, if_stmt_line, - "empty body in an if-statement"); ; - break;} -case 301: -#line 1500 "c-parse.y" -{ expand_end_cond (); ; - break;} -case 302: -#line 1502 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno); - /* The emit_nop used to come before emit_line_note, - but that made the nop seem like part of the preceding line. - And that was confusing when the preceding line was - inside of an if statement and was not really executed. - I think it ought to work to put the nop after the line number. - We will see. --rms, July 15, 1991. */ - emit_nop (); ; - break;} -case 303: -#line 1512 "c-parse.y" -{ /* Don't start the loop till we have succeeded - in parsing the end test. This is to make sure - that we end every loop we start. */ - expand_start_loop (1); - emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-1].ttype)); - position_after_white_space (); ; - break;} -case 304: -#line 1521 "c-parse.y" -{ expand_end_loop (); ; - break;} -case 305: -#line 1524 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-2].ttype)); - expand_end_loop (); - clear_momentary (); ; - break;} -case 306: -#line 1531 "c-parse.y" -{ expand_end_loop (); - clear_momentary (); ; - break;} -case 307: -#line 1535 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - /* See comment in `while' alternative, above. */ - emit_nop (); - if (yyvsp[-1].ttype) c_expand_expr_stmt (yyvsp[-1].ttype); - /* Next step is to call expand_start_loop_continue_elsewhere, - but wait till after we parse the entire for (...). - Otherwise, invalid input might cause us to call that - fn without calling expand_end_loop. */ - ; - break;} -case 308: -#line 1547 "c-parse.y" -{ yyvsp[0].lineno = lineno; - yyval.filename = input_filename; ; - break;} -case 309: -#line 1550 "c-parse.y" -{ - /* Start the loop. Doing this after parsing - all the expressions ensures we will end the loop. */ - expand_start_loop_continue_elsewhere (1); - /* Emit the end-test, with a line number. */ - emit_line_note (yyvsp[-2].filename, yyvsp[-3].lineno); - if (yyvsp[-4].ttype) - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-4].ttype)); - /* Don't let the tree nodes for $9 be discarded by - clear_momentary during the parsing of the next stmt. */ - push_momentary (); - yyvsp[-3].lineno = lineno; - yyvsp[-2].filename = input_filename; - position_after_white_space (); ; - break;} -case 310: -#line 1566 "c-parse.y" -{ /* Emit the increment expression, with a line number. */ - emit_line_note (yyvsp[-4].filename, yyvsp[-5].lineno); - expand_loop_continue_here (); - if (yyvsp[-3].ttype) - c_expand_expr_stmt (yyvsp[-3].ttype); - if (yychar == CONSTANT || yychar == STRING) - pop_momentary_nofree (); - else - pop_momentary (); - expand_end_loop (); ; - break;} -case 311: -#line 1577 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - c_expand_start_case (yyvsp[-1].ttype); - /* Don't let the tree nodes for $3 be discarded by - clear_momentary during the parsing of the next stmt. */ - push_momentary (); - position_after_white_space (); ; - break;} -case 312: -#line 1585 "c-parse.y" -{ expand_end_case (yyvsp[-3].ttype); - if (yychar == CONSTANT || yychar == STRING) - pop_momentary_nofree (); - else - pop_momentary (); ; - break;} -case 313: -#line 1591 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - if ( ! expand_exit_something ()) - error ("break statement not within loop or switch"); ; - break;} -case 314: -#line 1596 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - if (! expand_continue_loop (NULL_PTR)) - error ("continue statement not within a loop"); ; - break;} -case 315: -#line 1601 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - c_expand_return (NULL_TREE); ; - break;} -case 316: -#line 1605 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno); - c_expand_return (yyvsp[-1].ttype); ; - break;} -case 317: -#line 1609 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-7].filename, yyvsp[-6].lineno); - STRIP_NOPS (yyvsp[-2].ttype); - if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST) - || TREE_CODE (yyvsp[-2].ttype) == STRING_CST) - expand_asm (yyvsp[-2].ttype); - else - error ("argument of `asm' is not a constant string"); ; - break;} -case 318: -#line 1620 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-9].filename, yyvsp[-8].lineno); - c_expand_asm_operands (yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, NULL_TREE, - yyvsp[-6].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 319: -#line 1627 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-11].filename, yyvsp[-10].lineno); - c_expand_asm_operands (yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, - yyvsp[-8].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 320: -#line 1635 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-13].filename, yyvsp[-12].lineno); - c_expand_asm_operands (yyvsp[-8].ttype, yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, - yyvsp[-10].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 321: -#line 1641 "c-parse.y" -{ tree decl; - stmt_count++; - emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno); - decl = lookup_label (yyvsp[-1].ttype); - if (decl != 0) - { - TREE_USED (decl) = 1; - expand_goto (decl); - } - ; - break;} -case 322: -#line 1652 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - expand_computed_goto (convert (ptr_type_node, yyvsp[-1].ttype)); ; - break;} -case 325: -#line 1665 "c-parse.y" -{ - /* The value returned by this action is */ - /* 1 if everything is OK */ - /* 0 in case of error or already bound iterator */ - - yyval.itype = 0; - if (TREE_CODE (yyvsp[-1].ttype) != VAR_DECL) - error ("invalid `for (ITERATOR)' syntax"); - else if (! ITERATOR_P (yyvsp[-1].ttype)) - error ("`%s' is not an iterator", - IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype))); - else if (ITERATOR_BOUND_P (yyvsp[-1].ttype)) - error ("`for (%s)' inside expansion of same iterator", - IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype))); - else - { - yyval.itype = 1; - iterator_for_loop_start (yyvsp[-1].ttype); - } - ; - break;} -case 326: -#line 1686 "c-parse.y" -{ - if (yyvsp[-1].itype) - iterator_for_loop_end (yyvsp[-3].ttype); - ; - break;} -case 327: -#line 1721 "c-parse.y" -{ register tree value = check_case_value (yyvsp[-1].ttype); - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - stmt_count++; - - if (value != error_mark_node) - { - tree duplicate; - int success = pushcase (value, convert_and_check, - label, &duplicate); - if (success == 1) - error ("case label not within a switch statement"); - else if (success == 2) - { - error ("duplicate case value"); - error_with_decl (duplicate, "this is the first entry for that value"); - } - else if (success == 3) - warning ("case value out of range"); - else if (success == 5) - error ("case label within scope of cleanup or variable array"); - } - position_after_white_space (); ; - break;} -case 328: -#line 1746 "c-parse.y" -{ register tree value1 = check_case_value (yyvsp[-3].ttype); - register tree value2 = check_case_value (yyvsp[-1].ttype); - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - stmt_count++; - - if (value1 != error_mark_node && value2 != error_mark_node) - { - tree duplicate; - int success = pushcase_range (value1, value2, - convert_and_check, label, - &duplicate); - if (success == 1) - error ("case label not within a switch statement"); - else if (success == 2) - { - error ("duplicate case value"); - error_with_decl (duplicate, "this is the first entry for that value"); - } - else if (success == 3) - warning ("case value out of range"); - else if (success == 4) - warning ("empty case range"); - else if (success == 5) - error ("case label within scope of cleanup or variable array"); - } - position_after_white_space (); ; - break;} -case 329: -#line 1775 "c-parse.y" -{ - tree duplicate; - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - int success = pushcase (NULL_TREE, 0, label, &duplicate); - stmt_count++; - if (success == 1) - error ("default label not within a switch statement"); - else if (success == 2) - { - error ("multiple default labels in one switch"); - error_with_decl (duplicate, "this is the first default label"); - } - position_after_white_space (); ; - break;} -case 330: -#line 1790 "c-parse.y" -{ tree label = define_label (input_filename, lineno, yyvsp[-1].ttype); - stmt_count++; - emit_nop (); - if (label) - expand_label (label); - position_after_white_space (); ; - break;} -case 331: -#line 1802 "c-parse.y" -{ emit_line_note (input_filename, lineno); - yyval.ttype = NULL_TREE; ; - break;} -case 332: -#line 1805 "c-parse.y" -{ emit_line_note (input_filename, lineno); ; - break;} -case 333: -#line 1810 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 335: -#line 1817 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 338: -#line 1824 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 339: -#line 1829 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 340: -#line 1834 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), NULL_TREE); ; - break;} -case 341: -#line 1836 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), yyvsp[-2].ttype); ; - break;} -case 342: -#line 1842 "c-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (0); ; - break;} -case 343: -#line 1846 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 345: -#line 1854 "c-parse.y" -{ tree parm; - if (pedantic) - pedwarn ("ANSI C forbids forward parameter declarations"); - /* Mark the forward decls as such. */ - for (parm = getdecls (); parm; parm = TREE_CHAIN (parm)) - TREE_ASM_WRITTEN (parm) = 1; - clear_parm_order (); ; - break;} -case 346: -#line 1862 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 347: -#line 1864 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); ; - break;} -case 348: -#line 1870 "c-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 349: -#line 1872 "c-parse.y" -{ yyval.ttype = get_parm_info (0); - /* Gcc used to allow this as an extension. However, it does - not work for all targets, and thus has been disabled. - Also, since func (...) and func () are indistinguishable, - it caused problems with the code in expand_builtin which - tries to verify that BUILT_IN_NEXT_ARG is being used - correctly. */ - error ("ANSI C requires a named argument before `...'"); - ; - break;} -case 350: -#line 1882 "c-parse.y" -{ yyval.ttype = get_parm_info (1); ; - break;} -case 351: -#line 1884 "c-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 352: -#line 1889 "c-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 353: -#line 1891 "c-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 354: -#line 1898 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 355: -#line 1900 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 356: -#line 1902 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 357: -#line 1904 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 358: -#line 1906 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 359: -#line 1913 "c-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (1); ; - break;} -case 360: -#line 1917 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 362: -#line 1925 "c-parse.y" -{ tree t; - for (t = yyvsp[-1].ttype; t; t = TREE_CHAIN (t)) - if (TREE_VALUE (t) == NULL_TREE) - error ("`...' in old-style identifier list"); - yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 363: -#line 1935 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 364: -#line 1937 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 365: -#line 1943 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 366: -#line 1945 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 480 "/usr/local/lib/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; -} -#line 1948 "c-parse.y" - diff --git a/gnu/usr.bin/cc/cc1/c-pragma.c b/gnu/usr.bin/cc/cc1/c-pragma.c deleted file mode 100644 index cdade3e..0000000 --- a/gnu/usr.bin/cc/cc1/c-pragma.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. - Copyright (C) 1992 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <stdio.h> -#include "config.h" -#include "tree.h" -#include "function.h" -#include "defaults.h" - -#ifdef HANDLE_SYSV_PRAGMA - -/* Support #pragma weak by default if WEAK_ASM_OP and ASM_OUTPUT_DEF - are defined. */ -#if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (ASM_OUTPUT_DEF) -#define HANDLE_PRAGMA_WEAK 1 -#endif - -/* See varasm.c for an identical definition. */ -enum pragma_state -{ - ps_start, - ps_done, - ps_bad, - ps_weak, - ps_name, - ps_equals, - ps_value, - ps_pack, - ps_left, - ps_align, - ps_right -}; - -/* When structure field packing is in effect, this variable is the - number of bits to use as the maximum alignment. When packing is not - in effect, this is zero. */ - -extern int maximum_field_alignment; - -/* File used for outputting assembler code. */ -extern FILE *asm_out_file; - -/* Handle one token of a pragma directive. TOKEN is the - current token, and STRING is its printable form. */ - -void -handle_pragma_token (string, token) - char *string; - tree token; -{ - static enum pragma_state state = ps_start, type; - static char *name; - static char *value; - static int align; - - if (string == 0) - { - if (type == ps_pack) - { - if (state == ps_right) - maximum_field_alignment = align * 8; - else - warning ("malformed `#pragma pack'"); - } - else if (type == ps_weak) - { -#ifdef HANDLE_PRAGMA_WEAK - if (HANDLE_PRAGMA_WEAK) - handle_pragma_weak (state, asm_out_file, name, value); - -#endif /* HANDLE_PRAMA_WEAK */ - } - - type = state = ps_start; - return; - } - - switch (state) - { - case ps_start: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) - { - if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0) - type = state = ps_pack; - else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0) - type = state = ps_weak; - else - type = state = ps_done; - } - else - type = state = ps_done; - break; - - case ps_weak: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) - { - name = IDENTIFIER_POINTER (token); - state = ps_name; - } - else - state = ps_bad; - break; - - case ps_name: - state = (strcmp (string, "=") ? ps_bad : ps_equals); - break; - - case ps_equals: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) - { - value = IDENTIFIER_POINTER (token); - state = ps_value; - } - else - state = ps_bad; - break; - - case ps_value: - state = ps_bad; - break; - - case ps_pack: - if (strcmp (string, "(") == 0) - state = ps_left; - else - state = ps_bad; - break; - - case ps_left: - if (token && TREE_CODE (token) == INTEGER_CST - && TREE_INT_CST_HIGH (token) == 0) - switch (TREE_INT_CST_LOW (token)) - { - case 1: - case 2: - case 4: - align = TREE_INT_CST_LOW (token); - state = ps_align; - break; - - default: - state = ps_bad; - } - else if (! token && strcmp (string, ")") == 0) - { - align = 0; - state = ps_right; - } - else - state = ps_bad; - break; - - case ps_align: - if (strcmp (string, ")") == 0) - state = ps_right; - else - state = ps_bad; - break; - - case ps_right: - state = ps_bad; - break; - - case ps_bad: - case ps_done: - break; - - default: - abort (); - } -} -#endif /* HANDLE_SYSV_PRAGMA */ diff --git a/gnu/usr.bin/cc/cc1/c-typeck.c b/gnu/usr.bin/cc/cc1/c-typeck.c deleted file mode 100644 index edb9ae4..0000000 --- a/gnu/usr.bin/cc/cc1/c-typeck.c +++ /dev/null @@ -1,6414 +0,0 @@ -/* Build expressions with type checking for C compiler. - Copyright (C) 1987, 88, 91, 92, 93, 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* This file is part of the C front end. - It contains routines to build C expressions given their operands, - including computing the types of the result, C-specific error checks, - and some optimization. - - There are also routines to build RETURN_STMT nodes and CASE_STMT nodes, - and to process initializations in declarations (since they work - like a strange sort of assignment). */ - -#include "config.h" -#include <stdio.h> -#include "tree.h" -#include "c-tree.h" -#include "flags.h" - -/* Nonzero if we've already printed a "missing braces around initializer" - message within this initializer. */ -static int missing_braces_mentioned; - -extern char *index (); -extern char *rindex (); - -static tree quality_type PROTO((tree, tree)); -static int comp_target_types PROTO((tree, tree)); -static int function_types_compatible_p PROTO((tree, tree)); -static int type_lists_compatible_p PROTO((tree, tree)); -static int self_promoting_type_p PROTO((tree)); -static tree decl_constant_value PROTO((tree)); -static tree lookup_field PROTO((tree, tree, tree *)); -static tree convert_arguments PROTO((tree, tree, tree, tree)); -static tree pointer_int_sum PROTO((enum tree_code, tree, tree)); -static tree pointer_diff PROTO((tree, tree)); -static tree unary_complex_lvalue PROTO((enum tree_code, tree)); -static void pedantic_lvalue_warning PROTO((enum tree_code)); -static tree internal_build_compound_expr PROTO((tree, int)); -static tree convert_for_assignment PROTO((tree, tree, char *, tree, - tree, int)); -static void warn_for_assignment PROTO((char *, char *, tree, int)); -static tree valid_compound_expr_initializer PROTO((tree, tree)); -static void push_string PROTO((char *)); -static void push_member_name PROTO((tree)); -static void push_array_bounds PROTO((int)); -static int spelling_length PROTO((void)); -static char *print_spelling PROTO((char *)); -static char *get_spelling PROTO((char *)); -static void warning_init PROTO((char *, char *, - char *)); -static tree digest_init PROTO((tree, tree, int, int)); -static void check_init_type_bitfields PROTO((tree)); -static void output_init_element PROTO((tree, tree, tree, int)); -static void output_pending_init_elements PROTO((int)); - -/* Do `exp = require_complete_type (exp);' to make sure exp - does not have an incomplete type. (That includes void types.) */ - -tree -require_complete_type (value) - tree value; -{ - tree type = TREE_TYPE (value); - - /* First, detect a valid value with a complete type. */ - if (TYPE_SIZE (type) != 0 - && type != void_type_node) - return value; - - incomplete_type_error (value, type); - return error_mark_node; -} - -/* Print an error message for invalid use of an incomplete type. - VALUE is the expression that was used (or 0 if that isn't known) - and TYPE is the type that was invalid. */ - -void -incomplete_type_error (value, type) - tree value; - tree type; -{ - char *errmsg; - - /* Avoid duplicate error message. */ - if (TREE_CODE (type) == ERROR_MARK) - return; - - if (value != 0 && (TREE_CODE (value) == VAR_DECL - || TREE_CODE (value) == PARM_DECL)) - error ("`%s' has an incomplete type", - IDENTIFIER_POINTER (DECL_NAME (value))); - else - { - retry: - /* We must print an error message. Be clever about what it says. */ - - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - errmsg = "invalid use of undefined type `struct %s'"; - break; - - case UNION_TYPE: - errmsg = "invalid use of undefined type `union %s'"; - break; - - case ENUMERAL_TYPE: - errmsg = "invalid use of undefined type `enum %s'"; - break; - - case VOID_TYPE: - error ("invalid use of void expression"); - return; - - case ARRAY_TYPE: - if (TYPE_DOMAIN (type)) - { - type = TREE_TYPE (type); - goto retry; - } - error ("invalid use of array with unspecified bounds"); - return; - - default: - abort (); - } - - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); - else - /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error ("invalid use of incomplete typedef `%s'", - IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); - } -} - -/* Return a variant of TYPE which has all the type qualifiers of LIKE - as well as those of TYPE. */ - -static tree -qualify_type (type, like) - tree type, like; -{ - int constflag = TYPE_READONLY (type) || TYPE_READONLY (like); - int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like); - return c_build_type_variant (type, constflag, volflag); -} - -/* Return the common type of two types. - We assume that comptypes has already been done and returned 1; - if that isn't so, this may crash. In particular, we assume that qualifiers - match. - - This is the type for the result of most arithmetic operations - if the operands have the given two types. */ - -tree -common_type (t1, t2) - tree t1, t2; -{ - register enum tree_code code1; - register enum tree_code code2; - tree attributes; - - /* Save time if the two types are the same. */ - - if (t1 == t2) return t1; - - /* If one type is nonsense, use the other. */ - if (t1 == error_mark_node) - return t2; - if (t2 == error_mark_node) - return t1; - - /* Merge the attributes */ - - { register tree a1, a2; - a1 = TYPE_ATTRIBUTES (t1); - a2 = TYPE_ATTRIBUTES (t2); - - /* Either one unset? Take the set one. */ - - if (!(attributes = a1)) - attributes = a2; - - /* One that completely contains the other? Take it. */ - - else if (a2 && !attribute_list_contained (a1, a2)) - if (attribute_list_contained (a2, a1)) - attributes = a2; - else - { - /* Pick the longest list, and hang on the other - list. */ - - if (list_length (a1) < list_length (a2)) - attributes = a2, a2 = a1; - - for (; a2; a2 = TREE_CHAIN (a2)) - if (!value_member (attributes, a2)) - { - a1 = copy_node (a2); - TREE_CHAIN (a1) = attributes; - attributes = a1; - } - } - } - - /* Treat an enum type as the unsigned integer type of the same width. */ - - if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), 1); - if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), 1); - - code1 = TREE_CODE (t1); - code2 = TREE_CODE (t2); - - /* If one type is complex, form the common type of the non-complex - components, then make that complex. Use T1 or T2 if it is the - required type. */ - if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) - { - tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; - tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; - tree subtype = common_type (subtype1, subtype2); - - if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) - return build_type_attribute_variant (t1, attributes); - else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) - return build_type_attribute_variant (t2, attributes); - else - return build_type_attribute_variant (build_complex_type (subtype), - attributes); - } - - switch (code1) - { - case INTEGER_TYPE: - case REAL_TYPE: - /* If only one is real, use it as the result. */ - - if (code1 == REAL_TYPE && code2 != REAL_TYPE) - return build_type_attribute_variant (t1, attributes); - - if (code2 == REAL_TYPE && code1 != REAL_TYPE) - return build_type_attribute_variant (t2, attributes); - - /* Both real or both integers; use the one with greater precision. */ - - if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) - return build_type_attribute_variant (t1, attributes); - else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) - return build_type_attribute_variant (t2, attributes); - - /* Same precision. Prefer longs to ints even when same size. */ - - if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node - || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node) - return build_type_attribute_variant (long_unsigned_type_node, - attributes); - - if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node - || TYPE_MAIN_VARIANT (t2) == long_integer_type_node) - { - /* But preserve unsignedness from the other type, - since long cannot hold all the values of an unsigned int. */ - if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2)) - t1 = long_unsigned_type_node; - else - t1 = long_integer_type_node; - return build_type_attribute_variant (t1, attributes); - } - - /* Otherwise prefer the unsigned one. */ - - if (TREE_UNSIGNED (t1)) - return build_type_attribute_variant (t1, attributes); - else - return build_type_attribute_variant (t2, attributes); - - case POINTER_TYPE: - /* For two pointers, do this recursively on the target type, - and combine the qualifiers of the two types' targets. */ - /* This code was turned off; I don't know why. - But ANSI C specifies doing this with the qualifiers. - So I turned it on again. */ - { - tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)), - TYPE_MAIN_VARIANT (TREE_TYPE (t2))); - int constp - = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2)); - int volatilep - = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2)); - t1 = build_pointer_type (c_build_type_variant (target, constp, - volatilep)); - return build_type_attribute_variant (t1, attributes); - } -#if 0 - t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2))); - return build_type_attribute_variant (t1, attributes); -#endif - - case ARRAY_TYPE: - { - tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); - /* Save space: see if the result is identical to one of the args. */ - if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)) - return build_type_attribute_variant (t1, attributes); - if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)) - return build_type_attribute_variant (t2, attributes); - /* Merge the element types, and have a size if either arg has one. */ - t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); - return build_type_attribute_variant (t1, attributes); - } - - case FUNCTION_TYPE: - /* Function types: prefer the one that specified arg types. - If both do, merge the arg types. Also merge the return types. */ - { - tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); - tree p1 = TYPE_ARG_TYPES (t1); - tree p2 = TYPE_ARG_TYPES (t2); - int len; - tree newargs, n; - int i; - - /* Save space: see if the result is identical to one of the args. */ - if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2)) - return build_type_attribute_variant (t1, attributes); - if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1)) - return build_type_attribute_variant (t2, attributes); - - /* Simple way if one arg fails to specify argument types. */ - if (TYPE_ARG_TYPES (t1) == 0) - { - t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2)); - return build_type_attribute_variant (t1, attributes); - } - if (TYPE_ARG_TYPES (t2) == 0) - { - t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1)); - return build_type_attribute_variant (t1, attributes); - } - - /* If both args specify argument types, we must merge the two - lists, argument by argument. */ - - len = list_length (p1); - newargs = 0; - - for (i = 0; i < len; i++) - newargs = tree_cons (NULL_TREE, NULL_TREE, newargs); - - n = newargs; - - for (; p1; - p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n)) - { - /* A null type means arg type is not specified. - Take whatever the other function type has. */ - if (TREE_VALUE (p1) == 0) - { - TREE_VALUE (n) = TREE_VALUE (p2); - goto parm_done; - } - if (TREE_VALUE (p2) == 0) - { - TREE_VALUE (n) = TREE_VALUE (p1); - goto parm_done; - } - - /* Given wait (union {union wait *u; int *i} *) - and wait (union wait *), - prefer union wait * as type of parm. */ - if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE - && TREE_VALUE (p1) != TREE_VALUE (p2)) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (p1)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2))) - { - TREE_VALUE (n) = TREE_VALUE (p2); - if (pedantic) - pedwarn ("function types not truly compatible in ANSI C"); - goto parm_done; - } - } - if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE - && TREE_VALUE (p2) != TREE_VALUE (p1)) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (p2)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1))) - { - TREE_VALUE (n) = TREE_VALUE (p1); - if (pedantic) - pedwarn ("function types not truly compatible in ANSI C"); - goto parm_done; - } - } - TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2)); - parm_done: ; - } - - t1 = build_function_type (valtype, newargs); - /* ... falls through ... */ - } - - default: - return build_type_attribute_variant (t1, attributes); - } - -} - -/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment - or various other operations. Return 2 if they are compatible - but a warning may be needed if you use them together. */ - -int -comptypes (type1, type2) - tree type1, type2; -{ - register tree t1 = type1; - register tree t2 = type2; - int attrval, val; - - /* Suppress errors caused by previously reported errors. */ - - if (t1 == t2 || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK) - return 1; - - /* Treat an enum type as the integer type of the same width and - signedness. */ - - if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1)); - if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2)); - - if (t1 == t2) - return 1; - - /* Different classes of types can't be compatible. */ - - if (TREE_CODE (t1) != TREE_CODE (t2)) return 0; - - /* Qualifiers must match. */ - - if (TYPE_READONLY (t1) != TYPE_READONLY (t2)) - return 0; - if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) - return 0; - - /* Allow for two different type nodes which have essentially the same - definition. Note that we already checked for equality of the type - type qualifiers (just above). */ - - if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) - return 1; - -#ifndef COMP_TYPE_ATTRIBUTES -#define COMP_TYPE_ATTRIBUTES(t1,t2) 1 -#endif - - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2))) - return 0; - - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - val = 0; - - switch (TREE_CODE (t1)) - { - case POINTER_TYPE: - val = (TREE_TYPE (t1) == TREE_TYPE (t2) - ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); - break; - - case FUNCTION_TYPE: - val = function_types_compatible_p (t1, t2); - break; - - case ARRAY_TYPE: - { - tree d1 = TYPE_DOMAIN (t1); - tree d2 = TYPE_DOMAIN (t2); - val = 1; - - /* Target types must match incl. qualifiers. */ - if (TREE_TYPE (t1) != TREE_TYPE (t2) - && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))) - return 0; - - /* Sizes must match unless one is missing or variable. */ - if (d1 == 0 || d2 == 0 || d1 == d2 - || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST) - break; - - if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1)) - == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2))) - && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1)) - == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2))) - && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1)) - == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2))) - && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1)) - == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2))))) - val = 0; - break; - } - - case RECORD_TYPE: - if (maybe_objc_comptypes (t1, t2, 0) == 1) - val = 1; - break; - } - return attrval == 2 && val == 1 ? 2 : val; -} - -/* Return 1 if TTL and TTR are pointers to types that are equivalent, - ignoring their qualifiers. */ - -static int -comp_target_types (ttl, ttr) - tree ttl, ttr; -{ - int val; - - /* Give maybe_objc_comptypes a crack at letting these types through. */ - if (val = maybe_objc_comptypes (ttl, ttr, 1) >= 0) - return val; - - val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)), - TYPE_MAIN_VARIANT (TREE_TYPE (ttr))); - - if (val == 2 && pedantic) - pedwarn ("types are not quite compatible"); - return val; -} - -/* Subroutines of `comptypes'. */ - -/* Return 1 if two function types F1 and F2 are compatible. - If either type specifies no argument types, - the other must specify a fixed number of self-promoting arg types. - Otherwise, if one type specifies only the number of arguments, - the other must specify that number of self-promoting arg types. - Otherwise, the argument types must match. */ - -static int -function_types_compatible_p (f1, f2) - tree f1, f2; -{ - tree args1, args2; - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - int val1; - - if (!(TREE_TYPE (f1) == TREE_TYPE (f2) - || (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2))))) - return 0; - - args1 = TYPE_ARG_TYPES (f1); - args2 = TYPE_ARG_TYPES (f2); - - /* An unspecified parmlist matches any specified parmlist - whose argument types don't need default promotions. */ - - if (args1 == 0) - { - if (!self_promoting_args_p (args2)) - return 0; - /* If one of these types comes from a non-prototype fn definition, - compare that with the other type's arglist. - If they don't match, ask for a warning (but no error). */ - if (TYPE_ACTUAL_ARG_TYPES (f1) - && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1))) - val = 2; - return val; - } - if (args2 == 0) - { - if (!self_promoting_args_p (args1)) - return 0; - if (TYPE_ACTUAL_ARG_TYPES (f2) - && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2))) - val = 2; - return val; - } - - /* Both types have argument lists: compare them and propagate results. */ - val1 = type_lists_compatible_p (args1, args2); - return val1 != 1 ? val1 : val; -} - -/* Check two lists of types for compatibility, - returning 0 for incompatible, 1 for compatible, - or 2 for compatible with warning. */ - -static int -type_lists_compatible_p (args1, args2) - tree args1, args2; -{ - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - int newval = 0; - - while (1) - { - if (args1 == 0 && args2 == 0) - return val; - /* If one list is shorter than the other, - they fail to match. */ - if (args1 == 0 || args2 == 0) - return 0; - /* A null pointer instead of a type - means there is supposed to be an argument - but nothing is specified about what type it has. - So match anything that self-promotes. */ - if (TREE_VALUE (args1) == 0) - { - if (! self_promoting_type_p (TREE_VALUE (args2))) - return 0; - } - else if (TREE_VALUE (args2) == 0) - { - if (! self_promoting_type_p (TREE_VALUE (args1))) - return 0; - } - else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2)))) - { - /* Allow wait (union {union wait *u; int *i} *) - and wait (union wait *) to be compatible. */ - if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE - && (TYPE_NAME (TREE_VALUE (args1)) == 0 - || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1))) - && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST - && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)), - TYPE_SIZE (TREE_VALUE (args2)))) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (args1)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2))) - break; - if (memb == 0) - return 0; - } - else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE - && (TYPE_NAME (TREE_VALUE (args2)) == 0 - || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2))) - && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST - && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)), - TYPE_SIZE (TREE_VALUE (args1)))) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (args2)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1))) - break; - if (memb == 0) - return 0; - } - else - return 0; - } - - /* comptypes said ok, but record if it said to warn. */ - if (newval > val) - val = newval; - - args1 = TREE_CHAIN (args1); - args2 = TREE_CHAIN (args2); - } -} - -/* Return 1 if PARMS specifies a fixed number of parameters - and none of their types is affected by default promotions. */ - -int -self_promoting_args_p (parms) - tree parms; -{ - register tree t; - for (t = parms; t; t = TREE_CHAIN (t)) - { - register tree type = TREE_VALUE (t); - - if (TREE_CHAIN (t) == 0 && type != void_type_node) - return 0; - - if (type == 0) - return 0; - - if (TYPE_MAIN_VARIANT (type) == float_type_node) - return 0; - - if (C_PROMOTING_INTEGER_TYPE_P (type)) - return 0; - } - return 1; -} - -/* Return 1 if TYPE is not affected by default promotions. */ - -static int -self_promoting_type_p (type) - tree type; -{ - if (TYPE_MAIN_VARIANT (type) == float_type_node) - return 0; - - if (C_PROMOTING_INTEGER_TYPE_P (type)) - return 0; - - return 1; -} - -/* Return an unsigned type the same as TYPE in other respects. */ - -tree -unsigned_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - if (type1 == signed_char_type_node || type1 == char_type_node) - return unsigned_char_type_node; - if (type1 == integer_type_node) - return unsigned_type_node; - if (type1 == short_integer_type_node) - return short_unsigned_type_node; - if (type1 == long_integer_type_node) - return long_unsigned_type_node; - if (type1 == long_long_integer_type_node) - return long_long_unsigned_type_node; - return type; -} - -/* Return a signed type the same as TYPE in other respects. */ - -tree -signed_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - if (type1 == unsigned_char_type_node || type1 == char_type_node) - return signed_char_type_node; - if (type1 == unsigned_type_node) - return integer_type_node; - if (type1 == short_unsigned_type_node) - return short_integer_type_node; - if (type1 == long_unsigned_type_node) - return long_integer_type_node; - if (type1 == long_long_unsigned_type_node) - return long_long_integer_type_node; - return type; -} - -/* Return a type the same as TYPE except unsigned or - signed according to UNSIGNEDP. */ - -tree -signed_or_unsigned_type (unsignedp, type) - int unsignedp; - tree type; -{ - if (! INTEGRAL_TYPE_P (type)) - return type; - if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - return type; -} - -/* Compute the value of the `sizeof' operator. */ - -tree -c_sizeof (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (code == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("sizeof applied to a function type"); - return size_int (1); - } - if (code == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("sizeof applied to a void type"); - return size_int (1); - } - if (code == ERROR_MARK) - return size_int (1); - if (TYPE_SIZE (type) == 0) - { - error ("sizeof applied to an incomplete type"); - return size_int (0); - } - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - /* size_binop does not put the constant in range, so do it now. */ - if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0)) - TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1; - return t; -} - -tree -c_sizeof_nowarn (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (code == FUNCTION_TYPE - || code == VOID_TYPE - || code == ERROR_MARK) - return size_int (1); - if (TYPE_SIZE (type) == 0) - return size_int (0); - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - force_fit_type (t, 0); - return t; -} - -/* Compute the size to increment a pointer by. */ - -tree -c_size_in_bytes (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (code == FUNCTION_TYPE) - return size_int (1); - if (code == VOID_TYPE) - return size_int (1); - if (code == ERROR_MARK) - return size_int (1); - if (TYPE_SIZE (type) == 0) - { - error ("arithmetic on pointer to an incomplete type"); - return size_int (1); - } - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - force_fit_type (t, 0); - return t; -} - -/* Implement the __alignof keyword: Return the minimum required - alignment of TYPE, measured in bytes. */ - -tree -c_alignof (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - - if (code == FUNCTION_TYPE) - return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); - - if (code == VOID_TYPE || code == ERROR_MARK) - return size_int (1); - - return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT); -} - -/* Implement the __alignof keyword: Return the minimum required - alignment of EXPR, measured in bytes. For VAR_DECL's and - FIELD_DECL's return DECL_ALIGN (which can be set from an - "aligned" __attribute__ specification). */ - -tree -c_alignof_expr (expr) - tree expr; -{ - if (TREE_CODE (expr) == VAR_DECL) - return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT); - - if (TREE_CODE (expr) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) - { - error ("`__alignof' applied to a bit-field"); - return size_int (1); - } - else if (TREE_CODE (expr) == COMPONENT_REF - && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL) - return size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT); - - if (TREE_CODE (expr) == INDIRECT_REF) - { - tree t = TREE_OPERAND (expr, 0); - tree best = t; - int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - - while (TREE_CODE (t) == NOP_EXPR - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) - { - int thisalign; - - t = TREE_OPERAND (t, 0); - thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - if (thisalign > bestalign) - best = t, bestalign = thisalign; - } - return c_alignof (TREE_TYPE (TREE_TYPE (best))); - } - else - return c_alignof (TREE_TYPE (expr)); -} -/* Return either DECL or its known constant value (if it has one). */ - -static tree -decl_constant_value (decl) - tree decl; -{ - if (! TREE_PUBLIC (decl) - /* Don't change a variable array bound or initial value to a constant - in a place where a variable is invalid. */ - && current_function_decl != 0 - && ! pedantic - && ! TREE_THIS_VOLATILE (decl) - && TREE_READONLY (decl) && ! ITERATOR_P (decl) - && DECL_INITIAL (decl) != 0 - && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK - /* This is invalid if initial value is not constant. - If it has either a function call, a memory reference, - or a variable, then re-evaluating it could give different results. */ - && TREE_CONSTANT (DECL_INITIAL (decl)) - /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR - && DECL_MODE (decl) != BLKmode) - return DECL_INITIAL (decl); - return decl; -} - -/* Perform default promotions for C data used in expressions. - Arrays and functions are converted to pointers; - enumeral types or short or char, to int. - In addition, manifest constants symbols are replaced by their values. */ - -tree -default_conversion (exp) - tree exp; -{ - register tree type = TREE_TYPE (exp); - register enum tree_code code = TREE_CODE (type); - - /* Constants can be used directly unless they're not loadable. */ - if (TREE_CODE (exp) == CONST_DECL) - exp = DECL_INITIAL (exp); - - /* Replace a nonvolatile const static variable with its value unless - it is an array, in which case we must be sure that taking the - address of the array produces consistent results. */ - else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE) - { - exp = decl_constant_value (exp); - type = TREE_TYPE (exp); - } - - /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as - an lvalue. */ - /* Do not use STRIP_NOPS here! It will remove conversions from pointer - to integer and cause infinite recursion. */ - while (TREE_CODE (exp) == NON_LVALUE_EXPR - || (TREE_CODE (exp) == NOP_EXPR - && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp))) - exp = TREE_OPERAND (exp, 0); - - /* Normally convert enums to int, - but convert wide enums to something wider. */ - if (code == ENUMERAL_TYPE) - { - 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))); - return convert (type, exp); - } - - if (C_PROMOTING_INTEGER_TYPE_P (type)) - { - /* Traditionally, unsignedness is preserved in default promotions. - Also preserve unsignedness if not really getting any wider. */ - if (TREE_UNSIGNED (type) - && (flag_traditional - || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) - return convert (unsigned_type_node, exp); - return convert (integer_type_node, exp); - } - if (flag_traditional && !flag_allow_single_precision - && TYPE_MAIN_VARIANT (type) == float_type_node) - return convert (double_type_node, exp); - if (code == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - if (code == FUNCTION_TYPE) - { - return build_unary_op (ADDR_EXPR, exp, 0); - } - if (code == ARRAY_TYPE) - { - register tree adr; - tree restype = TREE_TYPE (type); - tree ptrtype; - int constp = 0; - int volatilep = 0; - - if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r' - || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd') - { - constp = TREE_READONLY (exp); - volatilep = TREE_THIS_VOLATILE (exp); - } - - if (TYPE_READONLY (type) || TYPE_VOLATILE (type) - || constp || volatilep) - restype = c_build_type_variant (restype, - TYPE_READONLY (type) || constp, - TYPE_VOLATILE (type) || volatilep); - - if (TREE_CODE (exp) == INDIRECT_REF) - return convert (TYPE_POINTER_TO (restype), - TREE_OPERAND (exp, 0)); - - if (TREE_CODE (exp) == COMPOUND_EXPR) - { - tree op1 = default_conversion (TREE_OPERAND (exp, 1)); - return build (COMPOUND_EXPR, TREE_TYPE (op1), - TREE_OPERAND (exp, 0), op1); - } - - if (!lvalue_p (exp) - && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp))) - { - error ("invalid use of non-lvalue array"); - return error_mark_node; - } - - ptrtype = build_pointer_type (restype); - - if (TREE_CODE (exp) == VAR_DECL) - { - /* ??? This is not really quite correct - in that the type of the operand of ADDR_EXPR - is not the target type of the type of the ADDR_EXPR itself. - Question is, can this lossage be avoided? */ - adr = build1 (ADDR_EXPR, ptrtype, exp); - if (mark_addressable (exp) == 0) - return error_mark_node; - TREE_CONSTANT (adr) = staticp (exp); - TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */ - return adr; - } - /* This way is better for a COMPONENT_REF since it can - simplify the offset for a component. */ - adr = build_unary_op (ADDR_EXPR, exp, 1); - return convert (ptrtype, adr); - } - return exp; -} - -/* Look up component name in the structure type definition. - - If this component name is found indirectly within an anonymous union, - store in *INDIRECT the component which directly contains - that anonymous union. Otherwise, set *INDIRECT to 0. */ - -static tree -lookup_field (type, component, indirect) - tree type, component; - tree *indirect; -{ - tree field; - - /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers - to the field elements. Use a binary search on this array to quickly - find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC - will always be set for structures which have many elements. */ - - if (TYPE_LANG_SPECIFIC (type)) - { - int bot, top, half; - tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0]; - - field = TYPE_FIELDS (type); - bot = 0; - top = TYPE_LANG_SPECIFIC (type)->len; - while (top - bot > 1) - { - HOST_WIDE_INT cmp; - - half = (top - bot + 1) >> 1; - field = field_array[bot+half]; - - if (DECL_NAME (field) == NULL_TREE) - { - /* Step through all anon unions in linear fashion. */ - while (DECL_NAME (field_array[bot]) == NULL_TREE) - { - tree anon, junk; - - field = field_array[bot++]; - anon = lookup_field (TREE_TYPE (field), component, &junk); - if (anon != NULL_TREE) - { - *indirect = field; - return anon; - } - } - - /* Entire record is only anon unions. */ - if (bot > top) - return NULL_TREE; - - /* Restart the binary search, with new lower bound. */ - continue; - } - - cmp = (HOST_WIDE_INT) DECL_NAME (field) - (HOST_WIDE_INT) component; - if (cmp == 0) - break; - if (cmp < 0) - bot += half; - else - top = bot + half; - } - - if (DECL_NAME (field_array[bot]) == component) - field = field_array[bot]; - else if (DECL_NAME (field) != component) - field = 0; - } - else - { - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) - { - if (DECL_NAME (field) == NULL_TREE) - { - tree junk; - tree anon = lookup_field (TREE_TYPE (field), component, &junk); - if (anon != NULL_TREE) - { - *indirect = field; - return anon; - } - } - - if (DECL_NAME (field) == component) - break; - } - } - - *indirect = NULL_TREE; - return field; -} - -/* Make an expression to refer to the COMPONENT field of - structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. */ - -tree -build_component_ref (datum, component) - tree datum, component; -{ - register tree type = TREE_TYPE (datum); - register enum tree_code code = TREE_CODE (type); - register tree field = NULL; - register tree ref; - - /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it - unless we are not to support things not strictly ANSI. */ - switch (TREE_CODE (datum)) - { - case COMPOUND_EXPR: - { - tree value = build_component_ref (TREE_OPERAND (datum, 1), component); - return build (COMPOUND_EXPR, TREE_TYPE (value), - TREE_OPERAND (datum, 0), value); - } - case COND_EXPR: - return build_conditional_expr - (TREE_OPERAND (datum, 0), - build_component_ref (TREE_OPERAND (datum, 1), component), - build_component_ref (TREE_OPERAND (datum, 2), component)); - } - - /* See if there is a field or component with name COMPONENT. */ - - if (code == RECORD_TYPE || code == UNION_TYPE) - { - tree indirect = 0; - - if (TYPE_SIZE (type) == 0) - { - incomplete_type_error (NULL_TREE, type); - return error_mark_node; - } - - field = lookup_field (type, component, &indirect); - - if (!field) - { - error (code == RECORD_TYPE - ? "structure has no member named `%s'" - : "union has no member named `%s'", - IDENTIFIER_POINTER (component)); - return error_mark_node; - } - if (TREE_TYPE (field) == error_mark_node) - return error_mark_node; - - /* If FIELD was found buried within an anonymous union, - make one COMPONENT_REF to get that anonymous union, - then fall thru to make a second COMPONENT_REF to get FIELD. */ - if (indirect != 0) - { - ref = build (COMPONENT_REF, TREE_TYPE (indirect), datum, indirect); - if (TREE_READONLY (datum) || TREE_READONLY (indirect)) - TREE_READONLY (ref) = 1; - if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (indirect)) - TREE_THIS_VOLATILE (ref) = 1; - datum = ref; - } - - ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field); - - if (TREE_READONLY (datum) || TREE_READONLY (field)) - TREE_READONLY (ref) = 1; - if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field)) - TREE_THIS_VOLATILE (ref) = 1; - - return ref; - } - else if (code != ERROR_MARK) - error ("request for member `%s' in something not a structure or union", - IDENTIFIER_POINTER (component)); - - return error_mark_node; -} - -/* Given an expression PTR for a pointer, return an expression - for the value pointed to. - ERRORSTRING is the name of the operator to appear in error messages. */ - -tree -build_indirect_ref (ptr, errorstring) - tree ptr; - char *errorstring; -{ - register tree pointer = default_conversion (ptr); - register tree type = TREE_TYPE (pointer); - - if (TREE_CODE (type) == POINTER_TYPE) - { - if (TREE_CODE (pointer) == ADDR_EXPR - && !flag_volatile - && (TREE_TYPE (TREE_OPERAND (pointer, 0)) - == TREE_TYPE (type))) - return TREE_OPERAND (pointer, 0); - else - { - tree t = TREE_TYPE (type); - register tree ref = build1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (t), pointer); - - if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE) - { - error ("dereferencing pointer to incomplete type"); - return error_mark_node; - } - if (TREE_CODE (t) == VOID_TYPE) - warning ("dereferencing `void *' pointer"); - - /* We *must* set TREE_READONLY when dereferencing a pointer to const, - so that we get the proper error message if the result is used - to assign to. Also, &* is supposed to be a no-op. - And ANSI C seems to specify that the type of the result - should be the const type. */ - /* A de-reference of a pointer to const is not a const. It is valid - to change it via some other pointer. */ - TREE_READONLY (ref) = TYPE_READONLY (t); - TREE_SIDE_EFFECTS (ref) - = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile; - TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); - return ref; - } - } - else if (TREE_CODE (pointer) != ERROR_MARK) - error ("invalid type argument of `%s'", errorstring); - return error_mark_node; -} - -/* This handles expressions of the form "a[i]", which denotes - an array reference. - - This is logically equivalent in C to *(a+i), but we may do it differently. - If A is a variable or a member, we generate a primitive ARRAY_REF. - This avoids forcing the array out of registers, and can work on - arrays that are not lvalues (for example, members of structures returned - by functions). */ - -tree -build_array_ref (array, index) - tree array, index; -{ - if (index == 0) - { - error ("subscript missing in array reference"); - return error_mark_node; - } - - if (TREE_TYPE (array) == error_mark_node - || TREE_TYPE (index) == error_mark_node) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE - && TREE_CODE (array) != INDIRECT_REF) - { - tree rval, type; - - /* Subscripting with type char is likely to lose - on a machine where chars are signed. - So warn on any machine, but optionally. - Don't warn for unsigned char since that type is safe. - Don't warn for signed char because anyone who uses that - must have done so deliberately. */ - if (warn_char_subscripts - && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node) - warning ("array subscript has type `char'"); - - /* Apply default promotions *after* noticing character types. */ - index = default_conversion (index); - - /* Require integer *after* promotion, for sake of enums. */ - if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE) - { - error ("array subscript is not an integer"); - return error_mark_node; - } - - /* An array that is indexed by a non-constant - cannot be stored in a register; we must be able to do - address arithmetic on its address. - Likewise an array of elements of variable size. */ - if (TREE_CODE (index) != INTEGER_CST - || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0 - && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) - { - if (mark_addressable (array) == 0) - return error_mark_node; - } - /* An array that is indexed by a constant value which is not within - the array bounds cannot be stored in a register either; because we - would get a crash in store_bit_field/extract_bit_field when trying - to access a non-existent part of the register. */ - if (TREE_CODE (index) == INTEGER_CST - && TYPE_VALUES (TREE_TYPE (array)) - && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array)))) - { - if (mark_addressable (array) == 0) - return error_mark_node; - } - - if (pedantic && !lvalue_p (array)) - { - if (DECL_REGISTER (array)) - pedwarn ("ANSI C forbids subscripting `register' array"); - else - pedwarn ("ANSI C forbids subscripting non-lvalue array"); - } - - if (pedantic) - { - tree foo = array; - while (TREE_CODE (foo) == COMPONENT_REF) - foo = TREE_OPERAND (foo, 0); - if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)) - pedwarn ("ANSI C forbids subscripting non-lvalue array"); - } - - type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array))); - rval = build (ARRAY_REF, type, array, index); - /* Array ref is const/volatile if the array elements are - or if the array is. */ - TREE_READONLY (rval) - |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array))) - | TREE_READONLY (array)); - TREE_SIDE_EFFECTS (rval) - |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) - | TREE_SIDE_EFFECTS (array)); - TREE_THIS_VOLATILE (rval) - |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) - /* This was added by rms on 16 Nov 91. - It fixes vol struct foo *a; a->elts[1] - in an inline function. - Hope it doesn't break something else. */ - | TREE_THIS_VOLATILE (array)); - return require_complete_type (fold (rval)); - } - - { - tree ar = default_conversion (array); - tree ind = default_conversion (index); - - /* Put the integer in IND to simplify error checking. */ - if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE) - { - tree temp = ar; - ar = ind; - ind = temp; - } - - if (ar == error_mark_node) - return ar; - - if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE) - { - error ("subscripted value is neither array nor pointer"); - return error_mark_node; - } - if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE) - { - error ("array subscript is not an integer"); - return error_mark_node; - } - - return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0), - "array indexing"); - } -} - -/* Build a function call to function FUNCTION with parameters PARAMS. - PARAMS is a list--a chain of TREE_LIST nodes--in which the - TREE_VALUE of each node is a parameter-expression. - FUNCTION's data type may be a function type or a pointer-to-function. */ - -tree -build_function_call (function, params) - tree function, params; -{ - register tree fntype, fundecl = 0; - register tree coerced_params; - tree name = NULL_TREE, assembler_name = NULL_TREE; - - /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ - STRIP_TYPE_NOPS (function); - - /* Convert anything with function type to a pointer-to-function. */ - if (TREE_CODE (function) == FUNCTION_DECL) - { - name = DECL_NAME (function); - assembler_name = DECL_ASSEMBLER_NAME (function); - - /* Differs from default_conversion by not setting TREE_ADDRESSABLE - (because calling an inline function does not mean the function - needs to be separately compiled). */ - fntype = build_type_variant (TREE_TYPE (function), - TREE_READONLY (function), - TREE_THIS_VOLATILE (function)); - fundecl = function; - function = build1 (ADDR_EXPR, build_pointer_type (fntype), function); - } - else - function = default_conversion (function); - - fntype = TREE_TYPE (function); - - if (TREE_CODE (fntype) == ERROR_MARK) - return error_mark_node; - - if (!(TREE_CODE (fntype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)) - { - error ("called object is not a function"); - return error_mark_node; - } - - /* fntype now gets the type of function pointed to. */ - fntype = TREE_TYPE (fntype); - - /* Convert the parameters to the types declared in the - function prototype, or apply default promotions. */ - - coerced_params - = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl); - - /* Check for errors in format strings. */ - - if (warn_format && (name || assembler_name)) - check_function_format (name, assembler_name, coerced_params); - - /* Recognize certain built-in functions so we can make tree-codes - other than CALL_EXPR. We do this when it enables fold-const.c - to do something useful. */ - - if (TREE_CODE (function) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL - && DECL_BUILT_IN (TREE_OPERAND (function, 0))) - switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0))) - { - case BUILT_IN_ABS: - case BUILT_IN_LABS: - case BUILT_IN_FABS: - if (coerced_params == 0) - return integer_zero_node; - return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0); - } - - { - register tree result - = build (CALL_EXPR, TREE_TYPE (fntype), - function, coerced_params, NULL_TREE); - - TREE_SIDE_EFFECTS (result) = 1; - if (TREE_TYPE (result) == void_type_node) - return result; - return require_complete_type (result); - } -} - -/* Convert the argument expressions in the list VALUES - to the types in the list TYPELIST. The result is a list of converted - argument expressions. - - If TYPELIST is exhausted, or when an element has NULL as its type, - perform the default conversions. - - PARMLIST is the chain of parm decls for the function being called. - It may be 0, if that info is not available. - It is used only for generating error messages. - - NAME is an IDENTIFIER_NODE or 0. It is used only for error messages. - - This is also where warnings about wrong number of args are generated. - - Both VALUES and the returned value are chains of TREE_LIST nodes - with the elements of the list in the TREE_VALUE slots of those nodes. */ - -static tree -convert_arguments (typelist, values, name, fundecl) - tree typelist, values, name, fundecl; -{ - register tree typetail, valtail; - register tree result = NULL; - int parmnum; - - /* Scan the given expressions and types, producing individual - converted arguments and pushing them on RESULT in reverse order. */ - - for (valtail = values, typetail = typelist, parmnum = 0; - valtail; - valtail = TREE_CHAIN (valtail), parmnum++) - { - register tree type = typetail ? TREE_VALUE (typetail) : 0; - register tree val = TREE_VALUE (valtail); - - if (type == void_type_node) - { - if (name) - error ("too many arguments to function `%s'", - IDENTIFIER_POINTER (name)); - else - error ("too many arguments to function"); - break; - } - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here! We do not want an enumerator with value 0 - to convert automatically to a pointer. */ - if (TREE_CODE (val) == NON_LVALUE_EXPR) - val = TREE_OPERAND (val, 0); - - if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE) - val = default_conversion (val); - - val = require_complete_type (val); - - if (type != 0) - { - /* Formal parm type is specified by a function prototype. */ - tree parmval; - - if (TYPE_SIZE (type) == 0) - { - error ("type of formal parameter %d is incomplete", parmnum + 1); - parmval = val; - } - else - { - /* Optionally warn about conversions that - differ from the default conversions. */ - if (warn_conversion) - { - int formal_prec = TYPE_PRECISION (type); - - if (INTEGRAL_TYPE_P (type) - && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) - warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1); - else if (TREE_CODE (type) == COMPLEX_TYPE - && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) - warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1); - else if (TREE_CODE (type) == REAL_TYPE - && INTEGRAL_TYPE_P (TREE_TYPE (val))) - warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1); - else if (TREE_CODE (type) == REAL_TYPE - && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE) - warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1); - /* ??? At some point, messages should be written about - conversions between complex types, but that's too messy - to do now. */ - else if (TREE_CODE (type) == REAL_TYPE - && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) - { - /* Warn if any argument is passed as `float', - since without a prototype it would be `double'. */ - if (formal_prec == TYPE_PRECISION (float_type_node)) - warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1); - } - /* Detect integer changing in width or signedness. */ - else if (INTEGRAL_TYPE_P (type) - && INTEGRAL_TYPE_P (TREE_TYPE (val))) - { - tree would_have_been = default_conversion (val); - tree type1 = TREE_TYPE (would_have_been); - - if (TREE_CODE (type) == ENUMERAL_TYPE - && type == TREE_TYPE (val)) - /* No warning if function asks for enum - and the actual arg is that enum type. */ - ; - else if (formal_prec != TYPE_PRECISION (type1)) - warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1); - else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1)) - ; - /* Don't complain if the formal parameter type - is an enum, because we can't tell now whether - the value was an enum--even the same enum. */ - else if (TREE_CODE (type) == ENUMERAL_TYPE) - ; - else if (TREE_CODE (val) == INTEGER_CST - && int_fits_type_p (val, type)) - /* Change in signedness doesn't matter - if a constant value is unaffected. */ - ; - /* Likewise for a constant in a NOP_EXPR. */ - else if (TREE_CODE (val) == NOP_EXPR - && TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST - && int_fits_type_p (TREE_OPERAND (val, 0), type)) - ; -#if 0 /* We never get such tree structure here. */ - else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE - && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type) - && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type)) - /* Change in signedness doesn't matter - if an enum value is unaffected. */ - ; -#endif - /* If the value is extended from a narrower - unsigned type, it doesn't matter whether we - pass it as signed or unsigned; the value - certainly is the same either way. */ - else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type) - && TREE_UNSIGNED (TREE_TYPE (val))) - ; - else if (TREE_UNSIGNED (type)) - warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1); - else - warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1); - } - } - - parmval = convert_for_assignment (type, val, - (char *)0, /* arg passing */ - fundecl, name, parmnum + 1); - -#ifdef PROMOTE_PROTOTYPES - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - parmval = default_conversion (parmval); -#endif - } - result = tree_cons (NULL_TREE, parmval, result); - } - else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE - && (TYPE_PRECISION (TREE_TYPE (val)) - < TYPE_PRECISION (double_type_node))) - /* Convert `float' to `double'. */ - result = tree_cons (NULL_TREE, convert (double_type_node, val), result); - else - /* Convert `short' and `char' to full-size `int'. */ - result = tree_cons (NULL_TREE, default_conversion (val), result); - - if (typetail) - typetail = TREE_CHAIN (typetail); - } - - if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) - { - if (name) - error ("too few arguments to function `%s'", - IDENTIFIER_POINTER (name)); - else - error ("too few arguments to function"); - } - - return nreverse (result); -} - -/* This is the entry point used by the parser - for binary operators in the input. - In addition to constructing the expression, - we check for operands that were written with other binary operators - in a way that is likely to confuse the user. */ - -tree -parser_build_binary_op (code, arg1, arg2) - enum tree_code code; - tree arg1, arg2; -{ - tree result = build_binary_op (code, arg1, arg2, 1); - - char class; - char class1 = TREE_CODE_CLASS (TREE_CODE (arg1)); - char class2 = TREE_CODE_CLASS (TREE_CODE (arg2)); - enum tree_code code1 = ERROR_MARK; - enum tree_code code2 = ERROR_MARK; - - if (class1 == 'e' || class1 == '1' - || class1 == '2' || class1 == '<') - code1 = C_EXP_ORIGINAL_CODE (arg1); - if (class2 == 'e' || class2 == '1' - || class2 == '2' || class2 == '<') - code2 = C_EXP_ORIGINAL_CODE (arg2); - - /* Check for cases such as x+y<<z which users are likely - to misinterpret. If parens are used, C_EXP_ORIGINAL_CODE - is cleared to prevent these warnings. */ - if (warn_parentheses) - { - if (code == LSHIFT_EXPR || code == RSHIFT_EXPR) - { - if (code1 == PLUS_EXPR || code1 == MINUS_EXPR - || code2 == PLUS_EXPR || code2 == MINUS_EXPR) - warning ("suggest parentheses around + or - inside shift"); - } - - if (code == TRUTH_ORIF_EXPR) - { - if (code1 == TRUTH_ANDIF_EXPR - || code2 == TRUTH_ANDIF_EXPR) - warning ("suggest parentheses around && within ||"); - } - - if (code == BIT_IOR_EXPR) - { - if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR - || code1 == PLUS_EXPR || code1 == MINUS_EXPR - || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR - || code2 == PLUS_EXPR || code2 == MINUS_EXPR) - warning ("suggest parentheses around arithmetic in operand of |"); - } - - if (code == BIT_XOR_EXPR) - { - if (code1 == BIT_AND_EXPR - || code1 == PLUS_EXPR || code1 == MINUS_EXPR - || code2 == BIT_AND_EXPR - || code2 == PLUS_EXPR || code2 == MINUS_EXPR) - warning ("suggest parentheses around arithmetic in operand of ^"); - } - - if (code == BIT_AND_EXPR) - { - if (code1 == PLUS_EXPR || code1 == MINUS_EXPR - || code2 == PLUS_EXPR || code2 == MINUS_EXPR) - warning ("suggest parentheses around + or - in operand of &"); - } - } - - /* Similarly, check for cases like 1<=i<=10 that are probably errors. */ - if (TREE_CODE_CLASS (code) == '<' && extra_warnings - && (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')) - warning ("comparisons like X<=Y<=Z do not have their mathematical meaning"); - - unsigned_conversion_warning (result, arg1); - unsigned_conversion_warning (result, arg2); - overflow_warning (result); - - class = TREE_CODE_CLASS (TREE_CODE (result)); - - /* Record the code that was specified in the source, - for the sake of warnings about confusing nesting. */ - if (class == 'e' || class == '1' - || class == '2' || class == '<') - C_SET_EXP_ORIGINAL_CODE (result, code); - else - { - int flag = TREE_CONSTANT (result); - /* We used to use NOP_EXPR rather than NON_LVALUE_EXPR - so that convert_for_assignment wouldn't strip it. - That way, we got warnings for things like p = (1 - 1). - But it turns out we should not get those warnings. */ - result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result); - C_SET_EXP_ORIGINAL_CODE (result, code); - TREE_CONSTANT (result) = flag; - } - - return result; -} - -/* Build a binary-operation expression without default conversions. - CODE is the kind of expression to build. - This function differs from `build' in several ways: - the data type of the result is computed and recorded in it, - warnings are generated if arg data types are invalid, - special handling for addition and subtraction of pointers is known, - and some optimization is done (operations on narrow ints - are done in the narrower type when that gives the same result). - Constant folding is also done before the result is returned. - - Note that the operands will never have enumeral types, or function - or array types, because either they will have the default conversions - performed or they have both just been converted to some other type in which - the arithmetic is to be done. */ - -tree -build_binary_op (code, orig_op0, orig_op1, convert_p) - enum tree_code code; - tree orig_op0, orig_op1; - int convert_p; -{ - tree type0, type1; - register enum tree_code code0, code1; - tree op0, op1; - - /* Expression code to give to the expression when it is built. - Normally this is CODE, which is what the caller asked for, - but in some special cases we change it. */ - register enum tree_code resultcode = code; - - /* Data type in which the computation is to be performed. - In the simplest cases this is the common type of the arguments. */ - register tree result_type = NULL; - - /* Nonzero means operands have already been type-converted - in whatever way is necessary. - Zero means they need to be converted to RESULT_TYPE. */ - int converted = 0; - - /* Nonzero means after finally constructing the expression - give it this type. Otherwise, give it type RESULT_TYPE. */ - tree final_type = 0; - - /* Nonzero if this is an operation like MIN or MAX which can - safely be computed in short if both args are promoted shorts. - Also implies COMMON. - -1 indicates a bitwise operation; this makes a difference - in the exact conditions for when it is safe to do the operation - in a narrower mode. */ - int shorten = 0; - - /* Nonzero if this is a comparison operation; - if both args are promoted shorts, compare the original shorts. - Also implies COMMON. */ - int short_compare = 0; - - /* Nonzero if this is a right-shift operation, which can be computed on the - original short and then promoted if the operand is a promoted short. */ - int short_shift = 0; - - /* Nonzero means set RESULT_TYPE to the common type of the args. */ - int common = 0; - - if (convert_p) - { - op0 = default_conversion (orig_op0); - op1 = default_conversion (orig_op1); - } - else - { - op0 = orig_op0; - op1 = orig_op1; - } - - type0 = TREE_TYPE (op0); - type1 = TREE_TYPE (op1); - - /* The expression codes of the data types of the arguments tell us - whether the arguments are integers, floating, pointers, etc. */ - code0 = TREE_CODE (type0); - code1 = TREE_CODE (type1); - - /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ - STRIP_TYPE_NOPS (op0); - STRIP_TYPE_NOPS (op1); - - /* If an error was already reported for one of the arguments, - avoid reporting another error. */ - - if (code0 == ERROR_MARK || code1 == ERROR_MARK) - return error_mark_node; - - switch (code) - { - case PLUS_EXPR: - /* Handle the pointer + int case. */ - if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op0, op1); - else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op1, op0); - else - common = 1; - break; - - case MINUS_EXPR: - /* Subtraction of two similar pointers. - We must subtract them as integers, then divide by object size. */ - if (code0 == POINTER_TYPE && code1 == POINTER_TYPE - && comp_target_types (type0, type1)) - return pointer_diff (op0, op1); - /* Handle pointer minus int. Just like pointer plus int. */ - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (MINUS_EXPR, op0, op1); - else - common = 1; - break; - - case MULT_EXPR: - common = 1; - break; - - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case EXACT_DIV_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) - { - if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)) - resultcode = RDIV_EXPR; - else - { - /* Although it would be tempting to shorten always here, that - loses on some targets, since the modulo instruction is - undefined if the quotient can't be represented in the - computation mode. We shorten only if unsigned or if - dividing by something we know != -1. */ - shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0)) - || (TREE_CODE (op1) == INTEGER_CST - && (TREE_INT_CST_LOW (op1) != -1 - || TREE_INT_CST_HIGH (op1) != -1))); - } - common = 1; - } - break; - - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - shorten = -1; - /* If one operand is a constant, and the other is a short type - that has been converted to an int, - really do the work in the short type and then convert the - result to int. If we are lucky, the constant will be 0 or 1 - in the short type, making the entire operation go away. */ - if (TREE_CODE (op0) == INTEGER_CST - && TREE_CODE (op1) == NOP_EXPR - && TYPE_PRECISION (type1) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0)))) - { - final_type = result_type; - op1 = TREE_OPERAND (op1, 0); - result_type = TREE_TYPE (op1); - } - if (TREE_CODE (op1) == INTEGER_CST - && TREE_CODE (op0) == NOP_EXPR - && TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) - { - final_type = result_type; - op0 = TREE_OPERAND (op0, 0); - result_type = TREE_TYPE (op0); - } - break; - - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - /* Although it would be tempting to shorten always here, that loses - on some targets, since the modulo instruction is undefined if the - quotient can't be represented in the computation mode. We shorten - only if unsigned or if dividing by something we know != -1. */ - shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0)) - || (TREE_CODE (op1) == INTEGER_CST - && (TREE_INT_CST_LOW (op1) != -1 - || TREE_INT_CST_HIGH (op1) != -1))); - common = 1; - } - break; - - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE - || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE - || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) - { - /* Result of these operations is always an int, - but that does not mean the operands should be - converted to ints! */ - result_type = integer_type_node; - op0 = truthvalue_conversion (op0); - op1 = truthvalue_conversion (op1); - converted = 1; - } - break; - - /* Shift operations: result has same type as first operand; - always convert second operand to int. - Also set SHORT_SHIFT if shifting rightward. */ - - case RSHIFT_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_sgn (op1) < 0) - warning ("right shift count is negative"); - else - { - if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1)) - short_shift = 1; - if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("right shift count >= width of type"); - } - } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ - result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - } - break; - - case LSHIFT_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_sgn (op1) < 0) - warning ("left shift count is negative"); - else if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("left shift count >= width of type"); - } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ - result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - } - break; - - case RROTATE_EXPR: - case LROTATE_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_sgn (op1) < 0) - warning ("shift count is negative"); - else if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("shift count >= width of type"); - } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ - result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - } - break; - - case EQ_EXPR: - case NE_EXPR: - /* Result of comparison is always int, - but don't convert the args to int! */ - result_type = integer_type_node; - converted = 1; - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) - short_compare = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - register tree tt0 = TREE_TYPE (type0); - register tree tt1 = TREE_TYPE (type1); - /* Anything compares with void *. void * compares with anything. - Otherwise, the targets must be compatible - and both must be object or both incomplete. */ - if (comp_target_types (type0, type1)) - ; - else if (TYPE_MAIN_VARIANT (tt0) == void_type_node) - { - /* op0 != orig_op0 detects the case of something - whose value is 0 but which isn't a valid null ptr const. */ - if (pedantic && (!integer_zerop (op0) || op0 != orig_op0) - && TREE_CODE (tt1) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); - } - else if (TYPE_MAIN_VARIANT (tt1) == void_type_node) - { - if (pedantic && (!integer_zerop (op1) || op1 != orig_op1) - && TREE_CODE (tt0) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); - } - else - pedwarn ("comparison of distinct pointer types lacks a cast"); - } - else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) - op1 = null_pointer_node; - else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) - op0 = null_pointer_node; - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op1 = convert (TREE_TYPE (op0), op1); - } - else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op0 = convert (TREE_TYPE (op1), op0); - } - else - /* If args are not valid, clear out RESULT_TYPE - to cause an error message later. */ - result_type = 0; - break; - - case MAX_EXPR: - case MIN_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) - shorten = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - if (! comp_target_types (type0, type1)) - pedwarn ("comparison of distinct pointer types lacks a cast"); - else if (pedantic - && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids ordered comparisons of pointers to functions"); - result_type = common_type (type0, type1); - } - break; - - case LE_EXPR: - case GE_EXPR: - case LT_EXPR: - case GT_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) - short_compare = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - if (! comp_target_types (type0, type1)) - pedwarn ("comparison of distinct pointer types lacks a cast"); - else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0) - != (TYPE_SIZE (TREE_TYPE (type1)) != 0)) - pedwarn ("comparison of complete and incomplete pointers"); - else if (pedantic - && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids ordered comparisons of pointers to functions"); - result_type = integer_type_node; - } - else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) - { - result_type = integer_type_node; - op1 = null_pointer_node; - if (pedantic) - pedwarn ("ordered comparison of pointer with integer zero"); - } - else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) - { - result_type = integer_type_node; - op0 = null_pointer_node; - if (pedantic) - pedwarn ("ordered comparison of pointer with integer zero"); - } - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - result_type = integer_type_node; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op1 = convert (TREE_TYPE (op0), op1); - } - else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - result_type = integer_type_node; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op0 = convert (TREE_TYPE (op1), op0); - } - converted = 1; - break; - } - - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) - && - (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) - { - int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); - - if (shorten || common || short_compare) - result_type = common_type (type0, type1); - - /* For certain operations (which identify themselves by shorten != 0) - if both args were extended from the same smaller type, - do the arithmetic in that type and then extend. - - shorten !=0 and !=1 indicates a bitwise operation. - For them, this optimization is safe only if - both args are zero-extended or both are sign-extended. - Otherwise, we might change the result. - Eg, (short)-1 | (unsigned short)-1 is (int)-1 - but calculated in (unsigned short) it would be (unsigned short)-1. */ - - if (shorten && none_complex) - { - int unsigned0, unsigned1; - tree arg0 = get_narrower (op0, &unsigned0); - tree arg1 = get_narrower (op1, &unsigned1); - /* UNS is 1 if the operation to be done is an unsigned one. */ - int uns = TREE_UNSIGNED (result_type); - tree type; - - final_type = result_type; - - /* Handle the case that OP0 (or OP1) does not *contain* a conversion - but it *requires* conversion to FINAL_TYPE. */ - - if ((TYPE_PRECISION (TREE_TYPE (op0)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && TREE_TYPE (op0) != final_type) - unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0)); - if ((TYPE_PRECISION (TREE_TYPE (op1)) - == TYPE_PRECISION (TREE_TYPE (arg1))) - && TREE_TYPE (op1) != final_type) - unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1)); - - /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */ - - /* For bitwise operations, signedness of nominal type - does not matter. Consider only how operands were extended. */ - if (shorten == -1) - uns = unsigned0; - - /* Note that in all three cases below we refrain from optimizing - an unsigned operation on sign-extended args. - That would not be valid. */ - - /* Both args variable: if both extended in same way - from same width, do it in that width. - Do it unsigned if args were zero-extended. */ - if ((TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && unsigned0 == unsigned1 - && (unsigned0 || !uns)) - result_type - = signed_or_unsigned_type (unsigned0, - common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); - else if (TREE_CODE (arg0) == INTEGER_CST - && (unsigned1 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned1, - TREE_TYPE (arg1)), - int_fits_type_p (arg0, type))) - result_type = type; - else if (TREE_CODE (arg1) == INTEGER_CST - && (unsigned0 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned0, - TREE_TYPE (arg0)), - int_fits_type_p (arg1, type))) - result_type = type; - } - - /* Shifts can be shortened if shifting right. */ - - if (short_shift) - { - int unsigned_arg; - tree arg0 = get_narrower (op0, &unsigned_arg); - - final_type = result_type; - - if (arg0 == op0 && final_type == TREE_TYPE (op0)) - unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0)); - - if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) - /* If arg is sign-extended and then unsigned-shifted, - we can simulate this with a signed shift in arg's type - only if the extended result is at least twice as wide - as the arg. Otherwise, the shift could use up all the - ones made by sign-extension and bring in zeros. - We can't optimize that case at all, but in most machines - it never happens because available widths are 2**N. */ - && (!TREE_UNSIGNED (final_type) - || unsigned_arg - || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type))) - { - /* Do an unsigned shift if the operand was zero-extended. */ - result_type - = signed_or_unsigned_type (unsigned_arg, - TREE_TYPE (arg0)); - /* Convert value-to-be-shifted to that type. */ - if (TREE_TYPE (op0) != result_type) - op0 = convert (result_type, op0); - converted = 1; - } - } - - /* Comparison operations are shortened too but differently. - They identify themselves by setting short_compare = 1. */ - - if (short_compare) - { - /* Don't write &op0, etc., because that would prevent op0 - from being kept in a register. - Instead, make copies of the our local variables and - pass the copies by reference, then copy them back afterward. */ - tree xop0 = op0, xop1 = op1, xresult_type = result_type; - enum tree_code xresultcode = resultcode; - tree val - = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); - if (val != 0) - return val; - op0 = xop0, op1 = xop1, result_type = xresult_type; - resultcode = xresultcode; - - if (extra_warnings) - { - tree op0_type = TREE_TYPE (orig_op0); - tree op1_type = TREE_TYPE (orig_op1); - int op0_unsigned = TREE_UNSIGNED (op0_type); - int op1_unsigned = TREE_UNSIGNED (op1_type); - - /* Give warnings for comparisons between signed and unsigned - quantities that will fail. Do not warn if the signed quantity - is an unsuffixed integer literal (or some static constant - expression involving such literals) and it is positive. - Do not warn if the width of the unsigned quantity is less - than that of the signed quantity, since in this case all - values of the unsigned quantity fit in the signed quantity. - Do not warn if the signed type is the same size as the - result_type since sign extension does not cause trouble in - this case. */ - /* Do the checking based on the original operand trees, so that - casts will be considered, but default promotions won't be. */ - if (op0_unsigned != op1_unsigned - && ((op0_unsigned - && TYPE_PRECISION (op0_type) >= TYPE_PRECISION (op1_type) - && TYPE_PRECISION (op0_type) < TYPE_PRECISION (result_type) - && (TREE_CODE (op1) != INTEGER_CST - || (TREE_CODE (op1) == INTEGER_CST - && INT_CST_LT (op1, integer_zero_node)))) - || - (op1_unsigned - && TYPE_PRECISION (op1_type) >= TYPE_PRECISION (op0_type) - && TYPE_PRECISION (op1_type) < TYPE_PRECISION (result_type) - && (TREE_CODE (op0) != INTEGER_CST - || (TREE_CODE (op0) == INTEGER_CST - && INT_CST_LT (op0, integer_zero_node)))))) - warning ("comparison between signed and unsigned"); - } - } - } - - /* At this point, RESULT_TYPE must be nonzero to avoid an error message. - If CONVERTED is zero, both args will be converted to type RESULT_TYPE. - Then the expression will be built. - It will be given type FINAL_TYPE if that is nonzero; - otherwise, it will be given type RESULT_TYPE. */ - - if (!result_type) - { - binary_op_error (code); - return error_mark_node; - } - - if (! converted) - { - if (TREE_TYPE (op0) != result_type) - op0 = convert (result_type, op0); - if (TREE_TYPE (op1) != result_type) - op1 = convert (result_type, op1); - } - - { - register tree result = build (resultcode, result_type, op0, op1); - register tree folded; - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); - if (final_type != 0) - return convert (final_type, folded); - return folded; - } -} - -/* Return a tree for the sum or difference (RESULTCODE says which) - of pointer PTROP and integer INTOP. */ - -static tree -pointer_int_sum (resultcode, ptrop, intop) - enum tree_code resultcode; - register tree ptrop, intop; -{ - tree size_exp; - - register tree result; - register tree folded; - - /* The result is a pointer of the same type that is being added. */ - - register tree result_type = TREE_TYPE (ptrop); - - if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("pointer of type `void *' used in arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("pointer to a function used in arithmetic"); - size_exp = integer_one_node; - } - else - size_exp = c_size_in_bytes (TREE_TYPE (result_type)); - - /* If what we are about to multiply by the size of the elements - contains a constant term, apply distributive law - and multiply that constant term separately. - This helps produce common subexpressions. */ - - if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR) - && ! TREE_CONSTANT (intop) - && TREE_CONSTANT (TREE_OPERAND (intop, 1)) - && TREE_CONSTANT (size_exp) - /* If the constant comes from pointer subtraction, - skip this optimization--it would cause an error. */ - && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE) - { - enum tree_code subcode = resultcode; - tree int_type = TREE_TYPE (intop); - if (TREE_CODE (intop) == MINUS_EXPR) - subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); - /* Convert both subexpression types to the type of intop, - because weird cases involving pointer arithmetic - can result in a sum or difference with different type args. */ - ptrop = build_binary_op (subcode, ptrop, - convert (int_type, TREE_OPERAND (intop, 1)), 1); - intop = convert (int_type, TREE_OPERAND (intop, 0)); - } - - /* Convert the integer argument to a type the same size as a pointer - so the multiply won't overflow spuriously. */ - - if (TYPE_PRECISION (TREE_TYPE (intop)) != POINTER_SIZE) - intop = convert (type_for_size (POINTER_SIZE, 0), intop); - - /* Replace the integer argument with a suitable product by the object size. - Do this multiplication as signed, then convert to the appropriate - pointer type (actually unsigned integral). */ - - intop = convert (result_type, - build_binary_op (MULT_EXPR, intop, - convert (TREE_TYPE (intop), size_exp), 1)); - - /* Create the sum or difference. */ - - result = build (resultcode, result_type, ptrop, intop); - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop); - return folded; -} - -/* Return a tree for the difference of pointers OP0 and OP1. - The resulting tree has type int. */ - -static tree -pointer_diff (op0, op1) - register tree op0, op1; -{ - register tree result, folded; - tree restype = ptrdiff_type_node; - - tree target_type = TREE_TYPE (TREE_TYPE (op0)); - - if (pedantic || warn_pointer_arith) - { - if (TREE_CODE (target_type) == VOID_TYPE) - pedwarn ("pointer of type `void *' used in subtraction"); - if (TREE_CODE (target_type) == FUNCTION_TYPE) - pedwarn ("pointer to a function used in subtraction"); - } - - /* First do the subtraction as integers; - then drop through to build the divide operator. */ - - op0 = build_binary_op (MINUS_EXPR, convert (restype, op0), - convert (restype, op1), 1); - /* This generates an error if op1 is pointer to incomplete type. */ - if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0) - error ("arithmetic on pointer to an incomplete type"); - - /* This generates an error if op0 is pointer to incomplete type. */ - op1 = c_size_in_bytes (target_type); - - /* Divide by the size, in easiest possible way. */ - - result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1)); - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); - return folded; -} - -/* Construct and perhaps optimize a tree representation - for a unary operation. CODE, a tree_code, specifies the operation - and XARG is the operand. NOCONVERT nonzero suppresses - the default promotions (such as from short to int). */ - -tree -build_unary_op (code, xarg, noconvert) - enum tree_code code; - tree xarg; - int noconvert; -{ - /* No default_conversion here. It causes trouble for ADDR_EXPR. */ - register tree arg = xarg; - register tree argtype = 0; - register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg)); - char *errstring = NULL; - tree val; - - if (typecode == ERROR_MARK) - return error_mark_node; - if (typecode == ENUMERAL_TYPE) - typecode = INTEGER_TYPE; - - switch (code) - { - case CONVERT_EXPR: - /* This is used for unary plus, because a CONVERT_EXPR - is enough to prevent anybody from looking inside for - associativity, but won't generate any code. */ - if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to unary plus"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case NEGATE_EXPR: - if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to unary minus"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case BIT_NOT_EXPR: - if (typecode == COMPLEX_TYPE) - { - code = CONJ_EXPR; - if (!noconvert) - arg = default_conversion (arg); - } - else if (typecode != INTEGER_TYPE) - errstring = "wrong type argument to bit-complement"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case ABS_EXPR: - if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to abs"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case CONJ_EXPR: - /* Conjugating a real value is a no-op, but allow it anyway. */ - if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to conjugation"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case TRUTH_NOT_EXPR: - if (typecode != INTEGER_TYPE - && typecode != REAL_TYPE && typecode != POINTER_TYPE - && typecode != COMPLEX_TYPE - /* These will convert to a pointer. */ - && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE) - { - errstring = "wrong type argument to unary exclamation mark"; - break; - } - arg = truthvalue_conversion (arg); - return invert_truthvalue (arg); - - case NOP_EXPR: - break; - - case REALPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_REALPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); - else - return arg; - - case IMAGPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_IMAGPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); - else - return convert (TREE_TYPE (arg), integer_zero_node); - - case PREINCREMENT_EXPR: - case POSTINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTDECREMENT_EXPR: - /* Handle complex lvalues (when permitted) - by reduction to simpler cases. */ - - val = unary_complex_lvalue (code, arg); - if (val != 0) - return val; - - /* Increment or decrement the real part of the value, - and don't change the imaginary part. */ - if (typecode == COMPLEX_TYPE) - { - tree real, imag; - - arg = stabilize_reference (arg); - real = build_unary_op (REALPART_EXPR, arg, 1); - imag = build_unary_op (IMAGPART_EXPR, arg, 1); - return build (COMPLEX_EXPR, TREE_TYPE (arg), - build_unary_op (code, real, 1), imag); - } - - /* Report invalid types. */ - - if (typecode != POINTER_TYPE - && typecode != INTEGER_TYPE && typecode != REAL_TYPE) - { - if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - errstring ="wrong type argument to increment"; - else - errstring ="wrong type argument to decrement"; - break; - } - - { - register tree inc; - tree result_type = TREE_TYPE (arg); - - arg = get_unwidened (arg, 0); - argtype = TREE_TYPE (arg); - - /* Compute the increment. */ - - if (typecode == POINTER_TYPE) - { - /* If pointer target is an undefined struct, - we just cannot know how to do the arithmetic. */ - if (TYPE_SIZE (TREE_TYPE (result_type)) == 0) - error ("%s of pointer to unknown structure", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); - else if ((pedantic || warn_pointer_arith) - && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)) - pedwarn ("wrong type argument to %s", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); - inc = c_size_in_bytes (TREE_TYPE (result_type)); - } - else - inc = integer_one_node; - - inc = convert (argtype, inc); - - /* Handle incrementing a cast-expression. */ - - while (1) - switch (TREE_CODE (arg)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - pedantic_lvalue_warning (CONVERT_EXPR); - /* If the real type has the same machine representation - as the type it is cast to, we can make better output - by adding directly to the inside of the cast. */ - if ((TREE_CODE (TREE_TYPE (arg)) - == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0)))) - && (TYPE_MODE (TREE_TYPE (arg)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0))))) - arg = TREE_OPERAND (arg, 0); - else - { - tree incremented, modify, value; - arg = stabilize_reference (arg); - if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) - value = arg; - else - value = save_expr (arg); - incremented = build (((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? PLUS_EXPR : MINUS_EXPR), - argtype, value, inc); - TREE_SIDE_EFFECTS (incremented) = 1; - modify = build_modify_expr (arg, NOP_EXPR, incremented); - value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); - TREE_USED (value) = 1; - return value; - } - break; - - default: - goto give_up; - } - give_up: - - /* Complain about anything else that is not a true lvalue. */ - if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"))) - return error_mark_node; - - /* Report a read-only lvalue. */ - if (TREE_READONLY (arg)) - readonly_warning (arg, - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); - - val = build (code, TREE_TYPE (arg), arg, inc); - TREE_SIDE_EFFECTS (val) = 1; - val = convert (result_type, val); - if (TREE_CODE (val) != code) - TREE_NO_UNUSED_WARNING (val) = 1; - return val; - } - - case ADDR_EXPR: - /* Note that this operation never does default_conversion - regardless of NOCONVERT. */ - - /* Let &* cancel out to simplify resulting code. */ - if (TREE_CODE (arg) == INDIRECT_REF) - { - /* Don't let this be an lvalue. */ - if (lvalue_p (TREE_OPERAND (arg, 0))) - return non_lvalue (TREE_OPERAND (arg, 0)); - return TREE_OPERAND (arg, 0); - } - - /* For &x[y], return x+y */ - if (TREE_CODE (arg) == ARRAY_REF) - { - if (mark_addressable (TREE_OPERAND (arg, 0)) == 0) - return error_mark_node; - return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0), - TREE_OPERAND (arg, 1), 1); - } - - /* Handle complex lvalues (when permitted) - by reduction to simpler cases. */ - val = unary_complex_lvalue (code, arg); - if (val != 0) - return val; - -#if 0 /* Turned off because inconsistent; - float f; *&(int)f = 3.4 stores in int format - whereas (int)f = 3.4 stores in float format. */ - /* Address of a cast is just a cast of the address - of the operand of the cast. */ - switch (TREE_CODE (arg)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - if (pedantic) - pedwarn ("ANSI C forbids the address of a cast expression"); - return convert (build_pointer_type (TREE_TYPE (arg)), - build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), - 0)); - } -#endif - - /* Allow the address of a constructor if all the elements - are constant. */ - if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg)) - ; - /* Anything not already handled and not a true memory reference - is an error. */ - else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'")) - return error_mark_node; - - /* Ordinary case; arg is a COMPONENT_REF or a decl. */ - argtype = TREE_TYPE (arg); - /* If the lvalue is const or volatile, - merge that into the type that the address will point to. */ - if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd' - || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r') - { - if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)) - argtype = c_build_type_variant (argtype, - TREE_READONLY (arg), - TREE_THIS_VOLATILE (arg)); - } - - argtype = build_pointer_type (argtype); - - if (mark_addressable (arg) == 0) - return error_mark_node; - - { - tree addr; - - if (TREE_CODE (arg) == COMPONENT_REF) - { - tree field = TREE_OPERAND (arg, 1); - - addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0); - - if (DECL_BIT_FIELD (field)) - { - error ("attempt to take address of bit-field structure member `%s'", - IDENTIFIER_POINTER (DECL_NAME (field))); - return error_mark_node; - } - - addr = convert (argtype, addr); - - if (! integer_zerop (DECL_FIELD_BITPOS (field))) - { - tree offset - = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field), - size_int (BITS_PER_UNIT)); - int flag = TREE_CONSTANT (addr); - addr = fold (build (PLUS_EXPR, argtype, - addr, convert (argtype, offset))); - TREE_CONSTANT (addr) = flag; - } - } - else - addr = build1 (code, argtype, arg); - - /* Address of a static or external variable or - file-scope function counts as a constant. */ - if (staticp (arg) - && ! (TREE_CODE (arg) == FUNCTION_DECL - && DECL_CONTEXT (arg) != 0)) - TREE_CONSTANT (addr) = 1; - return addr; - } - } - - if (!errstring) - { - if (argtype == 0) - argtype = TREE_TYPE (arg); - return fold (build1 (code, argtype, arg)); - } - - error (errstring); - return error_mark_node; -} - -#if 0 -/* If CONVERSIONS is a conversion expression or a nested sequence of such, - convert ARG with the same conversions in the same order - and return the result. */ - -static tree -convert_sequence (conversions, arg) - tree conversions; - tree arg; -{ - switch (TREE_CODE (conversions)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - return convert (TREE_TYPE (conversions), - convert_sequence (TREE_OPERAND (conversions, 0), - arg)); - - default: - return arg; - } -} -#endif /* 0 */ - -/* Return nonzero if REF is an lvalue valid for this language. - Lvalues can be assigned, unless their type has TYPE_READONLY. - Lvalues can have their address taken, unless they have DECL_REGISTER. */ - -int -lvalue_p (ref) - tree ref; -{ - register enum tree_code code = TREE_CODE (ref); - - switch (code) - { - case REALPART_EXPR: - case IMAGPART_EXPR: - case COMPONENT_REF: - return lvalue_p (TREE_OPERAND (ref, 0)); - - case STRING_CST: - return 1; - - case INDIRECT_REF: - case ARRAY_REF: - case VAR_DECL: - case PARM_DECL: - case RESULT_DECL: - case ERROR_MARK: - if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE - && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE) - return 1; - break; - } - return 0; -} - -/* Return nonzero if REF is an lvalue valid for this language; - otherwise, print an error message and return zero. */ - -int -lvalue_or_else (ref, string) - tree ref; - char *string; -{ - int win = lvalue_p (ref); - if (! win) - error ("invalid lvalue in %s", string); - return win; -} - -/* Apply unary lvalue-demanding operator CODE to the expression ARG - for certain kinds of expressions which are not really lvalues - but which we can accept as lvalues. - - If ARG is not a kind of expression we can handle, return zero. */ - -static tree -unary_complex_lvalue (code, arg) - enum tree_code code; - tree arg; -{ - /* Handle (a, b) used as an "lvalue". */ - if (TREE_CODE (arg) == COMPOUND_EXPR) - { - tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0); - pedantic_lvalue_warning (COMPOUND_EXPR); - return build (COMPOUND_EXPR, TREE_TYPE (real_result), - TREE_OPERAND (arg, 0), real_result); - } - - /* Handle (a ? b : c) used as an "lvalue". */ - if (TREE_CODE (arg) == COND_EXPR) - { - pedantic_lvalue_warning (COND_EXPR); - return (build_conditional_expr - (TREE_OPERAND (arg, 0), - build_unary_op (code, TREE_OPERAND (arg, 1), 0), - build_unary_op (code, TREE_OPERAND (arg, 2), 0))); - } - - return 0; -} - -/* If pedantic, warn about improper lvalue. CODE is either COND_EXPR - COMPOUND_EXPR, or CONVERT_EXPR (for casts). */ - -static void -pedantic_lvalue_warning (code) - enum tree_code code; -{ - if (pedantic) - pedwarn ("ANSI C forbids use of %s expressions as lvalues", - code == COND_EXPR ? "conditional" - : code == COMPOUND_EXPR ? "compound" : "cast"); -} - -/* Warn about storing in something that is `const'. */ - -void -readonly_warning (arg, string) - tree arg; - char *string; -{ - char buf[80]; - strcpy (buf, string); - - /* Forbid assignments to iterators. */ - if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg)) - { - strcat (buf, " of iterator `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg))); - } - - if (TREE_CODE (arg) == COMPONENT_REF) - { - if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) - readonly_warning (TREE_OPERAND (arg, 0), string); - else - { - strcat (buf, " of read-only member `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1)))); - } - } - else if (TREE_CODE (arg) == VAR_DECL) - { - strcat (buf, " of read-only variable `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg))); - } - else - { - pedwarn ("%s of read-only location", buf); - } -} - -/* Mark EXP saying that we need to be able to take the - address of it; it should not be allocated in a register. - Value is 1 if successful. */ - -int -mark_addressable (exp) - tree exp; -{ - register tree x = exp; - while (1) - switch (TREE_CODE (x)) - { - case ADDR_EXPR: - case COMPONENT_REF: - case ARRAY_REF: - case REALPART_EXPR: - case IMAGPART_EXPR: - x = TREE_OPERAND (x, 0); - break; - - case CONSTRUCTOR: - TREE_ADDRESSABLE (x) = 1; - return 1; - - case VAR_DECL: - case CONST_DECL: - case PARM_DECL: - case RESULT_DECL: - if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) - && DECL_NONLOCAL (x)) - { - if (TREE_PUBLIC (x)) - { - error ("global register variable `%s' used in nested function", - IDENTIFIER_POINTER (DECL_NAME (x))); - return 0; - } - pedwarn ("register variable `%s' used in nested function", - IDENTIFIER_POINTER (DECL_NAME (x))); - } - else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)) - { - if (TREE_PUBLIC (x)) - { - error ("address of global register variable `%s' requested", - IDENTIFIER_POINTER (DECL_NAME (x))); - return 0; - } - - /* If we are making this addressable due to its having - volatile components, give a different error message. Also - handle the case of an unnamed parameter by not trying - to give the name. */ - - else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x))) - { - error ("cannot put object with volatile field into register"); - return 0; - } - - pedwarn ("address of register variable `%s' requested", - IDENTIFIER_POINTER (DECL_NAME (x))); - } - put_var_into_stack (x); - - /* drops in */ - case FUNCTION_DECL: - TREE_ADDRESSABLE (x) = 1; -#if 0 /* poplevel deals with this now. */ - if (DECL_CONTEXT (x) == 0) - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1; -#endif - - default: - return 1; - } -} - -/* Build and return a conditional expression IFEXP ? OP1 : OP2. */ - -tree -build_conditional_expr (ifexp, op1, op2) - tree ifexp, op1, op2; -{ - register tree type1; - register tree type2; - register enum tree_code code1; - register enum tree_code code2; - register tree result_type = NULL; - tree orig_op1 = op1, orig_op2 = op2; - - /* If second operand is omitted, it is the same as the first one; - make sure it is calculated only once. */ - if (op1 == 0) - { - if (pedantic) - pedwarn ("ANSI C forbids omitting the middle term of a ?: expression"); - ifexp = op1 = save_expr (ifexp); - } - - ifexp = truthvalue_conversion (default_conversion (ifexp)); - -#if 0 /* Produces wrong result if within sizeof. */ - /* Don't promote the operands separately if they promote - the same way. Return the unpromoted type and let the combined - value get promoted if necessary. */ - - if (TREE_TYPE (op1) == TREE_TYPE (op2) - && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE - && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE) - { - if (TREE_CODE (ifexp) == INTEGER_CST) - return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); - - return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2)); - } -#endif - - /* Promote both alternatives. */ - - if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE) - op1 = default_conversion (op1); - if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE) - op2 = default_conversion (op2); - - if (TREE_CODE (ifexp) == ERROR_MARK - || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK - || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK) - return error_mark_node; - - type1 = TREE_TYPE (op1); - code1 = TREE_CODE (type1); - type2 = TREE_TYPE (op2); - code2 = TREE_CODE (type2); - - /* Quickly detect the usual case where op1 and op2 have the same type - after promotion. */ - if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) - { - if (type1 == type2) - result_type = type1; - else - result_type = TYPE_MAIN_VARIANT (type1); - } - else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE) - && (code2 == INTEGER_TYPE || code2 == REAL_TYPE)) - { - result_type = common_type (type1, type2); - } - else if (code1 == VOID_TYPE || code2 == VOID_TYPE) - { - if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE)) - pedwarn ("ANSI C forbids conditional expr with only one void side"); - result_type = void_type_node; - } - else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) - { - if (comp_target_types (type1, type2)) - result_type = common_type (type1, type2); - else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node - && TREE_CODE (orig_op1) != NOP_EXPR) - result_type = qualify_type (type2, type1); - else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node - && TREE_CODE (orig_op2) != NOP_EXPR) - result_type = qualify_type (type1, type2); - else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node) - { - if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer"); - result_type = qualify_type (type1, type2); - } - else if (TYPE_MAIN_VARIANT (TREE_TYPE (type2)) == void_type_node) - { - if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer"); - result_type = qualify_type (type2, type1); - } - else - { - pedwarn ("pointer type mismatch in conditional expression"); - result_type = build_pointer_type (void_type_node); - } - } - else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) - { - if (! integer_zerop (op2)) - pedwarn ("pointer/integer type mismatch in conditional expression"); - else - { - op2 = null_pointer_node; -#if 0 /* The spec seems to say this is permitted. */ - if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between 0 and function pointer"); -#endif - } - result_type = type1; - } - else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - if (!integer_zerop (op1)) - pedwarn ("pointer/integer type mismatch in conditional expression"); - else - { - op1 = null_pointer_node; -#if 0 /* The spec seems to say this is permitted. */ - if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between 0 and function pointer"); -#endif - } - result_type = type2; - } - - if (!result_type) - { - if (flag_cond_mismatch) - result_type = void_type_node; - else - { - error ("type mismatch in conditional expression"); - return error_mark_node; - } - } - - /* Merge const and volatile flags of the incoming types. */ - result_type - = build_type_variant (result_type, - TREE_READONLY (op1) || TREE_READONLY (op2), - TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2)); - - if (result_type != TREE_TYPE (op1)) - op1 = convert_and_check (result_type, op1); - if (result_type != TREE_TYPE (op2)) - op2 = convert_and_check (result_type, op2); - -#if 0 - if (code1 == RECORD_TYPE || code1 == UNION_TYPE) - { - result_type = TREE_TYPE (op1); - if (TREE_CONSTANT (ifexp)) - return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); - - if (TYPE_MODE (result_type) == BLKmode) - { - register tree tempvar - = build_decl (VAR_DECL, NULL_TREE, result_type); - register tree xop1 = build_modify_expr (tempvar, op1); - register tree xop2 = build_modify_expr (tempvar, op2); - register tree result = fold (build (COND_EXPR, result_type, - ifexp, xop1, xop2)); - - layout_decl (tempvar, TYPE_ALIGN (result_type)); - /* No way to handle variable-sized objects here. - I fear that the entire handling of BLKmode conditional exprs - needs to be redone. */ - if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST) - abort (); - DECL_RTL (tempvar) - = assign_stack_local (DECL_MODE (tempvar), - (TREE_INT_CST_LOW (DECL_SIZE (tempvar)) - + BITS_PER_UNIT - 1) - / BITS_PER_UNIT, - 0); - - TREE_SIDE_EFFECTS (result) - = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1) - | TREE_SIDE_EFFECTS (op2); - return build (COMPOUND_EXPR, result_type, result, tempvar); - } - } -#endif /* 0 */ - - if (TREE_CODE (ifexp) == INTEGER_CST) - return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); - - return fold (build (COND_EXPR, result_type, ifexp, op1, op2)); -} - -/* Given a list of expressions, return a compound expression - that performs them all and returns the value of the last of them. */ - -tree -build_compound_expr (list) - tree list; -{ - return internal_build_compound_expr (list, TRUE); -} - -static tree -internal_build_compound_expr (list, first_p) - tree list; - int first_p; -{ - register tree rest; - - if (TREE_CHAIN (list) == 0) - { -#if 0 /* If something inside inhibited lvalueness, we should not override. */ - /* Consider (x, y+0), which is not an lvalue since y+0 is not. */ - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (TREE_CODE (list) == NON_LVALUE_EXPR) - list = TREE_OPERAND (list, 0); -#endif - - /* Don't let (0, 0) be null pointer constant. */ - if (!first_p && integer_zerop (TREE_VALUE (list))) - return non_lvalue (TREE_VALUE (list)); - return TREE_VALUE (list); - } - - if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0) - { - /* Convert arrays to pointers when there really is a comma operator. */ - if (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (list)))) == ARRAY_TYPE) - TREE_VALUE (TREE_CHAIN (list)) - = default_conversion (TREE_VALUE (TREE_CHAIN (list))); - } - - rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE); - - /* When pedantic, a compound expression can be neither an lvalue - nor an integer constant expression. */ - if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)) && ! pedantic) - return rest; - - return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest); -} - -/* Build an expression representing a cast to type TYPE of expression EXPR. */ - -tree -build_c_cast (type, expr) - register tree type; - tree expr; -{ - register tree value = expr; - - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - type = TYPE_MAIN_VARIANT (type); - -#if 0 - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (TREE_CODE (value) == NON_LVALUE_EXPR) - value = TREE_OPERAND (value, 0); -#endif - - if (TREE_CODE (type) == ARRAY_TYPE) - { - error ("cast specifies array type"); - return error_mark_node; - } - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("cast specifies function type"); - return error_mark_node; - } - - if (type == TREE_TYPE (value)) - { - if (pedantic) - { - if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - pedwarn ("ANSI C forbids casting nonscalar to the same type"); - } - } - else if (TREE_CODE (type) == UNION_TYPE) - { - tree field; - if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE) - value = default_conversion (value); - - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)), - TYPE_MAIN_VARIANT (TREE_TYPE (value)))) - break; - - if (field) - { - char *name; - tree t; - - if (pedantic) - pedwarn ("ANSI C forbids casts to union type"); - if (TYPE_NAME (type) != 0) - { - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - name = IDENTIFIER_POINTER (TYPE_NAME (type)); - else - name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - } - else - name = ""; - t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE, - build_tree_list (field, value)), - 0, 0); - TREE_CONSTANT (t) = TREE_CONSTANT (value); - return t; - } - error ("cast to union type from type not present in union"); - return error_mark_node; - } - else - { - tree otype, ovalue; - - /* If casting to void, avoid the error that would come - from default_conversion in the case of a non-lvalue array. */ - if (type == void_type_node) - return build1 (CONVERT_EXPR, type, value); - - /* Convert functions and arrays to pointers, - but don't convert any other types. */ - if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE) - value = default_conversion (value); - otype = TREE_TYPE (value); - - /* Optionally warn about potentially worrisome casts. */ - - if (warn_cast_qual - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE) - { - if (TYPE_VOLATILE (TREE_TYPE (otype)) - && ! TYPE_VOLATILE (TREE_TYPE (type))) - pedwarn ("cast discards `volatile' from pointer target type"); - if (TYPE_READONLY (TREE_TYPE (otype)) - && ! TYPE_READONLY (TREE_TYPE (type))) - pedwarn ("cast discards `const' from pointer target type"); - } - - /* Warn about possible alignment problems. */ - if (STRICT_ALIGNMENT && warn_cast_align - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE - && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE - && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) - warning ("cast increases required alignment of target type"); - - if (TREE_CODE (type) == INTEGER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype) - && !TREE_CONSTANT (value)) - warning ("cast from pointer to integer of different size"); - - if (warn_bad_function_cast - && TREE_CODE (value) == CALL_EXPR - && TREE_CODE (type) != TREE_CODE (otype)) - warning ("cast does not match function type"); - - if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == INTEGER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype) -#if 0 - /* Don't warn about converting 0 to pointer, - provided the 0 was explicit--not cast or made by folding. */ - && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)) -#endif - /* Don't warn about converting any constant. */ - && !TREE_CONSTANT (value)) - warning ("cast to pointer from integer of different size"); - - ovalue = value; - value = convert (type, value); - - /* Ignore any integer overflow caused by the cast. */ - if (TREE_CODE (value) == INTEGER_CST) - { - TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); - TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue); - } - } - - /* Pedantically, don't ley (void *) (FOO *) 0 be a null pointer constant. */ - if (pedantic && TREE_CODE (value) == INTEGER_CST - && TREE_CODE (expr) == INTEGER_CST - && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE) - value = non_lvalue (value); - - /* If pedantic, don't let a cast be an lvalue. */ - if (value == expr && pedantic) - value = non_lvalue (value); - - return value; -} - -/* Build an assignment expression of lvalue LHS from value RHS. - MODIFYCODE is the code for a binary operator that we use - to combine the old value of LHS with RHS to get the new value. - Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */ - -tree -build_modify_expr (lhs, modifycode, rhs) - tree lhs, rhs; - enum tree_code modifycode; -{ - register tree result; - tree newrhs; - tree lhstype = TREE_TYPE (lhs); - tree olhstype = lhstype; - - /* Types that aren't fully specified cannot be used in assignments. */ - lhs = require_complete_type (lhs); - - /* Avoid duplicate error messages from operands that had errors. */ - if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK) - return error_mark_node; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here. We do not want an enumerator - whose value is 0 to count as a null pointer constant. */ - if (TREE_CODE (rhs) == NON_LVALUE_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - newrhs = rhs; - - /* Handle control structure constructs used as "lvalues". */ - - switch (TREE_CODE (lhs)) - { - /* Handle (a, b) used as an "lvalue". */ - case COMPOUND_EXPR: - pedantic_lvalue_warning (COMPOUND_EXPR); - newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), - modifycode, rhs); - if (TREE_CODE (newrhs) == ERROR_MARK) - return error_mark_node; - return build (COMPOUND_EXPR, lhstype, - TREE_OPERAND (lhs, 0), newrhs); - - /* Handle (a ? b : c) used as an "lvalue". */ - case COND_EXPR: - pedantic_lvalue_warning (COND_EXPR); - rhs = save_expr (rhs); - { - /* Produce (a ? (b = rhs) : (c = rhs)) - except that the RHS goes through a save-expr - so the code to compute it is only emitted once. */ - tree cond - = build_conditional_expr (TREE_OPERAND (lhs, 0), - build_modify_expr (TREE_OPERAND (lhs, 1), - modifycode, rhs), - build_modify_expr (TREE_OPERAND (lhs, 2), - modifycode, rhs)); - if (TREE_CODE (cond) == ERROR_MARK) - return cond; - /* Make sure the code to compute the rhs comes out - before the split. */ - return build (COMPOUND_EXPR, TREE_TYPE (lhs), - /* But cast it to void to avoid an "unused" error. */ - convert (void_type_node, rhs), cond); - } - } - - /* If a binary op has been requested, combine the old LHS value with the RHS - producing the value we should actually store into the LHS. */ - - if (modifycode != NOP_EXPR) - { - lhs = stabilize_reference (lhs); - newrhs = build_binary_op (modifycode, lhs, rhs, 1); - } - - /* Handle a cast used as an "lvalue". - We have already performed any binary operator using the value as cast. - Now convert the result to the cast type of the lhs, - and then true type of the lhs and store it there; - then convert result back to the cast type to be the value - of the assignment. */ - - switch (TREE_CODE (lhs)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE) - newrhs = default_conversion (newrhs); - { - tree inner_lhs = TREE_OPERAND (lhs, 0); - tree result; - result = build_modify_expr (inner_lhs, NOP_EXPR, - convert (TREE_TYPE (inner_lhs), - convert (lhstype, newrhs))); - if (TREE_CODE (result) == ERROR_MARK) - return result; - pedantic_lvalue_warning (CONVERT_EXPR); - return convert (TREE_TYPE (lhs), result); - } - } - - /* Now we have handled acceptable kinds of LHS that are not truly lvalues. - Reject anything strange now. */ - - if (!lvalue_or_else (lhs, "assignment")) - return error_mark_node; - - /* Warn about storing in something that is `const'. */ - - if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype) - || ((TREE_CODE (lhstype) == RECORD_TYPE - || TREE_CODE (lhstype) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (lhstype))) - readonly_warning (lhs, "assignment"); - - /* If storing into a structure or union member, - it has probably been given type `int'. - Compute the type that would go with - the actual amount of storage the member occupies. */ - - if (TREE_CODE (lhs) == COMPONENT_REF - && (TREE_CODE (lhstype) == INTEGER_TYPE - || TREE_CODE (lhstype) == REAL_TYPE - || TREE_CODE (lhstype) == ENUMERAL_TYPE)) - lhstype = TREE_TYPE (get_unwidened (lhs, 0)); - - /* If storing in a field that is in actuality a short or narrower than one, - we must store in the field in its actual type. */ - - if (lhstype != TREE_TYPE (lhs)) - { - lhs = copy_node (lhs); - TREE_TYPE (lhs) = lhstype; - } - - /* Convert new value to destination type. */ - - newrhs = convert_for_assignment (lhstype, newrhs, "assignment", - NULL_TREE, NULL_TREE, 0); - if (TREE_CODE (newrhs) == ERROR_MARK) - return error_mark_node; - - result = build (MODIFY_EXPR, lhstype, lhs, newrhs); - TREE_SIDE_EFFECTS (result) = 1; - - /* If we got the LHS in a different type for storing in, - convert the result back to the nominal type of LHS - so that the value we return always has the same type - as the LHS argument. */ - - if (olhstype == TREE_TYPE (result)) - return result; - return convert_for_assignment (olhstype, result, "assignment", - NULL_TREE, NULL_TREE, 0); -} - -/* Convert value RHS to type TYPE as preparation for an assignment - to an lvalue of type TYPE. - The real work of conversion is done by `convert'. - The purpose of this function is to generate error messages - for assignments that are not allowed in C. - ERRTYPE is a string to use in error messages: - "assignment", "return", etc. If it is null, this is parameter passing - for a function call (and different error messages are output). Otherwise, - it may be a name stored in the spelling stack and interpreted by - get_spelling. - - FUNNAME is the name of the function being called, - as an IDENTIFIER_NODE, or null. - PARMNUM is the number of the argument, for printing in error messages. */ - -static tree -convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) - tree type, rhs; - char *errtype; - tree fundecl, funname; - int parmnum; -{ - register enum tree_code codel = TREE_CODE (type); - register tree rhstype; - register enum tree_code coder; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here. We do not want an enumerator - whose value is 0 to count as a null pointer constant. */ - if (TREE_CODE (rhs) == NON_LVALUE_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE) - rhs = default_conversion (rhs); - else if (optimize && TREE_CODE (rhs) == VAR_DECL) - rhs = decl_constant_value (rhs); - - rhstype = TREE_TYPE (rhs); - coder = TREE_CODE (rhstype); - - if (coder == ERROR_MARK) - return error_mark_node; - - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) - { - overflow_warning (rhs); - /* Check for Objective-C protocols. This will issue a warning if - there are protocol violations. No need to use the return value. */ - maybe_objc_comptypes (type, rhstype, 0); - return rhs; - } - - if (coder == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - /* Arithmetic types all interconvert, and enum is treated like int. */ - if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE - || codel == COMPLEX_TYPE) - && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE - || coder == COMPLEX_TYPE)) - return convert_and_check (type, rhs); - - /* Conversion to a union from its member types. */ - else if (codel == UNION_TYPE) - { - tree memb_types; - - for (memb_types = TYPE_FIELDS (type); memb_types; - memb_types = TREE_CHAIN (memb_types)) - { - if (comptypes (TREE_TYPE (memb_types), TREE_TYPE (rhs))) - { - if (pedantic - && !(fundecl != 0 && DECL_IN_SYSTEM_HEADER (fundecl))) - pedwarn ("ANSI C prohibits argument conversion to union type"); - return build1 (NOP_EXPR, type, rhs); - } - - else if (coder == POINTER_TYPE - && TREE_CODE (TREE_TYPE (memb_types)) == POINTER_TYPE) - { - tree memb_type = TREE_TYPE (memb_types); - register tree ttl = TREE_TYPE (memb_type); - register tree ttr = TREE_TYPE (rhstype); - - /* Any non-function converts to a [const][volatile] void * - and vice versa; otherwise, targets must be the same. - Meanwhile, the lhs target must have all the qualifiers of - the rhs. */ - if (TYPE_MAIN_VARIANT (ttl) == void_type_node - || TYPE_MAIN_VARIANT (ttr) == void_type_node - || comp_target_types (memb_type, rhstype)) - { - /* Const and volatile mean something different for function - types, so the usual warnings are not appropriate. */ - if (TREE_CODE (ttr) != FUNCTION_TYPE - || TREE_CODE (ttl) != FUNCTION_TYPE) - { - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - warn_for_assignment ("%s discards `const' from pointer target type", - get_spelling (errtype), funname, - parmnum); - if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s discards `volatile' from pointer target type", - get_spelling (errtype), funname, - parmnum); - } - else - { - /* Because const and volatile on functions are - restrictions that say the function will not do - certain things, it is okay to use a const or volatile - function where an ordinary one is wanted, but not - vice-versa. */ - if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr)) - warn_for_assignment ("%s makes `const *' function pointer from non-const", - get_spelling (errtype), funname, - parmnum); - if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile", - get_spelling (errtype), funname, - parmnum); - } - - if (pedantic - && !(fundecl != 0 && DECL_IN_SYSTEM_HEADER (fundecl))) - pedwarn ("ANSI C prohibits argument conversion to union type"); - return build1 (NOP_EXPR, type, rhs); - } - } - - /* Can convert integer zero to any pointer type. */ - else if (TREE_CODE (TREE_TYPE (memb_types)) == POINTER_TYPE - && (integer_zerop (rhs) - || (TREE_CODE (rhs) == NOP_EXPR - && integer_zerop (TREE_OPERAND (rhs, 0))))) - return build1 (NOP_EXPR, type, null_pointer_node); - } - } - - /* Conversions among pointers */ - else if (codel == POINTER_TYPE && coder == POINTER_TYPE) - { - register tree ttl = TREE_TYPE (type); - register tree ttr = TREE_TYPE (rhstype); - - /* Any non-function converts to a [const][volatile] void * - and vice versa; otherwise, targets must be the same. - Meanwhile, the lhs target must have all the qualifiers of the rhs. */ - if (TYPE_MAIN_VARIANT (ttl) == void_type_node - || TYPE_MAIN_VARIANT (ttr) == void_type_node - || comp_target_types (type, rhstype) - || (unsigned_type (TYPE_MAIN_VARIANT (ttl)) - == unsigned_type (TYPE_MAIN_VARIANT (ttr)))) - { - if (pedantic - && ((TYPE_MAIN_VARIANT (ttl) == void_type_node - && TREE_CODE (ttr) == FUNCTION_TYPE) - || - (TYPE_MAIN_VARIANT (ttr) == void_type_node - /* Check TREE_CODE to catch cases like (void *) (char *) 0 - which are not ANSI null ptr constants. */ - && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR) - && TREE_CODE (ttl) == FUNCTION_TYPE))) - warn_for_assignment ("ANSI forbids %s between function pointer and `void *'", - get_spelling (errtype), funname, parmnum); - /* Const and volatile mean something different for function types, - so the usual warnings are not appropriate. */ - else if (TREE_CODE (ttr) != FUNCTION_TYPE - || TREE_CODE (ttl) != FUNCTION_TYPE) - { - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - warn_for_assignment ("%s discards `const' from pointer target type", - get_spelling (errtype), funname, parmnum); - else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s discards `volatile' from pointer target type", - get_spelling (errtype), funname, parmnum); - /* If this is not a case of ignoring a mismatch in signedness, - no warning. */ - else if (TYPE_MAIN_VARIANT (ttl) == void_type_node - || TYPE_MAIN_VARIANT (ttr) == void_type_node - || comp_target_types (type, rhstype)) - ; - /* If there is a mismatch, do warn. */ - else if (pedantic) - warn_for_assignment ("pointer targets in %s differ in signedness", - get_spelling (errtype), funname, parmnum); - } - else - { - /* Because const and volatile on functions are restrictions - that say the function will not do certain things, - it is okay to use a const or volatile function - where an ordinary one is wanted, but not vice-versa. */ - if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr)) - warn_for_assignment ("%s makes `const *' function pointer from non-const", - get_spelling (errtype), funname, parmnum); - if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile", - get_spelling (errtype), funname, parmnum); - } - } - else - warn_for_assignment ("%s from incompatible pointer type", - get_spelling (errtype), funname, parmnum); - return convert (type, rhs); - } - else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) - { - /* An explicit constant 0 can convert to a pointer, - or one that results from arithmetic, even including - a cast to integer type. */ - if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs)) - && - ! (TREE_CODE (rhs) == NOP_EXPR - && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE - && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST - && integer_zerop (TREE_OPERAND (rhs, 0)))) - { - warn_for_assignment ("%s makes pointer from integer without a cast", - get_spelling (errtype), funname, parmnum); - return convert (type, rhs); - } - return null_pointer_node; - } - else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) - { - warn_for_assignment ("%s makes integer from pointer without a cast", - get_spelling (errtype), funname, parmnum); - return convert (type, rhs); - } - - if (!errtype) - { - if (funname) - { - tree selector = maybe_building_objc_message_expr (); - - if (selector && parmnum > 2) - error ("incompatible type for argument %d of `%s'", - parmnum - 2, IDENTIFIER_POINTER (selector)); - else - error ("incompatible type for argument %d of `%s'", - parmnum, IDENTIFIER_POINTER (funname)); - } - else - error ("incompatible type for argument %d of indirect function call", - parmnum); - } - else - error ("incompatible types in %s", get_spelling (errtype)); - - return error_mark_node; -} - -/* Print a warning using MSG. - It gets OPNAME as its one parameter. - If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'". - FUNCTION and ARGNUM are handled specially if we are building an - Objective-C selector. */ - -static void -warn_for_assignment (msg, opname, function, argnum) - char *msg; - char *opname; - tree function; - int argnum; -{ - static char argstring[] = "passing arg %d of `%s'"; - static char argnofun[] = "passing arg %d"; - - if (opname == 0) - { - tree selector = maybe_building_objc_message_expr (); - - if (selector && argnum > 2) - { - function = selector; - argnum -= 2; - } - if (function) - { - /* Function name is known; supply it. */ - opname = (char *) alloca (IDENTIFIER_LENGTH (function) - + sizeof (argstring) + 25 /*%d*/ + 1); - sprintf (opname, argstring, argnum, IDENTIFIER_POINTER (function)); - } - else - { - /* Function name unknown (call through ptr); just give arg number. */ - opname = (char *) alloca (sizeof (argnofun) + 25 /*%d*/ + 1); - sprintf (opname, argnofun, argnum); - } - } - pedwarn (msg, opname); -} - -/* Return nonzero if VALUE is a valid constant-valued expression - for use in initializing a static variable; one that can be an - element of a "constant" initializer. - - Return null_pointer_node if the value is absolute; - if it is relocatable, return the variable that determines the relocation. - We assume that VALUE has been folded as much as possible; - therefore, we do not need to check for such things as - arithmetic-combinations of integers. */ - -tree -initializer_constant_valid_p (value, endtype) - tree value; - tree endtype; -{ - switch (TREE_CODE (value)) - { - case CONSTRUCTOR: - if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE - && TREE_CONSTANT (value)) - return - initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)), - endtype); - - return TREE_STATIC (value) ? null_pointer_node : 0; - - case INTEGER_CST: - case REAL_CST: - case STRING_CST: - case COMPLEX_CST: - return null_pointer_node; - - case ADDR_EXPR: - return TREE_OPERAND (value, 0); - - case NON_LVALUE_EXPR: - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - case CONVERT_EXPR: - case NOP_EXPR: - /* Allow conversions between pointer types. */ - if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between real types. */ - if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow length-preserving conversions between integer types. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (value)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between other integer types only if - explicit value. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE) - { - tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - if (inner == null_pointer_node) - return null_pointer_node; - return 0; - } - - /* Allow (int) &foo provided int is as wide as a pointer. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE - && (TYPE_PRECISION (TREE_TYPE (value)) - >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - - /* Likewise conversions from int to pointers. */ - if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (value)) - <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - - /* Allow conversions to union types if the value inside is okay. */ - if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - return 0; - - case PLUS_EXPR: - if (TREE_CODE (endtype) == INTEGER_TYPE - && TYPE_PRECISION (endtype) < POINTER_SIZE) - return 0; - { - tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), - endtype); - /* If either term is absolute, use the other terms relocation. */ - if (valid0 == null_pointer_node) - return valid1; - if (valid1 == null_pointer_node) - return valid0; - return 0; - } - - case MINUS_EXPR: - if (TREE_CODE (endtype) == INTEGER_TYPE - && TYPE_PRECISION (endtype) < POINTER_SIZE) - return 0; - { - tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), - endtype); - /* Win if second argument is absolute. */ - if (valid1 == null_pointer_node) - return valid0; - /* Win if both arguments have the same relocation. - Then the value is absolute. */ - if (valid0 == valid1) - return null_pointer_node; - return 0; - } - } - - return 0; -} - -/* If VALUE is a compound expr all of whose expressions are constant, then - return its value. Otherwise, return error_mark_node. - - This is for handling COMPOUND_EXPRs as initializer elements - which is allowed with a warning when -pedantic is specified. */ - -static tree -valid_compound_expr_initializer (value, endtype) - tree value; - tree endtype; -{ - if (TREE_CODE (value) == COMPOUND_EXPR) - { - if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype) - == error_mark_node) - return error_mark_node; - return valid_compound_expr_initializer (TREE_OPERAND (value, 1), - endtype); - } - else if (! TREE_CONSTANT (value) - && ! initializer_constant_valid_p (value, endtype)) - return error_mark_node; - else - return value; -} - -/* Perform appropriate conversions on the initial value of a variable, - store it in the declaration DECL, - and print any error messages that are appropriate. - If the init is invalid, store an ERROR_MARK. */ - -void -store_init_value (decl, init) - tree decl, init; -{ - register tree value, type; - - /* If variable's type was invalidly declared, just ignore it. */ - - type = TREE_TYPE (decl); - if (TREE_CODE (type) == ERROR_MARK) - return; - - /* Digest the specified initializer into an expression. */ - - value = digest_init (type, init, TREE_STATIC (decl), - TREE_STATIC (decl) || pedantic); - - /* Store the expression if valid; else report error. */ - -#if 0 - /* Note that this is the only place we can detect the error - in a case such as struct foo bar = (struct foo) { x, y }; - where there is one initial value which is a constructor expression. */ - if (value == error_mark_node) - ; - else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value)) - { - error ("initializer for static variable is not constant"); - value = error_mark_node; - } - else if (TREE_STATIC (decl) - && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) - { - error ("initializer for static variable uses complicated arithmetic"); - value = error_mark_node; - } - else - { - if (pedantic && TREE_CODE (value) == CONSTRUCTOR) - { - if (! TREE_CONSTANT (value)) - pedwarn ("aggregate initializer is not constant"); - else if (! TREE_STATIC (value)) - pedwarn ("aggregate initializer uses complicated arithmetic"); - } - } -#endif - - DECL_INITIAL (decl) = value; - - /* ANSI wants warnings about out-of-range constant initializers. */ - STRIP_TYPE_NOPS (value); - constant_expression_warning (value); -} - -/* Methods for storing and printing names for error messages. */ - -/* Implement a spelling stack that allows components of a name to be pushed - and popped. Each element on the stack is this structure. */ - -struct spelling -{ - int kind; - union - { - int i; - char *s; - } u; -}; - -#define SPELLING_STRING 1 -#define SPELLING_MEMBER 2 -#define SPELLING_BOUNDS 3 - -static struct spelling *spelling; /* Next stack element (unused). */ -static struct spelling *spelling_base; /* Spelling stack base. */ -static int spelling_size; /* Size of the spelling stack. */ - -/* Macros to save and restore the spelling stack around push_... functions. - Alternative to SAVE_SPELLING_STACK. */ - -#define SPELLING_DEPTH() (spelling - spelling_base) -#define RESTORE_SPELLING_DEPTH(depth) (spelling = spelling_base + depth) - -/* Save and restore the spelling stack around arbitrary C code. */ - -#define SAVE_SPELLING_DEPTH(code) \ -{ \ - int __depth = SPELLING_DEPTH (); \ - code; \ - RESTORE_SPELLING_DEPTH (__depth); \ -} - -/* Push an element on the spelling stack with type KIND and assign VALUE - to MEMBER. */ - -#define PUSH_SPELLING(KIND, VALUE, MEMBER) \ -{ \ - int depth = SPELLING_DEPTH (); \ - \ - if (depth >= spelling_size) \ - { \ - spelling_size += 10; \ - if (spelling_base == 0) \ - spelling_base \ - = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling)); \ - else \ - spelling_base \ - = (struct spelling *) xrealloc (spelling_base, \ - spelling_size * sizeof (struct spelling)); \ - RESTORE_SPELLING_DEPTH (depth); \ - } \ - \ - spelling->kind = (KIND); \ - spelling->MEMBER = (VALUE); \ - spelling++; \ -} - -/* Push STRING on the stack. Printed literally. */ - -static void -push_string (string) - char *string; -{ - PUSH_SPELLING (SPELLING_STRING, string, u.s); -} - -/* Push a member name on the stack. Printed as '.' STRING. */ - -static void -push_member_name (decl) - tree decl; - -{ - char *string - = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>"; - PUSH_SPELLING (SPELLING_MEMBER, string, u.s); -} - -/* Push an array bounds on the stack. Printed as [BOUNDS]. */ - -static void -push_array_bounds (bounds) - int bounds; -{ - PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i); -} - -/* Compute the maximum size in bytes of the printed spelling. */ - -static int -spelling_length () -{ - register int size = 0; - register struct spelling *p; - - for (p = spelling_base; p < spelling; p++) - { - if (p->kind == SPELLING_BOUNDS) - size += 25; - else - size += strlen (p->u.s) + 1; - } - - return size; -} - -/* Print the spelling to BUFFER and return it. */ - -static char * -print_spelling (buffer) - register char *buffer; -{ - register char *d = buffer; - register char *s; - register struct spelling *p; - - for (p = spelling_base; p < spelling; p++) - if (p->kind == SPELLING_BOUNDS) - { - sprintf (d, "[%d]", p->u.i); - d += strlen (d); - } - else - { - if (p->kind == SPELLING_MEMBER) - *d++ = '.'; - for (s = p->u.s; *d = *s++; d++) - ; - } - *d++ = '\0'; - return buffer; -} - -/* Provide a means to pass component names derived from the spelling stack. */ - -char initialization_message; - -/* Interpret the spelling of the given ERRTYPE message. */ - -static char * -get_spelling (errtype) - char *errtype; -{ - static char *buffer; - static int size = -1; - - if (errtype == &initialization_message) - { - /* Avoid counting chars */ - static char message[] = "initialization of `%s'"; - register int needed = sizeof (message) + spelling_length () + 1; - char *temp; - - if (size < 0) - buffer = (char *) xmalloc (size = needed); - if (needed > size) - buffer = (char *) xrealloc (buffer, size = needed); - - temp = (char *) alloca (needed); - sprintf (buffer, message, print_spelling (temp)); - return buffer; - } - - return errtype; -} - -/* Issue an error message for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ - -void -error_init (format, local, ofwhat) - char *format, *local, *ofwhat; -{ - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); - - if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - error (format, buffer); -} - -/* Issue a pedantic warning for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ - -void -pedwarn_init (format, local, ofwhat) - char *format, *local, *ofwhat; -{ - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); - - if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - pedwarn (format, buffer); -} - -/* Issue a warning for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ - -static void -warning_init (format, local, ofwhat) - char *format, *local, *ofwhat; -{ - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); - - if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - warning (format, buffer); -} - -/* Digest the parser output INIT as an initializer for type TYPE. - Return a C expression of type TYPE to represent the initial value. - - The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors - if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT - applies only to elements of constructors. */ - -static tree -digest_init (type, init, require_constant, constructor_constant) - tree type, init; - int require_constant, constructor_constant; -{ - enum tree_code code = TREE_CODE (type); - tree inside_init = init; - - if (init == error_mark_node) - return init; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here. We do not want an enumerator - whose value is 0 to count as a null pointer constant. */ - if (TREE_CODE (init) == NON_LVALUE_EXPR) - inside_init = TREE_OPERAND (init, 0); - - /* Initialization of an array of chars from a string constant - optionally enclosed in braces. */ - - if (code == ARRAY_TYPE) - { - tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - if ((typ1 == char_type_node - || typ1 == signed_char_type_node - || typ1 == unsigned_char_type_node - || typ1 == unsigned_wchar_type_node - || typ1 == signed_wchar_type_node) - && ((inside_init && TREE_CODE (inside_init) == STRING_CST))) - { - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), - TYPE_MAIN_VARIANT (type))) - return inside_init; - - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) - != char_type_node) - && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) - { - error_init ("char-array%s initialized from wide string", - " `%s'", NULL); - return error_mark_node; - } - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) - == char_type_node) - && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) - { - error_init ("int-array%s initialized from non-wide string", - " `%s'", NULL); - return error_mark_node; - } - - TREE_TYPE (inside_init) = type; - if (TYPE_DOMAIN (type) != 0 - && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) - { - register int size = TREE_INT_CST_LOW (TYPE_SIZE (type)); - size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT; - /* Subtract 1 (or sizeof (wchar_t)) - because it's ok to ignore the terminating null char - that is counted in the length of the constant. */ - if (size < TREE_STRING_LENGTH (inside_init) - - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node) - ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT - : 1)) - pedwarn_init ( - "initializer-string for array of chars%s is too long", - " `%s'", NULL); - } - return inside_init; - } - } - - /* Any type can be initialized - from an expression of the same type, optionally with braces. */ - - if (inside_init && TREE_TYPE (inside_init) != 0 - && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), - TYPE_MAIN_VARIANT (type)) - || (code == ARRAY_TYPE - && comptypes (TREE_TYPE (inside_init), type)) - || (code == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE) - && comptypes (TREE_TYPE (TREE_TYPE (inside_init)), - TREE_TYPE (type))))) - { - if (code == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)) - inside_init = default_conversion (inside_init); - else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST - && TREE_CODE (inside_init) != CONSTRUCTOR) - { - error_init ("array%s initialized from non-constant array expression", - " `%s'", NULL); - return error_mark_node; - } - - if (optimize && TREE_CODE (inside_init) == VAR_DECL) - inside_init = decl_constant_value (inside_init); - - /* Compound expressions can only occur here if -pedantic or - -pedantic-errors is specified. In the later case, we always want - an error. In the former case, we simply want a warning. */ - if (require_constant && pedantic - && TREE_CODE (inside_init) == COMPOUND_EXPR) - { - inside_init - = valid_compound_expr_initializer (inside_init, - TREE_TYPE (inside_init)); - if (inside_init == error_mark_node) - error_init ("initializer element%s is not constant", - " for `%s'", NULL); - else - pedwarn_init ("initializer element%s is not constant", - " for `%s'", NULL); - if (flag_pedantic_errors) - inside_init = error_mark_node; - } - else if (require_constant && ! TREE_CONSTANT (inside_init)) - { - error_init ("initializer element%s is not constant", - " for `%s'", NULL); - inside_init = error_mark_node; - } - else if (require_constant - && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", NULL); - inside_init = error_mark_node; - } - - return inside_init; - } - - /* Handle scalar types, including conversions. */ - - if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE - || code == ENUMERAL_TYPE || code == COMPLEX_TYPE) - { - /* Note that convert_for_assignment calls default_conversion - for arrays and functions. We must not call it in the - case where inside_init is a null pointer constant. */ - inside_init - = convert_for_assignment (type, init, "initialization", - NULL_TREE, NULL_TREE, 0); - - if (require_constant && ! TREE_CONSTANT (inside_init)) - { - error_init ("initializer element%s is not constant", - " for `%s'", NULL); - inside_init = error_mark_node; - } - else if (require_constant - && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", NULL); - inside_init = error_mark_node; - } - - return inside_init; - } - - /* Come here only for records and arrays. */ - - if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - { - error_init ("variable-sized object%s may not be initialized", - " `%s'", NULL); - return error_mark_node; - } - - /* Traditionally, you can write struct foo x = 0; - and it initializes the first element of x to 0. */ - if (flag_traditional) - { - tree top = 0, prev = 0; - while (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE - || TREE_CODE (type) == UNION_TYPE) - { - tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); - if (prev == 0) - top = temp; - else - TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp); - prev = temp; - if (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - else if (TYPE_FIELDS (type)) - type = TREE_TYPE (TYPE_FIELDS (type)); - else - { - error_init ("invalid initializer%s", " for `%s'", NULL); - return error_mark_node; - } - } - TREE_OPERAND (prev, 1) - = build_tree_list (NULL_TREE, - digest_init (type, init, require_constant, - constructor_constant)); - return top; - } - error_init ("invalid initializer%s", " for `%s'", NULL); - return error_mark_node; -} - -/* Handle initializers that use braces. */ - -/* Type of object we are accumulating a constructor for. - This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE. */ -static tree constructor_type; - -/* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields - left to fill. */ -static tree constructor_fields; - -/* For an ARRAY_TYPE, this is the specified index - at which to store the next element we get. - This is a special INTEGER_CST node that we modify in place. */ -static tree constructor_index; - -/* For an ARRAY_TYPE, this is the end index of the range - to intitialize with the next element, or NULL in the ordinary case - where the element is used just once. */ -static tree constructor_range_end; - -/* For an ARRAY_TYPE, this is the maximum index. */ -static tree constructor_max_index; - -/* For a RECORD_TYPE, this is the first field not yet written out. */ -static tree constructor_unfilled_fields; - -/* For an ARRAY_TYPE, this is the index of the first element - not yet written out. - This is a special INTEGER_CST node that we modify in place. */ -static tree constructor_unfilled_index; - -/* In a RECORD_TYPE, the byte index of the next consecutive field. - This is so we can generate gaps between fields, when appropriate. - This is a special INTEGER_CST node that we modify in place. */ -static tree constructor_bit_index; - -/* If we are saving up the elements rather than allocating them, - this is the list of elements so far (in reverse order, - most recent first). */ -static tree constructor_elements; - -/* 1 if so far this constructor's elements are all compile-time constants. */ -static int constructor_constant; - -/* 1 if so far this constructor's elements are all valid address constants. */ -static int constructor_simple; - -/* 1 if this constructor is erroneous so far. */ -static int constructor_erroneous; - -/* 1 if have called defer_addressed_constants. */ -static int constructor_subconstants_deferred; - -/* List of pending elements at this constructor level. - These are elements encountered out of order - which belong at places we haven't reached yet in actually - writing the output. */ -static tree constructor_pending_elts; - -/* The SPELLING_DEPTH of this constructor. */ -static int constructor_depth; - -/* 0 if implicitly pushing constructor levels is allowed. */ -int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */ - -/* 1 if this constructor level was entered implicitly. */ -static int constructor_implicit; - -static int require_constant_value; -static int require_constant_elements; - -/* 1 if it is ok to output this constructor as we read it. - 0 means must accumulate a CONSTRUCTOR expression. */ -static int constructor_incremental; - -/* DECL node for which an initializer is being read. - 0 means we are reading a constructor expression - such as (struct foo) {...}. */ -static tree constructor_decl; - -/* start_init saves the ASMSPEC arg here for really_start_incremental_init. */ -static char *constructor_asmspec; - -/* Nonzero if this is an initializer for a top-level decl. */ -static int constructor_top_level; - -/* When we finish reading a constructor expression - (constructor_decl is 0), the CONSTRUCTOR goes here. */ -static tree constructor_result; - -/* This stack has a level for each implicit or explicit level of - structuring in the initializer, including the outermost one. It - saves the values of most of the variables above. */ - -struct constructor_stack -{ - struct constructor_stack *next; - tree type; - tree fields; - tree index; - tree range_end; - tree max_index; - tree unfilled_index; - tree unfilled_fields; - tree bit_index; - tree elements; - int offset; - tree pending_elts; - int depth; - /* If nonzero, this value should replace the entire - constructor at this level. */ - tree replacement_value; - char constant; - char simple; - char implicit; - char incremental; - char erroneous; - char outer; -}; - -struct constructor_stack *constructor_stack; - -/* This stack records separate initializers that are nested. - Nested initializers can't happen in ANSI C, but GNU C allows them - in cases like { ... (struct foo) { ... } ... }. */ - -struct initializer_stack -{ - struct initializer_stack *next; - tree decl; - char *asmspec; - struct constructor_stack *constructor_stack; - tree elements; - struct spelling *spelling; - struct spelling *spelling_base; - int spelling_size; - char top_level; - char incremental; - char require_constant_value; - char require_constant_elements; - char deferred; -}; - -struct initializer_stack *initializer_stack; - -/* Prepare to parse and output the initializer for variable DECL. */ - -void -start_init (decl, asmspec_tree, top_level) - tree decl; - tree asmspec_tree; - int top_level; -{ - char *locus; - struct initializer_stack *p - = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack)); - char *asmspec = 0; - - if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); - - p->decl = constructor_decl; - p->asmspec = constructor_asmspec; - p->incremental = constructor_incremental; - p->require_constant_value = require_constant_value; - p->require_constant_elements = require_constant_elements; - p->constructor_stack = constructor_stack; - p->elements = constructor_elements; - p->spelling = spelling; - p->spelling_base = spelling_base; - p->spelling_size = spelling_size; - p->deferred = constructor_subconstants_deferred; - p->top_level = constructor_top_level; - p->next = initializer_stack; - initializer_stack = p; - - constructor_decl = decl; - constructor_incremental = top_level; - constructor_asmspec = asmspec; - constructor_subconstants_deferred = 0; - constructor_top_level = top_level; - - if (decl != 0) - { - require_constant_value = TREE_STATIC (decl); - require_constant_elements - = ((TREE_STATIC (decl) || pedantic) - /* For a scalar, you can always use any value to initialize, - even within braces. */ - && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE - || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE - || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE)); - locus = IDENTIFIER_POINTER (DECL_NAME (decl)); - constructor_incremental |= TREE_STATIC (decl); - } - else - { - require_constant_value = 0; - require_constant_elements = 0; - locus = "(anonymous)"; - } - - constructor_stack = 0; - - missing_braces_mentioned = 0; - - spelling_base = 0; - spelling_size = 0; - RESTORE_SPELLING_DEPTH (0); - - if (locus) - push_string (locus); -} - -void -finish_init () -{ - struct initializer_stack *p = initializer_stack; - - /* Output subconstants (string constants, usually) - that were referenced within this initializer and saved up. - Must do this if and only if we called defer_addressed_constants. */ - if (constructor_subconstants_deferred) - output_deferred_addressed_constants (); - - /* Free the whole constructor stack of this initializer. */ - while (constructor_stack) - { - struct constructor_stack *q = constructor_stack; - constructor_stack = q->next; - free (q); - } - - /* Pop back to the data of the outer initializer (if any). */ - constructor_decl = p->decl; - constructor_asmspec = p->asmspec; - constructor_incremental = p->incremental; - require_constant_value = p->require_constant_value; - require_constant_elements = p->require_constant_elements; - constructor_stack = p->constructor_stack; - constructor_elements = p->elements; - spelling = p->spelling; - spelling_base = p->spelling_base; - spelling_size = p->spelling_size; - constructor_subconstants_deferred = p->deferred; - constructor_top_level = p->top_level; - initializer_stack = p->next; - free (p); -} - -/* Call here when we see the initializer is surrounded by braces. - This is instead of a call to push_init_level; - it is matched by a call to pop_init_level. - - TYPE is the type to initialize, for a constructor expression. - For an initializer for a decl, TYPE is zero. */ - -void -really_start_incremental_init (type) - tree type; -{ - struct constructor_stack *p - = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); - - if (type == 0) - type = TREE_TYPE (constructor_decl); - - /* Turn off constructor_incremental if type is a struct with bitfields. - Do this before the first push, so that the corrected value - is available in finish_init. */ - check_init_type_bitfields (type); - - p->type = constructor_type; - p->fields = constructor_fields; - p->index = constructor_index; - p->range_end = constructor_range_end; - p->max_index = constructor_max_index; - p->unfilled_index = constructor_unfilled_index; - p->unfilled_fields = constructor_unfilled_fields; - p->bit_index = constructor_bit_index; - p->elements = constructor_elements; - p->constant = constructor_constant; - p->simple = constructor_simple; - p->erroneous = constructor_erroneous; - p->pending_elts = constructor_pending_elts; - p->depth = constructor_depth; - p->replacement_value = 0; - p->implicit = 0; - p->incremental = constructor_incremental; - p->outer = 0; - p->next = 0; - constructor_stack = p; - - constructor_constant = 1; - constructor_simple = 1; - constructor_depth = SPELLING_DEPTH (); - constructor_elements = 0; - constructor_pending_elts = 0; - constructor_type = type; - - if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - constructor_fields = TYPE_FIELDS (constructor_type); - /* Skip any nameless bit fields atthe beginning. */ - while (constructor_fields != 0 && DECL_BIT_FIELD (constructor_fields) - && DECL_NAME (constructor_fields) == 0) - constructor_fields = TREE_CHAIN (constructor_fields); - constructor_unfilled_fields = constructor_fields; - constructor_bit_index = copy_node (integer_zero_node); - } - else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - constructor_range_end = 0; - if (TYPE_DOMAIN (constructor_type)) - { - constructor_max_index - = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); - constructor_index - = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); - } - else - constructor_index = copy_node (integer_zero_node); - constructor_unfilled_index = copy_node (constructor_index); - } - else - { - /* Handle the case of int x = {5}; */ - constructor_fields = constructor_type; - constructor_unfilled_fields = constructor_type; - } - - if (constructor_incremental) - { - int momentary = suspend_momentary (); - push_obstacks_nochange (); - if (TREE_PERMANENT (constructor_decl)) - end_temporary_allocation (); - make_decl_rtl (constructor_decl, constructor_asmspec, - constructor_top_level); - assemble_variable (constructor_decl, constructor_top_level, 0, 1); - pop_obstacks (); - resume_momentary (momentary); - } - - if (constructor_incremental) - { - defer_addressed_constants (); - constructor_subconstants_deferred = 1; - } -} - -/* Push down into a subobject, for initialization. - If this is for an explicit set of braces, IMPLICIT is 0. - If it is because the next element belongs at a lower level, - IMPLICIT is 1. */ - -void -push_init_level (implicit) - int implicit; -{ - struct constructor_stack *p; - - /* If we've exhausted any levels that didn't have braces, - pop them now. */ - while (constructor_stack->implicit) - { - if ((TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - && constructor_fields == 0) - process_init_element (pop_init_level (1)); - else if (TREE_CODE (constructor_type) == ARRAY_TYPE - && tree_int_cst_lt (constructor_max_index, constructor_index)) - process_init_element (pop_init_level (1)); - else - break; - } - - /* Structure elements may require alignment. Do this now - if necessary for the subaggregate. */ - if (constructor_incremental && constructor_type != 0 - && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_fields) - { - /* Advance to offset of this element. */ - if (! tree_int_cst_equal (constructor_bit_index, - DECL_FIELD_BITPOS (constructor_fields))) - { - int next = (TREE_INT_CST_LOW - (DECL_FIELD_BITPOS (constructor_fields)) - / BITS_PER_UNIT); - int here = (TREE_INT_CST_LOW (constructor_bit_index) - / BITS_PER_UNIT); - - assemble_zeros (next - here); - } - } - - p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); - p->type = constructor_type; - p->fields = constructor_fields; - p->index = constructor_index; - p->range_end = constructor_range_end; - p->max_index = constructor_max_index; - p->unfilled_index = constructor_unfilled_index; - p->unfilled_fields = constructor_unfilled_fields; - p->bit_index = constructor_bit_index; - p->elements = constructor_elements; - p->constant = constructor_constant; - p->simple = constructor_simple; - p->erroneous = constructor_erroneous; - p->pending_elts = constructor_pending_elts; - p->depth = constructor_depth; - p->replacement_value = 0; - p->implicit = implicit; - p->incremental = constructor_incremental; - p->outer = 0; - p->next = constructor_stack; - constructor_stack = p; - - constructor_constant = 1; - constructor_simple = 1; - constructor_depth = SPELLING_DEPTH (); - constructor_elements = 0; - constructor_pending_elts = 0; - - /* Don't die if an entire brace-pair level is superfluous - in the containing level. */ - if (constructor_type == 0) - ; - else if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - /* Don't die if there are extra init elts at the end. */ - if (constructor_fields == 0) - constructor_type = 0; - else - { - constructor_type = TREE_TYPE (constructor_fields); - push_member_name (constructor_fields); - if (constructor_fields != constructor_unfilled_fields) - constructor_incremental = 0; - } - } - else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - constructor_type = TREE_TYPE (constructor_type); - push_array_bounds (TREE_INT_CST_LOW (constructor_index)); - if (! tree_int_cst_equal (constructor_index, constructor_unfilled_index) - || constructor_range_end != 0) - constructor_incremental = 0; - } - - if (constructor_type == 0) - { - error_init ("extra brace group at end of initializer%s", - " for `%s'", NULL); - constructor_fields = 0; - constructor_unfilled_fields = 0; - return; - } - - /* Turn off constructor_incremental if type is a struct with bitfields. */ - check_init_type_bitfields (constructor_type); - - if (implicit && warn_missing_braces && !missing_braces_mentioned) - { - missing_braces_mentioned = 1; - warning_init ("missing braces around initializer%s", " for `%s'", NULL); - } - - if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - constructor_fields = TYPE_FIELDS (constructor_type); - /* Skip any nameless bit fields atthe beginning. */ - while (constructor_fields != 0 && DECL_BIT_FIELD (constructor_fields) - && DECL_NAME (constructor_fields) == 0) - constructor_fields = TREE_CHAIN (constructor_fields); - constructor_unfilled_fields = constructor_fields; - constructor_bit_index = copy_node (integer_zero_node); - } - else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - constructor_range_end = 0; - if (TYPE_DOMAIN (constructor_type)) - { - constructor_max_index - = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); - constructor_index - = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); - } - else - constructor_index = copy_node (integer_zero_node); - constructor_unfilled_index = copy_node (constructor_index); - } - else - { - warning_init ("braces around scalar initializer%s", " for `%s'", NULL); - constructor_fields = constructor_type; - constructor_unfilled_fields = constructor_type; - } -} - -/* Don't read a struct incrementally if it has any bitfields, - because the incremental reading code doesn't know how to - handle bitfields yet. */ - -static void -check_init_type_bitfields (type) - tree type; -{ - if (TREE_CODE (type) == RECORD_TYPE) - { - tree tail; - for (tail = TYPE_FIELDS (type); tail; - tail = TREE_CHAIN (tail)) - { - if (DECL_BIT_FIELD (tail) - /* This catches cases like `int foo : 8;'. */ - || DECL_MODE (tail) != TYPE_MODE (TREE_TYPE (tail))) - { - constructor_incremental = 0; - break; - } - - check_init_type_bitfields (TREE_TYPE (tail)); - } - } - - else if (TREE_CODE (type) == ARRAY_TYPE) - check_init_type_bitfields (TREE_TYPE (type)); -} - -/* At the end of an implicit or explicit brace level, - finish up that level of constructor. - If we were outputting the elements as they are read, return 0 - from inner levels (process_init_element ignores that), - but return error_mark_node from the outermost level - (that's what we want to put in DECL_INITIAL). - Otherwise, return a CONSTRUCTOR expression. */ - -tree -pop_init_level (implicit) - int implicit; -{ - struct constructor_stack *p; - int size = 0; - tree constructor = 0; - - if (implicit == 0) - { - /* When we come to an explicit close brace, - pop any inner levels that didn't have explicit braces. */ - while (constructor_stack->implicit) - process_init_element (pop_init_level (1)); - } - - p = constructor_stack; - - if (constructor_type != 0) - size = int_size_in_bytes (constructor_type); - - /* Now output all pending elements. */ - output_pending_init_elements (1); - -#if 0 /* c-parse.in warns about {}. */ - /* In ANSI, each brace level must have at least one element. */ - if (! implicit && pedantic - && (TREE_CODE (constructor_type) == ARRAY_TYPE - ? integer_zerop (constructor_unfilled_index) - : constructor_unfilled_fields == TYPE_FIELDS (constructor_type))) - pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL); -#endif - - /* Pad out the end of the structure. */ - - if (p->replacement_value) - { - /* If this closes a superfluous brace pair, - just pass out the element between them. */ - constructor = p->replacement_value; - /* If this is the top level thing within the initializer, - and it's for a variable, then since we already called - assemble_variable, we must output the value now. */ - if (p->next == 0 && constructor_decl != 0 - && constructor_incremental) - { - constructor = digest_init (constructor_type, constructor, - 0, 0); - - /* If initializing an array of unknown size, - determine the size now. */ - if (TREE_CODE (constructor_type) == ARRAY_TYPE - && TYPE_DOMAIN (constructor_type) == 0) - { - int failure; - int momentary_p; - - push_obstacks_nochange (); - if (TREE_PERMANENT (constructor_type)) - end_temporary_allocation (); - - momentary_p = suspend_momentary (); - - /* We shouldn't have an incomplete array type within - some other type. */ - if (constructor_stack->next) - abort (); - - failure - = complete_array_type (constructor_type, - constructor, 0); - if (failure) - abort (); - - size = int_size_in_bytes (constructor_type); - resume_momentary (momentary_p); - pop_obstacks (); - } - - output_constant (constructor, size); - } - } - else if (constructor_type == 0) - ; - else if (TREE_CODE (constructor_type) != RECORD_TYPE - && TREE_CODE (constructor_type) != UNION_TYPE - && TREE_CODE (constructor_type) != ARRAY_TYPE - && ! constructor_incremental) - { - /* A nonincremental scalar initializer--just return - the element, after verifying there is just one. */ - if (constructor_elements == 0) - { - error_init ("empty scalar initializer%s", - " for `%s'", NULL); - constructor = error_mark_node; - } - else if (TREE_CHAIN (constructor_elements) != 0) - { - error_init ("extra elements in scalar initializer%s", - " for `%s'", NULL); - constructor = TREE_VALUE (constructor_elements); - } - else - constructor = TREE_VALUE (constructor_elements); - } - else if (! constructor_incremental) - { - if (constructor_erroneous) - constructor = error_mark_node; - else - { - int momentary = suspend_momentary (); - - constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE, - nreverse (constructor_elements)); - if (constructor_constant) - TREE_CONSTANT (constructor) = 1; - if (constructor_constant && constructor_simple) - TREE_STATIC (constructor) = 1; - - resume_momentary (momentary); - } - } - else - { - tree filled; - int momentary = suspend_momentary (); - - if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - /* Find the offset of the end of that field. */ - filled = size_binop (CEIL_DIV_EXPR, - constructor_bit_index, - size_int (BITS_PER_UNIT)); - } - else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - /* If initializing an array of unknown size, - determine the size now. */ - if (TREE_CODE (constructor_type) == ARRAY_TYPE - && TYPE_DOMAIN (constructor_type) == 0) - { - tree maxindex - = size_binop (MINUS_EXPR, - constructor_unfilled_index, - integer_one_node); - - push_obstacks_nochange (); - if (TREE_PERMANENT (constructor_type)) - end_temporary_allocation (); - maxindex = copy_node (maxindex); - TYPE_DOMAIN (constructor_type) = build_index_type (maxindex); - TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type); - - /* TYPE_MAX_VALUE is always one less than the number of elements - in the array, because we start counting at zero. Therefore, - warn only if the value is less than zero. */ - if (pedantic - && (tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type))) - < 0)) - error_with_decl (constructor_decl, - "zero or negative array size `%s'"); - layout_type (constructor_type); - size = int_size_in_bytes (constructor_type); - pop_obstacks (); - } - - filled = size_binop (MULT_EXPR, constructor_unfilled_index, - size_in_bytes (TREE_TYPE (constructor_type))); - } - else - filled = 0; - - if (filled != 0) - assemble_zeros (size - TREE_INT_CST_LOW (filled)); - - resume_momentary (momentary); - } - - - constructor_type = p->type; - constructor_fields = p->fields; - constructor_index = p->index; - constructor_range_end = p->range_end; - constructor_max_index = p->max_index; - constructor_unfilled_index = p->unfilled_index; - constructor_unfilled_fields = p->unfilled_fields; - constructor_bit_index = p->bit_index; - constructor_elements = p->elements; - constructor_constant = p->constant; - constructor_simple = p->simple; - constructor_erroneous = p->erroneous; - constructor_pending_elts = p->pending_elts; - constructor_depth = p->depth; - constructor_incremental = p->incremental; - RESTORE_SPELLING_DEPTH (constructor_depth); - - constructor_stack = p->next; - free (p); - - if (constructor == 0) - { - if (constructor_stack == 0) - return error_mark_node; - return NULL_TREE; - } - return constructor; -} - -/* Within an array initializer, specify the next index to be initialized. - FIRST is that index. If LAST is nonzero, then initialize a range - of indices, running from FIRST through LAST. */ - -void -set_init_index (first, last) - tree first, last; -{ - while ((TREE_CODE (first) == NOP_EXPR - || TREE_CODE (first) == CONVERT_EXPR - || TREE_CODE (first) == NON_LVALUE_EXPR) - && (TYPE_MODE (TREE_TYPE (first)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0))))) - (first) = TREE_OPERAND (first, 0); - if (last) - while ((TREE_CODE (last) == NOP_EXPR - || TREE_CODE (last) == CONVERT_EXPR - || TREE_CODE (last) == NON_LVALUE_EXPR) - && (TYPE_MODE (TREE_TYPE (last)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0))))) - (last) = TREE_OPERAND (last, 0); - - if (TREE_CODE (first) != INTEGER_CST) - error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); - else if (last != 0 && TREE_CODE (last) != INTEGER_CST) - error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); - else if (tree_int_cst_lt (first, constructor_unfilled_index)) - error_init ("duplicate array index in initializer%s", " for `%s'", NULL); - else - { - TREE_INT_CST_LOW (constructor_index) - = TREE_INT_CST_LOW (first); - TREE_INT_CST_HIGH (constructor_index) - = TREE_INT_CST_HIGH (first); - - if (last != 0 && tree_int_cst_lt (last, first)) - error_init ("empty index range in initializer%s", " for `%s'", NULL); - else - { - if (pedantic) - pedwarn ("ANSI C forbids specifying element to initialize"); - constructor_range_end = last; - } - } -} - -/* Within a struct initializer, specify the next field to be initialized. */ - -void -set_init_label (fieldname) - tree fieldname; -{ - tree tail; - int passed = 0; - - for (tail = TYPE_FIELDS (constructor_type); tail; - tail = TREE_CHAIN (tail)) - { - if (tail == constructor_unfilled_fields) - passed = 1; - if (DECL_NAME (tail) == fieldname) - break; - } - - if (tail == 0) - error ("unknown field `%s' specified in initializer", - IDENTIFIER_POINTER (fieldname)); - else if (!passed) - error ("field `%s' already initialized", - IDENTIFIER_POINTER (fieldname)); - else - { - constructor_fields = tail; - if (pedantic) - pedwarn ("ANSI C forbids specifying structure member to initialize"); - } -} - -/* "Output" the next constructor element. - At top level, really output it to assembler code now. - Otherwise, collect it in a list from which we will make a CONSTRUCTOR. - TYPE is the data type that the containing data type wants here. - FIELD is the field (a FIELD_DECL) or the index that this element fills. - - PENDING if non-nil means output pending elements that belong - right after this element. (PENDING is normally 1; - it is 0 while outputting pending elements, to avoid recursion.) */ - -static void -output_init_element (value, type, field, pending) - tree value, type, field; - int pending; -{ - int duplicate = 0; - - if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE - || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE - && !(TREE_CODE (value) == STRING_CST - && TREE_CODE (type) == ARRAY_TYPE - && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE) - && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)), - TYPE_MAIN_VARIANT (type)))) - value = default_conversion (value); - - if (value == error_mark_node) - constructor_erroneous = 1; - else if (!TREE_CONSTANT (value)) - constructor_constant = 0; - else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) - constructor_simple = 0; - - if (require_constant_value && ! TREE_CONSTANT (value)) - { - error_init ("initializer element%s is not constant", - " for `%s'", NULL); - value = error_mark_node; - } - else if (require_constant_elements - && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", NULL); - value = error_mark_node; - } - - /* If this element duplicates one on constructor_pending_elts, - print a message and ignore it. Don't do this when we're - processing elements taken off constructor_pending_elts, - because we'd always get spurious errors. */ - if (pending) - { - if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - if (purpose_member (field, constructor_pending_elts)) - { - error_init ("duplicate initializer%s", " for `%s'", NULL); - duplicate = 1; - } - } - if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - tree tail; - for (tail = constructor_pending_elts; tail; - tail = TREE_CHAIN (tail)) - if (TREE_PURPOSE (tail) != 0 - && TREE_CODE (TREE_PURPOSE (tail)) == INTEGER_CST - && tree_int_cst_equal (TREE_PURPOSE (tail), constructor_index)) - break; - - if (tail != 0) - { - error_init ("duplicate initializer%s", " for `%s'", NULL); - duplicate = 1; - } - } - } - - /* If this element doesn't come next in sequence, - put it on constructor_pending_elts. */ - if (TREE_CODE (constructor_type) == ARRAY_TYPE - && !tree_int_cst_equal (field, constructor_unfilled_index)) - { - if (! duplicate) - /* The copy_node is needed in case field is actually - constructor_index, which is modified in place. */ - constructor_pending_elts - = tree_cons (copy_node (field), - digest_init (type, value, 0, 0), - constructor_pending_elts); - } - else if (TREE_CODE (constructor_type) == RECORD_TYPE - && field != constructor_unfilled_fields) - { - /* We do this for records but not for unions. In a union, - no matter which field is specified, it can be initialized - right away since it starts at the beginning of the union. */ - if (!duplicate) - constructor_pending_elts - = tree_cons (field, - digest_init (type, value, 0, 0), - constructor_pending_elts); - } - else - { - /* Otherwise, output this element either to - constructor_elements or to the assembler file. */ - - if (!duplicate) - { - if (! constructor_incremental) - { - if (field && TREE_CODE (field) == INTEGER_CST) - field = copy_node (field); - constructor_elements - = tree_cons (field, digest_init (type, value, 0, 0), - constructor_elements); - } - else - { - /* Structure elements may require alignment. - Do this, if necessary. */ - if (TREE_CODE (constructor_type) == RECORD_TYPE) - { - /* Advance to offset of this element. */ - if (! tree_int_cst_equal (constructor_bit_index, - DECL_FIELD_BITPOS (field))) - { - int next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) - / BITS_PER_UNIT); - int here = (TREE_INT_CST_LOW (constructor_bit_index) - / BITS_PER_UNIT); - - assemble_zeros (next - here); - } - } - output_constant (digest_init (type, value, 0, 0), - int_size_in_bytes (type)); - - /* For a record or union, - keep track of end position of last field. */ - if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (field), - DECL_SIZE (field)); - TREE_INT_CST_LOW (constructor_bit_index) - = TREE_INT_CST_LOW (temp); - TREE_INT_CST_HIGH (constructor_bit_index) - = TREE_INT_CST_HIGH (temp); - } - } - } - - /* Advance the variable that indicates sequential elements output. */ - if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index, - integer_one_node); - TREE_INT_CST_LOW (constructor_unfilled_index) - = TREE_INT_CST_LOW (tem); - TREE_INT_CST_HIGH (constructor_unfilled_index) - = TREE_INT_CST_HIGH (tem); - } - else if (TREE_CODE (constructor_type) == RECORD_TYPE) - constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); - else if (TREE_CODE (constructor_type) == UNION_TYPE) - constructor_unfilled_fields = 0; - - /* Now output any pending elements which have become next. */ - if (pending) - output_pending_init_elements (0); - } -} - -/* Output any pending elements which have become next. - As we output elements, constructor_unfilled_{fields,index} - advances, which may cause other elements to become next; - if so, they too are output. - - If ALL is 0, we return when there are - no more pending elements to output now. - - If ALL is 1, we output space as necessary so that - we can output all the pending elements. */ - -static void -output_pending_init_elements (all) - int all; -{ - tree tail; - tree next; - - retry: - - /* Look thru the whole pending list. - If we find an element that should be output now, - output it. Otherwise, set NEXT to the element - that comes first among those still pending. */ - - next = 0; - for (tail = constructor_pending_elts; tail; - tail = TREE_CHAIN (tail)) - { - if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - if (tree_int_cst_equal (TREE_PURPOSE (tail), - constructor_unfilled_index)) - { - output_init_element (TREE_VALUE (tail), - TREE_TYPE (constructor_type), - constructor_unfilled_index, 0); - goto retry; - } - else if (tree_int_cst_lt (TREE_PURPOSE (tail), - constructor_unfilled_index)) - ; - else if (next == 0 - || tree_int_cst_lt (TREE_PURPOSE (tail), next)) - next = TREE_PURPOSE (tail); - } - else if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - if (TREE_PURPOSE (tail) == constructor_unfilled_fields) - { - output_init_element (TREE_VALUE (tail), - TREE_TYPE (constructor_unfilled_fields), - constructor_unfilled_fields, - 0); - goto retry; - } - else if (constructor_unfilled_fields == 0 - || tree_int_cst_lt (DECL_FIELD_BITPOS (TREE_PURPOSE (tail)), - DECL_FIELD_BITPOS (constructor_unfilled_fields))) - ; - else if (next == 0 - || tree_int_cst_lt (DECL_FIELD_BITPOS (TREE_PURPOSE (tail)), - DECL_FIELD_BITPOS (next))) - next = TREE_PURPOSE (tail); - } - } - - /* Ordinarily return, but not if we want to output all - and there are elements left. */ - if (! (all && next != 0)) - return; - - /* Generate space up to the position of NEXT. */ - if (constructor_incremental) - { - tree filled; - tree nextpos_tree = size_int (0); - - if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - { - /* Find the last field written out, if any. */ - for (tail = TYPE_FIELDS (constructor_type); tail; - tail = TREE_CHAIN (tail)) - if (TREE_CHAIN (tail) == constructor_unfilled_fields) - break; - - if (tail) - /* Find the offset of the end of that field. */ - filled = size_binop (CEIL_DIV_EXPR, - size_binop (PLUS_EXPR, - DECL_FIELD_BITPOS (tail), - DECL_SIZE (tail)), - size_int (BITS_PER_UNIT)); - else - filled = size_int (0); - - nextpos_tree = size_binop (CEIL_DIV_EXPR, - DECL_FIELD_BITPOS (next), - size_int (BITS_PER_UNIT)); - - TREE_INT_CST_HIGH (constructor_bit_index) - = TREE_INT_CST_HIGH (DECL_FIELD_BITPOS (next)); - TREE_INT_CST_LOW (constructor_bit_index) - = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (next)); - constructor_unfilled_fields = next; - } - else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - filled = size_binop (MULT_EXPR, constructor_unfilled_index, - size_in_bytes (TREE_TYPE (constructor_type))); - nextpos_tree - = size_binop (MULT_EXPR, next, - size_in_bytes (TREE_TYPE (constructor_type))); - TREE_INT_CST_LOW (constructor_unfilled_index) - = TREE_INT_CST_LOW (next); - TREE_INT_CST_HIGH (constructor_unfilled_index) - = TREE_INT_CST_HIGH (next); - } - else - filled = 0; - - if (filled) - { - int nextpos = TREE_INT_CST_LOW (nextpos_tree); - - assemble_zeros (nextpos - TREE_INT_CST_LOW (filled)); - } - } - else - { - /* If it's not incremental, just skip over the gap, - so that after jumping to retry we will output the next - successive element. */ - if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - constructor_unfilled_fields = next; - else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - TREE_INT_CST_LOW (constructor_unfilled_index) - = TREE_INT_CST_LOW (next); - TREE_INT_CST_HIGH (constructor_unfilled_index) - = TREE_INT_CST_HIGH (next); - } - } - - goto retry; -} - -/* Add one non-braced element to the current constructor level. - This adjusts the current position within the constructor's type. - This may also start or terminate implicit levels - to handle a partly-braced initializer. - - Once this has found the correct level for the new element, - it calls output_init_element. - - Note: if we are incrementally outputting this constructor, - this function may be called with a null argument - representing a sub-constructor that was already incrementally output. - When that happens, we output nothing, but we do the bookkeeping - to skip past that element of the current constructor. */ - -void -process_init_element (value) - tree value; -{ - tree orig_value = value; - int string_flag = value != 0 && TREE_CODE (value) == STRING_CST; - - /* Handle superfluous braces around string cst as in - char x[] = {"foo"}; */ - if (string_flag - && constructor_type - && TREE_CODE (constructor_type) == ARRAY_TYPE - && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE - && integer_zerop (constructor_unfilled_index)) - { - constructor_stack->replacement_value = value; - return; - } - - if (constructor_stack->replacement_value != 0) - { - error_init ("excess elements in struct initializer%s", - " after `%s'", NULL_PTR); - return; - } - - /* Ignore elements of a brace group if it is entirely superfluous - and has already been diagnosed. */ - if (constructor_type == 0) - return; - - /* If we've exhausted any levels that didn't have braces, - pop them now. */ - while (constructor_stack->implicit) - { - if ((TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - && constructor_fields == 0) - process_init_element (pop_init_level (1)); - else if (TREE_CODE (constructor_type) == ARRAY_TYPE - && tree_int_cst_lt (constructor_max_index, constructor_index)) - process_init_element (pop_init_level (1)); - else - break; - } - - while (1) - { - if (TREE_CODE (constructor_type) == RECORD_TYPE) - { - tree fieldtype; - enum tree_code fieldcode; - - if (constructor_fields == 0) - { - pedwarn_init ("excess elements in struct initializer%s", - " after `%s'", NULL_PTR); - break; - } - - fieldtype = TREE_TYPE (constructor_fields); - if (fieldtype != error_mark_node) - fieldtype = TYPE_MAIN_VARIANT (fieldtype); - fieldcode = TREE_CODE (fieldtype); - - /* Accept a string constant to initialize a subarray. */ - if (value != 0 - && fieldcode == ARRAY_TYPE - && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE - && string_flag) - value = orig_value; - /* Otherwise, if we have come to a subaggregate, - and we don't have an element of its type, push into it. */ - else if (value != 0 && !constructor_no_implicit - && value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype - && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE - || fieldcode == UNION_TYPE)) - { - push_init_level (1); - continue; - } - - if (value) - { - push_member_name (constructor_fields); - output_init_element (value, fieldtype, constructor_fields, 1); - RESTORE_SPELLING_DEPTH (constructor_depth); - } - else - /* Do the bookkeeping for an element that was - directly output as a constructor. */ - { - /* For a record, keep track of end position of last field. */ - tree temp = size_binop (PLUS_EXPR, - DECL_FIELD_BITPOS (constructor_fields), - DECL_SIZE (constructor_fields)); - TREE_INT_CST_LOW (constructor_bit_index) - = TREE_INT_CST_LOW (temp); - TREE_INT_CST_HIGH (constructor_bit_index) - = TREE_INT_CST_HIGH (temp); - - constructor_unfilled_fields = TREE_CHAIN (constructor_fields); - } - - constructor_fields = TREE_CHAIN (constructor_fields); - /* Skip any nameless bit fields atthe beginning. */ - while (constructor_fields != 0 && DECL_BIT_FIELD (constructor_fields) - && DECL_NAME (constructor_fields) == 0) - constructor_fields = TREE_CHAIN (constructor_fields); - break; - } - if (TREE_CODE (constructor_type) == UNION_TYPE) - { - tree fieldtype; - enum tree_code fieldcode; - - if (constructor_fields == 0) - { - pedwarn_init ("excess elements in union initializer%s", - " after `%s'", NULL_PTR); - break; - } - - fieldtype = TREE_TYPE (constructor_fields); - if (fieldtype != error_mark_node) - fieldtype = TYPE_MAIN_VARIANT (fieldtype); - fieldcode = TREE_CODE (fieldtype); - - /* Accept a string constant to initialize a subarray. */ - if (value != 0 - && fieldcode == ARRAY_TYPE - && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE - && string_flag) - value = orig_value; - /* Otherwise, if we have come to a subaggregate, - and we don't have an element of its type, push into it. */ - else if (value != 0 && !constructor_no_implicit - && value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype - && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE - || fieldcode == UNION_TYPE)) - { - push_init_level (1); - continue; - } - - if (value) - { - push_member_name (constructor_fields); - output_init_element (value, fieldtype, constructor_fields, 1); - RESTORE_SPELLING_DEPTH (constructor_depth); - } - else - /* Do the bookkeeping for an element that was - directly output as a constructor. */ - { - TREE_INT_CST_LOW (constructor_bit_index) - = TREE_INT_CST_LOW (DECL_SIZE (constructor_fields)); - TREE_INT_CST_HIGH (constructor_bit_index) - = TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields)); - - constructor_unfilled_fields = TREE_CHAIN (constructor_fields); - } - - constructor_fields = 0; - break; - } - if (TREE_CODE (constructor_type) == ARRAY_TYPE) - { - tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); - enum tree_code eltcode = TREE_CODE (elttype); - - /* Accept a string constant to initialize a subarray. */ - if (value != 0 - && eltcode == ARRAY_TYPE - && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE - && string_flag) - value = orig_value; - /* Otherwise, if we have come to a subaggregate, - and we don't have an element of its type, push into it. */ - else if (value != 0 && !constructor_no_implicit - && value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype - && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE - || eltcode == UNION_TYPE)) - { - push_init_level (1); - continue; - } - - if (constructor_max_index != 0 - && tree_int_cst_lt (constructor_max_index, constructor_index)) - { - pedwarn_init ("excess elements in array initializer%s", - " after `%s'", NULL_PTR); - break; - } - - /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once. */ - if (constructor_range_end) - value = save_expr (value); - - /* Now output the actual element. - Ordinarily, output once. - If there is a range, repeat it till we advance past the range. */ - do - { - tree tem; - - if (value) - { - push_array_bounds (TREE_INT_CST_LOW (constructor_index)); - output_init_element (value, elttype, constructor_index, 1); - RESTORE_SPELLING_DEPTH (constructor_depth); - } - - tem = size_binop (PLUS_EXPR, constructor_index, - integer_one_node); - TREE_INT_CST_LOW (constructor_index) - = TREE_INT_CST_LOW (tem); - TREE_INT_CST_HIGH (constructor_index) - = TREE_INT_CST_HIGH (tem); - - if (!value) - /* If we are doing the bookkeeping for an element that was - directly output as a constructor, - we must update constructor_unfilled_index. */ - { - TREE_INT_CST_LOW (constructor_unfilled_index) - = TREE_INT_CST_LOW (constructor_index); - TREE_INT_CST_HIGH (constructor_unfilled_index) - = TREE_INT_CST_HIGH (constructor_index); - } - } - while (! (constructor_range_end == 0 - || tree_int_cst_lt (constructor_range_end, - constructor_index))); - - break; - } - - /* Handle the sole element allowed in a braced initializer - for a scalar variable. */ - if (constructor_fields == 0) - { - pedwarn_init ("excess elements in scalar initializer%s", - " after `%s'", NULL_PTR); - break; - } - - if (value) - output_init_element (value, constructor_type, NULL_TREE, 1); - constructor_fields = 0; - break; - } - - /* If the (lexically) previous elments are not now saved, - we can discard the storage for them. */ - if (constructor_incremental && constructor_pending_elts == 0 && value != 0) - clear_momentary (); -} - -/* Expand an ASM statement with operands, handling output operands - that are not variables or INDIRECT_REFS by transforming such - cases into cases that expand_asm_operands can handle. - - Arguments are same as for expand_asm_operands. */ - -void -c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) - tree string, outputs, inputs, clobbers; - int vol; - char *filename; - int line; -{ - int noutputs = list_length (outputs); - register int i; - /* o[I] is the place that output number I should be written. */ - register tree *o = (tree *) alloca (noutputs * sizeof (tree)); - register tree tail; - - if (TREE_CODE (string) == ADDR_EXPR) - string = TREE_OPERAND (string, 0); - if (TREE_CODE (string) != STRING_CST) - { - error ("asm template is not a string constant"); - return; - } - - /* Record the contents of OUTPUTS before it is modified. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - o[i] = TREE_VALUE (tail); - - /* Perform default conversions on array and function inputs. */ - /* Don't do this for other types-- - it would screw up operands expected to be in memory. */ - for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++) - if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE) - TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail)); - - /* Generate the ASM_OPERANDS insn; - store into the TREE_VALUEs of OUTPUTS some trees for - where the values were actually stored. */ - expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line); - - /* Copy all the intermediate outputs into the specified outputs. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - { - if (o[i] != TREE_VALUE (tail)) - { - expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)), - 0, VOIDmode, 0); - free_temp_slots (); - } - /* Detect modification of read-only values. - (Otherwise done by build_modify_expr.) */ - else - { - tree type = TREE_TYPE (o[i]); - if (TYPE_READONLY (type) - || ((TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (type))) - readonly_warning (o[i], "modification by `asm'"); - } - } - - /* Those MODIFY_EXPRs could do autoincrements. */ - emit_queue (); -} - -/* Expand a C `return' statement. - RETVAL is the expression for what to return, - or a null pointer for `return;' with no value. */ - -void -c_expand_return (retval) - tree retval; -{ - tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)); - - if (TREE_THIS_VOLATILE (current_function_decl)) - warning ("function declared `noreturn' has a `return' statement"); - - if (!retval) - { - current_function_returns_null = 1; - if (warn_return_type && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) - warning ("`return' with no value, in function returning non-void"); - expand_null_return (); - } - else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE) - { - current_function_returns_null = 1; - if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) - pedwarn ("`return' with a value, in function returning void"); - expand_return (retval); - } - else - { - tree t = convert_for_assignment (valtype, retval, "return", - NULL_TREE, NULL_TREE, 0); - tree res = DECL_RESULT (current_function_decl); - tree inner; - - if (t == error_mark_node) - return; - - inner = t = convert (TREE_TYPE (res), t); - - /* Strip any conversions, additions, and subtractions, and see if - we are returning the address of a local variable. Warn if so. */ - while (TREE_CODE (inner) == NOP_EXPR - || TREE_CODE (inner) == NON_LVALUE_EXPR - || TREE_CODE (inner) == CONVERT_EXPR - || TREE_CODE (inner) == PLUS_EXPR - || TREE_CODE (inner) == MINUS_EXPR) - inner = TREE_OPERAND (inner, 0); - - if (TREE_CODE (inner) == ADDR_EXPR) - { - inner = TREE_OPERAND (inner, 0); - - while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r') - inner = TREE_OPERAND (inner, 0); - - if (TREE_CODE (inner) == VAR_DECL - && ! DECL_EXTERNAL (inner) - && ! TREE_STATIC (inner) - && DECL_CONTEXT (inner) == current_function_decl) - warning ("function returns address of local variable"); - } - - t = build (MODIFY_EXPR, TREE_TYPE (res), res, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_return (t); - current_function_returns_value = 1; - } -} - -/* Start a C switch statement, testing expression EXP. - Return EXP if it is valid, an error node otherwise. */ - -tree -c_expand_start_case (exp) - tree exp; -{ - register enum tree_code code = TREE_CODE (TREE_TYPE (exp)); - tree type = TREE_TYPE (exp); - - if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK) - { - error ("switch quantity not an integer"); - exp = error_mark_node; - } - else - { - tree index; - type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - - if (warn_traditional - && (type == long_integer_type_node - || type == long_unsigned_type_node)) - pedwarn ("`long' switch expression not converted to `int' in ANSI C"); - - exp = default_conversion (exp); - type = TREE_TYPE (exp); - index = get_unwidened (exp, NULL_TREE); - /* We can't strip a conversion from a signed type to an unsigned, - because if we did, int_fits_type_p would do the wrong thing - when checking case values for being in range, - and it's too hard to do the right thing. */ - if (TREE_UNSIGNED (TREE_TYPE (exp)) - == TREE_UNSIGNED (TREE_TYPE (index))) - exp = index; - } - - expand_start_case (1, exp, type, "switch statement"); - - return exp; -} |