mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-27 04:55:01 +08:00
invoke.texi: Document -flang-isoc9x.
* invoke.texi: Document -flang-isoc9x. * Makefile.in (OBJS): Add splay-tree.o. (c-common.o): Depend on rtl.h. (splay-tree.o): List dependencies and provide build rule. * rtl.h (record_alias_subset): New function. * alias.c: Include splay-tree.h. (alias_set_entry): New type. (CHECK_ALIAS_SETS_FOR_CONSISTENCY): Remove. (DIFFERENT_ALIAS_SETS_P): Use mem_in_disjoint_alias_sets_p. (mems_in_disjoin_alias_sets_p): New function. (alias_set_compare): Likewise. (insert_subset_children): Likewise. (get_alias_set_entry): Likewise. * tree.h (TYPE_RESTRICT): New macro. (TYPE_UNQUALIFIED): New manifest constant. (TYPE_QUAL_CONST): Likewise (TYPE_QUAL_VOLATILE): Likewise. (TYPE_QUAL_RESTRICT): Likewise. (tree_type): Add restrict_flag. Reduce count of free bits. (DECL_POINTER_ALIAS_SET): New macro. (DECL_POINTER_ALIAS_SET_KNOWN_P): Likewise. (tree_decl): Add pointer_alias_set. (build_qualified_type): New function. (build_type_variant): Define in terms of build_qualified_type. * tree.c (set_type_quals): New function. (make_node): Initializae DECL_POINTER_ALIAS_SET. (build_type_attribute_variant): Use build_qualified_type and set_type_quals. (build_type_variant): Rename, and modify, to become... (build_qualified_type): New function. (build_complex_type): Use set_type_quals. * c-tree.h (C_TYPE_OBJECT_P): New macro. (C_TYPE_FUNCTION_P): Likewise. (C_TYPE_INCOMPLETE_P): Likewise. (C_TYPE_OBJECT_OR_INCOMPLETE_P): Likewise. (c_apply_type_quals_to_decl): New function. (c_build_qualified_type): New function. (c_build_type_variant): Define in terms of c_build_qualified_type. (flag_isoc9x): Declare. * c-typeck.c (qualify_type): Use c_build_qualified_type. (common_type): Change to use TYPE_QUALS. (comptypes): Likewise. (convert_for_assignment): Likewise. * c-aux-info.c (gen_type): Likewise. Deal with `restrict'. * c-decl.c (flag_isoc9x): Define. (c_decode_option): Handle -flang-isoc9x. (grokdeclarator): Update to handle restrict. Use TYPE_QUALS, c_build_qualified_type, etc. Use c_apply_type_quals_to_decl. * c-lex.c (init_lex): Deal with restrict. (init_lex): Don't treat restrict as a reserved word in -traditional mode, or without -flang-isoc9x. * c-lex.h (rid): Add RID_RESTRICT. * c-parse.gperf (restrict, __restrict, __restrict__): Make equivalent to RID_RESTRICT. * c-parse.in (TYPE_QUAL): Update comment. * c-common.c: Include rtl.h. (c_find_base_decl): New function. (c_build_type_variant): Rename, and modify, to become ... (c_build_qualified_type): New function. (c_apply_type_quals_to_decl): Likewise. (c_get_alias_set): For INDIRECT_REFs, check to see if we can find a particular alias set for the reference. * toplev.c (documented_lang_options): Add -flang-isoc9x. From-SVN: r23212
This commit is contained in:
parent
52e90c5508
commit
3932261a55
@ -1,3 +1,73 @@
|
||||
Wed Oct 21 09:18:58 1998 Mark Mitchell <mark@markmitchell.com>
|
||||
|
||||
* invoke.texi: Document -flang-isoc9x.
|
||||
|
||||
* Makefile.in (OBJS): Add splay-tree.o.
|
||||
(c-common.o): Depend on rtl.h.
|
||||
(splay-tree.o): List dependencies and provide build rule.
|
||||
|
||||
* rtl.h (record_alias_subset): New function.
|
||||
* alias.c: Include splay-tree.h.
|
||||
(alias_set_entry): New type.
|
||||
(CHECK_ALIAS_SETS_FOR_CONSISTENCY): Remove.
|
||||
(DIFFERENT_ALIAS_SETS_P): Use mem_in_disjoint_alias_sets_p.
|
||||
(mems_in_disjoin_alias_sets_p): New function.
|
||||
(alias_set_compare): Likewise.
|
||||
(insert_subset_children): Likewise.
|
||||
(get_alias_set_entry): Likewise.
|
||||
|
||||
* tree.h (TYPE_RESTRICT): New macro.
|
||||
(TYPE_UNQUALIFIED): New manifest constant.
|
||||
(TYPE_QUAL_CONST): Likewise
|
||||
(TYPE_QUAL_VOLATILE): Likewise.
|
||||
(TYPE_QUAL_RESTRICT): Likewise.
|
||||
(tree_type): Add restrict_flag. Reduce count of free bits.
|
||||
(DECL_POINTER_ALIAS_SET): New macro.
|
||||
(DECL_POINTER_ALIAS_SET_KNOWN_P): Likewise.
|
||||
(tree_decl): Add pointer_alias_set.
|
||||
(build_qualified_type): New function.
|
||||
(build_type_variant): Define in terms of build_qualified_type.
|
||||
* tree.c (set_type_quals): New function.
|
||||
(make_node): Initializae DECL_POINTER_ALIAS_SET.
|
||||
(build_type_attribute_variant): Use build_qualified_type and
|
||||
set_type_quals.
|
||||
(build_type_variant): Rename, and modify, to become...
|
||||
(build_qualified_type): New function.
|
||||
(build_complex_type): Use set_type_quals.
|
||||
|
||||
* c-tree.h (C_TYPE_OBJECT_P): New macro.
|
||||
(C_TYPE_FUNCTION_P): Likewise.
|
||||
(C_TYPE_INCOMPLETE_P): Likewise.
|
||||
(C_TYPE_OBJECT_OR_INCOMPLETE_P): Likewise.
|
||||
(c_apply_type_quals_to_decl): New function.
|
||||
(c_build_qualified_type): New function.
|
||||
(c_build_type_variant): Define in terms of c_build_qualified_type.
|
||||
(flag_isoc9x): Declare.
|
||||
* c-typeck.c (qualify_type): Use c_build_qualified_type.
|
||||
(common_type): Change to use TYPE_QUALS.
|
||||
(comptypes): Likewise.
|
||||
(convert_for_assignment): Likewise.
|
||||
* c-aux-info.c (gen_type): Likewise. Deal with `restrict'.
|
||||
* c-decl.c (flag_isoc9x): Define.
|
||||
(c_decode_option): Handle -flang-isoc9x.
|
||||
(grokdeclarator): Update to handle restrict. Use TYPE_QUALS,
|
||||
c_build_qualified_type, etc. Use c_apply_type_quals_to_decl.
|
||||
* c-lex.c (init_lex): Deal with restrict.
|
||||
(init_lex): Don't treat restrict as a reserved word in
|
||||
-traditional mode, or without -flang-isoc9x.
|
||||
* c-lex.h (rid): Add RID_RESTRICT.
|
||||
* c-parse.gperf (restrict, __restrict, __restrict__): Make
|
||||
equivalent to RID_RESTRICT.
|
||||
* c-parse.in (TYPE_QUAL): Update comment.
|
||||
* c-common.c: Include rtl.h.
|
||||
(c_find_base_decl): New function.
|
||||
(c_build_type_variant): Rename, and modify, to become ...
|
||||
(c_build_qualified_type): New function.
|
||||
(c_apply_type_quals_to_decl): Likewise.
|
||||
(c_get_alias_set): For INDIRECT_REFs, check to see if we can find
|
||||
a particular alias set for the reference.
|
||||
* toplev.c (documented_lang_options): Add -flang-isoc9x.
|
||||
|
||||
Wed Oct 21 09:15:06 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* config/arm/arm.h (TARGET_SWITCHES): Document arm specific
|
||||
|
@ -645,7 +645,7 @@ OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
|
||||
insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
|
||||
insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
|
||||
profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o \
|
||||
mbchar.o dyn-string.o
|
||||
mbchar.o dyn-string.o splay-tree.o
|
||||
|
||||
# GEN files are listed separately, so they can be built before doing parallel
|
||||
# makes for cc1 or cc1plus. Otherwise sequent parallel make attempts to load
|
||||
@ -1319,6 +1319,13 @@ vfprintf.o: $(srcdir)/../libiberty/vfprintf.c $(CONFIG_H) system.h gansidecl.h
|
||||
$(LN_S) $(srcdir)/../libiberty/vfprintf.c vfprintf.c
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) vfprintf.c
|
||||
|
||||
splay-tree.o: $(srcdir)/../libiberty/splay-tree.c \
|
||||
$(srcdir)/../include/splay-tree.h $(srcdir)/../include/libiberty.h \
|
||||
gansidecl.h
|
||||
rm -f splay-tree.c
|
||||
$(LN_S) $(srcdir)/../libiberty/splay-tree.c splay-tree.c
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) splay-tree.c
|
||||
|
||||
underscore.c: s-under ; @true
|
||||
|
||||
s-under: $(GCC_PASSES)
|
||||
@ -1337,7 +1344,7 @@ s-under: $(GCC_PASSES)
|
||||
# A file used by all variants of C.
|
||||
|
||||
c-common.o : c-common.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h \
|
||||
flags.h toplev.h output.h
|
||||
flags.h toplev.h output.h rtl.h
|
||||
|
||||
# Language-independent files.
|
||||
|
||||
|
232
gcc/alias.c
232
gcc/alias.c
@ -28,6 +28,49 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "flags.h"
|
||||
#include "output.h"
|
||||
#include "toplev.h"
|
||||
#include "splay-tree.h"
|
||||
|
||||
/* The alias sets assigned to MEMs assist the back-end in determining
|
||||
which MEMs can alias which other MEMs. In general, two MEMs in
|
||||
different alias sets to not alias each other. There is one
|
||||
exception, however. Consider something like:
|
||||
|
||||
struct S {int i; double d; };
|
||||
|
||||
a store to an `S' can alias something of either type `int' or type
|
||||
`double'. (However, a store to an `int' cannot alias a `double'
|
||||
and vice versa.) We indicate this via a tree structure that looks
|
||||
like:
|
||||
struct S
|
||||
/ \
|
||||
/ \
|
||||
|/_ _\|
|
||||
int double
|
||||
|
||||
(The arrows are directed and point downwards.) If, when comparing
|
||||
two alias sets, we can hold one set fixed, and trace the other set
|
||||
downwards, and at some point find the first set, the two MEMs can
|
||||
alias one another. In this situation we say the alias set for
|
||||
`struct S' is the `superset' and that those for `int' and `double'
|
||||
are `subsets'.
|
||||
|
||||
Alias set zero is implicitly a superset of all other alias sets.
|
||||
However, this is no actual entry for alias set zero. It is an
|
||||
error to attempt to explicitly construct a subset of zero. */
|
||||
|
||||
typedef struct alias_set_entry {
|
||||
/* The alias set number, as stored in MEM_ALIAS_SET. */
|
||||
int alias_set;
|
||||
|
||||
/* The children of the alias set. These are not just the immediate
|
||||
children, but, in fact, all children. So, if we have:
|
||||
|
||||
struct T { struct S s; float f; }
|
||||
|
||||
continuing our example above, the children here will be all of
|
||||
`int', `double', `float', and `struct S'. */
|
||||
splay_tree children;
|
||||
}* alias_set_entry;
|
||||
|
||||
static rtx canon_rtx PROTO((rtx));
|
||||
static int rtx_equal_for_memref_p PROTO((rtx, rtx));
|
||||
@ -39,35 +82,23 @@ static rtx find_base_term PROTO((rtx));
|
||||
static int base_alias_check PROTO((rtx, rtx, enum machine_mode,
|
||||
enum machine_mode));
|
||||
static rtx find_base_value PROTO((rtx));
|
||||
static int mems_in_disjoint_alias_sets_p PROTO((rtx, rtx));
|
||||
static int alias_set_compare PROTO((splay_tree_key,
|
||||
splay_tree_key));
|
||||
static int insert_subset_children PROTO((splay_tree_node,
|
||||
void*));
|
||||
static alias_set_entry get_alias_set_entry PROTO((int));
|
||||
|
||||
/* Set up all info needed to perform alias analysis on memory references. */
|
||||
|
||||
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
|
||||
|
||||
/* Perform a basic sanity check. Namely, that there are
|
||||
no alias sets if we're not doing strict aliasing. This helps
|
||||
to catch bugs whereby someone uses PUT_CODE, but doesn't clear
|
||||
MEM_ALIAS_SET, or where a MEM is allocated in some way other
|
||||
than by the use of gen_rtx_MEM, and the MEM_ALIAS_SET is not
|
||||
cleared. */
|
||||
#ifdef ENABLE_CHECKING
|
||||
#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) \
|
||||
(!flag_strict_aliasing \
|
||||
&& (MEM_ALIAS_SET (MEM1) || MEM_ALIAS_SET (MEM2)) \
|
||||
? (abort (), 0) : 0)
|
||||
#else
|
||||
#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) ((void)0)
|
||||
#endif
|
||||
|
||||
/* Returns nonzero if MEM1 and MEM2 do not alias because they are in
|
||||
different alias sets. We ignore alias sets in functions making use
|
||||
of variable arguments because the va_arg macros on some systems are
|
||||
not legal ANSI C. */
|
||||
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
|
||||
(CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2), \
|
||||
MEM_ALIAS_SET (MEM1) && MEM_ALIAS_SET (MEM2) \
|
||||
&& MEM_ALIAS_SET (MEM1) != MEM_ALIAS_SET (MEM2) \
|
||||
&& !current_function_stdarg && !current_function_varargs)
|
||||
mems_in_disjoint_alias_sets_p (MEM1, MEM2)
|
||||
|
||||
/* Cap the number of passes we make over the insns propagating alias
|
||||
information through set chains.
|
||||
@ -131,6 +162,167 @@ char *reg_known_equiv_p;
|
||||
|
||||
static int copying_arguments;
|
||||
|
||||
/* The splay-tree used to store the various alias set entries. */
|
||||
|
||||
static splay_tree alias_sets;
|
||||
|
||||
/* Returns -1, 0, 1 according to whether SET1 is less than, equal to,
|
||||
or greater than SET2. */
|
||||
|
||||
static int
|
||||
alias_set_compare (set1, set2)
|
||||
splay_tree_key set1;
|
||||
splay_tree_key set2;
|
||||
{
|
||||
int s1 = (int) set1;
|
||||
int s2 = (int) set2;
|
||||
|
||||
if (s1 < s2)
|
||||
return -1;
|
||||
else if (s1 > s2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
|
||||
such an entry, or NULL otherwise. */
|
||||
|
||||
static alias_set_entry
|
||||
get_alias_set_entry (alias_set)
|
||||
int alias_set;
|
||||
{
|
||||
splay_tree_node sn =
|
||||
splay_tree_lookup (alias_sets, (splay_tree_key) alias_set);
|
||||
|
||||
return sn ? ((alias_set_entry) sn->value) : ((alias_set_entry) 0);
|
||||
}
|
||||
|
||||
/* Returns nonzero value if the alias sets for MEM1 and MEM2 are such
|
||||
that the two MEMs cannot alias each other. */
|
||||
|
||||
static int
|
||||
mems_in_disjoint_alias_sets_p (mem1, mem2)
|
||||
rtx mem1;
|
||||
rtx mem2;
|
||||
{
|
||||
alias_set_entry ase;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* Perform a basic sanity check. Namely, that there are no alias sets
|
||||
if we're not using strict aliasing. This helps to catch bugs
|
||||
whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or
|
||||
where a MEM is allocated in some way other than by the use of
|
||||
gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared. If we begin to
|
||||
use alias sets to indicate that spilled registers cannot alias each
|
||||
other, we might need to remove this check. */
|
||||
if (!flag_strict_aliasing &&
|
||||
(MEM_ALIAS_SET (mem1) || MEM_ALIAS_SET (mem2)))
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
/* The code used in varargs macros are often not conforming ANSI C,
|
||||
which can trick the compiler into making incorrect aliasing
|
||||
assumptions in these functions. So, we don't use alias sets in
|
||||
such a function. FIXME: This should be moved into the front-end;
|
||||
it is a language-dependent notion, and there's no reason not to
|
||||
still use these checks to handle globals. */
|
||||
if (current_function_stdarg || current_function_varargs)
|
||||
return 0;
|
||||
|
||||
if (!MEM_ALIAS_SET (mem1) || !MEM_ALIAS_SET (mem2))
|
||||
/* We have no alias set information for one of the MEMs, so we
|
||||
have to assume it can alias anything. */
|
||||
return 0;
|
||||
|
||||
if (MEM_ALIAS_SET (mem1) == MEM_ALIAS_SET (mem2))
|
||||
/* The two alias sets are the same, so they may alias. */
|
||||
return 0;
|
||||
|
||||
/* Iterate through each of the children of the first alias set,
|
||||
comparing it with the second alias set. */
|
||||
ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
|
||||
if (ase && splay_tree_lookup (ase->children,
|
||||
(splay_tree_key) MEM_ALIAS_SET (mem2)))
|
||||
return 0;
|
||||
|
||||
/* Now do the same, but with the alias sets reversed. */
|
||||
ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
|
||||
if (ase && splay_tree_lookup (ase->children,
|
||||
(splay_tree_key) MEM_ALIAS_SET (mem1)))
|
||||
return 0;
|
||||
|
||||
/* The two MEMs are in distinct alias sets, and neither one is the
|
||||
child of the other. Therefore, they cannot alias. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Insert the NODE into the splay tree given by DATA. Used by
|
||||
record_alias_subset via splay_tree_foreach. */
|
||||
|
||||
static int
|
||||
insert_subset_children (node, data)
|
||||
splay_tree_node node;
|
||||
void *data;
|
||||
{
|
||||
splay_tree_insert ((splay_tree) data,
|
||||
node->key,
|
||||
node->value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Indicate that things in SUBSET can alias things in SUPERSET, but
|
||||
not vice versa. For example, in C, a store to an `int' can alias a
|
||||
structure containing an `int', but not vice versa. Here, the
|
||||
structure would be the SUPERSET and `int' the SUBSET. This
|
||||
function should be called only once per SUPERSET/SUBSET pair. At
|
||||
present any given alias set may only be a subset of one superset.
|
||||
|
||||
It is illegal for SUPERSET to be zero; everything is implicitly a
|
||||
subset of alias set zero. */
|
||||
|
||||
void
|
||||
record_alias_subset (superset, subset)
|
||||
int superset;
|
||||
int subset;
|
||||
{
|
||||
alias_set_entry superset_entry;
|
||||
alias_set_entry subset_entry;
|
||||
|
||||
if (superset == 0)
|
||||
abort ();
|
||||
|
||||
superset_entry = get_alias_set_entry (superset);
|
||||
if (!superset_entry)
|
||||
{
|
||||
/* Create an entry for the SUPERSET, so that we have a place to
|
||||
attach the SUBSET. */
|
||||
superset_entry =
|
||||
(alias_set_entry) xmalloc (sizeof (struct alias_set_entry));
|
||||
superset_entry->alias_set = superset;
|
||||
superset_entry->children
|
||||
= splay_tree_new (&alias_set_compare, 0, 0);
|
||||
splay_tree_insert (alias_sets,
|
||||
(splay_tree_key) superset,
|
||||
(splay_tree_value) superset_entry);
|
||||
|
||||
}
|
||||
|
||||
subset_entry = get_alias_set_entry (subset);
|
||||
if (subset_entry)
|
||||
/* There is an entry for the subset. Enter all of its children
|
||||
(if they are not already present) as children of the SUPERSET. */
|
||||
splay_tree_foreach (subset_entry->children,
|
||||
&insert_subset_children,
|
||||
superset_entry->children);
|
||||
|
||||
/* Enter the SUBSET itself as a child of the SUPERSET. */
|
||||
splay_tree_insert (superset_entry->children,
|
||||
(splay_tree_key) subset,
|
||||
/*value=*/0);
|
||||
}
|
||||
|
||||
/* Inside SRC, the source of a SET, find a base address. */
|
||||
|
||||
static rtx
|
||||
@ -1063,6 +1255,8 @@ init_alias_once ()
|
||||
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
|
||||
&& HARD_REGNO_MODE_OK (i, Pmode))
|
||||
SET_HARD_REG_BIT (argument_registers, i);
|
||||
|
||||
alias_sets = splay_tree_new (&alias_set_compare, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -478,8 +478,8 @@ gen_type (ret_val, t, style)
|
||||
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)))
|
||||
with a type qualifier. */
|
||||
if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
|
||||
data_type = concat ("unsigned ", data_type);
|
||||
break;
|
||||
|
||||
@ -503,6 +503,8 @@ gen_type (ret_val, t, style)
|
||||
ret_val = concat ("const ", ret_val);
|
||||
if (TYPE_VOLATILE (t))
|
||||
ret_val = concat ("volatile ", ret_val);
|
||||
if (TYPE_RESTRICT (t))
|
||||
ret_val = concat ("restrict ", ret_val);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
133
gcc/c-common.c
133
gcc/c-common.c
@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "toplev.h"
|
||||
#include "output.h"
|
||||
#include "c-pragma.h"
|
||||
#include "rtl.h"
|
||||
|
||||
#if USE_CPPLIB
|
||||
#include "cpplib.h"
|
||||
@ -66,6 +67,7 @@ static void init_attributes PROTO((void));
|
||||
static void record_function_format PROTO((tree, tree, enum format_type,
|
||||
int, int));
|
||||
static void record_international_format PROTO((tree, tree, int));
|
||||
static tree c_find_base_decl PROTO((tree));
|
||||
|
||||
/* Keep a stack of if statements. We record the number of compound
|
||||
statements seen up to the if keyword, as well as the line number
|
||||
@ -2995,15 +2997,126 @@ get_directive_line (finput)
|
||||
down to the element type of an array. */
|
||||
|
||||
tree
|
||||
c_build_type_variant (type, constp, volatilep)
|
||||
c_build_qualified_type (type, type_quals)
|
||||
tree type;
|
||||
int constp, volatilep;
|
||||
int type_quals;
|
||||
{
|
||||
/* A restrict-qualified pointer type must be a pointer to object or
|
||||
incomplete type. Note that the use of POINTER_TYPE_P also allows
|
||||
REFERENCE_TYPEs, which is appropriate for C++. Unfortunately,
|
||||
the C++ front-end also use POINTER_TYPE for pointer-to-member
|
||||
values, so even though it should be illegal to use `restrict'
|
||||
with such an entity we don't flag that here. Thus, special case
|
||||
code for that case is required in the C++ front-end. */
|
||||
if ((type_quals & TYPE_QUAL_RESTRICT)
|
||||
&& (!POINTER_TYPE_P (type)
|
||||
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
|
||||
{
|
||||
error ("invalid use of `restrict'");
|
||||
type_quals &= ~TYPE_QUAL_RESTRICT;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
return build_array_type (c_build_type_variant (TREE_TYPE (type),
|
||||
constp, volatilep),
|
||||
return build_array_type (c_build_qualified_type (TREE_TYPE (type),
|
||||
type_quals),
|
||||
TYPE_DOMAIN (type));
|
||||
return build_type_variant (type, constp, volatilep);
|
||||
return build_qualified_type (type, type_quals);
|
||||
}
|
||||
|
||||
/* Apply the TYPE_QUALS to the new DECL. */
|
||||
|
||||
void
|
||||
c_apply_type_quals_to_decl (type_quals, decl)
|
||||
int type_quals;
|
||||
tree decl;
|
||||
{
|
||||
if (type_quals & TYPE_QUAL_CONST)
|
||||
TREE_READONLY (decl) = 1;
|
||||
if (type_quals & TYPE_QUAL_VOLATILE)
|
||||
{
|
||||
TREE_SIDE_EFFECTS (decl) = 1;
|
||||
TREE_THIS_VOLATILE (decl) = 1;
|
||||
}
|
||||
if ((type_quals & TYPE_QUAL_RESTRICT) && flag_strict_aliasing)
|
||||
{
|
||||
/* No two restricted pointers can point at the same thing.
|
||||
However, a restricted pointer can point at the same thing as
|
||||
an unrestricted pointer, if that unrestricted pointer is
|
||||
based on the restricted pointer. So, we make the alias set
|
||||
for the restricted pointer a subset of the alias set for the
|
||||
type pointed to by the type of the decl. */
|
||||
|
||||
int pointed_to_alias_set
|
||||
= get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
|
||||
|
||||
if (!pointed_to_alias_set)
|
||||
/* It's not legal to make a subset of alias set zero. */
|
||||
;
|
||||
else
|
||||
{
|
||||
DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
|
||||
record_alias_subset (pointed_to_alias_set,
|
||||
DECL_POINTER_ALIAS_SET (decl));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* T is an expression with pointer type. Find the DECL on which this
|
||||
expression is based. (For example, in `a[i]' this would be `a'.)
|
||||
If there is no such DECL, or a unique decl cannot be determined,
|
||||
NULL_TREE is retured. */
|
||||
|
||||
static tree
|
||||
c_find_base_decl (t)
|
||||
tree t;
|
||||
{
|
||||
int i;
|
||||
tree decl;
|
||||
|
||||
if (t == NULL_TREE || t == error_mark_node)
|
||||
return NULL_TREE;
|
||||
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (t)))
|
||||
return NULL_TREE;
|
||||
|
||||
decl = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (t) == FIELD_DECL
|
||||
|| TREE_CODE (t) == PARM_DECL
|
||||
|| TREE_CODE (t) == VAR_DECL)
|
||||
/* Aha, we found a pointer-typed declaration. */
|
||||
return t;
|
||||
|
||||
/* It would be nice to deal with COMPONENT_REFs here. If we could
|
||||
tell that `a' and `b' were the same, then `a->f' and `b->f' are
|
||||
also the same. */
|
||||
|
||||
/* Handle general expressions. */
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (t)))
|
||||
{
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
for (i = tree_code_length [(int) TREE_CODE (t)]; --i >= 0;)
|
||||
{
|
||||
tree d = c_find_base_decl (TREE_OPERAND (t, i));
|
||||
if (d)
|
||||
{
|
||||
if (!decl)
|
||||
decl = d;
|
||||
else if (d && d != decl)
|
||||
/* Two different declarations. That's confusing; let's
|
||||
just assume we don't know what's going on. */
|
||||
decl = NULL_TREE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
/* Return the typed-based alias set for T, which may be an expression
|
||||
@ -3044,6 +3157,16 @@ c_get_alias_set (t)
|
||||
says that such accesses have implementation-defined behavior. */
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (t) == INDIRECT_REF)
|
||||
{
|
||||
/* Check for accesses through restrict-qualified pointers. */
|
||||
tree decl = c_find_base_decl (TREE_OPERAND (t, 0));
|
||||
|
||||
if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
|
||||
/* We use the alias set indicated in the declaration. */
|
||||
return DECL_POINTER_ALIAS_SET (decl);
|
||||
}
|
||||
|
||||
/* From here on, only the type matters. */
|
||||
|
||||
if (TYPE_ALIAS_SET_KNOWN_P (type))
|
||||
|
140
gcc/c-decl.c
140
gcc/c-decl.c
@ -468,6 +468,10 @@ int flag_no_nonansi_builtin;
|
||||
|
||||
int flag_traditional;
|
||||
|
||||
/* Nonzero means use the ISO C9x dialect of C. */
|
||||
|
||||
int flag_isoc9x = 0;
|
||||
|
||||
/* Nonzero means that we have builtin functions, and main is an int */
|
||||
|
||||
int flag_hosted = 1;
|
||||
@ -648,6 +652,8 @@ c_decode_option (argc, argv)
|
||||
flag_traditional = 0;
|
||||
flag_writable_strings = 0;
|
||||
}
|
||||
else if (!strcmp (p, "-flang-isoc9x"))
|
||||
flag_isoc9x = 1;
|
||||
else if (!strcmp (p, "-fdollars-in-identifiers"))
|
||||
dollars_in_ident = 1;
|
||||
else if (!strcmp (p, "-fno-dollars-in-identifiers"))
|
||||
@ -4322,7 +4328,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
tree type = NULL_TREE;
|
||||
int longlong = 0;
|
||||
int constp;
|
||||
int restrictp;
|
||||
int volatilep;
|
||||
int type_quals = TYPE_UNQUALIFIED;
|
||||
int inlinep;
|
||||
int explicit_int = 0;
|
||||
int explicit_char = 0;
|
||||
@ -4632,19 +4640,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
type = build_complex_type (type);
|
||||
}
|
||||
|
||||
/* Set CONSTP if this declaration is `const', whether by
|
||||
explicit specification or via a typedef.
|
||||
Likewise for VOLATILEP. */
|
||||
|
||||
/* Figure out the type qualifiers for the declaration. There are
|
||||
two ways a declaration can become qualified. One is something
|
||||
like `const int i' where the `const' is explicit. Another is
|
||||
something like `typedef const int CI; CI i' where the type of the
|
||||
declaration contains the `const'. */
|
||||
constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
|
||||
restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
|
||||
volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
|
||||
inlinep = !! (specbits & (1 << (int) RID_INLINE));
|
||||
if (constp > 1)
|
||||
pedwarn ("duplicate `const'");
|
||||
if (restrictp > 1)
|
||||
pedwarn ("duplicate `restrict'");
|
||||
if (volatilep > 1)
|
||||
pedwarn ("duplicate `volatile'");
|
||||
if (! flag_gen_aux_info && (TYPE_READONLY (type) || TYPE_VOLATILE (type)))
|
||||
if (! flag_gen_aux_info && (TYPE_QUALS (type)))
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
|
||||
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
|
||||
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
|
||||
|
||||
/* Warn if two storage classes are given. Default to `auto'. */
|
||||
|
||||
@ -4878,13 +4893,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
is set correctly. */
|
||||
|
||||
type = build_array_type (type, itype);
|
||||
if (constp || volatilep)
|
||||
type = c_build_type_variant (type, constp, volatilep);
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
|
||||
#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;
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
#endif
|
||||
|
||||
if (size_varies)
|
||||
@ -4949,12 +4963,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
flag_traditional
|
||||
? NULL_TREE : arg_types);
|
||||
#endif
|
||||
/* ANSI seems to say that `const int foo ();'
|
||||
does not make the function foo const. */
|
||||
if (constp || volatilep)
|
||||
type = c_build_type_variant (type, constp, volatilep);
|
||||
constp = 0;
|
||||
volatilep = 0;
|
||||
/* Type qualifiers before the return type of the function
|
||||
qualify the return type, not the function type. */
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
|
||||
type = build_function_type (type, arg_types);
|
||||
declarator = TREE_OPERAND (declarator, 0);
|
||||
@ -4978,12 +4991,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
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;
|
||||
&& type_quals)
|
||||
pedwarn ("ANSI C forbids qualified function types");
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
size_varies = 0;
|
||||
|
||||
type = build_pointer_type (type);
|
||||
@ -4995,13 +5007,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
{
|
||||
register tree typemodlist;
|
||||
int erred = 0;
|
||||
|
||||
constp = 0;
|
||||
volatilep = 0;
|
||||
restrictp = 0;
|
||||
for (typemodlist = TREE_TYPE (declarator); typemodlist;
|
||||
typemodlist = TREE_CHAIN (typemodlist))
|
||||
{
|
||||
if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST])
|
||||
tree qualifier = TREE_VALUE (typemodlist);
|
||||
|
||||
if (qualifier == ridpointers[(int) RID_CONST])
|
||||
constp++;
|
||||
else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE])
|
||||
else if (qualifier == ridpointers[(int) RID_VOLATILE])
|
||||
volatilep++;
|
||||
else if (qualifier == ridpointers[(int) RID_RESTRICT])
|
||||
restrictp++;
|
||||
else if (!erred)
|
||||
{
|
||||
erred = 1;
|
||||
@ -5012,6 +5032,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
pedwarn ("duplicate `const'");
|
||||
if (volatilep > 1)
|
||||
pedwarn ("duplicate `volatile'");
|
||||
if (restrictp > 1)
|
||||
pedwarn ("duplicate `restrict'");
|
||||
|
||||
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
|
||||
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
|
||||
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
|
||||
}
|
||||
|
||||
declarator = TREE_OPERAND (declarator, 0);
|
||||
@ -5038,10 +5064,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
/* 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);
|
||||
&& type_quals)
|
||||
pedwarn ("ANSI C forbids qualified function types");
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
decl = build_decl (TYPE_DECL, declarator, type);
|
||||
if ((specbits & (1 << (int) RID_SIGNED))
|
||||
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
|
||||
@ -5073,10 +5099,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
/* Note that the grammar rejects storage classes
|
||||
in typenames, fields or parameters */
|
||||
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
|
||||
&& (constp || volatilep))
|
||||
&& type_quals)
|
||||
pedwarn ("ANSI C forbids const or volatile function types");
|
||||
if (constp || volatilep)
|
||||
type = c_build_type_variant (type, constp, volatilep);
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
pop_obstacks ();
|
||||
return type;
|
||||
}
|
||||
@ -5116,20 +5142,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
{
|
||||
/* Transfer const-ness of array into that of type pointed to. */
|
||||
type = TREE_TYPE (type);
|
||||
if (constp || volatilep)
|
||||
type = c_build_type_variant (type, constp, volatilep);
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
type = build_pointer_type (type);
|
||||
volatilep = constp = 0;
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
size_varies = 0;
|
||||
}
|
||||
else if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
{
|
||||
if (pedantic && (constp || volatilep))
|
||||
pedwarn ("ANSI C forbids const or volatile function types");
|
||||
if (constp || volatilep)
|
||||
type = c_build_type_variant (type, constp, volatilep);
|
||||
if (pedantic && type_quals)
|
||||
pedwarn ("ANSI C forbids qualified function types");
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
type = build_pointer_type (type);
|
||||
volatilep = constp = 0;
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
}
|
||||
|
||||
decl = build_decl (PARM_DECL, declarator, type);
|
||||
@ -5177,13 +5203,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
type = error_mark_node;
|
||||
}
|
||||
/* Move type qualifiers down to element of an array. */
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep))
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
|
||||
{
|
||||
type = build_array_type (c_build_type_variant (TREE_TYPE (type),
|
||||
constp, volatilep),
|
||||
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
|
||||
type_quals),
|
||||
TYPE_DOMAIN (type));
|
||||
#if 0 /* Leave the field const or volatile as well. */
|
||||
constp = volatilep = 0;
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
#endif
|
||||
}
|
||||
decl = build_decl (FIELD_DECL, declarator, type);
|
||||
@ -5222,18 +5248,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
decl = build_decl (FUNCTION_DECL, declarator, type);
|
||||
decl = build_decl_attribute_variant (decl, decl_machine_attr);
|
||||
|
||||
if (pedantic && (constp || volatilep)
|
||||
&& ! DECL_IN_SYSTEM_HEADER (decl))
|
||||
pedwarn ("ANSI C forbids const or volatile functions");
|
||||
if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
|
||||
pedwarn ("ANSI C forbids qualified function types");
|
||||
|
||||
if (pedantic
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
|
||||
&& (TYPE_READONLY (TREE_TYPE (TREE_TYPE (decl)))
|
||||
|| TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (decl))))
|
||||
&& TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
|
||||
&& ! DECL_IN_SYSTEM_HEADER (decl))
|
||||
pedwarn ("ANSI C forbids const or volatile void function return type");
|
||||
pedwarn ("ANSI C forbids qualified void function return type");
|
||||
|
||||
if (volatilep
|
||||
/* GNU C interprets a `volatile void' return type to indicate
|
||||
that the function does not return. */
|
||||
if ((type_quals & TYPE_QUAL_VOLATILE)
|
||||
&& TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
|
||||
warning ("`noreturn' function returns non-void value");
|
||||
|
||||
@ -5263,13 +5289,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
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))
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
|
||||
{
|
||||
type = build_array_type (c_build_type_variant (TREE_TYPE (type),
|
||||
constp, volatilep),
|
||||
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
|
||||
type_quals),
|
||||
TYPE_DOMAIN (type));
|
||||
#if 0 /* Leave the variable const or volatile as well. */
|
||||
constp = volatilep = 0;
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5316,14 +5342,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
DECL_REGISTER (decl) = 1;
|
||||
|
||||
/* Record constancy and volatility. */
|
||||
c_apply_type_quals_to_decl (type_quals, decl);
|
||||
|
||||
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. */
|
||||
|
248
gcc/c-gperf.h
248
gcc/c-gperf.h
@ -1,14 +1,14 @@
|
||||
/* KR-C code produced by gperf version 2.7.1 (19981006 egcs) */
|
||||
/* Command-line: gperf -L KR-C -F , 0, 0 -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ /hurl/puke/law/egcs/egcs/gcc/c-parse.gperf */
|
||||
/* Command-line: gperf -L KR-C -F , 0, 0 -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ ../../gcc/c-parse.gperf */
|
||||
/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
|
||||
struct resword { char *name; short token; enum rid rid; };
|
||||
|
||||
#define TOTAL_KEYWORDS 80
|
||||
#define TOTAL_KEYWORDS 83
|
||||
#define MIN_WORD_LENGTH 2
|
||||
#define MAX_WORD_LENGTH 20
|
||||
#define MIN_HASH_VALUE 10
|
||||
#define MAX_HASH_VALUE 162
|
||||
/* maximum key range = 153, duplicates = 0 */
|
||||
#define MIN_HASH_VALUE 8
|
||||
#define MAX_HASH_VALUE 141
|
||||
/* maximum key range = 134, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
@ -20,32 +20,32 @@ hash (str, len)
|
||||
{
|
||||
static unsigned char asso_values[] =
|
||||
{
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 8, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 1, 163, 24, 8, 61,
|
||||
37, 6, 47, 49, 2, 5, 163, 3, 51, 30,
|
||||
58, 91, 35, 163, 33, 13, 1, 18, 49, 2,
|
||||
2, 5, 3, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
||||
163, 163, 163, 163, 163, 163
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 35, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 1, 142, 90, 1, 28,
|
||||
40, 6, 1, 24, 3, 13, 142, 36, 60, 14,
|
||||
49, 3, 6, 142, 19, 8, 1, 50, 33, 11,
|
||||
2, 23, 4, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||
142, 142, 142, 142, 142, 142
|
||||
};
|
||||
register int hval = len;
|
||||
|
||||
@ -64,120 +64,112 @@ hash (str, len)
|
||||
|
||||
static struct resword wordlist[] =
|
||||
{
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"out", TYPE_QUAL, RID_OUT},
|
||||
{"", 0, 0},
|
||||
{"float", TYPESPEC, RID_FLOAT},
|
||||
{"__typeof", TYPEOF, NORID},
|
||||
{"", 0, 0},
|
||||
{"int", TYPESPEC, RID_INT},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"__typeof__", TYPEOF, NORID},
|
||||
{"", 0, 0},
|
||||
{"typeof", TYPEOF, NORID},
|
||||
{"typedef", SCSPEC, RID_TYPEDEF},
|
||||
{"if", IF, NORID},
|
||||
{"short", TYPESPEC, RID_SHORT},
|
||||
{"int", TYPESPEC, RID_INT},
|
||||
{"sizeof", SIZEOF, NORID},
|
||||
{"__signed__", TYPESPEC, RID_SIGNED},
|
||||
{"__extension__", EXTENSION, NORID},
|
||||
{"inout", TYPE_QUAL, RID_INOUT},
|
||||
{"__imag__", IMAGPART, NORID},
|
||||
{"", 0, 0},
|
||||
{"else", ELSE, NORID},
|
||||
{"__inline__", SCSPEC, RID_INLINE},
|
||||
{"while", WHILE, NORID},
|
||||
{"byref", TYPE_QUAL, RID_BYREF},
|
||||
{"__iterator__", SCSPEC, RID_ITERATOR},
|
||||
{"__inline", SCSPEC, RID_INLINE},
|
||||
{"__extension__", EXTENSION, NORID},
|
||||
{"break", BREAK, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"__signed__", TYPESPEC, RID_SIGNED},
|
||||
{"switch", SWITCH, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"else", ELSE, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"@defs", DEFS, NORID},
|
||||
{"__asm__", ASM_KEYWORD, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"__alignof__", ALIGNOF, NORID},
|
||||
{"", 0, 0},
|
||||
{"__attribute__", ATTRIBUTE, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"__attribute", ATTRIBUTE, NORID},
|
||||
{"__real__", REALPART, NORID},
|
||||
{"id", OBJECTNAME, RID_ID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"__iterator", SCSPEC, RID_ITERATOR},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"switch", SWITCH, NORID},
|
||||
{"__restrict", TYPE_QUAL, RID_RESTRICT},
|
||||
{"goto", GOTO, NORID},
|
||||
{"__restrict__", TYPE_QUAL, RID_RESTRICT},
|
||||
{"struct", STRUCT, NORID},
|
||||
{"if", IF, NORID},
|
||||
{"@private", PRIVATE, NORID},
|
||||
{"@selector", SELECTOR, NORID},
|
||||
{"__typeof", TYPEOF, NORID},
|
||||
{"enum", ENUM, NORID},
|
||||
{"__signed", TYPESPEC, RID_SIGNED},
|
||||
{"__asm", ASM_KEYWORD, NORID},
|
||||
{"__imag", IMAGPART, NORID},
|
||||
{"__label__", LABEL, NORID},
|
||||
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
|
||||
{"", 0, 0},
|
||||
{"in", TYPE_QUAL, RID_IN},
|
||||
{"__volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"double", TYPESPEC, RID_DOUBLE},
|
||||
{"inline", SCSPEC, RID_INLINE},
|
||||
{"sizeof", SIZEOF, NORID},
|
||||
{"while", WHILE, NORID},
|
||||
{"restrict", TYPE_QUAL, RID_RESTRICT},
|
||||
{"__const", TYPE_QUAL, RID_CONST},
|
||||
{"extern", SCSPEC, RID_EXTERN},
|
||||
{"oneway", TYPE_QUAL, RID_ONEWAY},
|
||||
{"__const__", TYPE_QUAL, RID_CONST},
|
||||
{"__complex", TYPESPEC, RID_COMPLEX},
|
||||
{"__complex__", TYPESPEC, RID_COMPLEX},
|
||||
{"", 0, 0},
|
||||
{"unsigned", TYPESPEC, RID_UNSIGNED},
|
||||
{"", 0, 0},
|
||||
{"@class", CLASS, NORID},
|
||||
{"@encode", ENCODE, NORID},
|
||||
{"bycopy", TYPE_QUAL, RID_BYCOPY},
|
||||
{"__alignof", ALIGNOF, NORID},
|
||||
{"@interface", INTERFACE, NORID},
|
||||
{"", 0, 0},
|
||||
{"case", CASE, NORID},
|
||||
{"", 0, 0},
|
||||
{"union", UNION, NORID},
|
||||
{"asm", ASM_KEYWORD, NORID},
|
||||
{"@protected", PROTECTED, NORID},
|
||||
{"typeof", TYPEOF, NORID},
|
||||
{"typedef", SCSPEC, RID_TYPEDEF},
|
||||
{"__real", REALPART, NORID},
|
||||
{"default", DEFAULT, NORID},
|
||||
{"byref", TYPE_QUAL, RID_BYREF},
|
||||
{"@public", PUBLIC, NORID},
|
||||
{"void", TYPESPEC, RID_VOID},
|
||||
{"out", TYPE_QUAL, RID_OUT},
|
||||
{"", 0, 0},
|
||||
{"return", RETURN, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"@protocol", PROTOCOL, NORID},
|
||||
{"inout", TYPE_QUAL, RID_INOUT},
|
||||
{"", 0, 0},
|
||||
{"static", SCSPEC, RID_STATIC},
|
||||
{"signed", TYPESPEC, RID_SIGNED},
|
||||
{"", 0, 0},
|
||||
{"@end", END, NORID},
|
||||
{"oneway", TYPE_QUAL, RID_ONEWAY},
|
||||
{"", 0, 0},
|
||||
{"short", TYPESPEC, RID_SHORT},
|
||||
{"@implementation", IMPLEMENTATION, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"", 0, 0},
|
||||
{"for", FOR, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"auto", SCSPEC, RID_AUTO},
|
||||
{"", 0, 0},
|
||||
{"char", TYPESPEC, RID_CHAR},
|
||||
{"register", SCSPEC, RID_REGISTER},
|
||||
{"", 0, 0},
|
||||
{"const", TYPE_QUAL, RID_CONST},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"__iterator", SCSPEC, RID_ITERATOR},
|
||||
{"__imag", IMAGPART, NORID},
|
||||
{"do", DO, NORID},
|
||||
{"case", CASE, NORID},
|
||||
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
|
||||
{"break", BREAK, NORID},
|
||||
{"default", DEFAULT, NORID},
|
||||
{"__volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"@defs", DEFS, NORID},
|
||||
{"id", OBJECTNAME, RID_ID},
|
||||
{"", 0, 0},
|
||||
{"__signed", TYPESPEC, RID_SIGNED},
|
||||
{"bycopy", TYPE_QUAL, RID_BYCOPY},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"extern", SCSPEC, RID_EXTERN},
|
||||
{"", 0, 0},
|
||||
{"in", TYPE_QUAL, RID_IN},
|
||||
{"", 0, 0},
|
||||
{"@compatibility_alias", ALIAS, NORID},
|
||||
{"continue", CONTINUE, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"", 0, 0},
|
||||
{"float", TYPESPEC, RID_FLOAT},
|
||||
{"goto", GOTO, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"long", TYPESPEC, RID_LONG}
|
||||
{"@private", PRIVATE, NORID},
|
||||
{"@selector", SELECTOR, NORID},
|
||||
{"register", SCSPEC, RID_REGISTER},
|
||||
{"__label__", LABEL, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"enum", ENUM, NORID},
|
||||
{"return", RETURN, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"signed", TYPESPEC, RID_SIGNED},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"const", TYPE_QUAL, RID_CONST},
|
||||
{"", 0, 0},
|
||||
{"inline", SCSPEC, RID_INLINE},
|
||||
{"__real", REALPART, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"void", TYPESPEC, RID_VOID},
|
||||
{"continue", CONTINUE, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"@encode", ENCODE, NORID},
|
||||
{"auto", SCSPEC, RID_AUTO},
|
||||
{"__asm__", ASM_KEYWORD, NORID},
|
||||
{"@interface", INTERFACE, NORID},
|
||||
{"__alignof", ALIGNOF, NORID},
|
||||
{"double", TYPESPEC, RID_DOUBLE},
|
||||
{"__alignof__", ALIGNOF, NORID},
|
||||
{"@protected", PROTECTED, NORID},
|
||||
{"__attribute__", ATTRIBUTE, NORID},
|
||||
{"unsigned", TYPESPEC, RID_UNSIGNED},
|
||||
{"volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"__attribute", ATTRIBUTE, NORID},
|
||||
{"@class", CLASS, NORID},
|
||||
{"__asm", ASM_KEYWORD, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"@implementation", IMPLEMENTATION, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"union", UNION, NORID},
|
||||
{"", 0, 0}, {"", 0, 0},
|
||||
{"@public", PUBLIC, NORID},
|
||||
{"asm", ASM_KEYWORD, NORID},
|
||||
{"", 0, 0},
|
||||
{"@protocol", PROTOCOL, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"@end", END, NORID},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"static", SCSPEC, RID_STATIC},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"long", TYPESPEC, RID_LONG},
|
||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
||||
{"char", TYPESPEC, RID_CHAR}
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -245,6 +245,7 @@ init_lex ()
|
||||
ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
|
||||
ridpointers[(int) RID_INLINE] = get_identifier ("inline");
|
||||
ridpointers[(int) RID_CONST] = get_identifier ("const");
|
||||
ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict");
|
||||
ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
|
||||
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
|
||||
ridpointers[(int) RID_STATIC] = get_identifier ("static");
|
||||
@ -274,6 +275,7 @@ init_lex ()
|
||||
if (flag_traditional)
|
||||
{
|
||||
UNSET_RESERVED_WORD ("const");
|
||||
UNSET_RESERVED_WORD ("restrict");
|
||||
UNSET_RESERVED_WORD ("volatile");
|
||||
UNSET_RESERVED_WORD ("typeof");
|
||||
UNSET_RESERVED_WORD ("signed");
|
||||
@ -281,6 +283,9 @@ init_lex ()
|
||||
UNSET_RESERVED_WORD ("iterator");
|
||||
UNSET_RESERVED_WORD ("complex");
|
||||
}
|
||||
else if (!flag_isoc9x)
|
||||
UNSET_RESERVED_WORD ("restrict");
|
||||
|
||||
if (flag_no_asm)
|
||||
{
|
||||
UNSET_RESERVED_WORD ("asm");
|
||||
|
@ -40,6 +40,7 @@ enum rid
|
||||
RID_TYPEDEF,
|
||||
RID_SIGNED,
|
||||
RID_CONST,
|
||||
RID_RESTRICT,
|
||||
RID_VOLATILE,
|
||||
RID_INLINE,
|
||||
RID_NOALIAS,
|
||||
|
@ -1164,7 +1164,7 @@ static const short yycheck[] = { 38,
|
||||
52
|
||||
};
|
||||
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
|
||||
#line 3 "/usr/cygnus/progressive-98r1/share/bison.simple"
|
||||
#line 3 "/usr/lib/bison.simple"
|
||||
|
||||
/* Skeleton output parser for bison,
|
||||
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
|
||||
@ -1357,7 +1357,7 @@ __yy_memcpy (char *to, char *from, int count)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#line 196 "/usr/cygnus/progressive-98r1/share/bison.simple"
|
||||
#line 196 "/usr/lib/bison.simple"
|
||||
|
||||
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
|
||||
into yyparse. The argument should have type void *.
|
||||
@ -3676,7 +3676,7 @@ case 401:
|
||||
break;}
|
||||
}
|
||||
/* the action file gets copied in in place of this dollarsign */
|
||||
#line 498 "/usr/cygnus/progressive-98r1/share/bison.simple"
|
||||
#line 498 "/usr/lib/bison.simple"
|
||||
|
||||
yyvsp -= yylen;
|
||||
yyssp -= yylen;
|
||||
|
@ -35,6 +35,8 @@ __iterator__, SCSPEC, RID_ITERATOR
|
||||
__label__, LABEL, NORID
|
||||
__real, REALPART, NORID
|
||||
__real__, REALPART, NORID
|
||||
__restrict, TYPE_QUAL, RID_RESTRICT
|
||||
__restrict__, TYPE_QUAL, RID_RESTRICT
|
||||
__signed, TYPESPEC, RID_SIGNED
|
||||
__signed__, TYPESPEC, RID_SIGNED
|
||||
__typeof, TYPEOF, NORID
|
||||
@ -69,6 +71,7 @@ long, TYPESPEC, RID_LONG
|
||||
oneway, TYPE_QUAL, RID_ONEWAY
|
||||
out, TYPE_QUAL, RID_OUT
|
||||
register, SCSPEC, RID_REGISTER
|
||||
restrict, TYPE_QUAL, RID_RESTRICT
|
||||
return, RETURN, NORID
|
||||
short, TYPESPEC, RID_SHORT
|
||||
signed, TYPESPEC, RID_SIGNED
|
||||
|
@ -116,7 +116,7 @@ end ifc
|
||||
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||
%token TYPESPEC
|
||||
|
||||
/* Reserved words that qualify type: "const" or "volatile".
|
||||
/* Reserved words that qualify type: "const", "volatile", or "restrict".
|
||||
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||
%token TYPE_QUAL
|
||||
|
||||
|
@ -104,7 +104,7 @@ char *language_string = "GNU C";
|
||||
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||
%token TYPESPEC
|
||||
|
||||
/* Reserved words that qualify type: "const" or "volatile".
|
||||
/* Reserved words that qualify type: "const", "volatile", or "restrict".
|
||||
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||
%token TYPE_QUAL
|
||||
|
||||
|
27
gcc/c-tree.h
27
gcc/c-tree.h
@ -80,6 +80,22 @@ extern int pedantic;
|
||||
nonzero if the definition of the type has already started. */
|
||||
#define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type)
|
||||
|
||||
/* C types are partitioned into three subsets: object, function, and
|
||||
incomplete types. */
|
||||
#define C_TYPE_OBJECT_P(type) \
|
||||
(TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type))
|
||||
|
||||
#define C_TYPE_FUNCTION_P(type) \
|
||||
(TREE_CODE (type) == FUNCTION_TYPE)
|
||||
|
||||
#define C_TYPE_INCOMPLETE_P(type) \
|
||||
(TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type) == 0)
|
||||
|
||||
/* For convenience we define a single macro to identify the class of
|
||||
object or incomplete types. */
|
||||
#define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \
|
||||
(!C_TYPE_FUNCTION_P (type))
|
||||
|
||||
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
|
||||
struct lang_type
|
||||
{
|
||||
@ -165,6 +181,7 @@ extern void decl_attributes PROTO((tree, tree, tree));
|
||||
extern void init_function_format_info PROTO((void));
|
||||
extern void check_function_format PROTO((tree, tree, tree));
|
||||
extern int c_get_alias_set PROTO((tree));
|
||||
extern void c_apply_type_quals_to_decl PROTO((int, tree));
|
||||
/* Print an error message for invalid operands to arith operation CODE.
|
||||
NOP_EXPR is used as a special case (see truthvalue_conversion). */
|
||||
extern void binary_op_error PROTO((enum tree_code));
|
||||
@ -267,7 +284,11 @@ extern tree build_enumerator PROTO((tree, tree));
|
||||
/* Declare a predefined function. Return the declaration. */
|
||||
extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *));
|
||||
/* Add qualifiers to a type, in the fashion for C. */
|
||||
extern tree c_build_type_variant PROTO((tree, int, int));
|
||||
extern tree c_build_qualified_type PROTO((tree, int));
|
||||
#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \
|
||||
c_build_qualified_type (TYPE, \
|
||||
((CONST_P) ? TYPE_QUAL_CONST : 0) | \
|
||||
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
|
||||
extern int c_decode_option PROTO((int, char **));
|
||||
extern void c_mark_varargs PROTO((void));
|
||||
extern tree check_identifier PROTO((tree, tree));
|
||||
@ -497,6 +518,10 @@ extern int warn_main;
|
||||
|
||||
extern int flag_traditional;
|
||||
|
||||
/* Nonzero means use the ISO C9x dialect of C. */
|
||||
|
||||
extern int flag_isoc9x;
|
||||
|
||||
/* Nonzero means to allow single precision math even if we're generally
|
||||
being traditional. */
|
||||
extern int flag_allow_single_precision;
|
||||
|
101
gcc/c-typeck.c
101
gcc/c-typeck.c
@ -163,9 +163,7 @@ 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 c_build_qualified_type (type, TYPE_QUALS (like));
|
||||
}
|
||||
|
||||
/* Return the common type of two types.
|
||||
@ -283,14 +281,14 @@ common_type (t1, t2)
|
||||
But ANSI C specifies doing this with the qualifiers.
|
||||
So I turned it on again. */
|
||||
{
|
||||
tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
|
||||
TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
|
||||
int constp
|
||||
= TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
|
||||
int volatilep
|
||||
= TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
|
||||
t1 = build_pointer_type (c_build_type_variant (target, constp,
|
||||
volatilep));
|
||||
tree pointed_to_1 = TREE_TYPE (t1);
|
||||
tree pointed_to_2 = TREE_TYPE (t2);
|
||||
tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
|
||||
TYPE_MAIN_VARIANT (pointed_to_2));
|
||||
t1 = build_pointer_type (c_build_qualified_type
|
||||
(target,
|
||||
TYPE_QUALS (pointed_to_1) |
|
||||
TYPE_QUALS (pointed_to_2)));
|
||||
return build_type_attribute_variant (t1, attributes);
|
||||
}
|
||||
#if 0
|
||||
@ -447,9 +445,7 @@ comptypes (type1, type2)
|
||||
|
||||
/* Qualifiers must match. */
|
||||
|
||||
if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
|
||||
return 0;
|
||||
if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
|
||||
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
|
||||
return 0;
|
||||
|
||||
/* Allow for two different type nodes which have essentially the same
|
||||
@ -1084,11 +1080,12 @@ default_conversion (exp)
|
||||
volatilep = TREE_THIS_VOLATILE (exp);
|
||||
}
|
||||
|
||||
if (TYPE_READONLY (type) || TYPE_VOLATILE (type)
|
||||
|| constp || volatilep)
|
||||
restype = c_build_type_variant (restype,
|
||||
TYPE_READONLY (type) || constp,
|
||||
TYPE_VOLATILE (type) || volatilep);
|
||||
if (TYPE_QUALS (type) || constp || volatilep)
|
||||
restype
|
||||
= c_build_qualified_type (restype,
|
||||
TYPE_QUALS (type)
|
||||
| (constp * TYPE_QUAL_CONST)
|
||||
| (volatilep * TYPE_QUAL_VOLATILE));
|
||||
|
||||
if (TREE_CODE (exp) == INDIRECT_REF)
|
||||
return convert (TYPE_POINTER_TO (restype),
|
||||
@ -3080,8 +3077,10 @@ build_unary_op (code, xarg, noconvert)
|
||||
|
||||
/* 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 the lvalue is const or volatile, merge that into the type
|
||||
to which the address will point. Note that you can't get a
|
||||
restricted pointer by taking the address of something, so we
|
||||
only have to deal with `const' and `volatile' here. */
|
||||
if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
|
||||
|| TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
|
||||
{
|
||||
@ -3779,11 +3778,11 @@ build_c_cast (type, expr)
|
||||
in_type = TREE_TYPE (in_type);
|
||||
while (TREE_CODE (in_otype) == POINTER_TYPE)
|
||||
in_otype = TREE_TYPE (in_otype);
|
||||
|
||||
if (TYPE_VOLATILE (in_otype) && ! TYPE_VOLATILE (in_type))
|
||||
pedwarn ("cast discards `volatile' from pointer target type");
|
||||
if (TYPE_READONLY (in_otype) && ! TYPE_READONLY (in_type))
|
||||
pedwarn ("cast discards `const' from pointer target type");
|
||||
|
||||
if (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type))
|
||||
/* There are qualifiers present in IN_OTYPE that are not
|
||||
present in IN_TYPE. */
|
||||
pedwarn ("cast discards qualifiers from pointer target type");
|
||||
}
|
||||
|
||||
/* Warn about possible alignment problems. */
|
||||
@ -4114,12 +4113,13 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|
||||
|| comp_target_types (memb_type, rhstype))
|
||||
{
|
||||
/* If this type won't generate any warnings, use it. */
|
||||
if ((TREE_CODE (ttr) == FUNCTION_TYPE
|
||||
&& TREE_CODE (ttl) == FUNCTION_TYPE)
|
||||
? ((! TYPE_READONLY (ttl) | TYPE_READONLY (ttr))
|
||||
& (! TYPE_VOLATILE (ttl) | TYPE_VOLATILE (ttr)))
|
||||
: ((TYPE_READONLY (ttl) | ! TYPE_READONLY (ttr))
|
||||
& (TYPE_VOLATILE (ttl) | ! TYPE_VOLATILE (ttr))))
|
||||
if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
|
||||
|| ((TREE_CODE (ttr) == FUNCTION_TYPE
|
||||
&& TREE_CODE (ttl) == FUNCTION_TYPE)
|
||||
? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
|
||||
== TYPE_QUALS (ttr))
|
||||
: (TYPE_QUALS (ttl) | TYPE_QUALS (ttr)
|
||||
== TYPE_QUALS (ttl))))
|
||||
break;
|
||||
|
||||
/* Keep looking for a better type, but remember this one. */
|
||||
@ -4157,26 +4157,15 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|
||||
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 (! 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",
|
||||
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
|
||||
warn_for_assignment ("%s makes qualified function pointer from unqualified",
|
||||
get_spelling (errtype), funname,
|
||||
parmnum);
|
||||
}
|
||||
else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
|
||||
warn_for_assignment ("%s discards qualifiers from pointer target type",
|
||||
get_spelling (errtype), funname,
|
||||
parmnum);
|
||||
}
|
||||
|
||||
if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
|
||||
@ -4217,11 +4206,8 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|
||||
else if (TREE_CODE (ttr) != FUNCTION_TYPE
|
||||
&& TREE_CODE (ttl) != FUNCTION_TYPE)
|
||||
{
|
||||
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
|
||||
warn_for_assignment ("%s discards `const' from pointer target type",
|
||||
get_spelling (errtype), funname, parmnum);
|
||||
else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
|
||||
warn_for_assignment ("%s discards `volatile' from pointer target type",
|
||||
if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
|
||||
warn_for_assignment ("%s discards qualifiers from pointer target type",
|
||||
get_spelling (errtype), funname, parmnum);
|
||||
/* If this is not a case of ignoring a mismatch in signedness,
|
||||
no warning. */
|
||||
@ -4241,11 +4227,8 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|
||||
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",
|
||||
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
|
||||
warn_for_assignment ("%s makes qualified function pointer from unqualified",
|
||||
get_spelling (errtype), funname, parmnum);
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ in the following sections.
|
||||
@item C Language Options
|
||||
@xref{C Dialect Options,,Options Controlling C Dialect}.
|
||||
@smallexample
|
||||
-ansi -fallow-single-precision -fcond-mismatch -fno-asm
|
||||
-ansi -flang-isoc9x -fallow-single-precision -fcond-mismatch -fno-asm
|
||||
-fno-builtin -ffreestanding -fhosted -fsigned-bitfields -fsigned-char
|
||||
-funsigned-bitfields -funsigned-char -fwritable-strings
|
||||
-traditional -traditional-cpp -trigraphs
|
||||
@ -644,6 +644,15 @@ programs that might use these names for other things.
|
||||
The functions @code{alloca}, @code{abort}, @code{exit}, and
|
||||
@code{_exit} are not builtin functions when @samp{-ansi} is used.
|
||||
|
||||
@item -flang-isoc9x
|
||||
Enable support for features found in the C9X standard. In particular,
|
||||
enable support for the C9X @code{restrict} keyword.
|
||||
|
||||
Even when this option is not specified, you can still use some C9X
|
||||
features in so far as they do not conflict with previous C standards.
|
||||
For example, you may use @code{__restrict__} even when -flang-isoc9x
|
||||
is not specified.
|
||||
|
||||
@item -fno-asm
|
||||
Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
|
||||
keyword, so that code can use these words as identifiers. You can use
|
||||
|
@ -404,6 +404,8 @@ print_node (file, prefix, node, indent)
|
||||
fprintf (file, " built-in code %d", DECL_FUNCTION_CODE (node));
|
||||
if (TREE_CODE (node) == FIELD_DECL)
|
||||
print_node (file, "bitpos", DECL_FIELD_BITPOS (node), indent + 4);
|
||||
if (DECL_POINTER_ALIAS_SET_KNOWN_P (node))
|
||||
fprintf (file, " alias set %d", DECL_POINTER_ALIAS_SET (node));
|
||||
print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
|
||||
print_node_brief (file, "machine_attributes", DECL_MACHINE_ATTRIBUTES (node), indent + 4);
|
||||
print_node_brief (file, "abstract_origin",
|
||||
|
@ -1505,5 +1505,6 @@ extern void init_alias_analysis PROTO ((void));
|
||||
extern void end_alias_analysis PROTO ((void));
|
||||
|
||||
extern void record_base_value PROTO ((int, rtx, int));
|
||||
extern void record_alias_subset PROTO ((int, int));
|
||||
|
||||
#endif /* _RTL_H */
|
||||
|
@ -949,6 +949,7 @@ documented_lang_options[] =
|
||||
{ "-traditional", "Attempt to support traditional K&R style C"},
|
||||
{ "-fnotraditional", "" },
|
||||
{ "-fno-traditional", "" },
|
||||
{ "-flang-isoc9x", "Enable C9X features"},
|
||||
|
||||
{ "-fasm", "" },
|
||||
{ "-fno-asm", "Do not recognise the 'asm' keyword" },
|
||||
|
58
gcc/tree.c
58
gcc/tree.c
@ -264,6 +264,8 @@ int (*lang_get_alias_set) PROTO((tree));
|
||||
codes are made. */
|
||||
#define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
|
||||
|
||||
static void set_type_quals PROTO((tree, int));
|
||||
|
||||
extern char *mode_name[];
|
||||
|
||||
void gcc_obstack_init ();
|
||||
@ -1100,6 +1102,9 @@ make_node (code)
|
||||
DECL_SOURCE_LINE (t) = lineno;
|
||||
DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";
|
||||
DECL_UID (t) = next_decl_uid++;
|
||||
/* Note that we have not yet computed the alias set for this
|
||||
declaration. */
|
||||
DECL_POINTER_ALIAS_SET (t) = -1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
@ -3294,7 +3299,7 @@ build_type_attribute_variant (ttype, attribute)
|
||||
/* Create a new main variant of TYPE. */
|
||||
TYPE_MAIN_VARIANT (ntype) = ntype;
|
||||
TYPE_NEXT_VARIANT (ntype) = 0;
|
||||
TYPE_READONLY (ntype) = TYPE_VOLATILE (ntype) = 0;
|
||||
set_type_quals (ntype, TYPE_UNQUALIFIED);
|
||||
|
||||
hashcode = TYPE_HASH (TREE_CODE (ntype))
|
||||
+ TYPE_HASH (TREE_TYPE (ntype))
|
||||
@ -3319,8 +3324,7 @@ build_type_attribute_variant (ttype, attribute)
|
||||
}
|
||||
|
||||
ntype = type_hash_canon (hashcode, ntype);
|
||||
ttype = build_type_variant (ntype, TYPE_READONLY (ttype),
|
||||
TYPE_VOLATILE (ttype));
|
||||
ttype = build_qualified_type (ntype, TYPE_QUALS (ttype));
|
||||
}
|
||||
|
||||
return ttype;
|
||||
@ -3576,45 +3580,44 @@ merge_machine_decl_attributes (olddecl, newdecl)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return a type like TYPE except that its TYPE_READONLY is CONSTP
|
||||
and its TYPE_VOLATILE is VOLATILEP.
|
||||
/* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
|
||||
of the various TYPE_QUAL values. */
|
||||
|
||||
Such variant types already made are recorded so that duplicates
|
||||
are not made.
|
||||
static void
|
||||
set_type_quals (type, type_quals)
|
||||
tree type;
|
||||
int type_quals;
|
||||
{
|
||||
TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
|
||||
TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
|
||||
TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
|
||||
}
|
||||
|
||||
A variant types should never be used as the type of an expression.
|
||||
Always copy the variant information into the TREE_READONLY
|
||||
and TREE_THIS_VOLATILE of the expression, and then give the expression
|
||||
as its type the "main variant", the variant whose TYPE_READONLY
|
||||
and TYPE_VOLATILE are zero. Use TYPE_MAIN_VARIANT to find the
|
||||
main variant. */
|
||||
/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for
|
||||
the same kind of data as TYPE describes. Variants point to the
|
||||
"main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT,
|
||||
and it points to a chain of other variants so that duplicate
|
||||
variants are never made. Only main variants should ever appear as
|
||||
types of expressions. */
|
||||
|
||||
tree
|
||||
build_type_variant (type, constp, volatilep)
|
||||
build_qualified_type (type, type_quals)
|
||||
tree type;
|
||||
int constp, volatilep;
|
||||
int type_quals;
|
||||
{
|
||||
register tree t;
|
||||
|
||||
/* Treat any nonzero argument as 1. */
|
||||
constp = !!constp;
|
||||
volatilep = !!volatilep;
|
||||
|
||||
|
||||
/* Search the chain of variants to see if there is already one there just
|
||||
like the one we need to have. If so, use that existing one. We must
|
||||
preserve the TYPE_NAME, since there is code that depends on this. */
|
||||
|
||||
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
|
||||
if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t)
|
||||
&& TYPE_NAME (t) == TYPE_NAME (type))
|
||||
if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type))
|
||||
return t;
|
||||
|
||||
/* We need a new one. */
|
||||
|
||||
t = build_type_copy (type);
|
||||
TYPE_READONLY (t) = constp;
|
||||
TYPE_VOLATILE (t) = volatilep;
|
||||
|
||||
set_type_quals (t, type_quals);
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -4422,8 +4425,7 @@ build_complex_type (component_type)
|
||||
t = make_node (COMPLEX_TYPE);
|
||||
|
||||
TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
|
||||
TYPE_VOLATILE (t) = TYPE_VOLATILE (component_type);
|
||||
TYPE_READONLY (t) = TYPE_READONLY (component_type);
|
||||
set_type_quals (t, TYPE_QUALS (component_type));
|
||||
|
||||
/* If we already have such a type, use the old one and free this one. */
|
||||
hashcode = TYPE_HASH (component_type);
|
||||
|
58
gcc/tree.h
58
gcc/tree.h
@ -830,6 +830,25 @@ struct tree_block
|
||||
/* Means this type is const-qualified. */
|
||||
#define TYPE_READONLY(NODE) ((NODE)->common.readonly_flag)
|
||||
|
||||
/* If nonzero, this type is `restrict'-qualified, in the C sense of
|
||||
the term. */
|
||||
#define TYPE_RESTRICT(NODE) (TYPE_CHECK (NODE)->type.restrict_flag)
|
||||
|
||||
/* There is a TYPE_QUAL value for each type qualifier. They can be
|
||||
combined by bitwise-or to form the complete set of qualifiers for a
|
||||
type. */
|
||||
|
||||
#define TYPE_UNQUALIFIED 0x0
|
||||
#define TYPE_QUAL_CONST 0x1
|
||||
#define TYPE_QUAL_VOLATILE 0x2
|
||||
#define TYPE_QUAL_RESTRICT 0x4
|
||||
|
||||
/* The set of type qualifiers for this type. */
|
||||
#define TYPE_QUALS(NODE) \
|
||||
((TYPE_READONLY(NODE) * TYPE_QUAL_CONST) | \
|
||||
(TYPE_VOLATILE(NODE) * TYPE_QUAL_VOLATILE) | \
|
||||
(TYPE_RESTRICT(NODE) * TYPE_QUAL_RESTRICT))
|
||||
|
||||
/* These flags are available for each language front end to use internally. */
|
||||
#define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type.lang_flag_0)
|
||||
#define TYPE_LANG_FLAG_1(NODE) (TYPE_CHECK (NODE)->type.lang_flag_1)
|
||||
@ -881,6 +900,8 @@ struct tree_type
|
||||
unsigned needs_constructing_flag : 1;
|
||||
unsigned transparent_union_flag : 1;
|
||||
unsigned packed_flag : 1;
|
||||
unsigned restrict_flag : 1;
|
||||
|
||||
unsigned lang_flag_0 : 1;
|
||||
unsigned lang_flag_1 : 1;
|
||||
unsigned lang_flag_2 : 1;
|
||||
@ -888,7 +909,7 @@ struct tree_type
|
||||
unsigned lang_flag_4 : 1;
|
||||
unsigned lang_flag_5 : 1;
|
||||
unsigned lang_flag_6 : 1;
|
||||
/* room for 4 more bits */
|
||||
/* room for 3 more bits */
|
||||
|
||||
unsigned int align;
|
||||
union tree_node *pointer_to;
|
||||
@ -1244,6 +1265,16 @@ struct tree_type
|
||||
an address constant. */
|
||||
#define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
|
||||
|
||||
/* Used to indicate an alias set for the memory pointed to by this
|
||||
particular FIELD_DECL, PARM_DECL, or VAR_DECL, which must have
|
||||
pointer (or reference) type. */
|
||||
#define DECL_POINTER_ALIAS_SET(NODE) \
|
||||
(DECL_CHECK (NODE)->decl.pointer_alias_set)
|
||||
|
||||
/* Nonzero if an alias set has been assigned to this declaration. */
|
||||
#define DECL_POINTER_ALIAS_SET_KNOWN_P(NODE) \
|
||||
(DECL_POINTER_ALIAS_SET (NODE) != - 1)
|
||||
|
||||
struct tree_decl
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
@ -1316,6 +1347,7 @@ struct tree_decl
|
||||
HOST_WIDE_INT i;
|
||||
} saved_insns;
|
||||
union tree_node *vindex;
|
||||
int pointer_alias_set;
|
||||
/* Points to a structure whose details depend on the language in use. */
|
||||
struct lang_decl *lang_specific;
|
||||
};
|
||||
@ -1502,14 +1534,24 @@ extern tree lookup_attribute PROTO((char *, tree));
|
||||
|
||||
extern tree merge_attributes PROTO((tree, tree));
|
||||
|
||||
/* Given a type node TYPE, and CONSTP and VOLATILEP, return a type
|
||||
for the same kind of data as TYPE describes.
|
||||
Variants point to the "main variant" (which has neither CONST nor VOLATILE)
|
||||
via TYPE_MAIN_VARIANT, and it points to a chain of other variants
|
||||
so that duplicate variants are never made.
|
||||
Only main variants should ever appear as types of expressions. */
|
||||
/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for
|
||||
the same kind of data as TYPE describes. Variants point to the
|
||||
"main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT,
|
||||
and it points to a chain of other variants so that duplicate
|
||||
variants are never made. Only main variants should ever appear as
|
||||
types of expressions. */
|
||||
|
||||
extern tree build_type_variant PROTO((tree, int, int));
|
||||
extern tree build_qualified_type PROTO((tree, int));
|
||||
|
||||
/* Like build_qualified_type, but only deals with the `const' and
|
||||
`volatile' qualifiers. This interface is retained for backwards
|
||||
compatiblity with the various front-ends; new code should use
|
||||
build_qualified_type instead. */
|
||||
|
||||
#define build_type_variant(TYPE, CONST_P, VOLATILE_P) \
|
||||
build_qualified_type (TYPE, \
|
||||
((CONST_P) ? TYPE_QUAL_CONST : 0) \
|
||||
| ((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
|
||||
|
||||
/* Make a copy of a type node. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user