diff options
| author | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 |
|---|---|---|
| committer | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 |
| commit | a16f65c7d117419bd266c28a1901ef129a337569 (patch) | |
| tree | 2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /gnu/gcc2/cc1 | |
| parent | 8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff) | |
Diffstat (limited to 'gnu/gcc2/cc1')
| -rw-r--r-- | gnu/gcc2/cc1/Makefile | 23 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-aux-info.c | 642 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-convert.c | 95 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-decl.c | 6494 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-iterate.c | 594 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-lang.c | 129 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-lex.c | 2111 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-parse.c | 3435 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-pragma.c | 198 | ||||
| -rw-r--r-- | gnu/gcc2/cc1/c-typeck.c | 5827 |
10 files changed, 0 insertions, 19548 deletions
diff --git a/gnu/gcc2/cc1/Makefile b/gnu/gcc2/cc1/Makefile deleted file mode 100644 index 6e26b5140699..000000000000 --- a/gnu/gcc2/cc1/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# @(#)Makefile 6.2 (Berkeley) 2/2/91 - -PROG= gcc1 -BINDIR= /usr/libexec -SRCS= c-parse.c c-lang.c c-lex.c c-pragma.c c-decl.c \ - c-typeck.c c-convert.c c-aux-info.c c-iterate.c - -CFLAGS+= -I. -I$(.CURDIR) -I$(.CURDIR)/../lib -YFLAGS= -NOMAN= noman - -.if exists(${.CURDIR}/../lib/obj) -LDADD= -L${.CURDIR}/../lib/obj -lgcc2 -DPADD= ${.CURDIR}/../lib/obj/libgcc2.a -.else -LDADD= -L${.CURDIR}/../lib/ -lgcc2 -DPADD= ${.CURDIR}/../lib/libgcc2.a -.endif - -LDADD+= -lgnumalloc -DPADD+= ${LIBGNUMALLOC} - -.include <bsd.prog.mk> diff --git a/gnu/gcc2/cc1/c-aux-info.c b/gnu/gcc2/cc1/c-aux-info.c deleted file mode 100644 index 2e1506447e35..000000000000 --- a/gnu/gcc2/cc1/c-aux-info.c +++ /dev/null @@ -1,642 +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. - - This code was written by Ron Guilmette (rfg@mcc.com). - - Copyright (C) 1989, 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 <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; - char* outer_modifier = ""; - - 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/gcc2/cc1/c-convert.c b/gnu/gcc2/cc1/c-convert.c deleted file mode 100644 index cfa590cfa6c2..000000000000 --- a/gnu/gcc2/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/gcc2/cc1/c-decl.c b/gnu/gcc2/cc1/c-decl.c deleted file mode 100644 index 08f003e1f0e5..000000000000 --- a/gnu/gcc2/cc1/c-decl.c +++ /dev/null @@ -1,6494 +0,0 @@ -/* Process declarations and variables for C compiler. - Copyright (C) 1988, 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. */ - - -/* 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. */ - -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, 0, 0, 0}; - -/* 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 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; - -/* 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 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, "-fnotraditional") || !strcmp (p, "-fno-traditional")) - { - flag_traditional = 0; - flag_writable_strings = 0; - dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 1; - } - 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, "-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, "-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 () -{ -} - -void -print_lang_type () -{ -} - -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 - output_inline_function (decl); - } - - /* 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 teh 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); - - 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)) - { - /* 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 (!TREE_PUBLIC (newdecl)) - { - if (warn_shadow) - warning_with_decl (newdecl, "shadowing built-in 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_NONANSI (olddecl)) - warning_with_decl (newdecl, - "built-in function `%s' declared as non-function"); - else - error_with_decl (newdecl, - "built-in function `%s' declared as non-function"); - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN_NONANSI (olddecl)) - { - /* If overriding decl is static, - optionally warn this was a bad choice of name. */ - if (!TREE_PUBLIC (newdecl)) - { - if (warn_shadow) - warning_with_decl (newdecl, "shadowing library function `%s'"); - } - /* Otherwise, always warn. */ - else - warning_with_decl (newdecl, - "library 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; - } - 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 - { - char *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"); - /* It is nice to warn when a function is declared - global first and then static. */ - if (TREE_CODE (olddecl) == FUNCTION_DECL - && TREE_PUBLIC (olddecl) - && !TREE_PUBLIC (newdecl)) - warning_with_decl (newdecl, "static declaration for `%s' follows non-static"); - - /* These bits are logically part of the type, for variables. - But not for functions - (where qualifiers are not valid ANSI anyway). */ - 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 (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)) - { - 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) - { - /* 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. */ - if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0) - { - DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); - DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); - } - - /* 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); - } - /* 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_SET_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)) - warning ("nested extern declaration of `%s'", IDENTIFIER_POINTER (name)); - - if (name) - { - char *file; - int line; - - 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)); - } - - 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 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 (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_SET_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 - { - /* Objects declared with block scope: */ - /* Reject two definitions, and reject a definition - together with an external reference. */ - if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (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) - { - 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; -} - -/* 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)); - - /* `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. */ - if (flag_traditional) - sizetype = long_integer_type_node; - else - sizetype - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); - - 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; - - 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)); - - 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)); - - short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"), - short_unsigned_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)); - - /* 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 = type_for_size (wchar_type_size, 0); - unsigned_wchar_type_node = type_for_size (wchar_type_size, 1); - - 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, endlink), - 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 (); - - init_format_info_table (); - - 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_SET_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 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 (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; - } - - if (pedantic && TYPE_DOMAIN (type) != 0 - && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), - integer_zero_node)) - error_with_decl (decl, "zero-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 or `static'. - Otherwise, let it through, but if it is not `extern' - then it may cause an error message later. */ - !TREE_PUBLIC (decl) || DECL_INITIAL (decl) - : - /* 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"); - } - } - - /* 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 && 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. */ - if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)) - && temporary && TREE_PERMANENT (decl) - /* 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 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 (); - - /* 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, olddecl; - 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)) - { - 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) - { - register int nelts - = list_length (CONSTRUCTOR_ELTS (initial_value)); - maxindex = build_int_2 (nelts - 1, - (nelts == 0)); - } - 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) - 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; - } - } - - /* 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; - else if (specbits & 1 << (int) RID_COMPLEX) - { - if (defaulted_int) - 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 - error ("invalid complex 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)); - - 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 (INT_CST_LT (size, integer_zero_node)) - { - error ("size of array `%s' is negative", name); - size = integer_one_node; - } - itype = build_index_type (size_binop (MINUS_EXPR, size, - size_one_node)); - } - else - { - if (pedantic) - { - if (TREE_CONSTANT (size)) - pedwarn ("ANSI C forbids array `%s' whose size can't be evaluated", name); - else - pedwarn ("ANSI C forbids variable-size array `%s'", name); - } - itype = build_binary_op (MINUS_EXPR, size, integer_one_node, - 1); - /* Make sure the array size remains visibly nonconstant - even if it is (eg) a const variable with known value. */ - size_varies = 1; - 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 - 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; - } - - /* `void' at top level (not within pointer) - is allowed only in typedefs or type names. - 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) - { - 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 = build_pointer_type - (c_build_type_variant (TREE_TYPE (type), constp, volatilep)); - 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"); - type = build_pointer_type (c_build_type_variant (type, constp, volatilep)); - 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 (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 - && 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) - 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_lt (DECL_INITIAL (x), integer_zero_node)) - { - 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 - { - 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; - register HOST_WIDE_INT maxvalue = 0; - register HOST_WIDE_INT minvalue = 0; - register int i; - unsigned precision = 0; - int toplevel = global_binding_level == current_binding_level; - int temporary = allocation_temporary_p (); - - if (in_parm_level_p ()) - warning ("enum defined inside parms"); - - /* Calculate the maximum value of any enumerator in this type. */ - - 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; - - /* Determine the precision this type needs. */ - - if (TREE_INT_CST_HIGH (minnode) >= 0 - ? tree_int_cst_lt (TYPE_MAX_VALUE (unsigned_type_node), maxnode) - : (tree_int_cst_lt (minnode, TYPE_MIN_VALUE (integer_type_node)) - || tree_int_cst_lt (TYPE_MAX_VALUE (integer_type_node), maxnode))) - precision = TYPE_PRECISION (long_long_integer_type_node); - else - { - maxvalue = TREE_INT_CST_LOW (maxnode); - minvalue = TREE_INT_CST_LOW (minnode); - - if (maxvalue > 0) - precision = floor_log2 (maxvalue) + 1; - if (minvalue < 0) - { - /* Compute number of bits to represent magnitude of a negative value. - Add one to MINVALUE since range of negative numbers - includes the power of two. */ - unsigned negprecision = floor_log2 (-minvalue - 1) + 1; - if (negprecision > precision) - precision = negprecision; - precision += 1; /* room for sign bit */ - } - - if (!precision) - precision = 1; - } - - 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); - - /* An enum can have some negative values; then it is signed. */ - TREE_UNSIGNED (enumtype) = ! tree_int_cst_lt (minnode, integer_zero_node); - - /* If the enumerators might not fit in an int, change their type now. */ - /* It seems more useful in the debugger to leave these as int - unless the enumerator is wider than int. */ - if (TYPE_PRECISION (enumtype) <= TYPE_PRECISION (integer_type_node)) - for (pair = values; pair; pair = TREE_CHAIN (pair)) - { - TREE_TYPE (TREE_PURPOSE (pair)) = enumtype; - DECL_SIZE (TREE_PURPOSE (pair)) = TYPE_SIZE (enumtype); - if (TREE_CODE (TREE_PURPOSE (pair)) != FUNCTION_DECL) - DECL_ALIGN (TREE_PURPOSE (pair)) = TYPE_ALIGN (enumtype); - } - - /* 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; - - /* 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) - 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. */ - - decl = build_decl (CONST_DECL, name, integer_type_node); - DECL_INITIAL (decl) = value; - TREE_TYPE (value) = integer_type_node; - 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; - - 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; - - 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); - } - - /* 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) - && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0)) - warning_with_decl (decl1, "`%s' was used with no prototype 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; - - 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 - && 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 - { - register tree actual, type; - register tree last = 0; - - 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); - - /* 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 ("`volatile' 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"); - - /* Free all the tree nodes making up this function. */ - /* Switch back to allocating nodes permanently - until we start another function. */ - if (! nested) - permanent_allocation (); - - 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. */ - 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 enum_next_value; - 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->enum_next_value = enum_next_value; - 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; - - enum_next_value = p->enum_next_value; - 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); -} diff --git a/gnu/gcc2/cc1/c-iterate.c b/gnu/gcc2/cc1/c-iterate.c deleted file mode 100644 index 09df3e466336..000000000000 --- a/gnu/gcc2/cc1/c-iterate.c +++ /dev/null @@ -1,594 +0,0 @@ -/* Build expressions with type checking for C compiler. - Copyright (C) 1987, 1988, 1989, 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. */ - - -/* 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. */ - { - tree tail; - for (tail = save_exprs; tail; tail = TREE_CHAIN (tail)) - if (TREE_VALUE (tail) == exp) - 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; -{ - /* Force the save_expr in DECL_INITIAL to be calculated - if it hasn't been calculated yet. */ - expand_expr (DECL_INITIAL (idecl), 0, VOIDmode, 0); - - if (DECL_RTL (idecl) == 0) - expand_decl (idecl); - - if (start_note) - *start_note = emit_note (0, NOTE_INSN_DELETED); - /* Initialize counter. */ - expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), - idecl, integer_zero_node), - 0, 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); - expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr), - 0, 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/gcc2/cc1/c-lang.c b/gnu/gcc2/cc1/c-lang.c deleted file mode 100644 index 8b46b3c10cb5..000000000000 --- a/gnu/gcc2/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/gcc2/cc1/c-lex.c b/gnu/gcc2/cc1/c-lex.c deleted file mode 100644 index d83b5dccb623..000000000000 --- a/gnu/gcc2/cc1/c-lex.c +++ /dev/null @@ -1,2111 +0,0 @@ -/* Lexical analyzer for C and Objective C. - Copyright (C) 1987, 1988, 1989, 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 <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" - -#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 (); - -/* Nonzero tells yylex to ignore \ in string constants. */ -static int ignore_escape_flag = 0; - -/* C code produced by gperf version 2.5 (GNU C++ version) */ -/* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ c-parse.gperf */ -struct resword { char *name; short token; enum rid rid; }; - -#define TOTAL_KEYWORDS 79 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 20 -#define MIN_HASH_VALUE 10 -#define MAX_HASH_VALUE 144 -/* maximum key range = 135, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#endif -static unsigned int -hash (str, len) - register char *str; - register int unsigned len; -{ - static unsigned char asso_values[] = - { - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 25, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 1, 145, 46, 8, 15, - 61, 6, 36, 48, 3, 5, 145, 18, 63, 25, - 29, 76, 1, 145, 13, 2, 1, 51, 37, 9, - 9, 1, 3, 145, 145, 145, 145, 145, - }; - register int hval = len; - - switch (hval) - { - default: - case 3: - hval += asso_values[str[2]]; - case 2: - case 1: - hval += asso_values[str[0]]; - } - return hval + asso_values[str[len - 1]]; -} - -static struct resword wordlist[] = -{ - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"",}, - {"int", TYPESPEC, RID_INT}, - {"",}, {"",}, - {"__typeof__", TYPEOF, NORID}, - {"__signed__", TYPESPEC, RID_SIGNED}, - {"__imag__", IMAGPART, NORID}, - {"switch", SWITCH, NORID}, - {"__inline__", SCSPEC, RID_INLINE}, - {"else", ELSE, NORID}, - {"__iterator__", SCSPEC, RID_ITERATOR}, - {"__inline", SCSPEC, RID_INLINE}, - {"__extension__", EXTENSION, NORID}, - {"struct", STRUCT, NORID}, - {"__real__", REALPART, NORID}, - {"__const", TYPE_QUAL, RID_CONST}, - {"while", WHILE, NORID}, - {"__const__", TYPE_QUAL, RID_CONST}, - {"case", CASE, NORID}, - {"__complex__", TYPESPEC, RID_COMPLEX}, - {"__iterator", SCSPEC, RID_ITERATOR}, - {"bycopy", TYPE_QUAL, RID_BYCOPY}, - {"",}, {"",}, {"",}, - {"__complex", TYPESPEC, RID_COMPLEX}, - {"",}, - {"in", TYPE_QUAL, RID_IN}, - {"break", BREAK, NORID}, - {"@defs", DEFS, NORID}, - {"",}, {"",}, {"",}, - {"extern", SCSPEC, RID_EXTERN}, - {"if", IF, NORID}, - {"typeof", TYPEOF, NORID}, - {"typedef", SCSPEC, RID_TYPEDEF}, - {"__typeof", TYPEOF, NORID}, - {"sizeof", SIZEOF, NORID}, - {"",}, - {"return", RETURN, NORID}, - {"const", TYPE_QUAL, RID_CONST}, - {"__volatile__", TYPE_QUAL, RID_VOLATILE}, - {"@private", PRIVATE, NORID}, - {"@selector", SELECTOR, NORID}, - {"__volatile", TYPE_QUAL, RID_VOLATILE}, - {"__asm__", ASM_KEYWORD, NORID}, - {"",}, {"",}, - {"continue", CONTINUE, NORID}, - {"__alignof__", ALIGNOF, NORID}, - {"__imag", IMAGPART, NORID}, - {"__attribute__", ATTRIBUTE, NORID}, - {"",}, {"",}, - {"__attribute", ATTRIBUTE, NORID}, - {"for", FOR, NORID}, - {"",}, - {"@encode", ENCODE, NORID}, - {"id", OBJECTNAME, RID_ID}, - {"static", SCSPEC, RID_STATIC}, - {"@interface", INTERFACE, NORID}, - {"",}, - {"__signed", TYPESPEC, RID_SIGNED}, - {"",}, - {"__label__", LABEL, NORID}, - {"",}, {"",}, - {"__asm", ASM_KEYWORD, NORID}, - {"char", TYPESPEC, RID_CHAR}, - {"",}, - {"inline", SCSPEC, RID_INLINE}, - {"out", TYPE_QUAL, RID_OUT}, - {"register", SCSPEC, RID_REGISTER}, - {"__real", REALPART, NORID}, - {"short", TYPESPEC, RID_SHORT}, - {"",}, - {"enum", ENUM, NORID}, - {"inout", TYPE_QUAL, RID_INOUT}, - {"",}, - {"oneway", TYPE_QUAL, RID_ONEWAY}, - {"union", UNION, NORID}, - {"",}, - {"__alignof", ALIGNOF, NORID}, - {"",}, - {"@implementation", IMPLEMENTATION, NORID}, - {"",}, - {"@class", CLASS, NORID}, - {"",}, - {"@public", PUBLIC, NORID}, - {"asm", ASM_KEYWORD, NORID}, - {"",}, {"",}, {"",}, {"",}, {"",}, - {"default", DEFAULT, NORID}, - {"",}, - {"void", TYPESPEC, RID_VOID}, - {"",}, - {"@protected", PROTECTED, NORID}, - {"@protocol", PROTOCOL, NORID}, - {"",}, {"",}, {"",}, - {"volatile", TYPE_QUAL, RID_VOLATILE}, - {"",}, {"",}, - {"signed", TYPESPEC, RID_SIGNED}, - {"float", TYPESPEC, RID_FLOAT}, - {"@end", END, NORID}, - {"",}, {"",}, - {"unsigned", TYPESPEC, RID_UNSIGNED}, - {"@compatibility_alias", ALIAS, NORID}, - {"double", TYPESPEC, RID_DOUBLE}, - {"",}, {"",}, - {"auto", SCSPEC, RID_AUTO}, - {"",}, - {"goto", GOTO, NORID}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"do", DO, NORID}, - {"",}, {"",}, {"",}, {"",}, - {"long", TYPESPEC, RID_LONG}, -}; - -#ifdef __GNUC__ -__inline -#endif -struct resword * -is_reserved_word (str, len) - register char *str; - register unsigned int len; -{ - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register char *s = wordlist[key].name; - - if (*s == *str && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} - -/* 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); -#endif /* HANDLE_SYSV_PRAGMA */ -#ifdef HANDLE_PRAGMA - HANDLE_PRAGMA (finput); -#endif /* HANDLE_PRAGMA */ - goto skipline; - } - } - - 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, but don't treat \ as special. */ - ignore_escape_flag = 1; - token = yylex (); - ignore_escape_flag = 0; - - 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 isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9')) -#define isdigit(char) (char >= '0' && char <= '9') -#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; - 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 == AFTER_POINT) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - } - 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 - { - set_float_handler (handler); - -/* The second argument, machine_mode, of REAL_VALUE_ATOF tells the - desired precision of the binary result of decimal-to-binary conversion. */ - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - type = float_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `float'"); - garbage_chars = -1; - break; - - case 'l': case 'L': - type = long_double_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ( - "floating point number exceeds range of `long double'"); - garbage_chars = -1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - imag = 1; - garbage_chars = -1; - break; - - default: - value = REAL_VALUE_ATOF (token_buffer, 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 - /* Note: garbage_chars is -1 if first char is *not* garbage. */ - 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"); - - /* 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"); - 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); - } - 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) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && 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/gcc2/cc1/c-parse.c b/gnu/gcc2/cc1/c-parse.c deleted file mode 100644 index fb86c886faf7..000000000000 --- a/gnu/gcc2/cc1/c-parse.c +++ /dev/null @@ -1,3435 +0,0 @@ - -/* A Bison parser, made from c-parse.y */ - -#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 44 "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 81 "c-parse.y" -typedef union {long itype; tree ttype; enum tree_code code; - char *filename; int lineno; } YYSTYPE; -#line 192 "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 __STDC__ -#define const -#endif - - - -#define YYFINAL 613 -#define YYFLAG -32768 -#define YYNTBASE 85 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 317 ? yytranslate[x] : 212) - -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 -}; - -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, 175, 177, - 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, - 221, 225, 229, 233, 239, 243, 247, 249, 251, 253, - 257, 261, 262, 267, 272, 277, 281, 285, 288, 291, - 293, 296, 297, 299, 302, 306, 308, 310, 313, 316, - 321, 326, 329, 332, 336, 338, 340, 343, 346, 347, - 352, 357, 361, 365, 368, 371, 374, 378, 379, 382, - 385, 387, 389, 392, 395, 398, 402, 403, 406, 408, - 410, 412, 417, 422, 424, 426, 428, 430, 434, 436, - 440, 441, 446, 447, 454, 458, 459, 466, 470, 471, - 478, 480, 484, 486, 491, 496, 505, 507, 510, 514, - 519, 521, 523, 527, 534, 543, 548, 555, 559, 565, - 566, 570, 571, 575, 577, 579, 583, 587, 592, 596, - 600, 602, 606, 611, 615, 619, 621, 625, 629, 633, - 638, 642, 644, 645, 652, 657, 660, 661, 668, 673, - 676, 677, 685, 686, 693, 696, 697, 699, 700, 702, - 704, 707, 708, 712, 715, 719, 721, 725, 727, 729, - 731, 735, 740, 747, 753, 755, 759, 761, 765, 768, - 771, 772, 774, 776, 779, 780, 783, 787, 791, 794, - 798, 803, 807, 810, 814, 817, 819, 822, 825, 826, - 828, 831, 832, 833, 835, 837, 840, 844, 846, 849, - 852, 859, 865, 871, 874, 877, 882, 883, 888, 889, - 890, 894, 899, 903, 905, 907, 909, 911, 914, 915, - 920, 922, 926, 927, 928, 936, 942, 945, 946, 947, - 948, 961, 962, 969, 972, 975, 978, 982, 989, 998, - 1009, 1022, 1026, 1031, 1033, 1035, 1036, 1043, 1047, 1053, - 1056, 1059, 1060, 1062, 1063, 1065, 1066, 1068, 1070, 1074, - 1079, 1081, 1085, 1086, 1089, 1092, 1093, 1098, 1101, 1102, - 1104, 1106, 1110, 1112, 1116, 1119, 1122, 1125, 1128, 1131, - 1132, 1135, 1137, 1140, 1142, 1146, 1148 -}; - -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, 116, 126, 78, 0, 120, 116, 126, 78, 0, - 118, 116, 125, 78, 0, 120, 78, 0, 118, 78, - 0, 1, 78, 0, 1, 79, 0, 78, 0, 0, - 0, 118, 116, 141, 92, 110, 93, 171, 0, 118, - 116, 141, 1, 0, 0, 0, 120, 116, 144, 94, - 110, 95, 171, 0, 120, 116, 144, 1, 0, 0, - 0, 116, 144, 96, 110, 97, 171, 0, 116, 144, - 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, 106, 0, 102, 82, 106, - 0, 107, 0, 51, 105, 0, 0, 32, 104, 105, - 0, 99, 105, 0, 41, 98, 0, 11, 103, 0, - 11, 60, 159, 77, 0, 29, 103, 0, 29, 60, - 159, 77, 0, 34, 105, 0, 35, 105, 0, 103, - 0, 60, 159, 77, 105, 0, 60, 159, 77, 83, - 136, 150, 79, 0, 105, 0, 106, 49, 106, 0, - 106, 50, 106, 0, 106, 51, 106, 0, 106, 52, - 106, 0, 106, 53, 106, 0, 106, 47, 106, 0, - 106, 48, 106, 0, 106, 46, 106, 0, 106, 45, - 106, 0, 106, 44, 106, 0, 106, 42, 106, 0, - 106, 43, 106, 0, 106, 41, 106, 0, 106, 40, - 106, 0, 106, 38, 195, 39, 106, 0, 106, 37, - 106, 0, 106, 36, 106, 0, 3, 0, 8, 0, - 109, 0, 60, 100, 77, 0, 60, 1, 77, 0, - 0, 60, 108, 172, 77, 0, 107, 60, 101, 77, - 0, 107, 61, 100, 84, 0, 107, 59, 98, 0, - 107, 58, 98, 0, 107, 55, 0, 107, 56, 0, - 9, 0, 109, 9, 0, 0, 112, 0, 112, 10, - 0, 177, 178, 113, 0, 111, 0, 166, 0, 112, - 111, 0, 111, 166, 0, 118, 116, 125, 78, 0, - 120, 116, 126, 78, 0, 118, 78, 0, 120, 78, - 0, 177, 178, 117, 0, 114, 0, 166, 0, 115, - 114, 0, 114, 166, 0, 0, 118, 116, 125, 78, - 0, 120, 116, 126, 78, 0, 118, 116, 137, 0, - 120, 116, 139, 0, 118, 78, 0, 120, 78, 0, - 123, 119, 0, 120, 123, 119, 0, 0, 119, 124, - 0, 119, 5, 0, 7, 0, 5, 0, 120, 7, - 0, 120, 5, 0, 123, 122, 0, 161, 123, 122, - 0, 0, 122, 124, 0, 6, 0, 145, 0, 4, - 0, 28, 60, 100, 77, 0, 28, 60, 159, 77, - 0, 6, 0, 7, 0, 145, 0, 128, 0, 125, - 82, 128, 0, 130, 0, 126, 82, 128, 0, 0, - 27, 60, 109, 77, 0, 0, 141, 127, 132, 37, - 129, 135, 0, 141, 127, 132, 0, 0, 144, 127, - 132, 37, 131, 135, 0, 144, 127, 132, 0, 0, - 31, 60, 60, 133, 77, 77, 0, 134, 0, 133, - 82, 134, 0, 3, 0, 3, 60, 3, 77, 0, - 3, 60, 8, 77, 0, 3, 60, 3, 82, 8, - 82, 8, 77, 0, 106, 0, 83, 79, 0, 83, - 136, 79, 0, 83, 136, 82, 79, 0, 1, 0, - 135, 0, 136, 82, 135, 0, 61, 106, 10, 106, - 84, 135, 0, 136, 82, 61, 106, 10, 106, 84, - 135, 0, 61, 106, 84, 135, 0, 136, 82, 61, - 106, 84, 135, 0, 98, 39, 135, 0, 136, 82, - 98, 39, 135, 0, 0, 141, 138, 172, 0, 0, - 144, 140, 172, 0, 142, 0, 144, 0, 60, 142, - 77, 0, 142, 60, 207, 0, 142, 61, 100, 84, - 0, 142, 61, 84, 0, 51, 162, 142, 0, 4, - 0, 143, 60, 207, 0, 143, 61, 100, 84, 0, - 143, 61, 84, 0, 51, 162, 143, 0, 4, 0, - 144, 60, 207, 0, 60, 144, 77, 0, 51, 162, - 144, 0, 144, 61, 100, 84, 0, 144, 61, 84, - 0, 3, 0, 0, 13, 98, 83, 146, 152, 79, - 0, 13, 83, 152, 79, 0, 13, 98, 0, 0, - 14, 98, 83, 147, 152, 79, 0, 14, 83, 152, - 79, 0, 14, 98, 0, 0, 12, 98, 83, 148, - 157, 151, 79, 0, 0, 12, 83, 149, 157, 151, - 79, 0, 12, 98, 0, 0, 82, 0, 0, 82, - 0, 153, 0, 153, 154, 0, 0, 153, 154, 78, - 0, 153, 78, 0, 121, 116, 155, 0, 121, 0, - 161, 116, 155, 0, 161, 0, 1, 0, 156, 0, - 155, 82, 156, 0, 177, 178, 141, 132, 0, 177, - 178, 141, 39, 106, 132, 0, 177, 178, 39, 106, - 132, 0, 158, 0, 157, 82, 158, 0, 98, 0, - 98, 37, 106, 0, 121, 160, 0, 161, 160, 0, - 0, 163, 0, 7, 0, 161, 7, 0, 0, 162, - 7, 0, 60, 163, 77, 0, 51, 162, 163, 0, - 51, 162, 0, 163, 60, 200, 0, 163, 61, 100, - 84, 0, 163, 61, 84, 0, 60, 200, 0, 61, - 100, 84, 0, 61, 84, 0, 180, 0, 164, 180, - 0, 164, 166, 0, 0, 164, 0, 1, 78, 0, - 0, 0, 169, 0, 170, 0, 169, 170, 0, 33, - 211, 78, 0, 172, 0, 1, 172, 0, 83, 79, - 0, 83, 167, 168, 115, 165, 79, 0, 83, 167, - 168, 1, 79, 0, 83, 167, 168, 164, 79, 0, - 174, 179, 0, 174, 1, 0, 15, 60, 100, 77, - 0, 0, 18, 176, 179, 17, 0, 0, 0, 177, - 178, 182, 0, 177, 178, 193, 179, 0, 177, 178, - 181, 0, 182, 0, 193, 0, 172, 0, 190, 0, - 100, 78, 0, 0, 173, 16, 183, 179, 0, 173, - 0, 173, 16, 1, 0, 0, 0, 17, 184, 60, - 100, 77, 185, 179, 0, 175, 60, 100, 77, 78, - 0, 175, 1, 0, 0, 0, 0, 19, 60, 195, - 78, 186, 195, 78, 187, 195, 77, 188, 179, 0, - 0, 20, 60, 100, 77, 189, 179, 0, 23, 78, - 0, 24, 78, 0, 25, 78, 0, 25, 100, 78, - 0, 27, 194, 60, 100, 77, 78, 0, 27, 194, - 60, 100, 39, 196, 77, 78, 0, 27, 194, 60, - 100, 39, 196, 39, 196, 77, 78, 0, 27, 194, - 60, 100, 39, 196, 39, 196, 39, 199, 77, 78, - 0, 26, 98, 78, 0, 26, 51, 100, 78, 0, - 78, 0, 191, 0, 0, 19, 60, 107, 77, 192, - 179, 0, 21, 106, 39, 0, 21, 106, 10, 106, - 39, 0, 22, 39, 0, 98, 39, 0, 0, 7, - 0, 0, 100, 0, 0, 197, 0, 198, 0, 197, - 82, 198, 0, 9, 60, 100, 77, 0, 109, 0, - 199, 82, 109, 0, 0, 201, 202, 0, 204, 77, - 0, 0, 205, 78, 203, 202, 0, 1, 77, 0, - 0, 10, 0, 205, 0, 205, 82, 10, 0, 206, - 0, 205, 82, 206, 0, 118, 143, 0, 118, 144, - 0, 118, 160, 0, 120, 144, 0, 120, 160, 0, - 0, 208, 209, 0, 202, 0, 210, 77, 0, 3, - 0, 210, 82, 3, 0, 98, 0, 211, 82, 98, - 0 -}; - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 218, 222, 235, 237, 237, 238, 240, 242, 243, 253, - 259, 261, 263, 265, 267, 268, 269, 274, 280, 282, - 283, 285, 290, 292, 293, 295, 300, 302, 303, 307, - 309, 312, 314, 316, 318, 320, 322, 324, 328, 332, - 335, 338, 341, 345, 347, 350, 353, 356, 360, 386, - 391, 393, 395, 397, 399, 403, 405, 408, 433, 435, - 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, - 457, 459, 461, 463, 465, 468, 474, 575, 576, 578, - 584, 586, 600, 618, 620, 622, 626, 632, 634, 639, - 641, 646, 648, 649, 659, 664, 666, 667, 668, 671, - 676, 680, 683, 691, 696, 698, 699, 700, 707, 715, - 720, 724, 728, 732, 734, 742, 745, 749, 751, 753, - 764, 768, 770, 773, 786, 789, 793, 795, 803, 804, - 805, 809, 811, 817, 818, 819, 822, 824, 827, 829, - 832, 835, 841, 846, 848, 854, 859, 861, 868, 871, - 876, 878, 883, 888, 898, 909, 927, 929, 933, 935, - 937, 943, 946, 951, 955, 960, 962, 964, 966, 970, - 987, 991, 1008, 1015, 1017, 1022, 1025, 1030, 1032, 1034, - 1036, 1044, 1050, 1052, 1054, 1056, 1062, 1068, 1070, 1072, - 1074, 1076, 1079, 1084, 1088, 1091, 1093, 1095, 1097, 1100, - 1102, 1105, 1108, 1111, 1114, 1118, 1120, 1123, 1125, 1129, - 1132, 1137, 1139, 1141, 1155, 1161, 1166, 1171, 1176, 1180, - 1182, 1186, 1190, 1194, 1204, 1206, 1211, 1214, 1218, 1221, - 1225, 1228, 1231, 1234, 1238, 1241, 1245, 1249, 1251, 1253, - 1255, 1257, 1259, 1261, 1263, 1271, 1273, 1274, 1277, 1279, - 1282, 1285, 1296, 1298, 1303, 1305, 1308, 1322, 1325, 1328, - 1330, 1335, 1340, 1348, 1353, 1356, 1369, 1377, 1381, 1385, - 1389, 1395, 1399, 1404, 1406, 1417, 1420, 1421, 1426, 1431, - 1434, 1442, 1444, 1454, 1464, 1465, 1473, 1476, 1488, 1492, - 1509, 1516, 1525, 1527, 1532, 1537, 1541, 1545, 1556, 1563, - 1570, 1577, 1588, 1592, 1595, 1600, 1623, 1654, 1678, 1706, - 1721, 1732, 1735, 1739, 1742, 1747, 1749, 1752, 1754, 1758, - 1763, 1766, 1772, 1777, 1782, 1784, 1793, 1794, 1800, 1802, - 1807, 1809, 1813, 1816, 1822, 1825, 1827, 1829, 1831, 1838, - 1843, 1848, 1850, 1859, 1862, 1867, 1870 -}; - -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","expr_no_commas", -"primary","@10","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","@11","notype_initdcl","@12", -"maybe_attribute","attribute_list","attrib","init","initlist","nested_function", -"@13","notype_nested_function","@14","declarator","after_type_declarator","parm_declarator", -"notype_declarator","structsp","@15","@16","@17","@18","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", -"@19","save_filename","save_lineno","lineno_labeled_stmt","lineno_stmt_or_label", -"stmt_or_label","stmt","@20","@21","@22","@23","@24","@25","@26","all_iter_stmt", -"all_iter_stmt_simple","@27","label","maybe_type_qual","xexpr","asm_operands", -"nonnull_asm_operands","asm_operand","asm_clobbers","parmlist","@28","parmlist_1", -"@29","parmlist_2","parms","parm","parmlist_or_identifiers","@30","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, 105, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, - 107, 108, 107, 107, 107, 107, 107, 107, 107, 109, - 109, 110, 110, 110, 111, 112, 112, 112, 112, 113, - 113, 113, 113, 114, 115, 115, 115, 115, 116, 117, - 117, 117, 117, 117, 117, 118, 118, 119, 119, 119, - 120, 120, 120, 120, 121, 121, 122, 122, 123, 123, - 123, 123, 123, 124, 124, 124, 125, 125, 126, 126, - 127, 127, 129, 128, 128, 131, 130, 130, 132, 132, - 133, 133, 134, 134, 134, 134, 135, 135, 135, 135, - 135, 136, 136, 136, 136, 136, 136, 136, 136, 138, - 137, 140, 139, 141, 141, 142, 142, 142, 142, 142, - 142, 143, 143, 143, 143, 143, 144, 144, 144, 144, - 144, 144, 146, 145, 145, 145, 147, 145, 145, 145, - 148, 145, 149, 145, 145, 150, 150, 151, 151, 152, - 152, 153, 153, 153, 154, 154, 154, 154, 154, 155, - 155, 156, 156, 156, 157, 157, 158, 158, 159, 159, - 160, 160, 161, 161, 162, 162, 163, 163, 163, 163, - 163, 163, 163, 163, 163, 164, 164, 164, 165, 165, - 166, 167, 168, 168, 169, 169, 170, 171, 171, 172, - 172, 172, 172, 173, 173, 174, 176, 175, 177, 178, - 179, 179, 180, 181, 181, 182, 182, 182, 183, 182, - 182, 182, 184, 185, 182, 182, 182, 186, 187, 188, - 182, 189, 182, 182, 182, 182, 182, 182, 182, 182, - 182, 182, 182, 182, 190, 192, 191, 193, 193, 193, - 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, - 199, 199, 201, 200, 202, 203, 202, 202, 204, 204, - 204, 204, 205, 205, 206, 206, 206, 206, 206, 208, - 207, 209, 209, 210, 210, 211, 211 -}; - -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, 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, 6, - 1, 3, 1, 4, 4, 8, 1, 2, 3, 4, - 1, 1, 3, 6, 8, 4, 6, 3, 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, 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, 131, 122, 129, 121, 0, 0, - 0, 0, 0, 17, 4, 8, 7, 0, 109, 109, - 118, 130, 6, 15, 16, 30, 31, 203, 205, 212, - 196, 212, 200, 0, 0, 192, 235, 0, 0, 139, - 0, 14, 0, 124, 123, 13, 0, 118, 116, 0, - 201, 0, 0, 193, 0, 197, 77, 78, 90, 0, - 0, 46, 0, 0, 0, 32, 34, 33, 0, 35, - 36, 0, 37, 38, 0, 0, 39, 56, 59, 42, - 44, 79, 233, 0, 231, 127, 0, 231, 0, 0, - 10, 0, 29, 0, 340, 0, 0, 149, 181, 235, - 0, 0, 137, 0, 174, 175, 0, 0, 117, 120, - 134, 135, 119, 136, 227, 208, 225, 0, 195, 219, - 214, 109, 211, 109, 212, 199, 212, 0, 50, 0, - 52, 0, 54, 55, 49, 45, 0, 0, 0, 0, - 48, 0, 0, 0, 0, 314, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 88, 89, 0, 0, 40, 0, 91, 132, 235, 323, - 0, 229, 232, 125, 133, 234, 127, 230, 236, 189, - 188, 140, 141, 0, 187, 0, 191, 0, 0, 27, - 0, 269, 97, 270, 0, 148, 0, 0, 12, 0, - 21, 0, 149, 340, 0, 11, 25, 0, 0, 209, - 0, 208, 269, 213, 269, 0, 0, 0, 0, 47, - 81, 80, 252, 0, 0, 9, 43, 76, 75, 315, - 0, 73, 72, 70, 71, 69, 68, 67, 65, 66, - 60, 61, 62, 63, 64, 87, 86, 0, 41, 0, - 239, 0, 243, 0, 245, 0, 323, 0, 128, 126, - 0, 0, 344, 330, 231, 231, 342, 0, 331, 333, - 341, 0, 190, 251, 0, 99, 94, 98, 0, 0, - 146, 180, 176, 138, 19, 145, 177, 179, 0, 23, - 228, 226, 204, 0, 215, 220, 270, 217, 194, 198, - 51, 53, 260, 253, 83, 0, 57, 0, 84, 85, - 238, 237, 324, 244, 240, 242, 0, 142, 328, 186, - 235, 323, 335, 336, 337, 235, 338, 339, 325, 326, - 0, 343, 0, 0, 28, 258, 95, 109, 109, 0, - 0, 0, 143, 178, 0, 202, 269, 0, 0, 0, - 254, 255, 161, 77, 0, 0, 0, 157, 162, 206, - 74, 241, 239, 340, 0, 239, 0, 332, 334, 345, - 259, 102, 0, 103, 0, 153, 0, 151, 147, 20, - 0, 24, 221, 0, 149, 346, 0, 0, 0, 269, - 0, 106, 270, 246, 256, 0, 158, 0, 0, 0, - 0, 185, 182, 184, 0, 327, 0, 0, 141, 0, - 0, 0, 144, 149, 0, 222, 257, 0, 262, 108, - 107, 0, 0, 263, 248, 270, 247, 0, 0, 0, - 159, 0, 168, 0, 0, 163, 58, 183, 100, 101, - 0, 0, 150, 152, 224, 149, 347, 261, 0, 131, - 0, 283, 267, 0, 0, 0, 0, 0, 0, 0, - 0, 312, 304, 0, 0, 104, 109, 109, 276, 281, - 0, 0, 273, 274, 277, 305, 275, 0, 166, 160, - 0, 0, 154, 0, 155, 223, 0, 0, 269, 314, - 0, 0, 310, 294, 295, 296, 0, 0, 0, 313, - 0, 311, 278, 114, 0, 115, 0, 0, 265, 270, - 264, 287, 0, 0, 0, 0, 169, 0, 0, 0, - 0, 44, 0, 0, 0, 308, 297, 0, 302, 0, - 0, 112, 141, 0, 113, 141, 282, 269, 0, 0, - 164, 0, 167, 0, 266, 0, 268, 306, 288, 292, - 0, 303, 0, 110, 0, 111, 0, 280, 271, 269, - 0, 0, 0, 284, 269, 314, 269, 309, 316, 0, - 171, 173, 272, 286, 165, 156, 269, 307, 0, 293, - 0, 0, 317, 318, 298, 285, 289, 0, 316, 0, - 0, 314, 0, 0, 299, 319, 0, 320, 0, 0, - 290, 321, 0, 300, 269, 0, 0, 291, 301, 322, - 0, 0, 0 -}; - -static const short yydefgoto[] = { 611, - 1, 2, 3, 15, 16, 17, 202, 342, 208, 345, - 97, 275, 115, 75, 230, 248, 77, 78, 132, 79, - 80, 81, 139, 82, 190, 191, 192, 337, 389, 390, - 18, 466, 265, 49, 266, 85, 174, 21, 113, 102, - 39, 98, 103, 381, 40, 341, 196, 377, 378, 359, - 360, 532, 555, 535, 557, 183, 105, 323, 106, 22, - 125, 127, 118, 50, 401, 211, 52, 53, 123, 295, - 296, 116, 117, 87, 172, 88, 89, 173, 391, 423, - 193, 304, 350, 351, 352, 335, 336, 470, 471, 472, - 489, 510, 279, 511, 394, 473, 474, 538, 488, 577, - 566, 592, 605, 567, 475, 476, 565, 477, 501, 231, - 582, 583, 584, 603, 253, 254, 267, 367, 268, 269, - 270, 185, 186, 271, 272, 387 -}; - -static const short yypact[] = { 49, - 95, 710, 710, 262,-32768,-32768,-32768,-32768, 64, 66, - 70, 60, 86,-32768,-32768,-32768,-32768, 33, -36, 332, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 65,-32768, - 79,-32768, 128, 1837, 1753,-32768,-32768, 33, 94,-32768, - 391,-32768, 444,-32768,-32768,-32768, 33,-32768, 312, 68, --32768, 141, 154,-32768, 144,-32768,-32768,-32768,-32768, 1850, - 1900,-32768, 1837, 1837, 68,-32768,-32768,-32768, 1837,-32768, --32768, 1032,-32768,-32768, 1837, 165, 169,-32768,-32768, 2059, - 637, 247,-32768, 188, 187,-32768, 191, 951, 356, 0, --32768, 444,-32768, 211,-32768, 1379, 529, 245,-32768,-32768, - 444, 153,-32768, 273, 297, 308, 176, 486, 312,-32768, --32768,-32768,-32768,-32768, 244, 202,-32768, 68,-32768,-32768, --32768, 311, 224, 215,-32768,-32768,-32768, 1032,-32768, 1032, --32768, 1837,-32768,-32768,-32768,-32768, 228, 231, 251, 243, --32768, 265, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, --32768,-32768, 68, 68, 1837, 1837,-32768,-32768,-32768, 187, - 1392,-32768, 352, 538,-32768,-32768,-32768,-32768,-32768, 308, --32768,-32768, 321, 362,-32768, 632,-32768, 307, 322,-32768, - 360, 42,-32768,-32768, 346, 377, 263, 4,-32768, 444, --32768, 529, 245,-32768, 1446,-32768,-32768, 529, 1837, 68, - 341, 202,-32768,-32768,-32768, 344, 350, 354, 357,-32768, --32768,-32768, 376, 373, 1695,-32768, 2059, 2059, 2059,-32768, - 400, 2072, 1299, 2083, 1875, 2092, 1485, 459, 432, 432, - 328, 328,-32768,-32768,-32768,-32768,-32768, 383, 169, 379, - 114, 109,-32768, 789,-32768, 393,-32768, 1459,-32768, 538, - 24, 420,-32768,-32768, 222, 875,-32768, 424, 181,-32768, --32768, 101,-32768,-32768, 40,-32768,-32768,-32768, 926, 443, --32768, 297,-32768,-32768,-32768, 485,-32768,-32768, 442,-32768, - 2059,-32768,-32768, 448, 447,-32768,-32768, 447,-32768,-32768, --32768,-32768,-32768, 498,-32768, 1273,-32768, 1837,-32768,-32768, - 352,-32768,-32768,-32768,-32768,-32768, 454,-32768,-32768,-32768, --32768, 261, 411, 308,-32768,-32768, 308,-32768,-32768,-32768, - 1104,-32768, 536, 251,-32768,-32768,-32768, 462, 371, 545, - 1329, 40,-32768,-32768, 40,-32768,-32768, 405, 68, 650, - 498,-32768,-32768, 510, 1837, 1090, 514, 2059,-32768, 473, - 1669,-32768, 103,-32768, 1513, 237, 789,-32768,-32768,-32768, --32768,-32768, 444,-32768, 33, 496, 110,-32768,-32768,-32768, - 1329,-32768,-32768, 1837, 111,-32768, 225, 410, 569, 479, - 731,-32768,-32768,-32768,-32768, 1926,-32768, 26, 1329, 1151, - 480, 411,-32768,-32768, 481,-32768, 250, 304, 235, 177, - 489, 545,-32768, 2016, 1837,-32768,-32768, 68,-32768,-32768, --32768, 812, 484,-32768,-32768,-32768,-32768, 1595, 1837, 1329, --32768, 1212,-32768, 1837, 528,-32768,-32768,-32768,-32768,-32768, - 157, 502,-32768,-32768,-32768, 2016,-32768,-32768, 1645, 546, - 539,-32768,-32768, 540, 542, 1837, 566, 531, 533, 1787, - 52, 599,-32768, 568, 537,-32768, 543, 845,-32768, 598, - 893, 30,-32768,-32768,-32768,-32768,-32768, 1971,-32768,-32768, - 1947, 1329,-32768, 608,-32768,-32768, 1837, 557,-32768, 1837, - 1837, 1539,-32768,-32768,-32768,-32768, 544, 1837, 548,-32768, - 563,-32768,-32768,-32768, 444,-32768, 33, 974,-32768,-32768, --32768,-32768, 1837, 1329, 1837, 1329,-32768, 549, 550, 1837, - 611, 460, 552, 555, 1837,-32768,-32768, 556,-32768, 1837, - 358,-32768, 21, 388,-32768, 230,-32768,-32768, 1645, 564, --32768, 1992,-32768, 635,-32768, 589,-32768,-32768,-32768,-32768, - 2041,-32768, 15,-32768, 251,-32768, 251,-32768,-32768,-32768, - 562, 1329, 603,-32768,-32768, 1837,-32768,-32768, 672, 605, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 609,-32768, - 626, 20, 606,-32768,-32768,-32768,-32768, 1837, 672, 612, - 672, 1837, 625, 39,-32768,-32768, 627,-32768, 362, 629, --32768, 247, 168,-32768,-32768, 630, 362,-32768,-32768, 247, - 689, 703,-32768 -}; - -static const short yypgoto[] = {-32768, --32768,-32768,-32768, 709,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768, -7,-32768, -34,-32768, 553, 464,-32768, -18, - 46, 229,-32768, -175, -117, 534,-32768,-32768, 330,-32768, - -9,-32768, 10, 673, 13, 674, 559, -6, -124, -346, - -40, -96, -55,-32768,-32768,-32768, -177,-32768, 313, -301, - 385,-32768,-32768,-32768,-32768, -37, -62, 366, -13, -30, --32768,-32768,-32768,-32768,-32768, 532, 3,-32768,-32768, 530, - 396, 641, 554, -19, -56, 694, -80, -149, 372,-32768, - -173,-32768,-32768,-32768, 416, -259, -122,-32768,-32768,-32768, --32768, -75, -274, -426, -347,-32768, 232,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 234,-32768, -466, - 179,-32768, 178,-32768, 517,-32768, -224,-32768,-32768,-32768, - 445, -176,-32768,-32768,-32768,-32768 -}; - - -#define YYLAST 2145 - - -static const short yytable[] = { 76, - 84, 29, 31, 33, 41, 104, 107, 203, 261, 43, - 47, 19, 19, 48, 20, 20, 224, 276, 114, 197, - 252, 194, 348, 523, 90, 286, 407, 287, 86, 313, - 512, 178, 167, 108, 55, 36, 182, 138, 198, 379, - 334, 42, -93, 427, 133, 134, 86, 94, -1, 259, - 136, 277, 140, 569, 26, 27, 141, 135, 589, 95, - 96, 188, 521, 204, 205, 86, 26, 27, 26, 27, - 26, 27, 26, 27, 427, 180, 181, 599, 114, 413, - 283, 177, 380, 37, 285, 382, 203, 90, 251, 513, - 290, 570, 38, 138, -2, 138, 590, 433, 436, 579, - 318, 311, 498, -170, 431, 36, 320, 432, 218, 179, - 219, 558, 213, 220, 215, 600, 194, 177, 428, 34, - 179, 86, 223, 86, -93, 597, 194, 216, 479, 217, - 436, 250, 194, 573, 282, 259, 256, 297, 578, 297, - 580, 195, 406, 114, 284, 35, 28, 51, 30, 415, - 586, 449, 32, 321, 120, 246, 247, 5, 531, 7, - 83, 54, 322, 171, 169, 9, 10, 11, 257, 258, - 289, 91, 252, 170, 171, 92, 392, 332, 608, 441, - 517, 13, 333, 180, 442, 312, 411, 403, 227, 228, - 229, 412, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 307, 416, 325, 328, - 56, 371, 541, 311, 543, 420, 311, 425, 5, 119, - 7, 176, 126, 317, 36, 320, 9, 10, 11, 114, - 199, 121, -210, 483, 200, 539, 445, 169, 484, 36, - 363, 142, 13, 179, 606, 366, 170, 171, 425, 607, - 143, 324, 327, 206, 291, 167, 94, 92, 330, 48, - 575, 94, 331, 36, 168, 36, 99, 175, 486, 179, - 184, 297, 321, 201, 393, 195, -18, -18, -18, -18, - 209, 322, 171, 210, -18, -18, -18, 326, 338, 95, - 96, 339, -218, -218, 95, 96, 322, 171, 357, 94, - -18, 214, 417, -141, 221, 469, 418, 222, 90, -141, - 385, 326, -172, 100, 393, 426, 110, 111, 112, 225, - 322, 171, 101, 9, 10, 11, 469, 439, 373, 375, - 405, 200, 48, 223, 408, 5, 44, 7, 45, 24, - 25, 386, 226, 9, 10, 11, 426, 94, 357, 180, - -141, 358, 180, 361, -141, -18, 204, 205, 36, 13, - 189, 409, 179, -96, -96, -96, -96, 95, 96, -96, - 59, -96, -96, -96, 5, 44, 7, 45, 158, 159, - 160, 440, 9, 10, 11, 92, 358, -96, -216, -216, - 273, 93, 435, 465, -26, -26, -26, -26, 13, 274, - 396, 358, -26, -26, -26, 280, 37, 36, 99, 46, - 447, 257, 258, 281, 465, 38, 469, 94, -26, 293, - 464, -141, 299, 602, 435, 497, 358, -141, 300, 414, - 301, 610, 571, 302, 572, 554, 203, 467, 308, 200, - 468, 464, -96, 384, 358, 358, 36, 99, 374, 305, - 95, 96, 519, 499, 303, 100, 524, 505, 507, 309, - 446, 48, 310, 528, 101, 556, 534, 533, -141, 92, - 364, 365, -141, -26, 478, 358, 314, 358, 540, 481, - 156, 157, 158, 159, 160, 546, 207, 274, 419, -22, - -22, -22, -22, 536, 100, 553, 319, -22, -22, -22, - 329, 492, 340, 101, 465, 154, 155, 156, 157, 158, - 159, 160, 94, -22, 161, 162, -141, 163, 164, 165, - 166, 343, -141, 129, 131, 344, 346, 358, 347, 189, - 349, 464, -269, -269, -269, -269, 548, 362, 370, 372, - -269, -269, -269, 111, 112, 95, 96, 376, -30, 9, - 10, 11, 399, 593, 400, 410, -269, -249, 437, 358, - 542, 358, 448, -141, 438, 443, 482, -141, -22, 189, - 551, -105, -105, -105, -105, -105, -105, -105, 485, -105, - -105, -105, -105, -105, -31, -105, -105, -105, -105, -105, - -105, -105, -105, -105, -105, -105, -105, -105, 487, 490, - -105, 491, -105, -105, 493, 500, 502, 358, 494, -105, - 495, -92, -105, 508, 503, 518, 520, -105, -105, -105, - 504, 527, 530, -105, -105, 529, 545, 547, -105, 549, - 544, 550, 262, 552, 263, 5, 6, 7, 8, 574, - 561, 264, 563, 9, 10, 11, -105, -105, -105, -105, - 388, -105, -269, -269, -269, -269, -269, -269, -269, 13, - -269, -269, -269, -269, -269, 564, -269, -269, -269, -269, - -269, -269, -269, -269, -269, -269, -269, -269, -269, 576, - 581, -269, 585, -269, -269, 588, 587, 591, 612, 595, - -269, 161, 162, -269, 163, 164, 165, 166, -269, -269, - -269, 598, 613, 601, -269, -269, 604, 609, -329, -269, - 4, 23, -109, 5, 6, 7, 8, 249, 522, 421, - 109, 9, 10, 11, 444, 278, 122, -269, 402, -269, - -269, 189, -269, -269, -269, 260, 12, 13, -269, -269, - 398, -269, 383, 294, 298, -269, 124, -269, -269, -269, - -269, -269, -269, -269, -269, -269, -269, -269, 212, -269, - -109, 422, -269, 292, -269, -269, 395, 594, 596, -109, - 559, -269, 560, 315, -269, 369, 0, 0, 0, -269, - -269, -269, 0, 0, 0, -269, -269, 14, 0, 262, - -269, 0, 5, 6, 7, 8, 0, 0, 264, 0, - 9, 10, 11, 0, 0, 0, 0, 0, -269, 424, - -269, -269, 189, -269, -269, -269, 13, 0, 0, -269, - -269, 0, -269, 0, 0, 0, -269, 0, -269, -269, - -269, -269, -269, -269, -269, -269, -269, -269, -269, 0, - -269, 0, 0, -269, 0, -269, -269, 0, 5, 44, - 7, 45, -269, 0, 0, -269, 9, 10, 11, 0, - -269, -269, -269, 0, 0, -329, -269, -269, 0, 0, - 0, -269, 13, 0, 0, 0, 0, 36, 5, 44, - 7, 45, 0, 0, 0, 0, 9, 10, 11, -269, - -250, -269, -269, 509, -269, -269, -269, 0, 0, 0, - -269, -269, 13, -269, 0, 0, 0, -269, 0, -269, - -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, - 0, -269, 506, 0, -269, 326, -269, -269, 0, 5, - 6, 7, 8, -269, 322, 171, -269, 9, 10, 11, - 0, -269, -269, -269, 0, 0, 0, -269, -269, 0, - 0, 0, -269, 13, 5, 0, 7, 176, 0, 0, - 0, 0, 9, 10, 11, 0, 0, 0, 0, 0, - -269, 0, -269, -269, 537, -269, -279, -279, 13, 0, - 0, -279, -279, 0, -279, 0, 0, 0, -279, 0, - -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, - -279, 169, -279, 0, 0, -279, 0, -279, -279, 0, - 170, 171, 0, 0, -279, 0, 0, -279, 0, 0, - 0, 0, -279, -279, -279, 0, 0, 0, -279, -279, - 0, 0, 137, -279, 57, 5, 0, 7, 83, 58, - 59, 0, 60, 9, 10, 11, 0, 0, 0, 0, - 0, -279, 0, -279, -279, 0, -279, 0, 0, 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, 0, 0, 70, 71, 0, 0, - 353, 72, 354, 27, 0, 0, 0, 58, 59, 0, - 60, 0, 0, 0, 0, 0, 0, 5, 6, 7, - 8, 73, 74, 368, -82, 9, 10, 11, 61, 0, - 0, 62, 0, 63, 64, 0, 0, 0, 0, 0, - 65, 13, 0, 66, 0, 0, 0, 0, 67, 68, - 69, 0, 0, 0, 70, 71, 0, 0, 0, 72, - 355, 353, 0, 354, 27, 0, 0, 0, 58, 59, - 0, 60, 0, 0, 0, 0, 0, 0, 397, 73, - 74, 0, 356, 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, 0, - 72, 434, 353, 0, 354, 27, 0, 0, 0, 58, - 59, 0, 60, 0, 0, 0, 0, 0, 0, -207, - 73, 74, 0, 356, 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, - 0, 72, 434, 353, 0, 354, 27, 0, 0, 0, - 58, 59, 0, 60, 0, 0, 0, 0, 0, 0, - 480, 73, 74, 0, 356, 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, 353, - 0, 57, 72, 355, 0, 0, 58, 59, 0, 60, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 73, 74, 0, 356, 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, 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, 356, 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, 57, 187, 0, 0, 0, 58, 59, 0, 60, - 0, 73, 74, 0, 61, 255, 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, 288, - 153, 154, 155, 156, 157, 158, 159, 160, 73, 74, - 0, 61, 316, 0, 62, 0, 63, 64, 525, 0, - 0, 0, 0, 65, 0, 0, 66, 0, 0, 0, - 0, 67, 68, 69, 0, 0, 0, 70, 71, 0, - 0, 0, 72, 0, 144, 145, 146, 526, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 73, 74, 0, 0, 404, 354, 450, 6, - 7, 8, 58, 59, 0, 60, 9, 10, 11, 451, - 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 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, 354, 27, 70, - 71, 0, 58, 59, 72, 60, 0, 0, 0, 451, - 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 61, 73, 74, 62, 223, 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, 146, 0, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 463, 61, 73, 74, 62, 223, 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, 0, 72, 57, 5, 0, 7, 83, - 58, 59, 0, 60, 9, 10, 11, 0, 0, 0, - 0, 0, 0, 0, 73, 74, 0, 306, 0, 0, - 13, 61, 0, 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, 496, 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, 128, - 60, 0, 0, 0, 0, 0, 73, 74, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 61, 73, - 74, 62, 0, 63, 64, 429, 0, 0, 0, 0, - 65, 0, 0, 66, 0, 0, 0, 0, 67, 68, - 69, 0, 0, 0, 70, 71, 515, 0, 0, 130, - 0, 144, 145, 146, 0, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 73, - 74, 0, 144, 145, 146, 0, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 0, 0, 0, 0, 0, 0, 144, 145, 146, 430, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 0, 0, 0, 144, 145, 146, - 516, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 0, 195, 0, 0, 0, - 0, 144, 145, 146, 514, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, - 0, 0, 0, 0, 0, 562, 144, 145, 146, 568, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 144, 145, 146, 0, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 152, 153, 154, 155, - 156, 157, 158, 159, 160 -}; - -static const short yycheck[] = { 34, - 35, 9, 10, 11, 18, 43, 47, 104, 184, 19, - 20, 2, 3, 20, 2, 3, 139, 191, 49, 100, - 170, 97, 297, 490, 38, 203, 373, 204, 35, 254, - 1, 88, 9, 47, 32, 3, 92, 72, 101, 341, - 1, 78, 1, 391, 63, 64, 53, 27, 0, 174, - 69, 10, 72, 39, 3, 4, 75, 65, 39, 60, - 61, 96, 489, 60, 61, 72, 3, 4, 3, 4, - 3, 4, 3, 4, 422, 89, 77, 39, 109, 381, - 77, 88, 342, 51, 202, 345, 183, 101, 169, 60, - 208, 77, 60, 128, 0, 130, 77, 399, 400, 566, - 77, 251, 51, 83, 79, 3, 4, 82, 128, 7, - 130, 538, 122, 132, 124, 77, 192, 124, 393, 60, - 7, 128, 83, 130, 83, 592, 202, 125, 430, 127, - 432, 166, 208, 560, 197, 260, 171, 213, 565, 215, - 567, 31, 367, 174, 200, 60, 83, 83, 83, 39, - 577, 426, 83, 51, 1, 163, 164, 4, 505, 6, - 7, 83, 60, 61, 51, 12, 13, 14, 60, 61, - 205, 78, 322, 60, 61, 82, 350, 77, 605, 3, - 482, 28, 82, 197, 8, 77, 77, 364, 143, 144, - 145, 82, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 225, 385, 265, 266, - 83, 334, 514, 363, 516, 389, 366, 391, 4, 79, - 6, 7, 79, 258, 3, 4, 12, 13, 14, 260, - 78, 78, 79, 77, 82, 510, 414, 51, 82, 3, - 321, 77, 28, 7, 77, 326, 60, 61, 422, 82, - 82, 265, 266, 78, 209, 9, 27, 82, 78, 266, - 562, 27, 82, 3, 77, 3, 4, 77, 446, 7, - 60, 347, 51, 1, 350, 31, 4, 5, 6, 7, - 37, 60, 61, 82, 12, 13, 14, 51, 279, 60, - 61, 279, 78, 79, 60, 61, 60, 61, 306, 27, - 28, 78, 78, 31, 77, 428, 82, 77, 322, 37, - 348, 51, 83, 51, 390, 391, 5, 6, 7, 77, - 60, 61, 60, 12, 13, 14, 449, 78, 338, 339, - 365, 82, 339, 83, 375, 4, 5, 6, 7, 78, - 79, 349, 78, 12, 13, 14, 422, 27, 356, 363, - 78, 306, 366, 308, 82, 83, 60, 61, 3, 28, - 1, 375, 7, 4, 5, 6, 7, 60, 61, 10, - 9, 12, 13, 14, 4, 5, 6, 7, 51, 52, - 53, 78, 12, 13, 14, 82, 341, 28, 78, 79, - 84, 1, 400, 428, 4, 5, 6, 7, 28, 78, - 355, 356, 12, 13, 14, 60, 51, 3, 4, 78, - 418, 60, 61, 37, 449, 60, 539, 27, 28, 79, - 428, 31, 79, 599, 432, 460, 381, 37, 79, 384, - 77, 607, 555, 77, 557, 78, 533, 428, 39, 82, - 428, 449, 83, 39, 399, 400, 3, 4, 78, 77, - 60, 61, 487, 461, 79, 51, 491, 467, 468, 77, - 415, 468, 84, 498, 60, 78, 507, 505, 78, 82, - 60, 61, 82, 83, 429, 430, 84, 432, 513, 434, - 49, 50, 51, 52, 53, 520, 1, 78, 79, 4, - 5, 6, 7, 507, 51, 530, 77, 12, 13, 14, - 77, 456, 60, 60, 539, 47, 48, 49, 50, 51, - 52, 53, 27, 28, 55, 56, 31, 58, 59, 60, - 61, 37, 37, 60, 61, 84, 79, 482, 82, 1, - 33, 539, 4, 5, 6, 7, 77, 84, 3, 78, - 12, 13, 14, 6, 7, 60, 61, 3, 39, 12, - 13, 14, 39, 588, 82, 60, 28, 79, 79, 514, - 515, 516, 79, 78, 84, 77, 39, 82, 83, 1, - 525, 3, 4, 5, 6, 7, 8, 9, 77, 11, - 12, 13, 14, 15, 39, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 60, 60, - 32, 60, 34, 35, 39, 7, 39, 562, 78, 41, - 78, 83, 44, 16, 78, 8, 60, 49, 50, 51, - 78, 78, 60, 55, 56, 78, 77, 17, 60, 78, - 82, 77, 1, 78, 3, 4, 5, 6, 7, 78, - 77, 10, 8, 12, 13, 14, 78, 79, 80, 81, - 1, 83, 3, 4, 5, 6, 7, 8, 9, 28, - 11, 12, 13, 14, 15, 77, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 77, - 9, 32, 78, 34, 35, 60, 78, 82, 0, 78, - 41, 55, 56, 44, 58, 59, 60, 61, 49, 50, - 51, 77, 0, 77, 55, 56, 78, 78, 77, 60, - 1, 3, 3, 4, 5, 6, 7, 165, 490, 390, - 48, 12, 13, 14, 412, 192, 53, 78, 363, 80, - 81, 1, 83, 3, 4, 177, 27, 28, 8, 9, - 356, 11, 347, 212, 215, 15, 53, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 118, 29, - 51, 390, 32, 210, 34, 35, 351, 589, 591, 60, - 539, 41, 539, 257, 44, 331, -1, -1, -1, 49, - 50, 51, -1, -1, -1, 55, 56, 78, -1, 1, - 60, -1, 4, 5, 6, 7, -1, -1, 10, -1, - 12, 13, 14, -1, -1, -1, -1, -1, 78, 79, - 80, 81, 1, 83, 3, 4, 28, -1, -1, 8, - 9, -1, 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, 4, 5, - 6, 7, 41, -1, -1, 44, 12, 13, 14, -1, - 49, 50, 51, -1, -1, 77, 55, 56, -1, -1, - -1, 60, 28, -1, -1, -1, -1, 3, 4, 5, - 6, 7, -1, -1, -1, -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, 78, -1, 32, 51, 34, 35, -1, 4, - 5, 6, 7, 41, 60, 61, 44, 12, 13, 14, - -1, 49, 50, 51, -1, -1, -1, 55, 56, -1, - -1, -1, 60, 28, 4, -1, 6, 7, -1, -1, - -1, -1, 12, 13, 14, -1, -1, -1, -1, -1, - 78, -1, 80, 81, 1, 83, 3, 4, 28, -1, - -1, 8, 9, -1, 11, -1, -1, -1, 15, -1, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 51, 29, -1, -1, 32, -1, 34, 35, -1, - 60, 61, -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, 78, -1, 80, 81, -1, 83, -1, -1, 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, -1, -1, 55, 56, -1, -1, - 1, 60, 3, 4, -1, -1, -1, 8, 9, -1, - 11, -1, -1, -1, -1, -1, -1, 4, 5, 6, - 7, 80, 81, 10, 83, 12, 13, 14, 29, -1, - -1, 32, -1, 34, 35, -1, -1, -1, -1, -1, - 41, 28, -1, 44, -1, -1, -1, -1, 49, 50, - 51, -1, -1, -1, 55, 56, -1, -1, -1, 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, -1, - 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, - -1, 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, 3, 60, 61, -1, -1, 8, 9, -1, 11, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 80, 81, -1, 83, -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, 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, -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, 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, -1, - -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, -1, -1, 55, 56, -1, - -1, -1, 60, -1, 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, 38, -1, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 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, -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, -1, -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, -1, 80, 81, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 29, 80, - 81, 32, -1, 34, 35, 10, -1, -1, -1, -1, - 41, -1, -1, 44, -1, -1, -1, -1, 49, 50, - 51, -1, -1, -1, 55, 56, 10, -1, -1, 60, - -1, 36, 37, 38, -1, 40, 41, 42, 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, - -1, -1, -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, 36, 37, 38, - 84, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, -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, -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, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 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 "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__) -#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 -#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 - -#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 169 "bison.simple" -int -yyparse() -{ - 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; /* 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. */ - - 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. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), -#ifdef YYLSP_NEEDED - &yyls1, size * sizeof (*yylsp), -#endif - &yystacksize); - - 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 - - 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]; - 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 symboles 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 219 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids an empty source file"); - ; - break;} -case 2: -#line 223 "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 236 "c-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 5: -#line 237 "c-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 9: -#line 244 "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 255 "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 260 "c-parse.y" -{; - break;} -case 12: -#line 262 "c-parse.y" -{; - break;} -case 13: -#line 264 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 14: -#line 266 "c-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 17: -#line 270 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C does not allow extra `;' outside of a function"); ; - break;} -case 18: -#line 276 "c-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 19: -#line 280 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 20: -#line 282 "c-parse.y" -{ finish_function (0); ; - break;} -case 21: -#line 284 "c-parse.y" -{ ; - break;} -case 22: -#line 286 "c-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 23: -#line 290 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 24: -#line 292 "c-parse.y" -{ finish_function (0); ; - break;} -case 25: -#line 294 "c-parse.y" -{ ; - break;} -case 26: -#line 296 "c-parse.y" -{ if (! start_function (NULL_TREE, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 27: -#line 300 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 28: -#line 302 "c-parse.y" -{ finish_function (0); ; - break;} -case 29: -#line 304 "c-parse.y" -{ ; - break;} -case 32: -#line 313 "c-parse.y" -{ yyval.code = ADDR_EXPR; ; - break;} -case 33: -#line 315 "c-parse.y" -{ yyval.code = NEGATE_EXPR; ; - break;} -case 34: -#line 317 "c-parse.y" -{ yyval.code = CONVERT_EXPR; ; - break;} -case 35: -#line 319 "c-parse.y" -{ yyval.code = PREINCREMENT_EXPR; ; - break;} -case 36: -#line 321 "c-parse.y" -{ yyval.code = PREDECREMENT_EXPR; ; - break;} -case 37: -#line 323 "c-parse.y" -{ yyval.code = BIT_NOT_EXPR; ; - break;} -case 38: -#line 325 "c-parse.y" -{ yyval.code = TRUTH_NOT_EXPR; ; - break;} -case 39: -#line 329 "c-parse.y" -{ yyval.ttype = build_compound_expr (yyvsp[0].ttype); ; - break;} -case 40: -#line 334 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 42: -#line 340 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 43: -#line 342 "c-parse.y" -{ chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 45: -#line 348 "c-parse.y" -{ yyval.ttype = build_indirect_ref (yyvsp[0].ttype, "unary *"); ; - break;} -case 46: -#line 351 "c-parse.y" -{ yyvsp[0].itype = pedantic; - pedantic = 0; ; - break;} -case 47: -#line 354 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - pedantic = yyvsp[-2].itype; ; - break;} -case 48: -#line 357 "c-parse.y" -{ yyval.ttype = build_unary_op (yyvsp[-1].code, yyvsp[0].ttype, 0); - overflow_warning (yyval.ttype); ; - break;} -case 49: -#line 361 "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 387 "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 392 "c-parse.y" -{ yyval.ttype = c_sizeof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 52: -#line 394 "c-parse.y" -{ yyval.ttype = c_alignof_expr (yyvsp[0].ttype); ; - break;} -case 53: -#line 396 "c-parse.y" -{ yyval.ttype = c_alignof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 54: -#line 398 "c-parse.y" -{ yyval.ttype = build_unary_op (REALPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 55: -#line 400 "c-parse.y" -{ yyval.ttype = build_unary_op (IMAGPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 57: -#line 406 "c-parse.y" -{ tree type = groktypename (yyvsp[-2].ttype); - yyval.ttype = build_c_cast (type, yyvsp[0].ttype); ; - break;} -case 58: -#line 409 "c-parse.y" -{ tree type = groktypename (yyvsp[-5].ttype); - char *name; - 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 = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-2].ttype)), - NULL_PTR, 0, 0, name); - if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) - { - int failure = complete_array_type (type, yyval.ttype, 1); - if (failure) - abort (); - } - ; - break;} -case 60: -#line 436 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 61: -#line 438 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 62: -#line 440 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 63: -#line 442 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 64: -#line 444 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 65: -#line 446 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 66: -#line 448 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 67: -#line 450 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 68: -#line 452 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 69: -#line 454 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 70: -#line 456 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 71: -#line 458 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 72: -#line 460 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ANDIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 73: -#line 462 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ORIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 74: -#line 464 "c-parse.y" -{ yyval.ttype = build_conditional_expr (yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 75: -#line 466 "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 76: -#line 469 "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 77: -#line 476 "c-parse.y" -{ - tree context; - - 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 79: -#line 577 "c-parse.y" -{ yyval.ttype = combine_strings (yyvsp[0].ttype); ; - break;} -case 80: -#line 579 "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 81: -#line 585 "c-parse.y" -{ yyval.ttype = error_mark_node; ; - break;} -case 82: -#line 587 "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 83: -#line 601 "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; - - /* 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); - ; - break;} -case 84: -#line 619 "c-parse.y" -{ yyval.ttype = build_function_call (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 85: -#line 621 "c-parse.y" -{ yyval.ttype = build_array_ref (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 86: -#line 623 "c-parse.y" -{ - yyval.ttype = build_component_ref (yyvsp[-2].ttype, yyvsp[0].ttype); - ; - break;} -case 87: -#line 627 "c-parse.y" -{ - tree expr = build_indirect_ref (yyvsp[-2].ttype, "->"); - - yyval.ttype = build_component_ref (expr, yyvsp[0].ttype); - ; - break;} -case 88: -#line 633 "c-parse.y" -{ yyval.ttype = build_unary_op (POSTINCREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 89: -#line 635 "c-parse.y" -{ yyval.ttype = build_unary_op (POSTDECREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 91: -#line 642 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 94: -#line 651 "c-parse.y" -{ c_mark_varargs (); - if (pedantic) - pedwarn ("ANSI C does not permit use of `varargs.h'"); ; - break;} -case 95: -#line 661 "c-parse.y" -{ ; - break;} -case 100: -#line 673 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 101: -#line 677 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 102: -#line 681 "c-parse.y" -{ shadow_tag_warned (yyvsp[-1].ttype, 1); - pedwarn ("empty declaration"); ; - break;} -case 103: -#line 684 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 104: -#line 693 "c-parse.y" -{ ; - break;} -case 109: -#line 708 "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 110: -#line 717 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 111: -#line 721 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 112: -#line 725 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 113: -#line 729 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 114: -#line 733 "c-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 115: -#line 735 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 116: -#line 744 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 117: -#line 746 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 118: -#line 750 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 119: -#line 752 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 120: -#line 754 "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 121: -#line 766 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 122: -#line 769 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 123: -#line 771 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 124: -#line 774 "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 125: -#line 788 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 126: -#line 790 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 127: -#line 794 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 128: -#line 796 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 131: -#line 806 "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 132: -#line 810 "c-parse.y" -{ yyval.ttype = TREE_TYPE (yyvsp[-1].ttype); ; - break;} -case 133: -#line 812 "c-parse.y" -{ yyval.ttype = groktypename (yyvsp[-1].ttype); ; - break;} -case 141: -#line 834 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 142: -#line 836 "c-parse.y" -{ if (TREE_CHAIN (yyvsp[-1].ttype)) yyvsp[-1].ttype = combine_strings (yyvsp[-1].ttype); - yyval.ttype = yyvsp[-1].ttype; - ; - break;} -case 143: -#line 843 "c-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); ; - break;} -case 144: -#line 846 "c-parse.y" -{ decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 145: -#line 849 "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 146: -#line 856 "c-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); ; - break;} -case 147: -#line 859 "c-parse.y" -{ decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 148: -#line 862 "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 149: -#line 870 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 150: -#line 872 "c-parse.y" -{ yyval.ttype = yyvsp[-2].ttype; ; - break;} -case 151: -#line 877 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 152: -#line 879 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 153: -#line 884 "c-parse.y" -{ if (strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "packed")) - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = yyvsp[0].ttype; ; - break;} -case 154: -#line 889 "c-parse.y" -{ /* If not "mode (m)", then issue warning. */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-3].ttype), "mode") != 0) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-3].ttype)); - yyval.ttype = yyvsp[-3].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); ; - break;} -case 155: -#line 899 "c-parse.y" -{ /* if not "aligned(n)", then issue warning */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-3].ttype), "aligned") != 0 - || TREE_CODE (yyvsp[-1].ttype) != INTEGER_CST) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-3].ttype)); - yyval.ttype = yyvsp[-3].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); ; - break;} -case 156: -#line 910 "c-parse.y" -{ /* if not "format(...)", then issue warning */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-7].ttype), "format") != 0 - || TREE_CODE (yyvsp[-3].ttype) != INTEGER_CST - || TREE_CODE (yyvsp[-1].ttype) != INTEGER_CST) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-7].ttype)); - yyval.ttype = yyvsp[-7].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-7].ttype, - tree_cons (yyvsp[-5].ttype, - tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE), - NULL_TREE), - NULL_TREE); ; - break;} -case 158: -#line 930 "c-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - if (pedantic) - pedwarn ("ANSI C forbids empty initializer braces"); ; - break;} -case 159: -#line 934 "c-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-1].ttype)); ; - break;} -case 160: -#line 936 "c-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-2].ttype)); ; - break;} -case 161: -#line 938 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 162: -#line 945 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 163: -#line 947 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 164: -#line 952 "c-parse.y" -{ yyval.ttype = build_tree_list (tree_cons (yyvsp[-4].ttype, NULL_TREE, - build_tree_list (yyvsp[-2].ttype, NULL_TREE)), - yyvsp[0].ttype); ; - break;} -case 165: -#line 956 "c-parse.y" -{ yyval.ttype = tree_cons (tree_cons (yyvsp[-4].ttype, NULL_TREE, - build_tree_list (yyvsp[-2].ttype, NULL_TREE)), - yyvsp[0].ttype, - yyvsp[-7].ttype); ; - break;} -case 166: -#line 961 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 167: -#line 963 "c-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-2].ttype, yyvsp[0].ttype, yyvsp[-5].ttype); ; - break;} -case 168: -#line 965 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 169: -#line 967 "c-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-2].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 170: -#line 972 "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 171: -#line 987 "c-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 172: -#line 993 "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 173: -#line 1008 "c-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 176: -#line 1024 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 177: -#line 1026 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 178: -#line 1031 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 179: -#line 1033 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 180: -#line 1035 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 182: -#line 1046 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 183: -#line 1051 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 184: -#line 1053 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 185: -#line 1055 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 187: -#line 1064 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 188: -#line 1069 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 189: -#line 1071 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 190: -#line 1073 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 191: -#line 1075 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 193: -#line 1081 "c-parse.y" -{ yyval.ttype = start_struct (RECORD_TYPE, yyvsp[-1].ttype); - /* Start scope of tag before parsing components. */ - ; - break;} -case 194: -#line 1085 "c-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); - /* Really define the structure. */ - ; - break;} -case 195: -#line 1089 "c-parse.y" -{ yyval.ttype = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 196: -#line 1092 "c-parse.y" -{ yyval.ttype = xref_tag (RECORD_TYPE, yyvsp[0].ttype); ; - break;} -case 197: -#line 1094 "c-parse.y" -{ yyval.ttype = start_struct (UNION_TYPE, yyvsp[-1].ttype); ; - break;} -case 198: -#line 1096 "c-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 199: -#line 1098 "c-parse.y" -{ yyval.ttype = finish_struct (start_struct (UNION_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 200: -#line 1101 "c-parse.y" -{ yyval.ttype = xref_tag (UNION_TYPE, yyvsp[0].ttype); ; - break;} -case 201: -#line 1103 "c-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (yyvsp[-1].ttype); ; - break;} -case 202: -#line 1106 "c-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 203: -#line 1109 "c-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (NULL_TREE); ; - break;} -case 204: -#line 1112 "c-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 205: -#line 1115 "c-parse.y" -{ yyval.ttype = xref_tag (ENUMERAL_TYPE, yyvsp[0].ttype); ; - break;} -case 209: -#line 1126 "c-parse.y" -{ if (pedantic) pedwarn ("comma at end of enumerator list"); ; - break;} -case 210: -#line 1131 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 211: -#line 1133 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); - pedwarn ("no semicolon at end of struct or union"); ; - break;} -case 212: -#line 1138 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 213: -#line 1140 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 214: -#line 1142 "c-parse.y" -{ if (pedantic) - pedwarn ("extra semicolon in struct or union specified"); ; - break;} -case 215: -#line 1157 "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 216: -#line 1162 "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 217: -#line 1167 "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 218: -#line 1172 "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 219: -#line 1177 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 221: -#line 1183 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 222: -#line 1188 "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 223: -#line 1192 "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 224: -#line 1195 "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 226: -#line 1207 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 227: -#line 1213 "c-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 228: -#line 1215 "c-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 229: -#line 1220 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 230: -#line 1222 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 231: -#line 1227 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 233: -#line 1233 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 234: -#line 1235 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 235: -#line 1240 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 236: -#line 1242 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 237: -#line 1247 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 238: -#line 1250 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 239: -#line 1252 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 240: -#line 1254 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 241: -#line 1256 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 242: -#line 1258 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 243: -#line 1260 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 244: -#line 1262 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 245: -#line 1264 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); ; - break;} -case 252: -#line 1286 "c-parse.y" -{ emit_line_note (input_filename, lineno); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - ; - break;} -case 254: -#line 1299 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids label declarations"); ; - break;} -case 257: -#line 1310 "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 258: -#line 1324 "c-parse.y" -{; - break;} -case 260: -#line 1329 "c-parse.y" -{ yyval.ttype = convert (void_type_node, integer_zero_node); ; - break;} -case 261: -#line 1331 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), 1, 0); - yyval.ttype = poplevel (1, 1, 0); - pop_momentary (); ; - break;} -case 262: -#line 1336 "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); - pop_momentary (); ; - break;} -case 263: -#line 1341 "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); - pop_momentary (); ; - break;} -case 266: -#line 1358 "c-parse.y" -{ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - expand_start_cond (truthvalue_conversion (yyvsp[-1].ttype), 0); - yyvsp[-3].itype = stmt_count; - if_stmt_file = yyvsp[-5].filename; - if_stmt_line = yyvsp[-4].lineno; - position_after_white_space (); ; - break;} -case 267: -#line 1371 "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 268: -#line 1378 "c-parse.y" -{ expand_loop_continue_here (); ; - break;} -case 269: -#line 1382 "c-parse.y" -{ yyval.filename = input_filename; ; - break;} -case 270: -#line 1386 "c-parse.y" -{ yyval.lineno = lineno; ; - break;} -case 271: -#line 1391 "c-parse.y" -{ ; - break;} -case 272: -#line 1396 "c-parse.y" -{ ; - break;} -case 273: -#line 1401 "c-parse.y" -{ ; - break;} -case 275: -#line 1407 "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 276: -#line 1419 "c-parse.y" -{ stmt_count++; ; - break;} -case 278: -#line 1422 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - iterator_expand (yyvsp[-1].ttype); - clear_momentary (); ; - break;} -case 279: -#line 1427 "c-parse.y" -{ expand_start_else (); - yyvsp[-1].itype = stmt_count; - position_after_white_space (); ; - break;} -case 280: -#line 1431 "c-parse.y" -{ expand_end_cond (); - if (extra_warnings && stmt_count == yyvsp[-3].itype) - warning ("empty body in an else-statement"); ; - break;} -case 281: -#line 1435 "c-parse.y" -{ expand_end_cond (); - 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 282: -#line 1443 "c-parse.y" -{ expand_end_cond (); ; - break;} -case 283: -#line 1445 "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 284: -#line 1455 "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 285: -#line 1464 "c-parse.y" -{ expand_end_loop (); ; - break;} -case 286: -#line 1467 "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 287: -#line 1474 "c-parse.y" -{ expand_end_loop (); - clear_momentary (); ; - break;} -case 288: -#line 1478 "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 289: -#line 1490 "c-parse.y" -{ yyvsp[0].lineno = lineno; - yyval.filename = input_filename; ; - break;} -case 290: -#line 1493 "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 291: -#line 1509 "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); - pop_momentary (); - expand_end_loop (); ; - break;} -case 292: -#line 1517 "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 293: -#line 1525 "c-parse.y" -{ expand_end_case (yyvsp[-3].ttype); - pop_momentary (); ; - break;} -case 294: -#line 1528 "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 295: -#line 1533 "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 296: -#line 1538 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - c_expand_return (NULL_TREE); ; - break;} -case 297: -#line 1542 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno); - c_expand_return (yyvsp[-1].ttype); ; - break;} -case 298: -#line 1546 "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 299: -#line 1557 "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 300: -#line 1564 "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 301: -#line 1572 "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 302: -#line 1578 "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 303: -#line 1589 "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 306: -#line 1602 "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"); - 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 307: -#line 1623 "c-parse.y" -{ - if (yyvsp[-1].itype) - iterator_for_loop_end (yyvsp[-3].ttype); - ; - break;} -case 308: -#line 1655 "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, 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 309: -#line 1679 "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, 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 310: -#line 1707 "c-parse.y" -{ - tree duplicate; - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - int success = pushcase (NULL_TREE, 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 311: -#line 1722 "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 312: -#line 1734 "c-parse.y" -{ emit_line_note (input_filename, lineno); ; - break;} -case 313: -#line 1736 "c-parse.y" -{ emit_line_note (input_filename, lineno); ; - break;} -case 314: -#line 1741 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 316: -#line 1748 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 319: -#line 1755 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 320: -#line 1760 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 321: -#line 1765 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), NULL_TREE); ; - break;} -case 322: -#line 1767 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), yyvsp[-2].ttype); ; - break;} -case 323: -#line 1773 "c-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (0); ; - break;} -case 324: -#line 1777 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 326: -#line 1785 "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 327: -#line 1793 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 328: -#line 1795 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); ; - break;} -case 329: -#line 1801 "c-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 330: -#line 1803 "c-parse.y" -{ yyval.ttype = get_parm_info (0); - if (pedantic) - pedwarn ("ANSI C requires a named argument before `...'"); - ; - break;} -case 331: -#line 1808 "c-parse.y" -{ yyval.ttype = get_parm_info (1); ; - break;} -case 332: -#line 1810 "c-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 333: -#line 1815 "c-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 334: -#line 1817 "c-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 335: -#line 1824 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 336: -#line 1826 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 337: -#line 1828 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 338: -#line 1830 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 339: -#line 1832 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 340: -#line 1839 "c-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (1); ; - break;} -case 341: -#line 1843 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 343: -#line 1851 "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 344: -#line 1861 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 345: -#line 1863 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 346: -#line 1869 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 347: -#line 1871 "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 440 "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; - for (x = 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 = 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"); - } - -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 1874 "c-parse.y" - diff --git a/gnu/gcc2/cc1/c-pragma.c b/gnu/gcc2/cc1/c-pragma.c deleted file mode 100644 index 9bb92661d2ba..000000000000 --- a/gnu/gcc2/cc1/c-pragma.c +++ /dev/null @@ -1,198 +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" - -#ifdef HANDLE_SYSV_PRAGMA - -/* Support #pragma weak by default if WEAK_ASM_OP is defined. */ -#if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (SET_ASM_OP) -#define HANDLE_PRAGMA_WEAK 1 -#endif - -/* 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 - { - ps_start, - ps_done, - ps_bad, - ps_weak, - ps_name, - ps_equals, - ps_value, - ps_pack, - ps_left, - ps_align, - ps_right - } 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) - { - if (state == ps_name || state == ps_value) - { - fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP); - ASM_OUTPUT_LABELREF (asm_out_file, name); - fputc ('\n', asm_out_file); - if (state == ps_value) - { - fprintf (asm_out_file, "\t%s\t", SET_ASM_OP); - ASM_OUTPUT_LABELREF (asm_out_file, name); - fputc (',', asm_out_file); - ASM_OUTPUT_LABELREF (asm_out_file, value); - fputc ('\n', asm_out_file); - } - } - else if (! (state == ps_done || state == ps_start)) - warning ("malformed `#pragma weak'"); - } -#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/gcc2/cc1/c-typeck.c b/gnu/gcc2/cc1/c-typeck.c deleted file mode 100644 index a10fb0abcc3f..000000000000 --- a/gnu/gcc2/cc1/c-typeck.c +++ /dev/null @@ -1,5827 +0,0 @@ -/* Build expressions with type checking for C compiler. - Copyright (C) 1987, 1988, 1989, 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. */ - - -/* 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 "partly bracketed initializer" - message within this initializer. */ -static int partial_bracket_mentioned = 0; - -extern char *index (); -extern char *rindex (); - -int mark_addressable (); -static tree convert_for_assignment (); -static void warn_for_assignment (); -static int function_types_compatible_p (); -static int type_lists_compatible_p (); -int self_promoting_args_p (); -static int self_promoting_type_p (); -static int comp_target_types (); -static tree pointer_int_sum (); -static tree pointer_diff (); -static tree convert_sequence (); -static tree unary_complex_lvalue (); -static tree process_init_constructor (); -static tree convert_arguments (); -static char *get_spelling (); -tree digest_init (); -static void pedantic_lvalue_warning (); -tree truthvalue_conversion (); -void incomplete_type_error (); -void readonly_warning (); -static tree internal_build_compound_expr (); - - -/* 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; - - /* 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; - - /* 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. */ - if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) - { - tree subtype1, subtype2, subtype; - if (code1 == COMPLEX_TYPE) - subtype1 = TREE_TYPE (t1); - else - subtype1 = t1; - if (code2 == COMPLEX_TYPE) - subtype2 = TREE_TYPE (t2); - else - subtype2 = t2; - subtype = common_type (subtype1, subtype2); - return build_complex_type (subtype); - } - - 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 t1; - - if (code2 == REAL_TYPE && code1 != REAL_TYPE) - return t2; - - /* Both real or both integers; use the one with greater precision. */ - - if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) - return t1; - else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) - return t2; - - /* Same precision. Prefer longs to ints even when same size. */ - - if (t1 == long_unsigned_type_node - || t2 == long_unsigned_type_node) - return long_unsigned_type_node; - - if (t1 == long_integer_type_node - || 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)) - return long_unsigned_type_node; - return long_integer_type_node; - } - - /* Otherwise prefer the unsigned one. */ - - if (TREE_UNSIGNED (t1)) - return t1; - else return t2; - - 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)); - return build_pointer_type (c_build_type_variant (target, constp, volatilep)); - } -#if 0 - return build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2))); -#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 t1; - if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)) - return t2; - /* Merge the element types, and have a size if either arg has one. */ - return build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); - } - - 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 t1; - if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1)) - return t2; - - /* Simple way if one arg fails to specify argument types. */ - if (TYPE_ARG_TYPES (t1) == 0) - return build_function_type (valtype, TYPE_ARG_TYPES (t2)); - if (TYPE_ARG_TYPES (t2) == 0) - return build_function_type (valtype, TYPE_ARG_TYPES (t1)); - - /* 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: ; - } - - return build_function_type (valtype, newargs); - } - - default: - return t1; - } - -} - -/* 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; - - /* 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 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); - - 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; - - switch (TREE_CODE (t1)) - { - case POINTER_TYPE: - return (TREE_TYPE (t1) == TREE_TYPE (t2) - ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); - - case FUNCTION_TYPE: - return function_types_compatible_p (t1, t2); - - case ARRAY_TYPE: - { - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - tree d1 = TYPE_DOMAIN (t1); - tree d2 = TYPE_DOMAIN (t2); - - /* 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) - return val; - - return (((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); - } - - case RECORD_TYPE: - if (maybe_objc_comptypes (t1, t2, 0) == 1) - return 1; - } - return 0; -} - -/* 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; - - 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 - && 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 - && 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 (TREE_CODE (type) != INTEGER_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) - TREE_CONSTANT_OVERFLOW (t) |= force_fit_type (t, 0); - 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) - && 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. */ - else if (optimize - && TREE_CODE (exp) == VAR_DECL - && TREE_READONLY (exp) - /* But not for iterators! */ - && !ITERATOR_P (exp) - && DECL_MODE (exp) != BLKmode) - { - 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 && 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 && 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; - - 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; - } - - if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) - restype = c_build_type_variant (restype, TYPE_READONLY (type), - TYPE_VOLATILE (type)); - - 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; -} - -/* 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) - { - if (TYPE_SIZE (type) == 0) - { - incomplete_type_error (NULL_TREE, type); - return error_mark_node; - } - - /* Look up component name in the structure type definition. - - 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) - { - int cmp; - - half = (top - bot + 1) >> 1; - field = field_array[bot+half]; - cmp = (long)DECL_NAME (field) - (long)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) == component) - break; - } - } - - 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; - - 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) || flag_volatile; - 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; - } - - 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"); - } -} - -/* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against PARAMS. */ - -#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') - -#define T_I &integer_type_node -#define T_L &long_integer_type_node -#define T_S &short_integer_type_node -#define T_UI &unsigned_type_node -#define T_UL &long_unsigned_type_node -#define T_US &short_unsigned_type_node -#define T_F &float_type_node -#define T_D &double_type_node -#define T_LD &long_double_type_node -#define T_C &char_type_node -#define T_V &void_type_node -#define T_W &wchar_type_node - -typedef struct -{ - char *format_chars; - int pointer_count; - /* Type of argument if no length modifier is used. */ - tree *nolen; - /* Type of argument if length modifier for shortening is used. - If NULL, then this modifier is not allowed. */ - tree *hlen; - /* Type of argument if length modifier `l' is used. - If NULL, then this modifier is not allowed. */ - tree *llen; - /* Type of argument if length modifier `L' is used. - If NULL, then this modifier is not allowed. */ - tree *bigllen; - /* List of other modifier characters allowed with these options. */ - char *flag_chars; -} format_char_info; - -static format_char_info print_table[] - = { - { "di", 0, T_I, T_I, T_L, NULL, "-wp0 +" }, - { "oxX", 0, T_UI, T_UI, T_UL, NULL, "-wp0#" }, - { "u", 0, T_UI, T_UI, T_UL, NULL, "-wp0" }, - { "feEgG", 0, T_D, NULL, NULL, T_LD, "-wp0 +#" }, - { "c", 0, T_I, NULL, T_W, NULL, "-w" }, - { "C", 0, T_W, NULL, NULL, NULL, "-w" }, - { "s", 1, T_C, NULL, T_W, NULL, "-wp" }, - { "S", 1, T_W, NULL, NULL, NULL, "-wp" }, - { "p", 1, T_V, NULL, NULL, NULL, "-" }, - { "n", 1, T_I, T_S, T_L, NULL, "" }, - { NULL } - }; - -static format_char_info scan_table[] - = { - { "di", 1, T_I, T_S, T_L, NULL, "*" }, - { "ouxX", 1, T_UI, T_US, T_UL, NULL, "*" }, - { "efgEG", 1, T_F, NULL, T_D, T_LD, "*" }, - { "sc", 1, T_C, NULL, T_W, NULL, "*" }, - { "[", 1, T_C, NULL, NULL, NULL, "*" }, - { "C", 1, T_W, NULL, NULL, NULL, "*" }, - { "S", 1, T_W, NULL, NULL, NULL, "*" }, - { "p", 2, T_V, NULL, NULL, NULL, "*" }, - { "n", 1, T_I, T_S, T_L, NULL, "" }, - { NULL } - }; - -typedef struct -{ - tree function_ident; /* identifier such as "printf" */ - int is_scan; /* TRUE if *scanf */ - int format_num; /* number of format argument */ - int first_arg_num; /* number of first arg (zero for varargs) */ -} function_info; - -static unsigned int function_info_entries = 0; -static function_info *function_info_table = NULL; - -/* Record information for argument format checking. FUNCTION_IDENT is - the identifier node for the name of the function to check (its decl - need not exist yet). IS_SCAN is true for scanf-type format checking; - false indicates printf-style format checking. FORMAT_NUM is the number - of the argument which is the format control string (starting from 1). - FIRST_ARG_NUM is the number of the first actual argument to check - against teh format string, or zero if no checking is not be done - (e.g. for varargs such as vfprintf). */ - -void -record_format_info (function_ident, is_scan, format_num, first_arg_num) - tree function_ident; - int is_scan; - int format_num; - int first_arg_num; -{ - function_info *info; - - function_info_entries++; - if (function_info_table) - function_info_table - = (function_info *) xrealloc (function_info_table, - function_info_entries * sizeof (function_info)); - else - function_info_table = (function_info *) xmalloc (sizeof (function_info)); - - info = &function_info_table[function_info_entries - 1]; - - info->function_ident = function_ident; - info->is_scan = is_scan; - info->format_num = format_num; - info->first_arg_num = first_arg_num; -} - -/* Initialize the table of functions to perform format checking on. - The ANSI functions are always checked (whether <stdio.h> is - included or not), since it is common to call printf without - including <stdio.h>. There shouldn't be a problem with this, - since ANSI reserves these function names whether you include the - header file or not. In any case, the checking is harmless. */ - -void -init_format_info_table () -{ - record_format_info (get_identifier ("printf"), 0, 1, 2); - record_format_info (get_identifier ("fprintf"), 0, 2, 3); - record_format_info (get_identifier ("sprintf"), 0, 2, 3); - record_format_info (get_identifier ("scanf"), 1, 1, 2); - record_format_info (get_identifier ("fscanf"), 1, 2, 3); - record_format_info (get_identifier ("sscanf"), 1, 2, 3); - record_format_info (get_identifier ("vprintf"), 0, 1, 0); - record_format_info (get_identifier ("vfprintf"), 0, 2, 0); - record_format_info (get_identifier ("vsprintf"), 0, 2, 0); -} - -static char tfaff[] = "too few arguments for format"; - -/* Check the argument list of a call to printf, scanf, etc. - INFO points to the element of function_info_table. - PARAMS is the list of argument values. */ - -static void -check_format (info, params) - function_info *info; - tree params; -{ - int i; - int arg_num; - int suppressed, wide, precise; - int length_char; - int format_char; - int format_length; - tree format_tree; - tree cur_param; - tree cur_type; - tree wanted_type; - char *format_chars; - format_char_info *fci; - static char message[132]; - char flag_chars[8]; - - /* Skip to format argument. If the argument isn't available, there's - no work for us to do; prototype checking will catch the problem. */ - for (arg_num = 1; ; ++arg_num) - { - if (params == 0) - return; - if (arg_num == info->format_num) - break; - params = TREE_CHAIN (params); - } - format_tree = TREE_VALUE (params); - params = TREE_CHAIN (params); - if (format_tree == 0) - return; - /* We can only check the format if it's a string constant. */ - while (TREE_CODE (format_tree) == NOP_EXPR) - format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */ - if (format_tree == null_pointer_node) - { - warning ("null format string"); - return; - } - if (TREE_CODE (format_tree) != ADDR_EXPR) - return; - format_tree = TREE_OPERAND (format_tree, 0); - if (TREE_CODE (format_tree) != STRING_CST) - return; - format_chars = TREE_STRING_POINTER (format_tree); - format_length = TREE_STRING_LENGTH (format_tree); - if (format_length <= 1) - warning ("zero-length format string"); - if (format_chars[--format_length] != 0) - { - warning ("unterminated format string"); - return; - } - /* Skip to first argument to check. */ - while (arg_num + 1 < info->first_arg_num) - { - if (params == 0) - return; - params = TREE_CHAIN (params); - ++arg_num; - } - while (1) - { - if (*format_chars == 0) - { - if (format_chars - TREE_STRING_POINTER (format_tree) != format_length) - warning ("embedded `\\0' in format"); - if (info->first_arg_num != 0 && params != 0) - warning ("too many arguments for format"); - return; - } - if (*format_chars++ != '%') - continue; - if (*format_chars == 0) - { - warning ("spurious trailing `%%' in format"); - continue; - } - if (*format_chars == '%') - { - ++format_chars; - continue; - } - flag_chars[0] = 0; - suppressed = wide = precise = FALSE; - if (info->is_scan) - { - suppressed = *format_chars == '*'; - if (suppressed) - ++format_chars; - while (ISDIGIT (*format_chars)) - ++format_chars; - } - else - { - while (*format_chars != 0 && index (" +#0-", *format_chars) != 0) - { - if (index (flag_chars, *format_chars) != 0) - { - sprintf (message, "repeated `%c' flag in format", - *format_chars); - warning (message); - } - i = strlen (flag_chars); - flag_chars[i++] = *format_chars++; - flag_chars[i] = 0; - } - /* "If the space and + flags both appear, - the space flag will be ignored." */ - if (index (flag_chars, ' ') != 0 - && index (flag_chars, '+') != 0) - warning ("use of both ` ' and `+' flags in format"); - /* "If the 0 and - flags both appear, - the 0 flag will be ignored." */ - if (index (flag_chars, '0') != 0 - && index (flag_chars, '-') != 0) - warning ("use of both `0' and `-' flags in format"); - if (*format_chars == '*') - { - wide = TRUE; - /* "...a field width...may be indicated by an asterisk. - In this case, an int argument supplies the field width..." */ - ++format_chars; - if (params == 0) - { - warning (tfaff); - return; - } - if (info->first_arg_num != 0) - { - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - /* size_t is generally not valid here. - It will work on most machines, because size_t and int - have the same mode. But might as well warn anyway, - since it will fail on other machines. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) - != integer_type_node) - { - sprintf (message, - "field width is not type int (arg %d)", - arg_num); - warning (message); - } - } - } - else - { - while (ISDIGIT (*format_chars)) - { - wide = TRUE; - ++format_chars; - } - } - if (*format_chars == '.') - { - precise = TRUE; - ++format_chars; - if (*format_chars != '*' && !ISDIGIT (*format_chars)) - warning ("`.' not followed by `*' or digit in format"); - /* "...a...precision...may be indicated by an asterisk. - In this case, an int argument supplies the...precision." */ - if (*format_chars == '*') - { - if (info->first_arg_num != 0) - { - ++format_chars; - if (params == 0) - { - warning (tfaff); - return; - } - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) - != integer_type_node) - { - sprintf (message, - "field width is not type int (arg %d)", - arg_num); - warning (message); - } - } - } - else - { - while (ISDIGIT (*format_chars)) - ++format_chars; - } - } - } - if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'L') - length_char = *format_chars++; - else - length_char = 0; - if (suppressed && length_char != 0) - { - sprintf (message, - "use of `*' and `%c' together in format", - length_char); - warning (message); - } - format_char = *format_chars; - if (format_char == 0) - { - warning ("conversion lacks type at end of format"); - continue; - } - format_chars++; - fci = info->is_scan ? scan_table : print_table; - while (1) - { - if (fci->format_chars == 0 - || index (fci->format_chars, format_char) != 0) - break; - ++fci; - } - if (fci->format_chars == 0) - { - if (format_char >= 040 && format_char < 0177) - sprintf (message, - "unknown conversion type character `%c' in format", - format_char); - else - sprintf (message, - "unknown conversion type character 0x%x in format", - format_char); - warning (message); - continue; - } - if (wide && index (fci->flag_chars, 'w') == 0) - { - sprintf (message, "width used with `%c' format", - format_char); - warning (message); - } - if (precise && index (fci->flag_chars, 'p') == 0) - { - sprintf (message, "precision used with `%c' format", - format_char); - warning (message); - } - if (suppressed) - { - if (index (fci->flag_chars, '*') == 0) - { - sprintf (message, - "suppression of `%c' conversion in format", - format_char); - warning (message); - } - continue; - } - for (i = 0; flag_chars[i] != 0; ++i) - { - if (index (fci->flag_chars, flag_chars[i]) == 0) - { - sprintf (message, "flag `%c' used with type `%c'", - flag_chars[i], format_char); - warning (message); - } - } - if (precise && index (flag_chars, '0') != 0 - && (format_char == 'd' || format_char == 'i' - || format_char == 'o' || format_char == 'u' - || format_char == 'x' || format_char == 'x')) - { - sprintf (message, - "precision and `0' flag not both allowed with `%c' format", - format_char); - warning (message); - } - switch (length_char) - { - default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break; - case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break; - case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break; - case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break; - } - if (wanted_type == 0) - { - sprintf (message, - "use of `%c' length character with `%c' type character", - length_char, format_char); - warning (message); - } - - /* - ** XXX -- should kvetch about stuff such as - ** { - ** const int i; - ** - ** scanf ("%d", &i); - ** } - */ - - /* Finally. . .check type of argument against desired type! */ - if (info->first_arg_num == 0) - continue; - if (params == 0) - { - warning (tfaff); - return; - } - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - cur_type = TREE_TYPE (cur_param); - - /* Check the types of any additional pointer arguments - that precede the "real" argument. */ - for (i = 0; i < fci->pointer_count; ++i) - { - if (TREE_CODE (cur_type) == POINTER_TYPE) - { - cur_type = TREE_TYPE (cur_type); - continue; - } - sprintf (message, - "format argument is not a %s (arg %d)", - ((fci->pointer_count == 1) ? "pointer" : "pointer to a pointer"), - arg_num); - warning (message); - break; - } - - /* Check the type of the "real" argument, if there's a type we want. */ - if (i == fci->pointer_count && wanted_type != 0 - && wanted_type != TYPE_MAIN_VARIANT (cur_type) - /* If we want `void *', allow any pointer type. - (Anything else would already have got a warning.) */ - && ! (wanted_type == void_type_node - && fci->pointer_count > 0) - /* Don't warn about differences merely in signedness. */ - && !(TREE_CODE (wanted_type) == INTEGER_TYPE - && TREE_CODE (cur_type) == INTEGER_TYPE - && TYPE_PRECISION (wanted_type) == TYPE_PRECISION (cur_type))) - { - register char *this; - register char *that; - - this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type))); - that = 0; - if (TREE_CODE (cur_type) != ERROR_MARK - && TYPE_NAME (cur_type) != 0 - && TREE_CODE (cur_type) != INTEGER_TYPE - && !(TREE_CODE (cur_type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE)) - { - if (TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (cur_type)) != 0) - that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type))); - else - that = IDENTIFIER_POINTER (TYPE_NAME (cur_type)); - } - - /* A nameless type can't possibly match what the format wants. - So there will be a warning for it. - Make up a string to describe vaguely what it is. */ - if (that == 0) - { - if (TREE_CODE (cur_type) == POINTER_TYPE) - that = "pointer"; - else - that = "different type"; - } - - if (strcmp (this, that) != 0) - { - sprintf (message, "%s format, %s arg (arg %d)", - this, that, arg_num); - warning (message); - } - } - } -} - -/* 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; - register tree coerced_params; - tree 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); - /* 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 != 0) - { - unsigned int i; - - /* See if this function is a format function. */ - for (i = 0; i < function_info_entries; i++) - if (function_info_table[i].function_ident == name) - { - register char *message; - - /* If so, check it. */ - check_format (&function_info_table[i], coerced_params); - break; - } - } - - /* 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 - { - tree parmname; -#ifdef PROMOTE_PROTOTYPES - /* Rather than truncating and then reextending, - convert directly to int, if that's the type we will want. */ - if (! flag_traditional - && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - type = integer_type_node; -#endif - -#if 0 /* This turns out not to win--there's no way to write a prototype - for a function whose arg type is a union with no tag. */ - /* Nameless union automatically casts the types it contains. */ - if (TREE_CODE (type) == UNION_TYPE && TYPE_NAME (type) == 0) - { - tree field; - - for (field = TYPE_FIELDS (type); field; - field = TREE_CHAIN (field)) - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)), - TYPE_MAIN_VARIANT (TREE_TYPE (val)))) - break; - - if (field) - val = build1 (CONVERT_EXPR, type, val); - } -#endif - - /* Optionally warn about conversions that - differ from the default conversions. */ - if (warn_conversion) - { - int formal_prec = TYPE_PRECISION (type); - - if (TREE_CODE (type) != REAL_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) == REAL_TYPE - && TREE_CODE (TREE_TYPE (val)) != REAL_TYPE) - 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)) == 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 ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && (TREE_CODE (TREE_TYPE (val)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE)) - { - 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. */ - ; - 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. */ - ; - 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 - && (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 use NOP_EXPR rather than NON_LVALUE_EXPR - so that convert_for_assignment won't strip it. - That way, we get warnings for things like p = (1 - 1). */ - result = build1 (NOP_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 - /* When dividing two signed integers, you have to promote to int. - E.g. (short) -32868 / (short) -1 doesn't fit in a short. */ - shorten = TREE_UNSIGNED (op0); - 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) - shorten = 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_lt (op1, integer_zero_node)) - 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_lt (op1, integer_zero_node)) - 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_lt (op1, integer_zero_node)) - 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 the same. */ - if (comp_target_types (type0, type1)) - ; - else if (TYPE_MAIN_VARIANT (tt0) == void_type_node) - { - if (pedantic && !integer_zerop (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) - && 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 - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_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 - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_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 (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 (! flag_traditional) - 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 && none_complex) - { - /* 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. */ - - intop = build_binary_op (MULT_EXPR, 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, 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 != 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 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_sizeof_nowarn (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: - 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; - } - 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; - - /* 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 (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) - result_type = qualify_type (type2, type1); - else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node) - 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 (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 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; - 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 nvalue; - - 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 = ""; - return digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, - build_tree_list (field, value)), - NULL_PTR, 0, 0, name); - } - error ("cast to union type from type not present in union"); - return error_mark_node; - } - else - { - tree otype; - - /* 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 (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"); - - value = convert (type, value); - - /* Ignore any integer overflow caused by the cast. */ - if (TREE_CODE (value) == INTEGER_CST) - TREE_CONSTANT_OVERFLOW (value) = 0; - } - - if (value == expr && pedantic) - { - /* If pedantic, don't let a cast be an lvalue. */ - return 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); - return build (COMPOUND_EXPR, lhstype, - TREE_OPERAND (lhs, 0), - build_modify_expr (TREE_OPERAND (lhs, 1), - modifycode, rhs)); - - /* 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)); - /* 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))); - 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); - - 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 - || codel == COMPLEX_TYPE)) - /* Don't use convert_and_check here. If the input has type int - and did not overflow, and we are converting it here to a short, - we don't want an error. A warning would be okay, but it's too risky now - to add an option to convert_and_check to get just warnings. */ - return convert (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); - } - } - } - } - /* 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)) - { - if (pedantic - && ((TYPE_MAIN_VARIANT (ttl) == void_type_node - && TREE_CODE (ttr) == FUNCTION_TYPE) - || - (TYPE_MAIN_VARIANT (ttr) == void_type_node - && !integer_zerop (rhs) - && 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); - 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); - } - } - else if (unsigned_type (TYPE_MAIN_VARIANT (ttl)) - == unsigned_type (TYPE_MAIN_VARIANT (ttr))) - { - if (pedantic) - warn_for_assignment ("pointer targets in %s differ in signedness", - 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, - but not a 0 that results from casting or folding. */ - if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))) - { - 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. */ - -static tree -initializer_constant_valid_p (value, endtype) - tree value; - tree endtype; -{ - switch (TREE_CODE (value)) - { - case CONSTRUCTOR: - 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 - && tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (value)), - TYPE_SIZE (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - /* Allow conversions between 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 - && ! tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (value)), - TYPE_SIZE (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; -} - -/* 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, NULL_PTR, TREE_STATIC (decl), - TREE_STATIC (decl) || pedantic, - IDENTIFIER_POINTER (DECL_NAME (decl))); - - /* 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 - - /* ANSI wants warnings about out-of-range constant initializers. */ - constant_expression_warning (value); - - DECL_INITIAL (decl) = 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 (string) - char *string; -{ - 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); -} - -/* Keep a pointer to the last free TREE_LIST node as we digest an initializer, - so that we can reuse it. This is set in digest_init, and used in - process_init_constructor. - - We will never keep more than one free TREE_LIST node here. This is for - two main reasons. First, we take elements off the old list and add them - to the new list one at a time, thus there should never be more than - one free TREE_LIST at a time, and thus even if there is, we will never - need more than one. Secondly, to avoid dangling pointers to freed obstacks, - we want to always ensure that we have either a pointer to a valid TREE_LIST - within the current initializer, or else a pointer to null. */ - -static tree free_tree_list = NULL_TREE; - -/* Digest the parser output INIT as an initializer for type TYPE. - Return a C expression of type TYPE to represent the initial value. - - If TAIL is nonzero, it points to a variable holding a list of elements - of which INIT is the first. We update the list stored there by - removing from the head all the elements that we use. - Normally this is only one; we use more than one element only if - TYPE is an aggregate and INIT is not a constructor. - - 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. - - If OFWHAT is nonnull, it specifies what we are initializing, for error - messages. Examples: variable name, variable.member, array[44]. - If OFWHAT is null, the component name is stored on the spelling stack. - (That is true for all nested calls to digest_init.) */ - -tree -digest_init (type, init, tail, require_constant, constructor_constant, ofwhat) - tree type, init, *tail; - int require_constant, constructor_constant; - char *ofwhat; -{ - enum tree_code code = TREE_CODE (type); - tree element = 0; - tree old_tail_contents; - /* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR - tree node which has no TREE_TYPE. */ - int raw_constructor - = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0; - tree inside_init = init; - - /* Make sure there is just one "partially bracketed" message - per top-level initializer or constructor. */ - if (ofwhat != 0) - partial_bracket_mentioned = 0; - - /* By default, assume we use one element from a list. - We correct this later in the cases where it is not true. - - Thus, we update TAIL now to point to the next element, and save the - old value in OLD_TAIL_CONTENTS. If we didn't actually use the first - element, then we will reset TAIL before proceeding. FREE_TREE_LIST - is handled similarly. */ - - if (tail) - { - old_tail_contents = *tail; - *tail = TREE_CHAIN (*tail); - free_tree_list = old_tail_contents; - } - else - free_tree_list = 0; - - 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); - - if (inside_init && raw_constructor - && CONSTRUCTOR_ELTS (inside_init) != 0 - && TREE_CHAIN (CONSTRUCTOR_ELTS (inside_init)) == 0) - { - element = TREE_VALUE (CONSTRUCTOR_ELTS (inside_init)); - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (element && TREE_CODE (element) == NON_LVALUE_EXPR) - element = TREE_OPERAND (element, 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) - || (element && TREE_CODE (element) == STRING_CST))) - { - tree string = element ? element : inside_init; - - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) - != char_type_node) - && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) - { - error_init ("char-array%s initialized from wide string", - " `%s'", ofwhat); - return error_mark_node; - } - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) - == char_type_node) - && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) - { - error_init ("int-array%s initialized from non-wide string", - " `%s'", ofwhat); - return error_mark_node; - } - - TREE_TYPE (string) = 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 (string) - - (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'", ofwhat); - } - return string; - } - } - - /* Any type except an array can be initialized - from an expression of the same type, optionally with braces. - For an array, this is allowed only for a string constant. */ - - if (inside_init && TREE_TYPE (inside_init) != 0 - && ((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) - { - error_init ("array%s initialized from non-constant array expression", - " `%s'", ofwhat); - return error_mark_node; - } - - if (optimize && TREE_READONLY (inside_init) - && TREE_CODE (inside_init) == VAR_DECL) - inside_init = decl_constant_value (inside_init); - - if (require_constant && ! TREE_CONSTANT (inside_init)) - { - error_init ("initializer element%s is not constant", - " for `%s'", ofwhat); - 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'", ofwhat); - inside_init = error_mark_node; - } - - return inside_init; - } - - if (element && (TREE_TYPE (element) == type - || (code == ARRAY_TYPE && TREE_TYPE (element) - && comptypes (TREE_TYPE (element), type)))) - { - if (code == ARRAY_TYPE) - { - error_init ("array%s initialized from non-constant array expression", - " `%s'", ofwhat); - return error_mark_node; - } - if (pedantic && (code == RECORD_TYPE || code == UNION_TYPE)) - pedwarn ("single-expression nonscalar initializer has braces"); - if (optimize && TREE_READONLY (element) && TREE_CODE (element) == VAR_DECL) - element = decl_constant_value (element); - - if (require_constant && ! TREE_CONSTANT (element)) - { - error_init ("initializer element%s is not constant", - " for `%s'", ofwhat); - element = error_mark_node; - } - else if (require_constant - && initializer_constant_valid_p (element, TREE_TYPE (element)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", ofwhat); - element = error_mark_node; - } - - return element; - } - - /* Check for initializing a union by its first field. - Such an initializer must use braces. */ - - if (code == UNION_TYPE) - { - tree result; - tree field = TYPE_FIELDS (type); - - /* Find the first named field. ANSI decided in September 1990 - that only named fields count here. */ - while (field && DECL_NAME (field) == 0) - field = TREE_CHAIN (field); - - if (field == 0) - { - error_init ("union%s with no named members cannot be initialized", - " `%s'", ofwhat); - return error_mark_node; - } - - if (raw_constructor) - result = process_init_constructor (type, inside_init, NULL_PTR, - require_constant, - constructor_constant, ofwhat); - else if (tail != 0) - { - *tail = old_tail_contents; - free_tree_list = NULL_TREE; - result = process_init_constructor (type, NULL_TREE, tail, - require_constant, - constructor_constant, ofwhat); - } - else - result = 0; - - if (result) - return result; - } - - /* Handle scalar types, including conversions. */ - - if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE - || code == ENUMERAL_TYPE || code == COMPLEX_TYPE) - { - if (raw_constructor) - { - if (element == 0) - { - error_init ( - "initializer for scalar%s requires one element", - " `%s'", ofwhat); - return error_mark_node; - } - else - { - /* Deal with extra levels of {...}. */ - if (TREE_CODE (element) == CONSTRUCTOR - && TREE_TYPE (element) == 0) - { - error_init ( - "initializer for scalar%s requires one element", - " `%s'", ofwhat); - return error_mark_node; - } - inside_init = element; - } - } - -#if 0 /* A non-raw constructor is an actual expression. */ - if (TREE_CODE (inside_init) == CONSTRUCTOR) - { - error_init ("initializer for scalar%s has extra braces", - " `%s'", ofwhat); - return error_mark_node; - } -#endif - - SAVE_SPELLING_DEPTH - ({ - if (ofwhat) - push_string (ofwhat); - if (!raw_constructor) - inside_init = init; - /* 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, inside_init, - &initialization_message, - NULL_TREE, NULL_TREE, 0); - }); - - if (require_constant && ! TREE_CONSTANT (inside_init)) - { - error_init ("initializer element%s is not constant", - " for `%s'", ofwhat); - 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'", ofwhat); - 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'", ofwhat); - return error_mark_node; - } - - if (code == ARRAY_TYPE || code == RECORD_TYPE) - { - if (raw_constructor) - return process_init_constructor (type, inside_init, - NULL_PTR, constructor_constant, - constructor_constant, ofwhat); - else if (tail != 0) - { - *tail = old_tail_contents; - free_tree_list = NULL_TREE; - return process_init_constructor (type, NULL_TREE, tail, - constructor_constant, - constructor_constant, ofwhat); - } - else if (flag_traditional) - /* Traditionally one can say `char x[100] = 0;'. */ - return process_init_constructor (type, - build_nt (CONSTRUCTOR, NULL_TREE, - tree_cons (NULL_TREE, - inside_init, - NULL_TREE)), - NULL_PTR, constructor_constant, - constructor_constant, ofwhat); - } - - error_init ("invalid initializer%s", " for `%s'", ofwhat); - return error_mark_node; -} - -/* Process a constructor for a variable of type TYPE. - The constructor elements may be specified either with INIT or with ELTS, - only one of which should be non-null. - - If INIT is specified, it is a CONSTRUCTOR node which is specifically - and solely for initializing this datum. - - If ELTS is specified, it is the address of a variable containing - a list of expressions. We take as many elements as we need - from the head of the list and update the list. - - In the resulting constructor, TREE_CONSTANT is set if all elts are - constant, and TREE_STATIC is set if, in addition, all elts are simple enough - constants that the assembler and linker can compute them. - - The argument CONSTANT_VALUE says to print an error if either the - value or any element is not a constant. - - The argument CONSTANT_ELEMENT says to print an error if an element - of an aggregate is not constant. It does not apply to a value - which is not a constructor. - - OFWHAT is a character string describing the object being initialized, - for error messages. It might be "variable" or "variable.member" - or "variable[17].member[5]". - - If OFWHAT is null, the description string is stored on the spelling - stack. That is always true for recursive calls. */ - -static tree -process_init_constructor (type, init, elts, constant_value, constant_element, - ofwhat) - tree type, init, *elts; - int constant_value, constant_element; - char *ofwhat; -{ - register tree tail; - /* List of the elements of the result constructor, - in reverse order. */ - register tree members = NULL; - tree result; - int allconstant = 1; - int allsimple = 1; - int erroneous = 0; - int depth = SPELLING_DEPTH (); - - if (ofwhat) - push_string (ofwhat); - - /* Make TAIL be the list of elements to use for the initialization, - no matter how the data was given to us. */ - - if (elts) - { - if (warn_missing_braces) - { - if (! partial_bracket_mentioned) - warning ("aggregate has a partly bracketed initializer"); - partial_bracket_mentioned = 1; - } - tail = *elts; - } - else - tail = CONSTRUCTOR_ELTS (init); - - /* Gobble as many elements as needed, and make a constructor or initial value - for each element of this aggregate. Chain them together in result. - If there are too few, use 0 for each scalar ultimate component. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree min_index, max_index; - /* These are non-zero only within a range initializer. */ - tree start_index = 0, end_index = 0; - /* Within a range, this is the value for the elts in the range. */ - tree range_val = 0; - /* Do arithmetic using double integers, but don't use fold/build, - because these allocate a new tree object everytime they are called, - thus resulting in gcc using too much memory for large - initializers. */ - union tree_node current_index_node, members_index_node; - tree current_index = ¤t_index_node; - tree members_index = &members_index_node; - TREE_TYPE (current_index) = integer_type_node; - TREE_TYPE (members_index) = integer_type_node; - - /* If we have array bounds, set our bounds from that. Otherwise, - we have a lower bound of zero and an unknown upper bound. */ - if (TYPE_DOMAIN (type)) - { - min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); - max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); - } - else - { - min_index = integer_zero_node; - max_index = 0; - } - - TREE_INT_CST_LOW (members_index) = TREE_INT_CST_LOW (min_index); - TREE_INT_CST_HIGH (members_index) = TREE_INT_CST_HIGH (min_index); - - /* Don't leave the loop based on index if the next item has an explicit - index value that will override it. */ - - for (TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (min_index), - TREE_INT_CST_HIGH (current_index) = TREE_INT_CST_HIGH (min_index); - tail != 0 || end_index; - add_double (TREE_INT_CST_LOW (current_index), - TREE_INT_CST_HIGH (current_index), 1, 0, - &TREE_INT_CST_LOW (current_index), - &TREE_INT_CST_HIGH (current_index))) - { - register tree next1 = 0; - - /* Handle the case where we are inside of a range. - current_index increments through the range, - so just keep reusing the same element of TAIL - until the end of the range. */ - if (end_index != 0) - { - next1 = range_val; - if (!tree_int_cst_lt (current_index, end_index)) - end_index = 0; - } - - /* If this element specifies an index, - move to that index before storing it in the new list. */ - else if (TREE_PURPOSE (tail) != 0) - { - int win = 0; - tree index = TREE_PURPOSE (tail); - - if (index && (TREE_CODE (index) == NON_LVALUE_EXPR - || TREE_CODE (index) == NOP_EXPR)) - index = TREE_OPERAND (index, 0); - - /* Begin a range. */ - if (TREE_CODE (index) == TREE_LIST) - { - start_index = TREE_PURPOSE (index); - end_index = TREE_PURPOSE (TREE_CHAIN (index)); - - /* Expose constants. It Doesn't matter if we change - the mode.*/ - if (end_index - && (TREE_CODE (end_index) == NON_LVALUE_EXPR - || TREE_CODE (end_index) == NOP_EXPR)) - end_index = TREE_OPERAND (end_index, 0); - if (start_index - && (TREE_CODE (start_index) == NON_LVALUE_EXPR - || TREE_CODE (start_index) == NOP_EXPR)) - start_index = TREE_OPERAND (start_index, 0); - - constant_expression_warning (start_index); - constant_expression_warning (end_index); - - if ((TREE_CODE (start_index) == IDENTIFIER_NODE) - || (TREE_CODE (end_index) == IDENTIFIER_NODE)) - error ("field name used as index in array initializer"); - else if ((TREE_CODE (start_index) != INTEGER_CST) - || (TREE_CODE (end_index) != INTEGER_CST)) - error ("non-constant or non-integer array index in initializer"); - else if (tree_int_cst_lt (start_index, min_index) - || (max_index && tree_int_cst_lt (max_index, start_index)) - || tree_int_cst_lt (end_index, min_index) - || (max_index && tree_int_cst_lt (max_index, end_index))) - error ("array index out of range in initializer"); - else if (tree_int_cst_lt (end_index, start_index)) - { - /* If the range is empty, don't initialize any elements, - but do reset current_index for the next initializer - element. */ - warning ("empty array initializer range"); - tail = TREE_CHAIN (tail); - TREE_INT_CST_LOW (current_index) - = TREE_INT_CST_LOW (end_index); - TREE_INT_CST_HIGH (current_index) - = TREE_INT_CST_HIGH (end_index); - continue; - } - else - { - TREE_INT_CST_LOW (current_index) - = TREE_INT_CST_LOW (start_index); - TREE_INT_CST_HIGH (current_index) - = TREE_INT_CST_HIGH (start_index); - win = 1; - /* See if the first element is also the last. */ - if (!tree_int_cst_lt (current_index, end_index)) - end_index = 0; - } - } - else if (TREE_CODE (index) == IDENTIFIER_NODE) - error ("field name used as index in array initializer"); - else if (TREE_CODE (index) != INTEGER_CST) - error ("non-constant array index in initializer"); - else if (tree_int_cst_lt (index, min_index) - || (max_index && tree_int_cst_lt (max_index, index))) - error ("array index out of range in initializer"); - else - { - constant_expression_warning (index); - TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (index); - TREE_INT_CST_HIGH (current_index) - = TREE_INT_CST_HIGH (index); - win = 1; - } - - if (!win) - { - /* If there was an error, end the current range. */ - end_index = 0; - TREE_VALUE (tail) = error_mark_node; - } - } - - if (max_index && tree_int_cst_lt (max_index, current_index)) - break; /* Stop if we've indeed run out of elements. */ - - /* Now digest the value specified. */ - if (next1 != 0) - ; - else if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - /* Build the element of this array, with "[]" notation. For - error messages, we assume that the index fits within a - host int. */ - SAVE_SPELLING_DEPTH - ({ - push_array_bounds (TREE_INT_CST_LOW (current_index)); - next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)), - TREE_VALUE (tail), &tail1, - /* Both of these are the same because - a value here is an elt overall. */ - constant_element, constant_element, - NULL_PTR); - }); - - if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) - abort (); - if (tail == tail1 && TYPE_DOMAIN (type) == 0) - { - error_init ( - "non-empty initializer for array%s of empty elements", - " `%s'", NULL_PTR); - /* Just ignore what we were supposed to use. */ - tail1 = 0; - } - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - - if (end_index != 0) - range_val = next1; - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) - allsimple = 0; - - /* Now store NEXT1 in the list, I elements from the *end*. - Make the list longer if necessary. */ - while (! tree_int_cst_lt (current_index, members_index)) - { - if (free_tree_list) - { - TREE_CHAIN (free_tree_list) = members; - TREE_PURPOSE (free_tree_list) = NULL_TREE; - TREE_VALUE (free_tree_list) = NULL_TREE; - members = free_tree_list; - free_tree_list = NULL_TREE; - } - else - members = tree_cons (NULL_TREE, NULL_TREE, members); - add_double (TREE_INT_CST_LOW (members_index), - TREE_INT_CST_HIGH (members_index), 1, 0, - &TREE_INT_CST_LOW (members_index), - &TREE_INT_CST_HIGH (members_index)); - } - - { - tree temp; - union tree_node idx_node; - tree idx = &idx_node; - TREE_TYPE (idx) = integer_type_node; - - temp = members; - for (add_double (TREE_INT_CST_LOW (members_index), - TREE_INT_CST_HIGH (members_index), -1, -1, - &TREE_INT_CST_LOW (idx), - &TREE_INT_CST_HIGH (idx)); - tree_int_cst_lt (current_index, idx); - add_double (TREE_INT_CST_LOW (idx), - TREE_INT_CST_HIGH (idx), -1, -1, - &TREE_INT_CST_LOW (idx), - &TREE_INT_CST_HIGH (idx))) - temp = TREE_CHAIN (temp); - TREE_VALUE (temp) = next1; - } - } - } - if (TREE_CODE (type) == RECORD_TYPE) - { - register tree field; - int members_length = 0; - int i; - - /* Don't leave the loop based on field just yet; see if next item - overrides the expected field first. */ - - for (field = TYPE_FIELDS (type), i = 0; tail; - field = TREE_CHAIN (field), i++) - { - register tree next1; - - /* If this element specifies a field, - move to that field before storing it in the new list. */ - if (TREE_PURPOSE (tail) != 0) - { - int win = 0; - - if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) - error ("index value instead of field name in structure initializer"); - else - { - tree temp; - int j; - for (temp = TYPE_FIELDS (type), j = 0; - temp; - temp = TREE_CHAIN (temp), j++) - if (DECL_NAME (temp) == TREE_PURPOSE (tail)) - break; - if (temp) - field = temp, i = j, win = 1; - else - error ("no field `%s' in structure being initialized", - IDENTIFIER_POINTER (TREE_PURPOSE (tail))); - } - if (!win) - TREE_VALUE (tail) = error_mark_node; - } - - if (field == 0) - break; /* No more fields to init. */ - - if (! DECL_NAME (field)) - { - next1 = integer_zero_node; - } - else if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - /* Build the name of this member, with a "." for membership. */ - SAVE_SPELLING_DEPTH - ({ - push_member_name (IDENTIFIER_POINTER (DECL_NAME (field))); - next1 = digest_init (TREE_TYPE (field), - TREE_VALUE (tail), &tail1, - constant_element, constant_element, - NULL_PTR); - }); - if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) - abort (); - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) - allsimple = 0; - - /* Now store NEXT1 in the list, I elements from the *end*. - Make the list longer if necessary. */ - while (i >= members_length) - { - if (free_tree_list) - { - TREE_CHAIN (free_tree_list) = members; - TREE_PURPOSE (free_tree_list) = NULL_TREE; - TREE_VALUE (free_tree_list) = NULL_TREE; - members = free_tree_list; - free_tree_list = NULL_TREE; - } - else - members = tree_cons (NULL_TREE, NULL_TREE, members); - members_length++; - } - { - tree temp; - int j; - - temp = members; - for (j = members_length - 1; j > i; j--) - temp = TREE_CHAIN (temp); - TREE_VALUE (temp) = next1; - TREE_PURPOSE (temp) = field; - } - } - } - if (TREE_CODE (type) == UNION_TYPE) - { - register tree field = TYPE_FIELDS (type); - register tree next1; - - /* Find the first named field. ANSI decided in September 1990 - that only named fields count here. */ - while (field && DECL_NAME (field) == 0) - field = TREE_CHAIN (field); - - /* For a union, get the initializer for 1 fld. */ - - if (tail == 0) - { - error ("empty initializer for union"); - tail = build_tree_list (0, 0); - } - - /* If this element specifies a field, initialize via that field. */ - if (TREE_PURPOSE (tail) != 0) - { - int win = 0; - - if (TREE_CODE (TREE_PURPOSE (tail)) == FIELD_DECL) - /* Handle the case of a call by build_c_cast. */ - field = TREE_PURPOSE (tail), win = 1; - else if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) - error ("index value instead of field name in union initializer"); - else - { - tree temp; - for (temp = TYPE_FIELDS (type); - temp; - temp = TREE_CHAIN (temp)) - if (DECL_NAME (temp) == TREE_PURPOSE (tail)) - break; - if (temp) - field = temp, win = 1; - else - error ("no field `%s' in union being initialized", - IDENTIFIER_POINTER (TREE_PURPOSE (tail))); - } - if (!win) - TREE_VALUE (tail) = error_mark_node; - } - - if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - /* Build the name of this member, with a "." for membership. */ - SAVE_SPELLING_DEPTH - ({ - push_member_name (IDENTIFIER_POINTER (DECL_NAME (field))); - next1 = digest_init (TREE_TYPE (field), - TREE_VALUE (tail), &tail1, - constant_value, constant_element, NULL_PTR); - }); - if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) - abort (); - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) - allsimple = 0; - if (free_tree_list) - { - TREE_CHAIN (free_tree_list) = members; - TREE_PURPOSE (free_tree_list) = field; - TREE_VALUE (free_tree_list) = next1; - members = free_tree_list; - free_tree_list = NULL_TREE; - } - else - members = tree_cons (field, next1, members); - } - - /* If arguments were specified as a list, just remove the ones we used. */ - if (elts) - *elts = tail; - /* If arguments were specified as a constructor, - complain unless we used all the elements of the constructor. */ - else if (tail) - { - if (TREE_CODE (type) == UNION_TYPE) - { - pedwarn_init ("excess elements in union initializer%s", - " after `%s'", NULL_PTR); - } - else - { - pedwarn_init ("excess elements in aggregate initializer%s", - " after `%s'", NULL_PTR); - } - } - - /* It might be possible to use SAVE_SPELLING_DEPTH, but I suspect that - some preprocessor somewhere won't accept that much text as an argument. - It's also likely to make debugging difficult. */ - - RESTORE_SPELLING_DEPTH (depth); - - if (erroneous) - return error_mark_node; - - if (elts) - result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members)); - else - { - result = init; - CONSTRUCTOR_ELTS (result) = nreverse (members); - TREE_TYPE (result) = type; - TREE_CONSTANT (result) = 0; - TREE_STATIC (result) = 0; - } - if (allconstant) TREE_CONSTANT (result) = 1; - if (allconstant && allsimple) TREE_STATIC (result) = 1; - return result; -} - -/* 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 `volatile' 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); - t = build (MODIFY_EXPR, TREE_TYPE (res), - res, convert (TREE_TYPE (res), t)); - 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; -} |
