1992-02-04 20:51:11 +01:00
|
|
|
|
/* Subroutines shared by all languages that are variants of C.
|
2001-01-02 03:04:52 +01:00
|
|
|
|
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
Free Software Foundation, Inc.
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
This file is part of GNU CC.
|
|
|
|
|
|
|
|
|
|
GNU CC is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
|
|
GNU CC is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with GNU CC; see the file COPYING. If not, write to
|
1995-06-15 13:33:25 +02:00
|
|
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
|
|
|
Boston, MA 02111-1307, USA. */
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
#include "config.h"
|
Major cutover to using system.h:
* Makefile.in (alias.o, bitmap.o, c-aux-info.o, c-common.o,
c-decl.o, c-iterate.o, c-lang.o, c-lex.o, c-pragma.o, c-typeck.o,
caller-save.o, calls.o, collect2.o, combine.o, cse.o, dbxout.o,
dwarf2out.o, dwarfout.o, emit-rtl.o, except.o, explow.o, expmed.o,
expr.o, final.o, flow.o, function.o, getpwd.o, global.o,
integrate.o, jump.o, local-alloc.o, loop.o, optabs.o, pexecute.o,
prefix.o, print-rtl.o, print-tree.o, profile.o, real.o, recog.o,
reg-stack.o, regclass.o, regmove.o, reload.o, reload1.o, reorg.o,
rtl.o, rtlanal.o, sdbout.o, stmt.o, stor-layout.o, stupid.o,
tlink.o, toplev.o, tree.o, unroll.o, varasm.o, xcoffout.o): Depend
on system.h.
* alias.c, bitmap.c, c-aux-info.c, c-common.c, c-decl.c,
c-iterate.c, c-lang.c, c-lex.c, c-pragma.c, c-typeck.c,
caller-save.c, calls.c, collect2.c, combine.c, cse.c, dbxout.c,
dwarf2out.c, dwarfout.c, emit-rtl.c, except.c, explow.c, expmed.c,
expr.c, final.c, flow.c, function.c, gcc.c, getpwd.c, global.c,
integrate.c, jump.c, local-alloc.c, loop.c, optabs.c, pexecute.c,
prefix.c, print-rtl.c, print-tree.c, profile.c, real.c, recog.c,
reg-stack.c, regclass.c, regmove.c, reload.c, reload1.c, reorg.c,
rtl.c, rtlanal.c, sched.c, sdbout.c, stmt.c, stor-layout.c,
stupid.c, tlink.c, toplev.c, tree.c, unroll.c, varasm.c,
xcoffout.c: Include system.h. Organize include ordering so
that stdarg/varargs comes before other system headers. Remove
spurious casts of functions assured of a prototype in system.h.
From-SVN: r18726
1998-03-20 15:58:42 +01:00
|
|
|
|
#include "system.h"
|
1992-02-04 20:51:11 +01:00
|
|
|
|
#include "tree.h"
|
|
|
|
|
#include "flags.h"
|
toplev.h: New file.
Wed May 6 06:35:38 1998 Robert Lipe <robertl@dgii.com>
* toplev.h: New file. Protypes for functions in toplev.c.
* tree.h, rtl.h: Deleted protos for functions in toplev.c.
* c-common.c, c-convert.c, c-decl.c, c-iterate.c, c-lex.c,
c-parse.in, c-parse.y, c-pragma.c, c-typeck.c, calls.c,
convert.c, dwarf2out.c, except.c, expr.c, final.c, fold-const.c,
function.c, hash.c, profile.c, real.c, reg-stack.c, regclass.c,
reload.c, reload1.c, stmt.c, stor-layout.c, tlink.c, tree.c,
varasm.c: include it.
From-SVN: r19563
1998-05-06 06:45:47 +02:00
|
|
|
|
#include "toplev.h"
|
Warning fixes:
* Makefile.in (c-lang.o): Depend on c-tree.h, c-lex.h and toplev.h.
(c-lex.o): Depend on output.h.
(c-common.o): Likewise.
(stmt.o): Likewise.
(calls.o): Likewise.
(integrate.o): Depend on toplev.h.
(regclass.o): Depend on output.h.
(final.o): Depend on reload.h.
* c-common.c: Include output.h.
(check_format_info): Remove unused variable `integral_format'.
* c-decl.c (print_lang_decl): Mark parameters `file', `node' and
`indent' with ATTRIBUTE_UNUSED.
(print_lang_type): Likewise.
(maybe_build_cleanup): Likewise for parameter `decl'.
(copy_lang_decl): Likewise for parameter `node'.
* c-lang.c: Include c-tree.h, c-lex.h and toplev.h.
(lang_print_xnode): Mark parameters `file', `node' and `indent'
with ATTRIBUTE_UNUSED.
(lookup_interface): Likewise for parameter `arg'.
(is_class_name): Likewise.
(maybe_objc_check_decl): Likewise for parameter `decl'.
(maybe_objc_comptypes): Likewise for parameters `lhs', `rhs' and
`reflexive'.
(maybe_objc_method_name): Likewise for parameter `decl'.
(build_objc_string): Likewise for parameters `len' and `str'.
* c-lex.c: Include output.h.
* c-lex.h (position_after_white_space): Correct typo in prototype.
* c-tree.h (finish_file, c_expand_start_cond, c_expand_start_else,
c_expand_end_cond, init_iterators): Add prototypes.
* caller-save.c (set_reg_live): Mark parameters `reg' and `setter'
with ATTRIBUTE_UNUSED.
* calls.c: Include output.h.
* cccp.c (pipe_closed): Mark parameter `signo' with
ATTRIBUTE_UNUSED.
* combine.c: Move inclusion of expr.h to after insn-config.h.
* iris6.h (ASM_IDENTIFY_GCC, ASM_IDENTIFY_LANGUAGE): Don't define
as empty, rather define as ((void)0).
* sparc.c (sparc_check_64): Add braces around ambiguous `else'.
Add parentheses around assignment used as truth value.
* cplus-dem.c (squangle_mop_up): Change return type to void.
(internal_cplus_demangle): Remove unused parameter `options'.
All callers changed.
(cplus_demangle_opname): Remove function wide variable `int i' and
replace with `size_t i' at each location where it is used.
(cplus_demangle_opname): change type of `i' from int to size_t.
* cppexp.c (right_shift): Mark parameter `pfile' with
ATTRIBUTE_UNUSED.
* cpphash.c (cpp_lookup): Likewise.
(cpp_hash_cleanup): Likewise.
* cpplib.c (parse_name): Add a prototype and make it static.
(null_underflow): Mark parameter `pfile' with ATTRIBUTE_UNUSED.
(null_cleanup): Likewise for parameters `pbuf' and `pfile'.
(macro_cleanup): Likewise for parameter `pfile'.
(file_cleanup): Likewise.
* cpplib.h (cpp_reader_init, cpp_options_init, cpp_start_read,
cpp_read_check_assertion, skip_rest_of_line): Add prototypes.
* crtstuff.c (force_to_data, __CTOR_LIST__, force_to_data,
__DTOR_END__, __FRAME_END__): Mark with ATTRIBUTE_UNUSED.
* cse.c (cse_check_loop_start): Mark parameter `set' with
ATTRIBUTE_UNUSED.
* dbxout.c (flag_minimal_debug, have_used_extensions,
source_label_number): Move inside macro wrapper check against
defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO).
* dwarf2out.c (gen_entry_point_die): Hide prototype and definition.
* except.h (doing_eh): Provide prototype.
* expr.c: Move inclusion of expr.h to after insn-config.h.
* final.c: Include reload.h.
(shorten_branches): Cast the first argument of bzero to char *.
* fix-header.c (cpp_print_containing_files): Mark parameter
`pfile' with ATTRIBUTE_UNUSED.
(cpp_fatal): Likewise.
* flow.c (find_basic_blocks_1): Cast the first argument of bzero
to char *.
* genattrtab.c (make_length_attrs): Change the type of variable
`i' from int to size_t.
(zero_fn): Mark parameter `exp' with ATTRIBUTE_UNUSED.
(one_fn): Likewise.
* genextract.c (main): When generating insn-extract.c, mark
variable `junk' with ATTRIBUTE_UNUSED.
* gengenrtl.c (gencode): When generating genrtl.c, cast the first
argument of bzero to char*.
* integrate.c: Include toplev.h.
* libgcc2.c: Wrap `struct exception_table' and
`find_exception_handler' in macro DWARF2_UNWIND_INFO.
* objc/Make-lang.in (objc-act.o): Depend on toplev.h.
* objc/objc-act.c: Include toplev.h.
(lang_print_xnode): Mark parameters `file', `node' and `indent'
with ATTRIBUTE_UNUSED.
(finish_protocol): Likewise for parameter `protocol'.
* output.h (declare_weak): Add prototype.
(decode_reg_name): Don't wrap with TREE_CODE macro.
(assemble_alias): Add prototype.
* regclass.c: Include output.h.
* reload.h (reloads_conflict): Add prototype.
* rtl.h (print_rtl_single, mark_elimiation, reg_class_subset_p,
output_func_start_profiler): Add prototypes.
* rtlanal.c (reg_set_p_1): Mark parameters `x' and `pat' with
ATTRIBUTE_UNUSED.
* scan-decls.c: Include scan.h.
* scan.h (recognized_function, recognized_extern): Add prototypes.
* stmt.c: Include output.h.
* toplev.c (error_for_asm, warning_for_asm): Remove prototypes.
(output_lang_identify): Hide prototype and definition.
(float_signal): Mark parameter `signo' with ATTRIBUTE_UNUSED.
(pipe_closed): Likewise.
* toplev.h (count_error, strip_off_ending, error_for_asm,
warning_for_asm): Add prototypes.
From-SVN: r19712
1998-05-13 14:40:39 +02:00
|
|
|
|
#include "output.h"
|
1998-10-01 12:50:15 +02:00
|
|
|
|
#include "c-pragma.h"
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
#include "rtl.h"
|
1999-09-06 23:28:22 +02:00
|
|
|
|
#include "ggc.h"
|
Makefile.in (c-common.o): Depend on $(EXPR_H).
* Makefile.in (c-common.o): Depend on $(EXPR_H).
* c-common.c: Include expr.h.
* c-pragma.c (mark_align_stack): Add prototype.
* caller-save.c (add_stored_regs): Likewise.
* combine.c (record_promoted_value): Likewise.
* i386.c (ix86_sched_reorder_pentium, ix86_sched_reorder_ppro):
Likewise.
* cppinit.c (new_pending_define): Likewise.
* cpplib.c (skip_block_comment, skip_line_comment): Likewise.
* dwarf2out.c (save_rtx, splice_child_die, reverse_die_lists,
AT_class, AT_flag, AT_int, AT_unsigned, AT_string, AT_ref, AT_loc,
AT_addr, AT_lbl, get_AT_ref, free_AT, free_die, local_scope_p,
class_scope_p): Likewise.
* dwarf2out.h (dwarf2out_set_demangle_name_func,
dwarf2out_add_library_unit_info): Likewise.
* ggc.h (ggc_page_print_statistics): Likewise.
* haifa-sched.c (propagate_deps): Likewise.
* reg-stack.c (next_flags_user, record_label_references): Likewise.
* rtl.h (set_stack_check_libfunc): Likewise.
* toplev.h (set_fatal_function): Likewise.
* toplev.c (set_fatal_function): Delete prototype.
* diagnostic.c: Deconstify functions returning malloc'ed ptrs.
From-SVN: r31810
2000-02-06 04:40:46 +01:00
|
|
|
|
#include "expr.h"
|
2000-09-17 09:38:23 +02:00
|
|
|
|
#include "c-common.h"
|
2000-01-11 00:48:03 +01:00
|
|
|
|
#include "tm_p.h"
|
2000-11-24 12:49:46 +01:00
|
|
|
|
#include "obstack.h"
|
1998-05-21 10:54:04 +02:00
|
|
|
|
#include "cpplib.h"
|
2000-12-07 08:14:42 +01:00
|
|
|
|
cpp_reader *parse_in; /* Declared in c-lex.h. */
|
1998-05-21 10:54:04 +02:00
|
|
|
|
|
1999-09-23 23:03:53 +02:00
|
|
|
|
#undef WCHAR_TYPE_SIZE
|
|
|
|
|
#define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node)
|
1995-12-19 01:13:24 +01:00
|
|
|
|
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
/* We let tm.h override the types used here, to handle trivial differences
|
|
|
|
|
such as the choice of unsigned int or long unsigned int for size_t.
|
|
|
|
|
When machines start needing nontrivial differences in the size type,
|
|
|
|
|
it would be best to do something here to figure out automatically
|
|
|
|
|
from other information what type to use. */
|
|
|
|
|
|
|
|
|
|
#ifndef SIZE_TYPE
|
|
|
|
|
#define SIZE_TYPE "long unsigned int"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef WCHAR_TYPE
|
|
|
|
|
#define WCHAR_TYPE "int"
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-12-02 11:50:27 +01:00
|
|
|
|
#ifndef PTRDIFF_TYPE
|
|
|
|
|
#define PTRDIFF_TYPE "long int"
|
|
|
|
|
#endif
|
|
|
|
|
|
c-common.c: Include "defaults.h".
* c-common.c: Include "defaults.h".
(WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Define.
(c_common_nodes_and_builtins): Create string_type_node,
const_string_type_node, wint_type_node, intmax_type_node,
uintmax_type_node, default_function_type, ptrdiff_type_node and
unsigned_ptrdiff_type_node.
* c-common.h (identifier_global_value): Declare.
* c-decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
(init_decl_processing): Don't create string_type_node,
const_string_type_node, wint_type_node, intmax_type_node,
uintmax_type_node, default_function_type, ptrdiff_type_node and
unsigned_ptrdiff_type_node.
(identifier_global_value): New function.
cp:
* decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
(init_decl_processing): Don't create string_type_node,
const_string_type_node, wint_type_node, intmax_type_node,
uintmax_type_node, default_function_type, ptrdiff_type_node and
unsigned_ptrdiff_type_node. Adjust position of call to
c_common_nodes_and_builtins.
(identifier_global_value): New function.
From-SVN: r37931
2000-12-01 23:25:43 +01:00
|
|
|
|
#ifndef WINT_TYPE
|
|
|
|
|
#define WINT_TYPE "unsigned int"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef INTMAX_TYPE
|
|
|
|
|
#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
|
|
|
|
|
? "int" \
|
|
|
|
|
: ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
|
|
|
|
|
? "long int" \
|
|
|
|
|
: "long long int"))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef UINTMAX_TYPE
|
|
|
|
|
#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
|
|
|
|
|
? "unsigned int" \
|
|
|
|
|
: ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
|
|
|
|
|
? "long unsigned int" \
|
|
|
|
|
: "long long unsigned int"))
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-07-20 12:41:10 +02:00
|
|
|
|
/* The following symbols are subsumed in the c_global_trees array, and
|
2000-01-03 22:48:49 +01:00
|
|
|
|
listed here individually for documentation purposes.
|
1999-07-20 12:41:10 +02:00
|
|
|
|
|
|
|
|
|
INTEGER_TYPE and REAL_TYPE nodes for the standard data types.
|
|
|
|
|
|
|
|
|
|
tree short_integer_type_node;
|
|
|
|
|
tree long_integer_type_node;
|
|
|
|
|
tree long_long_integer_type_node;
|
|
|
|
|
|
|
|
|
|
tree short_unsigned_type_node;
|
|
|
|
|
tree long_unsigned_type_node;
|
|
|
|
|
tree long_long_unsigned_type_node;
|
|
|
|
|
|
|
|
|
|
tree boolean_type_node;
|
|
|
|
|
tree boolean_false_node;
|
|
|
|
|
tree boolean_true_node;
|
|
|
|
|
|
|
|
|
|
tree ptrdiff_type_node;
|
|
|
|
|
|
|
|
|
|
tree unsigned_char_type_node;
|
|
|
|
|
tree signed_char_type_node;
|
|
|
|
|
tree wchar_type_node;
|
|
|
|
|
tree signed_wchar_type_node;
|
|
|
|
|
tree unsigned_wchar_type_node;
|
|
|
|
|
|
|
|
|
|
tree float_type_node;
|
|
|
|
|
tree double_type_node;
|
|
|
|
|
tree long_double_type_node;
|
|
|
|
|
|
|
|
|
|
tree complex_integer_type_node;
|
|
|
|
|
tree complex_float_type_node;
|
|
|
|
|
tree complex_double_type_node;
|
|
|
|
|
tree complex_long_double_type_node;
|
|
|
|
|
|
|
|
|
|
tree intQI_type_node;
|
|
|
|
|
tree intHI_type_node;
|
|
|
|
|
tree intSI_type_node;
|
|
|
|
|
tree intDI_type_node;
|
|
|
|
|
tree intTI_type_node;
|
|
|
|
|
|
|
|
|
|
tree unsigned_intQI_type_node;
|
|
|
|
|
tree unsigned_intHI_type_node;
|
|
|
|
|
tree unsigned_intSI_type_node;
|
|
|
|
|
tree unsigned_intDI_type_node;
|
|
|
|
|
tree unsigned_intTI_type_node;
|
|
|
|
|
|
|
|
|
|
tree widest_integer_literal_type_node;
|
|
|
|
|
tree widest_unsigned_literal_type_node;
|
|
|
|
|
|
|
|
|
|
Nodes for types `void *' and `const void *'.
|
|
|
|
|
|
|
|
|
|
tree ptr_type_node, const_ptr_type_node;
|
|
|
|
|
|
|
|
|
|
Nodes for types `char *' and `const char *'.
|
|
|
|
|
|
|
|
|
|
tree string_type_node, const_string_type_node;
|
|
|
|
|
|
|
|
|
|
Type `char[SOMENUMBER]'.
|
|
|
|
|
Used when an array of char is needed and the size is irrelevant.
|
|
|
|
|
|
|
|
|
|
tree char_array_type_node;
|
|
|
|
|
|
|
|
|
|
Type `int[SOMENUMBER]' or something like it.
|
|
|
|
|
Used when an array of int needed and the size is irrelevant.
|
|
|
|
|
|
|
|
|
|
tree int_array_type_node;
|
|
|
|
|
|
|
|
|
|
Type `wchar_t[SOMENUMBER]' or something like it.
|
|
|
|
|
Used when a wide string literal is created.
|
|
|
|
|
|
|
|
|
|
tree wchar_array_type_node;
|
|
|
|
|
|
|
|
|
|
Type `int ()' -- used for implicit declaration of functions.
|
|
|
|
|
|
|
|
|
|
tree default_function_type;
|
|
|
|
|
|
|
|
|
|
A VOID_TYPE node, packaged in a TREE_LIST.
|
|
|
|
|
|
|
|
|
|
tree void_list_node;
|
|
|
|
|
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
The lazily created VAR_DECLS for __FUNCTION__, __PRETTY_FUNCTION__,
|
|
|
|
|
and __func__. (C doesn't generate __FUNCTION__ and__PRETTY_FUNCTION__
|
|
|
|
|
VAR_DECLS, but C++ does.)
|
top level:
* c-common.c (declare_function_name): Use func_id_node,
function_id_node, and pretty_function_id_node. Do not make
__func__ visible at file scope.
* c-common.h (c_tree_index): Add CTI_FUNCTION_ID,
CTI_PRETTY_FUNCTION_ID, and CTI_FUNC_ID.
(function_id_node, pretty_function_id_node, func_id_node): New
macros.
* c-decl.c (init_decl_processing): Initialize function_id_node,
pretty_function_id_node, and func_id_node.
(c_make_fname_decl): Correct comment.
* tree.h (struct tree_identifier): Constify pointer member.
* c-decl.c (pushdecl, implicit_decl_warning): Constify a char *.
* c-pragma.h (struct weak_syms): Constify name and value members.
(add_weak): Constify arguments.
* calls.c (special_function_p): Constify a char *.
(expand_call): Remove variable which is initialized and then
never used.
* dependence.c (struct def_use, struct induction, struct subscript):
Constify 'variable' member.
(get_low_bound, have_induction_variable): Constify char * argument.
(find_induction_variable): Add braces to avoid dangling else.
(classify_dependence): Constify char * arrays.
* profile.c (output_func_start_profiler): Constify a char *.
* stor-layout.c (finalize_record_size): Constify a char *.
* tree.c (is_attribute_p): Constify a char *.
* varasm.c (add_weak, remove_from_pending_weak_list): Constify argument.
* varasm.c (make_function_rtl, make_decl_rtl): Rearrange code
for comprehensibility. Do not call get_identifier if we did
not change the DECL_ASSEMBLER_NAME of the decl. Use alloca to
create temporary string constants, not ggc_alloc_string. No
need to copy result of ASM_FORMAT_PRIVATE_NAME. Use const
char * to hold IDENTIFIER_POINTERs.
ch:
* inout.c (add_enum_to_list): Use DECL_NAME directly, don't get
its IDENTIFIER_POINTER and immediately call get_identifier on it.
* lex.c (yywrap): Constify a char *.
cp:
* class.c (build_secondary_vtable): Constify a char *.
* decl.c (init_decl_processing): Initialize function_id_node,
pretty_function_id_node, and func_id_node.
* input.c (struct input_source): Constify 'str'.
(feed_input): Constify first argument.
* mangle.c (write_identifier): Constify argument.
* pt.c (mangle_class_name_for_template): Constify argument.
f:
* ansify.c: Use #line, not # <number>.
java:
* jcf-parse.c (set_source_filename): Constify a char *.
* jcf-write.c (append_innerclasses_attribute,
make_class_file_name): Constify a char *. Don't recycle a
variable for an unrelated purpose.
* parse.y: (build_alias_initializer_parameter_list): Constify a char *.
(breakdown_qualified): Do not modify IDENTIFIER_POINTER strings.
From-SVN: r36055
2000-08-29 23:39:49 +02:00
|
|
|
|
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
tree function_name_decl_node;
|
|
|
|
|
tree pretty_function_name_declnode;
|
|
|
|
|
tree c99_function_name_decl_node;
|
|
|
|
|
|
|
|
|
|
Stack of nested function name VAR_DECLs.
|
|
|
|
|
|
|
|
|
|
tree saved_function_name_decls;
|
top level:
* c-common.c (declare_function_name): Use func_id_node,
function_id_node, and pretty_function_id_node. Do not make
__func__ visible at file scope.
* c-common.h (c_tree_index): Add CTI_FUNCTION_ID,
CTI_PRETTY_FUNCTION_ID, and CTI_FUNC_ID.
(function_id_node, pretty_function_id_node, func_id_node): New
macros.
* c-decl.c (init_decl_processing): Initialize function_id_node,
pretty_function_id_node, and func_id_node.
(c_make_fname_decl): Correct comment.
* tree.h (struct tree_identifier): Constify pointer member.
* c-decl.c (pushdecl, implicit_decl_warning): Constify a char *.
* c-pragma.h (struct weak_syms): Constify name and value members.
(add_weak): Constify arguments.
* calls.c (special_function_p): Constify a char *.
(expand_call): Remove variable which is initialized and then
never used.
* dependence.c (struct def_use, struct induction, struct subscript):
Constify 'variable' member.
(get_low_bound, have_induction_variable): Constify char * argument.
(find_induction_variable): Add braces to avoid dangling else.
(classify_dependence): Constify char * arrays.
* profile.c (output_func_start_profiler): Constify a char *.
* stor-layout.c (finalize_record_size): Constify a char *.
* tree.c (is_attribute_p): Constify a char *.
* varasm.c (add_weak, remove_from_pending_weak_list): Constify argument.
* varasm.c (make_function_rtl, make_decl_rtl): Rearrange code
for comprehensibility. Do not call get_identifier if we did
not change the DECL_ASSEMBLER_NAME of the decl. Use alloca to
create temporary string constants, not ggc_alloc_string. No
need to copy result of ASM_FORMAT_PRIVATE_NAME. Use const
char * to hold IDENTIFIER_POINTERs.
ch:
* inout.c (add_enum_to_list): Use DECL_NAME directly, don't get
its IDENTIFIER_POINTER and immediately call get_identifier on it.
* lex.c (yywrap): Constify a char *.
cp:
* class.c (build_secondary_vtable): Constify a char *.
* decl.c (init_decl_processing): Initialize function_id_node,
pretty_function_id_node, and func_id_node.
* input.c (struct input_source): Constify 'str'.
(feed_input): Constify first argument.
* mangle.c (write_identifier): Constify argument.
* pt.c (mangle_class_name_for_template): Constify argument.
f:
* ansify.c: Use #line, not # <number>.
java:
* jcf-parse.c (set_source_filename): Constify a char *.
* jcf-write.c (append_innerclasses_attribute,
make_class_file_name): Constify a char *. Don't recycle a
variable for an unrelated purpose.
* parse.y: (build_alias_initializer_parameter_list): Constify a char *.
(breakdown_qualified): Do not modify IDENTIFIER_POINTER strings.
From-SVN: r36055
2000-08-29 23:39:49 +02:00
|
|
|
|
|
1999-07-20 12:41:10 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
tree c_global_trees[CTI_MAX];
|
1993-01-30 07:06:09 +01:00
|
|
|
|
|
2000-10-18 20:59:04 +02:00
|
|
|
|
/* Nonzero means don't recognize the non-ANSI builtin functions. */
|
|
|
|
|
|
|
|
|
|
int flag_no_builtin;
|
|
|
|
|
|
|
|
|
|
/* Nonzero means don't recognize the non-ANSI builtin functions.
|
|
|
|
|
-ansi sets this. */
|
|
|
|
|
|
|
|
|
|
int flag_no_nonansi_builtin;
|
|
|
|
|
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
/* Nonzero means give `double' the same size as `float'. */
|
|
|
|
|
|
|
|
|
|
int flag_short_double;
|
|
|
|
|
|
|
|
|
|
/* Nonzero means give `wchar_t' the same size as `short'. */
|
|
|
|
|
|
|
|
|
|
int flag_short_wchar;
|
|
|
|
|
|
2000-10-17 11:34:21 +02:00
|
|
|
|
/* Nonzero means warn about possible violations of sequence point rules. */
|
|
|
|
|
|
|
|
|
|
int warn_sequence_point;
|
|
|
|
|
|
2000-06-30 20:20:42 +02:00
|
|
|
|
/* The elements of `ridpointers' are identifier nodes for the reserved
|
|
|
|
|
type names and storage classes. It is indexed by a RID_... value. */
|
|
|
|
|
tree *ridpointers;
|
|
|
|
|
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
tree (*make_fname_decl) PARAMS ((tree, int));
|
2000-03-08 12:21:28 +01:00
|
|
|
|
|
2000-09-07 03:36:11 +02:00
|
|
|
|
/* If non-NULL, the address of a language-specific function that
|
|
|
|
|
returns 1 for language-specific statement codes. */
|
|
|
|
|
int (*lang_statement_code_p) PARAMS ((enum tree_code));
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
/* If non-NULL, the address of a language-specific function that takes
|
|
|
|
|
any action required right before expand_function_end is called. */
|
|
|
|
|
void (*lang_expand_function_end) PARAMS ((void));
|
|
|
|
|
|
2000-10-18 07:45:37 +02:00
|
|
|
|
/* If this variable is defined to a non-NULL value, it will be called
|
|
|
|
|
after the file has been completely parsed. */
|
|
|
|
|
void (*back_end_hook) PARAMS ((tree));
|
|
|
|
|
|
1996-12-07 23:51:24 +01:00
|
|
|
|
/* Nonzero means the expression being parsed will never be evaluated.
|
|
|
|
|
This is a count, since unevaluated expressions can nest. */
|
|
|
|
|
int skip_evaluation;
|
|
|
|
|
|
1996-05-06 20:36:48 +02:00
|
|
|
|
enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
|
1998-10-11 04:21:54 +02:00
|
|
|
|
A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION,
|
1995-04-10 14:20:09 +02:00
|
|
|
|
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
|
1999-12-04 04:00:04 +01:00
|
|
|
|
A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS, A_MALLOC,
|
2000-04-13 15:59:00 +02:00
|
|
|
|
A_NO_LIMIT_STACK, A_PURE};
|
1995-03-30 15:59:11 +02:00
|
|
|
|
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
/* Information about how a function name is generated. */
|
|
|
|
|
struct fname_var_t
|
|
|
|
|
{
|
|
|
|
|
tree *decl; /* pointer to the VAR_DECL. */
|
|
|
|
|
unsigned rid; /* RID number for the identifier. */
|
|
|
|
|
int pretty; /* How pretty is it? */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* The three ways of getting then name of the current function. */
|
|
|
|
|
|
|
|
|
|
const struct fname_var_t fname_vars[] =
|
|
|
|
|
{
|
|
|
|
|
/* C99 compliant __func__, must be first. */
|
|
|
|
|
{&c99_function_name_decl_node, RID_C99_FUNCTION_NAME, 0},
|
|
|
|
|
/* GCC __FUNCTION__ compliant. */
|
|
|
|
|
{&function_name_decl_node, RID_FUNCTION_NAME, 0},
|
|
|
|
|
/* GCC __PRETTY_FUNCTION__ compliant. */
|
|
|
|
|
{&pretty_function_name_decl_node, RID_PRETTY_FUNCTION_NAME, 1},
|
|
|
|
|
{NULL, 0, 0},
|
|
|
|
|
};
|
|
|
|
|
|
2000-01-12 23:47:13 +01:00
|
|
|
|
static void add_attribute PARAMS ((enum attrs, const char *,
|
|
|
|
|
int, int, int));
|
|
|
|
|
static void init_attributes PARAMS ((void));
|
|
|
|
|
static int default_valid_lang_attribute PARAMS ((tree, tree, tree, tree));
|
2001-02-12 09:34:30 +01:00
|
|
|
|
static int constant_fits_type_p PARAMS ((tree, tree));
|
1993-08-15 11:30:20 +02:00
|
|
|
|
|
1998-02-17 23:28:23 +01:00
|
|
|
|
/* 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
|
|
|
|
|
and file of the if. If a potentially ambiguous else is seen, that
|
|
|
|
|
fact is recorded; the warning is issued when we can be sure that
|
|
|
|
|
the enclosing if statement does not have an else branch. */
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
int compstmt_count;
|
|
|
|
|
int line;
|
c-aux-info.c (data_type, [...]): Qualify a char* with the `const' keyword.
* c-aux-info.c (data_type, affix_data_type, gen_decl,
gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type):
Qualify a char* with the `const' keyword.
* c-common.c (declare_hidden_char_array, add_attribute, if_elt,
declare_function_name, decl_attributes, format_char_info,
check_format_info, binary_op_error): Likewise.
* cexp.y (yyerror, error, pedwarn, warning, token): Likewise.
* gcse.c (dump_hash_table): Likewise.
* integrate.c (function_cannot_inline_p): Likewise
* optabs.c: Include insn-config.h earlier.
(init_libfuncs, init_integral_libfuncs, init_floating_libfuncs):
Qualify a char* with the `const' keyword.
* real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe,
asctoeg, mtherr, ereal_atof): Likewise.
* real.h (ereal_atof): Likewise.
* sbitmap.c (dump_sbitmap_vector): Likewise.
* sbitmap.h (dump_sbitmap_vector): Likewise.
* stmt.c (nesting, n_occurrences, expand_start_case): Likewise.
* toplev.c (rest_of_compilation): Likewise.
* tree.h (function_cannot_inline_p, expand_start_case): Likewise.
From-SVN: r25614
1999-03-06 06:34:26 +01:00
|
|
|
|
const char *file;
|
1998-02-17 23:28:23 +01:00
|
|
|
|
int needs_warning;
|
2000-09-17 09:38:23 +02:00
|
|
|
|
tree if_stmt;
|
1998-02-17 23:28:23 +01:00
|
|
|
|
} if_elt;
|
|
|
|
|
|
|
|
|
|
static if_elt *if_stack;
|
1998-02-05 21:54:49 +01:00
|
|
|
|
|
|
|
|
|
/* Amount of space in the if statement stack. */
|
|
|
|
|
static int if_stack_space = 0;
|
|
|
|
|
|
|
|
|
|
/* Stack pointer. */
|
|
|
|
|
static int if_stack_pointer = 0;
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
/* Record the start of an if-then, and record the start of it
|
1998-02-17 23:28:23 +01:00
|
|
|
|
for ambiguous else detection. */
|
|
|
|
|
|
1998-02-05 21:54:49 +01:00
|
|
|
|
void
|
2000-09-17 09:38:23 +02:00
|
|
|
|
c_expand_start_cond (cond, compstmt_count)
|
1998-02-05 21:54:49 +01:00
|
|
|
|
tree cond;
|
|
|
|
|
int compstmt_count;
|
|
|
|
|
{
|
2000-09-17 09:38:23 +02:00
|
|
|
|
tree if_stmt;
|
|
|
|
|
|
1998-02-05 21:54:49 +01:00
|
|
|
|
/* Make sure there is enough space on the stack. */
|
|
|
|
|
if (if_stack_space == 0)
|
|
|
|
|
{
|
|
|
|
|
if_stack_space = 10;
|
1998-02-17 23:28:23 +01:00
|
|
|
|
if_stack = (if_elt *)xmalloc (10 * sizeof (if_elt));
|
1998-02-05 21:54:49 +01:00
|
|
|
|
}
|
|
|
|
|
else if (if_stack_space == if_stack_pointer)
|
|
|
|
|
{
|
|
|
|
|
if_stack_space += 10;
|
1998-02-17 23:28:23 +01:00
|
|
|
|
if_stack = (if_elt *)xrealloc (if_stack, if_stack_space * sizeof (if_elt));
|
1998-02-05 21:54:49 +01:00
|
|
|
|
}
|
1998-02-17 23:28:23 +01:00
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
if_stmt = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
|
|
|
|
|
IF_COND (if_stmt) = cond;
|
|
|
|
|
add_stmt (if_stmt);
|
|
|
|
|
|
1998-02-05 21:54:49 +01:00
|
|
|
|
/* Record this if statement. */
|
1998-02-17 23:28:23 +01:00
|
|
|
|
if_stack[if_stack_pointer].compstmt_count = compstmt_count;
|
|
|
|
|
if_stack[if_stack_pointer].file = input_filename;
|
|
|
|
|
if_stack[if_stack_pointer].line = lineno;
|
|
|
|
|
if_stack[if_stack_pointer].needs_warning = 0;
|
2000-09-17 09:38:23 +02:00
|
|
|
|
if_stack[if_stack_pointer].if_stmt = if_stmt;
|
1998-02-17 23:28:23 +01:00
|
|
|
|
if_stack_pointer++;
|
2000-09-17 09:38:23 +02:00
|
|
|
|
}
|
1998-02-05 21:54:49 +01:00
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
/* Called after the then-clause for an if-statement is processed. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
c_finish_then ()
|
|
|
|
|
{
|
|
|
|
|
tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt;
|
|
|
|
|
RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt));
|
1998-02-05 21:54:49 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
/* Record the end of an if-then. Optionally warn if a nested
|
1998-02-17 23:28:23 +01:00
|
|
|
|
if statement had an ambiguous else clause. */
|
|
|
|
|
|
1998-02-05 21:54:49 +01:00
|
|
|
|
void
|
|
|
|
|
c_expand_end_cond ()
|
|
|
|
|
{
|
|
|
|
|
if_stack_pointer--;
|
1998-02-17 23:28:23 +01:00
|
|
|
|
if (if_stack[if_stack_pointer].needs_warning)
|
|
|
|
|
warning_with_file_and_line (if_stack[if_stack_pointer].file,
|
|
|
|
|
if_stack[if_stack_pointer].line,
|
|
|
|
|
"suggest explicit braces to avoid ambiguous `else'");
|
2000-09-17 09:38:23 +02:00
|
|
|
|
last_expr_type = NULL_TREE;
|
1998-02-05 21:54:49 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
/* Called between the then-clause and the else-clause
|
1998-02-17 23:28:23 +01:00
|
|
|
|
of an if-then-else. */
|
|
|
|
|
|
1998-02-05 21:54:49 +01:00
|
|
|
|
void
|
|
|
|
|
c_expand_start_else ()
|
|
|
|
|
{
|
1998-02-17 23:28:23 +01:00
|
|
|
|
/* An ambiguous else warning must be generated for the enclosing if
|
|
|
|
|
statement, unless we see an else branch for that one, too. */
|
1998-02-05 21:54:49 +01:00
|
|
|
|
if (warn_parentheses
|
|
|
|
|
&& if_stack_pointer > 1
|
1998-02-17 23:28:23 +01:00
|
|
|
|
&& (if_stack[if_stack_pointer - 1].compstmt_count
|
|
|
|
|
== if_stack[if_stack_pointer - 2].compstmt_count))
|
|
|
|
|
if_stack[if_stack_pointer - 2].needs_warning = 1;
|
|
|
|
|
|
|
|
|
|
/* Even if a nested if statement had an else branch, it can't be
|
|
|
|
|
ambiguous if this one also has an else. So don't warn in that
|
|
|
|
|
case. Also don't warn for any if statements nested in this else. */
|
|
|
|
|
if_stack[if_stack_pointer - 1].needs_warning = 0;
|
|
|
|
|
if_stack[if_stack_pointer - 1].compstmt_count--;
|
2000-09-17 09:38:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Called after the else-clause for an if-statement is processed. */
|
1998-02-05 21:54:49 +01:00
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
void
|
|
|
|
|
c_finish_else ()
|
|
|
|
|
{
|
|
|
|
|
tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt;
|
|
|
|
|
RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt));
|
1998-02-05 21:54:49 +01:00
|
|
|
|
}
|
|
|
|
|
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
/* Push current bindings for the function name VAR_DECLS. */
|
1992-05-22 22:33:20 +02:00
|
|
|
|
|
|
|
|
|
void
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
start_fname_decls ()
|
1992-05-22 22:33:20 +02:00
|
|
|
|
{
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
unsigned ix;
|
|
|
|
|
tree saved = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
for (ix = 0; fname_vars[ix].decl; ix++)
|
|
|
|
|
{
|
|
|
|
|
tree decl = *fname_vars[ix].decl;
|
1992-05-22 22:33:20 +02:00
|
|
|
|
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
if (decl)
|
|
|
|
|
{
|
|
|
|
|
saved = tree_cons (decl, build_int_2 (ix, 0), saved);
|
|
|
|
|
*fname_vars[ix].decl = NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (saved || saved_function_name_decls)
|
|
|
|
|
/* Normally they'll have been NULL, so only push if we've got a
|
|
|
|
|
stack, or they are non-NULL. */
|
|
|
|
|
saved_function_name_decls = tree_cons (saved, NULL_TREE,
|
|
|
|
|
saved_function_name_decls);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Finish up the current bindings, adding them into the
|
|
|
|
|
current function's statement tree. This is done by wrapping the
|
|
|
|
|
function's body in a COMPOUND_STMT containing these decls too. This
|
|
|
|
|
must be done _before_ finish_stmt_tree is called. If there is no
|
|
|
|
|
current function, we must be at file scope and no statements are
|
|
|
|
|
involved. Pop the previous bindings. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
finish_fname_decls ()
|
|
|
|
|
{
|
|
|
|
|
unsigned ix;
|
|
|
|
|
tree body = NULL_TREE;
|
|
|
|
|
tree stack = saved_function_name_decls;
|
|
|
|
|
|
|
|
|
|
for (; stack && TREE_VALUE (stack); stack = TREE_CHAIN (stack))
|
|
|
|
|
body = chainon (TREE_VALUE (stack), body);
|
|
|
|
|
|
|
|
|
|
if (body)
|
|
|
|
|
{
|
|
|
|
|
/* They were called into existance, so add to statement tree. */
|
|
|
|
|
body = chainon (body,
|
|
|
|
|
TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)));
|
|
|
|
|
body = build_stmt (COMPOUND_STMT, body);
|
|
|
|
|
|
|
|
|
|
COMPOUND_STMT_NO_SCOPE (body) = 1;
|
|
|
|
|
TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)) = body;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ix = 0; fname_vars[ix].decl; ix++)
|
|
|
|
|
*fname_vars[ix].decl = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
if (stack)
|
1992-05-22 22:33:20 +02:00
|
|
|
|
{
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
/* We had saved values, restore them. */
|
|
|
|
|
tree saved;
|
|
|
|
|
|
|
|
|
|
for (saved = TREE_PURPOSE (stack); saved; saved = TREE_CHAIN (saved))
|
|
|
|
|
{
|
|
|
|
|
tree decl = TREE_PURPOSE (saved);
|
|
|
|
|
unsigned ix = TREE_INT_CST_LOW (TREE_VALUE (saved));
|
|
|
|
|
|
|
|
|
|
*fname_vars[ix].decl = decl;
|
|
|
|
|
}
|
|
|
|
|
stack = TREE_CHAIN (stack);
|
1992-05-22 22:33:20 +02:00
|
|
|
|
}
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
saved_function_name_decls = stack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the text name of the current function, suitable prettified
|
|
|
|
|
by PRETTY_P. */
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
fname_as_string (pretty_p)
|
|
|
|
|
int pretty_p;
|
|
|
|
|
{
|
|
|
|
|
const char *name = NULL;
|
|
|
|
|
|
|
|
|
|
if (pretty_p)
|
|
|
|
|
name = (current_function_decl
|
|
|
|
|
? (*decl_printable_name) (current_function_decl, 2)
|
|
|
|
|
: "top level");
|
|
|
|
|
else if (current_function_decl && DECL_NAME (current_function_decl))
|
|
|
|
|
name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
|
1992-05-22 22:33:20 +02:00
|
|
|
|
else
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
name = "";
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the text name of the current function, formatted as
|
|
|
|
|
required by the supplied RID value. */
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
fname_string (rid)
|
|
|
|
|
unsigned rid;
|
|
|
|
|
{
|
|
|
|
|
unsigned ix;
|
|
|
|
|
|
|
|
|
|
for (ix = 0; fname_vars[ix].decl; ix++)
|
|
|
|
|
if (fname_vars[ix].rid == rid)
|
|
|
|
|
break;
|
|
|
|
|
return fname_as_string (fname_vars[ix].pretty);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the VAR_DECL for a const char array naming the current
|
|
|
|
|
function. If the VAR_DECL has not yet been created, create it
|
|
|
|
|
now. RID indicates how it should be formatted and IDENTIFIER_NODE
|
|
|
|
|
ID is its name (unfortunately C and C++ hold the RID values of
|
|
|
|
|
keywords in different places, so we can't derive RID from ID in
|
|
|
|
|
this language independant code. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
fname_decl (rid, id)
|
|
|
|
|
unsigned rid;
|
|
|
|
|
tree id;
|
|
|
|
|
{
|
|
|
|
|
unsigned ix;
|
|
|
|
|
tree decl = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
for (ix = 0; fname_vars[ix].decl; ix++)
|
|
|
|
|
if (fname_vars[ix].rid == rid)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
decl = *fname_vars[ix].decl;
|
|
|
|
|
if (!decl)
|
1992-05-22 22:33:20 +02:00
|
|
|
|
{
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
tree saved_last_tree = last_tree;
|
|
|
|
|
|
|
|
|
|
decl = (*make_fname_decl) (id, fname_vars[ix].pretty);
|
|
|
|
|
if (last_tree != saved_last_tree)
|
|
|
|
|
{
|
|
|
|
|
/* We created some statement tree for the decl. This belongs
|
|
|
|
|
at the start of the function, so remove it now and reinsert
|
|
|
|
|
it after the function is complete. */
|
|
|
|
|
tree stmts = TREE_CHAIN (saved_last_tree);
|
|
|
|
|
|
|
|
|
|
TREE_CHAIN (saved_last_tree) = NULL_TREE;
|
|
|
|
|
last_tree = saved_last_tree;
|
|
|
|
|
saved_function_name_decls = tree_cons (decl, stmts,
|
|
|
|
|
saved_function_name_decls);
|
|
|
|
|
}
|
|
|
|
|
*fname_vars[ix].decl = decl;
|
1992-05-22 22:33:20 +02:00
|
|
|
|
}
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
if (!ix && !current_function_decl)
|
|
|
|
|
pedwarn_with_decl (decl, "`%s' is not defined outside of function scope");
|
2000-03-08 12:21:28 +01:00
|
|
|
|
|
Lazy __FUNCTION__ generation.
gcc:
Lazy __FUNCTION__ generation.
* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
RID_C99_FUNCTION_NAME): New _RIDs.
(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove.
(CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New
global tree slots.
(function_id_node, pretty_function_id_node, func_id_node): Remove.
(c99_function_name_decl_node, function_name_decl_node,
pretty_function_name_decl_node, saved_function_name_decls):
Declare.
(struct language_function): Remove x_function_name_declared_p.
(make_fname_decl): Remove a parameter.
(declare_function_names): Remove prototype.
(start_fname_decls, finish_fname_decls): Prototype.
(fname_as_string): Likewise.
(fname_string, fname_decl): Likewise.
* c-common.c (make_fname_decl): Adjust.
(struct fname_var_t): New struct.
(fname_vars): New static array.
(declare_function_name): Remove.
(start_fname_decls, finish_fname_decls): New functions.
(fname_as_string): New function from remnants of
declare_function_name.
(fname_string, fname_decl): New functions.
* c-decl.c (c_function_name_declared_p): Remove.
(init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(c_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number. Call finish_decl.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
Remove c_function_name_declared_p.
(push_c_function_context): Don't push c_function_name_declared_p.
(pop_c_function_context): Don't pop c_function_name_declared_p.
(c_begin_compound_stmt): Don't check c_function_name_declared_p.
* c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens.
(program): Call finish_fname_decls for C.
(primary): Add VAR_FUNC_NAME.
(reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
(yylexname): If it's a STRING_FUNC_NAME generate the function name
now. Don't look for VAR_DECLs containing __FUNCTION__ et al.
* c-semantics.c (prune_unused_decls): Remove.
(finish_stmt_tree): Don't call prune_unused_decls.
(genrtl_decl_stmt): Don't prune unused decls here.
cp:
Lazy __FUNCTION__ generation.
* cp-tree.def (FUNCTION_NAME): Remove.
* cp-tree.h (function_name_declared_p): Remove.
(cp_fname_init): Prototype.
* decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
don't call declare_function_name. Call start_fname_decls.
(cp_make_fname_decl): Adjust parameters. Generate the name. Don't
clobber the line number.
(cp_fname_init): New function.
(start_function): Call start_fname_decls.
(finish_function): Call finish_fname_decls.
* lex.c (reswords): Add slots for __FUNCTION__ et al.
(rid_to_yy): Add mappings for __FUNCTION__ et al.
* optimize.c (maybe_clone_body): Remove function_name_declared_p.
* parse.y (VAR_FUNC_NAME): New token.
(primary): Add VAR_FUNC_NAME.
* pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
generation.
(tsubst, FUNCTION_NAME case): Remove.
(tsubst_copy, FUNCTION_NAME case): Remove.
(tsubst_expr, DECL_STMT case): Be careful with a
DECL_PRETTY_FUNCTION_P.
(instantiate_decl): Remove function_name_declared_p.
* semantics.c (begin_compound_statement): Don't call
declare_function_name here.
(setup_vtbl_ptr). Don't save & restore function_name_declared_p.
(finish_translation_unit): Call finish_fname_decls.
(expand_body): Remove function_name_declared_p.
* typeck2.c (digest_init): Allow any ERROR_MARK.
testsuite:
* gcc.dg/c99-func-2.c: Remove xfail.
* gcc.dg/c99-func-3.c: Remove xfail.
* gcc.dg/c99-func-4.c: Remove xfail.
From-SVN: r41520
2001-04-24 10:22:06 +02:00
|
|
|
|
return decl;
|
1992-05-22 22:33:20 +02:00
|
|
|
|
}
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
/* Given a chain of STRING_CST nodes,
|
|
|
|
|
concatenate them into one STRING_CST
|
|
|
|
|
and give it a suitable array-of-chars data type. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
combine_strings (strings)
|
|
|
|
|
tree strings;
|
|
|
|
|
{
|
|
|
|
|
register tree value, t;
|
|
|
|
|
register int length = 1;
|
|
|
|
|
int wide_length = 0;
|
|
|
|
|
int wide_flag = 0;
|
|
|
|
|
int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
|
|
|
|
|
int nchars;
|
2000-07-12 23:03:29 +02:00
|
|
|
|
const int nchars_max = flag_isoc99 ? 4095 : 509;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
if (TREE_CHAIN (strings))
|
|
|
|
|
{
|
|
|
|
|
/* More than one in the chain, so concatenate. */
|
|
|
|
|
register char *p, *q;
|
|
|
|
|
|
|
|
|
|
/* Don't include the \0 at the end of each substring,
|
|
|
|
|
except for the last one.
|
|
|
|
|
Count wide strings and ordinary strings separately. */
|
|
|
|
|
for (t = strings; t; t = TREE_CHAIN (t))
|
|
|
|
|
{
|
|
|
|
|
if (TREE_TYPE (t) == wchar_array_type_node)
|
|
|
|
|
{
|
|
|
|
|
wide_length += (TREE_STRING_LENGTH (t) - wchar_bytes);
|
|
|
|
|
wide_flag = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
length += (TREE_STRING_LENGTH (t) - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If anything is wide, the non-wides will be converted,
|
|
|
|
|
which makes them take more space. */
|
|
|
|
|
if (wide_flag)
|
|
|
|
|
length = length * wchar_bytes + wide_length;
|
|
|
|
|
|
stringpool.c: New file.
* stringpool.c: New file.
* ggc-common.c (ggc_mark_string_ptr, ggc_add_string_root): Delete.
(ggc_alloc_string): Now in stringpool.o.
* ggc-page.c, ggc-simple.c: Do not define or allocate empty_string.
* ggc.h: Delete prototype of ggc_add_string_root. #define
ggc_add_string_root and ggc_mark_string to nothing. Prototype
init_stringpool and stringpool_statistics.
(ggc_alloc_string): Returns a const char *.
* tree.c (hash_table, do_identifier_warnings): Delete.
(init_obstacks): Don't initialize the identifier hash table.
(get_identifier, maybe_get_identifier, start_identifier_warnings,
set_identifier_size): Now in stringpool.c.
* tree.h (struct tree_string): Constify pointer field.
(approx_sqrt): Prototype.
* Makefile.in (stringpool.o): Add rule, mention in OBJS.
* toplev.c (approx_sqrt): New function.
(compile_file): Call stringpool_statistics if mem_report is on.
(main): Call init_stringpool.
* builtins.c (c_strlen), c-decl.c (finish_decl), c-lex.c
(process_directive), c-typeck.c (constructor_asmspec, struct
initializer_stack, start_init), except.c (create_rethrow_ref),
stmt.c (digit_strings), toplev.c (decode_f_option), tree.c
(built_in_filename), varasm,c (in_named_name,
assemble_static_space, struct constant_descriptor, struct
deferred_string, struct pool_constant, force_const_mem),
i386.c (pic_label_name, global_offset_table_name), rs6000.c
(rs6000_emit_prologue, rs6000_emit_epilogue) : Constify a char *.
* c-common.c (combine_strings): Combine strings in scratch
buffer, then pass to build_string.
* optabs.c (init_libfuncs), profile.c (init_edge_profiler,
output_func_start_profiler), stmt.c (init_stmt), alpha.c
(alpha_need_linkage), arm.c (arm_encode_call_attribute),
i386.c (load_pic_register), ia64.c (ia64_encode_section_info),
rs6000.c (rs6000_encode_section_info): Create string in
scratch buffer, then pass to ggc_alloc_string.
* stmt.c (expand_asm_operands): If we must adjust the
constraint strings, do so by creating a new one, not by
modifying the old one in place. Constify some char *s.
* config/pa/pa.c (hppa_encode_label): Drop unnecessary second
argument. Create string in scratch buffer, then pass to
ggc_alloc_string.
* config/pa/pa-protos.h: Update prototype.
* config/pa/elf.h, config/pa/pa.h, config/pa/som.h:
hppa_encode_label takes only one argument.
* c-parse.in (if_prefix): Find the filename and line number at
$-2 and $-1 respectively.
* diagnostic.c (error_recursion): Add missing newline, use
fputs, translate string.
cp:
* lex.c (struct impl_files, internal_filename): Constify a char *.
java:
* jcf-parse.c (get_constant), parse.y (do_merge_string_cste):
Create string in scratch buffer, then pass to build_string.
From-SVN: r37514
2000-11-17 07:05:31 +01:00
|
|
|
|
p = alloca (length);
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
/* Copy the individual strings into the new combined string.
|
|
|
|
|
If the combined string is wide, convert the chars to ints
|
|
|
|
|
for any individual strings that are not wide. */
|
|
|
|
|
|
|
|
|
|
q = p;
|
|
|
|
|
for (t = strings; t; t = TREE_CHAIN (t))
|
|
|
|
|
{
|
|
|
|
|
int len = (TREE_STRING_LENGTH (t)
|
|
|
|
|
- ((TREE_TYPE (t) == wchar_array_type_node)
|
|
|
|
|
? wchar_bytes : 1));
|
|
|
|
|
if ((TREE_TYPE (t) == wchar_array_type_node) == wide_flag)
|
|
|
|
|
{
|
1998-09-21 01:54:10 +02:00
|
|
|
|
memcpy (q, TREE_STRING_POINTER (t), len);
|
1992-02-04 20:51:11 +01:00
|
|
|
|
q += len;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2001-05-10 19:39:19 +02:00
|
|
|
|
int i, j;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
for (i = 0; i < len; i++)
|
1995-11-29 20:05:42 +01:00
|
|
|
|
{
|
2001-05-10 19:39:19 +02:00
|
|
|
|
if (BYTES_BIG_ENDIAN)
|
|
|
|
|
{
|
|
|
|
|
for (j=0; j<(WCHAR_TYPE_SIZE / BITS_PER_UNIT)-1; j++)
|
|
|
|
|
*q++ = 0;
|
|
|
|
|
*q++ = TREE_STRING_POINTER (t)[i];
|
|
|
|
|
}
|
1995-11-29 20:05:42 +01:00
|
|
|
|
else
|
2001-05-10 19:39:19 +02:00
|
|
|
|
{
|
|
|
|
|
*q++ = TREE_STRING_POINTER (t)[i];
|
|
|
|
|
for (j=0; j<(WCHAR_TYPE_SIZE / BITS_PER_UNIT)-1; j++)
|
|
|
|
|
*q++ = 0;
|
|
|
|
|
}
|
1995-11-29 20:05:42 +01:00
|
|
|
|
}
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (wide_flag)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < wchar_bytes; i++)
|
|
|
|
|
*q++ = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
*q = 0;
|
|
|
|
|
|
stringpool.c: New file.
* stringpool.c: New file.
* ggc-common.c (ggc_mark_string_ptr, ggc_add_string_root): Delete.
(ggc_alloc_string): Now in stringpool.o.
* ggc-page.c, ggc-simple.c: Do not define or allocate empty_string.
* ggc.h: Delete prototype of ggc_add_string_root. #define
ggc_add_string_root and ggc_mark_string to nothing. Prototype
init_stringpool and stringpool_statistics.
(ggc_alloc_string): Returns a const char *.
* tree.c (hash_table, do_identifier_warnings): Delete.
(init_obstacks): Don't initialize the identifier hash table.
(get_identifier, maybe_get_identifier, start_identifier_warnings,
set_identifier_size): Now in stringpool.c.
* tree.h (struct tree_string): Constify pointer field.
(approx_sqrt): Prototype.
* Makefile.in (stringpool.o): Add rule, mention in OBJS.
* toplev.c (approx_sqrt): New function.
(compile_file): Call stringpool_statistics if mem_report is on.
(main): Call init_stringpool.
* builtins.c (c_strlen), c-decl.c (finish_decl), c-lex.c
(process_directive), c-typeck.c (constructor_asmspec, struct
initializer_stack, start_init), except.c (create_rethrow_ref),
stmt.c (digit_strings), toplev.c (decode_f_option), tree.c
(built_in_filename), varasm,c (in_named_name,
assemble_static_space, struct constant_descriptor, struct
deferred_string, struct pool_constant, force_const_mem),
i386.c (pic_label_name, global_offset_table_name), rs6000.c
(rs6000_emit_prologue, rs6000_emit_epilogue) : Constify a char *.
* c-common.c (combine_strings): Combine strings in scratch
buffer, then pass to build_string.
* optabs.c (init_libfuncs), profile.c (init_edge_profiler,
output_func_start_profiler), stmt.c (init_stmt), alpha.c
(alpha_need_linkage), arm.c (arm_encode_call_attribute),
i386.c (load_pic_register), ia64.c (ia64_encode_section_info),
rs6000.c (rs6000_encode_section_info): Create string in
scratch buffer, then pass to ggc_alloc_string.
* stmt.c (expand_asm_operands): If we must adjust the
constraint strings, do so by creating a new one, not by
modifying the old one in place. Constify some char *s.
* config/pa/pa.c (hppa_encode_label): Drop unnecessary second
argument. Create string in scratch buffer, then pass to
ggc_alloc_string.
* config/pa/pa-protos.h: Update prototype.
* config/pa/elf.h, config/pa/pa.h, config/pa/som.h:
hppa_encode_label takes only one argument.
* c-parse.in (if_prefix): Find the filename and line number at
$-2 and $-1 respectively.
* diagnostic.c (error_recursion): Add missing newline, use
fputs, translate string.
cp:
* lex.c (struct impl_files, internal_filename): Constify a char *.
java:
* jcf-parse.c (get_constant), parse.y (do_merge_string_cste):
Create string in scratch buffer, then pass to build_string.
From-SVN: r37514
2000-11-17 07:05:31 +01:00
|
|
|
|
value = build_string (length, p);
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
value = strings;
|
|
|
|
|
length = TREE_STRING_LENGTH (value);
|
|
|
|
|
if (TREE_TYPE (value) == wchar_array_type_node)
|
|
|
|
|
wide_flag = 1;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 22:19:33 +02:00
|
|
|
|
/* Compute the number of elements, for the array type. */
|
1992-02-04 20:51:11 +01:00
|
|
|
|
nchars = wide_flag ? length / wchar_bytes : length;
|
|
|
|
|
|
2000-12-02 23:32:15 +01:00
|
|
|
|
if (pedantic && nchars - 1 > nchars_max && c_language == clk_c)
|
2001-02-11 00:30:55 +01:00
|
|
|
|
pedwarn ("string length `%d' is greater than the length `%d' ISO C%d compilers are required to support",
|
2000-12-02 23:32:15 +01:00
|
|
|
|
nchars - 1, nchars_max, flag_isoc99 ? 99 : 89);
|
2000-07-12 23:03:29 +02:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
/* Create the array type for the string constant.
|
|
|
|
|
-Wwrite-strings says make the string constant an array of const char
|
1998-08-24 04:08:45 +02:00
|
|
|
|
so that copying it to a non-const pointer will get a warning.
|
|
|
|
|
For C++, this is the standard behavior. */
|
|
|
|
|
if (flag_const_strings
|
1992-02-04 20:51:11 +01:00
|
|
|
|
&& (! flag_traditional && ! flag_writable_strings))
|
|
|
|
|
{
|
|
|
|
|
tree elements
|
|
|
|
|
= build_type_variant (wide_flag ? wchar_type_node : char_type_node,
|
|
|
|
|
1, 0);
|
|
|
|
|
TREE_TYPE (value)
|
|
|
|
|
= build_array_type (elements,
|
|
|
|
|
build_index_type (build_int_2 (nchars - 1, 0)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
TREE_TYPE (value)
|
|
|
|
|
= build_array_type (wide_flag ? wchar_type_node : char_type_node,
|
|
|
|
|
build_index_type (build_int_2 (nchars - 1, 0)));
|
1998-08-24 04:08:45 +02:00
|
|
|
|
|
1999-08-25 23:05:16 +02:00
|
|
|
|
TREE_CONSTANT (value) = 1;
|
|
|
|
|
TREE_READONLY (value) = ! flag_writable_strings;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
TREE_STATIC (value) = 1;
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
/* To speed up processing of attributes, we maintain an array of
|
|
|
|
|
IDENTIFIER_NODES and the corresponding attribute types. */
|
|
|
|
|
|
|
|
|
|
/* Array to hold attribute information. */
|
|
|
|
|
|
|
|
|
|
static struct {enum attrs id; tree name; int min, max, decl_req;} attrtab[50];
|
|
|
|
|
|
|
|
|
|
static int attrtab_idx = 0;
|
|
|
|
|
|
|
|
|
|
/* Add an entry to the attribute table above. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
add_attribute (id, string, min_len, max_len, decl_req)
|
|
|
|
|
enum attrs id;
|
c-aux-info.c (data_type, [...]): Qualify a char* with the `const' keyword.
* c-aux-info.c (data_type, affix_data_type, gen_decl,
gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type):
Qualify a char* with the `const' keyword.
* c-common.c (declare_hidden_char_array, add_attribute, if_elt,
declare_function_name, decl_attributes, format_char_info,
check_format_info, binary_op_error): Likewise.
* cexp.y (yyerror, error, pedwarn, warning, token): Likewise.
* gcse.c (dump_hash_table): Likewise.
* integrate.c (function_cannot_inline_p): Likewise
* optabs.c: Include insn-config.h earlier.
(init_libfuncs, init_integral_libfuncs, init_floating_libfuncs):
Qualify a char* with the `const' keyword.
* real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe,
asctoeg, mtherr, ereal_atof): Likewise.
* real.h (ereal_atof): Likewise.
* sbitmap.c (dump_sbitmap_vector): Likewise.
* sbitmap.h (dump_sbitmap_vector): Likewise.
* stmt.c (nesting, n_occurrences, expand_start_case): Likewise.
* toplev.c (rest_of_compilation): Likewise.
* tree.h (function_cannot_inline_p, expand_start_case): Likewise.
From-SVN: r25614
1999-03-06 06:34:26 +01:00
|
|
|
|
const char *string;
|
1995-03-30 15:59:11 +02:00
|
|
|
|
int min_len, max_len;
|
|
|
|
|
int decl_req;
|
|
|
|
|
{
|
|
|
|
|
char buf[100];
|
|
|
|
|
|
|
|
|
|
attrtab[attrtab_idx].id = id;
|
|
|
|
|
attrtab[attrtab_idx].name = get_identifier (string);
|
|
|
|
|
attrtab[attrtab_idx].min = min_len;
|
|
|
|
|
attrtab[attrtab_idx].max = max_len;
|
|
|
|
|
attrtab[attrtab_idx++].decl_req = decl_req;
|
|
|
|
|
|
|
|
|
|
sprintf (buf, "__%s__", string);
|
|
|
|
|
|
|
|
|
|
attrtab[attrtab_idx].id = id;
|
|
|
|
|
attrtab[attrtab_idx].name = get_identifier (buf);
|
|
|
|
|
attrtab[attrtab_idx].min = min_len;
|
|
|
|
|
attrtab[attrtab_idx].max = max_len;
|
|
|
|
|
attrtab[attrtab_idx++].decl_req = decl_req;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize attribute table. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_attributes ()
|
|
|
|
|
{
|
1995-04-26 23:23:10 +02:00
|
|
|
|
add_attribute (A_PACKED, "packed", 0, 0, 0);
|
1995-04-10 14:20:09 +02:00
|
|
|
|
add_attribute (A_NOCOMMON, "nocommon", 0, 0, 1);
|
1996-05-06 20:36:48 +02:00
|
|
|
|
add_attribute (A_COMMON, "common", 0, 0, 1);
|
1995-03-30 15:59:11 +02:00
|
|
|
|
add_attribute (A_NORETURN, "noreturn", 0, 0, 1);
|
|
|
|
|
add_attribute (A_NORETURN, "volatile", 0, 0, 1);
|
1998-02-05 21:54:49 +01:00
|
|
|
|
add_attribute (A_UNUSED, "unused", 0, 0, 0);
|
1995-03-30 15:59:11 +02:00
|
|
|
|
add_attribute (A_CONST, "const", 0, 0, 1);
|
|
|
|
|
add_attribute (A_T_UNION, "transparent_union", 0, 0, 0);
|
|
|
|
|
add_attribute (A_CONSTRUCTOR, "constructor", 0, 0, 1);
|
|
|
|
|
add_attribute (A_DESTRUCTOR, "destructor", 0, 0, 1);
|
|
|
|
|
add_attribute (A_MODE, "mode", 1, 1, 1);
|
|
|
|
|
add_attribute (A_SECTION, "section", 1, 1, 1);
|
|
|
|
|
add_attribute (A_ALIGNED, "aligned", 0, 1, 0);
|
1995-03-31 14:26:28 +02:00
|
|
|
|
add_attribute (A_FORMAT, "format", 3, 3, 1);
|
1996-06-08 19:35:57 +02:00
|
|
|
|
add_attribute (A_FORMAT_ARG, "format_arg", 1, 1, 1);
|
1995-04-16 08:14:00 +02:00
|
|
|
|
add_attribute (A_WEAK, "weak", 0, 0, 1);
|
|
|
|
|
add_attribute (A_ALIAS, "alias", 1, 1, 1);
|
1998-07-30 12:38:22 +02:00
|
|
|
|
add_attribute (A_NO_INSTRUMENT_FUNCTION, "no_instrument_function", 0, 0, 1);
|
1998-10-11 04:21:54 +02:00
|
|
|
|
add_attribute (A_NO_CHECK_MEMORY_USAGE, "no_check_memory_usage", 0, 0, 1);
|
1999-11-28 21:45:34 +01:00
|
|
|
|
add_attribute (A_MALLOC, "malloc", 0, 0, 1);
|
1999-12-04 04:00:04 +01:00
|
|
|
|
add_attribute (A_NO_LIMIT_STACK, "no_stack_limit", 0, 0, 1);
|
2000-04-13 15:59:00 +02:00
|
|
|
|
add_attribute (A_PURE, "pure", 0, 0, 1);
|
1995-03-30 15:59:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-04-13 23:04:06 +02:00
|
|
|
|
/* Default implementation of valid_lang_attribute, below. By default, there
|
|
|
|
|
are no language-specific attributes. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
default_valid_lang_attribute (attr_name, attr_args, decl, type)
|
|
|
|
|
tree attr_name ATTRIBUTE_UNUSED;
|
|
|
|
|
tree attr_args ATTRIBUTE_UNUSED;
|
|
|
|
|
tree decl ATTRIBUTE_UNUSED;
|
|
|
|
|
tree type ATTRIBUTE_UNUSED;
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return a 1 if ATTR_NAME and ATTR_ARGS denote a valid language-specific
|
|
|
|
|
attribute for either declaration DECL or type TYPE and 0 otherwise. */
|
|
|
|
|
|
2000-01-12 23:47:13 +01:00
|
|
|
|
int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree))
|
1999-04-13 23:04:06 +02:00
|
|
|
|
= default_valid_lang_attribute;
|
|
|
|
|
|
1995-02-21 23:55:41 +01:00
|
|
|
|
/* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
|
1995-03-30 15:59:11 +02:00
|
|
|
|
and install them in NODE, which is either a DECL (including a TYPE_DECL)
|
|
|
|
|
or a TYPE. PREFIX_ATTRIBUTES can appear after the declaration specifiers
|
1996-07-04 00:07:53 +02:00
|
|
|
|
and declaration modifiers but before the declaration proper. */
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
void
|
1995-03-30 15:59:11 +02:00
|
|
|
|
decl_attributes (node, attributes, prefix_attributes)
|
|
|
|
|
tree node, attributes, prefix_attributes;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
{
|
1998-03-25 14:42:05 +01:00
|
|
|
|
tree decl = 0, type = 0;
|
|
|
|
|
int is_type = 0;
|
1995-03-30 15:59:11 +02:00
|
|
|
|
tree a;
|
|
|
|
|
|
|
|
|
|
if (attrtab_idx == 0)
|
|
|
|
|
init_attributes ();
|
|
|
|
|
|
builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
* builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
* c-common.c (decl_attributes,check_format_info,truthvalue_conversion,
c_get_alias_set): Likewise.
* c-decl.c (duplicate_decls): Likewise.
* c-typeck.c (default_conversion,build_unary_op): Likewise.
* calls.c (initialize_argument_information): Likewise.
* dwarf2out.c (decl_class_context,add_abstract_origin_attribute):
Likewise.
* dwarfout.c (decl_class_context,output_type): Likewise.
* expr.c (get_inner_reference): Likewise.
* fold-const.c (simple_operand_p,fold): Likewise.
* function.c (aggregate_value_p): Likewise.
* stmt.c (expand_asm_operands): Likewise.
* varasm.c (named_section): Likewise.
* call.c (check_dtor_name,build_new_method_call): Likewise.
* decl.c (push_class_binding,poplevel,pushtag,lookup_namespace_name,
make_typename_type,check_initializer,cp_finish_decl,xref_tag): Likewise.
* decl2.c (grokfield,build_expr_from_tree,build_expr_from_tree,
decl_namespace,arg_assoc_template_arg,arg_assoc,
validate_nonmember_using_decl,do_class_using_decl): Likewise.
* error.c (dump_template_argument,dump_expr,cp_file_of,cp_line_of,
args_to_string): Likewise.
* friend.c (is_friend): Likewise.
* lex.c (note_got_semicolon,note_list_got_semicolon,is_global): Likewise.
* method.c (build_overload_nested_name,build_overload_value,
build_qualified_name,build_qualified_name,hack_identifier): Likewise.
* parse.y (typename_sub,typename_sub1): Likewise.
* pt.c (push_inline_template_parms_recursive,check_template_shadow,
process_partial_specialization,convert_template_argument,
template_args_equal,add_pending_template,lookup_template_class,
for_each_template_parm_r,maybe_fold_nontype_arg,
tsubst,instantiate_template,type_unification_real,unify,
instantiate_pending_templates,set_mangled_name_for_template_decl):
Likewise.
* repo.c (repo_get_id,repo_template_used): Likewise.
* search.c (lookup_field_1): Likewise.
* tree.c (walk_tree,get_type_decl,cp_tree_equal,member_p): Likewise.
* xref.c (classname): Likewise.
From-SVN: r32698
2000-03-23 01:41:05 +01:00
|
|
|
|
if (DECL_P (node))
|
1995-03-30 15:59:11 +02:00
|
|
|
|
{
|
|
|
|
|
decl = node;
|
|
|
|
|
type = TREE_TYPE (decl);
|
|
|
|
|
is_type = TREE_CODE (node) == TYPE_DECL;
|
|
|
|
|
}
|
builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
* builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
* c-common.c (decl_attributes,check_format_info,truthvalue_conversion,
c_get_alias_set): Likewise.
* c-decl.c (duplicate_decls): Likewise.
* c-typeck.c (default_conversion,build_unary_op): Likewise.
* calls.c (initialize_argument_information): Likewise.
* dwarf2out.c (decl_class_context,add_abstract_origin_attribute):
Likewise.
* dwarfout.c (decl_class_context,output_type): Likewise.
* expr.c (get_inner_reference): Likewise.
* fold-const.c (simple_operand_p,fold): Likewise.
* function.c (aggregate_value_p): Likewise.
* stmt.c (expand_asm_operands): Likewise.
* varasm.c (named_section): Likewise.
* call.c (check_dtor_name,build_new_method_call): Likewise.
* decl.c (push_class_binding,poplevel,pushtag,lookup_namespace_name,
make_typename_type,check_initializer,cp_finish_decl,xref_tag): Likewise.
* decl2.c (grokfield,build_expr_from_tree,build_expr_from_tree,
decl_namespace,arg_assoc_template_arg,arg_assoc,
validate_nonmember_using_decl,do_class_using_decl): Likewise.
* error.c (dump_template_argument,dump_expr,cp_file_of,cp_line_of,
args_to_string): Likewise.
* friend.c (is_friend): Likewise.
* lex.c (note_got_semicolon,note_list_got_semicolon,is_global): Likewise.
* method.c (build_overload_nested_name,build_overload_value,
build_qualified_name,build_qualified_name,hack_identifier): Likewise.
* parse.y (typename_sub,typename_sub1): Likewise.
* pt.c (push_inline_template_parms_recursive,check_template_shadow,
process_partial_specialization,convert_template_argument,
template_args_equal,add_pending_template,lookup_template_class,
for_each_template_parm_r,maybe_fold_nontype_arg,
tsubst,instantiate_template,type_unification_real,unify,
instantiate_pending_templates,set_mangled_name_for_template_decl):
Likewise.
* repo.c (repo_get_id,repo_template_used): Likewise.
* search.c (lookup_field_1): Likewise.
* tree.c (walk_tree,get_type_decl,cp_tree_equal,member_p): Likewise.
* xref.c (classname): Likewise.
From-SVN: r32698
2000-03-23 01:41:05 +01:00
|
|
|
|
else if (TYPE_P (node))
|
1995-03-30 15:59:11 +02:00
|
|
|
|
type = node, is_type = 1;
|
1994-05-07 00:32:17 +02:00
|
|
|
|
|
1998-10-01 12:50:15 +02:00
|
|
|
|
#ifdef PRAGMA_INSERT_ATTRIBUTES
|
|
|
|
|
/* If the code in c-pragma.c wants to insert some attributes then
|
|
|
|
|
allow it to do so. Do this before allowing machine back ends to
|
|
|
|
|
insert attributes, so that they have the opportunity to override
|
|
|
|
|
anything done here. */
|
|
|
|
|
PRAGMA_INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes);
|
|
|
|
|
#endif
|
2000-01-03 22:48:49 +01:00
|
|
|
|
|
1998-09-02 11:59:57 +02:00
|
|
|
|
#ifdef INSERT_ATTRIBUTES
|
|
|
|
|
INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes);
|
|
|
|
|
#endif
|
2000-01-03 22:48:49 +01:00
|
|
|
|
|
1995-03-10 03:33:58 +01:00
|
|
|
|
attributes = chainon (prefix_attributes, attributes);
|
1994-02-17 23:48:50 +01:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
for (a = attributes; a; a = TREE_CHAIN (a))
|
1995-03-30 15:59:11 +02:00
|
|
|
|
{
|
|
|
|
|
tree name = TREE_PURPOSE (a);
|
|
|
|
|
tree args = TREE_VALUE (a);
|
|
|
|
|
int i;
|
|
|
|
|
enum attrs id;
|
1998-05-04 22:19:33 +02:00
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
for (i = 0; i < attrtab_idx; i++)
|
|
|
|
|
if (attrtab[i].name == name)
|
|
|
|
|
break;
|
|
|
|
|
|
1995-04-28 03:09:12 +02:00
|
|
|
|
if (i == attrtab_idx)
|
1995-03-30 15:59:11 +02:00
|
|
|
|
{
|
1999-04-13 23:04:06 +02:00
|
|
|
|
if (! valid_machine_attribute (name, args, decl, type)
|
|
|
|
|
&& ! (* valid_lang_attribute) (name, args, decl, type))
|
1995-04-28 03:09:12 +02:00
|
|
|
|
warning ("`%s' attribute directive ignored",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
1996-05-06 22:58:44 +02:00
|
|
|
|
else if (decl != 0)
|
|
|
|
|
type = TREE_TYPE (decl);
|
1995-03-30 15:59:11 +02:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (attrtab[i].decl_req && decl == 0)
|
|
|
|
|
{
|
|
|
|
|
warning ("`%s' attribute does not apply to types",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (list_length (args) < attrtab[i].min
|
|
|
|
|
|| list_length (args) > attrtab[i].max)
|
|
|
|
|
{
|
|
|
|
|
error ("wrong number of arguments specified for `%s' attribute",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
id = attrtab[i].id;
|
|
|
|
|
switch (id)
|
|
|
|
|
{
|
|
|
|
|
case A_PACKED:
|
1995-08-30 01:15:19 +02:00
|
|
|
|
if (is_type)
|
1995-04-26 23:23:10 +02:00
|
|
|
|
TYPE_PACKED (type) = 1;
|
|
|
|
|
else if (TREE_CODE (decl) == FIELD_DECL)
|
1995-03-30 15:59:11 +02:00
|
|
|
|
DECL_PACKED (decl) = 1;
|
|
|
|
|
/* We can't set DECL_PACKED for a VAR_DECL, because the bit is
|
|
|
|
|
used for DECL_REGISTER. It wouldn't mean anything anyway. */
|
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
1995-04-10 14:20:09 +02:00
|
|
|
|
case A_NOCOMMON:
|
|
|
|
|
if (TREE_CODE (decl) == VAR_DECL)
|
|
|
|
|
DECL_COMMON (decl) = 0;
|
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
1996-05-06 20:36:48 +02:00
|
|
|
|
case A_COMMON:
|
|
|
|
|
if (TREE_CODE (decl) == VAR_DECL)
|
|
|
|
|
DECL_COMMON (decl) = 1;
|
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
case A_NORETURN:
|
|
|
|
|
if (TREE_CODE (decl) == FUNCTION_DECL)
|
|
|
|
|
TREE_THIS_VOLATILE (decl) = 1;
|
|
|
|
|
else if (TREE_CODE (type) == POINTER_TYPE
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
|
1998-05-04 22:19:33 +02:00
|
|
|
|
TREE_TYPE (decl) = type
|
1995-03-30 15:59:11 +02:00
|
|
|
|
= build_pointer_type
|
|
|
|
|
(build_type_variant (TREE_TYPE (type),
|
|
|
|
|
TREE_READONLY (TREE_TYPE (type)), 1));
|
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
1999-11-28 21:45:34 +01:00
|
|
|
|
case A_MALLOC:
|
|
|
|
|
if (TREE_CODE (decl) == FUNCTION_DECL)
|
|
|
|
|
DECL_IS_MALLOC (decl) = 1;
|
2000-04-13 15:59:00 +02:00
|
|
|
|
/* ??? TODO: Support types. */
|
1999-11-28 21:45:34 +01:00
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
1995-04-30 13:13:38 +02:00
|
|
|
|
case A_UNUSED:
|
1998-02-05 21:54:49 +01:00
|
|
|
|
if (is_type)
|
2000-05-05 20:16:49 +02:00
|
|
|
|
if (decl)
|
|
|
|
|
TREE_USED (decl) = 1;
|
|
|
|
|
else
|
|
|
|
|
TREE_USED (type) = 1;
|
1998-05-04 22:19:33 +02:00
|
|
|
|
else if (TREE_CODE (decl) == PARM_DECL
|
1998-02-05 21:54:49 +01:00
|
|
|
|
|| TREE_CODE (decl) == VAR_DECL
|
1999-01-04 08:48:37 +01:00
|
|
|
|
|| TREE_CODE (decl) == FUNCTION_DECL
|
|
|
|
|
|| TREE_CODE (decl) == LABEL_DECL)
|
1995-04-30 13:13:38 +02:00
|
|
|
|
TREE_USED (decl) = 1;
|
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
case A_CONST:
|
|
|
|
|
if (TREE_CODE (decl) == FUNCTION_DECL)
|
|
|
|
|
TREE_READONLY (decl) = 1;
|
|
|
|
|
else if (TREE_CODE (type) == POINTER_TYPE
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
|
|
|
|
|
TREE_TYPE (decl) = type
|
|
|
|
|
= build_pointer_type
|
|
|
|
|
(build_type_variant (TREE_TYPE (type), 1,
|
|
|
|
|
TREE_THIS_VOLATILE (TREE_TYPE (type))));
|
|
|
|
|
else
|
|
|
|
|
warning ( "`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
2000-04-13 15:59:00 +02:00
|
|
|
|
case A_PURE:
|
|
|
|
|
if (TREE_CODE (decl) == FUNCTION_DECL)
|
|
|
|
|
DECL_IS_PURE (decl) = 1;
|
|
|
|
|
/* ??? TODO: Support types. */
|
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
case A_T_UNION:
|
1995-08-30 01:15:19 +02:00
|
|
|
|
if (is_type
|
1995-03-30 15:59:11 +02:00
|
|
|
|
&& TREE_CODE (type) == UNION_TYPE
|
1995-08-30 01:15:19 +02:00
|
|
|
|
&& (decl == 0
|
1996-06-10 17:29:39 +02:00
|
|
|
|
|| (TYPE_FIELDS (type) != 0
|
|
|
|
|
&& TYPE_MODE (type) == DECL_MODE (TYPE_FIELDS (type)))))
|
1995-08-30 01:15:19 +02:00
|
|
|
|
TYPE_TRANSPARENT_UNION (type) = 1;
|
|
|
|
|
else if (decl != 0 && TREE_CODE (decl) == PARM_DECL
|
1995-03-30 15:59:11 +02:00
|
|
|
|
&& TREE_CODE (type) == UNION_TYPE
|
|
|
|
|
&& TYPE_MODE (type) == DECL_MODE (TYPE_FIELDS (type)))
|
1995-08-30 01:15:19 +02:00
|
|
|
|
DECL_TRANSPARENT_UNION (decl) = 1;
|
1995-03-30 15:59:11 +02:00
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case A_CONSTRUCTOR:
|
|
|
|
|
if (TREE_CODE (decl) == FUNCTION_DECL
|
|
|
|
|
&& TREE_CODE (type) == FUNCTION_TYPE
|
|
|
|
|
&& decl_function_context (decl) == 0)
|
1995-06-27 22:42:57 +02:00
|
|
|
|
{
|
|
|
|
|
DECL_STATIC_CONSTRUCTOR (decl) = 1;
|
|
|
|
|
TREE_USED (decl) = 1;
|
|
|
|
|
}
|
1995-03-30 15:59:11 +02:00
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case A_DESTRUCTOR:
|
|
|
|
|
if (TREE_CODE (decl) == FUNCTION_DECL
|
|
|
|
|
&& TREE_CODE (type) == FUNCTION_TYPE
|
|
|
|
|
&& decl_function_context (decl) == 0)
|
1995-06-27 22:42:57 +02:00
|
|
|
|
{
|
|
|
|
|
DECL_STATIC_DESTRUCTOR (decl) = 1;
|
|
|
|
|
TREE_USED (decl) = 1;
|
|
|
|
|
}
|
1995-03-30 15:59:11 +02:00
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case A_MODE:
|
|
|
|
|
if (TREE_CODE (TREE_VALUE (args)) != IDENTIFIER_NODE)
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int j;
|
c-aux-info.c (data_type, [...]): Qualify a char* with the `const' keyword.
* c-aux-info.c (data_type, affix_data_type, gen_decl,
gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type):
Qualify a char* with the `const' keyword.
* c-common.c (declare_hidden_char_array, add_attribute, if_elt,
declare_function_name, decl_attributes, format_char_info,
check_format_info, binary_op_error): Likewise.
* cexp.y (yyerror, error, pedwarn, warning, token): Likewise.
* gcse.c (dump_hash_table): Likewise.
* integrate.c (function_cannot_inline_p): Likewise
* optabs.c: Include insn-config.h earlier.
(init_libfuncs, init_integral_libfuncs, init_floating_libfuncs):
Qualify a char* with the `const' keyword.
* real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe,
asctoeg, mtherr, ereal_atof): Likewise.
* real.h (ereal_atof): Likewise.
* sbitmap.c (dump_sbitmap_vector): Likewise.
* sbitmap.h (dump_sbitmap_vector): Likewise.
* stmt.c (nesting, n_occurrences, expand_start_case): Likewise.
* toplev.c (rest_of_compilation): Likewise.
* tree.h (function_cannot_inline_p, expand_start_case): Likewise.
From-SVN: r25614
1999-03-06 06:34:26 +01:00
|
|
|
|
const char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
|
1995-03-30 15:59:11 +02:00
|
|
|
|
int len = strlen (p);
|
|
|
|
|
enum machine_mode mode = VOIDmode;
|
|
|
|
|
tree typefm;
|
|
|
|
|
|
|
|
|
|
if (len > 4 && p[0] == '_' && p[1] == '_'
|
|
|
|
|
&& p[len - 1] == '_' && p[len - 2] == '_')
|
|
|
|
|
{
|
1995-06-05 14:14:46 +02:00
|
|
|
|
char *newp = (char *) alloca (len - 1);
|
1995-03-30 15:59:11 +02:00
|
|
|
|
|
|
|
|
|
strcpy (newp, &p[2]);
|
|
|
|
|
newp[len - 4] = '\0';
|
|
|
|
|
p = newp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Give this decl a type with the specified mode.
|
|
|
|
|
First check for the special modes. */
|
|
|
|
|
if (! strcmp (p, "byte"))
|
|
|
|
|
mode = byte_mode;
|
|
|
|
|
else if (!strcmp (p, "word"))
|
|
|
|
|
mode = word_mode;
|
|
|
|
|
else if (! strcmp (p, "pointer"))
|
|
|
|
|
mode = ptr_mode;
|
|
|
|
|
else
|
|
|
|
|
for (j = 0; j < NUM_MACHINE_MODES; j++)
|
|
|
|
|
if (!strcmp (p, GET_MODE_NAME (j)))
|
|
|
|
|
mode = (enum machine_mode) j;
|
|
|
|
|
|
|
|
|
|
if (mode == VOIDmode)
|
|
|
|
|
error ("unknown machine mode `%s'", p);
|
|
|
|
|
else if (0 == (typefm = type_for_mode (mode,
|
|
|
|
|
TREE_UNSIGNED (type))))
|
|
|
|
|
error ("no data type for mode `%s'", p);
|
|
|
|
|
else
|
|
|
|
|
{
|
tm.texi (INTMAX_TYPE, [...]): Define.
* tm.texi (INTMAX_TYPE, UINTMAX_TYPE): Define.
* c-common.h (enum c_tree_index): Add CTI_INTMAX_TYPE and
CTI_UINTMAX_TYPE.
(intmax_type_node, uintmax_type_node): Define.
* c-common.c (decl_attributes): If pedantic, warn if `mode'
attributes create a type wider than intmax_t.
(T_IM, T_UIM): Define properly.
* c-decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
defined.
(init_decl_processing): Initialize intmax_type_node and
uintmax_type_node.
* c-lex.c (lex_number): When pedantic and warning for integer
constants that are too large, in C99 mode warn for those that have
a type wider than long long.
cp:
* decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
defined.
(init_decl_processing): Initialize intmax_type_node and
uintmax_type_node.
testsuite:
* gcc.dg/c99-printf-1.c, gcc.dg/c99-scanf-1.c,
gcc.dg/c90-printf-2.c, gcc.dg/c90-scanf-2.c: Define intmax_t and
uintmax_t using <limits.h> to emulate the compiler's internal
logic. No longer XFAIL %j tests.
From-SVN: r36791
2000-10-08 23:20:45 +02:00
|
|
|
|
if (TYPE_PRECISION (typefm) > (TREE_UNSIGNED (type)
|
|
|
|
|
? TYPE_PRECISION(uintmax_type_node)
|
|
|
|
|
: TYPE_PRECISION(intmax_type_node))
|
|
|
|
|
&& pedantic)
|
|
|
|
|
pedwarn ("type with more precision than %s",
|
|
|
|
|
TREE_UNSIGNED (type) ? "uintmax_t" : "intmax_t");
|
1995-03-30 15:59:11 +02:00
|
|
|
|
TREE_TYPE (decl) = type = typefm;
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0;
|
1995-03-30 15:59:11 +02:00
|
|
|
|
layout_decl (decl, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case A_SECTION:
|
1994-02-17 23:48:50 +01:00
|
|
|
|
#ifdef ASM_OUTPUT_SECTION_NAME
|
1995-03-30 15:59:11 +02:00
|
|
|
|
if ((TREE_CODE (decl) == FUNCTION_DECL
|
|
|
|
|
|| TREE_CODE (decl) == VAR_DECL)
|
|
|
|
|
&& TREE_CODE (TREE_VALUE (args)) == STRING_CST)
|
|
|
|
|
{
|
1998-05-04 22:19:33 +02:00
|
|
|
|
if (TREE_CODE (decl) == VAR_DECL
|
1996-09-23 03:06:39 +02:00
|
|
|
|
&& current_function_decl != NULL_TREE
|
|
|
|
|
&& ! TREE_STATIC (decl))
|
1995-03-30 15:59:11 +02:00
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"section attribute cannot be specified for local variables");
|
|
|
|
|
/* The decl may have already been given a section attribute from
|
|
|
|
|
a previous declaration. Ensure they match. */
|
|
|
|
|
else if (DECL_SECTION_NAME (decl) != NULL_TREE
|
|
|
|
|
&& strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
|
|
|
|
|
TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
|
|
|
|
|
error_with_decl (node,
|
|
|
|
|
"section of `%s' conflicts with previous declaration");
|
|
|
|
|
else
|
|
|
|
|
DECL_SECTION_NAME (decl) = TREE_VALUE (args);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
error_with_decl (node,
|
1994-02-17 23:48:50 +01:00
|
|
|
|
"section attribute not allowed for `%s'");
|
|
|
|
|
#else
|
1995-03-30 15:59:11 +02:00
|
|
|
|
error_with_decl (node,
|
|
|
|
|
"section attributes are not supported for this target");
|
1994-02-17 23:48:50 +01:00
|
|
|
|
#endif
|
1995-03-30 15:59:11 +02:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case A_ALIGNED:
|
1993-12-24 13:38:37 +01:00
|
|
|
|
{
|
1995-03-30 15:59:11 +02:00
|
|
|
|
tree align_expr
|
1996-01-01 22:15:08 +01:00
|
|
|
|
= (args ? TREE_VALUE (args)
|
|
|
|
|
: size_int (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
|
tree.h (INT_CST_LT, [...]): Remove unneeded casts.
* tree.h (INT_CST_LT, INT_CST_LT_UNSIGNED): Remove unneeded casts.
(struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT.
(attribute_hash_list, type_hash_canon): hashcode is now unsigned.
(type_hash_lookup, type_hash_add, type_hash_list): Likewise.
(min_precision): Result is unsignd.
(add_double, neg_double, mul_double): Low word is unsigned.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double): Likewise.
(tree_floor_log2, compare_tree_int): New functions.
(preserve_rtl_expr_temps): New declaration.
* c-common.c (declare_hidden_char_array): Use compare_tree_int.
(decl_attributes): Use tree_log2 to find alignment.
Check for TREE_INT_CST_HIGH for format args.
(min_precision): Now unsigned.
Use tree_floor_log2.
(truthvalue_conversion): Delete long-disabled code.
* c-decl.c (finish_struct): Clean up tests on field width.
(finish_function): Use compare_tree_int.
* c-pragma.c (handle_pragma_token): Use tree_log2 for alignment.
* c-typeck.c (comptypes): Use tree_int_cst_equal.
(default_conversion, digest_init): Use compare_tree_int.
(build_binary_op): Use integer_all_onesp and compare_tree_int.
Fix type errors in forming masks.
* calls.c (initialize_argument_information): Use compare_tree_int.
* dbxout.c (dbxout_type): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* except.c (expand_eh_region_start_tree): Use compare_tree_int.
* expr.c (is_zeros_p, case INTEGER_CST): Use integer_zerop.
(store_field): Use compare_tree_int.
(expand_expr, case CONSTRUCTOR): Use TYPE_SIZE_UNIT.
(expand_expr, case ARRAY_REF): Use compare_tree_int.
(do_jump, case BIT_AND_EXPR): Use tree_floor_log2.
(do_store_flag): Use compare_tree_int.
* fold-const.c (encode, decode): Low part is always unsigned.
(force_fit_type, add_double, neg_double, mul_double): Likewise.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double, int_const_binop): Likewise.
(fold_convert): Use compare_tree_int.
(operand_equal_p, case INTEGER_CST): Use tree_int_cst_equal.
(invert_truthvalue, case INTEGER_CST): Likewise.
(fold): Use compare_tree_int; add casts for unsigned TREE_INT_CST_LOW.
* mkdeps.c (deps_dummy_targets): Make I unsigned.
* rtl.h (add_double, neg_double, mul_double): Low words are unsigned.
(lshift_double, rshift_double, lrotate_double, rrotate_double):
Likewise.
* stmt.c (expand_decl): Use compare_tree_int and mode_for_size_tree.
(expand_end_case): Use compare_tree_int.
(estimate_case_costs): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* stor-layout.c (mode_for_size_tree): Use compare_tree_int.
(layout_decl): Likewise.
(layout_record, layout_union): Make sizes unsigned.
(layout_type, case VOID_TYPE): TYPE_SIZE must be bitsizetype.
(layout_type, case QUAL_UNION_TYPE): Use compare_tree_int.
* tree.c (struct type_hash): hashcode is unsigned.
(build_type_attribute_variant, type_hash_list): Likewise.
(type_hash_lookup, type_hash_add, type_hash_canon): Likewise.
(attribute_hash_list, build_array_type, build_method_type): Likewise.
(build_complex_type): Likewise.
(real_value_from_int_cst): Remove unneeded casts.
(integer_all_onesp): Add casts.
(tree_floor_log2, compare_tree_int): New functions.
(build_index_type): Use tree_int_cst_sgn.
* varasm.c (assemble_variable): Use compare_tree_int.
* ch/actions.c (chill_convert_for_assignment): INDEX is unsigned
HOST_WIDE_INT.
* ch/ch-tree.h (DECL_NESTING_LEVEL): Use TREE_INT_CST_HIGH
since unsigned.
* ch/except.c (chill_handle_on_labels): ALTERNATIVE is unsigned.
Use compare_tree_int.
(expand_goto_except_cleanup): Likewise.
* cp/class.c (dfs_modify_vtables): I is now unsigned.
(check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
(build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
* cp/init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
* cp/typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
Call integer_all_onesp.
* cp/typeck2.c (process_init_constructor): Use compare_tree_int.
* f/com.c (ffecom_f2c_set_lio_code_): Use compare_tree_int.
(ffecom_sym_transform_, ffecom_transform_common_): Likewise.
(ffecom_transform_equiv_): Likewise.
* java/decl.c (emit_init_test_initialization): Mark KEY as unused.
* java/expr.c (build_newarray): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
(build_anewarray): Likewise.
* java/parse.y (patch_newarray): Likewise.
* java/parse.c: Regenerated.
From-SVN: r32383
2000-03-07 12:41:32 +01:00
|
|
|
|
int i;
|
2000-01-03 22:48:49 +01:00
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
/* Strip any NOPs of any kind. */
|
|
|
|
|
while (TREE_CODE (align_expr) == NOP_EXPR
|
|
|
|
|
|| TREE_CODE (align_expr) == CONVERT_EXPR
|
|
|
|
|
|| TREE_CODE (align_expr) == NON_LVALUE_EXPR)
|
|
|
|
|
align_expr = TREE_OPERAND (align_expr, 0);
|
1998-05-04 22:19:33 +02:00
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
if (TREE_CODE (align_expr) != INTEGER_CST)
|
|
|
|
|
{
|
|
|
|
|
error ("requested alignment is not a constant");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
tree.h (INT_CST_LT, [...]): Remove unneeded casts.
* tree.h (INT_CST_LT, INT_CST_LT_UNSIGNED): Remove unneeded casts.
(struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT.
(attribute_hash_list, type_hash_canon): hashcode is now unsigned.
(type_hash_lookup, type_hash_add, type_hash_list): Likewise.
(min_precision): Result is unsignd.
(add_double, neg_double, mul_double): Low word is unsigned.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double): Likewise.
(tree_floor_log2, compare_tree_int): New functions.
(preserve_rtl_expr_temps): New declaration.
* c-common.c (declare_hidden_char_array): Use compare_tree_int.
(decl_attributes): Use tree_log2 to find alignment.
Check for TREE_INT_CST_HIGH for format args.
(min_precision): Now unsigned.
Use tree_floor_log2.
(truthvalue_conversion): Delete long-disabled code.
* c-decl.c (finish_struct): Clean up tests on field width.
(finish_function): Use compare_tree_int.
* c-pragma.c (handle_pragma_token): Use tree_log2 for alignment.
* c-typeck.c (comptypes): Use tree_int_cst_equal.
(default_conversion, digest_init): Use compare_tree_int.
(build_binary_op): Use integer_all_onesp and compare_tree_int.
Fix type errors in forming masks.
* calls.c (initialize_argument_information): Use compare_tree_int.
* dbxout.c (dbxout_type): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* except.c (expand_eh_region_start_tree): Use compare_tree_int.
* expr.c (is_zeros_p, case INTEGER_CST): Use integer_zerop.
(store_field): Use compare_tree_int.
(expand_expr, case CONSTRUCTOR): Use TYPE_SIZE_UNIT.
(expand_expr, case ARRAY_REF): Use compare_tree_int.
(do_jump, case BIT_AND_EXPR): Use tree_floor_log2.
(do_store_flag): Use compare_tree_int.
* fold-const.c (encode, decode): Low part is always unsigned.
(force_fit_type, add_double, neg_double, mul_double): Likewise.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double, int_const_binop): Likewise.
(fold_convert): Use compare_tree_int.
(operand_equal_p, case INTEGER_CST): Use tree_int_cst_equal.
(invert_truthvalue, case INTEGER_CST): Likewise.
(fold): Use compare_tree_int; add casts for unsigned TREE_INT_CST_LOW.
* mkdeps.c (deps_dummy_targets): Make I unsigned.
* rtl.h (add_double, neg_double, mul_double): Low words are unsigned.
(lshift_double, rshift_double, lrotate_double, rrotate_double):
Likewise.
* stmt.c (expand_decl): Use compare_tree_int and mode_for_size_tree.
(expand_end_case): Use compare_tree_int.
(estimate_case_costs): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* stor-layout.c (mode_for_size_tree): Use compare_tree_int.
(layout_decl): Likewise.
(layout_record, layout_union): Make sizes unsigned.
(layout_type, case VOID_TYPE): TYPE_SIZE must be bitsizetype.
(layout_type, case QUAL_UNION_TYPE): Use compare_tree_int.
* tree.c (struct type_hash): hashcode is unsigned.
(build_type_attribute_variant, type_hash_list): Likewise.
(type_hash_lookup, type_hash_add, type_hash_canon): Likewise.
(attribute_hash_list, build_array_type, build_method_type): Likewise.
(build_complex_type): Likewise.
(real_value_from_int_cst): Remove unneeded casts.
(integer_all_onesp): Add casts.
(tree_floor_log2, compare_tree_int): New functions.
(build_index_type): Use tree_int_cst_sgn.
* varasm.c (assemble_variable): Use compare_tree_int.
* ch/actions.c (chill_convert_for_assignment): INDEX is unsigned
HOST_WIDE_INT.
* ch/ch-tree.h (DECL_NESTING_LEVEL): Use TREE_INT_CST_HIGH
since unsigned.
* ch/except.c (chill_handle_on_labels): ALTERNATIVE is unsigned.
Use compare_tree_int.
(expand_goto_except_cleanup): Likewise.
* cp/class.c (dfs_modify_vtables): I is now unsigned.
(check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
(build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
* cp/init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
* cp/typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
Call integer_all_onesp.
* cp/typeck2.c (process_init_constructor): Use compare_tree_int.
* f/com.c (ffecom_f2c_set_lio_code_): Use compare_tree_int.
(ffecom_sym_transform_, ffecom_transform_common_): Likewise.
(ffecom_transform_equiv_): Likewise.
* java/decl.c (emit_init_test_initialization): Mark KEY as unused.
* java/expr.c (build_newarray): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
(build_anewarray): Likewise.
* java/parse.y (patch_newarray): Likewise.
* java/parse.c: Regenerated.
From-SVN: r32383
2000-03-07 12:41:32 +01:00
|
|
|
|
if ((i = tree_log2 (align_expr)) == -1)
|
1995-03-30 15:59:11 +02:00
|
|
|
|
error ("requested alignment is not a power of 2");
|
tree.h (INT_CST_LT, [...]): Remove unneeded casts.
* tree.h (INT_CST_LT, INT_CST_LT_UNSIGNED): Remove unneeded casts.
(struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT.
(attribute_hash_list, type_hash_canon): hashcode is now unsigned.
(type_hash_lookup, type_hash_add, type_hash_list): Likewise.
(min_precision): Result is unsignd.
(add_double, neg_double, mul_double): Low word is unsigned.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double): Likewise.
(tree_floor_log2, compare_tree_int): New functions.
(preserve_rtl_expr_temps): New declaration.
* c-common.c (declare_hidden_char_array): Use compare_tree_int.
(decl_attributes): Use tree_log2 to find alignment.
Check for TREE_INT_CST_HIGH for format args.
(min_precision): Now unsigned.
Use tree_floor_log2.
(truthvalue_conversion): Delete long-disabled code.
* c-decl.c (finish_struct): Clean up tests on field width.
(finish_function): Use compare_tree_int.
* c-pragma.c (handle_pragma_token): Use tree_log2 for alignment.
* c-typeck.c (comptypes): Use tree_int_cst_equal.
(default_conversion, digest_init): Use compare_tree_int.
(build_binary_op): Use integer_all_onesp and compare_tree_int.
Fix type errors in forming masks.
* calls.c (initialize_argument_information): Use compare_tree_int.
* dbxout.c (dbxout_type): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* except.c (expand_eh_region_start_tree): Use compare_tree_int.
* expr.c (is_zeros_p, case INTEGER_CST): Use integer_zerop.
(store_field): Use compare_tree_int.
(expand_expr, case CONSTRUCTOR): Use TYPE_SIZE_UNIT.
(expand_expr, case ARRAY_REF): Use compare_tree_int.
(do_jump, case BIT_AND_EXPR): Use tree_floor_log2.
(do_store_flag): Use compare_tree_int.
* fold-const.c (encode, decode): Low part is always unsigned.
(force_fit_type, add_double, neg_double, mul_double): Likewise.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double, int_const_binop): Likewise.
(fold_convert): Use compare_tree_int.
(operand_equal_p, case INTEGER_CST): Use tree_int_cst_equal.
(invert_truthvalue, case INTEGER_CST): Likewise.
(fold): Use compare_tree_int; add casts for unsigned TREE_INT_CST_LOW.
* mkdeps.c (deps_dummy_targets): Make I unsigned.
* rtl.h (add_double, neg_double, mul_double): Low words are unsigned.
(lshift_double, rshift_double, lrotate_double, rrotate_double):
Likewise.
* stmt.c (expand_decl): Use compare_tree_int and mode_for_size_tree.
(expand_end_case): Use compare_tree_int.
(estimate_case_costs): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* stor-layout.c (mode_for_size_tree): Use compare_tree_int.
(layout_decl): Likewise.
(layout_record, layout_union): Make sizes unsigned.
(layout_type, case VOID_TYPE): TYPE_SIZE must be bitsizetype.
(layout_type, case QUAL_UNION_TYPE): Use compare_tree_int.
* tree.c (struct type_hash): hashcode is unsigned.
(build_type_attribute_variant, type_hash_list): Likewise.
(type_hash_lookup, type_hash_add, type_hash_canon): Likewise.
(attribute_hash_list, build_array_type, build_method_type): Likewise.
(build_complex_type): Likewise.
(real_value_from_int_cst): Remove unneeded casts.
(integer_all_onesp): Add casts.
(tree_floor_log2, compare_tree_int): New functions.
(build_index_type): Use tree_int_cst_sgn.
* varasm.c (assemble_variable): Use compare_tree_int.
* ch/actions.c (chill_convert_for_assignment): INDEX is unsigned
HOST_WIDE_INT.
* ch/ch-tree.h (DECL_NESTING_LEVEL): Use TREE_INT_CST_HIGH
since unsigned.
* ch/except.c (chill_handle_on_labels): ALTERNATIVE is unsigned.
Use compare_tree_int.
(expand_goto_except_cleanup): Likewise.
* cp/class.c (dfs_modify_vtables): I is now unsigned.
(check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
(build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
* cp/init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
* cp/typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
Call integer_all_onesp.
* cp/typeck2.c (process_init_constructor): Use compare_tree_int.
* f/com.c (ffecom_f2c_set_lio_code_): Use compare_tree_int.
(ffecom_sym_transform_, ffecom_transform_common_): Likewise.
(ffecom_transform_equiv_): Likewise.
* java/decl.c (emit_init_test_initialization): Mark KEY as unused.
* java/expr.c (build_newarray): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
(build_anewarray): Likewise.
* java/parse.y (patch_newarray): Likewise.
* java/parse.c: Regenerated.
From-SVN: r32383
2000-03-07 12:41:32 +01:00
|
|
|
|
else if (i > HOST_BITS_PER_INT - 2)
|
|
|
|
|
error ("requested alignment is too large");
|
1995-03-30 15:59:11 +02:00
|
|
|
|
else if (is_type)
|
2000-06-14 07:30:09 +02:00
|
|
|
|
{
|
2000-08-25 01:48:25 +02:00
|
|
|
|
/* If we have a TYPE_DECL, then copy the type, so that we
|
|
|
|
|
don't accidentally modify a builtin type. See pushdecl. */
|
|
|
|
|
if (decl && TREE_TYPE (decl) != error_mark_node
|
|
|
|
|
&& DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
|
2000-06-30 16:59:10 +02:00
|
|
|
|
{
|
2000-08-25 01:48:25 +02:00
|
|
|
|
tree tt = TREE_TYPE (decl);
|
|
|
|
|
DECL_ORIGINAL_TYPE (decl) = tt;
|
|
|
|
|
tt = build_type_copy (tt);
|
|
|
|
|
TYPE_NAME (tt) = decl;
|
|
|
|
|
TREE_USED (tt) = TREE_USED (decl);
|
|
|
|
|
TREE_TYPE (decl) = tt;
|
|
|
|
|
type = tt;
|
2000-06-30 16:59:10 +02:00
|
|
|
|
}
|
2000-08-25 01:48:25 +02:00
|
|
|
|
|
|
|
|
|
TYPE_ALIGN (type) = (1 << i) * BITS_PER_UNIT;
|
|
|
|
|
TYPE_USER_ALIGN (type) = 1;
|
2000-06-14 07:30:09 +02:00
|
|
|
|
}
|
1995-03-30 15:59:11 +02:00
|
|
|
|
else if (TREE_CODE (decl) != VAR_DECL
|
|
|
|
|
&& TREE_CODE (decl) != FIELD_DECL)
|
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"alignment may not be specified for `%s'");
|
|
|
|
|
else
|
2000-06-14 07:30:09 +02:00
|
|
|
|
{
|
|
|
|
|
DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
|
|
|
|
|
DECL_USER_ALIGN (decl) = 1;
|
|
|
|
|
}
|
1993-12-24 13:38:37 +01:00
|
|
|
|
}
|
1995-03-30 15:59:11 +02:00
|
|
|
|
break;
|
1993-12-24 13:38:37 +01:00
|
|
|
|
|
1995-03-30 15:59:11 +02:00
|
|
|
|
case A_FORMAT:
|
2001-01-14 00:30:02 +01:00
|
|
|
|
decl_handle_format_attribute (decl, args);
|
|
|
|
|
break;
|
1995-04-16 08:14:00 +02:00
|
|
|
|
|
1996-06-08 19:35:57 +02:00
|
|
|
|
case A_FORMAT_ARG:
|
2001-01-14 00:30:02 +01:00
|
|
|
|
decl_handle_format_arg_attribute (decl, args);
|
|
|
|
|
break;
|
1996-06-08 19:35:57 +02:00
|
|
|
|
|
1995-04-16 08:14:00 +02:00
|
|
|
|
case A_WEAK:
|
|
|
|
|
declare_weak (decl);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case A_ALIAS:
|
|
|
|
|
if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
|
1996-11-15 18:11:24 +01:00
|
|
|
|
|| (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
|
1995-04-16 08:14:00 +02:00
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"`%s' defined both normally and as an alias");
|
|
|
|
|
else if (decl_function_context (decl) == 0)
|
|
|
|
|
{
|
1998-08-18 14:40:52 +02:00
|
|
|
|
tree id;
|
|
|
|
|
|
|
|
|
|
id = TREE_VALUE (args);
|
|
|
|
|
if (TREE_CODE (id) != STRING_CST)
|
|
|
|
|
{
|
|
|
|
|
error ("alias arg not a string");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
id = get_identifier (TREE_STRING_POINTER (id));
|
2000-04-20 18:09:27 +02:00
|
|
|
|
/* This counts as a use of the object pointed to. */
|
|
|
|
|
TREE_USED (id) = 1;
|
1998-08-18 14:40:52 +02:00
|
|
|
|
|
1995-04-16 08:14:00 +02:00
|
|
|
|
if (TREE_CODE (decl) == FUNCTION_DECL)
|
|
|
|
|
DECL_INITIAL (decl) = error_mark_node;
|
|
|
|
|
else
|
|
|
|
|
DECL_EXTERNAL (decl) = 0;
|
|
|
|
|
assemble_alias (decl, id);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
|
|
|
|
break;
|
1998-07-30 12:38:22 +02:00
|
|
|
|
|
1998-10-11 04:21:54 +02:00
|
|
|
|
case A_NO_CHECK_MEMORY_USAGE:
|
|
|
|
|
if (TREE_CODE (decl) != FUNCTION_DECL)
|
|
|
|
|
{
|
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"`%s' attribute applies only to functions",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
}
|
|
|
|
|
else if (DECL_INITIAL (decl))
|
|
|
|
|
{
|
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"can't set `%s' attribute after definition",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
DECL_NO_CHECK_MEMORY_USAGE (decl) = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
1998-07-30 12:38:22 +02:00
|
|
|
|
case A_NO_INSTRUMENT_FUNCTION:
|
|
|
|
|
if (TREE_CODE (decl) != FUNCTION_DECL)
|
|
|
|
|
{
|
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"`%s' attribute applies only to functions",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
}
|
|
|
|
|
else if (DECL_INITIAL (decl))
|
|
|
|
|
{
|
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"can't set `%s' attribute after definition",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
|
|
|
|
|
break;
|
1999-12-04 04:00:04 +01:00
|
|
|
|
|
|
|
|
|
case A_NO_LIMIT_STACK:
|
|
|
|
|
if (TREE_CODE (decl) != FUNCTION_DECL)
|
|
|
|
|
{
|
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"`%s' attribute applies only to functions",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
}
|
|
|
|
|
else if (DECL_INITIAL (decl))
|
|
|
|
|
{
|
|
|
|
|
error_with_decl (decl,
|
|
|
|
|
"can't set `%s' attribute after definition",
|
|
|
|
|
IDENTIFIER_POINTER (name));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
DECL_NO_LIMIT_STACK (decl) = 1;
|
|
|
|
|
break;
|
1995-03-30 15:59:11 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
1996-10-09 13:35:43 +02:00
|
|
|
|
|
|
|
|
|
/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
|
|
|
|
|
lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
|
|
|
|
|
|
|
|
|
|
The head of the declspec list is stored in DECLSPECS.
|
|
|
|
|
The head of the attribute list is stored in PREFIX_ATTRIBUTES.
|
|
|
|
|
|
|
|
|
|
Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
|
|
|
|
|
the list elements. We drop the containing TREE_LIST nodes and link the
|
|
|
|
|
resulting attributes together the way decl_attributes expects them. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
|
|
|
|
|
tree specs_attrs;
|
|
|
|
|
tree *declspecs, *prefix_attributes;
|
|
|
|
|
{
|
|
|
|
|
tree t, s, a, next, specs, attrs;
|
|
|
|
|
|
2000-01-18 01:01:06 +01:00
|
|
|
|
/* This can happen after an __extension__ in pedantic mode. */
|
|
|
|
|
if (specs_attrs != NULL_TREE
|
|
|
|
|
&& TREE_CODE (specs_attrs) == INTEGER_CST)
|
|
|
|
|
{
|
|
|
|
|
*declspecs = NULL_TREE;
|
|
|
|
|
*prefix_attributes = NULL_TREE;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
1996-10-09 13:35:43 +02:00
|
|
|
|
/* This can happen in c++ (eg: decl: typespec initdecls ';'). */
|
|
|
|
|
if (specs_attrs != NULL_TREE
|
|
|
|
|
&& TREE_CODE (specs_attrs) != TREE_LIST)
|
|
|
|
|
{
|
|
|
|
|
*declspecs = specs_attrs;
|
|
|
|
|
*prefix_attributes = NULL_TREE;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remember to keep the lists in the same order, element-wise. */
|
|
|
|
|
|
|
|
|
|
specs = s = NULL_TREE;
|
|
|
|
|
attrs = a = NULL_TREE;
|
|
|
|
|
for (t = specs_attrs; t; t = next)
|
|
|
|
|
{
|
|
|
|
|
next = TREE_CHAIN (t);
|
|
|
|
|
/* Declspecs have a non-NULL TREE_VALUE. */
|
|
|
|
|
if (TREE_VALUE (t) != NULL_TREE)
|
|
|
|
|
{
|
|
|
|
|
if (specs == NULL_TREE)
|
|
|
|
|
specs = s = t;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TREE_CHAIN (s) = t;
|
|
|
|
|
s = t;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (attrs == NULL_TREE)
|
|
|
|
|
attrs = a = TREE_PURPOSE (t);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TREE_CHAIN (a) = TREE_PURPOSE (t);
|
|
|
|
|
a = TREE_PURPOSE (t);
|
|
|
|
|
}
|
|
|
|
|
/* More attrs can be linked here, move A to the end. */
|
|
|
|
|
while (TREE_CHAIN (a) != NULL_TREE)
|
|
|
|
|
a = TREE_CHAIN (a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Terminate the lists. */
|
|
|
|
|
if (s != NULL_TREE)
|
|
|
|
|
TREE_CHAIN (s) = NULL_TREE;
|
|
|
|
|
if (a != NULL_TREE)
|
|
|
|
|
TREE_CHAIN (a) = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* All done. */
|
|
|
|
|
*declspecs = specs;
|
|
|
|
|
*prefix_attributes = attrs;
|
|
|
|
|
}
|
1998-02-18 11:38:57 +01:00
|
|
|
|
|
|
|
|
|
/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
|
|
|
|
|
This function is used by the parser when a rule will accept attributes
|
|
|
|
|
in a particular position, but we don't want to support that just yet.
|
|
|
|
|
|
|
|
|
|
A warning is issued for every ignored attribute. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
strip_attrs (specs_attrs)
|
|
|
|
|
tree specs_attrs;
|
|
|
|
|
{
|
|
|
|
|
tree specs, attrs;
|
|
|
|
|
|
|
|
|
|
split_specs_attrs (specs_attrs, &specs, &attrs);
|
|
|
|
|
|
|
|
|
|
while (attrs)
|
|
|
|
|
{
|
|
|
|
|
warning ("`%s' attribute ignored",
|
|
|
|
|
IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
|
|
|
|
|
attrs = TREE_CHAIN (attrs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return specs;
|
|
|
|
|
}
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
2000-10-06 16:59:56 +02:00
|
|
|
|
static int is_valid_printf_arglist PARAMS ((tree));
|
2000-10-13 21:28:07 +02:00
|
|
|
|
static rtx c_expand_builtin PARAMS ((tree, rtx, enum machine_mode, enum expand_modifier));
|
2000-10-06 16:59:56 +02:00
|
|
|
|
static rtx c_expand_builtin_printf PARAMS ((tree, rtx, enum machine_mode,
|
|
|
|
|
enum expand_modifier, int));
|
2001-01-08 00:15:47 +01:00
|
|
|
|
static rtx c_expand_builtin_fprintf PARAMS ((tree, rtx, enum machine_mode,
|
|
|
|
|
enum expand_modifier, int));
|
1993-10-05 20:14:50 +01:00
|
|
|
|
|
1993-02-02 05:40:43 +01:00
|
|
|
|
/* Print a warning if a constant expression had overflow in folding.
|
|
|
|
|
Invoke this function on every expression that the language
|
|
|
|
|
requires to be a constant expression.
|
|
|
|
|
Note the ANSI C standard says it is erroneous for a
|
|
|
|
|
constant expression to overflow. */
|
1992-09-08 01:42:39 +02:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
constant_expression_warning (value)
|
|
|
|
|
tree value;
|
|
|
|
|
{
|
1994-03-13 14:31:27 +01:00
|
|
|
|
if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
|
|
|
|
|
|| TREE_CODE (value) == COMPLEX_CST)
|
|
|
|
|
&& TREE_CONSTANT_OVERFLOW (value) && pedantic)
|
|
|
|
|
pedwarn ("overflow in constant expression");
|
1993-02-02 05:40:43 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Print a warning if an expression had overflow in folding.
|
|
|
|
|
Invoke this function on every expression that
|
|
|
|
|
(1) appears in the source code, and
|
|
|
|
|
(2) might be a constant expression that overflowed, and
|
|
|
|
|
(3) is not already checked by convert_and_check;
|
|
|
|
|
however, do not invoke this function on operands of explicit casts. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
overflow_warning (value)
|
|
|
|
|
tree value;
|
|
|
|
|
{
|
1994-03-13 14:31:27 +01:00
|
|
|
|
if ((TREE_CODE (value) == INTEGER_CST
|
|
|
|
|
|| (TREE_CODE (value) == COMPLEX_CST
|
|
|
|
|
&& TREE_CODE (TREE_REALPART (value)) == INTEGER_CST))
|
|
|
|
|
&& TREE_OVERFLOW (value))
|
1993-02-02 05:40:43 +01:00
|
|
|
|
{
|
1993-07-02 03:26:01 +02:00
|
|
|
|
TREE_OVERFLOW (value) = 0;
|
1996-12-07 23:51:24 +01:00
|
|
|
|
if (skip_evaluation == 0)
|
|
|
|
|
warning ("integer overflow in expression");
|
1993-02-02 05:40:43 +01:00
|
|
|
|
}
|
1994-03-13 14:31:27 +01:00
|
|
|
|
else if ((TREE_CODE (value) == REAL_CST
|
|
|
|
|
|| (TREE_CODE (value) == COMPLEX_CST
|
|
|
|
|
&& TREE_CODE (TREE_REALPART (value)) == REAL_CST))
|
|
|
|
|
&& TREE_OVERFLOW (value))
|
|
|
|
|
{
|
|
|
|
|
TREE_OVERFLOW (value) = 0;
|
1996-12-07 23:51:24 +01:00
|
|
|
|
if (skip_evaluation == 0)
|
|
|
|
|
warning ("floating point overflow in expression");
|
1994-03-13 14:31:27 +01:00
|
|
|
|
}
|
1993-02-02 05:40:43 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Print a warning if a large constant is truncated to unsigned,
|
|
|
|
|
or if -Wconversion is used and a constant < 0 is converted to unsigned.
|
|
|
|
|
Invoke this function on every expression that might be implicitly
|
|
|
|
|
converted to an unsigned type. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
unsigned_conversion_warning (result, operand)
|
|
|
|
|
tree result, operand;
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (operand) == INTEGER_CST
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
|
|
|
|
|
&& TREE_UNSIGNED (TREE_TYPE (result))
|
1996-12-07 23:51:24 +01:00
|
|
|
|
&& skip_evaluation == 0
|
1993-02-02 05:40:43 +01:00
|
|
|
|
&& !int_fits_type_p (operand, TREE_TYPE (result)))
|
|
|
|
|
{
|
|
|
|
|
if (!int_fits_type_p (operand, signed_type (TREE_TYPE (result))))
|
|
|
|
|
/* This detects cases like converting -129 or 256 to unsigned char. */
|
1993-07-12 23:10:27 +02:00
|
|
|
|
warning ("large integer implicitly truncated to unsigned type");
|
1993-02-02 05:40:43 +01:00
|
|
|
|
else if (warn_conversion)
|
1993-07-12 23:10:27 +02:00
|
|
|
|
warning ("negative integer implicitly converted to unsigned type");
|
1993-02-02 05:40:43 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-12 09:34:30 +01:00
|
|
|
|
/* Nonzero if constant C has a value that is permissible
|
|
|
|
|
for type TYPE (an INTEGER_TYPE). */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
constant_fits_type_p (c, type)
|
|
|
|
|
tree c, type;
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (c) == INTEGER_CST)
|
|
|
|
|
return int_fits_type_p (c, type);
|
|
|
|
|
|
|
|
|
|
c = convert (type, c);
|
|
|
|
|
return !TREE_OVERFLOW (c);
|
|
|
|
|
}
|
|
|
|
|
|
1993-02-02 05:40:43 +01:00
|
|
|
|
/* Convert EXPR to TYPE, warning about conversion problems with constants.
|
|
|
|
|
Invoke this function on every expression that is converted implicitly,
|
|
|
|
|
i.e. because of language rules and not because of an explicit cast. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
convert_and_check (type, expr)
|
|
|
|
|
tree type, expr;
|
|
|
|
|
{
|
|
|
|
|
tree t = convert (type, expr);
|
|
|
|
|
if (TREE_CODE (t) == INTEGER_CST)
|
|
|
|
|
{
|
1993-07-02 03:26:01 +02:00
|
|
|
|
if (TREE_OVERFLOW (t))
|
1993-02-02 05:40:43 +01:00
|
|
|
|
{
|
1993-07-02 03:26:01 +02:00
|
|
|
|
TREE_OVERFLOW (t) = 0;
|
|
|
|
|
|
1995-05-12 00:48:51 +02:00
|
|
|
|
/* Do not diagnose overflow in a constant expression merely
|
|
|
|
|
because a conversion overflowed. */
|
|
|
|
|
TREE_CONSTANT_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (expr);
|
|
|
|
|
|
1993-07-02 03:26:01 +02:00
|
|
|
|
/* No warning for converting 0x80000000 to int. */
|
|
|
|
|
if (!(TREE_UNSIGNED (type) < TREE_UNSIGNED (TREE_TYPE (expr))
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
|
|
|
|
|
&& TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr))))
|
1993-10-30 09:34:05 +01:00
|
|
|
|
/* If EXPR fits in the unsigned version of TYPE,
|
|
|
|
|
don't warn unless pedantic. */
|
1996-12-07 23:51:24 +01:00
|
|
|
|
if ((pedantic
|
|
|
|
|
|| TREE_UNSIGNED (type)
|
2001-02-12 09:34:30 +01:00
|
|
|
|
|| ! constant_fits_type_p (expr, unsigned_type (type)))
|
1996-12-07 23:51:24 +01:00
|
|
|
|
&& skip_evaluation == 0)
|
1998-04-12 21:52:16 +02:00
|
|
|
|
warning ("overflow in implicit constant conversion");
|
1993-02-02 05:40:43 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
unsigned_conversion_warning (t, expr);
|
|
|
|
|
}
|
|
|
|
|
return t;
|
1992-09-08 01:42:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
/* A node in a list that describes references to variables (EXPR), which are
|
|
|
|
|
either read accesses if WRITER is zero, or write accesses, in which case
|
|
|
|
|
WRITER is the parent of EXPR. */
|
|
|
|
|
struct tlist
|
|
|
|
|
{
|
|
|
|
|
struct tlist *next;
|
|
|
|
|
tree expr, writer;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Used to implement a cache the results of a call to verify_tree. We only
|
|
|
|
|
use this for SAVE_EXPRs. */
|
|
|
|
|
struct tlist_cache
|
|
|
|
|
{
|
|
|
|
|
struct tlist_cache *next;
|
|
|
|
|
struct tlist *cache_before_sp;
|
|
|
|
|
struct tlist *cache_after_sp;
|
|
|
|
|
tree expr;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
};
|
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
/* Obstack to use when allocating tlist structures, and corresponding
|
|
|
|
|
firstobj. */
|
|
|
|
|
static struct obstack tlist_obstack;
|
|
|
|
|
static char *tlist_firstobj = 0;
|
|
|
|
|
|
|
|
|
|
/* Keep track of the identifiers we've warned about, so we can avoid duplicate
|
|
|
|
|
warnings. */
|
|
|
|
|
static struct tlist *warned_ids;
|
|
|
|
|
/* SAVE_EXPRs need special treatment. We process them only once and then
|
|
|
|
|
cache the results. */
|
|
|
|
|
static struct tlist_cache *save_expr_cache;
|
|
|
|
|
|
|
|
|
|
static void add_tlist PARAMS ((struct tlist **, struct tlist *, tree, int));
|
|
|
|
|
static void merge_tlist PARAMS ((struct tlist **, struct tlist *, int));
|
|
|
|
|
static void verify_tree PARAMS ((tree, struct tlist **, struct tlist **, tree));
|
|
|
|
|
static int warning_candidate_p PARAMS ((tree));
|
|
|
|
|
static void warn_for_collisions PARAMS ((struct tlist *));
|
|
|
|
|
static void warn_for_collisions_1 PARAMS ((tree, tree, struct tlist *, int));
|
|
|
|
|
static struct tlist *new_tlist PARAMS ((struct tlist *, tree, tree));
|
2000-10-17 11:34:21 +02:00
|
|
|
|
static void verify_sequence_points PARAMS ((tree));
|
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
/* Create a new struct tlist and fill in its fields. */
|
|
|
|
|
static struct tlist *
|
|
|
|
|
new_tlist (next, t, writer)
|
|
|
|
|
struct tlist *next;
|
|
|
|
|
tree t;
|
|
|
|
|
tree writer;
|
|
|
|
|
{
|
|
|
|
|
struct tlist *l;
|
|
|
|
|
l = (struct tlist *) obstack_alloc (&tlist_obstack, sizeof *l);
|
|
|
|
|
l->next = next;
|
|
|
|
|
l->expr = t;
|
|
|
|
|
l->writer = writer;
|
|
|
|
|
return l;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add duplicates of the nodes found in ADD to the list *TO. If EXCLUDE_WRITER
|
|
|
|
|
is nonnull, we ignore any node we find which has a writer equal to it. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
add_tlist (to, add, exclude_writer, copy)
|
|
|
|
|
struct tlist **to;
|
|
|
|
|
struct tlist *add;
|
|
|
|
|
tree exclude_writer;
|
|
|
|
|
int copy;
|
|
|
|
|
{
|
|
|
|
|
while (add)
|
|
|
|
|
{
|
|
|
|
|
struct tlist *next = add->next;
|
|
|
|
|
if (! copy)
|
|
|
|
|
add->next = *to;
|
|
|
|
|
if (! exclude_writer || add->writer != exclude_writer)
|
|
|
|
|
*to = copy ? new_tlist (*to, add->expr, add->writer) : add;
|
|
|
|
|
add = next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Merge the nodes of ADD into TO. This merging process is done so that for
|
|
|
|
|
each variable that already exists in TO, no new node is added; however if
|
|
|
|
|
there is a write access recorded in ADD, and an occurrence on TO is only
|
|
|
|
|
a read access, then the occurrence in TO will be modified to record the
|
|
|
|
|
write. */
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
|
|
|
|
static void
|
2000-11-24 12:49:46 +01:00
|
|
|
|
merge_tlist (to, add, copy)
|
|
|
|
|
struct tlist **to;
|
|
|
|
|
struct tlist *add;
|
|
|
|
|
int copy;
|
|
|
|
|
{
|
|
|
|
|
struct tlist **end = to;
|
|
|
|
|
|
|
|
|
|
while (*end)
|
|
|
|
|
end = &(*end)->next;
|
|
|
|
|
|
|
|
|
|
while (add)
|
|
|
|
|
{
|
|
|
|
|
int found = 0;
|
|
|
|
|
struct tlist *tmp2;
|
|
|
|
|
struct tlist *next = add->next;
|
|
|
|
|
|
|
|
|
|
for (tmp2 = *to; tmp2; tmp2 = tmp2->next)
|
|
|
|
|
if (tmp2->expr == add->expr)
|
|
|
|
|
{
|
|
|
|
|
found = 1;
|
|
|
|
|
if (! tmp2->writer)
|
|
|
|
|
tmp2->writer = add->writer;
|
|
|
|
|
}
|
|
|
|
|
if (! found)
|
|
|
|
|
{
|
|
|
|
|
*end = copy ? add : new_tlist (NULL, add->expr, add->writer);
|
|
|
|
|
end = &(*end)->next;
|
|
|
|
|
*end = 0;
|
|
|
|
|
}
|
|
|
|
|
add = next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* WRITTEN is a variable, WRITER is its parent. Warn if any of the variable
|
|
|
|
|
references in list LIST conflict with it, excluding reads if ONLY writers
|
|
|
|
|
is nonzero. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
warn_for_collisions_1 (written, writer, list, only_writes)
|
|
|
|
|
tree written, writer;
|
|
|
|
|
struct tlist *list;
|
|
|
|
|
int only_writes;
|
|
|
|
|
{
|
|
|
|
|
struct tlist *tmp;
|
|
|
|
|
|
|
|
|
|
/* Avoid duplicate warnings. */
|
|
|
|
|
for (tmp = warned_ids; tmp; tmp = tmp->next)
|
|
|
|
|
if (tmp->expr == written)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
if (list->expr == written
|
|
|
|
|
&& list->writer != writer
|
|
|
|
|
&& (! only_writes || list->writer))
|
|
|
|
|
{
|
|
|
|
|
warned_ids = new_tlist (warned_ids, written, NULL_TREE);
|
|
|
|
|
warning ("operation on `%s' may be undefined",
|
|
|
|
|
IDENTIFIER_POINTER (DECL_NAME (list->expr)));
|
|
|
|
|
}
|
|
|
|
|
list = list->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Given a list LIST of references to variables, find whether any of these
|
|
|
|
|
can cause conflicts due to missing sequence points. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
warn_for_collisions (list)
|
|
|
|
|
struct tlist *list;
|
|
|
|
|
{
|
|
|
|
|
struct tlist *tmp;
|
|
|
|
|
|
|
|
|
|
for (tmp = list; tmp; tmp = tmp->next)
|
|
|
|
|
{
|
|
|
|
|
if (tmp->writer)
|
|
|
|
|
warn_for_collisions_1 (tmp->expr, tmp->writer, list, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return nonzero if X is a tree that can be verified by the sequence poitn
|
|
|
|
|
warnings. */
|
|
|
|
|
static int
|
|
|
|
|
warning_candidate_p (x)
|
2000-10-17 11:34:21 +02:00
|
|
|
|
tree x;
|
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
return TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == PARM_DECL;
|
|
|
|
|
}
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
/* Walk the tree X, and record accesses to variables. If X is written by the
|
|
|
|
|
parent tree, WRITER is the parent.
|
|
|
|
|
We store accesses in one of the two lists: PBEFORE_SP, and PNO_SP. If this
|
|
|
|
|
expression or its only operand forces a sequence point, then everything up
|
|
|
|
|
to the sequence point is stored in PBEFORE_SP. Everything else gets stored
|
|
|
|
|
in PNO_SP.
|
|
|
|
|
Once we return, we will have emitted warnings if any subexpression before
|
|
|
|
|
such a sequence point could be undefined. On a higher level, however, the
|
|
|
|
|
sequence point may not be relevant, and we'll merge the two lists.
|
|
|
|
|
|
|
|
|
|
Example: (b++, a) + b;
|
|
|
|
|
The call that processes the COMPOUND_EXPR will store the increment of B
|
|
|
|
|
in PBEFORE_SP, and the use of A in PNO_SP. The higher-level call that
|
|
|
|
|
processes the PLUS_EXPR will need to merge the two lists so that
|
|
|
|
|
eventually, all accesses end up on the same list (and we'll warn about the
|
|
|
|
|
unordered subexpressions b++ and b.
|
|
|
|
|
|
|
|
|
|
A note on merging. If we modify the former example so that our expression
|
|
|
|
|
becomes
|
|
|
|
|
(b++, b) + a
|
|
|
|
|
care must be taken not simply to add all three expressions into the final
|
|
|
|
|
PNO_SP list. The function merge_tlist takes care of that by merging the
|
|
|
|
|
before-SP list of the COMPOUND_EXPR into its after-SP list in a special
|
|
|
|
|
way, so that no more than one access to B is recorded. */
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
static void
|
|
|
|
|
verify_tree (x, pbefore_sp, pno_sp, writer)
|
|
|
|
|
tree x;
|
|
|
|
|
struct tlist **pbefore_sp, **pno_sp;
|
|
|
|
|
tree writer;
|
|
|
|
|
{
|
|
|
|
|
struct tlist *tmp_before, *tmp_nosp, *tmp_list2, *tmp_list3;
|
|
|
|
|
enum tree_code code;
|
|
|
|
|
char class;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
restart:
|
|
|
|
|
code = TREE_CODE (x);
|
|
|
|
|
class = TREE_CODE_CLASS (code);
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
if (warning_candidate_p (x))
|
2000-10-17 11:34:21 +02:00
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
*pno_sp = new_tlist (*pno_sp, x, writer);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
2000-11-24 15:22:01 +01:00
|
|
|
|
case CONSTRUCTOR:
|
|
|
|
|
return;
|
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
case COMPOUND_EXPR:
|
|
|
|
|
case TRUTH_ANDIF_EXPR:
|
|
|
|
|
case TRUTH_ORIF_EXPR:
|
|
|
|
|
tmp_before = tmp_nosp = tmp_list3 = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE);
|
|
|
|
|
warn_for_collisions (tmp_nosp);
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_before, 0);
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_nosp, 0);
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 1), &tmp_list3, pno_sp, NULL_TREE);
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_list3, 0);
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case COND_EXPR:
|
|
|
|
|
tmp_before = tmp_list2 = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_list2, NULL_TREE);
|
|
|
|
|
warn_for_collisions (tmp_list2);
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_before, 0);
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_list2, 1);
|
|
|
|
|
|
|
|
|
|
tmp_list3 = tmp_nosp = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 1), &tmp_list3, &tmp_nosp, NULL_TREE);
|
|
|
|
|
warn_for_collisions (tmp_nosp);
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_list3, 0);
|
|
|
|
|
|
|
|
|
|
tmp_list3 = tmp_list2 = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 2), &tmp_list3, &tmp_list2, NULL_TREE);
|
|
|
|
|
warn_for_collisions (tmp_list2);
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_list3, 0);
|
|
|
|
|
/* Rather than add both tmp_nosp and tmp_list2, we have to merge the
|
|
|
|
|
two first, to avoid warning for (a ? b++ : b++). */
|
|
|
|
|
merge_tlist (&tmp_nosp, tmp_list2, 0);
|
|
|
|
|
add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0);
|
|
|
|
|
return;
|
|
|
|
|
|
2000-10-17 11:34:21 +02:00
|
|
|
|
case PREDECREMENT_EXPR:
|
|
|
|
|
case PREINCREMENT_EXPR:
|
|
|
|
|
case POSTDECREMENT_EXPR:
|
|
|
|
|
case POSTINCREMENT_EXPR:
|
2000-11-24 12:49:46 +01:00
|
|
|
|
verify_tree (TREE_OPERAND (x, 0), pno_sp, pno_sp, x);
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case MODIFY_EXPR:
|
|
|
|
|
tmp_before = tmp_nosp = tmp_list3 = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 1), &tmp_before, &tmp_nosp, NULL_TREE);
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 0), &tmp_list3, &tmp_list3, x);
|
|
|
|
|
/* Expressions inside the LHS are not ordered wrt. the sequence points
|
|
|
|
|
in the RHS. Example:
|
|
|
|
|
*a = (a++, 2)
|
|
|
|
|
Despite the fact that the modification of "a" is in the before_sp
|
|
|
|
|
list (tmp_before), it conflicts with the use of "a" in the LHS.
|
|
|
|
|
We can handle this by adding the contents of tmp_list3
|
|
|
|
|
to those of tmp_before, and redoing the collision warnings for that
|
|
|
|
|
list. */
|
|
|
|
|
add_tlist (&tmp_before, tmp_list3, x, 1);
|
|
|
|
|
warn_for_collisions (tmp_before);
|
|
|
|
|
/* Exclude the LHS itself here; we first have to merge it into the
|
|
|
|
|
tmp_nosp list. This is done to avoid warning for "a = a"; if we
|
|
|
|
|
didn't exclude the LHS, we'd get it twice, once as a read and once
|
|
|
|
|
as a write. */
|
|
|
|
|
add_tlist (pno_sp, tmp_list3, x, 0);
|
|
|
|
|
warn_for_collisions_1 (TREE_OPERAND (x, 0), x, tmp_nosp, 1);
|
|
|
|
|
|
|
|
|
|
merge_tlist (pbefore_sp, tmp_before, 0);
|
|
|
|
|
if (warning_candidate_p (TREE_OPERAND (x, 0)))
|
|
|
|
|
merge_tlist (&tmp_nosp, new_tlist (NULL, TREE_OPERAND (x, 0), x), 0);
|
|
|
|
|
add_tlist (pno_sp, tmp_nosp, NULL_TREE, 1);
|
|
|
|
|
return;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
|
|
|
|
case CALL_EXPR:
|
2000-11-24 12:49:46 +01:00
|
|
|
|
/* We need to warn about conflicts among arguments and conflicts between
|
|
|
|
|
args and the function address. Side effects of the function address,
|
|
|
|
|
however, are not ordered by the sequence point of the call. */
|
|
|
|
|
tmp_before = tmp_nosp = tmp_list2 = tmp_list3 = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE);
|
|
|
|
|
if (TREE_OPERAND (x, 1))
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 1), &tmp_list2, &tmp_list3, NULL_TREE);
|
|
|
|
|
merge_tlist (&tmp_list3, tmp_list2, 0);
|
|
|
|
|
add_tlist (&tmp_before, tmp_list3, NULL_TREE, 0);
|
|
|
|
|
add_tlist (&tmp_before, tmp_nosp, NULL_TREE, 0);
|
|
|
|
|
warn_for_collisions (tmp_before);
|
|
|
|
|
add_tlist (pbefore_sp, tmp_before, NULL_TREE, 0);
|
|
|
|
|
return;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
|
|
|
|
case TREE_LIST:
|
|
|
|
|
/* Scan all the list, e.g. indices of multi dimensional array. */
|
|
|
|
|
while (x)
|
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
tmp_before = tmp_nosp = 0;
|
|
|
|
|
verify_tree (TREE_VALUE (x), &tmp_before, &tmp_nosp, NULL_TREE);
|
|
|
|
|
merge_tlist (&tmp_nosp, tmp_before, 0);
|
|
|
|
|
add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0);
|
2000-10-17 11:34:21 +02:00
|
|
|
|
x = TREE_CHAIN (x);
|
|
|
|
|
}
|
2000-11-24 12:49:46 +01:00
|
|
|
|
return;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
case SAVE_EXPR:
|
|
|
|
|
{
|
|
|
|
|
struct tlist_cache *t;
|
|
|
|
|
for (t = save_expr_cache; t; t = t->next)
|
|
|
|
|
if (t->expr == x)
|
|
|
|
|
break;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
if (! t)
|
2000-10-17 11:34:21 +02:00
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
t = (struct tlist_cache *) obstack_alloc (&tlist_obstack,
|
|
|
|
|
sizeof *t);
|
|
|
|
|
t->next = save_expr_cache;
|
|
|
|
|
t->expr = x;
|
|
|
|
|
save_expr_cache = t;
|
|
|
|
|
|
|
|
|
|
tmp_before = tmp_nosp = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE);
|
|
|
|
|
warn_for_collisions (tmp_nosp);
|
|
|
|
|
|
|
|
|
|
tmp_list3 = 0;
|
|
|
|
|
while (tmp_nosp)
|
|
|
|
|
{
|
|
|
|
|
struct tlist *t = tmp_nosp;
|
|
|
|
|
tmp_nosp = t->next;
|
|
|
|
|
merge_tlist (&tmp_list3, t, 0);
|
|
|
|
|
}
|
|
|
|
|
t->cache_before_sp = tmp_before;
|
|
|
|
|
t->cache_after_sp = tmp_list3;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
}
|
2000-11-24 12:49:46 +01:00
|
|
|
|
merge_tlist (pbefore_sp, t->cache_before_sp, 1);
|
|
|
|
|
add_tlist (pno_sp, t->cache_after_sp, NULL_TREE, 1);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
default:
|
2000-10-17 11:34:21 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
if (class == '1')
|
2000-10-17 11:34:21 +02:00
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
if (first_rtl_op (code) == 0)
|
|
|
|
|
return;
|
|
|
|
|
x = TREE_OPERAND (x, 0);
|
|
|
|
|
writer = 0;
|
|
|
|
|
goto restart;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
switch (class)
|
2000-10-17 11:34:21 +02:00
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
case 'r':
|
|
|
|
|
case '<':
|
|
|
|
|
case '2':
|
|
|
|
|
case 'b':
|
|
|
|
|
case 'e':
|
|
|
|
|
case 's':
|
|
|
|
|
case 'x':
|
|
|
|
|
{
|
|
|
|
|
int lp;
|
|
|
|
|
int max = first_rtl_op (TREE_CODE (x));
|
|
|
|
|
for (lp = 0; lp < max; lp++)
|
|
|
|
|
{
|
|
|
|
|
tmp_before = tmp_nosp = 0;
|
|
|
|
|
verify_tree (TREE_OPERAND (x, lp), &tmp_before, &tmp_nosp, NULL_TREE);
|
|
|
|
|
merge_tlist (&tmp_nosp, tmp_before, 0);
|
|
|
|
|
add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2000-10-17 11:34:21 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Try to warn for undefined behaviour in EXPR due to missing sequence
|
|
|
|
|
points. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
verify_sequence_points (expr)
|
|
|
|
|
tree expr;
|
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
struct tlist *before_sp = 0, *after_sp = 0;
|
2000-10-17 11:34:21 +02:00
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
warned_ids = 0;
|
|
|
|
|
save_expr_cache = 0;
|
|
|
|
|
if (tlist_firstobj == 0)
|
2000-10-17 11:34:21 +02:00
|
|
|
|
{
|
2000-11-24 12:49:46 +01:00
|
|
|
|
gcc_obstack_init (&tlist_obstack);
|
|
|
|
|
tlist_firstobj = obstack_alloc (&tlist_obstack, 0);
|
2000-10-17 11:34:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-11-24 12:49:46 +01:00
|
|
|
|
verify_tree (expr, &before_sp, &after_sp, 0);
|
|
|
|
|
warn_for_collisions (after_sp);
|
|
|
|
|
obstack_free (&tlist_obstack, tlist_firstobj);
|
2000-10-17 11:34:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-12-20 19:18:24 +01:00
|
|
|
|
tree
|
1992-02-04 20:51:11 +01:00
|
|
|
|
c_expand_expr_stmt (expr)
|
|
|
|
|
tree expr;
|
|
|
|
|
{
|
|
|
|
|
/* Do default conversion if safe and possibly important,
|
|
|
|
|
in case within ({...}). */
|
|
|
|
|
if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE && lvalue_p (expr))
|
|
|
|
|
|| TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
|
|
|
|
|
expr = default_conversion (expr);
|
|
|
|
|
|
2000-10-17 11:34:21 +02:00
|
|
|
|
if (warn_sequence_point)
|
|
|
|
|
verify_sequence_points (expr);
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (TREE_TYPE (expr) != error_mark_node
|
2000-03-21 20:33:42 +01:00
|
|
|
|
&& !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
&& TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
|
|
|
|
|
error ("expression statement has incomplete type");
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
last_expr_type = TREE_TYPE (expr);
|
2000-12-20 19:18:24 +01:00
|
|
|
|
return add_stmt (build_stmt (EXPR_STMT, expr));
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Validate the expression after `case' and apply default promotions. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
check_case_value (value)
|
|
|
|
|
tree value;
|
|
|
|
|
{
|
|
|
|
|
if (value == NULL_TREE)
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
|
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
|
1992-07-10 03:50:20 +02:00
|
|
|
|
STRIP_TYPE_NOPS (value);
|
2000-09-10 23:34:41 +02:00
|
|
|
|
/* In C++, the following is allowed:
|
|
|
|
|
|
|
|
|
|
const int i = 3;
|
|
|
|
|
switch (...) { case i: ... }
|
|
|
|
|
|
|
|
|
|
So, we try to reduce the VALUE to a constant that way. */
|
|
|
|
|
if (c_language == clk_cplusplus)
|
|
|
|
|
{
|
|
|
|
|
value = decl_constant_value (value);
|
|
|
|
|
STRIP_TYPE_NOPS (value);
|
|
|
|
|
value = fold (value);
|
|
|
|
|
}
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
if (TREE_CODE (value) != INTEGER_CST
|
|
|
|
|
&& value != error_mark_node)
|
|
|
|
|
{
|
|
|
|
|
error ("case label does not reduce to an integer constant");
|
|
|
|
|
value = error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* Promote char or short to int. */
|
|
|
|
|
value = default_conversion (value);
|
|
|
|
|
|
1992-09-07 08:07:30 +02:00
|
|
|
|
constant_expression_warning (value);
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return an integer type with BITS bits of precision,
|
|
|
|
|
that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
type_for_size (bits, unsignedp)
|
|
|
|
|
unsigned bits;
|
|
|
|
|
int unsignedp;
|
|
|
|
|
{
|
1995-01-31 01:40:42 +01:00
|
|
|
|
if (bits == TYPE_PRECISION (integer_type_node))
|
|
|
|
|
return unsignedp ? unsigned_type_node : integer_type_node;
|
|
|
|
|
|
1992-07-03 08:41:07 +02:00
|
|
|
|
if (bits == TYPE_PRECISION (signed_char_type_node))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
|
|
|
|
|
|
1992-07-03 08:41:07 +02:00
|
|
|
|
if (bits == TYPE_PRECISION (short_integer_type_node))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
|
|
|
|
|
|
1992-07-03 08:41:07 +02:00
|
|
|
|
if (bits == TYPE_PRECISION (long_integer_type_node))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
|
|
|
|
|
1992-07-03 08:41:07 +02:00
|
|
|
|
if (bits == TYPE_PRECISION (long_long_integer_type_node))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return (unsignedp ? long_long_unsigned_type_node
|
|
|
|
|
: long_long_integer_type_node);
|
|
|
|
|
|
1999-07-02 12:30:01 +02:00
|
|
|
|
if (bits == TYPE_PRECISION (widest_integer_literal_type_node))
|
|
|
|
|
return (unsignedp ? widest_unsigned_literal_type_node
|
|
|
|
|
: widest_integer_literal_type_node);
|
|
|
|
|
|
1992-07-03 08:41:07 +02:00
|
|
|
|
if (bits <= TYPE_PRECISION (intQI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
|
|
|
|
|
|
|
|
|
|
if (bits <= TYPE_PRECISION (intHI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
|
|
|
|
|
|
|
|
|
|
if (bits <= TYPE_PRECISION (intSI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
|
|
|
|
|
|
|
|
|
|
if (bits <= TYPE_PRECISION (intDI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return a data type that has machine mode MODE.
|
|
|
|
|
If the mode is an integer,
|
|
|
|
|
then UNSIGNEDP selects between signed and unsigned types. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
type_for_mode (mode, unsignedp)
|
|
|
|
|
enum machine_mode mode;
|
|
|
|
|
int unsignedp;
|
|
|
|
|
{
|
1995-01-31 01:40:42 +01:00
|
|
|
|
if (mode == TYPE_MODE (integer_type_node))
|
|
|
|
|
return unsignedp ? unsigned_type_node : integer_type_node;
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (mode == TYPE_MODE (signed_char_type_node))
|
|
|
|
|
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (short_integer_type_node))
|
|
|
|
|
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (long_integer_type_node))
|
|
|
|
|
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (long_long_integer_type_node))
|
|
|
|
|
return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
|
|
|
|
|
|
1999-07-02 12:30:01 +02:00
|
|
|
|
if (mode == TYPE_MODE (widest_integer_literal_type_node))
|
2000-01-03 22:48:49 +01:00
|
|
|
|
return unsignedp ? widest_unsigned_literal_type_node
|
1999-07-02 12:30:01 +02:00
|
|
|
|
: widest_integer_literal_type_node;
|
|
|
|
|
|
1992-07-03 08:41:07 +02:00
|
|
|
|
if (mode == TYPE_MODE (intQI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (intHI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (intSI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (intDI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
|
|
|
|
|
|
1998-10-08 06:37:30 +02:00
|
|
|
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
1998-04-21 15:25:56 +02:00
|
|
|
|
if (mode == TYPE_MODE (intTI_type_node))
|
|
|
|
|
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
|
1998-10-08 06:37:30 +02:00
|
|
|
|
#endif
|
1998-04-21 15:25:56 +02:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (mode == TYPE_MODE (float_type_node))
|
|
|
|
|
return float_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (double_type_node))
|
|
|
|
|
return double_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (long_double_type_node))
|
|
|
|
|
return long_double_type_node;
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
|
|
|
|
|
return build_pointer_type (char_type_node);
|
|
|
|
|
|
|
|
|
|
if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
|
|
|
|
|
return build_pointer_type (integer_type_node);
|
|
|
|
|
|
2000-06-25 19:27:28 +02:00
|
|
|
|
#ifdef VECTOR_MODE_SUPPORTED_P
|
|
|
|
|
if (mode == TYPE_MODE (V4SF_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
|
|
|
|
|
return V4SF_type_node;
|
|
|
|
|
if (mode == TYPE_MODE (V4SI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
|
|
|
|
|
return V4SI_type_node;
|
|
|
|
|
if (mode == TYPE_MODE (V2SI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
|
|
|
|
|
return V2SI_type_node;
|
|
|
|
|
if (mode == TYPE_MODE (V4HI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
|
|
|
|
|
return V4HI_type_node;
|
|
|
|
|
if (mode == TYPE_MODE (V8QI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
|
|
|
|
|
return V8QI_type_node;
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
1999-07-06 14:34:50 +02:00
|
|
|
|
|
|
|
|
|
/* Return an unsigned type the same as TYPE in other respects. */
|
|
|
|
|
tree
|
|
|
|
|
unsigned_type (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree type1 = TYPE_MAIN_VARIANT (type);
|
|
|
|
|
if (type1 == signed_char_type_node || type1 == char_type_node)
|
|
|
|
|
return unsigned_char_type_node;
|
|
|
|
|
if (type1 == integer_type_node)
|
|
|
|
|
return unsigned_type_node;
|
|
|
|
|
if (type1 == short_integer_type_node)
|
|
|
|
|
return short_unsigned_type_node;
|
|
|
|
|
if (type1 == long_integer_type_node)
|
|
|
|
|
return long_unsigned_type_node;
|
|
|
|
|
if (type1 == long_long_integer_type_node)
|
|
|
|
|
return long_long_unsigned_type_node;
|
|
|
|
|
if (type1 == widest_integer_literal_type_node)
|
|
|
|
|
return widest_unsigned_literal_type_node;
|
|
|
|
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
|
|
|
|
if (type1 == intTI_type_node)
|
|
|
|
|
return unsigned_intTI_type_node;
|
|
|
|
|
#endif
|
|
|
|
|
if (type1 == intDI_type_node)
|
|
|
|
|
return unsigned_intDI_type_node;
|
|
|
|
|
if (type1 == intSI_type_node)
|
|
|
|
|
return unsigned_intSI_type_node;
|
|
|
|
|
if (type1 == intHI_type_node)
|
|
|
|
|
return unsigned_intHI_type_node;
|
|
|
|
|
if (type1 == intQI_type_node)
|
|
|
|
|
return unsigned_intQI_type_node;
|
|
|
|
|
|
|
|
|
|
return signed_or_unsigned_type (1, type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return a signed type the same as TYPE in other respects. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
signed_type (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree type1 = TYPE_MAIN_VARIANT (type);
|
|
|
|
|
if (type1 == unsigned_char_type_node || type1 == char_type_node)
|
|
|
|
|
return signed_char_type_node;
|
|
|
|
|
if (type1 == unsigned_type_node)
|
|
|
|
|
return integer_type_node;
|
|
|
|
|
if (type1 == short_unsigned_type_node)
|
|
|
|
|
return short_integer_type_node;
|
|
|
|
|
if (type1 == long_unsigned_type_node)
|
|
|
|
|
return long_integer_type_node;
|
|
|
|
|
if (type1 == long_long_unsigned_type_node)
|
|
|
|
|
return long_long_integer_type_node;
|
|
|
|
|
if (type1 == widest_unsigned_literal_type_node)
|
|
|
|
|
return widest_integer_literal_type_node;
|
|
|
|
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
|
|
|
|
if (type1 == unsigned_intTI_type_node)
|
|
|
|
|
return intTI_type_node;
|
|
|
|
|
#endif
|
|
|
|
|
if (type1 == unsigned_intDI_type_node)
|
|
|
|
|
return intDI_type_node;
|
|
|
|
|
if (type1 == unsigned_intSI_type_node)
|
|
|
|
|
return intSI_type_node;
|
|
|
|
|
if (type1 == unsigned_intHI_type_node)
|
|
|
|
|
return intHI_type_node;
|
|
|
|
|
if (type1 == unsigned_intQI_type_node)
|
|
|
|
|
return intQI_type_node;
|
|
|
|
|
|
|
|
|
|
return signed_or_unsigned_type (0, type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return a type the same as TYPE except unsigned or
|
|
|
|
|
signed according to UNSIGNEDP. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
signed_or_unsigned_type (unsignedp, type)
|
|
|
|
|
int unsignedp;
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
if (! INTEGRAL_TYPE_P (type)
|
|
|
|
|
|| TREE_UNSIGNED (type) == unsignedp)
|
|
|
|
|
return type;
|
|
|
|
|
|
|
|
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
|
|
|
|
|
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
|
2000-01-03 22:48:49 +01:00
|
|
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
|
1999-07-06 14:34:50 +02:00
|
|
|
|
return unsignedp ? unsigned_type_node : integer_type_node;
|
2000-01-03 22:48:49 +01:00
|
|
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
|
1999-07-06 14:34:50 +02:00
|
|
|
|
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
|
2000-01-03 22:48:49 +01:00
|
|
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
|
1999-07-06 14:34:50 +02:00
|
|
|
|
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
2000-01-03 22:48:49 +01:00
|
|
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
|
1999-07-06 14:34:50 +02:00
|
|
|
|
return (unsignedp ? long_long_unsigned_type_node
|
|
|
|
|
: long_long_integer_type_node);
|
2000-01-03 22:48:49 +01:00
|
|
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node))
|
1999-07-06 14:34:50 +02:00
|
|
|
|
return (unsignedp ? widest_unsigned_literal_type_node
|
|
|
|
|
: widest_integer_literal_type_node);
|
|
|
|
|
return type;
|
|
|
|
|
}
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
1994-09-03 01:40:51 +02:00
|
|
|
|
/* Return the minimum number of bits needed to represent VALUE in a
|
|
|
|
|
signed or unsigned type, UNSIGNEDP says which. */
|
|
|
|
|
|
tree.h (INT_CST_LT, [...]): Remove unneeded casts.
* tree.h (INT_CST_LT, INT_CST_LT_UNSIGNED): Remove unneeded casts.
(struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT.
(attribute_hash_list, type_hash_canon): hashcode is now unsigned.
(type_hash_lookup, type_hash_add, type_hash_list): Likewise.
(min_precision): Result is unsignd.
(add_double, neg_double, mul_double): Low word is unsigned.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double): Likewise.
(tree_floor_log2, compare_tree_int): New functions.
(preserve_rtl_expr_temps): New declaration.
* c-common.c (declare_hidden_char_array): Use compare_tree_int.
(decl_attributes): Use tree_log2 to find alignment.
Check for TREE_INT_CST_HIGH for format args.
(min_precision): Now unsigned.
Use tree_floor_log2.
(truthvalue_conversion): Delete long-disabled code.
* c-decl.c (finish_struct): Clean up tests on field width.
(finish_function): Use compare_tree_int.
* c-pragma.c (handle_pragma_token): Use tree_log2 for alignment.
* c-typeck.c (comptypes): Use tree_int_cst_equal.
(default_conversion, digest_init): Use compare_tree_int.
(build_binary_op): Use integer_all_onesp and compare_tree_int.
Fix type errors in forming masks.
* calls.c (initialize_argument_information): Use compare_tree_int.
* dbxout.c (dbxout_type): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* except.c (expand_eh_region_start_tree): Use compare_tree_int.
* expr.c (is_zeros_p, case INTEGER_CST): Use integer_zerop.
(store_field): Use compare_tree_int.
(expand_expr, case CONSTRUCTOR): Use TYPE_SIZE_UNIT.
(expand_expr, case ARRAY_REF): Use compare_tree_int.
(do_jump, case BIT_AND_EXPR): Use tree_floor_log2.
(do_store_flag): Use compare_tree_int.
* fold-const.c (encode, decode): Low part is always unsigned.
(force_fit_type, add_double, neg_double, mul_double): Likewise.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double, int_const_binop): Likewise.
(fold_convert): Use compare_tree_int.
(operand_equal_p, case INTEGER_CST): Use tree_int_cst_equal.
(invert_truthvalue, case INTEGER_CST): Likewise.
(fold): Use compare_tree_int; add casts for unsigned TREE_INT_CST_LOW.
* mkdeps.c (deps_dummy_targets): Make I unsigned.
* rtl.h (add_double, neg_double, mul_double): Low words are unsigned.
(lshift_double, rshift_double, lrotate_double, rrotate_double):
Likewise.
* stmt.c (expand_decl): Use compare_tree_int and mode_for_size_tree.
(expand_end_case): Use compare_tree_int.
(estimate_case_costs): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* stor-layout.c (mode_for_size_tree): Use compare_tree_int.
(layout_decl): Likewise.
(layout_record, layout_union): Make sizes unsigned.
(layout_type, case VOID_TYPE): TYPE_SIZE must be bitsizetype.
(layout_type, case QUAL_UNION_TYPE): Use compare_tree_int.
* tree.c (struct type_hash): hashcode is unsigned.
(build_type_attribute_variant, type_hash_list): Likewise.
(type_hash_lookup, type_hash_add, type_hash_canon): Likewise.
(attribute_hash_list, build_array_type, build_method_type): Likewise.
(build_complex_type): Likewise.
(real_value_from_int_cst): Remove unneeded casts.
(integer_all_onesp): Add casts.
(tree_floor_log2, compare_tree_int): New functions.
(build_index_type): Use tree_int_cst_sgn.
* varasm.c (assemble_variable): Use compare_tree_int.
* ch/actions.c (chill_convert_for_assignment): INDEX is unsigned
HOST_WIDE_INT.
* ch/ch-tree.h (DECL_NESTING_LEVEL): Use TREE_INT_CST_HIGH
since unsigned.
* ch/except.c (chill_handle_on_labels): ALTERNATIVE is unsigned.
Use compare_tree_int.
(expand_goto_except_cleanup): Likewise.
* cp/class.c (dfs_modify_vtables): I is now unsigned.
(check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
(build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
* cp/init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
* cp/typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
Call integer_all_onesp.
* cp/typeck2.c (process_init_constructor): Use compare_tree_int.
* f/com.c (ffecom_f2c_set_lio_code_): Use compare_tree_int.
(ffecom_sym_transform_, ffecom_transform_common_): Likewise.
(ffecom_transform_equiv_): Likewise.
* java/decl.c (emit_init_test_initialization): Mark KEY as unused.
* java/expr.c (build_newarray): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
(build_anewarray): Likewise.
* java/parse.y (patch_newarray): Likewise.
* java/parse.c: Regenerated.
From-SVN: r32383
2000-03-07 12:41:32 +01:00
|
|
|
|
unsigned int
|
1994-09-03 01:40:51 +02:00
|
|
|
|
min_precision (value, unsignedp)
|
|
|
|
|
tree value;
|
|
|
|
|
int unsignedp;
|
|
|
|
|
{
|
|
|
|
|
int log;
|
|
|
|
|
|
|
|
|
|
/* If the value is negative, compute its negative minus 1. The latter
|
|
|
|
|
adjustment is because the absolute value of the largest negative value
|
|
|
|
|
is one larger than the largest positive value. This is equivalent to
|
|
|
|
|
a bit-wise negation, so use that operation instead. */
|
|
|
|
|
|
|
|
|
|
if (tree_int_cst_sgn (value) < 0)
|
|
|
|
|
value = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (value), value));
|
|
|
|
|
|
|
|
|
|
/* Return the number of bits needed, taking into account the fact
|
|
|
|
|
that we need one more bit for a signed than unsigned type. */
|
|
|
|
|
|
|
|
|
|
if (integer_zerop (value))
|
|
|
|
|
log = 0;
|
|
|
|
|
else
|
tree.h (INT_CST_LT, [...]): Remove unneeded casts.
* tree.h (INT_CST_LT, INT_CST_LT_UNSIGNED): Remove unneeded casts.
(struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT.
(attribute_hash_list, type_hash_canon): hashcode is now unsigned.
(type_hash_lookup, type_hash_add, type_hash_list): Likewise.
(min_precision): Result is unsignd.
(add_double, neg_double, mul_double): Low word is unsigned.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double): Likewise.
(tree_floor_log2, compare_tree_int): New functions.
(preserve_rtl_expr_temps): New declaration.
* c-common.c (declare_hidden_char_array): Use compare_tree_int.
(decl_attributes): Use tree_log2 to find alignment.
Check for TREE_INT_CST_HIGH for format args.
(min_precision): Now unsigned.
Use tree_floor_log2.
(truthvalue_conversion): Delete long-disabled code.
* c-decl.c (finish_struct): Clean up tests on field width.
(finish_function): Use compare_tree_int.
* c-pragma.c (handle_pragma_token): Use tree_log2 for alignment.
* c-typeck.c (comptypes): Use tree_int_cst_equal.
(default_conversion, digest_init): Use compare_tree_int.
(build_binary_op): Use integer_all_onesp and compare_tree_int.
Fix type errors in forming masks.
* calls.c (initialize_argument_information): Use compare_tree_int.
* dbxout.c (dbxout_type): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* except.c (expand_eh_region_start_tree): Use compare_tree_int.
* expr.c (is_zeros_p, case INTEGER_CST): Use integer_zerop.
(store_field): Use compare_tree_int.
(expand_expr, case CONSTRUCTOR): Use TYPE_SIZE_UNIT.
(expand_expr, case ARRAY_REF): Use compare_tree_int.
(do_jump, case BIT_AND_EXPR): Use tree_floor_log2.
(do_store_flag): Use compare_tree_int.
* fold-const.c (encode, decode): Low part is always unsigned.
(force_fit_type, add_double, neg_double, mul_double): Likewise.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double, int_const_binop): Likewise.
(fold_convert): Use compare_tree_int.
(operand_equal_p, case INTEGER_CST): Use tree_int_cst_equal.
(invert_truthvalue, case INTEGER_CST): Likewise.
(fold): Use compare_tree_int; add casts for unsigned TREE_INT_CST_LOW.
* mkdeps.c (deps_dummy_targets): Make I unsigned.
* rtl.h (add_double, neg_double, mul_double): Low words are unsigned.
(lshift_double, rshift_double, lrotate_double, rrotate_double):
Likewise.
* stmt.c (expand_decl): Use compare_tree_int and mode_for_size_tree.
(expand_end_case): Use compare_tree_int.
(estimate_case_costs): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* stor-layout.c (mode_for_size_tree): Use compare_tree_int.
(layout_decl): Likewise.
(layout_record, layout_union): Make sizes unsigned.
(layout_type, case VOID_TYPE): TYPE_SIZE must be bitsizetype.
(layout_type, case QUAL_UNION_TYPE): Use compare_tree_int.
* tree.c (struct type_hash): hashcode is unsigned.
(build_type_attribute_variant, type_hash_list): Likewise.
(type_hash_lookup, type_hash_add, type_hash_canon): Likewise.
(attribute_hash_list, build_array_type, build_method_type): Likewise.
(build_complex_type): Likewise.
(real_value_from_int_cst): Remove unneeded casts.
(integer_all_onesp): Add casts.
(tree_floor_log2, compare_tree_int): New functions.
(build_index_type): Use tree_int_cst_sgn.
* varasm.c (assemble_variable): Use compare_tree_int.
* ch/actions.c (chill_convert_for_assignment): INDEX is unsigned
HOST_WIDE_INT.
* ch/ch-tree.h (DECL_NESTING_LEVEL): Use TREE_INT_CST_HIGH
since unsigned.
* ch/except.c (chill_handle_on_labels): ALTERNATIVE is unsigned.
Use compare_tree_int.
(expand_goto_except_cleanup): Likewise.
* cp/class.c (dfs_modify_vtables): I is now unsigned.
(check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
(build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
* cp/init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
* cp/method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
* cp/typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
Call integer_all_onesp.
* cp/typeck2.c (process_init_constructor): Use compare_tree_int.
* f/com.c (ffecom_f2c_set_lio_code_): Use compare_tree_int.
(ffecom_sym_transform_, ffecom_transform_common_): Likewise.
(ffecom_transform_equiv_): Likewise.
* java/decl.c (emit_init_test_initialization): Mark KEY as unused.
* java/expr.c (build_newarray): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
(build_anewarray): Likewise.
* java/parse.y (patch_newarray): Likewise.
* java/parse.c: Regenerated.
From-SVN: r32383
2000-03-07 12:41:32 +01:00
|
|
|
|
log = tree_floor_log2 (value);
|
1994-09-03 01:40:51 +02:00
|
|
|
|
|
|
|
|
|
return log + 1 + ! unsignedp;
|
|
|
|
|
}
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
/* Print an error message for invalid operands to arith operation CODE.
|
|
|
|
|
NOP_EXPR is used as a special case (see truthvalue_conversion). */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
binary_op_error (code)
|
|
|
|
|
enum tree_code code;
|
|
|
|
|
{
|
c-aux-info.c (data_type, [...]): Qualify a char* with the `const' keyword.
* c-aux-info.c (data_type, affix_data_type, gen_decl,
gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type):
Qualify a char* with the `const' keyword.
* c-common.c (declare_hidden_char_array, add_attribute, if_elt,
declare_function_name, decl_attributes, format_char_info,
check_format_info, binary_op_error): Likewise.
* cexp.y (yyerror, error, pedwarn, warning, token): Likewise.
* gcse.c (dump_hash_table): Likewise.
* integrate.c (function_cannot_inline_p): Likewise
* optabs.c: Include insn-config.h earlier.
(init_libfuncs, init_integral_libfuncs, init_floating_libfuncs):
Qualify a char* with the `const' keyword.
* real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe,
asctoeg, mtherr, ereal_atof): Likewise.
* real.h (ereal_atof): Likewise.
* sbitmap.c (dump_sbitmap_vector): Likewise.
* sbitmap.h (dump_sbitmap_vector): Likewise.
* stmt.c (nesting, n_occurrences, expand_start_case): Likewise.
* toplev.c (rest_of_compilation): Likewise.
* tree.h (function_cannot_inline_p, expand_start_case): Likewise.
From-SVN: r25614
1999-03-06 06:34:26 +01:00
|
|
|
|
register const char *opname;
|
1994-02-27 16:42:51 +01:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case NOP_EXPR:
|
|
|
|
|
error ("invalid truth-value expression");
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case PLUS_EXPR:
|
|
|
|
|
opname = "+"; break;
|
|
|
|
|
case MINUS_EXPR:
|
|
|
|
|
opname = "-"; break;
|
|
|
|
|
case MULT_EXPR:
|
|
|
|
|
opname = "*"; break;
|
|
|
|
|
case MAX_EXPR:
|
|
|
|
|
opname = "max"; break;
|
|
|
|
|
case MIN_EXPR:
|
|
|
|
|
opname = "min"; break;
|
|
|
|
|
case EQ_EXPR:
|
|
|
|
|
opname = "=="; break;
|
|
|
|
|
case NE_EXPR:
|
|
|
|
|
opname = "!="; break;
|
|
|
|
|
case LE_EXPR:
|
|
|
|
|
opname = "<="; break;
|
|
|
|
|
case GE_EXPR:
|
|
|
|
|
opname = ">="; break;
|
|
|
|
|
case LT_EXPR:
|
|
|
|
|
opname = "<"; break;
|
|
|
|
|
case GT_EXPR:
|
|
|
|
|
opname = ">"; break;
|
|
|
|
|
case LSHIFT_EXPR:
|
|
|
|
|
opname = "<<"; break;
|
|
|
|
|
case RSHIFT_EXPR:
|
|
|
|
|
opname = ">>"; break;
|
|
|
|
|
case TRUNC_MOD_EXPR:
|
1992-04-04 21:11:28 +02:00
|
|
|
|
case FLOOR_MOD_EXPR:
|
1992-02-04 20:51:11 +01:00
|
|
|
|
opname = "%"; break;
|
|
|
|
|
case TRUNC_DIV_EXPR:
|
1992-04-04 21:11:28 +02:00
|
|
|
|
case FLOOR_DIV_EXPR:
|
1992-02-04 20:51:11 +01:00
|
|
|
|
opname = "/"; break;
|
|
|
|
|
case BIT_AND_EXPR:
|
|
|
|
|
opname = "&"; break;
|
|
|
|
|
case BIT_IOR_EXPR:
|
|
|
|
|
opname = "|"; break;
|
|
|
|
|
case TRUTH_ANDIF_EXPR:
|
|
|
|
|
opname = "&&"; break;
|
|
|
|
|
case TRUTH_ORIF_EXPR:
|
|
|
|
|
opname = "||"; break;
|
|
|
|
|
case BIT_XOR_EXPR:
|
|
|
|
|
opname = "^"; break;
|
1992-04-04 21:11:28 +02:00
|
|
|
|
case LROTATE_EXPR:
|
|
|
|
|
case RROTATE_EXPR:
|
|
|
|
|
opname = "rotate"; break;
|
1998-02-05 21:54:49 +01:00
|
|
|
|
default:
|
|
|
|
|
opname = "unknown"; break;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
error ("invalid operands to binary %s", opname);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Subroutine of build_binary_op, used for comparison operations.
|
|
|
|
|
See if the operands have both been converted from subword integer types
|
|
|
|
|
and, if so, perhaps change them both back to their original type.
|
1993-10-31 21:19:31 +01:00
|
|
|
|
This function is also responsible for converting the two operands
|
|
|
|
|
to the proper common type for comparison.
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
The arguments of this function are all pointers to local variables
|
|
|
|
|
of build_binary_op: OP0_PTR is &OP0, OP1_PTR is &OP1,
|
|
|
|
|
RESTYPE_PTR is &RESULT_TYPE and RESCODE_PTR is &RESULTCODE.
|
|
|
|
|
|
|
|
|
|
If this function returns nonzero, it means that the comparison has
|
|
|
|
|
a constant value. What this function returns is an expression for
|
|
|
|
|
that value. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
|
|
|
|
|
tree *op0_ptr, *op1_ptr;
|
|
|
|
|
tree *restype_ptr;
|
|
|
|
|
enum tree_code *rescode_ptr;
|
|
|
|
|
{
|
|
|
|
|
register tree type;
|
|
|
|
|
tree op0 = *op0_ptr;
|
|
|
|
|
tree op1 = *op1_ptr;
|
|
|
|
|
int unsignedp0, unsignedp1;
|
|
|
|
|
int real1, real2;
|
|
|
|
|
tree primop0, primop1;
|
|
|
|
|
enum tree_code code = *rescode_ptr;
|
|
|
|
|
|
|
|
|
|
/* Throw away any conversions to wider types
|
|
|
|
|
already present in the operands. */
|
|
|
|
|
|
|
|
|
|
primop0 = get_narrower (op0, &unsignedp0);
|
|
|
|
|
primop1 = get_narrower (op1, &unsignedp1);
|
|
|
|
|
|
|
|
|
|
/* Handle the case that OP0 does not *contain* a conversion
|
|
|
|
|
but it *requires* conversion to FINAL_TYPE. */
|
|
|
|
|
|
|
|
|
|
if (op0 == primop0 && TREE_TYPE (op0) != *restype_ptr)
|
|
|
|
|
unsignedp0 = TREE_UNSIGNED (TREE_TYPE (op0));
|
|
|
|
|
if (op1 == primop1 && TREE_TYPE (op1) != *restype_ptr)
|
|
|
|
|
unsignedp1 = TREE_UNSIGNED (TREE_TYPE (op1));
|
|
|
|
|
|
|
|
|
|
/* If one of the operands must be floated, we cannot optimize. */
|
|
|
|
|
real1 = TREE_CODE (TREE_TYPE (primop0)) == REAL_TYPE;
|
|
|
|
|
real2 = TREE_CODE (TREE_TYPE (primop1)) == REAL_TYPE;
|
|
|
|
|
|
|
|
|
|
/* If first arg is constant, swap the args (changing operation
|
1994-08-25 23:43:46 +02:00
|
|
|
|
so value is preserved), for canonicalization. Don't do this if
|
|
|
|
|
the second arg is 0. */
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
1994-08-25 23:43:46 +02:00
|
|
|
|
if (TREE_CONSTANT (primop0)
|
|
|
|
|
&& ! integer_zerop (primop1) && ! real_zerop (primop1))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
{
|
|
|
|
|
register tree tem = primop0;
|
|
|
|
|
register int temi = unsignedp0;
|
|
|
|
|
primop0 = primop1;
|
|
|
|
|
primop1 = tem;
|
|
|
|
|
tem = op0;
|
|
|
|
|
op0 = op1;
|
|
|
|
|
op1 = tem;
|
|
|
|
|
*op0_ptr = op0;
|
|
|
|
|
*op1_ptr = op1;
|
|
|
|
|
unsignedp0 = unsignedp1;
|
|
|
|
|
unsignedp1 = temi;
|
|
|
|
|
temi = real1;
|
|
|
|
|
real1 = real2;
|
|
|
|
|
real2 = temi;
|
|
|
|
|
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case LT_EXPR:
|
|
|
|
|
code = GT_EXPR;
|
|
|
|
|
break;
|
|
|
|
|
case GT_EXPR:
|
|
|
|
|
code = LT_EXPR;
|
|
|
|
|
break;
|
|
|
|
|
case LE_EXPR:
|
|
|
|
|
code = GE_EXPR;
|
|
|
|
|
break;
|
|
|
|
|
case GE_EXPR:
|
|
|
|
|
code = LE_EXPR;
|
|
|
|
|
break;
|
1998-02-05 21:54:49 +01:00
|
|
|
|
default:
|
|
|
|
|
break;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
*rescode_ptr = code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If comparing an integer against a constant more bits wide,
|
|
|
|
|
maybe we can deduce a value of 1 or 0 independent of the data.
|
|
|
|
|
Or else truncate the constant now
|
|
|
|
|
rather than extend the variable at run time.
|
|
|
|
|
|
|
|
|
|
This is only interesting if the constant is the wider arg.
|
|
|
|
|
Also, it is not safe if the constant is unsigned and the
|
|
|
|
|
variable arg is signed, since in this case the variable
|
|
|
|
|
would be sign-extended and then regarded as unsigned.
|
|
|
|
|
Our technique fails in this case because the lowest/highest
|
|
|
|
|
possible unsigned results don't follow naturally from the
|
|
|
|
|
lowest/highest possible values of the variable operand.
|
|
|
|
|
For just EQ_EXPR and NE_EXPR there is another technique that
|
|
|
|
|
could be used: see if the constant can be faithfully represented
|
|
|
|
|
in the other operand's type, by truncating it and reextending it
|
|
|
|
|
and see if that preserves the constant's value. */
|
|
|
|
|
|
|
|
|
|
if (!real1 && !real2
|
|
|
|
|
&& TREE_CODE (primop1) == INTEGER_CST
|
|
|
|
|
&& TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr))
|
|
|
|
|
{
|
|
|
|
|
int min_gt, max_gt, min_lt, max_lt;
|
|
|
|
|
tree maxval, minval;
|
|
|
|
|
/* 1 if comparison is nominally unsigned. */
|
|
|
|
|
int unsignedp = TREE_UNSIGNED (*restype_ptr);
|
|
|
|
|
tree val;
|
|
|
|
|
|
|
|
|
|
type = signed_or_unsigned_type (unsignedp0, TREE_TYPE (primop0));
|
1999-02-16 01:41:58 +01:00
|
|
|
|
|
|
|
|
|
/* If TYPE is an enumeration, then we need to get its min/max
|
|
|
|
|
values from it's underlying integral type, not the enumerated
|
|
|
|
|
type itself. */
|
|
|
|
|
if (TREE_CODE (type) == ENUMERAL_TYPE)
|
|
|
|
|
type = type_for_size (TYPE_PRECISION (type), unsignedp0);
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
maxval = TYPE_MAX_VALUE (type);
|
|
|
|
|
minval = TYPE_MIN_VALUE (type);
|
|
|
|
|
|
|
|
|
|
if (unsignedp && !unsignedp0)
|
|
|
|
|
*restype_ptr = signed_type (*restype_ptr);
|
|
|
|
|
|
|
|
|
|
if (TREE_TYPE (primop1) != *restype_ptr)
|
|
|
|
|
primop1 = convert (*restype_ptr, primop1);
|
|
|
|
|
if (type != *restype_ptr)
|
|
|
|
|
{
|
|
|
|
|
minval = convert (*restype_ptr, minval);
|
|
|
|
|
maxval = convert (*restype_ptr, maxval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (unsignedp && unsignedp0)
|
|
|
|
|
{
|
|
|
|
|
min_gt = INT_CST_LT_UNSIGNED (primop1, minval);
|
|
|
|
|
max_gt = INT_CST_LT_UNSIGNED (primop1, maxval);
|
|
|
|
|
min_lt = INT_CST_LT_UNSIGNED (minval, primop1);
|
|
|
|
|
max_lt = INT_CST_LT_UNSIGNED (maxval, primop1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
min_gt = INT_CST_LT (primop1, minval);
|
|
|
|
|
max_gt = INT_CST_LT (primop1, maxval);
|
|
|
|
|
min_lt = INT_CST_LT (minval, primop1);
|
|
|
|
|
max_lt = INT_CST_LT (maxval, primop1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val = 0;
|
|
|
|
|
/* This used to be a switch, but Genix compiler can't handle that. */
|
|
|
|
|
if (code == NE_EXPR)
|
|
|
|
|
{
|
|
|
|
|
if (max_lt || min_gt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
else if (code == EQ_EXPR)
|
|
|
|
|
{
|
|
|
|
|
if (max_lt || min_gt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_false_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
else if (code == LT_EXPR)
|
|
|
|
|
{
|
|
|
|
|
if (max_lt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (!min_lt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_false_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
else if (code == GT_EXPR)
|
|
|
|
|
{
|
|
|
|
|
if (min_gt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (!max_gt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_false_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
else if (code == LE_EXPR)
|
|
|
|
|
{
|
|
|
|
|
if (!max_gt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (min_gt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_false_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
else if (code == GE_EXPR)
|
|
|
|
|
{
|
|
|
|
|
if (!min_lt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (max_lt)
|
1995-01-17 22:43:40 +01:00
|
|
|
|
val = boolean_false_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If primop0 was sign-extended and unsigned comparison specd,
|
|
|
|
|
we did a signed comparison above using the signed type bounds.
|
|
|
|
|
But the comparison we output must be unsigned.
|
|
|
|
|
|
|
|
|
|
Also, for inequalities, VAL is no good; but if the signed
|
|
|
|
|
comparison had *any* fixed result, it follows that the
|
|
|
|
|
unsigned comparison just tests the sign in reverse
|
|
|
|
|
(positive values are LE, negative ones GE).
|
|
|
|
|
So we can generate an unsigned comparison
|
|
|
|
|
against an extreme value of the signed type. */
|
|
|
|
|
|
|
|
|
|
if (unsignedp && !unsignedp0)
|
|
|
|
|
{
|
|
|
|
|
if (val != 0)
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case LT_EXPR:
|
|
|
|
|
case GE_EXPR:
|
|
|
|
|
primop1 = TYPE_MIN_VALUE (type);
|
|
|
|
|
val = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LE_EXPR:
|
|
|
|
|
case GT_EXPR:
|
|
|
|
|
primop1 = TYPE_MAX_VALUE (type);
|
|
|
|
|
val = 0;
|
|
|
|
|
break;
|
1998-02-05 21:54:49 +01:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
type = unsigned_type (type);
|
|
|
|
|
}
|
|
|
|
|
|
1993-11-25 00:14:43 +01:00
|
|
|
|
if (!max_gt && !unsignedp0 && TREE_CODE (primop0) != INTEGER_CST)
|
1992-02-04 20:51:11 +01:00
|
|
|
|
{
|
|
|
|
|
/* This is the case of (char)x >?< 0x80, which people used to use
|
|
|
|
|
expecting old C compilers to change the 0x80 into -0x80. */
|
1995-01-17 22:43:40 +01:00
|
|
|
|
if (val == boolean_false_node)
|
1998-11-19 20:40:56 +01:00
|
|
|
|
warning ("comparison is always false due to limited range of data type");
|
1995-01-17 22:43:40 +01:00
|
|
|
|
if (val == boolean_true_node)
|
1998-11-19 20:40:56 +01:00
|
|
|
|
warning ("comparison is always true due to limited range of data type");
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
1993-11-25 00:14:43 +01:00
|
|
|
|
if (!min_lt && unsignedp0 && TREE_CODE (primop0) != INTEGER_CST)
|
1992-02-04 20:51:11 +01:00
|
|
|
|
{
|
1992-05-08 23:25:25 +02:00
|
|
|
|
/* This is the case of (unsigned char)x >?< -1 or < 0. */
|
1995-01-17 22:43:40 +01:00
|
|
|
|
if (val == boolean_false_node)
|
1998-11-19 20:40:56 +01:00
|
|
|
|
warning ("comparison is always false due to limited range of data type");
|
1995-01-17 22:43:40 +01:00
|
|
|
|
if (val == boolean_true_node)
|
1998-11-19 20:40:56 +01:00
|
|
|
|
warning ("comparison is always true due to limited range of data type");
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (val != 0)
|
|
|
|
|
{
|
|
|
|
|
/* Don't forget to evaluate PRIMOP0 if it has side effects. */
|
|
|
|
|
if (TREE_SIDE_EFFECTS (primop0))
|
|
|
|
|
return build (COMPOUND_EXPR, TREE_TYPE (val), primop0, val);
|
|
|
|
|
return val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Value is not predetermined, but do the comparison
|
|
|
|
|
in the type of the operand that is not constant.
|
|
|
|
|
TYPE is already properly set. */
|
|
|
|
|
}
|
|
|
|
|
else if (real1 && real2
|
1993-03-04 20:36:42 +01:00
|
|
|
|
&& (TYPE_PRECISION (TREE_TYPE (primop0))
|
|
|
|
|
== TYPE_PRECISION (TREE_TYPE (primop1))))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
type = TREE_TYPE (primop0);
|
|
|
|
|
|
|
|
|
|
/* If args' natural types are both narrower than nominal type
|
|
|
|
|
and both extend in the same manner, compare them
|
|
|
|
|
in the type of the wider arg.
|
|
|
|
|
Otherwise must actually extend both to the nominal
|
|
|
|
|
common type lest different ways of extending
|
|
|
|
|
alter the result.
|
|
|
|
|
(eg, (short)-1 == (unsigned short)-1 should be 0.) */
|
|
|
|
|
|
|
|
|
|
else if (unsignedp0 == unsignedp1 && real1 == real2
|
|
|
|
|
&& TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr)
|
|
|
|
|
&& TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (*restype_ptr))
|
|
|
|
|
{
|
|
|
|
|
type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
|
|
|
|
|
type = signed_or_unsigned_type (unsignedp0
|
|
|
|
|
|| TREE_UNSIGNED (*restype_ptr),
|
|
|
|
|
type);
|
|
|
|
|
/* Make sure shorter operand is extended the right way
|
|
|
|
|
to match the longer operand. */
|
|
|
|
|
primop0 = convert (signed_or_unsigned_type (unsignedp0, TREE_TYPE (primop0)),
|
|
|
|
|
primop0);
|
|
|
|
|
primop1 = convert (signed_or_unsigned_type (unsignedp1, TREE_TYPE (primop1)),
|
|
|
|
|
primop1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Here we must do the comparison on the nominal type
|
|
|
|
|
using the args exactly as we received them. */
|
|
|
|
|
type = *restype_ptr;
|
|
|
|
|
primop0 = op0;
|
|
|
|
|
primop1 = op1;
|
|
|
|
|
|
|
|
|
|
if (!real1 && !real2 && integer_zerop (primop1)
|
1994-03-18 00:39:11 +01:00
|
|
|
|
&& TREE_UNSIGNED (*restype_ptr))
|
1992-02-04 20:51:11 +01:00
|
|
|
|
{
|
|
|
|
|
tree value = 0;
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case GE_EXPR:
|
1994-08-25 23:43:46 +02:00
|
|
|
|
/* All unsigned values are >= 0, so we warn if extra warnings
|
|
|
|
|
are requested. However, if OP0 is a constant that is
|
|
|
|
|
>= 0, the signedness of the comparison isn't an issue,
|
|
|
|
|
so suppress the warning. */
|
2000-07-17 10:33:55 +02:00
|
|
|
|
if (extra_warnings && !in_system_header
|
1994-08-25 23:43:46 +02:00
|
|
|
|
&& ! (TREE_CODE (primop0) == INTEGER_CST
|
|
|
|
|
&& ! TREE_OVERFLOW (convert (signed_type (type),
|
|
|
|
|
primop0))))
|
1998-11-19 20:40:56 +01:00
|
|
|
|
warning ("comparison of unsigned expression >= 0 is always true");
|
1995-01-17 22:43:40 +01:00
|
|
|
|
value = boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LT_EXPR:
|
2000-07-17 10:33:55 +02:00
|
|
|
|
if (extra_warnings && !in_system_header
|
1994-08-25 23:43:46 +02:00
|
|
|
|
&& ! (TREE_CODE (primop0) == INTEGER_CST
|
|
|
|
|
&& ! TREE_OVERFLOW (convert (signed_type (type),
|
|
|
|
|
primop0))))
|
1998-11-19 20:40:56 +01:00
|
|
|
|
warning ("comparison of unsigned expression < 0 is always false");
|
1995-01-17 22:43:40 +01:00
|
|
|
|
value = boolean_false_node;
|
1998-02-05 21:54:49 +01:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value != 0)
|
|
|
|
|
{
|
|
|
|
|
/* Don't forget to evaluate PRIMOP0 if it has side effects. */
|
|
|
|
|
if (TREE_SIDE_EFFECTS (primop0))
|
|
|
|
|
return build (COMPOUND_EXPR, TREE_TYPE (value),
|
|
|
|
|
primop0, value);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*op0_ptr = convert (type, primop0);
|
|
|
|
|
*op1_ptr = convert (type, primop1);
|
|
|
|
|
|
1995-01-17 22:43:40 +01:00
|
|
|
|
*restype_ptr = boolean_type_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
|
|
|
|
|
or validate its data type for an `if' or `while' statement or ?..: exp.
|
|
|
|
|
|
|
|
|
|
This preparation consists of taking the ordinary
|
|
|
|
|
representation of an expression expr and producing a valid tree
|
|
|
|
|
boolean expression describing whether expr is nonzero. We could
|
1995-01-17 22:43:40 +01:00
|
|
|
|
simply always do build_binary_op (NE_EXPR, expr, boolean_false_node, 1),
|
1992-02-04 20:51:11 +01:00
|
|
|
|
but we optimize comparisons, &&, ||, and !.
|
|
|
|
|
|
1995-01-17 22:43:40 +01:00
|
|
|
|
The resulting type should always be `boolean_type_node'. */
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
truthvalue_conversion (expr)
|
|
|
|
|
tree expr;
|
|
|
|
|
{
|
1993-05-01 06:09:06 +02:00
|
|
|
|
if (TREE_CODE (expr) == ERROR_MARK)
|
|
|
|
|
return expr;
|
|
|
|
|
|
1993-05-06 17:58:59 +02:00
|
|
|
|
#if 0 /* This appears to be wrong for C++. */
|
1993-05-01 06:09:06 +02:00
|
|
|
|
/* These really should return error_mark_node after 2.4 is stable.
|
|
|
|
|
But not all callers handle ERROR_MARK properly. */
|
|
|
|
|
switch (TREE_CODE (TREE_TYPE (expr)))
|
|
|
|
|
{
|
|
|
|
|
case RECORD_TYPE:
|
|
|
|
|
error ("struct type value used where scalar is required");
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return boolean_false_node;
|
1993-05-01 06:09:06 +02:00
|
|
|
|
|
|
|
|
|
case UNION_TYPE:
|
|
|
|
|
error ("union type value used where scalar is required");
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return boolean_false_node;
|
1993-05-01 06:09:06 +02:00
|
|
|
|
|
|
|
|
|
case ARRAY_TYPE:
|
|
|
|
|
error ("array type value used where scalar is required");
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return boolean_false_node;
|
1993-05-01 06:09:06 +02:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
1993-05-06 17:58:59 +02:00
|
|
|
|
#endif /* 0 */
|
1993-05-01 06:09:06 +02:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
switch (TREE_CODE (expr))
|
|
|
|
|
{
|
|
|
|
|
case EQ_EXPR:
|
|
|
|
|
case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
|
|
|
|
|
case TRUTH_ANDIF_EXPR:
|
|
|
|
|
case TRUTH_ORIF_EXPR:
|
|
|
|
|
case TRUTH_AND_EXPR:
|
|
|
|
|
case TRUTH_OR_EXPR:
|
1992-12-30 12:01:57 +01:00
|
|
|
|
case TRUTH_XOR_EXPR:
|
1995-05-24 21:41:29 +02:00
|
|
|
|
case TRUTH_NOT_EXPR:
|
1995-01-17 22:43:40 +01:00
|
|
|
|
TREE_TYPE (expr) = boolean_type_node;
|
|
|
|
|
return expr;
|
1994-03-14 03:16:59 +01:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
case ERROR_MARK:
|
|
|
|
|
return expr;
|
|
|
|
|
|
|
|
|
|
case INTEGER_CST:
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
case REAL_CST:
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return real_zerop (expr) ? boolean_false_node : boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
|
|
|
|
case ADDR_EXPR:
|
1996-05-06 21:41:35 +02:00
|
|
|
|
/* If we are taking the address of a external decl, it might be zero
|
|
|
|
|
if it is weak, so we cannot optimize. */
|
builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
* builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
* c-common.c (decl_attributes,check_format_info,truthvalue_conversion,
c_get_alias_set): Likewise.
* c-decl.c (duplicate_decls): Likewise.
* c-typeck.c (default_conversion,build_unary_op): Likewise.
* calls.c (initialize_argument_information): Likewise.
* dwarf2out.c (decl_class_context,add_abstract_origin_attribute):
Likewise.
* dwarfout.c (decl_class_context,output_type): Likewise.
* expr.c (get_inner_reference): Likewise.
* fold-const.c (simple_operand_p,fold): Likewise.
* function.c (aggregate_value_p): Likewise.
* stmt.c (expand_asm_operands): Likewise.
* varasm.c (named_section): Likewise.
* call.c (check_dtor_name,build_new_method_call): Likewise.
* decl.c (push_class_binding,poplevel,pushtag,lookup_namespace_name,
make_typename_type,check_initializer,cp_finish_decl,xref_tag): Likewise.
* decl2.c (grokfield,build_expr_from_tree,build_expr_from_tree,
decl_namespace,arg_assoc_template_arg,arg_assoc,
validate_nonmember_using_decl,do_class_using_decl): Likewise.
* error.c (dump_template_argument,dump_expr,cp_file_of,cp_line_of,
args_to_string): Likewise.
* friend.c (is_friend): Likewise.
* lex.c (note_got_semicolon,note_list_got_semicolon,is_global): Likewise.
* method.c (build_overload_nested_name,build_overload_value,
build_qualified_name,build_qualified_name,hack_identifier): Likewise.
* parse.y (typename_sub,typename_sub1): Likewise.
* pt.c (push_inline_template_parms_recursive,check_template_shadow,
process_partial_specialization,convert_template_argument,
template_args_equal,add_pending_template,lookup_template_class,
for_each_template_parm_r,maybe_fold_nontype_arg,
tsubst,instantiate_template,type_unification_real,unify,
instantiate_pending_templates,set_mangled_name_for_template_decl):
Likewise.
* repo.c (repo_get_id,repo_template_used): Likewise.
* search.c (lookup_field_1): Likewise.
* tree.c (walk_tree,get_type_decl,cp_tree_equal,member_p): Likewise.
* xref.c (classname): Likewise.
From-SVN: r32698
2000-03-23 01:41:05 +01:00
|
|
|
|
if (DECL_P (TREE_OPERAND (expr, 0))
|
1996-05-06 21:41:35 +02:00
|
|
|
|
&& DECL_EXTERNAL (TREE_OPERAND (expr, 0)))
|
|
|
|
|
break;
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return build (COMPOUND_EXPR, boolean_type_node,
|
|
|
|
|
TREE_OPERAND (expr, 0), boolean_true_node);
|
1992-02-04 20:51:11 +01:00
|
|
|
|
else
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return boolean_true_node;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
|
1993-03-04 20:36:42 +01:00
|
|
|
|
case COMPLEX_EXPR:
|
1993-03-04 21:34:56 +01:00
|
|
|
|
return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
|
1993-09-04 17:16:10 +02:00
|
|
|
|
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
|
1993-03-04 21:34:56 +01:00
|
|
|
|
truthvalue_conversion (TREE_OPERAND (expr, 0)),
|
|
|
|
|
truthvalue_conversion (TREE_OPERAND (expr, 1)),
|
1993-03-04 20:36:42 +01:00
|
|
|
|
0);
|
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
case NEGATE_EXPR:
|
|
|
|
|
case ABS_EXPR:
|
|
|
|
|
case FLOAT_EXPR:
|
|
|
|
|
case FFS_EXPR:
|
|
|
|
|
/* These don't change whether an object is non-zero or zero. */
|
|
|
|
|
return truthvalue_conversion (TREE_OPERAND (expr, 0));
|
|
|
|
|
|
|
|
|
|
case LROTATE_EXPR:
|
|
|
|
|
case RROTATE_EXPR:
|
|
|
|
|
/* These don't change whether an object is zero or non-zero, but
|
|
|
|
|
we can't ignore them if their second arg has side-effects. */
|
|
|
|
|
if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return build (COMPOUND_EXPR, boolean_type_node, TREE_OPERAND (expr, 1),
|
1992-02-04 20:51:11 +01:00
|
|
|
|
truthvalue_conversion (TREE_OPERAND (expr, 0)));
|
|
|
|
|
else
|
|
|
|
|
return truthvalue_conversion (TREE_OPERAND (expr, 0));
|
1998-05-04 22:19:33 +02:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
case COND_EXPR:
|
|
|
|
|
/* Distribute the conversion into the arms of a COND_EXPR. */
|
1995-01-17 22:43:40 +01:00
|
|
|
|
return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
|
1992-02-04 20:51:11 +01:00
|
|
|
|
truthvalue_conversion (TREE_OPERAND (expr, 1)),
|
|
|
|
|
truthvalue_conversion (TREE_OPERAND (expr, 2))));
|
|
|
|
|
|
|
|
|
|
case CONVERT_EXPR:
|
|
|
|
|
/* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
|
|
|
|
|
since that affects how `default_conversion' will behave. */
|
|
|
|
|
if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
|
|
|
|
|
|| TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
|
|
|
|
|
break;
|
1996-07-04 00:07:53 +02:00
|
|
|
|
/* fall through... */
|
1992-02-04 20:51:11 +01:00
|
|
|
|
case NOP_EXPR:
|
|
|
|
|
/* If this is widening the argument, we can ignore it. */
|
|
|
|
|
if (TYPE_PRECISION (TREE_TYPE (expr))
|
|
|
|
|
>= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
|
|
|
|
|
return truthvalue_conversion (TREE_OPERAND (expr, 0));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case MINUS_EXPR:
|
1993-05-04 01:33:42 +02:00
|
|
|
|
/* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
|
|
|
|
|
this case. */
|
|
|
|
|
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
|
|
|
|
|
break;
|
1996-07-04 00:07:53 +02:00
|
|
|
|
/* fall through... */
|
1993-05-04 01:33:42 +02:00
|
|
|
|
case BIT_XOR_EXPR:
|
1993-05-06 17:58:59 +02:00
|
|
|
|
/* This and MINUS_EXPR can be changed into a comparison of the
|
1993-05-04 01:33:42 +02:00
|
|
|
|
two objects. */
|
1992-02-04 20:51:11 +01:00
|
|
|
|
if (TREE_TYPE (TREE_OPERAND (expr, 0))
|
|
|
|
|
== TREE_TYPE (TREE_OPERAND (expr, 1)))
|
|
|
|
|
return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
|
|
|
|
|
TREE_OPERAND (expr, 1), 1);
|
|
|
|
|
return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
|
|
|
|
|
fold (build1 (NOP_EXPR,
|
|
|
|
|
TREE_TYPE (TREE_OPERAND (expr, 0)),
|
|
|
|
|
TREE_OPERAND (expr, 1))), 1);
|
1992-08-15 01:45:09 +02:00
|
|
|
|
|
1994-05-13 22:30:24 +02:00
|
|
|
|
case BIT_AND_EXPR:
|
1995-05-31 13:31:46 +02:00
|
|
|
|
if (integer_onep (TREE_OPERAND (expr, 1))
|
|
|
|
|
&& TREE_TYPE (expr) != boolean_type_node)
|
|
|
|
|
/* Using convert here would cause infinite recursion. */
|
|
|
|
|
return build1 (NOP_EXPR, boolean_type_node, expr);
|
|
|
|
|
break;
|
1994-05-13 22:30:24 +02:00
|
|
|
|
|
1992-08-15 01:45:09 +02:00
|
|
|
|
case MODIFY_EXPR:
|
|
|
|
|
if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
|
|
|
|
|
warning ("suggest parentheses around assignment used as truth value");
|
|
|
|
|
break;
|
1998-05-04 22:19:33 +02:00
|
|
|
|
|
1998-02-05 21:54:49 +01:00
|
|
|
|
default:
|
|
|
|
|
break;
|
1992-02-04 20:51:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
1993-03-04 21:34:56 +01:00
|
|
|
|
if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
|
1998-06-19 03:46:50 +02:00
|
|
|
|
{
|
|
|
|
|
tree tem = save_expr (expr);
|
|
|
|
|
return (build_binary_op
|
|
|
|
|
((TREE_SIDE_EFFECTS (expr)
|
|
|
|
|
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
|
|
|
|
|
truthvalue_conversion (build_unary_op (REALPART_EXPR, tem, 0)),
|
|
|
|
|
truthvalue_conversion (build_unary_op (IMAGPART_EXPR, tem, 0)),
|
|
|
|
|
0));
|
|
|
|
|
}
|
1993-03-04 21:34:56 +01:00
|
|
|
|
|
1992-02-04 20:51:11 +01:00
|
|
|
|
return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2000-12-23 01:48:08 +01:00
|
|
|
|
static tree builtin_function_2 PARAMS ((const char *, const char *, tree, tree,
|
|
|
|
|
int, enum built_in_class, int, int,
|
|
|
|
|
int));
|
|
|
|
|
|
1993-01-30 07:06:09 +01:00
|
|
|
|
/* Make a variant type in the proper way for C/C++, propagating qualifiers
|
|
|
|
|
down to the element type of an array. */
|
|
|
|
|
|
|
|
|
|
tree
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
c_build_qualified_type (type, type_quals)
|
1993-01-30 07:06:09 +01:00
|
|
|
|
tree type;
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
int type_quals;
|
1993-01-30 07:06:09 +01: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
1998-10-21 11:53:40 +02:00
|
|
|
|
/* 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;
|
|
|
|
|
}
|
|
|
|
|
|
1993-01-30 07:06:09 +01:00
|
|
|
|
if (TREE_CODE (type) == ARRAY_TYPE)
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
return build_array_type (c_build_qualified_type (TREE_TYPE (type),
|
|
|
|
|
type_quals),
|
1997-06-10 00:37:37 +02:00
|
|
|
|
TYPE_DOMAIN (type));
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
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;
|
|
|
|
|
{
|
2000-04-28 04:04:00 +02:00
|
|
|
|
if ((type_quals & TYPE_QUAL_CONST)
|
|
|
|
|
|| (TREE_TYPE (decl)
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE))
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
TREE_READONLY (decl) = 1;
|
|
|
|
|
if (type_quals & TYPE_QUAL_VOLATILE)
|
|
|
|
|
{
|
|
|
|
|
TREE_SIDE_EFFECTS (decl) = 1;
|
|
|
|
|
TREE_THIS_VOLATILE (decl) = 1;
|
|
|
|
|
}
|
1998-10-21 11:59:32 +02:00
|
|
|
|
if (type_quals & TYPE_QUAL_RESTRICT)
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
{
|
1998-10-21 11:59:32 +02:00
|
|
|
|
if (!TREE_TYPE (decl)
|
|
|
|
|
|| !POINTER_TYPE_P (TREE_TYPE (decl))
|
|
|
|
|
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl))))
|
|
|
|
|
error ("invalid use of `restrict'");
|
|
|
|
|
else if (flag_strict_aliasing)
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
{
|
1998-10-21 11:59:32 +02:00
|
|
|
|
/* 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. */
|
|
|
|
|
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
HOST_WIDE_INT pointed_to_alias_set
|
1998-10-21 11:59:32 +02:00
|
|
|
|
= get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
|
2000-01-03 22:48:49 +01:00
|
|
|
|
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
if (pointed_to_alias_set == 0)
|
1998-10-21 11:59:32 +02:00
|
|
|
|
/* 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));
|
|
|
|
|
}
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-25 17:14:41 +02:00
|
|
|
|
|
|
|
|
|
/* Return the typed-based alias set for T, which may be an expression
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
or a type. Return -1 if we don't do anything special. */
|
1998-06-25 17:14:41 +02:00
|
|
|
|
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
HOST_WIDE_INT
|
2000-06-03 02:33:00 +02:00
|
|
|
|
lang_get_alias_set (t)
|
1998-06-25 17:14:41 +02:00
|
|
|
|
tree t;
|
|
|
|
|
{
|
1998-10-31 21:44:46 +01:00
|
|
|
|
tree u;
|
2001-01-05 18:22:30 +01:00
|
|
|
|
|
|
|
|
|
/* We know nothing about vector types */
|
|
|
|
|
if (TREE_CODE (t) == VECTOR_TYPE)
|
|
|
|
|
return 0;
|
|
|
|
|
|
1998-10-31 21:44:46 +01:00
|
|
|
|
/* Permit type-punning when accessing a union, provided the access
|
|
|
|
|
is directly through the union. For example, this code does not
|
|
|
|
|
permit taking the address of a union member and then storing
|
|
|
|
|
through it. Even the type-punning allowed here is a GCC
|
|
|
|
|
extension, albeit a common and useful one; the C standard says
|
|
|
|
|
that such accesses have implementation-defined behavior. */
|
|
|
|
|
for (u = t;
|
|
|
|
|
TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
|
|
|
|
|
u = TREE_OPERAND (u, 0))
|
|
|
|
|
if (TREE_CODE (u) == COMPONENT_REF
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
|
|
|
|
|
return 0;
|
1998-09-28 09:44:12 +02:00
|
|
|
|
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
/* If this is a char *, the ANSI C standard says it can alias
|
2000-06-01 18:18:18 +02:00
|
|
|
|
anything. Note that all references need do this. */
|
|
|
|
|
if (TREE_CODE_CLASS (TREE_CODE (t)) == 'r'
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
|
|
|
|
|
&& TYPE_PRECISION (TREE_TYPE (t)) == TYPE_PRECISION (char_type_node))
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
return 0;
|
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
1998-10-21 11:53:40 +02:00
|
|
|
|
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
/* That's all the expressions we handle specially. */
|
|
|
|
|
if (! TYPE_P (t))
|
|
|
|
|
return -1;
|
1998-06-25 17:14:41 +02:00
|
|
|
|
|
2000-06-01 18:18:18 +02:00
|
|
|
|
/* The C standard specifically allows aliasing between signed and
|
|
|
|
|
unsigned variants of the same type. We treat the signed
|
|
|
|
|
variant as canonical. */
|
|
|
|
|
if (TREE_CODE (t) == INTEGER_TYPE && TREE_UNSIGNED (t))
|
2000-06-02 14:50:08 +02:00
|
|
|
|
{
|
|
|
|
|
tree t1 = signed_type (t);
|
2000-06-01 18:18:18 +02:00
|
|
|
|
|
2000-06-02 14:50:08 +02:00
|
|
|
|
/* t1 == t can happen for boolean nodes which are always unsigned. */
|
|
|
|
|
if (t1 != t)
|
|
|
|
|
return get_alias_set (t1);
|
|
|
|
|
}
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
else if (POINTER_TYPE_P (t))
|
1999-08-19 23:39:04 +02:00
|
|
|
|
{
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
tree t1;
|
1999-08-19 23:39:04 +02:00
|
|
|
|
|
|
|
|
|
/* Unfortunately, there is no canonical form of a pointer type.
|
|
|
|
|
In particular, if we have `typedef int I', then `int *', and
|
|
|
|
|
`I *' are different types. So, we have to pick a canonical
|
|
|
|
|
representative. We do this below.
|
2000-01-03 22:48:49 +01:00
|
|
|
|
|
1999-08-20 23:57:38 +02:00
|
|
|
|
Technically, this approach is actually more conservative that
|
|
|
|
|
it needs to be. In particular, `const int *' and `int *'
|
|
|
|
|
chould be in different alias sets, according to the C and C++
|
|
|
|
|
standard, since their types are not the same, and so,
|
|
|
|
|
technically, an `int **' and `const int **' cannot point at
|
|
|
|
|
the same thing.
|
|
|
|
|
|
|
|
|
|
But, the standard is wrong. In particular, this code is
|
|
|
|
|
legal C++:
|
|
|
|
|
|
|
|
|
|
int *ip;
|
|
|
|
|
int **ipp = &ip;
|
2001-05-21 18:06:37 +02:00
|
|
|
|
const int* const* cipp = &ipp;
|
1999-08-20 23:57:38 +02:00
|
|
|
|
|
|
|
|
|
And, it doesn't make sense for that to be legal unless you
|
|
|
|
|
can dereference IPP and CIPP. So, we ignore cv-qualifiers on
|
|
|
|
|
the pointed-to types. This issue has been reported to the
|
|
|
|
|
C++ committee. */
|
2000-11-15 15:39:14 +01:00
|
|
|
|
t1 = build_type_no_quals (t);
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
if (t1 != t)
|
|
|
|
|
return get_alias_set (t1);
|
1999-08-19 23:39:04 +02:00
|
|
|
|
}
|
2000-06-06 23:54:54 +02:00
|
|
|
|
/* It's not yet safe to use alias sets for classes in C++ because
|
|
|
|
|
the TYPE_FIELDs list for a class doesn't mention base classes. */
|
2000-06-12 21:14:08 +02:00
|
|
|
|
else if (c_language == clk_cplusplus && AGGREGATE_TYPE_P (t))
|
2000-06-06 23:54:54 +02:00
|
|
|
|
return 0;
|
1998-09-28 09:44:12 +02:00
|
|
|
|
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
return -1;
|
1998-06-25 17:14:41 +02:00
|
|
|
|
}
|
1999-07-20 12:41:10 +02:00
|
|
|
|
|
|
|
|
|
/* Build tree nodes and builtin functions common to both C and C++ language
|
2000-10-18 20:59:04 +02:00
|
|
|
|
frontends. */
|
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
2000-05-31 20:37:31 +02:00
|
|
|
|
|
1999-07-20 12:41:10 +02:00
|
|
|
|
void
|
2000-10-18 20:59:04 +02:00
|
|
|
|
c_common_nodes_and_builtins ()
|
1999-07-20 12:41:10 +02:00
|
|
|
|
{
|
2001-05-25 22:00:59 +02:00
|
|
|
|
enum builtin_type
|
|
|
|
|
{
|
|
|
|
|
#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
|
|
|
|
|
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
|
|
|
|
|
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
|
|
|
|
|
#include "builtin-types.def"
|
|
|
|
|
#undef DEF_PRIMITIVE_TYPE
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_0
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_1
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_2
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_3
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_4
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_VAR_0
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_VAR_1
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_VAR_2
|
|
|
|
|
#undef DEF_POINTER_TYPE
|
|
|
|
|
BT_LAST
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef enum builtin_type builtin_type;
|
|
|
|
|
|
|
|
|
|
tree builtin_types[(int)BT_LAST];
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
int wchar_type_size;
|
|
|
|
|
tree array_domain_type;
|
1999-07-20 12:41:10 +02:00
|
|
|
|
/* Either char* or void*. */
|
|
|
|
|
tree traditional_ptr_type_node;
|
2000-03-23 22:32:10 +01:00
|
|
|
|
/* Either const char* or const void*. */
|
|
|
|
|
tree traditional_cptr_type_node;
|
|
|
|
|
tree traditional_len_type_node;
|
2000-03-30 02:03:14 +02:00
|
|
|
|
tree va_list_ref_type_node;
|
1999-07-27 07:43:56 +02:00
|
|
|
|
tree va_list_arg_type_node;
|
builtins.c (expand_builtin_saveregs): Remove static, remove exp and ignore arguments, bail if no EXPAND_BUILTIN_SAVEREGS.
* builtins.c (expand_builtin_saveregs): Remove static, remove exp
and ignore arguments, bail if no EXPAND_BUILTIN_SAVEREGS.
(expand_builtin_next_arg): Accept ARGLIST not EXP.
(stabilize_va_list): New function.
(std_expand_builtin_va_start): New function.
(expand_builtin_va_start): New function.
(get_varargs_alias_set): New function.
(std_expand_builtin_va_arg): New function.
(expand_builtin_va_arg): New function.
(expand_builtin_va_end): New function.
(expand_builtin_va_copy): New function.
(expand_builtin): Call them.
* c-common.c (c_common_nodes_and_builtins): Build __builtin_va_list,
__builtin_{varargs_start,stdarg_start,end,copy}.
(build_va_arg): New function.
* c-common.h (CTI_PTR_TYPE, ptr_type_node): Delete.
(build_va_arg): Declare.
* c-decl.c (ptr_type_node, va_list_type_node): New.
* c-parse.gperf (__builtin_va_arg): New.
* c-parse.in (VA_ARG): New token.
(unary_expr): Recognize it.
* expr.c (expand_expr): Expand VA_ARG_EXPR.
* expr.h (std_expand_builtin_va_start): Declare.
(std_expand_builtin_va_arg): Declare.
(expand_builtin_va_arg): Declare.
(get_varargs_alias_set): Declare.
* tree.def (VA_ARG_EXPR): New.
* tree.h (BUILT_IN_VARARGS_START): New.
(BUILT_IN_STDARG_START, BUILT_IN_VA_END): New.
(ptr_type_node, va_list_type_node): Declare.
* tm.texi (EXPAND_BUILTIN_SAVEREGS): Kill unused ARGLIST argument.
* m32r.h (EXPAND_BUILTIN_SAVEREGS): Likewise.
* m88k.h, m88k.c: Likewise.
* mn10300.h, mn10300.c: Likewise.
* pa.h, pa.c: Likewise.
* rs6000.h, rs6000.c: Likewise.
* sh.h, sh.c: Likewise.
* sparc.h, sparc.c: Likewise.
* emit-rtl.c (operand_subword): Copy alias set.
(change_address): Likewise.
From-SVN: r28243
1999-07-26 03:21:03 +02:00
|
|
|
|
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
/* Define `int' and `char' first so that dbx will output them first. */
|
2001-05-01 14:11:35 +02:00
|
|
|
|
record_builtin_type (RID_INT, NULL, integer_type_node);
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
record_builtin_type (RID_CHAR, "char", char_type_node);
|
|
|
|
|
|
|
|
|
|
/* `signed' is the same as `int'. FIXME: the declarations of "signed",
|
|
|
|
|
"unsigned long", "long long unsigned" and "unsigned short" were in C++
|
|
|
|
|
but not C. Are the conditionals here needed? */
|
|
|
|
|
if (c_language == clk_cplusplus)
|
2001-05-01 14:11:35 +02:00
|
|
|
|
record_builtin_type (RID_SIGNED, NULL, integer_type_node);
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
record_builtin_type (RID_LONG, "long int", long_integer_type_node);
|
|
|
|
|
record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node);
|
|
|
|
|
record_builtin_type (RID_MAX, "long unsigned int",
|
|
|
|
|
long_unsigned_type_node);
|
|
|
|
|
if (c_language == clk_cplusplus)
|
|
|
|
|
record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
|
|
|
|
|
record_builtin_type (RID_MAX, "long long int",
|
|
|
|
|
long_long_integer_type_node);
|
|
|
|
|
record_builtin_type (RID_MAX, "long long unsigned int",
|
|
|
|
|
long_long_unsigned_type_node);
|
|
|
|
|
if (c_language == clk_cplusplus)
|
|
|
|
|
record_builtin_type (RID_MAX, "long long unsigned",
|
|
|
|
|
long_long_unsigned_type_node);
|
|
|
|
|
record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
|
|
|
|
|
record_builtin_type (RID_MAX, "short unsigned int",
|
|
|
|
|
short_unsigned_type_node);
|
|
|
|
|
if (c_language == clk_cplusplus)
|
|
|
|
|
record_builtin_type (RID_MAX, "unsigned short",
|
|
|
|
|
short_unsigned_type_node);
|
|
|
|
|
|
|
|
|
|
/* Define both `signed char' and `unsigned char'. */
|
|
|
|
|
record_builtin_type (RID_MAX, "signed char", signed_char_type_node);
|
|
|
|
|
record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node);
|
|
|
|
|
|
|
|
|
|
/* These are types that type_for_size and type_for_mode use. */
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
|
|
|
|
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node));
|
|
|
|
|
#endif
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
|
|
|
|
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Create the widest literal types. */
|
|
|
|
|
widest_integer_literal_type_node
|
|
|
|
|
= make_signed_type (HOST_BITS_PER_WIDE_INT * 2);
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE,
|
|
|
|
|
widest_integer_literal_type_node));
|
|
|
|
|
|
|
|
|
|
widest_unsigned_literal_type_node
|
|
|
|
|
= make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2);
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, NULL_TREE,
|
|
|
|
|
widest_unsigned_literal_type_node));
|
|
|
|
|
|
|
|
|
|
/* `unsigned long' is the standard type for sizeof.
|
|
|
|
|
Note that stddef.h uses `unsigned long',
|
|
|
|
|
and this must agree, even if long and int are the same size. */
|
|
|
|
|
c_size_type_node =
|
|
|
|
|
TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE)));
|
|
|
|
|
signed_size_type_node = signed_type (c_size_type_node);
|
|
|
|
|
if (flag_traditional)
|
|
|
|
|
c_size_type_node = signed_size_type_node;
|
|
|
|
|
set_sizetype (c_size_type_node);
|
|
|
|
|
|
|
|
|
|
build_common_tree_nodes_2 (flag_short_double);
|
|
|
|
|
|
2001-05-01 14:11:35 +02:00
|
|
|
|
record_builtin_type (RID_FLOAT, NULL, float_type_node);
|
|
|
|
|
record_builtin_type (RID_DOUBLE, NULL, double_type_node);
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
record_builtin_type (RID_MAX, "long double", long_double_type_node);
|
|
|
|
|
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
|
|
|
|
|
complex_integer_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
|
|
|
|
|
complex_float_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
|
|
|
|
|
complex_double_type_node));
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
|
|
|
|
|
complex_long_double_type_node));
|
|
|
|
|
|
2001-05-01 14:11:35 +02:00
|
|
|
|
record_builtin_type (RID_VOID, NULL, void_type_node);
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
|
2001-05-25 22:00:59 +02:00
|
|
|
|
void_zero_node = build_int_2 (0, 0);
|
|
|
|
|
TREE_TYPE (void_zero_node) = void_type_node;
|
|
|
|
|
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
void_list_node = build_void_list_node ();
|
|
|
|
|
|
|
|
|
|
/* Make a type to be the domain of a few array types
|
|
|
|
|
whose domains don't really matter.
|
|
|
|
|
200 is small enough that it always fits in size_t
|
|
|
|
|
and large enough that it can hold most function names for the
|
|
|
|
|
initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */
|
|
|
|
|
array_domain_type = build_index_type (size_int (200));
|
|
|
|
|
|
|
|
|
|
/* Make a type for arrays of characters.
|
|
|
|
|
With luck nothing will ever really depend on the length of this
|
|
|
|
|
array type. */
|
|
|
|
|
char_array_type_node
|
|
|
|
|
= build_array_type (char_type_node, array_domain_type);
|
|
|
|
|
|
|
|
|
|
/* Likewise for arrays of ints. */
|
|
|
|
|
int_array_type_node
|
|
|
|
|
= build_array_type (integer_type_node, array_domain_type);
|
|
|
|
|
|
2001-05-25 22:00:59 +02:00
|
|
|
|
string_type_node = build_pointer_type (char_type_node);
|
|
|
|
|
const_string_type_node
|
|
|
|
|
= build_pointer_type (build_qualified_type
|
|
|
|
|
(char_type_node, TYPE_QUAL_CONST));
|
|
|
|
|
|
|
|
|
|
traditional_ptr_type_node = ((flag_traditional &&
|
|
|
|
|
c_language != clk_cplusplus)
|
|
|
|
|
? string_type_node : ptr_type_node);
|
|
|
|
|
traditional_cptr_type_node = ((flag_traditional &&
|
|
|
|
|
c_language != clk_cplusplus)
|
|
|
|
|
? const_string_type_node : const_ptr_type_node);
|
|
|
|
|
|
c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
* c-common.c (SIZE_TYPE, WCHAR_TYPE): Define.
(flag_short_double, flag_short_wchar): Define.
(c_common_nodes_and_builtins): Create many tree nodes shared
between C and C++ here instead of in cp/decl.c and ...
* c-decl.c (init_decl_processing): ... here.
(SIZE_TYPE, WCHAR_TYPE): Don't define.
(flag_short_double, flag_short_wchar): Don't define.
(record_builtin_type): New function.
(build_void_list_node): New function.
* c-common.h (flag_short_double, flag_short_wchar,
record_builtin_type, build_void_list_node): Declare.
cp:
* decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
(record_builtin_type): Make non-static.
(flag_short_double): Don't declare.
(init_decl_processing): Remove the creation of many tree nodes now
in c_common_nodes_and_builtins.
(build_void_list_node): New function.
* decl2.c (flag_short_double, flag_short_wchar): Don't define.
* cp-tree.h (flag_short_wchar): Don't declare.
From-SVN: r38695
2001-01-05 00:53:54 +01:00
|
|
|
|
MD_INIT_BUILTINS;
|
|
|
|
|
|
|
|
|
|
/* This is special for C++ so functions can be overloaded. */
|
|
|
|
|
wchar_type_node = get_identifier (flag_short_wchar
|
|
|
|
|
? "short unsigned int"
|
|
|
|
|
: WCHAR_TYPE);
|
|
|
|
|
wchar_type_node = TREE_TYPE (identifier_global_value (wchar_type_node));
|
|
|
|
|
wchar_type_size = TYPE_PRECISION (wchar_type_node);
|
|
|
|
|
if (c_language == clk_cplusplus)
|
|
|
|
|
{
|
|
|
|
|
if (TREE_UNSIGNED (wchar_type_node))
|
|
|
|
|
wchar_type_node = make_unsigned_type (wchar_type_size);
|
|
|
|
|
else
|
|
|
|
|
wchar_type_node = make_signed_type (wchar_type_size);
|
|
|
|
|
record_builtin_type (RID_WCHAR, "wchar_t", wchar_type_node);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
signed_wchar_type_node = signed_type (wchar_type_node);
|
|
|
|
|
unsigned_wchar_type_node = unsigned_type (wchar_type_node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This is for wide string constants. */
|
|
|
|
|
wchar_array_type_node
|
|
|
|
|
= build_array_type (wchar_type_node, array_domain_type);
|
|
|
|
|
|
c-common.c: Include "defaults.h".
* c-common.c: Include "defaults.h".
(WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Define.
(c_common_nodes_and_builtins): Create string_type_node,
const_string_type_node, wint_type_node, intmax_type_node,
uintmax_type_node, default_function_type, ptrdiff_type_node and
unsigned_ptrdiff_type_node.
* c-common.h (identifier_global_value): Declare.
* c-decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
(init_decl_processing): Don't create string_type_node,
const_string_type_node, wint_type_node, intmax_type_node,
uintmax_type_node, default_function_type, ptrdiff_type_node and
unsigned_ptrdiff_type_node.
(identifier_global_value): New function.
cp:
* decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
(init_decl_processing): Don't create string_type_node,
const_string_type_node, wint_type_node, intmax_type_node,
uintmax_type_node, default_function_type, ptrdiff_type_node and
unsigned_ptrdiff_type_node. Adjust position of call to
c_common_nodes_and_builtins.
(identifier_global_value): New function.
From-SVN: r37931
2000-12-01 23:25:43 +01:00
|
|
|
|
wint_type_node =
|
|
|
|
|
TREE_TYPE (identifier_global_value (get_identifier (WINT_TYPE)));
|
|
|
|
|
|
|
|
|
|
intmax_type_node =
|
|
|
|
|
TREE_TYPE (identifier_global_value (get_identifier (INTMAX_TYPE)));
|
|
|
|
|
uintmax_type_node =
|
|
|
|
|
TREE_TYPE (identifier_global_value (get_identifier (UINTMAX_TYPE)));
|
|
|
|
|
|
|
|
|
|
default_function_type = build_function_type (integer_type_node, NULL_TREE);
|
|
|
|
|
ptrdiff_type_node
|
|
|
|
|
= TREE_TYPE (identifier_global_value (get_identifier (PTRDIFF_TYPE)));
|
|
|
|
|
unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
|
|
|
|
|
|
builtins.c (expand_builtin_saveregs): Remove static, remove exp and ignore arguments, bail if no EXPAND_BUILTIN_SAVEREGS.
* builtins.c (expand_builtin_saveregs): Remove static, remove exp
and ignore arguments, bail if no EXPAND_BUILTIN_SAVEREGS.
(expand_builtin_next_arg): Accept ARGLIST not EXP.
(stabilize_va_list): New function.
(std_expand_builtin_va_start): New function.
(expand_builtin_va_start): New function.
(get_varargs_alias_set): New function.
(std_expand_builtin_va_arg): New function.
(expand_builtin_va_arg): New function.
(expand_builtin_va_end): New function.
(expand_builtin_va_copy): New function.
(expand_builtin): Call them.
* c-common.c (c_common_nodes_and_builtins): Build __builtin_va_list,
__builtin_{varargs_start,stdarg_start,end,copy}.
(build_va_arg): New function.
* c-common.h (CTI_PTR_TYPE, ptr_type_node): Delete.
(build_va_arg): Declare.
* c-decl.c (ptr_type_node, va_list_type_node): New.
* c-parse.gperf (__builtin_va_arg): New.
* c-parse.in (VA_ARG): New token.
(unary_expr): Recognize it.
* expr.c (expand_expr): Expand VA_ARG_EXPR.
* expr.h (std_expand_builtin_va_start): Declare.
(std_expand_builtin_va_arg): Declare.
(expand_builtin_va_arg): Declare.
(get_varargs_alias_set): Declare.
* tree.def (VA_ARG_EXPR): New.
* tree.h (BUILT_IN_VARARGS_START): New.
(BUILT_IN_STDARG_START, BUILT_IN_VA_END): New.
(ptr_type_node, va_list_type_node): Declare.
* tm.texi (EXPAND_BUILTIN_SAVEREGS): Kill unused ARGLIST argument.
* m32r.h (EXPAND_BUILTIN_SAVEREGS): Likewise.
* m88k.h, m88k.c: Likewise.
* mn10300.h, mn10300.c: Likewise.
* pa.h, pa.c: Likewise.
* rs6000.h, rs6000.c: Likewise.
* sh.h, sh.c: Likewise.
* sparc.h, sparc.c: Likewise.
* emit-rtl.c (operand_subword): Copy alias set.
(change_address): Likewise.
From-SVN: r28243
1999-07-26 03:21:03 +02:00
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
|
|
|
|
|
va_list_type_node));
|
1999-07-27 07:43:56 +02:00
|
|
|
|
|
1999-12-10 05:26:06 +01:00
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_ptrdiff_t"),
|
|
|
|
|
ptrdiff_type_node));
|
|
|
|
|
|
|
|
|
|
pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_size_t"),
|
|
|
|
|
sizetype));
|
|
|
|
|
|
1999-07-27 07:43:56 +02:00
|
|
|
|
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
|
2000-03-30 02:03:14 +02:00
|
|
|
|
{
|
|
|
|
|
va_list_arg_type_node = va_list_ref_type_node =
|
|
|
|
|
build_pointer_type (TREE_TYPE (va_list_type_node));
|
|
|
|
|
}
|
1999-07-27 07:43:56 +02:00
|
|
|
|
else
|
2000-03-30 02:03:14 +02:00
|
|
|
|
{
|
|
|
|
|
va_list_arg_type_node = va_list_type_node;
|
|
|
|
|
va_list_ref_type_node = build_reference_type (va_list_type_node);
|
|
|
|
|
}
|
|
|
|
|
|
2000-10-18 20:59:04 +02:00
|
|
|
|
traditional_len_type_node = ((flag_traditional &&
|
|
|
|
|
c_language != clk_cplusplus)
|
2000-03-23 22:32:10 +01:00
|
|
|
|
? integer_type_node : sizetype);
|
1999-07-20 12:41:10 +02:00
|
|
|
|
|
2001-05-25 22:00:59 +02:00
|
|
|
|
#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
|
|
|
|
|
builtin_types[(int) ENUM] = VALUE;
|
|
|
|
|
#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type (builtin_types[(int) RETURN], \
|
|
|
|
|
void_list_node);
|
|
|
|
|
#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type (builtin_types[(int) RETURN], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG1], \
|
|
|
|
|
void_list_node));
|
|
|
|
|
#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type \
|
|
|
|
|
(builtin_types[(int) RETURN], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG1], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG2], \
|
|
|
|
|
void_list_node)));
|
|
|
|
|
#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type \
|
|
|
|
|
(builtin_types[(int) RETURN], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG1], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG2], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG3], \
|
|
|
|
|
void_list_node))));
|
|
|
|
|
#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type \
|
|
|
|
|
(builtin_types[(int) RETURN], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG1], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG2], \
|
|
|
|
|
tree_cons \
|
|
|
|
|
(NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG3], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG4], \
|
|
|
|
|
void_list_node)))));
|
|
|
|
|
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type (builtin_types[(int) RETURN], NULL_TREE);
|
|
|
|
|
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type (builtin_types[(int) RETURN], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG1], \
|
2000-09-19 20:19:44 +02:00
|
|
|
|
NULL_TREE));
|
|
|
|
|
|
2001-05-25 22:00:59 +02:00
|
|
|
|
#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_function_type \
|
|
|
|
|
(builtin_types[(int) RETURN], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG1], \
|
|
|
|
|
tree_cons (NULL_TREE, \
|
|
|
|
|
builtin_types[(int) ARG2], \
|
|
|
|
|
NULL_TREE)));
|
|
|
|
|
#define DEF_POINTER_TYPE(ENUM, TYPE) \
|
|
|
|
|
builtin_types[(int) ENUM] \
|
|
|
|
|
= build_pointer_type (builtin_types[(int) TYPE]);
|
|
|
|
|
#include "builtin-types.def"
|
|
|
|
|
#undef DEF_PRIMITIVE_TYPE
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_1
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_2
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_3
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_4
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_VAR_0
|
|
|
|
|
#undef DEF_FUNCTION_TYPE_VAR_1
|
|
|
|
|
#undef DEF_POINTER_TYPE
|
|
|
|
|
|
|
|
|
|
#define DEF_BUILTIN(ENUM, NAME, CLASS, \
|
|
|
|
|
TYPE, LIBTYPE, BOTH_P, FALLBACK_P, NONANSI_P) \
|
|
|
|
|
if (NAME) \
|
|
|
|
|
{ \
|
|
|
|
|
tree decl; \
|
|
|
|
|
\
|
|
|
|
|
if (strncmp (NAME, "__builtin_", strlen ("__builtin_")) != 0) \
|
|
|
|
|
abort (); \
|
|
|
|
|
\
|
|
|
|
|
if (!BOTH_P) \
|
|
|
|
|
decl = builtin_function (NAME, builtin_types[TYPE], ENUM, \
|
|
|
|
|
CLASS, \
|
|
|
|
|
(FALLBACK_P \
|
|
|
|
|
? (NAME + strlen ("__builtin_")) \
|
|
|
|
|
: NULL)); \
|
|
|
|
|
else \
|
|
|
|
|
decl = builtin_function_2 (NAME, \
|
|
|
|
|
NAME + strlen ("__builtin_"), \
|
|
|
|
|
builtin_types[TYPE], \
|
|
|
|
|
builtin_types[LIBTYPE], \
|
|
|
|
|
ENUM, \
|
|
|
|
|
CLASS, \
|
|
|
|
|
FALLBACK_P, \
|
|
|
|
|
NONANSI_P, \
|
|
|
|
|
/*noreturn_p=*/0); \
|
|
|
|
|
\
|
|
|
|
|
built_in_decls[(int) ENUM] = decl; \
|
|
|
|
|
}
|
|
|
|
|
#include "builtins.def"
|
|
|
|
|
#undef DEF_BUILTIN
|
2001-03-28 13:04:51 +02:00
|
|
|
|
|
2001-01-07 12:26:15 +01:00
|
|
|
|
/* Declare _exit and _Exit just to mark them as non-returning. */
|
2001-05-25 22:00:59 +02:00
|
|
|
|
builtin_function_2 (NULL, "_exit", NULL_TREE,
|
|
|
|
|
builtin_types[BT_FN_VOID_INT],
|
2000-12-23 01:48:08 +01:00
|
|
|
|
0, NOT_BUILT_IN, 0, 1, 1);
|
2001-05-25 22:00:59 +02:00
|
|
|
|
builtin_function_2 (NULL, "_Exit", NULL_TREE,
|
|
|
|
|
builtin_types[BT_FN_VOID_INT],
|
2001-01-07 12:26:15 +01:00
|
|
|
|
0, NOT_BUILT_IN, 0, !flag_isoc99, 1);
|
2000-12-23 01:48:08 +01:00
|
|
|
|
|
|
|
|
|
/* Declare these functions non-returning
|
|
|
|
|
to avoid spurious "control drops through" warnings. */
|
2001-05-01 14:11:35 +02:00
|
|
|
|
builtin_function_2 (NULL, "abort",
|
2000-12-23 01:48:08 +01:00
|
|
|
|
NULL_TREE, ((c_language == clk_cplusplus)
|
2001-05-25 22:00:59 +02:00
|
|
|
|
? builtin_types[BT_FN_VOID]
|
|
|
|
|
: builtin_types[BT_FN_VOID_VAR]),
|
2000-12-23 01:48:08 +01:00
|
|
|
|
0, NOT_BUILT_IN, 0, 0, 1);
|
|
|
|
|
|
2001-05-01 14:11:35 +02:00
|
|
|
|
builtin_function_2 (NULL, "exit",
|
2000-12-23 01:48:08 +01:00
|
|
|
|
NULL_TREE, ((c_language == clk_cplusplus)
|
2001-05-25 22:00:59 +02:00
|
|
|
|
? builtin_types[BT_FN_VOID_INT]
|
|
|
|
|
: builtin_types[BT_FN_VOID_VAR]),
|
2000-12-23 01:48:08 +01:00
|
|
|
|
0, NOT_BUILT_IN, 0, 0, 1);
|
1999-07-20 12:41:10 +02:00
|
|
|
|
|
2000-08-24 22:09:27 +02:00
|
|
|
|
main_identifier_node = get_identifier ("main");
|
|
|
|
|
|
1999-09-08 06:51:16 +02:00
|
|
|
|
/* ??? Perhaps there's a better place to do this. But it is related
|
|
|
|
|
to __builtin_va_arg, so it isn't that off-the-wall. */
|
|
|
|
|
lang_type_promotes_to = simple_type_promotes_to;
|
1999-07-20 12:41:10 +02:00
|
|
|
|
}
|
builtins.c (expand_builtin_saveregs): Remove static, remove exp and ignore arguments, bail if no EXPAND_BUILTIN_SAVEREGS.
* builtins.c (expand_builtin_saveregs): Remove static, remove exp
and ignore arguments, bail if no EXPAND_BUILTIN_SAVEREGS.
(expand_builtin_next_arg): Accept ARGLIST not EXP.
(stabilize_va_list): New function.
(std_expand_builtin_va_start): New function.
(expand_builtin_va_start): New function.
(get_varargs_alias_set): New function.
(std_expand_builtin_va_arg): New function.
(expand_builtin_va_arg): New function.
(expand_builtin_va_end): New function.
(expand_builtin_va_copy): New function.
(expand_builtin): Call them.
* c-common.c (c_common_nodes_and_builtins): Build __builtin_va_list,
__builtin_{varargs_start,stdarg_start,end,copy}.
(build_va_arg): New function.
* c-common.h (CTI_PTR_TYPE, ptr_type_node): Delete.
(build_va_arg): Declare.
* c-decl.c (ptr_type_node, va_list_type_node): New.
* c-parse.gperf (__builtin_va_arg): New.
* c-parse.in (VA_ARG): New token.
(unary_expr): Recognize it.
* expr.c (expand_expr): Expand VA_ARG_EXPR.
* expr.h (std_expand_builtin_va_start): Declare.
(std_expand_builtin_va_arg): Declare.
(expand_builtin_va_arg): Declare.
(get_varargs_alias_set): Declare.
* tree.def (VA_ARG_EXPR): New.
* tree.h (BUILT_IN_VARARGS_START): New.
(BUILT_IN_STDARG_START, BUILT_IN_VA_END): New.
(ptr_type_node, va_list_type_node): Declare.
* tm.texi (EXPAND_BUILTIN_SAVEREGS): Kill unused ARGLIST argument.
* m32r.h (EXPAND_BUILTIN_SAVEREGS): Likewise.
* m88k.h, m88k.c: Likewise.
* mn10300.h, mn10300.c: Likewise.
* pa.h, pa.c: Likewise.
* rs6000.h, rs6000.c: Likewise.
* sh.h, sh.c: Likewise.
* sparc.h, sparc.c: Likewise.
* emit-rtl.c (operand_subword): Copy alias set.
(change_address): Likewise.
From-SVN: r28243
1999-07-26 03:21:03 +02:00
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
build_va_arg (expr, type)
|
|
|
|
|
tree expr, type;
|
|
|
|
|
{
|
|
|
|
|
return build1 (VA_ARG_EXPR, type, expr);
|
|
|
|
|
}
|
2000-12-23 01:48:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Possibly define a builtin function with one or two names. BUILTIN_NAME
|
|
|
|
|
is an __builtin_-prefixed name; NAME is the ordinary name; one or both
|
|
|
|
|
of these may be NULL (though both being NULL is useless).
|
|
|
|
|
BUILTIN_TYPE is the type of the __builtin_-prefixed function;
|
|
|
|
|
TYPE is the type of the function with the ordinary name. These
|
|
|
|
|
may differ if the ordinary name is declared with a looser type to avoid
|
|
|
|
|
conflicts with headers. FUNCTION_CODE and CLASS are as for
|
|
|
|
|
builtin_function. If LIBRARY_NAME_P is nonzero, NAME is passed as
|
|
|
|
|
the LIBRARY_NAME parameter to builtin_function when declaring BUILTIN_NAME.
|
|
|
|
|
If NONANSI_P is nonzero, the name NAME is treated as a non-ANSI name; if
|
|
|
|
|
NORETURN_P is nonzero, the function is marked as non-returning.
|
|
|
|
|
Returns the declaration of BUILTIN_NAME, if any, otherwise
|
|
|
|
|
the declaration of NAME. Does not declare NAME if flag_no_builtin,
|
|
|
|
|
or if NONANSI_P and flag_no_nonansi_builtin. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
|
|
|
|
|
class, library_name_p, nonansi_p, noreturn_p)
|
|
|
|
|
const char *builtin_name;
|
|
|
|
|
const char *name;
|
|
|
|
|
tree builtin_type;
|
|
|
|
|
tree type;
|
|
|
|
|
int function_code;
|
|
|
|
|
enum built_in_class class;
|
|
|
|
|
int library_name_p;
|
|
|
|
|
int nonansi_p;
|
|
|
|
|
int noreturn_p;
|
|
|
|
|
{
|
|
|
|
|
tree bdecl = NULL_TREE;
|
|
|
|
|
tree decl = NULL_TREE;
|
|
|
|
|
if (builtin_name != 0)
|
|
|
|
|
{
|
|
|
|
|
bdecl = builtin_function (builtin_name, builtin_type, function_code,
|
2001-05-01 14:11:35 +02:00
|
|
|
|
class, library_name_p ? name : NULL);
|
2000-12-23 01:48:08 +01:00
|
|
|
|
if (noreturn_p)
|
|
|
|
|
{
|
|
|
|
|
TREE_THIS_VOLATILE (bdecl) = 1;
|
|
|
|
|
TREE_SIDE_EFFECTS (bdecl) = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (name != 0 && !flag_no_builtin && !(nonansi_p && flag_no_nonansi_builtin))
|
|
|
|
|
{
|
2001-05-01 14:11:35 +02:00
|
|
|
|
decl = builtin_function (name, type, function_code, class, NULL);
|
2000-12-23 01:48:08 +01:00
|
|
|
|
if (nonansi_p)
|
|
|
|
|
DECL_BUILT_IN_NONANSI (decl) = 1;
|
|
|
|
|
if (noreturn_p)
|
|
|
|
|
{
|
|
|
|
|
TREE_THIS_VOLATILE (decl) = 1;
|
|
|
|
|
TREE_SIDE_EFFECTS (decl) = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return (bdecl != 0 ? bdecl : decl);
|
|
|
|
|
}
|
1999-09-08 06:51:16 +02:00
|
|
|
|
|
2001-05-01 01:59:10 +02:00
|
|
|
|
/* Nonzero if the type T promotes to int. This is (nearly) the
|
|
|
|
|
integral promotions defined in ISO C99 6.3.1.1/2. */
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
c_promoting_integer_type_p (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
switch (TREE_CODE (t))
|
|
|
|
|
{
|
|
|
|
|
case INTEGER_TYPE:
|
|
|
|
|
return (TYPE_MAIN_VARIANT (t) == char_type_node
|
|
|
|
|
|| TYPE_MAIN_VARIANT (t) == signed_char_type_node
|
|
|
|
|
|| TYPE_MAIN_VARIANT (t) == unsigned_char_type_node
|
|
|
|
|
|| TYPE_MAIN_VARIANT (t) == short_integer_type_node
|
|
|
|
|
|| TYPE_MAIN_VARIANT (t) == short_unsigned_type_node);
|
|
|
|
|
|
|
|
|
|
case ENUMERAL_TYPE:
|
|
|
|
|
/* ??? Technically all enumerations not larger than an int
|
|
|
|
|
promote to an int. But this is used along code paths
|
|
|
|
|
that only want to notice a size change. */
|
|
|
|
|
return TYPE_PRECISION (t) < TYPE_PRECISION (integer_type_node);
|
|
|
|
|
|
|
|
|
|
case BOOLEAN_TYPE:
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-08 06:51:16 +02:00
|
|
|
|
/* Given a type, apply default promotions wrt unnamed function arguments
|
|
|
|
|
and return the new type. Return NULL_TREE if no change. */
|
2000-01-03 22:48:49 +01:00
|
|
|
|
/* ??? There is a function of the same name in the C++ front end that
|
1999-09-08 06:51:16 +02:00
|
|
|
|
does something similar, but is more thorough and does not return NULL
|
2000-01-03 22:48:49 +01:00
|
|
|
|
if no change. We could perhaps share code, but it would make the
|
1999-09-08 06:51:16 +02:00
|
|
|
|
self_promoting_type property harder to identify. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
simple_type_promotes_to (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
if (TYPE_MAIN_VARIANT (type) == float_type_node)
|
|
|
|
|
return double_type_node;
|
|
|
|
|
|
2001-05-01 01:59:10 +02:00
|
|
|
|
if (c_promoting_integer_type_p (type))
|
1999-09-08 06:51:16 +02:00
|
|
|
|
{
|
|
|
|
|
/* Traditionally, unsignedness is preserved in default promotions.
|
|
|
|
|
Also preserve unsignedness if not really getting any wider. */
|
|
|
|
|
if (TREE_UNSIGNED (type)
|
|
|
|
|
&& (flag_traditional
|
|
|
|
|
|| TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
|
|
|
|
|
return unsigned_type_node;
|
|
|
|
|
return integer_type_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return 1 if PARMS specifies a fixed number of parameters
|
|
|
|
|
and none of their types is affected by default promotions. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
self_promoting_args_p (parms)
|
|
|
|
|
tree parms;
|
|
|
|
|
{
|
|
|
|
|
register tree t;
|
|
|
|
|
for (t = parms; t; t = TREE_CHAIN (t))
|
|
|
|
|
{
|
|
|
|
|
register tree type = TREE_VALUE (t);
|
1999-07-31 03:13:08 +02:00
|
|
|
|
|
1999-09-08 06:51:16 +02:00
|
|
|
|
if (TREE_CHAIN (t) == 0 && type != void_type_node)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (type == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (TYPE_MAIN_VARIANT (type) == float_type_node)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2001-05-01 01:59:10 +02:00
|
|
|
|
if (c_promoting_integer_type_p (type))
|
1999-09-08 06:51:16 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2000-01-25 01:45:14 +01:00
|
|
|
|
|
2000-11-10 05:29:45 +01:00
|
|
|
|
/* Recursively examines the array elements of TYPE, until a non-array
|
|
|
|
|
element type is found. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
strip_array_types (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
while (TREE_CODE (type) == ARRAY_TYPE)
|
|
|
|
|
type = TREE_TYPE (type);
|
|
|
|
|
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-25 01:45:14 +01:00
|
|
|
|
/* Recognize certain built-in functions so we can make tree-codes
|
|
|
|
|
other than CALL_EXPR. We do this when it enables fold-const.c
|
|
|
|
|
to do something useful. */
|
|
|
|
|
/* ??? By rights this should go in builtins.c, but only C and C++
|
|
|
|
|
implement build_{binary,unary}_op. Not exactly sure what bits
|
|
|
|
|
of functionality are actually needed from those functions, or
|
|
|
|
|
where the similar functionality exists in the other front ends. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
expand_tree_builtin (function, params, coerced_params)
|
|
|
|
|
tree function, params, coerced_params;
|
|
|
|
|
{
|
|
|
|
|
enum tree_code code;
|
|
|
|
|
|
|
|
|
|
if (DECL_BUILT_IN_CLASS (function) != BUILT_IN_NORMAL)
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
switch (DECL_FUNCTION_CODE (function))
|
|
|
|
|
{
|
|
|
|
|
case BUILT_IN_ABS:
|
2001-05-25 22:00:59 +02:00
|
|
|
|
case BUILT_IN_LABS:
|
|
|
|
|
case BUILT_IN_LLABS:
|
|
|
|
|
case BUILT_IN_IMAXABS:
|
2000-01-25 01:45:14 +01:00
|
|
|
|
case BUILT_IN_FABS:
|
2001-05-25 22:00:59 +02:00
|
|
|
|
case BUILT_IN_FABSL:
|
|
|
|
|
case BUILT_IN_FABSF:
|
2000-01-25 01:45:14 +01:00
|
|
|
|
if (coerced_params == 0)
|
|
|
|
|
return integer_zero_node;
|
|
|
|
|
return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
|
|
|
|
|
|
builtins.def (BUILT_IN_CONJ, [...]): Define.
* builtins.def (BUILT_IN_CONJ, BUILT_IN_CREAL, BUILT_IN_CIMAG):
Define.
* builtins.c (expand_builtin): Abort on BUILT_IN_CONJ,
BUILT_IN_CREAL and BUILT_IN_CIMAG.
* c-common.c (c_common_nodes_and_builtins): Create builtin conjf,
conj, conjl, crealf, creal, creall, cimagf, cimag and cimagl.
(expand_tree_builtin): Handle BUILT_IN_CONJ, BUILT_IN_CREAL and
BUILT_IN_CIMAG.
* extend.texi: Document these builtins.
testsuite:
* gcc.c-torture/execute/builtin-complex-1.c: New test.
From-SVN: r38716
2001-01-05 19:24:08 +01:00
|
|
|
|
case BUILT_IN_CONJ:
|
2001-05-25 22:00:59 +02:00
|
|
|
|
case BUILT_IN_CONJF:
|
|
|
|
|
case BUILT_IN_CONJL:
|
builtins.def (BUILT_IN_CONJ, [...]): Define.
* builtins.def (BUILT_IN_CONJ, BUILT_IN_CREAL, BUILT_IN_CIMAG):
Define.
* builtins.c (expand_builtin): Abort on BUILT_IN_CONJ,
BUILT_IN_CREAL and BUILT_IN_CIMAG.
* c-common.c (c_common_nodes_and_builtins): Create builtin conjf,
conj, conjl, crealf, creal, creall, cimagf, cimag and cimagl.
(expand_tree_builtin): Handle BUILT_IN_CONJ, BUILT_IN_CREAL and
BUILT_IN_CIMAG.
* extend.texi: Document these builtins.
testsuite:
* gcc.c-torture/execute/builtin-complex-1.c: New test.
From-SVN: r38716
2001-01-05 19:24:08 +01:00
|
|
|
|
if (coerced_params == 0)
|
|
|
|
|
return integer_zero_node;
|
|
|
|
|
return build_unary_op (CONJ_EXPR, TREE_VALUE (coerced_params), 0);
|
|
|
|
|
|
|
|
|
|
case BUILT_IN_CREAL:
|
2001-05-25 22:00:59 +02:00
|
|
|
|
case BUILT_IN_CREALF:
|
|
|
|
|
case BUILT_IN_CREALL:
|
builtins.def (BUILT_IN_CONJ, [...]): Define.
* builtins.def (BUILT_IN_CONJ, BUILT_IN_CREAL, BUILT_IN_CIMAG):
Define.
* builtins.c (expand_builtin): Abort on BUILT_IN_CONJ,
BUILT_IN_CREAL and BUILT_IN_CIMAG.
* c-common.c (c_common_nodes_and_builtins): Create builtin conjf,
conj, conjl, crealf, creal, creall, cimagf, cimag and cimagl.
(expand_tree_builtin): Handle BUILT_IN_CONJ, BUILT_IN_CREAL and
BUILT_IN_CIMAG.
* extend.texi: Document these builtins.
testsuite:
* gcc.c-torture/execute/builtin-complex-1.c: New test.
From-SVN: r38716
2001-01-05 19:24:08 +01:00
|
|
|
|
if (coerced_params == 0)
|
|
|
|
|
return integer_zero_node;
|
|
|
|
|
return build_unary_op (REALPART_EXPR, TREE_VALUE (coerced_params), 0);
|
|
|
|
|
|
|
|
|
|
case BUILT_IN_CIMAG:
|
2001-05-25 22:00:59 +02:00
|
|
|
|
case BUILT_IN_CIMAGF:
|
|
|
|
|
case BUILT_IN_CIMAGL:
|
builtins.def (BUILT_IN_CONJ, [...]): Define.
* builtins.def (BUILT_IN_CONJ, BUILT_IN_CREAL, BUILT_IN_CIMAG):
Define.
* builtins.c (expand_builtin): Abort on BUILT_IN_CONJ,
BUILT_IN_CREAL and BUILT_IN_CIMAG.
* c-common.c (c_common_nodes_and_builtins): Create builtin conjf,
conj, conjl, crealf, creal, creall, cimagf, cimag and cimagl.
(expand_tree_builtin): Handle BUILT_IN_CONJ, BUILT_IN_CREAL and
BUILT_IN_CIMAG.
* extend.texi: Document these builtins.
testsuite:
* gcc.c-torture/execute/builtin-complex-1.c: New test.
From-SVN: r38716
2001-01-05 19:24:08 +01:00
|
|
|
|
if (coerced_params == 0)
|
|
|
|
|
return integer_zero_node;
|
|
|
|
|
return build_unary_op (IMAGPART_EXPR, TREE_VALUE (coerced_params), 0);
|
|
|
|
|
|
2000-01-25 01:45:14 +01:00
|
|
|
|
case BUILT_IN_ISGREATER:
|
|
|
|
|
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
|
|
|
|
|
code = UNLE_EXPR;
|
|
|
|
|
else
|
|
|
|
|
code = LE_EXPR;
|
|
|
|
|
goto unordered_cmp;
|
|
|
|
|
|
|
|
|
|
case BUILT_IN_ISGREATEREQUAL:
|
|
|
|
|
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
|
|
|
|
|
code = UNLT_EXPR;
|
|
|
|
|
else
|
|
|
|
|
code = LT_EXPR;
|
|
|
|
|
goto unordered_cmp;
|
|
|
|
|
|
|
|
|
|
case BUILT_IN_ISLESS:
|
|
|
|
|
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
|
|
|
|
|
code = UNGE_EXPR;
|
|
|
|
|
else
|
|
|
|
|
code = GE_EXPR;
|
|
|
|
|
goto unordered_cmp;
|
|
|
|
|
|
|
|
|
|
case BUILT_IN_ISLESSEQUAL:
|
|
|
|
|
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
|
|
|
|
|
code = UNGT_EXPR;
|
|
|
|
|
else
|
|
|
|
|
code = GT_EXPR;
|
|
|
|
|
goto unordered_cmp;
|
|
|
|
|
|
|
|
|
|
case BUILT_IN_ISLESSGREATER:
|
|
|
|
|
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
|
|
|
|
|
code = UNEQ_EXPR;
|
|
|
|
|
else
|
|
|
|
|
code = EQ_EXPR;
|
|
|
|
|
goto unordered_cmp;
|
|
|
|
|
|
|
|
|
|
case BUILT_IN_ISUNORDERED:
|
|
|
|
|
if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
|
|
|
|
|
return integer_zero_node;
|
|
|
|
|
code = UNORDERED_EXPR;
|
|
|
|
|
goto unordered_cmp;
|
|
|
|
|
|
|
|
|
|
unordered_cmp:
|
|
|
|
|
{
|
|
|
|
|
tree arg0, arg1;
|
|
|
|
|
|
|
|
|
|
if (params == 0
|
|
|
|
|
|| TREE_CHAIN (params) == 0)
|
|
|
|
|
{
|
|
|
|
|
error ("too few arguments to function `%s'",
|
|
|
|
|
IDENTIFIER_POINTER (DECL_NAME (function)));
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
else if (TREE_CHAIN (TREE_CHAIN (params)) != 0)
|
|
|
|
|
{
|
|
|
|
|
error ("too many arguments to function `%s'",
|
|
|
|
|
IDENTIFIER_POINTER (DECL_NAME (function)));
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
arg0 = TREE_VALUE (params);
|
|
|
|
|
arg1 = TREE_VALUE (TREE_CHAIN (params));
|
|
|
|
|
arg0 = build_binary_op (code, arg0, arg1, 0);
|
|
|
|
|
if (code != UNORDERED_EXPR)
|
|
|
|
|
arg0 = build_unary_op (TRUTH_NOT_EXPR, arg0, 0);
|
|
|
|
|
return arg0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
2000-06-17 04:37:23 +02:00
|
|
|
|
|
2000-09-07 03:36:11 +02:00
|
|
|
|
/* Returns non-zero if CODE is the code for a statement. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
statement_code_p (code)
|
|
|
|
|
enum tree_code code;
|
|
|
|
|
{
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case EXPR_STMT:
|
|
|
|
|
case COMPOUND_STMT:
|
|
|
|
|
case DECL_STMT:
|
|
|
|
|
case IF_STMT:
|
|
|
|
|
case FOR_STMT:
|
|
|
|
|
case WHILE_STMT:
|
|
|
|
|
case DO_STMT:
|
|
|
|
|
case RETURN_STMT:
|
|
|
|
|
case BREAK_STMT:
|
|
|
|
|
case CONTINUE_STMT:
|
2000-09-17 09:38:23 +02:00
|
|
|
|
case SCOPE_STMT:
|
2000-09-07 03:36:11 +02:00
|
|
|
|
case SWITCH_STMT:
|
|
|
|
|
case GOTO_STMT:
|
|
|
|
|
case LABEL_STMT:
|
|
|
|
|
case ASM_STMT:
|
|
|
|
|
case CASE_LABEL:
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
if (lang_statement_code_p)
|
|
|
|
|
return (*lang_statement_code_p) (code);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-16 14:08:44 +01:00
|
|
|
|
/* Walk the statement tree, rooted at *tp. Apply FUNC to all the
|
2000-09-07 03:36:11 +02:00
|
|
|
|
sub-trees of *TP in a pre-order traversal. FUNC is called with the
|
|
|
|
|
DATA and the address of each sub-tree. If FUNC returns a non-NULL
|
|
|
|
|
value, the traversal is aborted, and the value returned by FUNC is
|
|
|
|
|
returned. If FUNC sets WALK_SUBTREES to zero, then the subtrees of
|
|
|
|
|
the node being visited are not walked.
|
|
|
|
|
|
|
|
|
|
We don't need a without_duplicates variant of this one because the
|
|
|
|
|
statement tree is a tree, not a graph. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
walk_stmt_tree (tp, func, data)
|
|
|
|
|
tree *tp;
|
|
|
|
|
walk_tree_fn func;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
enum tree_code code;
|
|
|
|
|
int walk_subtrees;
|
|
|
|
|
tree result;
|
|
|
|
|
int i, len;
|
|
|
|
|
|
|
|
|
|
#define WALK_SUBTREE(NODE) \
|
|
|
|
|
do \
|
|
|
|
|
{ \
|
|
|
|
|
result = walk_stmt_tree (&(NODE), func, data); \
|
|
|
|
|
if (result) \
|
|
|
|
|
return result; \
|
|
|
|
|
} \
|
|
|
|
|
while (0)
|
|
|
|
|
|
|
|
|
|
/* Skip empty subtrees. */
|
|
|
|
|
if (!*tp)
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* Skip subtrees below non-statement nodes. */
|
|
|
|
|
if (!statement_code_p (TREE_CODE (*tp)))
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* Call the function. */
|
|
|
|
|
walk_subtrees = 1;
|
|
|
|
|
result = (*func) (tp, &walk_subtrees, data);
|
|
|
|
|
|
|
|
|
|
/* If we found something, return it. */
|
|
|
|
|
if (result)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
/* FUNC may have modified the tree, recheck that we're looking at a
|
|
|
|
|
statement node. */
|
|
|
|
|
code = TREE_CODE (*tp);
|
|
|
|
|
if (!statement_code_p (code))
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
2001-02-28 02:25:42 +01:00
|
|
|
|
/* Visit the subtrees unless FUNC decided that there was nothing
|
|
|
|
|
interesting below this point in the tree. */
|
|
|
|
|
if (walk_subtrees)
|
|
|
|
|
{
|
|
|
|
|
/* Walk over all the sub-trees of this operand. Statement nodes
|
|
|
|
|
never contain RTL, and we needn't worry about TARGET_EXPRs. */
|
|
|
|
|
len = TREE_CODE_LENGTH (code);
|
|
|
|
|
|
|
|
|
|
/* Go through the subtrees. We need to do this in forward order so
|
|
|
|
|
that the scope of a FOR_EXPR is handled properly. */
|
|
|
|
|
for (i = 0; i < len; ++i)
|
|
|
|
|
WALK_SUBTREE (TREE_OPERAND (*tp, i));
|
|
|
|
|
}
|
2000-09-07 03:36:11 +02:00
|
|
|
|
|
|
|
|
|
/* Finally visit the chain. This can be tail-recursion optimized if
|
|
|
|
|
we write it this way. */
|
|
|
|
|
return walk_stmt_tree (&TREE_CHAIN (*tp), func, data);
|
|
|
|
|
|
|
|
|
|
#undef WALK_SUBTREE
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
/* Used to compare case labels. K1 and K2 are actually tree nodes
|
|
|
|
|
representing case labels, or NULL_TREE for a `default' label.
|
|
|
|
|
Returns -1 if K1 is ordered before K2, -1 if K1 is ordered after
|
|
|
|
|
K2, and 0 if K1 and K2 are equal. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
case_compare (k1, k2)
|
|
|
|
|
splay_tree_key k1;
|
|
|
|
|
splay_tree_key k2;
|
|
|
|
|
{
|
|
|
|
|
/* Consider a NULL key (such as arises with a `default' label) to be
|
|
|
|
|
smaller than anything else. */
|
|
|
|
|
if (!k1)
|
|
|
|
|
return k2 ? -1 : 0;
|
|
|
|
|
else if (!k2)
|
|
|
|
|
return k1 ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
return tree_int_cst_compare ((tree) k1, (tree) k2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Process a case label for the range LOW_VALUE ... HIGH_VALUE. If
|
|
|
|
|
LOW_VALUE and HIGH_VALUE are both NULL_TREE then this case label is
|
|
|
|
|
actually a `default' label. If only HIGH_VALUE is NULL_TREE, then
|
|
|
|
|
case label was declared using the usual C/C++ syntax, rather than
|
|
|
|
|
the GNU case range extension. CASES is a tree containing all the
|
|
|
|
|
case ranges processed so far; COND is the condition for the
|
|
|
|
|
switch-statement itself. Returns the CASE_LABEL created, or
|
|
|
|
|
ERROR_MARK_NODE if no CASE_LABEL is created. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
c_add_case_label (cases, cond, low_value, high_value)
|
|
|
|
|
splay_tree cases;
|
|
|
|
|
tree cond;
|
|
|
|
|
tree low_value;
|
|
|
|
|
tree high_value;
|
|
|
|
|
{
|
|
|
|
|
tree type;
|
|
|
|
|
tree label;
|
|
|
|
|
tree case_label;
|
|
|
|
|
splay_tree_node node;
|
|
|
|
|
|
|
|
|
|
/* Create the LABEL_DECL itself. */
|
|
|
|
|
label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
|
|
|
|
|
DECL_CONTEXT (label) = current_function_decl;
|
|
|
|
|
|
|
|
|
|
/* If there was an error processing the switch condition, bail now
|
|
|
|
|
before we get more confused. */
|
|
|
|
|
if (!cond || cond == error_mark_node)
|
|
|
|
|
{
|
|
|
|
|
/* Add a label anyhow so that the back-end doesn't think that
|
|
|
|
|
the beginning of the switch is unreachable. */
|
|
|
|
|
if (!cases->root)
|
|
|
|
|
add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((low_value && TREE_TYPE (low_value)
|
|
|
|
|
&& POINTER_TYPE_P (TREE_TYPE (low_value)))
|
|
|
|
|
|| (high_value && TREE_TYPE (high_value)
|
|
|
|
|
&& POINTER_TYPE_P (TREE_TYPE (high_value))))
|
|
|
|
|
error ("pointers are not permitted as case values");
|
|
|
|
|
|
|
|
|
|
/* Case ranges are a GNU extension. */
|
|
|
|
|
if (high_value && pedantic)
|
|
|
|
|
{
|
|
|
|
|
if (c_language == clk_cplusplus)
|
|
|
|
|
pedwarn ("ISO C++ forbids range expressions in switch statements");
|
|
|
|
|
else
|
|
|
|
|
pedwarn ("ISO C forbids range expressions in switch statements");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type = TREE_TYPE (cond);
|
|
|
|
|
if (low_value)
|
|
|
|
|
{
|
|
|
|
|
low_value = check_case_value (low_value);
|
|
|
|
|
low_value = convert_and_check (type, low_value);
|
|
|
|
|
}
|
|
|
|
|
if (high_value)
|
|
|
|
|
{
|
|
|
|
|
high_value = check_case_value (high_value);
|
|
|
|
|
high_value = convert_and_check (type, high_value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If an error has occurred, bail out now. */
|
|
|
|
|
if (low_value == error_mark_node || high_value == error_mark_node)
|
|
|
|
|
{
|
|
|
|
|
if (!cases->root)
|
|
|
|
|
add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't
|
|
|
|
|
really a case range, even though it was written that way. Remove
|
|
|
|
|
the HIGH_VALUE to simplify later processing. */
|
|
|
|
|
if (tree_int_cst_equal (low_value, high_value))
|
|
|
|
|
high_value = NULL_TREE;
|
|
|
|
|
if (low_value && high_value
|
|
|
|
|
&& !tree_int_cst_lt (low_value, high_value))
|
|
|
|
|
warning ("empty range specified");
|
|
|
|
|
|
|
|
|
|
/* Look up the LOW_VALUE in the table of case labels we already
|
|
|
|
|
have. */
|
|
|
|
|
node = splay_tree_lookup (cases, (splay_tree_key) low_value);
|
|
|
|
|
/* If there was not an exact match, check for overlapping ranges.
|
|
|
|
|
There's no need to do this if there's no LOW_VALUE or HIGH_VALUE;
|
|
|
|
|
that's a `default' label and the only overlap is an exact match. */
|
|
|
|
|
if (!node && (low_value || high_value))
|
|
|
|
|
{
|
|
|
|
|
splay_tree_node low_bound;
|
|
|
|
|
splay_tree_node high_bound;
|
|
|
|
|
|
|
|
|
|
/* Even though there wasn't an exact match, there might be an
|
|
|
|
|
overlap between this case range and another case range.
|
|
|
|
|
Since we've (inductively) not allowed any overlapping case
|
|
|
|
|
ranges, we simply need to find the greatest low case label
|
|
|
|
|
that is smaller that LOW_VALUE, and the smallest low case
|
|
|
|
|
label that is greater than LOW_VALUE. If there is an overlap
|
|
|
|
|
it will occur in one of these two ranges. */
|
|
|
|
|
low_bound = splay_tree_predecessor (cases,
|
|
|
|
|
(splay_tree_key) low_value);
|
|
|
|
|
high_bound = splay_tree_successor (cases,
|
|
|
|
|
(splay_tree_key) low_value);
|
|
|
|
|
|
|
|
|
|
/* Check to see if the LOW_BOUND overlaps. It is smaller than
|
|
|
|
|
the LOW_VALUE, so there is no need to check unless the
|
|
|
|
|
LOW_BOUND is in fact itself a case range. */
|
|
|
|
|
if (low_bound
|
|
|
|
|
&& CASE_HIGH ((tree) low_bound->value)
|
|
|
|
|
&& tree_int_cst_compare (CASE_HIGH ((tree) low_bound->value),
|
|
|
|
|
low_value) >= 0)
|
|
|
|
|
node = low_bound;
|
|
|
|
|
/* Check to see if the HIGH_BOUND overlaps. The low end of that
|
|
|
|
|
range is bigger than the low end of the current range, so we
|
|
|
|
|
are only interested if the current range is a real range, and
|
|
|
|
|
not an ordinary case label. */
|
|
|
|
|
else if (high_bound
|
|
|
|
|
&& high_value
|
|
|
|
|
&& (tree_int_cst_compare ((tree) high_bound->key,
|
|
|
|
|
high_value)
|
|
|
|
|
<= 0))
|
|
|
|
|
node = high_bound;
|
|
|
|
|
}
|
|
|
|
|
/* If there was an overlap, issue an error. */
|
|
|
|
|
if (node)
|
|
|
|
|
{
|
|
|
|
|
tree duplicate = CASE_LABEL_DECL ((tree) node->value);
|
|
|
|
|
|
|
|
|
|
if (high_value)
|
|
|
|
|
{
|
|
|
|
|
error ("duplicate (or overlapping) case value");
|
|
|
|
|
error_with_decl (duplicate,
|
|
|
|
|
"this is the first entry overlapping that value");
|
|
|
|
|
}
|
|
|
|
|
else if (low_value)
|
|
|
|
|
{
|
|
|
|
|
error ("duplicate case value") ;
|
|
|
|
|
error_with_decl (duplicate, "previously used here");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
error ("multiple default labels in one switch");
|
|
|
|
|
error_with_decl (duplicate, "this is the first default label");
|
|
|
|
|
}
|
|
|
|
|
if (!cases->root)
|
|
|
|
|
add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add a CASE_LABEL to the statement-tree. */
|
|
|
|
|
case_label = add_stmt (build_case_label (low_value, high_value, label));
|
|
|
|
|
/* Register this case label in the splay tree. */
|
|
|
|
|
splay_tree_insert (cases,
|
|
|
|
|
(splay_tree_key) low_value,
|
|
|
|
|
(splay_tree_value) case_label);
|
|
|
|
|
|
|
|
|
|
return case_label;
|
|
|
|
|
}
|
|
|
|
|
|
2001-05-11 08:38:48 +02:00
|
|
|
|
/* Finish an expression taking the address of LABEL. Returns an
|
|
|
|
|
expression for the address. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
finish_label_address_expr (label)
|
|
|
|
|
tree label;
|
|
|
|
|
{
|
|
|
|
|
tree result;
|
|
|
|
|
|
|
|
|
|
if (pedantic)
|
|
|
|
|
{
|
|
|
|
|
if (c_language == clk_cplusplus)
|
|
|
|
|
pedwarn ("ISO C++ forbids taking the address of a label");
|
|
|
|
|
else
|
|
|
|
|
pedwarn ("ISO C forbids taking the address of a label");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
label = lookup_label (label);
|
|
|
|
|
if (label == NULL_TREE)
|
|
|
|
|
result = null_pointer_node;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TREE_USED (label) = 1;
|
|
|
|
|
result = build1 (ADDR_EXPR, ptr_type_node, label);
|
|
|
|
|
TREE_CONSTANT (result) = 1;
|
|
|
|
|
/* The current function in not necessarily uninlinable.
|
|
|
|
|
Computed gotos are incompatible with inlining, but the value
|
|
|
|
|
here could be used only in a diagnostic, for example. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
/* Mark P (a stmt_tree) for GC. The use of a `void *' for the
|
|
|
|
|
parameter allows this function to be used as a GC-marking
|
|
|
|
|
function. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mark_stmt_tree (p)
|
|
|
|
|
void *p;
|
|
|
|
|
{
|
|
|
|
|
stmt_tree st = (stmt_tree) p;
|
|
|
|
|
|
|
|
|
|
ggc_mark_tree (st->x_last_stmt);
|
|
|
|
|
ggc_mark_tree (st->x_last_expr_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mark LD for GC. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
c_mark_lang_decl (c)
|
|
|
|
|
struct c_lang_decl *c;
|
|
|
|
|
{
|
|
|
|
|
ggc_mark_tree (c->saved_tree);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mark F for GC. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mark_c_language_function (f)
|
|
|
|
|
struct language_function *f;
|
|
|
|
|
{
|
|
|
|
|
if (!f)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
mark_stmt_tree (&f->x_stmt_tree);
|
|
|
|
|
ggc_mark_tree (f->x_scope_stmt_stack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hook used by expand_expr to expand language-specific tree codes. */
|
|
|
|
|
|
|
|
|
|
rtx
|
|
|
|
|
c_expand_expr (exp, target, tmode, modifier)
|
|
|
|
|
tree exp;
|
|
|
|
|
rtx target;
|
|
|
|
|
enum machine_mode tmode;
|
|
|
|
|
enum expand_modifier modifier;
|
|
|
|
|
{
|
|
|
|
|
switch (TREE_CODE (exp))
|
|
|
|
|
{
|
|
|
|
|
case STMT_EXPR:
|
|
|
|
|
{
|
|
|
|
|
tree rtl_expr;
|
|
|
|
|
rtx result;
|
|
|
|
|
|
|
|
|
|
/* Since expand_expr_stmt calls free_temp_slots after every
|
|
|
|
|
expression statement, we must call push_temp_slots here.
|
|
|
|
|
Otherwise, any temporaries in use now would be considered
|
|
|
|
|
out-of-scope after the first EXPR_STMT from within the
|
|
|
|
|
STMT_EXPR. */
|
|
|
|
|
push_temp_slots ();
|
|
|
|
|
rtl_expr = expand_start_stmt_expr ();
|
|
|
|
|
expand_stmt (STMT_EXPR_STMT (exp));
|
|
|
|
|
expand_end_stmt_expr (rtl_expr);
|
|
|
|
|
result = expand_expr (rtl_expr, target, tmode, modifier);
|
|
|
|
|
pop_temp_slots ();
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2000-10-06 16:59:56 +02:00
|
|
|
|
case CALL_EXPR:
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
|
|
|
|
|
&& (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
|
|
|
|
|
== FUNCTION_DECL)
|
|
|
|
|
&& DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
|
|
|
|
|
&& (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
|
|
|
|
|
== BUILT_IN_FRONTEND))
|
|
|
|
|
return c_expand_builtin (exp, target, tmode, modifier);
|
|
|
|
|
else
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2000-09-17 09:38:23 +02:00
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
abort ();
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hook used by safe_from_p to handle language-specific tree codes. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
c_safe_from_p (target, exp)
|
|
|
|
|
rtx target;
|
|
|
|
|
tree exp;
|
|
|
|
|
{
|
|
|
|
|
/* We can see statements here when processing the body of a
|
|
|
|
|
statement-expression. For a declaration statement declaring a
|
|
|
|
|
variable, look at the variable's initializer. */
|
|
|
|
|
if (TREE_CODE (exp) == DECL_STMT)
|
|
|
|
|
{
|
|
|
|
|
tree decl = DECL_STMT_DECL (exp);
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (decl) == VAR_DECL
|
|
|
|
|
&& DECL_INITIAL (decl)
|
|
|
|
|
&& !safe_from_p (target, DECL_INITIAL (decl), /*top_p=*/0))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* For any statement, we must follow the statement-chain. */
|
|
|
|
|
if (statement_code_p (TREE_CODE (exp)) && TREE_CHAIN (exp))
|
|
|
|
|
return safe_from_p (target, TREE_CHAIN (exp), /*top_p=*/0);
|
|
|
|
|
|
|
|
|
|
/* Assume everything else is safe. */
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-21 20:09:38 +01:00
|
|
|
|
/* Hook used by unsafe_for_reeval to handle language-specific tree codes. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
c_unsafe_for_reeval (exp)
|
|
|
|
|
tree exp;
|
|
|
|
|
{
|
|
|
|
|
/* Statement expressions may not be reevaluated. */
|
|
|
|
|
if (TREE_CODE (exp) == STMT_EXPR)
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
|
|
/* Walk all other expressions. */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-17 04:37:23 +02:00
|
|
|
|
/* Tree code classes. */
|
|
|
|
|
|
|
|
|
|
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
|
|
|
|
|
|
|
|
|
|
static char c_tree_code_type[] = {
|
|
|
|
|
'x',
|
|
|
|
|
#include "c-common.def"
|
|
|
|
|
};
|
|
|
|
|
#undef DEFTREECODE
|
|
|
|
|
|
|
|
|
|
/* Table indexed by tree code giving number of expression
|
|
|
|
|
operands beyond the fixed part of the node structure.
|
|
|
|
|
Not used for types or decls. */
|
|
|
|
|
|
|
|
|
|
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
|
|
|
|
|
|
|
|
|
|
static int c_tree_code_length[] = {
|
|
|
|
|
0,
|
|
|
|
|
#include "c-common.def"
|
|
|
|
|
};
|
|
|
|
|
#undef DEFTREECODE
|
|
|
|
|
|
|
|
|
|
/* Names of tree components.
|
|
|
|
|
Used for printing out the tree and error messages. */
|
|
|
|
|
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
|
|
|
|
|
|
|
|
|
|
static const char *c_tree_code_name[] = {
|
|
|
|
|
"@@dummy",
|
|
|
|
|
#include "c-common.def"
|
|
|
|
|
};
|
|
|
|
|
#undef DEFTREECODE
|
|
|
|
|
|
|
|
|
|
/* Adds the tree codes specific to the C front end to the list of all
|
|
|
|
|
tree codes. */
|
|
|
|
|
|
|
|
|
|
void
|
2000-06-18 15:09:26 +02:00
|
|
|
|
add_c_tree_codes ()
|
2000-06-17 04:37:23 +02:00
|
|
|
|
{
|
|
|
|
|
memcpy (tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
|
|
|
|
|
c_tree_code_type,
|
|
|
|
|
(int)LAST_C_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
|
|
|
|
|
memcpy (tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
|
|
|
|
|
c_tree_code_length,
|
|
|
|
|
(LAST_C_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
|
|
|
|
|
memcpy (tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
|
|
|
|
|
c_tree_code_name,
|
|
|
|
|
(LAST_C_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
|
2000-11-21 20:09:38 +01:00
|
|
|
|
lang_unsafe_for_reeval = c_unsafe_for_reeval;
|
2000-06-17 04:37:23 +02:00
|
|
|
|
}
|
2000-10-06 16:59:56 +02:00
|
|
|
|
|
|
|
|
|
#define CALLED_AS_BUILT_IN(NODE) \
|
|
|
|
|
(!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
|
|
|
|
|
|
|
|
|
|
static rtx
|
|
|
|
|
c_expand_builtin (exp, target, tmode, modifier)
|
|
|
|
|
tree exp;
|
|
|
|
|
rtx target;
|
|
|
|
|
enum machine_mode tmode;
|
|
|
|
|
enum expand_modifier modifier;
|
|
|
|
|
{
|
|
|
|
|
tree type = TREE_TYPE (exp);
|
|
|
|
|
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
|
|
|
|
|
tree arglist = TREE_OPERAND (exp, 1);
|
|
|
|
|
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
|
|
|
|
|
enum tree_code code = TREE_CODE (exp);
|
|
|
|
|
const int ignore = (target == const0_rtx
|
|
|
|
|
|| ((code == NON_LVALUE_EXPR || code == NOP_EXPR
|
|
|
|
|
|| code == CONVERT_EXPR || code == REFERENCE_EXPR
|
|
|
|
|
|| code == COND_EXPR)
|
|
|
|
|
&& TREE_CODE (type) == VOID_TYPE));
|
|
|
|
|
|
|
|
|
|
if (! optimize && ! CALLED_AS_BUILT_IN (fndecl))
|
|
|
|
|
return expand_call (exp, target, ignore);
|
|
|
|
|
|
|
|
|
|
switch (fcode)
|
|
|
|
|
{
|
|
|
|
|
case BUILT_IN_PRINTF:
|
|
|
|
|
target = c_expand_builtin_printf (arglist, target, tmode,
|
|
|
|
|
modifier, ignore);
|
|
|
|
|
if (target)
|
|
|
|
|
return target;
|
|
|
|
|
break;
|
|
|
|
|
|
2001-01-08 00:15:47 +01:00
|
|
|
|
case BUILT_IN_FPRINTF:
|
|
|
|
|
target = c_expand_builtin_fprintf (arglist, target, tmode,
|
|
|
|
|
modifier, ignore);
|
|
|
|
|
if (target)
|
|
|
|
|
return target;
|
|
|
|
|
break;
|
|
|
|
|
|
2000-10-06 16:59:56 +02:00
|
|
|
|
default: /* just do library call, if unknown builtin */
|
|
|
|
|
error ("built-in function `%s' not currently supported",
|
|
|
|
|
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The switch statement above can drop through to cause the function
|
|
|
|
|
to be called normally. */
|
|
|
|
|
return expand_call (exp, target, ignore);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check an arglist to *printf for problems. The arglist should start
|
|
|
|
|
at the format specifier, with the remaining arguments immediately
|
|
|
|
|
following it. */
|
|
|
|
|
static int
|
|
|
|
|
is_valid_printf_arglist (arglist)
|
|
|
|
|
tree arglist;
|
|
|
|
|
{
|
|
|
|
|
/* Save this value so we can restore it later. */
|
|
|
|
|
const int SAVE_pedantic = pedantic;
|
|
|
|
|
int diagnostic_occurred = 0;
|
|
|
|
|
|
|
|
|
|
/* Set this to a known value so the user setting won't affect code
|
|
|
|
|
generation. */
|
|
|
|
|
pedantic = 1;
|
|
|
|
|
/* Check to make sure there are no format specifier errors. */
|
|
|
|
|
check_function_format (&diagnostic_occurred,
|
|
|
|
|
maybe_get_identifier("printf"),
|
|
|
|
|
NULL_TREE, arglist);
|
|
|
|
|
|
|
|
|
|
/* Restore the value of `pedantic'. */
|
|
|
|
|
pedantic = SAVE_pedantic;
|
|
|
|
|
|
|
|
|
|
/* If calling `check_function_format_ptr' produces a warning, we
|
|
|
|
|
return false, otherwise we return true. */
|
|
|
|
|
return ! diagnostic_occurred;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the arguments passed to printf are suitable for optimizations,
|
|
|
|
|
we attempt to transform the call. */
|
|
|
|
|
static rtx
|
|
|
|
|
c_expand_builtin_printf (arglist, target, tmode, modifier, ignore)
|
|
|
|
|
tree arglist;
|
|
|
|
|
rtx target;
|
|
|
|
|
enum machine_mode tmode;
|
|
|
|
|
enum expand_modifier modifier;
|
|
|
|
|
int ignore;
|
|
|
|
|
{
|
|
|
|
|
tree fn_putchar = built_in_decls[BUILT_IN_PUTCHAR],
|
|
|
|
|
fn_puts = built_in_decls[BUILT_IN_PUTS];
|
|
|
|
|
tree fn, format_arg, stripped_string;
|
|
|
|
|
|
|
|
|
|
/* If the return value is used, or the replacement _DECL isn't
|
|
|
|
|
initialized, don't do the transformation. */
|
|
|
|
|
if (!ignore || !fn_putchar || !fn_puts)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Verify the required arguments in the original call. */
|
|
|
|
|
if (arglist == 0
|
|
|
|
|
|| (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Check the specifier vs. the parameters. */
|
|
|
|
|
if (!is_valid_printf_arglist (arglist))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
format_arg = TREE_VALUE (arglist);
|
|
|
|
|
stripped_string = format_arg;
|
|
|
|
|
STRIP_NOPS (stripped_string);
|
|
|
|
|
if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
|
|
|
|
|
stripped_string = TREE_OPERAND (stripped_string, 0);
|
|
|
|
|
|
|
|
|
|
/* If the format specifier isn't a STRING_CST, punt. */
|
|
|
|
|
if (TREE_CODE (stripped_string) != STRING_CST)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* OK! We can attempt optimization. */
|
|
|
|
|
|
|
|
|
|
/* If the format specifier was "%s\n", call __builtin_puts(arg2). */
|
|
|
|
|
if (strcmp (TREE_STRING_POINTER (stripped_string), "%s\n") == 0)
|
|
|
|
|
{
|
|
|
|
|
arglist = TREE_CHAIN (arglist);
|
|
|
|
|
fn = fn_puts;
|
|
|
|
|
}
|
|
|
|
|
/* If the format specifier was "%c", call __builtin_putchar (arg2). */
|
|
|
|
|
else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0)
|
|
|
|
|
{
|
|
|
|
|
arglist = TREE_CHAIN (arglist);
|
|
|
|
|
fn = fn_putchar;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* We can't handle anything else with % args or %% ... yet. */
|
|
|
|
|
if (strchr (TREE_STRING_POINTER (stripped_string), '%'))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* If the resulting constant string has a length of 1, call
|
|
|
|
|
putchar. Note, TREE_STRING_LENGTH includes the terminating
|
|
|
|
|
NULL in its count. */
|
|
|
|
|
if (TREE_STRING_LENGTH (stripped_string) == 2)
|
|
|
|
|
{
|
|
|
|
|
/* Given printf("c"), (where c is any one character,)
|
|
|
|
|
convert "c"[0] to an int and pass that to the replacement
|
|
|
|
|
function. */
|
|
|
|
|
arglist = build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0);
|
|
|
|
|
arglist = build_tree_list (NULL_TREE, arglist);
|
|
|
|
|
|
|
|
|
|
fn = fn_putchar;
|
|
|
|
|
}
|
|
|
|
|
/* If the resulting constant was "string\n", call
|
|
|
|
|
__builtin_puts("string"). Ensure "string" has at least one
|
|
|
|
|
character besides the trailing \n. Note, TREE_STRING_LENGTH
|
|
|
|
|
includes the terminating NULL in its count. */
|
|
|
|
|
else if (TREE_STRING_LENGTH (stripped_string) > 2
|
|
|
|
|
&& TREE_STRING_POINTER (stripped_string)
|
|
|
|
|
[TREE_STRING_LENGTH (stripped_string) - 2] == '\n')
|
|
|
|
|
{
|
|
|
|
|
/* Create a NULL-terminated string that's one char shorter
|
|
|
|
|
than the original, stripping off the trailing '\n'. */
|
|
|
|
|
const int newlen = TREE_STRING_LENGTH (stripped_string) - 1;
|
|
|
|
|
char *newstr = (char *) alloca (newlen);
|
|
|
|
|
memcpy (newstr, TREE_STRING_POINTER (stripped_string), newlen - 1);
|
|
|
|
|
newstr[newlen - 1] = 0;
|
|
|
|
|
|
2000-10-09 18:30:43 +02:00
|
|
|
|
arglist = combine_strings (build_string (newlen, newstr));
|
2000-10-06 16:59:56 +02:00
|
|
|
|
arglist = build_tree_list (NULL_TREE, arglist);
|
|
|
|
|
fn = fn_puts;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* We'd like to arrange to call fputs(string) here, but we
|
|
|
|
|
need stdout and don't have a way to get it ... yet. */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return expand_expr (build_function_call (fn, arglist),
|
|
|
|
|
(ignore ? const0_rtx : target),
|
|
|
|
|
tmode, modifier);
|
|
|
|
|
}
|
2001-01-08 00:15:47 +01:00
|
|
|
|
|
|
|
|
|
/* If the arguments passed to fprintf are suitable for optimizations,
|
|
|
|
|
we attempt to transform the call. */
|
|
|
|
|
static rtx
|
|
|
|
|
c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore)
|
|
|
|
|
tree arglist;
|
|
|
|
|
rtx target;
|
|
|
|
|
enum machine_mode tmode;
|
|
|
|
|
enum expand_modifier modifier;
|
|
|
|
|
int ignore;
|
|
|
|
|
{
|
|
|
|
|
tree fn_fputc = built_in_decls[BUILT_IN_FPUTC],
|
|
|
|
|
fn_fputs = built_in_decls[BUILT_IN_FPUTS];
|
|
|
|
|
tree fn, format_arg, stripped_string;
|
|
|
|
|
|
|
|
|
|
/* If the return value is used, or the replacement _DECL isn't
|
|
|
|
|
initialized, don't do the transformation. */
|
|
|
|
|
if (!ignore || !fn_fputc || !fn_fputs)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Verify the required arguments in the original call. */
|
|
|
|
|
if (arglist == 0
|
|
|
|
|
|| (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
|
|
|
|
|
|| (TREE_CHAIN (arglist) == 0)
|
|
|
|
|
|| (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) !=
|
|
|
|
|
POINTER_TYPE))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Check the specifier vs. the parameters. */
|
|
|
|
|
if (!is_valid_printf_arglist (TREE_CHAIN (arglist)))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
format_arg = TREE_VALUE (TREE_CHAIN (arglist));
|
|
|
|
|
stripped_string = format_arg;
|
|
|
|
|
STRIP_NOPS (stripped_string);
|
|
|
|
|
if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
|
|
|
|
|
stripped_string = TREE_OPERAND (stripped_string, 0);
|
|
|
|
|
|
|
|
|
|
/* If the format specifier isn't a STRING_CST, punt. */
|
|
|
|
|
if (TREE_CODE (stripped_string) != STRING_CST)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* OK! We can attempt optimization. */
|
|
|
|
|
|
|
|
|
|
/* If the format specifier was "%s", call __builtin_fputs(arg3, arg1). */
|
|
|
|
|
if (strcmp (TREE_STRING_POINTER (stripped_string), "%s") == 0)
|
|
|
|
|
{
|
|
|
|
|
tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist));
|
|
|
|
|
arglist = tree_cons (NULL_TREE,
|
|
|
|
|
TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
|
|
|
|
|
newarglist);
|
|
|
|
|
fn = fn_fputs;
|
|
|
|
|
}
|
|
|
|
|
/* If the format specifier was "%c", call __builtin_fputc (arg3, arg1). */
|
|
|
|
|
else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0)
|
|
|
|
|
{
|
|
|
|
|
tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist));
|
|
|
|
|
arglist = tree_cons (NULL_TREE,
|
|
|
|
|
TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
|
|
|
|
|
newarglist);
|
|
|
|
|
fn = fn_fputc;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* We can't handle anything else with % args or %% ... yet. */
|
|
|
|
|
if (strchr (TREE_STRING_POINTER (stripped_string), '%'))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* When "string" doesn't contain %, replace all cases of
|
|
|
|
|
fprintf(stream,string) with fputs(string,stream). The fputs
|
|
|
|
|
builtin will take take of special cases like length==1. */
|
|
|
|
|
arglist = tree_cons (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)),
|
|
|
|
|
build_tree_list (NULL_TREE, TREE_VALUE (arglist)));
|
|
|
|
|
fn = fn_fputs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return expand_expr (build_function_call (fn, arglist),
|
|
|
|
|
(ignore ? const0_rtx : target),
|
|
|
|
|
tmode, modifier);
|
|
|
|
|
}
|
2000-11-13 15:14:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Given a boolean expression ARG, return a tree representing an increment
|
|
|
|
|
or decrement (as indicated by CODE) of ARG. The front end must check for
|
|
|
|
|
invalid cases (e.g., decrement in C++). */
|
|
|
|
|
tree
|
|
|
|
|
boolean_increment (code, arg)
|
|
|
|
|
enum tree_code code;
|
|
|
|
|
tree arg;
|
|
|
|
|
{
|
|
|
|
|
tree val;
|
|
|
|
|
tree true_res = (c_language == clk_cplusplus
|
|
|
|
|
? boolean_true_node
|
|
|
|
|
: c_bool_true_node);
|
|
|
|
|
arg = stabilize_reference (arg);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case PREINCREMENT_EXPR:
|
|
|
|
|
val = build (MODIFY_EXPR, TREE_TYPE (arg), arg, true_res);
|
|
|
|
|
break;
|
|
|
|
|
case POSTINCREMENT_EXPR:
|
|
|
|
|
val = build (MODIFY_EXPR, TREE_TYPE (arg), arg, true_res);
|
|
|
|
|
arg = save_expr (arg);
|
|
|
|
|
val = build (COMPOUND_EXPR, TREE_TYPE (arg), val, arg);
|
|
|
|
|
val = build (COMPOUND_EXPR, TREE_TYPE (arg), arg, val);
|
|
|
|
|
break;
|
|
|
|
|
case PREDECREMENT_EXPR:
|
|
|
|
|
val = build (MODIFY_EXPR, TREE_TYPE (arg), arg, invert_truthvalue (arg));
|
|
|
|
|
break;
|
|
|
|
|
case POSTDECREMENT_EXPR:
|
|
|
|
|
val = build (MODIFY_EXPR, TREE_TYPE (arg), arg, invert_truthvalue (arg));
|
|
|
|
|
arg = save_expr (arg);
|
|
|
|
|
val = build (COMPOUND_EXPR, TREE_TYPE (arg), val, arg);
|
|
|
|
|
val = build (COMPOUND_EXPR, TREE_TYPE (arg), arg, val);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
TREE_SIDE_EFFECTS (val) = 1;
|
|
|
|
|
return val;
|
|
|
|
|
}
|
2001-01-03 21:56:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Do the parts of lang_init common to C and C++. */
|
|
|
|
|
void
|
|
|
|
|
c_common_lang_init ()
|
|
|
|
|
{
|
|
|
|
|
/* If still "unspecified", make it match -fbounded-pointers. */
|
|
|
|
|
if (flag_bounds_check < 0)
|
|
|
|
|
flag_bounds_check = flag_bounded_pointers;
|
|
|
|
|
|
|
|
|
|
/* Special format checking options don't work without -Wformat; warn if
|
|
|
|
|
they are used. */
|
|
|
|
|
if (warn_format_y2k && !warn_format)
|
|
|
|
|
warning ("-Wformat-y2k ignored without -Wformat");
|
|
|
|
|
if (warn_format_extra_args && !warn_format)
|
|
|
|
|
warning ("-Wformat-extra-args ignored without -Wformat");
|
|
|
|
|
if (warn_format_nonliteral && !warn_format)
|
|
|
|
|
warning ("-Wformat-nonliteral ignored without -Wformat");
|
|
|
|
|
if (warn_format_security && !warn_format)
|
|
|
|
|
warning ("-Wformat-security ignored without -Wformat");
|
|
|
|
|
if (warn_missing_format_attribute && !warn_format)
|
|
|
|
|
warning ("-Wmissing-format-attribute ignored without -Wformat");
|
|
|
|
|
}
|