mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-27 21:15:20 +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>
|
Wed Oct 21 09:15:06 1998 Nick Clifton <nickc@cygnus.com>
|
||||||
|
|
||||||
* config/arm/arm.h (TARGET_SWITCHES): Document arm specific
|
* 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-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 \
|
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 \
|
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
|
# 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
|
# 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
|
$(LN_S) $(srcdir)/../libiberty/vfprintf.c vfprintf.c
|
||||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) 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
|
underscore.c: s-under ; @true
|
||||||
|
|
||||||
s-under: $(GCC_PASSES)
|
s-under: $(GCC_PASSES)
|
||||||
@ -1337,7 +1344,7 @@ s-under: $(GCC_PASSES)
|
|||||||
# A file used by all variants of C.
|
# 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 \
|
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.
|
# Language-independent files.
|
||||||
|
|
||||||
|
232
gcc/alias.c
232
gcc/alias.c
@ -28,6 +28,49 @@ Boston, MA 02111-1307, USA. */
|
|||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "toplev.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 rtx canon_rtx PROTO((rtx));
|
||||||
static int rtx_equal_for_memref_p PROTO((rtx, 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,
|
static int base_alias_check PROTO((rtx, rtx, enum machine_mode,
|
||||||
enum machine_mode));
|
enum machine_mode));
|
||||||
static rtx find_base_value PROTO((rtx));
|
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. */
|
/* Set up all info needed to perform alias analysis on memory references. */
|
||||||
|
|
||||||
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
|
#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
|
/* Returns nonzero if MEM1 and MEM2 do not alias because they are in
|
||||||
different alias sets. We ignore alias sets in functions making use
|
different alias sets. We ignore alias sets in functions making use
|
||||||
of variable arguments because the va_arg macros on some systems are
|
of variable arguments because the va_arg macros on some systems are
|
||||||
not legal ANSI C. */
|
not legal ANSI C. */
|
||||||
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
|
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
|
||||||
(CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2), \
|
mems_in_disjoint_alias_sets_p (MEM1, MEM2)
|
||||||
MEM_ALIAS_SET (MEM1) && MEM_ALIAS_SET (MEM2) \
|
|
||||||
&& MEM_ALIAS_SET (MEM1) != MEM_ALIAS_SET (MEM2) \
|
|
||||||
&& !current_function_stdarg && !current_function_varargs)
|
|
||||||
|
|
||||||
/* Cap the number of passes we make over the insns propagating alias
|
/* Cap the number of passes we make over the insns propagating alias
|
||||||
information through set chains.
|
information through set chains.
|
||||||
@ -131,6 +162,167 @@ char *reg_known_equiv_p;
|
|||||||
|
|
||||||
static int copying_arguments;
|
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. */
|
/* Inside SRC, the source of a SET, find a base address. */
|
||||||
|
|
||||||
static rtx
|
static rtx
|
||||||
@ -1063,6 +1255,8 @@ init_alias_once ()
|
|||||||
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
|
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
|
||||||
&& HARD_REGNO_MODE_OK (i, Pmode))
|
&& HARD_REGNO_MODE_OK (i, Pmode))
|
||||||
SET_HARD_REG_BIT (argument_registers, i);
|
SET_HARD_REG_BIT (argument_registers, i);
|
||||||
|
|
||||||
|
alias_sets = splay_tree_new (&alias_set_compare, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -478,8 +478,8 @@ gen_type (ret_val, t, style)
|
|||||||
case INTEGER_TYPE:
|
case INTEGER_TYPE:
|
||||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||||
/* Normally, `unsigned' is part of the deal. Not so if it comes
|
/* Normally, `unsigned' is part of the deal. Not so if it comes
|
||||||
with `const' or `volatile'. */
|
with a type qualifier. */
|
||||||
if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t)))
|
if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
|
||||||
data_type = concat ("unsigned ", data_type);
|
data_type = concat ("unsigned ", data_type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -503,6 +503,8 @@ gen_type (ret_val, t, style)
|
|||||||
ret_val = concat ("const ", ret_val);
|
ret_val = concat ("const ", ret_val);
|
||||||
if (TYPE_VOLATILE (t))
|
if (TYPE_VOLATILE (t))
|
||||||
ret_val = concat ("volatile ", ret_val);
|
ret_val = concat ("volatile ", ret_val);
|
||||||
|
if (TYPE_RESTRICT (t))
|
||||||
|
ret_val = concat ("restrict ", ret_val);
|
||||||
return 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 "toplev.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "c-pragma.h"
|
#include "c-pragma.h"
|
||||||
|
#include "rtl.h"
|
||||||
|
|
||||||
#if USE_CPPLIB
|
#if USE_CPPLIB
|
||||||
#include "cpplib.h"
|
#include "cpplib.h"
|
||||||
@ -66,6 +67,7 @@ static void init_attributes PROTO((void));
|
|||||||
static void record_function_format PROTO((tree, tree, enum format_type,
|
static void record_function_format PROTO((tree, tree, enum format_type,
|
||||||
int, int));
|
int, int));
|
||||||
static void record_international_format PROTO((tree, tree, 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
|
/* 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
|
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. */
|
down to the element type of an array. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
c_build_type_variant (type, constp, volatilep)
|
c_build_qualified_type (type, type_quals)
|
||||||
tree type;
|
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)
|
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||||
return build_array_type (c_build_type_variant (TREE_TYPE (type),
|
return build_array_type (c_build_qualified_type (TREE_TYPE (type),
|
||||||
constp, volatilep),
|
type_quals),
|
||||||
TYPE_DOMAIN (type));
|
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
|
/* 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. */
|
says that such accesses have implementation-defined behavior. */
|
||||||
return 0;
|
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. */
|
/* From here on, only the type matters. */
|
||||||
|
|
||||||
if (TYPE_ALIAS_SET_KNOWN_P (type))
|
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;
|
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 */
|
/* Nonzero means that we have builtin functions, and main is an int */
|
||||||
|
|
||||||
int flag_hosted = 1;
|
int flag_hosted = 1;
|
||||||
@ -648,6 +652,8 @@ c_decode_option (argc, argv)
|
|||||||
flag_traditional = 0;
|
flag_traditional = 0;
|
||||||
flag_writable_strings = 0;
|
flag_writable_strings = 0;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (p, "-flang-isoc9x"))
|
||||||
|
flag_isoc9x = 1;
|
||||||
else if (!strcmp (p, "-fdollars-in-identifiers"))
|
else if (!strcmp (p, "-fdollars-in-identifiers"))
|
||||||
dollars_in_ident = 1;
|
dollars_in_ident = 1;
|
||||||
else if (!strcmp (p, "-fno-dollars-in-identifiers"))
|
else if (!strcmp (p, "-fno-dollars-in-identifiers"))
|
||||||
@ -4322,7 +4328,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
tree type = NULL_TREE;
|
tree type = NULL_TREE;
|
||||||
int longlong = 0;
|
int longlong = 0;
|
||||||
int constp;
|
int constp;
|
||||||
|
int restrictp;
|
||||||
int volatilep;
|
int volatilep;
|
||||||
|
int type_quals = TYPE_UNQUALIFIED;
|
||||||
int inlinep;
|
int inlinep;
|
||||||
int explicit_int = 0;
|
int explicit_int = 0;
|
||||||
int explicit_char = 0;
|
int explicit_char = 0;
|
||||||
@ -4632,19 +4640,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
type = build_complex_type (type);
|
type = build_complex_type (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set CONSTP if this declaration is `const', whether by
|
/* Figure out the type qualifiers for the declaration. There are
|
||||||
explicit specification or via a typedef.
|
two ways a declaration can become qualified. One is something
|
||||||
Likewise for VOLATILEP. */
|
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);
|
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);
|
volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
|
||||||
inlinep = !! (specbits & (1 << (int) RID_INLINE));
|
inlinep = !! (specbits & (1 << (int) RID_INLINE));
|
||||||
if (constp > 1)
|
if (constp > 1)
|
||||||
pedwarn ("duplicate `const'");
|
pedwarn ("duplicate `const'");
|
||||||
|
if (restrictp > 1)
|
||||||
|
pedwarn ("duplicate `restrict'");
|
||||||
if (volatilep > 1)
|
if (volatilep > 1)
|
||||||
pedwarn ("duplicate `volatile'");
|
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 = 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'. */
|
/* Warn if two storage classes are given. Default to `auto'. */
|
||||||
|
|
||||||
@ -4878,13 +4893,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
is set correctly. */
|
is set correctly. */
|
||||||
|
|
||||||
type = build_array_type (type, itype);
|
type = build_array_type (type, itype);
|
||||||
if (constp || volatilep)
|
if (type_quals)
|
||||||
type = c_build_type_variant (type, constp, volatilep);
|
type = c_build_qualified_type (type, type_quals);
|
||||||
|
|
||||||
#if 0 /* don't clear these; leave them set so that the array type
|
#if 0 /* don't clear these; leave them set so that the array type
|
||||||
or the variable is itself const or volatile. */
|
or the variable is itself const or volatile. */
|
||||||
constp = 0;
|
type_quals = TYPE_UNQUALIFIED;
|
||||||
volatilep = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (size_varies)
|
if (size_varies)
|
||||||
@ -4949,12 +4963,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
flag_traditional
|
flag_traditional
|
||||||
? NULL_TREE : arg_types);
|
? NULL_TREE : arg_types);
|
||||||
#endif
|
#endif
|
||||||
/* ANSI seems to say that `const int foo ();'
|
/* Type qualifiers before the return type of the function
|
||||||
does not make the function foo const. */
|
qualify the return type, not the function type. */
|
||||||
if (constp || volatilep)
|
if (type_quals)
|
||||||
type = c_build_type_variant (type, constp, volatilep);
|
type = c_build_qualified_type (type, type_quals);
|
||||||
constp = 0;
|
type_quals = TYPE_UNQUALIFIED;
|
||||||
volatilep = 0;
|
|
||||||
|
|
||||||
type = build_function_type (type, arg_types);
|
type = build_function_type (type, arg_types);
|
||||||
declarator = TREE_OPERAND (declarator, 0);
|
declarator = TREE_OPERAND (declarator, 0);
|
||||||
@ -4978,12 +4991,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
for the pointer. */
|
for the pointer. */
|
||||||
|
|
||||||
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
|
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
|
||||||
&& (constp || volatilep))
|
&& type_quals)
|
||||||
pedwarn ("ANSI C forbids const or volatile function types");
|
pedwarn ("ANSI C forbids qualified function types");
|
||||||
if (constp || volatilep)
|
if (type_quals)
|
||||||
type = c_build_type_variant (type, constp, volatilep);
|
type = c_build_qualified_type (type, type_quals);
|
||||||
constp = 0;
|
type_quals = TYPE_UNQUALIFIED;
|
||||||
volatilep = 0;
|
|
||||||
size_varies = 0;
|
size_varies = 0;
|
||||||
|
|
||||||
type = build_pointer_type (type);
|
type = build_pointer_type (type);
|
||||||
@ -4995,13 +5007,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
{
|
{
|
||||||
register tree typemodlist;
|
register tree typemodlist;
|
||||||
int erred = 0;
|
int erred = 0;
|
||||||
|
|
||||||
|
constp = 0;
|
||||||
|
volatilep = 0;
|
||||||
|
restrictp = 0;
|
||||||
for (typemodlist = TREE_TYPE (declarator); typemodlist;
|
for (typemodlist = TREE_TYPE (declarator); typemodlist;
|
||||||
typemodlist = TREE_CHAIN (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++;
|
constp++;
|
||||||
else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE])
|
else if (qualifier == ridpointers[(int) RID_VOLATILE])
|
||||||
volatilep++;
|
volatilep++;
|
||||||
|
else if (qualifier == ridpointers[(int) RID_RESTRICT])
|
||||||
|
restrictp++;
|
||||||
else if (!erred)
|
else if (!erred)
|
||||||
{
|
{
|
||||||
erred = 1;
|
erred = 1;
|
||||||
@ -5012,6 +5032,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
pedwarn ("duplicate `const'");
|
pedwarn ("duplicate `const'");
|
||||||
if (volatilep > 1)
|
if (volatilep > 1)
|
||||||
pedwarn ("duplicate `volatile'");
|
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);
|
declarator = TREE_OPERAND (declarator, 0);
|
||||||
@ -5038,10 +5064,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
/* Note that the grammar rejects storage classes
|
/* Note that the grammar rejects storage classes
|
||||||
in typenames, fields or parameters */
|
in typenames, fields or parameters */
|
||||||
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
|
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
|
||||||
&& (constp || volatilep))
|
&& type_quals)
|
||||||
pedwarn ("ANSI C forbids const or volatile function types");
|
pedwarn ("ANSI C forbids qualified function types");
|
||||||
if (constp || volatilep)
|
if (type_quals)
|
||||||
type = c_build_type_variant (type, constp, volatilep);
|
type = c_build_qualified_type (type, type_quals);
|
||||||
decl = build_decl (TYPE_DECL, declarator, type);
|
decl = build_decl (TYPE_DECL, declarator, type);
|
||||||
if ((specbits & (1 << (int) RID_SIGNED))
|
if ((specbits & (1 << (int) RID_SIGNED))
|
||||||
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
|
|| (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
|
/* Note that the grammar rejects storage classes
|
||||||
in typenames, fields or parameters */
|
in typenames, fields or parameters */
|
||||||
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
|
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
|
||||||
&& (constp || volatilep))
|
&& type_quals)
|
||||||
pedwarn ("ANSI C forbids const or volatile function types");
|
pedwarn ("ANSI C forbids const or volatile function types");
|
||||||
if (constp || volatilep)
|
if (type_quals)
|
||||||
type = c_build_type_variant (type, constp, volatilep);
|
type = c_build_qualified_type (type, type_quals);
|
||||||
pop_obstacks ();
|
pop_obstacks ();
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@ -5116,20 +5142,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
{
|
{
|
||||||
/* Transfer const-ness of array into that of type pointed to. */
|
/* Transfer const-ness of array into that of type pointed to. */
|
||||||
type = TREE_TYPE (type);
|
type = TREE_TYPE (type);
|
||||||
if (constp || volatilep)
|
if (type_quals)
|
||||||
type = c_build_type_variant (type, constp, volatilep);
|
type = c_build_qualified_type (type, type_quals);
|
||||||
type = build_pointer_type (type);
|
type = build_pointer_type (type);
|
||||||
volatilep = constp = 0;
|
type_quals = TYPE_UNQUALIFIED;
|
||||||
size_varies = 0;
|
size_varies = 0;
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (type) == FUNCTION_TYPE)
|
else if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||||
{
|
{
|
||||||
if (pedantic && (constp || volatilep))
|
if (pedantic && type_quals)
|
||||||
pedwarn ("ANSI C forbids const or volatile function types");
|
pedwarn ("ANSI C forbids qualified function types");
|
||||||
if (constp || volatilep)
|
if (type_quals)
|
||||||
type = c_build_type_variant (type, constp, volatilep);
|
type = c_build_qualified_type (type, type_quals);
|
||||||
type = build_pointer_type (type);
|
type = build_pointer_type (type);
|
||||||
volatilep = constp = 0;
|
type_quals = TYPE_UNQUALIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
decl = build_decl (PARM_DECL, declarator, type);
|
decl = build_decl (PARM_DECL, declarator, type);
|
||||||
@ -5177,13 +5203,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
type = error_mark_node;
|
type = error_mark_node;
|
||||||
}
|
}
|
||||||
/* Move type qualifiers down to element of an array. */
|
/* 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),
|
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
|
||||||
constp, volatilep),
|
type_quals),
|
||||||
TYPE_DOMAIN (type));
|
TYPE_DOMAIN (type));
|
||||||
#if 0 /* Leave the field const or volatile as well. */
|
#if 0 /* Leave the field const or volatile as well. */
|
||||||
constp = volatilep = 0;
|
type_quals = TYPE_UNQUALIFIED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
decl = build_decl (FIELD_DECL, declarator, type);
|
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 (FUNCTION_DECL, declarator, type);
|
||||||
decl = build_decl_attribute_variant (decl, decl_machine_attr);
|
decl = build_decl_attribute_variant (decl, decl_machine_attr);
|
||||||
|
|
||||||
if (pedantic && (constp || volatilep)
|
if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
|
||||||
&& ! DECL_IN_SYSTEM_HEADER (decl))
|
pedwarn ("ANSI C forbids qualified function types");
|
||||||
pedwarn ("ANSI C forbids const or volatile functions");
|
|
||||||
|
|
||||||
if (pedantic
|
if (pedantic
|
||||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
|
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
|
||||||
&& (TYPE_READONLY (TREE_TYPE (TREE_TYPE (decl)))
|
&& TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
|
||||||
|| TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (decl))))
|
|
||||||
&& ! DECL_IN_SYSTEM_HEADER (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)
|
&& TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
|
||||||
warning ("`noreturn' function returns non-void value");
|
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));
|
int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
|
||||||
|
|
||||||
/* Move type qualifiers down to element of an array. */
|
/* 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),
|
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
|
||||||
constp, volatilep),
|
type_quals),
|
||||||
TYPE_DOMAIN (type));
|
TYPE_DOMAIN (type));
|
||||||
#if 0 /* Leave the variable const or volatile as well. */
|
#if 0 /* Leave the variable const or volatile as well. */
|
||||||
constp = volatilep = 0;
|
type_quals = TYPE_UNQUALIFIED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5316,14 +5342,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||||||
DECL_REGISTER (decl) = 1;
|
DECL_REGISTER (decl) = 1;
|
||||||
|
|
||||||
/* Record constancy and volatility. */
|
/* 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.
|
/* If a type has volatile components, it should be stored in memory.
|
||||||
Otherwise, the fact that those components are volatile
|
Otherwise, the fact that those components are volatile
|
||||||
will be ignored, and would even crash the compiler. */
|
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) */
|
/* 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 */
|
/* 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; };
|
struct resword { char *name; short token; enum rid rid; };
|
||||||
|
|
||||||
#define TOTAL_KEYWORDS 80
|
#define TOTAL_KEYWORDS 83
|
||||||
#define MIN_WORD_LENGTH 2
|
#define MIN_WORD_LENGTH 2
|
||||||
#define MAX_WORD_LENGTH 20
|
#define MAX_WORD_LENGTH 20
|
||||||
#define MIN_HASH_VALUE 10
|
#define MIN_HASH_VALUE 8
|
||||||
#define MAX_HASH_VALUE 162
|
#define MAX_HASH_VALUE 141
|
||||||
/* maximum key range = 153, duplicates = 0 */
|
/* maximum key range = 134, duplicates = 0 */
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__inline
|
__inline
|
||||||
@ -20,32 +20,32 @@ hash (str, len)
|
|||||||
{
|
{
|
||||||
static unsigned char asso_values[] =
|
static unsigned char asso_values[] =
|
||||||
{
|
{
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 8, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 35, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 1, 163, 24, 8, 61,
|
142, 142, 142, 142, 142, 1, 142, 90, 1, 28,
|
||||||
37, 6, 47, 49, 2, 5, 163, 3, 51, 30,
|
40, 6, 1, 24, 3, 13, 142, 36, 60, 14,
|
||||||
58, 91, 35, 163, 33, 13, 1, 18, 49, 2,
|
49, 3, 6, 142, 19, 8, 1, 50, 33, 11,
|
||||||
2, 5, 3, 163, 163, 163, 163, 163, 163, 163,
|
2, 23, 4, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
|
142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
|
||||||
163, 163, 163, 163, 163, 163
|
142, 142, 142, 142, 142, 142
|
||||||
};
|
};
|
||||||
register int hval = len;
|
register int hval = len;
|
||||||
|
|
||||||
@ -64,120 +64,112 @@ hash (str, len)
|
|||||||
|
|
||||||
static struct resword wordlist[] =
|
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},
|
{"", 0, 0},
|
||||||
{"int", TYPESPEC, RID_INT},
|
|
||||||
{"", 0, 0}, {"", 0, 0},
|
|
||||||
{"__typeof__", TYPEOF, NORID},
|
{"__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},
|
{"__imag__", IMAGPART, NORID},
|
||||||
{"", 0, 0},
|
{"else", ELSE, NORID},
|
||||||
{"__inline__", SCSPEC, RID_INLINE},
|
{"__inline__", SCSPEC, RID_INLINE},
|
||||||
{"while", WHILE, NORID},
|
{"byref", TYPE_QUAL, RID_BYREF},
|
||||||
{"__iterator__", SCSPEC, RID_ITERATOR},
|
{"__iterator__", SCSPEC, RID_ITERATOR},
|
||||||
{"__inline", SCSPEC, RID_INLINE},
|
{"__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},
|
{"__real__", REALPART, NORID},
|
||||||
{"id", OBJECTNAME, RID_ID},
|
{"switch", SWITCH, NORID},
|
||||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
{"__restrict", TYPE_QUAL, RID_RESTRICT},
|
||||||
{"__iterator", SCSPEC, RID_ITERATOR},
|
{"goto", GOTO, NORID},
|
||||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
{"__restrict__", TYPE_QUAL, RID_RESTRICT},
|
||||||
{"struct", STRUCT, NORID},
|
{"struct", STRUCT, NORID},
|
||||||
{"if", IF, NORID},
|
{"while", WHILE, NORID},
|
||||||
{"@private", PRIVATE, NORID},
|
{"restrict", TYPE_QUAL, RID_RESTRICT},
|
||||||
{"@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},
|
|
||||||
{"__const", TYPE_QUAL, RID_CONST},
|
{"__const", TYPE_QUAL, RID_CONST},
|
||||||
{"extern", SCSPEC, RID_EXTERN},
|
{"oneway", TYPE_QUAL, RID_ONEWAY},
|
||||||
{"__const__", TYPE_QUAL, RID_CONST},
|
{"__const__", TYPE_QUAL, RID_CONST},
|
||||||
{"__complex", TYPESPEC, RID_COMPLEX},
|
{"__complex", TYPESPEC, RID_COMPLEX},
|
||||||
{"__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},
|
{"for", FOR, NORID},
|
||||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
{"__iterator", SCSPEC, RID_ITERATOR},
|
||||||
{"auto", SCSPEC, RID_AUTO},
|
{"__imag", IMAGPART, NORID},
|
||||||
{"", 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},
|
|
||||||
{"do", DO, 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},
|
{"", 0, 0},
|
||||||
{"@compatibility_alias", ALIAS, NORID},
|
{"@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},
|
{"", 0, 0},
|
||||||
{"float", TYPESPEC, RID_FLOAT},
|
{"@private", PRIVATE, NORID},
|
||||||
{"goto", GOTO, NORID},
|
{"@selector", SELECTOR, NORID},
|
||||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
{"register", SCSPEC, RID_REGISTER},
|
||||||
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
|
{"__label__", LABEL, NORID},
|
||||||
{"long", TYPESPEC, RID_LONG}
|
{"", 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__
|
#ifdef __GNUC__
|
||||||
|
@ -245,6 +245,7 @@ init_lex ()
|
|||||||
ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
|
ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
|
||||||
ridpointers[(int) RID_INLINE] = get_identifier ("inline");
|
ridpointers[(int) RID_INLINE] = get_identifier ("inline");
|
||||||
ridpointers[(int) RID_CONST] = get_identifier ("const");
|
ridpointers[(int) RID_CONST] = get_identifier ("const");
|
||||||
|
ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict");
|
||||||
ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
|
ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
|
||||||
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
|
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
|
||||||
ridpointers[(int) RID_STATIC] = get_identifier ("static");
|
ridpointers[(int) RID_STATIC] = get_identifier ("static");
|
||||||
@ -274,6 +275,7 @@ init_lex ()
|
|||||||
if (flag_traditional)
|
if (flag_traditional)
|
||||||
{
|
{
|
||||||
UNSET_RESERVED_WORD ("const");
|
UNSET_RESERVED_WORD ("const");
|
||||||
|
UNSET_RESERVED_WORD ("restrict");
|
||||||
UNSET_RESERVED_WORD ("volatile");
|
UNSET_RESERVED_WORD ("volatile");
|
||||||
UNSET_RESERVED_WORD ("typeof");
|
UNSET_RESERVED_WORD ("typeof");
|
||||||
UNSET_RESERVED_WORD ("signed");
|
UNSET_RESERVED_WORD ("signed");
|
||||||
@ -281,6 +283,9 @@ init_lex ()
|
|||||||
UNSET_RESERVED_WORD ("iterator");
|
UNSET_RESERVED_WORD ("iterator");
|
||||||
UNSET_RESERVED_WORD ("complex");
|
UNSET_RESERVED_WORD ("complex");
|
||||||
}
|
}
|
||||||
|
else if (!flag_isoc9x)
|
||||||
|
UNSET_RESERVED_WORD ("restrict");
|
||||||
|
|
||||||
if (flag_no_asm)
|
if (flag_no_asm)
|
||||||
{
|
{
|
||||||
UNSET_RESERVED_WORD ("asm");
|
UNSET_RESERVED_WORD ("asm");
|
||||||
|
@ -40,6 +40,7 @@ enum rid
|
|||||||
RID_TYPEDEF,
|
RID_TYPEDEF,
|
||||||
RID_SIGNED,
|
RID_SIGNED,
|
||||||
RID_CONST,
|
RID_CONST,
|
||||||
|
RID_RESTRICT,
|
||||||
RID_VOLATILE,
|
RID_VOLATILE,
|
||||||
RID_INLINE,
|
RID_INLINE,
|
||||||
RID_NOALIAS,
|
RID_NOALIAS,
|
||||||
|
@ -1164,7 +1164,7 @@ static const short yycheck[] = { 38,
|
|||||||
52
|
52
|
||||||
};
|
};
|
||||||
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
|
/* -*-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,
|
/* Skeleton output parser for bison,
|
||||||
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
|
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
|
||||||
@ -1357,7 +1357,7 @@ __yy_memcpy (char *to, char *from, int count)
|
|||||||
#endif
|
#endif
|
||||||
#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
|
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
|
||||||
into yyparse. The argument should have type void *.
|
into yyparse. The argument should have type void *.
|
||||||
@ -3676,7 +3676,7 @@ case 401:
|
|||||||
break;}
|
break;}
|
||||||
}
|
}
|
||||||
/* the action file gets copied in in place of this dollarsign */
|
/* 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;
|
yyvsp -= yylen;
|
||||||
yyssp -= yylen;
|
yyssp -= yylen;
|
||||||
|
@ -35,6 +35,8 @@ __iterator__, SCSPEC, RID_ITERATOR
|
|||||||
__label__, LABEL, NORID
|
__label__, LABEL, NORID
|
||||||
__real, REALPART, NORID
|
__real, REALPART, 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
|
||||||
__signed__, TYPESPEC, RID_SIGNED
|
__signed__, TYPESPEC, RID_SIGNED
|
||||||
__typeof, TYPEOF, NORID
|
__typeof, TYPEOF, NORID
|
||||||
@ -69,6 +71,7 @@ long, TYPESPEC, RID_LONG
|
|||||||
oneway, TYPE_QUAL, RID_ONEWAY
|
oneway, TYPE_QUAL, RID_ONEWAY
|
||||||
out, TYPE_QUAL, RID_OUT
|
out, TYPE_QUAL, RID_OUT
|
||||||
register, SCSPEC, RID_REGISTER
|
register, SCSPEC, RID_REGISTER
|
||||||
|
restrict, TYPE_QUAL, RID_RESTRICT
|
||||||
return, RETURN, NORID
|
return, RETURN, NORID
|
||||||
short, TYPESPEC, RID_SHORT
|
short, TYPESPEC, RID_SHORT
|
||||||
signed, TYPESPEC, RID_SIGNED
|
signed, TYPESPEC, RID_SIGNED
|
||||||
|
@ -116,7 +116,7 @@ end ifc
|
|||||||
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||||
%token TYPESPEC
|
%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. */
|
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||||
%token TYPE_QUAL
|
%token TYPE_QUAL
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ char *language_string = "GNU C";
|
|||||||
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||||
%token TYPESPEC
|
%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. */
|
yylval contains an IDENTIFIER_NODE which indicates which one. */
|
||||||
%token TYPE_QUAL
|
%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. */
|
nonzero if the definition of the type has already started. */
|
||||||
#define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type)
|
#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. */
|
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
|
||||||
struct lang_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 init_function_format_info PROTO((void));
|
||||||
extern void check_function_format PROTO((tree, tree, tree));
|
extern void check_function_format PROTO((tree, tree, tree));
|
||||||
extern int c_get_alias_set PROTO((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.
|
/* Print an error message for invalid operands to arith operation CODE.
|
||||||
NOP_EXPR is used as a special case (see truthvalue_conversion). */
|
NOP_EXPR is used as a special case (see truthvalue_conversion). */
|
||||||
extern void binary_op_error PROTO((enum tree_code));
|
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. */
|
/* Declare a predefined function. Return the declaration. */
|
||||||
extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *));
|
extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *));
|
||||||
/* Add qualifiers to a type, in the fashion for C. */
|
/* 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 int c_decode_option PROTO((int, char **));
|
||||||
extern void c_mark_varargs PROTO((void));
|
extern void c_mark_varargs PROTO((void));
|
||||||
extern tree check_identifier PROTO((tree, tree));
|
extern tree check_identifier PROTO((tree, tree));
|
||||||
@ -497,6 +518,10 @@ extern int warn_main;
|
|||||||
|
|
||||||
extern int flag_traditional;
|
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
|
/* Nonzero means to allow single precision math even if we're generally
|
||||||
being traditional. */
|
being traditional. */
|
||||||
extern int flag_allow_single_precision;
|
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)
|
qualify_type (type, like)
|
||||||
tree type, like;
|
tree type, like;
|
||||||
{
|
{
|
||||||
int constflag = TYPE_READONLY (type) || TYPE_READONLY (like);
|
return c_build_qualified_type (type, TYPE_QUALS (like));
|
||||||
int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like);
|
|
||||||
return c_build_type_variant (type, constflag, volflag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the common type of two types.
|
/* Return the common type of two types.
|
||||||
@ -283,14 +281,14 @@ common_type (t1, t2)
|
|||||||
But ANSI C specifies doing this with the qualifiers.
|
But ANSI C specifies doing this with the qualifiers.
|
||||||
So I turned it on again. */
|
So I turned it on again. */
|
||||||
{
|
{
|
||||||
tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
|
tree pointed_to_1 = TREE_TYPE (t1);
|
||||||
TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
|
tree pointed_to_2 = TREE_TYPE (t2);
|
||||||
int constp
|
tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
|
||||||
= TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
|
TYPE_MAIN_VARIANT (pointed_to_2));
|
||||||
int volatilep
|
t1 = build_pointer_type (c_build_qualified_type
|
||||||
= TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
|
(target,
|
||||||
t1 = build_pointer_type (c_build_type_variant (target, constp,
|
TYPE_QUALS (pointed_to_1) |
|
||||||
volatilep));
|
TYPE_QUALS (pointed_to_2)));
|
||||||
return build_type_attribute_variant (t1, attributes);
|
return build_type_attribute_variant (t1, attributes);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
@ -447,9 +445,7 @@ comptypes (type1, type2)
|
|||||||
|
|
||||||
/* Qualifiers must match. */
|
/* Qualifiers must match. */
|
||||||
|
|
||||||
if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
|
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
|
||||||
return 0;
|
|
||||||
if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Allow for two different type nodes which have essentially the same
|
/* Allow for two different type nodes which have essentially the same
|
||||||
@ -1084,11 +1080,12 @@ default_conversion (exp)
|
|||||||
volatilep = TREE_THIS_VOLATILE (exp);
|
volatilep = TREE_THIS_VOLATILE (exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TYPE_READONLY (type) || TYPE_VOLATILE (type)
|
if (TYPE_QUALS (type) || constp || volatilep)
|
||||||
|| constp || volatilep)
|
restype
|
||||||
restype = c_build_type_variant (restype,
|
= c_build_qualified_type (restype,
|
||||||
TYPE_READONLY (type) || constp,
|
TYPE_QUALS (type)
|
||||||
TYPE_VOLATILE (type) || volatilep);
|
| (constp * TYPE_QUAL_CONST)
|
||||||
|
| (volatilep * TYPE_QUAL_VOLATILE));
|
||||||
|
|
||||||
if (TREE_CODE (exp) == INDIRECT_REF)
|
if (TREE_CODE (exp) == INDIRECT_REF)
|
||||||
return convert (TYPE_POINTER_TO (restype),
|
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. */
|
/* Ordinary case; arg is a COMPONENT_REF or a decl. */
|
||||||
argtype = TREE_TYPE (arg);
|
argtype = TREE_TYPE (arg);
|
||||||
/* If the lvalue is const or volatile,
|
/* If the lvalue is const or volatile, merge that into the type
|
||||||
merge that into the type that the address will point to. */
|
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'
|
if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
|
||||||
|| TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
|
|| TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
|
||||||
{
|
{
|
||||||
@ -3779,11 +3778,11 @@ build_c_cast (type, expr)
|
|||||||
in_type = TREE_TYPE (in_type);
|
in_type = TREE_TYPE (in_type);
|
||||||
while (TREE_CODE (in_otype) == POINTER_TYPE)
|
while (TREE_CODE (in_otype) == POINTER_TYPE)
|
||||||
in_otype = TREE_TYPE (in_otype);
|
in_otype = TREE_TYPE (in_otype);
|
||||||
|
|
||||||
if (TYPE_VOLATILE (in_otype) && ! TYPE_VOLATILE (in_type))
|
if (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type))
|
||||||
pedwarn ("cast discards `volatile' from pointer target type");
|
/* There are qualifiers present in IN_OTYPE that are not
|
||||||
if (TYPE_READONLY (in_otype) && ! TYPE_READONLY (in_type))
|
present in IN_TYPE. */
|
||||||
pedwarn ("cast discards `const' from pointer target type");
|
pedwarn ("cast discards qualifiers from pointer target type");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Warn about possible alignment problems. */
|
/* Warn about possible alignment problems. */
|
||||||
@ -4114,12 +4113,13 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|
|||||||
|| comp_target_types (memb_type, rhstype))
|
|| comp_target_types (memb_type, rhstype))
|
||||||
{
|
{
|
||||||
/* If this type won't generate any warnings, use it. */
|
/* If this type won't generate any warnings, use it. */
|
||||||
if ((TREE_CODE (ttr) == FUNCTION_TYPE
|
if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
|
||||||
&& TREE_CODE (ttl) == FUNCTION_TYPE)
|
|| ((TREE_CODE (ttr) == FUNCTION_TYPE
|
||||||
? ((! TYPE_READONLY (ttl) | TYPE_READONLY (ttr))
|
&& TREE_CODE (ttl) == FUNCTION_TYPE)
|
||||||
& (! TYPE_VOLATILE (ttl) | TYPE_VOLATILE (ttr)))
|
? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
|
||||||
: ((TYPE_READONLY (ttl) | ! TYPE_READONLY (ttr))
|
== TYPE_QUALS (ttr))
|
||||||
& (TYPE_VOLATILE (ttl) | ! TYPE_VOLATILE (ttr))))
|
: (TYPE_QUALS (ttl) | TYPE_QUALS (ttr)
|
||||||
|
== TYPE_QUALS (ttl))))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Keep looking for a better type, but remember this one. */
|
/* 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
|
certain things, it is okay to use a const or volatile
|
||||||
function where an ordinary one is wanted, but not
|
function where an ordinary one is wanted, but not
|
||||||
vice-versa. */
|
vice-versa. */
|
||||||
if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
|
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
|
||||||
warn_for_assignment ("%s makes `const *' function pointer from non-const",
|
warn_for_assignment ("%s makes qualified function pointer from unqualified",
|
||||||
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",
|
|
||||||
get_spelling (errtype), funname,
|
get_spelling (errtype), funname,
|
||||||
parmnum);
|
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))
|
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
|
else if (TREE_CODE (ttr) != FUNCTION_TYPE
|
||||||
&& TREE_CODE (ttl) != FUNCTION_TYPE)
|
&& TREE_CODE (ttl) != FUNCTION_TYPE)
|
||||||
{
|
{
|
||||||
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
|
if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
|
||||||
warn_for_assignment ("%s discards `const' from pointer target type",
|
warn_for_assignment ("%s discards qualifiers from pointer target type",
|
||||||
get_spelling (errtype), funname, parmnum);
|
|
||||||
else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
|
|
||||||
warn_for_assignment ("%s discards `volatile' from pointer target type",
|
|
||||||
get_spelling (errtype), funname, parmnum);
|
get_spelling (errtype), funname, parmnum);
|
||||||
/* If this is not a case of ignoring a mismatch in signedness,
|
/* If this is not a case of ignoring a mismatch in signedness,
|
||||||
no warning. */
|
no warning. */
|
||||||
@ -4241,11 +4227,8 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|
|||||||
that say the function will not do certain things,
|
that say the function will not do certain things,
|
||||||
it is okay to use a const or volatile function
|
it is okay to use a const or volatile function
|
||||||
where an ordinary one is wanted, but not vice-versa. */
|
where an ordinary one is wanted, but not vice-versa. */
|
||||||
if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
|
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
|
||||||
warn_for_assignment ("%s makes `const *' function pointer from non-const",
|
warn_for_assignment ("%s makes qualified function pointer from unqualified",
|
||||||
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);
|
get_spelling (errtype), funname, parmnum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ in the following sections.
|
|||||||
@item C Language Options
|
@item C Language Options
|
||||||
@xref{C Dialect Options,,Options Controlling C Dialect}.
|
@xref{C Dialect Options,,Options Controlling C Dialect}.
|
||||||
@smallexample
|
@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
|
-fno-builtin -ffreestanding -fhosted -fsigned-bitfields -fsigned-char
|
||||||
-funsigned-bitfields -funsigned-char -fwritable-strings
|
-funsigned-bitfields -funsigned-char -fwritable-strings
|
||||||
-traditional -traditional-cpp -trigraphs
|
-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
|
The functions @code{alloca}, @code{abort}, @code{exit}, and
|
||||||
@code{_exit} are not builtin functions when @samp{-ansi} is used.
|
@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
|
@item -fno-asm
|
||||||
Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
|
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
|
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));
|
fprintf (file, " built-in code %d", DECL_FUNCTION_CODE (node));
|
||||||
if (TREE_CODE (node) == FIELD_DECL)
|
if (TREE_CODE (node) == FIELD_DECL)
|
||||||
print_node (file, "bitpos", DECL_FIELD_BITPOS (node), indent + 4);
|
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, "context", DECL_CONTEXT (node), indent + 4);
|
||||||
print_node_brief (file, "machine_attributes", DECL_MACHINE_ATTRIBUTES (node), indent + 4);
|
print_node_brief (file, "machine_attributes", DECL_MACHINE_ATTRIBUTES (node), indent + 4);
|
||||||
print_node_brief (file, "abstract_origin",
|
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 end_alias_analysis PROTO ((void));
|
||||||
|
|
||||||
extern void record_base_value PROTO ((int, rtx, int));
|
extern void record_base_value PROTO ((int, rtx, int));
|
||||||
|
extern void record_alias_subset PROTO ((int, int));
|
||||||
|
|
||||||
#endif /* _RTL_H */
|
#endif /* _RTL_H */
|
||||||
|
@ -949,6 +949,7 @@ documented_lang_options[] =
|
|||||||
{ "-traditional", "Attempt to support traditional K&R style C"},
|
{ "-traditional", "Attempt to support traditional K&R style C"},
|
||||||
{ "-fnotraditional", "" },
|
{ "-fnotraditional", "" },
|
||||||
{ "-fno-traditional", "" },
|
{ "-fno-traditional", "" },
|
||||||
|
{ "-flang-isoc9x", "Enable C9X features"},
|
||||||
|
|
||||||
{ "-fasm", "" },
|
{ "-fasm", "" },
|
||||||
{ "-fno-asm", "Do not recognise the 'asm' keyword" },
|
{ "-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. */
|
codes are made. */
|
||||||
#define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
|
#define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
|
||||||
|
|
||||||
|
static void set_type_quals PROTO((tree, int));
|
||||||
|
|
||||||
extern char *mode_name[];
|
extern char *mode_name[];
|
||||||
|
|
||||||
void gcc_obstack_init ();
|
void gcc_obstack_init ();
|
||||||
@ -1100,6 +1102,9 @@ make_node (code)
|
|||||||
DECL_SOURCE_LINE (t) = lineno;
|
DECL_SOURCE_LINE (t) = lineno;
|
||||||
DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";
|
DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";
|
||||||
DECL_UID (t) = next_decl_uid++;
|
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;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
@ -3294,7 +3299,7 @@ build_type_attribute_variant (ttype, attribute)
|
|||||||
/* Create a new main variant of TYPE. */
|
/* Create a new main variant of TYPE. */
|
||||||
TYPE_MAIN_VARIANT (ntype) = ntype;
|
TYPE_MAIN_VARIANT (ntype) = ntype;
|
||||||
TYPE_NEXT_VARIANT (ntype) = 0;
|
TYPE_NEXT_VARIANT (ntype) = 0;
|
||||||
TYPE_READONLY (ntype) = TYPE_VOLATILE (ntype) = 0;
|
set_type_quals (ntype, TYPE_UNQUALIFIED);
|
||||||
|
|
||||||
hashcode = TYPE_HASH (TREE_CODE (ntype))
|
hashcode = TYPE_HASH (TREE_CODE (ntype))
|
||||||
+ TYPE_HASH (TREE_TYPE (ntype))
|
+ TYPE_HASH (TREE_TYPE (ntype))
|
||||||
@ -3319,8 +3324,7 @@ build_type_attribute_variant (ttype, attribute)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ntype = type_hash_canon (hashcode, ntype);
|
ntype = type_hash_canon (hashcode, ntype);
|
||||||
ttype = build_type_variant (ntype, TYPE_READONLY (ttype),
|
ttype = build_qualified_type (ntype, TYPE_QUALS (ttype));
|
||||||
TYPE_VOLATILE (ttype));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ttype;
|
return ttype;
|
||||||
@ -3576,45 +3580,44 @@ merge_machine_decl_attributes (olddecl, newdecl)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a type like TYPE except that its TYPE_READONLY is CONSTP
|
/* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
|
||||||
and its TYPE_VOLATILE is VOLATILEP.
|
of the various TYPE_QUAL values. */
|
||||||
|
|
||||||
Such variant types already made are recorded so that duplicates
|
static void
|
||||||
are not made.
|
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.
|
/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for
|
||||||
Always copy the variant information into the TREE_READONLY
|
the same kind of data as TYPE describes. Variants point to the
|
||||||
and TREE_THIS_VOLATILE of the expression, and then give the expression
|
"main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT,
|
||||||
as its type the "main variant", the variant whose TYPE_READONLY
|
and it points to a chain of other variants so that duplicate
|
||||||
and TYPE_VOLATILE are zero. Use TYPE_MAIN_VARIANT to find the
|
variants are never made. Only main variants should ever appear as
|
||||||
main variant. */
|
types of expressions. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
build_type_variant (type, constp, volatilep)
|
build_qualified_type (type, type_quals)
|
||||||
tree type;
|
tree type;
|
||||||
int constp, volatilep;
|
int type_quals;
|
||||||
{
|
{
|
||||||
register tree t;
|
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
|
/* 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
|
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. */
|
preserve the TYPE_NAME, since there is code that depends on this. */
|
||||||
|
|
||||||
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
|
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
|
||||||
if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t)
|
if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type))
|
||||||
&& TYPE_NAME (t) == TYPE_NAME (type))
|
|
||||||
return t;
|
return t;
|
||||||
|
|
||||||
/* We need a new one. */
|
/* We need a new one. */
|
||||||
|
|
||||||
t = build_type_copy (type);
|
t = build_type_copy (type);
|
||||||
TYPE_READONLY (t) = constp;
|
set_type_quals (t, type_quals);
|
||||||
TYPE_VOLATILE (t) = volatilep;
|
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4422,8 +4425,7 @@ build_complex_type (component_type)
|
|||||||
t = make_node (COMPLEX_TYPE);
|
t = make_node (COMPLEX_TYPE);
|
||||||
|
|
||||||
TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
|
TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
|
||||||
TYPE_VOLATILE (t) = TYPE_VOLATILE (component_type);
|
set_type_quals (t, TYPE_QUALS (component_type));
|
||||||
TYPE_READONLY (t) = TYPE_READONLY (component_type);
|
|
||||||
|
|
||||||
/* If we already have such a type, use the old one and free this one. */
|
/* If we already have such a type, use the old one and free this one. */
|
||||||
hashcode = TYPE_HASH (component_type);
|
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. */
|
/* Means this type is const-qualified. */
|
||||||
#define TYPE_READONLY(NODE) ((NODE)->common.readonly_flag)
|
#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. */
|
/* 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_0(NODE) (TYPE_CHECK (NODE)->type.lang_flag_0)
|
||||||
#define TYPE_LANG_FLAG_1(NODE) (TYPE_CHECK (NODE)->type.lang_flag_1)
|
#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 needs_constructing_flag : 1;
|
||||||
unsigned transparent_union_flag : 1;
|
unsigned transparent_union_flag : 1;
|
||||||
unsigned packed_flag : 1;
|
unsigned packed_flag : 1;
|
||||||
|
unsigned restrict_flag : 1;
|
||||||
|
|
||||||
unsigned lang_flag_0 : 1;
|
unsigned lang_flag_0 : 1;
|
||||||
unsigned lang_flag_1 : 1;
|
unsigned lang_flag_1 : 1;
|
||||||
unsigned lang_flag_2 : 1;
|
unsigned lang_flag_2 : 1;
|
||||||
@ -888,7 +909,7 @@ struct tree_type
|
|||||||
unsigned lang_flag_4 : 1;
|
unsigned lang_flag_4 : 1;
|
||||||
unsigned lang_flag_5 : 1;
|
unsigned lang_flag_5 : 1;
|
||||||
unsigned lang_flag_6 : 1;
|
unsigned lang_flag_6 : 1;
|
||||||
/* room for 4 more bits */
|
/* room for 3 more bits */
|
||||||
|
|
||||||
unsigned int align;
|
unsigned int align;
|
||||||
union tree_node *pointer_to;
|
union tree_node *pointer_to;
|
||||||
@ -1244,6 +1265,16 @@ struct tree_type
|
|||||||
an address constant. */
|
an address constant. */
|
||||||
#define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
|
#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
|
struct tree_decl
|
||||||
{
|
{
|
||||||
char common[sizeof (struct tree_common)];
|
char common[sizeof (struct tree_common)];
|
||||||
@ -1316,6 +1347,7 @@ struct tree_decl
|
|||||||
HOST_WIDE_INT i;
|
HOST_WIDE_INT i;
|
||||||
} saved_insns;
|
} saved_insns;
|
||||||
union tree_node *vindex;
|
union tree_node *vindex;
|
||||||
|
int pointer_alias_set;
|
||||||
/* Points to a structure whose details depend on the language in use. */
|
/* Points to a structure whose details depend on the language in use. */
|
||||||
struct lang_decl *lang_specific;
|
struct lang_decl *lang_specific;
|
||||||
};
|
};
|
||||||
@ -1502,14 +1534,24 @@ extern tree lookup_attribute PROTO((char *, tree));
|
|||||||
|
|
||||||
extern tree merge_attributes PROTO((tree, tree));
|
extern tree merge_attributes PROTO((tree, tree));
|
||||||
|
|
||||||
/* Given a type node TYPE, and CONSTP and VOLATILEP, return a type
|
/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for
|
||||||
for the same kind of data as TYPE describes.
|
the same kind of data as TYPE describes. Variants point to the
|
||||||
Variants point to the "main variant" (which has neither CONST nor VOLATILE)
|
"main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT,
|
||||||
via TYPE_MAIN_VARIANT, and it points to a chain of other variants
|
and it points to a chain of other variants so that duplicate
|
||||||
so that duplicate variants are never made.
|
variants are never made. Only main variants should ever appear as
|
||||||
Only main variants should ever appear as types of expressions. */
|
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. */
|
/* Make a copy of a type node. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user