parent
bf6103db43
commit
5156628f9f
171
gcc/cp/ChangeLog
171
gcc/cp/ChangeLog
|
@ -1,3 +1,174 @@
|
|||
Mon Sep 30 12:58:40 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* input.c (sub_getch): Handle 8-bit characters in string literals.
|
||||
|
||||
Sun Sep 29 03:12:01 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* tree.c (mapcar): Handle CONSTRUCTORs.
|
||||
(copy_to_permanent): Handle expression_obstack properly.
|
||||
|
||||
* Make-lang.in (cplib2.txt): Also depend on the headers.
|
||||
|
||||
* rtti.c (get_tinfo_var): Don't assume that POINTER_SIZE ==
|
||||
INT_TYPE_SIZE.
|
||||
(expand_class_desc): Use USItype for offset field.
|
||||
* tinfo.h (struct __class_type_info): Likewise.
|
||||
|
||||
* method.c (build_overload_int): TYPE_PRECISION should be applied
|
||||
to types.
|
||||
|
||||
Sat Sep 28 14:44:50 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c (build_new_op): A COND_EXPR involving void must be a
|
||||
builtin.
|
||||
|
||||
Fri Sep 27 16:40:30 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* typeck.c (build_x_component_ref): New fn.
|
||||
(build_object_ref): Use it.
|
||||
* parse.y (primary): Use it.
|
||||
* decl2.c (build_expr_from_tree): Use it.
|
||||
* cp-tree.h: Declare it.
|
||||
|
||||
* decl.c (start_decl): variable-sized arrays cannot be initialized.
|
||||
* error.c (dump_type_suffix): Handle variable arrays.
|
||||
|
||||
Fri Sep 27 13:14:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* Make-lang.in (exception.o): Put back compiling it with -fPIC.
|
||||
|
||||
Fri Sep 27 03:00:09 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (lookup_name_real): Don't try to look up anything in a
|
||||
TYPENAME_TYPE.
|
||||
|
||||
* tinfo2.cc (__throw_type_match_rtti): Oops.
|
||||
|
||||
Thu Sep 26 22:11:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* Make-lang.in (exception.o): Use -fno-PIC for now.
|
||||
|
||||
Thu Sep 26 10:59:00 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* rtti.c (build_dynamic_cast): Pass tinfo fns rather than
|
||||
calling them.
|
||||
(get_tinfo_fn_dynamic): Extracted from build_typeid.
|
||||
* tinfo2.cc (__dynamic_cast): Adjust.
|
||||
|
||||
* rtti.c (build_typeid): Use resolves_to_fixed_type_p.
|
||||
(build_x_typeid): Likewise.
|
||||
|
||||
* parse.y: Call build_x_typeid instead of build_typeid.
|
||||
* cp-tree.def: Add TYPEID_EXPR.
|
||||
* pt.c (tsubst_copy): Handle typeid.
|
||||
* decl2.c (build_expr_from_tree): Likewise.
|
||||
* rtti.c (build_x_typeid): Throw bad_typeid from here.
|
||||
(build_typeid): Not here.
|
||||
* cp-tree.h: Declare build_x_typeid.
|
||||
|
||||
Wed Sep 25 17:26:16 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c (convert_like): Pull out constant values.
|
||||
|
||||
* tree.c (mapcar): Use build_cplus_array_type, not build_array_type.
|
||||
|
||||
Wed Sep 25 17:28:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
* decl.c (init_decl_processing): Create short int types before
|
||||
creating size_t in case a machine description needs to use
|
||||
unsigned short for size_t.
|
||||
|
||||
Tue Sep 24 18:18:44 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* Make-lang.in (exception.o): Turn off pic.
|
||||
|
||||
* tinfo2.cc (__throw_type_match_rtti): Fix cv-variants of the same
|
||||
type, multi-level ptr conversions.
|
||||
|
||||
* rtti.c (call_void_fn): Renamed and genericized from throw_bad_cast.
|
||||
(throw_bad_cast): Use it.
|
||||
(throw_bad_typeid): New fn.
|
||||
(build_typeid): Throw bad_typeid as needed.
|
||||
Use build_call.
|
||||
(synthesize_tinfo_fn): Handle functions and arrays before checking
|
||||
for cv-quals.
|
||||
|
||||
* Remove .h from standard C++ headers, add new.h, move into inc
|
||||
subdirectory.
|
||||
|
||||
* exception*: Remove pointer from object, constructors. Add
|
||||
default exception::what that uses type_info::name. Add
|
||||
__throw_bad_typeid.
|
||||
|
||||
* init.c (build_new): Don't add a cookie to new (void *) T[2].
|
||||
|
||||
Mon Sep 23 15:21:53 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* Make-lang.in: Building C++ code depends on cc1plus.
|
||||
|
||||
Mon Sep 23 12:38:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* decl.c (struct saved_scope): Declare PROCESSING_TEMPLATE_DECL as
|
||||
a HOST_WIDE_INT, not a tree.
|
||||
|
||||
Mon Sep 23 12:36:02 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* exception.cc: Don't include <stdlib.h>.
|
||||
|
||||
* Make-lang.in (c++.clean): Remove cplib2.*.
|
||||
|
||||
Mon Sep 23 09:42:19 1996 Doug Evans <dje@canuck.cygnus.com>
|
||||
|
||||
* parse.y (component_decl_1, component_costructor_declarator case):
|
||||
Pass attributes/prefix_attributes in tree list.
|
||||
|
||||
Mon Sep 23 01:18:50 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* tinfo{,2}.cc: #include <stddef.h> instead of <stdlib.h>.
|
||||
|
||||
Sun Sep 22 05:31:22 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* lex.c (do_identifier): Don't do deferred lookup in a template
|
||||
header.
|
||||
|
||||
* typeck2.c (store_init_value): Oops.
|
||||
|
||||
* new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}:
|
||||
New files for C++ lang-support library.
|
||||
* Make-lang.in (CXX_EXTRA_HEADERS): Define.
|
||||
(CXX_LIB2FUNCS): Define.
|
||||
And rules for building the C++ lang-support code.
|
||||
* config-lang.in (headers): Define.
|
||||
(lib2funcs): Define.
|
||||
|
||||
Sat Sep 21 19:17:28 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl2.c (build_expr_from_tree): If CONSTRUCTOR has a type, call
|
||||
digest_init.
|
||||
* pt.c (tsubst_copy): Compute type for CONSTRUCTOR.
|
||||
* typeck2.c (store_init_value): Check for initializing pmf with { }
|
||||
here.
|
||||
(process_init_constructor): Not here.
|
||||
|
||||
Thu Sep 19 16:41:07 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* pt.c (begin_template_parm_list): Increment
|
||||
processing_template_decl here.
|
||||
(end_template_parm_list): Not here.
|
||||
(process_template_parm): No need to add 1 to it now.
|
||||
* *.c: Use processing_template_decl instead of current_template_parms
|
||||
to check for being in a template.
|
||||
|
||||
* pt.c (uses_template_parms): Handle SCOPE_REF. Fix CONSTRUCTOR.
|
||||
(tsubst_copy): Handle CONSTRUCTOR.
|
||||
(instantiate_decl): Set up context properly for variables.
|
||||
* decl2.c (build_expr_from_tree): Handle CONSTRUCTOR.
|
||||
* class.c (finish_struct): Reverse CLASSTYPE_TAGS.
|
||||
|
||||
Wed Sep 18 13:30:20 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* lex.c (enum tree_node_kind) [GATHER_STATISTICS]: Put the enum back.
|
||||
|
||||
Wed Sep 18 04:24:07 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* method.c (make_thunk): Call comdat_linkage before setting the
|
||||
|
|
|
@ -52,6 +52,15 @@ GXX_CROSS_NAME = `t='$(program_transform_cross_name)'; echo g++ | sed $$t`
|
|||
|
||||
# The name to use for the demangler program.
|
||||
DEMANGLER_PROG = c++filt
|
||||
|
||||
# Extra headers to install.
|
||||
CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \
|
||||
$(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h
|
||||
|
||||
# Extra code to include in libgcc2.
|
||||
CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o exception.o
|
||||
CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/exception.cc \
|
||||
$(srcdir)/cp/tinfo.cc $(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h
|
||||
|
||||
# Define the names for selecting c++ in LANGUAGES.
|
||||
# Note that it would be nice to move the dependency on g++
|
||||
|
@ -105,6 +114,46 @@ c++.rest.encap: $(DEMANGLER_PROG)
|
|||
|
||||
c++.info:
|
||||
c++.dvi:
|
||||
|
||||
# C++ language-support library pieces for libgcc.
|
||||
tinfo.o: cc1plus $(srcdir)/cp/tinfo.cc
|
||||
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
|
||||
-c $(srcdir)/cp/tinfo.cc
|
||||
tinfo2.o: cc1plus $(srcdir)/cp/tinfo2.cc
|
||||
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
|
||||
-c $(srcdir)/cp/tinfo2.cc
|
||||
exception.o: cc1plus $(srcdir)/cp/exception.cc
|
||||
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
|
||||
-c -O0 -fexceptions $(srcdir)/cp/exception.cc
|
||||
new.o: cc1plus $(srcdir)/cp/new.cc
|
||||
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
|
||||
-c $(srcdir)/cp/new.cc
|
||||
|
||||
# We want to update cplib2.txt if any of the source files change...
|
||||
cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready
|
||||
if [ -f cc1plus ]; then \
|
||||
echo $(CXX_LIB2FUNCS) > cplib2.new; \
|
||||
else \
|
||||
echo "" > cplib2.new; \
|
||||
fi
|
||||
mv -f cplib2.new cplib2.txt
|
||||
|
||||
# Or if it would be different.
|
||||
cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs
|
||||
@if [ -r cplib2.txt ]; then \
|
||||
if [ -f cc1plus ]; then \
|
||||
echo $(CXX_LIB2FUNCS) > cplib2.new; \
|
||||
else \
|
||||
echo "" > cplib2.new; \
|
||||
fi; \
|
||||
if cmp -s cplib2.new cplib2.txt; then \
|
||||
touch cplib2.ready; \
|
||||
fi; \
|
||||
rm -f cplib2.new; \
|
||||
fi
|
||||
@if [ -f cplib2.ready ]; then true; else \
|
||||
touch cplib2.ready; \
|
||||
fi
|
||||
|
||||
# Install hooks:
|
||||
# cc1plus is installed elsewhere as part of $(COMPILERS).
|
||||
|
@ -165,6 +214,7 @@ c++.uninstall:
|
|||
c++.mostlyclean:
|
||||
-rm -f cp/*$(objext) $(DEMANGLER_PROG)
|
||||
c++.clean:
|
||||
-rm -f cplib2.txt cplib2.ready
|
||||
c++.distclean:
|
||||
-rm -f cp/config.status cp/Makefile
|
||||
-rm -f cp/parse.output
|
||||
|
|
|
@ -1410,7 +1410,7 @@ build_scoped_method_call (exp, basetype, name, parms)
|
|||
|| basetype == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
{
|
||||
|
@ -1681,7 +1681,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
|| (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
|
||||
return error_mark_node;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
{
|
||||
|
@ -4545,9 +4545,16 @@ build_new_op (code, flags, arg1, arg2, arg3)
|
|||
if (arg3 && TREE_CODE (arg3) == OFFSET_REF)
|
||||
arg3 = resolve_offset_ref (arg3);
|
||||
|
||||
if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
|
||||
&& (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2)))
|
||||
&& (! arg3 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
|
||||
if (code == COND_EXPR)
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE
|
||||
|| (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))
|
||||
&& ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
|
||||
goto builtin;
|
||||
}
|
||||
else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
|
||||
&& (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))))
|
||||
goto builtin;
|
||||
|
||||
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
|
||||
|
@ -4871,6 +4878,8 @@ convert_like (convs, expr)
|
|||
case IDENTITY_CONV:
|
||||
if (type_unknown_p (expr))
|
||||
expr = instantiate_type (TREE_TYPE (convs), expr, 1);
|
||||
if (TREE_READONLY_DECL_P (expr))
|
||||
expr = decl_constant_value (expr);
|
||||
return expr;
|
||||
case AMBIG_CONV:
|
||||
/* Call build_user_type_conversion again for the error. */
|
||||
|
|
|
@ -4341,7 +4341,10 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
|
|||
defined for this type. */
|
||||
if (CLASSTYPE_TAGS (t) || dummy)
|
||||
{
|
||||
x = CLASSTYPE_TAGS (t);
|
||||
/* The list of tags was built up in pushtag in reverse order; we need
|
||||
to fix that so that enumerators will be processed in forward order
|
||||
in template instantiation. */
|
||||
CLASSTYPE_TAGS (t) = x = nreverse (CLASSTYPE_TAGS (t));
|
||||
while (x)
|
||||
{
|
||||
tree tag = TYPE_NAME (TREE_VALUE (x));
|
||||
|
|
|
@ -33,3 +33,7 @@ compilers="cc1plus\$(exeext)"
|
|||
stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
|
||||
|
||||
diff_excludes="-x cp/parse.c -x cp/parse.h"
|
||||
|
||||
headers='$(CXX_EXTRA_HEADERS)'
|
||||
|
||||
lib2funcs=cplib2.txt
|
||||
|
|
|
@ -120,6 +120,7 @@ DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", "1", 1)
|
|||
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "1", 1)
|
||||
DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
|
||||
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
|
||||
DEFTREECODE (TYPEID_EXPR, "typeid_expr", "e", 1)
|
||||
|
||||
DEFTREECODE (EXPR_STMT, "expr_stmt", "e", 1)
|
||||
DEFTREECODE (COMPOUND_STMT, "compound_stmt", "e", 1)
|
||||
|
|
|
@ -2169,7 +2169,9 @@ extern void finish_repo PROTO((void));
|
|||
|
||||
/* in rtti.c */
|
||||
extern tree get_tinfo_fn PROTO((tree));
|
||||
extern tree get_tinfo_fn_dynamic PROTO((tree));
|
||||
extern tree build_typeid PROTO((tree));
|
||||
extern tree build_x_typeid PROTO((tree));
|
||||
extern tree get_typeid PROTO((tree));
|
||||
extern tree build_dynamic_cast PROTO((tree, tree));
|
||||
|
||||
|
@ -2454,6 +2456,7 @@ extern tree default_conversion PROTO((tree));
|
|||
extern tree build_object_ref PROTO((tree, tree, tree));
|
||||
extern tree build_component_ref_1 PROTO((tree, tree, int));
|
||||
extern tree build_component_ref PROTO((tree, tree, tree, int));
|
||||
extern tree build_x_component_ref PROTO((tree, tree, tree, int));
|
||||
extern tree build_x_indirect_ref PROTO((tree, char *));
|
||||
extern tree build_indirect_ref PROTO((tree, char *));
|
||||
extern tree build_x_array_ref PROTO((tree, tree));
|
||||
|
|
119
gcc/cp/decl.c
119
gcc/cp/decl.c
|
@ -1773,6 +1773,7 @@ struct saved_scope {
|
|||
int minimal_parse_mode;
|
||||
tree last_function_parms;
|
||||
tree template_parms;
|
||||
HOST_WIDE_INT processing_template_decl;
|
||||
tree previous_class_type, previous_class_values;
|
||||
};
|
||||
static struct saved_scope *current_saved_scope;
|
||||
|
@ -1869,6 +1870,7 @@ maybe_push_to_top_level (pseudo)
|
|||
s->minimal_parse_mode = minimal_parse_mode;
|
||||
s->last_function_parms = last_function_parms;
|
||||
s->template_parms = current_template_parms;
|
||||
s->processing_template_decl = processing_template_decl;
|
||||
s->previous_class_type = previous_class_type;
|
||||
s->previous_class_values = previous_class_values;
|
||||
|
||||
|
@ -1884,7 +1886,10 @@ maybe_push_to_top_level (pseudo)
|
|||
minimal_parse_mode = 0;
|
||||
previous_class_type = previous_class_values = NULL_TREE;
|
||||
if (!pseudo)
|
||||
{
|
||||
current_template_parms = NULL_TREE;
|
||||
processing_template_decl = 0;
|
||||
}
|
||||
|
||||
s->prev = current_saved_scope;
|
||||
s->old_bindings = old_bindings;
|
||||
|
@ -1943,6 +1948,7 @@ pop_from_top_level ()
|
|||
minimal_parse_mode = s->minimal_parse_mode;
|
||||
last_function_parms = s->last_function_parms;
|
||||
current_template_parms = s->template_parms;
|
||||
processing_template_decl = s->processing_template_decl;
|
||||
previous_class_type = s->previous_class_type;
|
||||
previous_class_values = s->previous_class_values;
|
||||
|
||||
|
@ -2078,7 +2084,7 @@ pushtag (name, type, globalize)
|
|||
|
||||
TYPE_NAME (type) = d;
|
||||
DECL_CONTEXT (d) = context;
|
||||
if (! globalize && current_template_parms && IS_AGGR_TYPE (type))
|
||||
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
|
||||
push_template_decl (d);
|
||||
|
||||
/* If it is anonymous, then we are called from pushdecl,
|
||||
|
@ -2110,7 +2116,7 @@ pushtag (name, type, globalize)
|
|||
|
||||
TYPE_MAIN_DECL (type) = d;
|
||||
DECL_CONTEXT (d) = context;
|
||||
if (! globalize && current_template_parms && IS_AGGR_TYPE (type))
|
||||
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
|
||||
push_template_decl (d);
|
||||
|
||||
d = pushdecl_class_level (d);
|
||||
|
@ -2723,7 +2729,7 @@ duplicate_decls (newdecl, olddecl)
|
|||
/* Lay the type out, unless already done. */
|
||||
if (oldtype != TREE_TYPE (newdecl)
|
||||
&& TREE_TYPE (newdecl) != error_mark_node
|
||||
&& !(current_template_parms && uses_template_parms (newdecl)))
|
||||
&& !(processing_template_decl && uses_template_parms (newdecl)))
|
||||
layout_type (TREE_TYPE (newdecl));
|
||||
|
||||
if ((TREE_CODE (newdecl) == VAR_DECL
|
||||
|
@ -2731,7 +2737,7 @@ duplicate_decls (newdecl, olddecl)
|
|||
|| TREE_CODE (newdecl) == RESULT_DECL
|
||||
|| TREE_CODE (newdecl) == FIELD_DECL
|
||||
|| TREE_CODE (newdecl) == TYPE_DECL)
|
||||
&& !(current_template_parms && uses_template_parms (newdecl)))
|
||||
&& !(processing_template_decl && uses_template_parms (newdecl)))
|
||||
layout_decl (newdecl, 0);
|
||||
|
||||
/* Merge the type qualifiers. */
|
||||
|
@ -4312,7 +4318,7 @@ make_typename_type (context, name)
|
|||
else if (TREE_CODE (name) != IDENTIFIER_NODE)
|
||||
my_friendly_abort (2000);
|
||||
|
||||
if (! current_template_parms
|
||||
if (! processing_template_decl
|
||||
|| ! uses_template_parms (context)
|
||||
|| context == current_class_type)
|
||||
{
|
||||
|
@ -4325,11 +4331,11 @@ make_typename_type (context, name)
|
|||
return TREE_TYPE (t);
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
t = make_lang_type (TYPENAME_TYPE);
|
||||
d = build_decl (TYPE_DECL, name, t);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
pop_obstacks ();
|
||||
|
||||
TYPE_CONTEXT (t) = context;
|
||||
|
@ -4389,7 +4395,8 @@ lookup_name_real (name, prefer_type, nonclass)
|
|||
val = lookup_namespace_name (type, name);
|
||||
}
|
||||
else if (! IS_AGGR_TYPE (type)
|
||||
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM)
|
||||
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|
||||
|| TREE_CODE (type) == TYPENAME_TYPE)
|
||||
/* Someone else will give an error about this if needed. */
|
||||
val = NULL_TREE;
|
||||
else if (TYPE_BEING_DEFINED (type))
|
||||
|
@ -4421,7 +4428,7 @@ lookup_name_real (name, prefer_type, nonclass)
|
|||
val = NULL_TREE;
|
||||
|
||||
#if 1
|
||||
if (got_scope && current_template_parms
|
||||
if (got_scope && processing_template_decl
|
||||
&& got_scope != current_class_type
|
||||
&& uses_template_parms (got_scope)
|
||||
&& val && TREE_CODE (val) == TYPE_DECL
|
||||
|
@ -4805,6 +4812,12 @@ init_decl_processing ()
|
|||
record_builtin_type (RID_MAX, "long long unsigned",
|
||||
long_long_unsigned_type_node);
|
||||
|
||||
short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
|
||||
record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
|
||||
short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
|
||||
record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node);
|
||||
record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node);
|
||||
|
||||
/* `unsigned long' is the standard type for sizeof.
|
||||
Traditionally, use a signed type.
|
||||
Note that stddef.h uses `unsigned long',
|
||||
|
@ -4824,12 +4837,8 @@ init_decl_processing ()
|
|||
TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype;
|
||||
TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype;
|
||||
TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype;
|
||||
|
||||
short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
|
||||
record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
|
||||
short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
|
||||
record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node);
|
||||
record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node);
|
||||
TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = sizetype;
|
||||
TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = sizetype;
|
||||
|
||||
/* Define both `signed char' and `unsigned char'. */
|
||||
signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
|
||||
|
@ -5646,7 +5655,7 @@ shadow_tag (declspecs)
|
|||
&& TYPE_SIZE (value) == NULL_TREE)
|
||||
{
|
||||
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (value);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_template_decl (TYPE_MAIN_DECL (value));
|
||||
}
|
||||
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (value))
|
||||
|
@ -5782,7 +5791,7 @@ start_decl (declarator, declspecs, initialized)
|
|||
type = TREE_TYPE (decl);
|
||||
|
||||
/* Don't lose if destructors must be executed at file-level. */
|
||||
if (! current_template_parms && TREE_STATIC (decl)
|
||||
if (! processing_template_decl && TREE_STATIC (decl)
|
||||
&& TYPE_NEEDS_DESTRUCTOR (complete_type (type))
|
||||
&& !TREE_PERMANENT (decl))
|
||||
{
|
||||
|
@ -5829,13 +5838,25 @@ start_decl (declarator, declspecs, initialized)
|
|||
break;
|
||||
|
||||
default:
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && ! current_template_parms
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
if (TYPE_SIZE (type) != NULL_TREE
|
||||
&& ! TREE_CONSTANT (TYPE_SIZE (type)))
|
||||
{
|
||||
cp_error
|
||||
("variable-sized object `%D' may not be initialized", decl);
|
||||
initialized = 0;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE
|
||||
&& TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
|
||||
{
|
||||
cp_error ("elements of array `%#D' have incomplete type", decl);
|
||||
cp_error
|
||||
("elements of array `%#D' have incomplete type", decl);
|
||||
initialized = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (initialized)
|
||||
{
|
||||
|
@ -5901,7 +5922,7 @@ start_decl (declarator, declspecs, initialized)
|
|||
else
|
||||
tem = pushdecl (decl);
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (! current_function_decl)
|
||||
push_template_decl (tem);
|
||||
|
@ -5922,7 +5943,7 @@ start_decl (declarator, declspecs, initialized)
|
|||
DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
|
||||
#endif
|
||||
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
start_decl_1 (tem);
|
||||
|
||||
/* Corresponding pop_obstacks is done in `cp_finish_decl'. */
|
||||
|
@ -5942,7 +5963,7 @@ start_decl (declarator, declspecs, initialized)
|
|||
use temporary storage. Do this even if we will ignore the value. */
|
||||
if (toplevel_bindings_p () && debug_temp_inits)
|
||||
{
|
||||
if (current_template_parms
|
||||
if (processing_template_decl
|
||||
|| TYPE_NEEDS_CONSTRUCTING (type)
|
||||
|| TREE_CODE (type) == REFERENCE_TYPE)
|
||||
/* In this case, the initializer must lay down in permanent
|
||||
|
@ -6002,7 +6023,7 @@ start_decl_1 (decl)
|
|||
&& TREE_CODE (decl) != TEMPLATE_DECL
|
||||
&& IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl))
|
||||
{
|
||||
if ((! current_template_parms || ! uses_template_parms (type))
|
||||
if ((! processing_template_decl || ! uses_template_parms (type))
|
||||
&& TYPE_SIZE (complete_type (type)) == NULL_TREE)
|
||||
{
|
||||
cp_error ("aggregate `%#D' has incomplete type and cannot be initialized",
|
||||
|
@ -6228,7 +6249,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
|
|||
return;
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (init && DECL_INITIAL (decl))
|
||||
DECL_INITIAL (decl) = init;
|
||||
|
@ -6796,7 +6817,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
|
|||
/* If requested, warn about definitions of large data objects. */
|
||||
|
||||
if (warn_larger_than
|
||||
&& ! current_template_parms
|
||||
&& ! processing_template_decl
|
||||
&& (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
|
||||
&& !DECL_EXTERNAL (decl))
|
||||
{
|
||||
|
@ -8393,7 +8414,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
|
||||
/* If this involves a template parameter, it'll be
|
||||
constant, but we don't know what the value is yet. */
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
itype = make_node (INTEGER_TYPE);
|
||||
TYPE_MIN_VALUE (itype) = size_zero_node;
|
||||
|
@ -9481,7 +9502,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
}
|
||||
|
||||
if (current_lang_name == lang_name_cplusplus
|
||||
&& ! current_template_parms
|
||||
&& ! processing_template_decl
|
||||
&& ! (IDENTIFIER_LENGTH (original_name) == 4
|
||||
&& IDENTIFIER_POINTER (original_name)[0] == 'm'
|
||||
&& strcmp (IDENTIFIER_POINTER (original_name), "main") == 0)
|
||||
|
@ -9873,7 +9894,7 @@ grokparms (first_parm, funcdef_flag)
|
|||
any_init++;
|
||||
if (TREE_CODE (init) == SAVE_EXPR)
|
||||
PARM_DECL_EXPR (init) = 1;
|
||||
else if (current_template_parms)
|
||||
else if (processing_template_decl)
|
||||
;
|
||||
else if (TREE_CODE (init) == VAR_DECL
|
||||
|| TREE_CODE (init) == PARM_DECL)
|
||||
|
@ -9893,7 +9914,7 @@ grokparms (first_parm, funcdef_flag)
|
|||
}
|
||||
else
|
||||
init = require_instantiated_type (type, init, integer_zero_node);
|
||||
if (! current_template_parms
|
||||
if (! processing_template_decl
|
||||
&& ! can_convert_arg (type, TREE_TYPE (init), init))
|
||||
cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
|
||||
TREE_TYPE (init), decl);
|
||||
|
@ -10229,7 +10250,7 @@ grok_op_properties (decl, virtualp, friendp)
|
|||
{
|
||||
if ((name == ansi_opname[(int) POSTINCREMENT_EXPR]
|
||||
|| name == ansi_opname[(int) POSTDECREMENT_EXPR])
|
||||
&& ! current_template_parms
|
||||
&& ! processing_template_decl
|
||||
&& TREE_VALUE (TREE_CHAIN (argtypes)) != integer_type_node)
|
||||
{
|
||||
if (methodp)
|
||||
|
@ -10688,7 +10709,7 @@ finish_enum (enumtype, values)
|
|||
register tree pair;
|
||||
register tree value = DECL_INITIAL (TREE_VALUE (values));
|
||||
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
/* Speed up the main loop by performing some precalculations */
|
||||
TREE_TYPE (TREE_VALUE (values)) = enumtype;
|
||||
|
@ -10700,7 +10721,7 @@ finish_enum (enumtype, values)
|
|||
for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
|
||||
{
|
||||
value = DECL_INITIAL (TREE_VALUE (pair));
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
TREE_TYPE (TREE_VALUE (pair)) = enumtype;
|
||||
TREE_TYPE (value) = enumtype;
|
||||
|
@ -10717,7 +10738,7 @@ finish_enum (enumtype, values)
|
|||
|
||||
TYPE_VALUES (enumtype) = values;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return enumtype;
|
||||
|
||||
{
|
||||
|
@ -10786,7 +10807,7 @@ build_enumerator (name, value)
|
|||
if (value)
|
||||
STRIP_TYPE_NOPS (value);
|
||||
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
/* Validate and default VALUE. */
|
||||
if (value != NULL_TREE)
|
||||
|
@ -10807,7 +10828,7 @@ build_enumerator (name, value)
|
|||
}
|
||||
|
||||
/* Default based on previous value. */
|
||||
if (value == NULL_TREE && ! current_template_parms)
|
||||
if (value == NULL_TREE && ! processing_template_decl)
|
||||
{
|
||||
value = enum_next_value;
|
||||
if (enum_overflow)
|
||||
|
@ -10849,7 +10870,7 @@ build_enumerator (name, value)
|
|||
GNU_xref_decl (current_function_decl, decl);
|
||||
}
|
||||
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
/* Set basis for default for next value. */
|
||||
enum_next_value = build_binary_op_nodefault (PLUS_EXPR, value,
|
||||
|
@ -11059,7 +11080,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|
|||
|
||||
announce_function (decl1);
|
||||
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE)
|
||||
{
|
||||
|
@ -11105,7 +11126,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|
|||
If we already have a decl for this name, and it is a FUNCTION_DECL,
|
||||
use the old decl. */
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_template_decl (decl1);
|
||||
else if (pre_parsed_p == 0)
|
||||
{
|
||||
|
@ -11129,7 +11150,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|
|||
|| flag_alt_external_templates))
|
||||
{
|
||||
if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)
|
||||
|| current_template_parms)
|
||||
|| processing_template_decl)
|
||||
DECL_EXTERNAL (decl1)
|
||||
= (interface_only
|
||||
|| (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines));
|
||||
|
@ -11246,7 +11267,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|
|||
of this function only. Tiemann moved up here from bottom of fn. */
|
||||
temporary_allocation ();
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
extern tree last_tree;
|
||||
++minimal_parse_mode;
|
||||
|
@ -11395,7 +11416,7 @@ store_parm_decls ()
|
|||
|
||||
pushdecl (parm);
|
||||
}
|
||||
if (! current_template_parms
|
||||
if (! processing_template_decl
|
||||
&& (cleanup = maybe_build_cleanup (parm), cleanup))
|
||||
{
|
||||
expand_decl (parm);
|
||||
|
@ -11433,7 +11454,7 @@ store_parm_decls ()
|
|||
|
||||
/* Initialize the RTL code for the function. */
|
||||
DECL_SAVED_INSNS (fndecl) = NULL_RTX;
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
expand_function_start (fndecl, parms_have_cleanups);
|
||||
|
||||
/* Create a binding contour which can be used to catch
|
||||
|
@ -11458,7 +11479,7 @@ store_parm_decls ()
|
|||
}
|
||||
|
||||
/* Take care of exception handling things. */
|
||||
if (! current_template_parms && flag_exceptions)
|
||||
if (! processing_template_decl && flag_exceptions)
|
||||
{
|
||||
rtx insns;
|
||||
start_sequence ();
|
||||
|
@ -11589,7 +11610,7 @@ finish_function (lineno, call_poplevel, nested)
|
|||
store_parm_decls ();
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (DECL_CONSTRUCTOR_P (fndecl) && call_poplevel)
|
||||
{
|
||||
|
@ -12017,7 +12038,7 @@ finish_function (lineno, call_poplevel, nested)
|
|||
to the FUNCTION_DECL node itself. */
|
||||
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
|
||||
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
/* So we can tell if jump_optimize sets it to 1. */
|
||||
can_reach_end = 0;
|
||||
|
@ -12070,7 +12091,7 @@ finish_function (lineno, call_poplevel, nested)
|
|||
/* Free all the tree nodes making up this function. */
|
||||
/* Switch back to allocating nodes permanently
|
||||
until we start another function. */
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
--minimal_parse_mode;
|
||||
DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl));
|
||||
|
@ -12086,7 +12107,7 @@ finish_function (lineno, call_poplevel, nested)
|
|||
was an actual function definition. */
|
||||
DECL_INITIAL (fndecl) = error_mark_node;
|
||||
/* And we need the arguments for template instantiation. */
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
if (! DECL_CONSTRUCTOR_P (fndecl)
|
||||
|| !(TYPE_USES_VIRTUAL_BASECLASSES
|
||||
|
@ -12178,7 +12199,7 @@ start_method (declspecs, declarator)
|
|||
if (flag_default_inline)
|
||||
DECL_INLINE (fndecl) = 1;
|
||||
|
||||
if (current_template_parms && ! current_function_decl)
|
||||
if (processing_template_decl && ! current_function_decl)
|
||||
push_template_decl (fndecl);
|
||||
|
||||
/* We read in the parameters on the maybepermanent_obstack,
|
||||
|
@ -12437,7 +12458,7 @@ cplus_expand_expr_stmt (exp)
|
|||
push_temp_slots ();
|
||||
target_temp_slot_level = temp_slot_level;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
add_tree (build_min_nt (EXPR_STMT, exp));
|
||||
return;
|
||||
|
|
|
@ -1053,7 +1053,7 @@ grok_array_decl (array_expr, index_exp)
|
|||
|
||||
if (type == error_mark_node || index_exp == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
|
||||
array_expr, index_exp);
|
||||
|
||||
|
@ -1133,7 +1133,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
|
|||
if (exp == error_mark_node)
|
||||
return exp;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
t = build_min (DELETE_EXPR, void_type_node, exp, size);
|
||||
DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
|
||||
|
@ -1455,7 +1455,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
|
|||
because `decl_const_value' would mis-interpret it
|
||||
as only meaning that this VAR_DECL is defined. */
|
||||
init = build1 (NOP_EXPR, TREE_TYPE (value), init);
|
||||
else if (current_template_parms)
|
||||
else if (processing_template_decl)
|
||||
;
|
||||
else if (! TREE_CONSTANT (init))
|
||||
{
|
||||
|
@ -1476,7 +1476,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
|
|||
/* The corresponding pop_obstacks is in cp_finish_decl. */
|
||||
push_obstacks_nochange ();
|
||||
|
||||
if (current_template_parms && ! current_function_decl
|
||||
if (processing_template_decl && ! current_function_decl
|
||||
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
|
||||
push_template_decl (value);
|
||||
|
||||
|
@ -1500,7 +1500,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
|
|||
DECL_ASSEMBLER_NAME (value)
|
||||
= build_static_name (current_class_type, DECL_NAME (value));
|
||||
}
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics);
|
||||
|
||||
/* Static consts need not be initialized in the class definition. */
|
||||
|
@ -1839,7 +1839,7 @@ setup_vtbl_ptr ()
|
|||
if (base_init_expr == 0
|
||||
&& DECL_CONSTRUCTOR_P (current_function_decl))
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
add_tree (build_min_nt
|
||||
(CTOR_INITIALIZER,
|
||||
current_member_init_list, current_base_init_list));
|
||||
|
@ -3412,13 +3412,26 @@ build_expr_from_tree (t)
|
|||
}
|
||||
|
||||
case COMPONENT_REF:
|
||||
return build_component_ref
|
||||
return build_x_component_ref
|
||||
(build_expr_from_tree (TREE_OPERAND (t, 0)),
|
||||
TREE_OPERAND (t, 1), NULL_TREE, 1);
|
||||
|
||||
case THROW_EXPR:
|
||||
return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
|
||||
|
||||
case CONSTRUCTOR:
|
||||
{
|
||||
tree r = build_nt (CONSTRUCTOR, NULL_TREE,
|
||||
build_expr_from_tree (CONSTRUCTOR_ELTS (t)));
|
||||
|
||||
if (TREE_TYPE (t))
|
||||
return digest_init (TREE_TYPE (t), r, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
case TYPEID_EXPR:
|
||||
return build_x_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
|
||||
|
||||
default:
|
||||
return t;
|
||||
}
|
||||
|
@ -3629,7 +3642,7 @@ mark_used (decl)
|
|||
tree decl;
|
||||
{
|
||||
TREE_USED (decl) = 1;
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return;
|
||||
assemble_external (decl);
|
||||
/* Is it a synthesized method that needs to be synthesized? */
|
||||
|
|
|
@ -487,7 +487,16 @@ dump_type_suffix (t, v)
|
|||
case ARRAY_TYPE:
|
||||
OB_PUTC ('[');
|
||||
if (TYPE_DOMAIN (t))
|
||||
{
|
||||
if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
|
||||
OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
|
||||
else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
|
||||
dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0);
|
||||
else
|
||||
dump_expr (fold (build_binary_op
|
||||
(PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
|
||||
integer_one_node, 1)), 0);
|
||||
}
|
||||
OB_PUTC (']');
|
||||
dump_type_suffix (TREE_TYPE (t), v);
|
||||
break;
|
||||
|
|
|
@ -1132,7 +1132,7 @@ build_throw (e)
|
|||
{
|
||||
if (e != error_mark_node)
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min (THROW_EXPR, void_type_node, e);
|
||||
e = build1 (THROW_EXPR, void_type_node, e);
|
||||
TREE_SIDE_EFFECTS (e) = 1;
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
// Functions for Exception Support for -*- C++ -*-
|
||||
// Copyright (C) 1994, 1995, 1996 Free Software Foundation
|
||||
|
||||
// This file is part of GNU CC.
|
||||
|
||||
// GNU CC is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// GNU CC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with GNU CC; see the file COPYING. If not, write to
|
||||
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
|
||||
// As a special exception, if you link this library with other files,
|
||||
// some of which are compiled with GCC, to produce an executable,
|
||||
// this library does not by itself cause the resulting executable
|
||||
// to be covered by the GNU General Public License.
|
||||
// This exception does not however invalidate any other reasons why
|
||||
// the executable file might be covered by the GNU General Public License.
|
||||
|
||||
#pragma implementation "exception"
|
||||
|
||||
#include "typeinfo"
|
||||
#include "exception"
|
||||
|
||||
/* terminate (), unexpected (), set_terminate (), set_unexpected () as
|
||||
well as the default terminate func and default unexpected func */
|
||||
|
||||
void
|
||||
__default_terminate ()
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
__default_unexpected ()
|
||||
{
|
||||
__default_terminate ();
|
||||
}
|
||||
|
||||
static terminate_handler __terminate_func = __default_terminate;
|
||||
static unexpected_handler __unexpected_func = __default_unexpected;
|
||||
|
||||
terminate_handler
|
||||
set_terminate (terminate_handler func)
|
||||
{
|
||||
terminate_handler old = __terminate_func;
|
||||
|
||||
__terminate_func = func;
|
||||
return old;
|
||||
}
|
||||
|
||||
unexpected_handler
|
||||
set_unexpected (unexpected_handler func)
|
||||
{
|
||||
unexpected_handler old = __unexpected_func;
|
||||
|
||||
__unexpected_func = func;
|
||||
return old;
|
||||
}
|
||||
|
||||
void
|
||||
terminate ()
|
||||
{
|
||||
__terminate_func ();
|
||||
}
|
||||
|
||||
void
|
||||
unexpected ()
|
||||
{
|
||||
__unexpected_func ();
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__throw_bad_cast (void)
|
||||
{
|
||||
throw bad_cast ();
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__throw_bad_typeid (void)
|
||||
{
|
||||
throw bad_typeid ();
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__throw_bad_exception (void)
|
||||
{
|
||||
throw bad_exception ();
|
||||
}
|
||||
|
||||
bool
|
||||
uncaught_exception ()
|
||||
{
|
||||
extern void *__eh_type;
|
||||
extern bool __eh_in_catch;
|
||||
return __eh_type && ! __eh_in_catch;
|
||||
}
|
||||
|
||||
const char * exception::
|
||||
what () const
|
||||
{
|
||||
return typeid (*this).name ();
|
||||
}
|
|
@ -373,7 +373,7 @@ do_case (start, end)
|
|||
if (end && pedantic)
|
||||
pedwarn ("ANSI C++ forbids range expressions in switch statement");
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
add_tree (build_min_nt (CASE_LABEL, start, end));
|
||||
return;
|
||||
|
|
|
@ -1176,10 +1176,9 @@ thrown is used instead. All code that originates exceptions, even code
|
|||
that throws exceptions as a side effect, like dynamic casting, and all
|
||||
code that catches exceptions must be compiled with either -frtti, or
|
||||
-fno-rtti. It is not possible to mix rtti base exception handling
|
||||
objects with code that doesn't use rtti. Also, -frtti can alter the
|
||||
binary layout of classes, so mixing -frtti code and -fno-rtti code can
|
||||
be dangerous. The exceptions to this, are code that doesn't catch or
|
||||
throw exceptions, catch (...), and code that just rethrows an exception.
|
||||
objects with code that doesn't use rtti. The exceptions to this, are
|
||||
code that doesn't catch or throw exceptions, catch (...), and code that
|
||||
just rethrows an exception.
|
||||
|
||||
Currently we use the normal mangling used in building functions names
|
||||
(int's are "i", const char * is PCc) to build the non-rtti base type
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// Exception Handling support header for -*- C++ -*-
|
||||
// Copyright (C) 1995, 1996 Free Software Foundation
|
||||
|
||||
#ifndef __EXCEPTION__
|
||||
#define __EXCEPTION__
|
||||
|
||||
#pragma interface "exception"
|
||||
|
||||
extern "C++" {
|
||||
|
||||
#if 0
|
||||
namespace std {
|
||||
#endif
|
||||
|
||||
class exception {
|
||||
public:
|
||||
exception () { }
|
||||
virtual ~exception () { }
|
||||
virtual const char* what () const;
|
||||
};
|
||||
|
||||
class bad_exception : public exception {
|
||||
public:
|
||||
bad_exception () { }
|
||||
virtual ~bad_exception () { }
|
||||
};
|
||||
|
||||
typedef void (*terminate_handler) ();
|
||||
typedef void (*unexpected_handler) ();
|
||||
|
||||
terminate_handler set_terminate (terminate_handler);
|
||||
void terminate (void);
|
||||
unexpected_handler set_unexpected (unexpected_handler);
|
||||
void unexpected (void);
|
||||
bool uncaught_exception ();
|
||||
} // extern "C++"
|
||||
|
||||
#if 0
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
// The -*- C++ -*- dynamic memory management header.
|
||||
// Copyright (C) 1994, 1996 Free Software Foundation
|
||||
|
||||
#ifndef __NEW__
|
||||
#define __NEW__
|
||||
|
||||
#pragma interface "new"
|
||||
#include <stddef.h>
|
||||
|
||||
extern "C++" {
|
||||
|
||||
#if 0
|
||||
namespace std {
|
||||
#endif
|
||||
|
||||
typedef void (*new_handler)();
|
||||
extern "C" new_handler set_new_handler (new_handler);
|
||||
|
||||
#if 0
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
// G++ implementation internals
|
||||
extern new_handler __new_handler;
|
||||
extern "C" void __default_new_handler (void);
|
||||
|
||||
// replaceable signatures
|
||||
void *operator new (size_t);
|
||||
void *operator new[] (size_t);
|
||||
void operator delete (void *);
|
||||
void operator delete[] (void *);
|
||||
|
||||
// default placement versions of operator new
|
||||
inline void *operator new(size_t, void *place) { return place; }
|
||||
inline void *operator new[](size_t, void *place) { return place; }
|
||||
} // extern "C++"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
// -*- C++ -*- forwarding header.
|
||||
|
||||
#ifndef __NEW_H__
|
||||
#define __NEW_H__
|
||||
|
||||
#include <new>
|
||||
|
||||
#if 0
|
||||
using std::new_handler;
|
||||
using std::set_new_handler;
|
||||
#endif
|
||||
|
||||
#endif // __NEW_H__
|
|
@ -0,0 +1,71 @@
|
|||
// RTTI support for -*- C++ -*-
|
||||
// Copyright (C) 1994, 1995, 1996 Free Software Foundation
|
||||
|
||||
#ifndef __TYPEINFO__
|
||||
#define __TYPEINFO__
|
||||
|
||||
#include <exception>
|
||||
|
||||
extern "C++" {
|
||||
|
||||
#if 0
|
||||
namespace std {
|
||||
#endif
|
||||
|
||||
class type_info {
|
||||
private:
|
||||
// assigning type_info is not supported. made private.
|
||||
type_info& operator= (const type_info&);
|
||||
type_info (const type_info&);
|
||||
|
||||
protected:
|
||||
type_info (const char *n): _name (n) { }
|
||||
|
||||
const char *_name;
|
||||
|
||||
public:
|
||||
// destructor
|
||||
virtual ~type_info ();
|
||||
|
||||
bool before (const type_info& arg);
|
||||
const char* name () const
|
||||
{ return _name; }
|
||||
bool operator== (const type_info& arg) const;
|
||||
bool operator!= (const type_info& arg) const;
|
||||
};
|
||||
|
||||
// We can't rely on common symbols being shared between translation units
|
||||
// under Windows. Sigh.
|
||||
|
||||
#ifndef _WIN32
|
||||
inline bool type_info::
|
||||
operator== (const type_info& arg) const
|
||||
{
|
||||
return &arg == this;
|
||||
}
|
||||
|
||||
inline bool type_info::
|
||||
operator!= (const type_info& arg) const
|
||||
{
|
||||
return &arg != this;
|
||||
}
|
||||
#endif
|
||||
|
||||
class bad_cast : public exception {
|
||||
public:
|
||||
bad_cast() { }
|
||||
virtual ~bad_cast() { }
|
||||
};
|
||||
|
||||
class bad_typeid : public exception {
|
||||
public:
|
||||
bad_typeid () { }
|
||||
virtual ~bad_typeid () { }
|
||||
};
|
||||
|
||||
#if 0
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
} // extern "C++"
|
||||
#endif
|
|
@ -1803,7 +1803,7 @@ build_offset_ref (type, name)
|
|||
tree basebinfo = NULL_TREE;
|
||||
int dtor = 0;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (SCOPE_REF, type, name);
|
||||
|
||||
/* Handle namespace names fully here. */
|
||||
|
@ -2601,6 +2601,7 @@ build_new (placement, decl, init, use_global_new)
|
|||
tree alloc_expr, alloc_temp;
|
||||
int has_array = 0;
|
||||
enum tree_code code = NEW_EXPR;
|
||||
int use_cookie;
|
||||
|
||||
tree pending_sizes = NULL_TREE;
|
||||
|
||||
|
@ -2648,7 +2649,7 @@ build_new (placement, decl, init, use_global_new)
|
|||
{
|
||||
if (this_nelts == NULL_TREE)
|
||||
error ("new of array type fails to specify size");
|
||||
else if (current_template_parms)
|
||||
else if (processing_template_decl)
|
||||
{
|
||||
nelts = this_nelts;
|
||||
absdcl = TREE_OPERAND (absdcl, 0);
|
||||
|
@ -2718,7 +2719,7 @@ build_new (placement, decl, init, use_global_new)
|
|||
decl = TYPE_NAME (type);
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
tree t;
|
||||
if (has_array)
|
||||
|
@ -2801,9 +2802,25 @@ build_new (placement, decl, init, use_global_new)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* Get a little extra space to store a couple of things before the new'ed
|
||||
array. */
|
||||
if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
|
||||
array, if this isn't the default placement new. */
|
||||
|
||||
use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
|
||||
&& ! (placement && ! TREE_CHAIN (placement)
|
||||
&& TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node));
|
||||
#else
|
||||
/* Get a little extra space to store a couple of things before the new'ed
|
||||
array, if this is either non-placement new or new (nothrow). */
|
||||
|
||||
use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
|
||||
&& (! placement
|
||||
|| (IS_AGGR_TYPE (TREE_TYPE (placement))
|
||||
&& (TYPE_IDENTIFIER (TREE_TYPE (placement))
|
||||
== get_identifier ("nothrow_t")))));
|
||||
#endif
|
||||
|
||||
if (use_cookie)
|
||||
{
|
||||
tree extra = BI_header_size;
|
||||
|
||||
|
@ -2857,7 +2874,7 @@ build_new (placement, decl, init, use_global_new)
|
|||
sure we have some extra bytes in that case for the BI_header_size
|
||||
cookies? And how does that interact with the code below? (mrs) */
|
||||
/* Finish up some magic for new'ed arrays */
|
||||
if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && rval != NULL_TREE)
|
||||
if (use_cookie && rval != NULL_TREE)
|
||||
{
|
||||
tree extra = BI_header_size;
|
||||
tree cookie, exp1;
|
||||
|
|
|
@ -163,7 +163,7 @@ sub_getch ()
|
|||
return getch ();
|
||||
}
|
||||
if (input)
|
||||
return input->str[input->offset++];
|
||||
return (unsigned char)input->str[input->offset++];
|
||||
}
|
||||
return getc (finput);
|
||||
}
|
||||
|
|
40
gcc/cp/lex.c
40
gcc/cp/lex.c
|
@ -2654,7 +2654,7 @@ do_identifier (token, parsing)
|
|||
cp_error ("enum `%D' is private", id);
|
||||
/* protected is OK, since it's an enum of `this'. */
|
||||
}
|
||||
if (! current_template_parms
|
||||
if (! processing_template_decl
|
||||
|| (DECL_INITIAL (id)
|
||||
&& TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_CONST_PARM))
|
||||
id = DECL_INITIAL (id);
|
||||
|
@ -2691,7 +2691,7 @@ do_scoped_id (token, parsing)
|
|||
yychar = yylex ();
|
||||
if (! id)
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
|
||||
LOOKUP_EXPR_GLOBAL (id) = 1;
|
||||
|
@ -2716,7 +2716,7 @@ do_scoped_id (token, parsing)
|
|||
else if (TREE_CODE (id) != TREE_LIST)
|
||||
mark_used (id);
|
||||
}
|
||||
if (TREE_CODE (id) == CONST_DECL && ! current_template_parms)
|
||||
if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
|
||||
{
|
||||
/* XXX CHS - should we set TREE_USED of the constant? */
|
||||
id = DECL_INITIAL (id);
|
||||
|
@ -2726,7 +2726,7 @@ do_scoped_id (token, parsing)
|
|||
TREE_CONSTANT (id) = 1;
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (is_overloaded_fn (id))
|
||||
{
|
||||
|
@ -3796,19 +3796,19 @@ real_yylex ()
|
|||
len = p - token_buffer - 1;
|
||||
}
|
||||
#endif
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
pop_obstacks ();
|
||||
TREE_TYPE (yylval.ttype) = wchar_array_type_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
pop_obstacks ();
|
||||
TREE_TYPE (yylval.ttype) = char_array_type_node;
|
||||
}
|
||||
|
@ -4027,6 +4027,30 @@ is_rid (t)
|
|||
}
|
||||
|
||||
#ifdef GATHER_STATISTICS
|
||||
/* The original for tree_node_kind is in the toplevel tree.c; changes there
|
||||
need to be brought into here, unless this were actually put into a header
|
||||
instead. */
|
||||
/* Statistics-gathering stuff. */
|
||||
typedef enum
|
||||
{
|
||||
d_kind,
|
||||
t_kind,
|
||||
b_kind,
|
||||
s_kind,
|
||||
r_kind,
|
||||
e_kind,
|
||||
c_kind,
|
||||
id_kind,
|
||||
op_id_kind,
|
||||
perm_list_kind,
|
||||
temp_list_kind,
|
||||
vec_kind,
|
||||
x_kind,
|
||||
lang_decl,
|
||||
lang_type,
|
||||
all_kinds
|
||||
} tree_node_kind;
|
||||
|
||||
extern int tree_node_counts[];
|
||||
extern int tree_node_sizes[];
|
||||
#endif
|
||||
|
|
|
@ -369,7 +369,7 @@ build_overload_int (value)
|
|||
OB_PUTC ('_');
|
||||
return;
|
||||
}
|
||||
else if (current_template_parms
|
||||
else if (processing_template_decl
|
||||
&& TREE_CODE (value) != INTEGER_CST)
|
||||
/* We don't ever want this output, but it's inconvenient not to
|
||||
be able to build the string. This should cause assembler
|
||||
|
@ -382,7 +382,7 @@ build_overload_int (value)
|
|||
}
|
||||
|
||||
my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
|
||||
if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
|
||||
if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
if (tree_int_cst_lt (value, integer_zero_node))
|
||||
{
|
||||
|
@ -1656,7 +1656,7 @@ hack_identifier (value, name)
|
|||
return value;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE && ! current_template_parms)
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl)
|
||||
value = convert_from_reference (value);
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// Implementation file for the -*- C++ -*- dynamic memory management header.
|
||||
// Copyright (C) 1996 Free Software Foundation
|
||||
// This file is part of GNU CC.
|
||||
|
||||
#pragma implementation "new"
|
||||
#include "new"
|
|
@ -990,7 +990,7 @@ compstmtend:
|
|||
already_scoped_stmt:
|
||||
'{'
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
|
||||
COMPOUND_STMT_NO_SCOPE ($<ttype>$) = 1;
|
||||
|
@ -999,7 +999,7 @@ already_scoped_stmt:
|
|||
}
|
||||
compstmtend
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
|
||||
TREE_CHAIN ($<ttype>2) = NULL_TREE;
|
||||
|
@ -1287,10 +1287,10 @@ primary:
|
|||
| boolean.literal
|
||||
| string
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
$$ = combine_strings ($$);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
pop_obstacks ();
|
||||
}
|
||||
| '(' expr ')'
|
||||
|
@ -1455,7 +1455,7 @@ primary:
|
|||
check_for_new_type ("const_cast", $3);
|
||||
$$ = build_const_cast (type, $6); }
|
||||
| TYPEID '(' expr ')'
|
||||
{ $$ = build_typeid ($3); }
|
||||
{ $$ = build_x_typeid ($3); }
|
||||
| TYPEID '(' type_id ')'
|
||||
{ tree type = groktypename ($3.t);
|
||||
check_for_new_type ("typeid", $3);
|
||||
|
@ -1473,20 +1473,20 @@ primary:
|
|||
| overqualified_id %prec HYPERUNARY
|
||||
{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
|
||||
| overqualified_id '(' nonnull_exprlist ')'
|
||||
{ if (current_template_parms)
|
||||
{ if (processing_template_decl)
|
||||
$$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1), $3, NULL_TREE);
|
||||
else
|
||||
$$ = build_member_call (OP0 ($$), OP1 ($$), $3); }
|
||||
| overqualified_id LEFT_RIGHT
|
||||
{ if (current_template_parms)
|
||||
{ if (processing_template_decl)
|
||||
$$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1),
|
||||
NULL_TREE, NULL_TREE);
|
||||
else
|
||||
$$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
|
||||
| object unqualified_id %prec UNARY
|
||||
{ $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
|
||||
{ $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); }
|
||||
| object overqualified_id %prec UNARY
|
||||
{ if (current_template_parms)
|
||||
{ if (processing_template_decl)
|
||||
$$ = build_min_nt (COMPONENT_REF, $1, copy_to_permanent ($2));
|
||||
else
|
||||
$$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
|
||||
|
@ -2294,7 +2294,7 @@ named_class_head:
|
|||
&& TYPE_SIZE ($$) == NULL_TREE)
|
||||
{
|
||||
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_template_decl (TYPE_MAIN_DECL ($$));
|
||||
}
|
||||
else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
|
||||
|
@ -2496,7 +2496,7 @@ left_curly:
|
|||
pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0);
|
||||
$<ttype>0 = t;
|
||||
}
|
||||
if (current_template_parms && TYPE_CONTEXT (t)
|
||||
if (processing_template_decl && TYPE_CONTEXT (t)
|
||||
&& ! current_class_type)
|
||||
push_template_decl (TYPE_STUB_DECL (t));
|
||||
pushclass (t, 0);
|
||||
|
@ -2507,7 +2507,7 @@ left_curly:
|
|||
&& TYPE_SIZE (t) == NULL_TREE)
|
||||
{
|
||||
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
push_template_decl (TYPE_MAIN_DECL (t));
|
||||
}
|
||||
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
|
||||
|
@ -2672,7 +2672,8 @@ component_decl_1:
|
|||
$$ = grokfield ($2, specs, $5, $3,
|
||||
build_tree_list ($4, attrs)); }
|
||||
| component_constructor_declarator maybeasm maybe_attribute maybe_init
|
||||
{ $$ = grokfield ($$, NULL_TREE, $4, $2, $3); }
|
||||
{ $$ = grokfield ($$, NULL_TREE, $4, $2,
|
||||
build_tree_list ($3, NULL_TREE)); }
|
||||
| using_decl
|
||||
{ $$ = do_class_using_decl ($1); }
|
||||
;
|
||||
|
@ -3242,7 +3243,7 @@ compstmt_or_error:
|
|||
compstmt:
|
||||
'{'
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
|
||||
add_tree ($<ttype>$);
|
||||
|
@ -3250,7 +3251,7 @@ compstmt:
|
|||
}
|
||||
.pushlevel compstmtend .poplevel
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
|
||||
TREE_CHAIN ($<ttype>2) = NULL_TREE;
|
||||
|
@ -3263,7 +3264,7 @@ compstmt:
|
|||
simple_if:
|
||||
IF
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (IF_STMT, NULL_TREE, NULL_TREE,
|
||||
NULL_TREE);
|
||||
|
@ -3273,7 +3274,7 @@ simple_if:
|
|||
}
|
||||
.pushlevel paren_cond_or_null
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (last_tree != $<ttype>2)
|
||||
{
|
||||
|
@ -3292,7 +3293,7 @@ simple_if:
|
|||
}
|
||||
implicitly_scoped_stmt
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>2, 1) = TREE_CHAIN ($<ttype>2);
|
||||
TREE_CHAIN ($<ttype>2) = NULL_TREE;
|
||||
|
@ -3306,7 +3307,7 @@ implicitly_scoped_stmt:
|
|||
{ finish_stmt (); }
|
||||
| .pushlevel
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
|
||||
add_tree ($<ttype>$);
|
||||
|
@ -3314,7 +3315,7 @@ implicitly_scoped_stmt:
|
|||
}
|
||||
simple_stmt .poplevel
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
|
||||
TREE_CHAIN ($<ttype>2) = NULL_TREE;
|
||||
|
@ -3336,7 +3337,7 @@ simple_stmt:
|
|||
| expr ';'
|
||||
{
|
||||
tree expr = $1;
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
emit_line_note (input_filename, lineno);
|
||||
/* Do default conversion if safe and possibly important,
|
||||
|
@ -3350,10 +3351,10 @@ simple_stmt:
|
|||
clear_momentary ();
|
||||
finish_stmt (); }
|
||||
| simple_if ELSE
|
||||
{ if (! current_template_parms) expand_start_else (); }
|
||||
{ if (! processing_template_decl) expand_start_else (); }
|
||||
implicitly_scoped_stmt
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>1, 2) = TREE_CHAIN ($<ttype>1);
|
||||
TREE_CHAIN ($<ttype>1) = NULL_TREE;
|
||||
|
@ -3365,12 +3366,12 @@ simple_stmt:
|
|||
.poplevel
|
||||
{ finish_stmt (); }
|
||||
| simple_if %prec IF
|
||||
{ if (! current_template_parms) expand_end_cond ();
|
||||
{ if (! processing_template_decl) expand_end_cond ();
|
||||
do_poplevel ();
|
||||
finish_stmt (); }
|
||||
| WHILE
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (WHILE_STMT, NULL_TREE, NULL_TREE);
|
||||
add_tree ($<ttype>$);
|
||||
|
@ -3385,7 +3386,7 @@ simple_stmt:
|
|||
}
|
||||
.pushlevel paren_cond_or_null
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (last_tree != $<ttype>2)
|
||||
{
|
||||
|
@ -3404,7 +3405,7 @@ simple_stmt:
|
|||
}
|
||||
already_scoped_stmt .poplevel
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>2, 1) = TREE_CHAIN ($<ttype>2);
|
||||
TREE_CHAIN ($<ttype>2) = NULL_TREE;
|
||||
|
@ -3416,7 +3417,7 @@ simple_stmt:
|
|||
}
|
||||
| DO
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (DO_STMT, NULL_TREE, NULL_TREE);
|
||||
add_tree ($<ttype>$);
|
||||
|
@ -3430,7 +3431,7 @@ simple_stmt:
|
|||
}
|
||||
implicitly_scoped_stmt WHILE
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
|
||||
TREE_CHAIN ($<ttype>2) = NULL_TREE;
|
||||
|
@ -3444,7 +3445,7 @@ simple_stmt:
|
|||
}
|
||||
paren_expr_or_null ';'
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
TREE_OPERAND ($<ttype>2, 1) = $6;
|
||||
else
|
||||
{
|
||||
|
@ -3456,7 +3457,7 @@ simple_stmt:
|
|||
finish_stmt ();
|
||||
}
|
||||
| FOR
|
||||
{ if (current_template_parms)
|
||||
{ if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (FOR_STMT, NULL_TREE, NULL_TREE,
|
||||
NULL_TREE, NULL_TREE);
|
||||
|
@ -3476,7 +3477,7 @@ simple_stmt:
|
|||
}
|
||||
'(' for.init.statement
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (last_tree != $<ttype>2)
|
||||
{
|
||||
|
@ -3494,7 +3495,7 @@ simple_stmt:
|
|||
}
|
||||
.pushlevel xcond ';'
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (last_tree != $<ttype>2)
|
||||
{
|
||||
|
@ -3515,13 +3516,13 @@ simple_stmt:
|
|||
/* Don't let the tree nodes for $10 be discarded
|
||||
by clear_momentary during the parsing of the next stmt. */
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
TREE_OPERAND ($<ttype>2, 2) = $10;
|
||||
push_momentary ();
|
||||
}
|
||||
already_scoped_stmt .poplevel
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>2, 3) = TREE_CHAIN ($<ttype>2);
|
||||
TREE_CHAIN ($<ttype>2) = NULL_TREE;
|
||||
|
@ -3542,7 +3543,7 @@ simple_stmt:
|
|||
finish_stmt (); }
|
||||
| SWITCH .pushlevel '(' condition ')'
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
$<ttype>$ = build_min_nt (SWITCH_STMT, $4, NULL_TREE);
|
||||
add_tree ($<ttype>$);
|
||||
|
@ -3559,7 +3560,7 @@ simple_stmt:
|
|||
}
|
||||
implicitly_scoped_stmt
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
TREE_OPERAND ($<ttype>6, 1) = TREE_CHAIN ($<ttype>6);
|
||||
TREE_CHAIN ($<ttype>6) = NULL_TREE;
|
||||
|
@ -3583,13 +3584,13 @@ simple_stmt:
|
|||
stmt
|
||||
| BREAK ';'
|
||||
{ emit_line_note (input_filename, lineno);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
add_tree (build_min_nt (BREAK_STMT));
|
||||
else if ( ! expand_exit_something ())
|
||||
error ("break statement not within loop or switch"); }
|
||||
| CONTINUE ';'
|
||||
{ emit_line_note (input_filename, lineno);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
add_tree (build_min_nt (CONTINUE_STMT));
|
||||
else if (! expand_continue_loop (0))
|
||||
error ("continue statement not within a loop"); }
|
||||
|
@ -3637,7 +3638,7 @@ simple_stmt:
|
|||
}
|
||||
| GOTO '*' expr ';'
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
add_tree (build_min_nt (GOTO_STMT, $3));
|
||||
else
|
||||
{ emit_line_note (input_filename, lineno);
|
||||
|
@ -3645,7 +3646,7 @@ simple_stmt:
|
|||
}
|
||||
| GOTO identifier ';'
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
add_tree (build_min_nt (GOTO_STMT, $2));
|
||||
else
|
||||
{
|
||||
|
|
61
gcc/cp/pt.c
61
gcc/cp/pt.c
|
@ -80,6 +80,7 @@ begin_template_parm_list ()
|
|||
{
|
||||
pushlevel (0);
|
||||
declare_pseudo_global_level ();
|
||||
++processing_template_decl;
|
||||
}
|
||||
|
||||
/* Process information from new template parameter NEXT and append it to the
|
||||
|
@ -141,7 +142,7 @@ process_template_parm (list, next)
|
|||
decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
|
||||
DECL_INITIAL (decl) = tinfo;
|
||||
DECL_INITIAL (parm) = tinfo;
|
||||
TEMPLATE_CONST_SET_INFO (tinfo, idx, processing_template_decl + 1);
|
||||
TEMPLATE_CONST_SET_INFO (tinfo, idx, processing_template_decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -150,7 +151,7 @@ process_template_parm (list, next)
|
|||
decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
|
||||
TYPE_MAIN_DECL (t) = decl;
|
||||
parm = decl;
|
||||
TEMPLATE_TYPE_SET_INFO (t, idx, processing_template_decl + 1);
|
||||
TEMPLATE_TYPE_SET_INFO (t, idx, processing_template_decl);
|
||||
}
|
||||
SET_DECL_ARTIFICIAL (decl);
|
||||
pushdecl (decl);
|
||||
|
@ -171,7 +172,6 @@ end_template_parm_list (parms)
|
|||
tree parm;
|
||||
tree saved_parmlist = make_tree_vec (list_length (parms));
|
||||
|
||||
++processing_template_decl;
|
||||
current_template_parms
|
||||
= tree_cons (build_int_2 (0, processing_template_decl),
|
||||
saved_parmlist, current_template_parms);
|
||||
|
@ -187,7 +187,7 @@ end_template_parm_list (parms)
|
|||
void
|
||||
end_template_decl ()
|
||||
{
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
return;
|
||||
|
||||
/* This matches the pushlevel in begin_template_parm_list. */
|
||||
|
@ -404,7 +404,7 @@ coerce_template_parms (parms, arglist, in_decl)
|
|||
if (is_type)
|
||||
{
|
||||
val = groktypename (arg);
|
||||
if (! current_template_parms)
|
||||
if (! processing_template_decl)
|
||||
{
|
||||
tree t = target_type (val);
|
||||
if (IS_AGGR_TYPE (t)
|
||||
|
@ -419,12 +419,12 @@ coerce_template_parms (parms, arglist, in_decl)
|
|||
{
|
||||
tree t = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (vec, 0),
|
||||
TREE_VEC_LENGTH (vec), in_decl);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
val = arg;
|
||||
else
|
||||
val = digest_init (t, arg, (tree *) 0);
|
||||
|
||||
if (val == error_mark_node || current_template_parms)
|
||||
if (val == error_mark_node || processing_template_decl)
|
||||
;
|
||||
|
||||
/* 14.2: Other template-arguments must be constant-expressions,
|
||||
|
@ -743,10 +743,10 @@ lookup_template_class (d1, arglist, in_decl)
|
|||
|
||||
if (TYPE_BEING_DEFINED (ctx) && ctx == current_class_type)
|
||||
{
|
||||
tree save_parms = current_template_parms;
|
||||
current_template_parms = NULL_TREE;
|
||||
int save_temp = processing_template_decl;
|
||||
processing_template_decl = 0;
|
||||
t = xref_tag_from_type (TREE_TYPE (template), id, 0);
|
||||
current_template_parms = save_parms;
|
||||
processing_template_decl = save_temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -910,10 +910,13 @@ uses_template_parms (t)
|
|||
case TYPENAME_TYPE:
|
||||
return 1;
|
||||
|
||||
case SCOPE_REF:
|
||||
return uses_template_parms (TREE_OPERAND (t, 0));
|
||||
|
||||
case CONSTRUCTOR:
|
||||
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
|
||||
return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
|
||||
/* else fall through */
|
||||
return uses_template_parms (TREE_OPERAND (t, 1));
|
||||
|
||||
default:
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (t)))
|
||||
|
@ -1384,7 +1387,7 @@ tsubst (t, args, nargs, in_decl)
|
|||
|
||||
{
|
||||
tree max = tsubst_expr (TYPE_MAX_VALUE (t), args, nargs, in_decl);
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
tree itype = make_node (INTEGER_TYPE);
|
||||
TYPE_MIN_VALUE (itype) = size_zero_node;
|
||||
|
@ -1986,6 +1989,7 @@ tsubst_copy (t, args, nargs, in_decl)
|
|||
case SIZEOF_EXPR:
|
||||
case ARROW_EXPR:
|
||||
case THROW_EXPR:
|
||||
case TYPEID_EXPR:
|
||||
return build1
|
||||
(code, NULL_TREE,
|
||||
tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl));
|
||||
|
@ -2139,6 +2143,11 @@ tsubst_copy (t, args, nargs, in_decl)
|
|||
else
|
||||
return t;
|
||||
|
||||
case CONSTRUCTOR:
|
||||
return build
|
||||
(CONSTRUCTOR, tsubst (TREE_TYPE (t), args, nargs, in_decl), NULL_TREE,
|
||||
tsubst_copy (CONSTRUCTOR_ELTS (t), args, nargs, in_decl));
|
||||
|
||||
default:
|
||||
return t;
|
||||
}
|
||||
|
@ -2153,7 +2162,7 @@ tsubst_expr (t, args, nargs, in_decl)
|
|||
if (t == NULL_TREE || t == error_mark_node)
|
||||
return t;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return tsubst_copy (t, args, nargs, in_decl);
|
||||
|
||||
switch (TREE_CODE (t))
|
||||
|
@ -3255,6 +3264,8 @@ instantiate_decl (d)
|
|||
int nested = in_function_p ();
|
||||
int d_defined;
|
||||
int pattern_defined;
|
||||
int line = lineno;
|
||||
char *file = input_filename;
|
||||
|
||||
if (TREE_CODE (d) == FUNCTION_DECL)
|
||||
{
|
||||
|
@ -3297,9 +3308,19 @@ instantiate_decl (d)
|
|||
variable is a static const initialized in the class body. */
|
||||
if (TREE_CODE (d) == VAR_DECL
|
||||
&& ! DECL_INITIAL (d) && DECL_INITIAL (pattern))
|
||||
{
|
||||
lineno = DECL_SOURCE_LINE (d);
|
||||
input_filename = DECL_SOURCE_FILE (d);
|
||||
|
||||
pushclass (DECL_CONTEXT (d), 2);
|
||||
DECL_INITIAL (d) = tsubst_expr
|
||||
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
|
||||
TREE_VEC_LENGTH (args), tmpl);
|
||||
popclass (1);
|
||||
|
||||
lineno = line;
|
||||
input_filename = file;
|
||||
}
|
||||
|
||||
if (! pattern_defined
|
||||
|| (TREE_CODE (d) == FUNCTION_DECL && ! DECL_INLINE (d)
|
||||
|
@ -3320,6 +3341,9 @@ instantiate_decl (d)
|
|||
|
||||
push_to_top_level ();
|
||||
|
||||
lineno = DECL_SOURCE_LINE (d);
|
||||
input_filename = DECL_SOURCE_FILE (d);
|
||||
|
||||
/* Trick tsubst into giving us a new decl in case the template changed. */
|
||||
save_ti = DECL_TEMPLATE_INFO (pattern);
|
||||
DECL_TEMPLATE_INFO (pattern) = NULL_TREE;
|
||||
|
@ -3328,9 +3352,13 @@ instantiate_decl (d)
|
|||
|
||||
/* And set up DECL_INITIAL, since tsubst doesn't. */
|
||||
if (TREE_CODE (td) == VAR_DECL)
|
||||
{
|
||||
pushclass (DECL_CONTEXT (d), 2);
|
||||
DECL_INITIAL (td) = tsubst_expr
|
||||
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
|
||||
TREE_VEC_LENGTH (args), tmpl);
|
||||
popclass (1);
|
||||
}
|
||||
|
||||
/* Convince duplicate_decls to use the DECL_ARGUMENTS from the new decl. */
|
||||
if (TREE_CODE (d) == FUNCTION_DECL)
|
||||
|
@ -3354,11 +3382,6 @@ instantiate_decl (d)
|
|||
else if (TREE_CODE (d) == FUNCTION_DECL)
|
||||
{
|
||||
tree t = DECL_SAVED_TREE (pattern);
|
||||
int line = lineno;
|
||||
char *file = input_filename;
|
||||
|
||||
lineno = DECL_SOURCE_LINE (d);
|
||||
input_filename = DECL_SOURCE_FILE (d);
|
||||
|
||||
start_function (NULL_TREE, d, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
|
@ -3392,10 +3415,10 @@ instantiate_decl (d)
|
|||
TREE_VEC_LENGTH (args), tmpl);
|
||||
|
||||
finish_function (lineno, 0, nested);
|
||||
}
|
||||
|
||||
lineno = line;
|
||||
input_filename = file;
|
||||
}
|
||||
|
||||
pop_from_top_level ();
|
||||
pop_tinst_level ();
|
||||
|
|
235
gcc/cp/rtti.c
235
gcc/cp/rtti.c
|
@ -30,6 +30,10 @@ Boston, MA 02111-1307, USA. */
|
|||
#undef NULL
|
||||
#define NULL 0
|
||||
|
||||
#ifndef INT_TYPE_SIZE
|
||||
#define INT_TYPE_SIZE BITS_PER_WORD
|
||||
#endif
|
||||
|
||||
extern tree define_function ();
|
||||
extern tree build_t_desc_overload ();
|
||||
extern struct obstack *permanent_obstack;
|
||||
|
@ -111,13 +115,59 @@ build_headof (exp)
|
|||
return build (PLUS_EXPR, type, exp,
|
||||
convert (ptrdiff_type_node, offset));
|
||||
}
|
||||
|
||||
/* Build a call to a generic entry point taking and returning void. */
|
||||
|
||||
static tree
|
||||
call_void_fn (name)
|
||||
char *name;
|
||||
{
|
||||
tree d = get_identifier (name);
|
||||
tree type;
|
||||
|
||||
if (IDENTIFIER_GLOBAL_VALUE (d))
|
||||
d = IDENTIFIER_GLOBAL_VALUE (d);
|
||||
else
|
||||
{
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
|
||||
type = build_function_type (void_type_node, void_list_node);
|
||||
d = build_lang_decl (FUNCTION_DECL, d, type);
|
||||
DECL_EXTERNAL (d) = 1;
|
||||
TREE_PUBLIC (d) = 1;
|
||||
DECL_ARTIFICIAL (d) = 1;
|
||||
pushdecl_top_level (d);
|
||||
make_function_rtl (d);
|
||||
assemble_external (d);
|
||||
|
||||
pop_obstacks ();
|
||||
}
|
||||
|
||||
return build_call (d, void_type_node, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Get a bad_cast node for the program to throw...
|
||||
|
||||
See libstdc++/exception.cc for __throw_bad_cast */
|
||||
|
||||
static tree
|
||||
throw_bad_cast ()
|
||||
{
|
||||
return call_void_fn ("__throw_bad_cast");
|
||||
}
|
||||
|
||||
static tree
|
||||
throw_bad_typeid ()
|
||||
{
|
||||
return call_void_fn ("__throw_bad_typeid");
|
||||
}
|
||||
|
||||
/* Return the type_info node associated with the expression EXP. If EXP is
|
||||
a reference to a polymorphic class, return the dynamic type; otherwise
|
||||
return the static type of the expression. */
|
||||
/* Return the type_info function associated with the expression EXP. If
|
||||
EXP is a reference to a polymorphic class, return the dynamic type;
|
||||
otherwise return the static type of the expression. */
|
||||
|
||||
tree
|
||||
build_typeid (exp)
|
||||
get_tinfo_fn_dynamic (exp)
|
||||
tree exp;
|
||||
{
|
||||
tree type;
|
||||
|
@ -127,14 +177,6 @@ build_typeid (exp)
|
|||
|
||||
type = TREE_TYPE (exp);
|
||||
|
||||
/* Strip top-level cv-qualifiers. */
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
/* if b is an instance of B, typeid(b) == typeid(B). Do this before
|
||||
reference trickiness. */
|
||||
if (TREE_CODE (exp) == VAR_DECL && TREE_CODE (type) == RECORD_TYPE)
|
||||
return get_typeid (type);
|
||||
|
||||
/* peel back references, so they match. */
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
type = TREE_TYPE (type);
|
||||
|
@ -142,12 +184,8 @@ build_typeid (exp)
|
|||
/* Peel off cv qualifiers. */
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
/* Apply trivial conversion T -> T& for dereferenced ptrs. */
|
||||
if (TREE_CODE (type) == RECORD_TYPE)
|
||||
type = build_reference_type (type);
|
||||
|
||||
/* If exp is a reference to polymorphic type, get the real type_info. */
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE && TYPE_VIRTUAL_P (TREE_TYPE (type)))
|
||||
if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0))
|
||||
{
|
||||
/* build reference to type_info from vtable. */
|
||||
tree t;
|
||||
|
@ -156,7 +194,7 @@ build_typeid (exp)
|
|||
warning ("taking dynamic typeid of object without -frtti");
|
||||
|
||||
/* If we don't have rtti stuff, get to a sub-object that does. */
|
||||
if (!CLASSTYPE_VFIELDS (TREE_TYPE (type)))
|
||||
if (! CLASSTYPE_VFIELDS (type))
|
||||
{
|
||||
exp = build_unary_op (ADDR_EXPR, exp, 0);
|
||||
exp = build_headof_sub (exp);
|
||||
|
@ -168,14 +206,57 @@ build_typeid (exp)
|
|||
else
|
||||
t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
|
||||
TREE_TYPE (t) = build_pointer_type (tinfo_fn_type);
|
||||
|
||||
t = build (CALL_EXPR, TREE_TYPE (tinfo_fn_type), t, NULL_TREE, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (t) = 1;
|
||||
return convert_from_reference (t);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* otherwise return the type_info for the static type of the expr. */
|
||||
return get_typeid (type);
|
||||
return get_tinfo_fn (TYPE_MAIN_VARIANT (type));
|
||||
}
|
||||
|
||||
tree
|
||||
build_typeid (exp)
|
||||
tree exp;
|
||||
{
|
||||
exp = get_tinfo_fn_dynamic (exp);
|
||||
exp = build_call (exp, TREE_TYPE (tinfo_fn_type), NULL_TREE);
|
||||
return convert_from_reference (exp);
|
||||
}
|
||||
|
||||
tree
|
||||
build_x_typeid (exp)
|
||||
tree exp;
|
||||
{
|
||||
tree cond = NULL_TREE;
|
||||
tree type = TREE_TYPE (tinfo_fn_type);
|
||||
int nonnull;
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (TYPEID_EXPR, exp);
|
||||
|
||||
if (TREE_CODE (exp) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
|
||||
&& TYPE_VIRTUAL_P (TREE_TYPE (exp))
|
||||
&& ! resolves_to_fixed_type_p (exp, &nonnull)
|
||||
&& ! nonnull)
|
||||
{
|
||||
exp = stabilize_reference (exp);
|
||||
cond = convert (boolean_type_node, TREE_OPERAND (exp, 0));
|
||||
}
|
||||
|
||||
exp = get_tinfo_fn_dynamic (exp);
|
||||
exp = build_call (exp, type, NULL_TREE);
|
||||
|
||||
if (cond)
|
||||
{
|
||||
tree bad = throw_bad_typeid ();
|
||||
|
||||
bad = build_compound_expr
|
||||
(tree_cons (NULL_TREE, bad, build_tree_list
|
||||
(NULL_TREE, convert (type, integer_zero_node))));
|
||||
exp = build (COND_EXPR, type, cond, exp, bad);
|
||||
}
|
||||
|
||||
return convert_from_reference (exp);
|
||||
}
|
||||
|
||||
tree
|
||||
|
@ -193,7 +274,7 @@ get_tinfo_var (type)
|
|||
If our struct layout or the type_info classes are changed, this will
|
||||
need to be modified. */
|
||||
if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
|
||||
size = 4 * POINTER_SIZE;
|
||||
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
|
||||
else if (TREE_CODE (type) == POINTER_TYPE
|
||||
&& ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
|
||||
|
@ -207,7 +288,7 @@ get_tinfo_var (type)
|
|||
(TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
|
||||
size = 3 * POINTER_SIZE;
|
||||
else
|
||||
size = 4 * POINTER_SIZE;
|
||||
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
|
||||
}
|
||||
else
|
||||
size = 2 * POINTER_SIZE;
|
||||
|
@ -266,9 +347,8 @@ tree
|
|||
get_typeid_1 (type)
|
||||
tree type;
|
||||
{
|
||||
tree t = build (CALL_EXPR, TREE_TYPE (tinfo_fn_type),
|
||||
default_conversion (get_tinfo_fn (type)), NULL_TREE, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (t) = 1;
|
||||
tree t = build_call
|
||||
(get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
|
||||
return convert_from_reference (t);
|
||||
}
|
||||
|
||||
|
@ -296,37 +376,6 @@ get_typeid (type)
|
|||
return get_typeid_1 (type);
|
||||
}
|
||||
|
||||
/* Get a bad_cast node for the program to throw...
|
||||
|
||||
See libstdc++/exception.cc for __throw_bad_cast */
|
||||
|
||||
static tree
|
||||
throw_bad_cast ()
|
||||
{
|
||||
tree d = get_identifier ("__throw_bad_cast");
|
||||
tree type;
|
||||
|
||||
if (IDENTIFIER_GLOBAL_VALUE (d))
|
||||
return IDENTIFIER_GLOBAL_VALUE (d);
|
||||
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
|
||||
type = build_function_type (void_type_node, void_list_node);
|
||||
d = build_lang_decl (FUNCTION_DECL, d, type);
|
||||
DECL_EXTERNAL (d) = 1;
|
||||
TREE_PUBLIC (d) = 1;
|
||||
DECL_ARTIFICIAL (d) = 1;
|
||||
pushdecl_top_level (d);
|
||||
make_function_rtl (d);
|
||||
assemble_external (d);
|
||||
|
||||
pop_obstacks ();
|
||||
|
||||
d = build (CALL_EXPR, void_type_node, default_conversion (d), NULL_TREE, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (d) = 1;
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Check whether TEST is null before returning RESULT. If TEST is used in
|
||||
RESULT, it must have previously had a save_expr applied to it. */
|
||||
|
||||
|
@ -355,7 +404,7 @@ build_dynamic_cast (type, expr)
|
|||
if (type == error_mark_node || expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
tree t = build_min (DYNAMIC_CAST_EXPR, type, expr);
|
||||
return t;
|
||||
|
@ -497,19 +546,22 @@ build_dynamic_cast (type, expr)
|
|||
expr2 = build_headof (expr1);
|
||||
|
||||
if (ec == POINTER_TYPE)
|
||||
td1 = build_typeid (build_indirect_ref (expr, NULL_PTR));
|
||||
td1 = get_tinfo_fn_dynamic (build_indirect_ref (expr, NULL_PTR));
|
||||
else
|
||||
td1 = build_typeid (expr);
|
||||
td1 = get_tinfo_fn_dynamic (expr);
|
||||
td1 = decay_conversion (td1);
|
||||
|
||||
td2 = get_typeid (TREE_TYPE (type));
|
||||
td3 = get_typeid (TREE_TYPE (exprtype));
|
||||
td2 = decay_conversion
|
||||
(get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type))));
|
||||
td3 = decay_conversion
|
||||
(get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype))));
|
||||
|
||||
elems = tree_cons
|
||||
(NULL_TREE, TREE_OPERAND (td1, 0), tree_cons
|
||||
(NULL_TREE, TREE_OPERAND (td2, 0), tree_cons
|
||||
(NULL_TREE, td1, tree_cons
|
||||
(NULL_TREE, td2, tree_cons
|
||||
(NULL_TREE, build_int_2 (1, 0), tree_cons
|
||||
(NULL_TREE, expr2, tree_cons
|
||||
(NULL_TREE, TREE_OPERAND (td3, 0), tree_cons
|
||||
(NULL_TREE, td3, tree_cons
|
||||
(NULL_TREE, expr1, NULL_TREE))))));
|
||||
|
||||
dcast_fn = get_identifier ("__dynamic_cast");
|
||||
|
@ -520,14 +572,12 @@ build_dynamic_cast (type, expr)
|
|||
tree tmp;
|
||||
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
tmp = build_reference_type
|
||||
(build_type_variant (type_info_type_node, 1, 0));
|
||||
tmp = tree_cons
|
||||
(NULL_TREE, tmp, tree_cons
|
||||
(NULL_TREE, tmp, tree_cons
|
||||
(NULL_TREE, TREE_TYPE (td1), tree_cons
|
||||
(NULL_TREE, TREE_TYPE (td1), tree_cons
|
||||
(NULL_TREE, integer_type_node, tree_cons
|
||||
(NULL_TREE, ptr_type_node, tree_cons
|
||||
(NULL_TREE, tmp, tree_cons
|
||||
(NULL_TREE, TREE_TYPE (td1), tree_cons
|
||||
(NULL_TREE, ptr_type_node, void_list_node))))));
|
||||
tmp = build_function_type (ptr_type_node, tmp);
|
||||
dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
|
||||
|
@ -540,15 +590,16 @@ build_dynamic_cast (type, expr)
|
|||
pop_obstacks ();
|
||||
}
|
||||
|
||||
result = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (dcast_fn)),
|
||||
decay_conversion (dcast_fn), elems, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (result) = 1;
|
||||
result = build_call
|
||||
(dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
|
||||
|
||||
if (tc == REFERENCE_TYPE)
|
||||
{
|
||||
expr1 = throw_bad_cast ();
|
||||
expr1 = build_compound_expr (tree_cons (NULL_TREE, expr1,
|
||||
build_tree_list (NULL_TREE, convert (type, integer_zero_node))));
|
||||
expr1 = build_compound_expr
|
||||
(tree_cons (NULL_TREE, expr1,
|
||||
build_tree_list (NULL_TREE, convert
|
||||
(type, integer_zero_node))));
|
||||
TREE_TYPE (expr1) = type;
|
||||
result = save_expr (result);
|
||||
return build (COND_EXPR, type, result, result, expr1);
|
||||
|
@ -625,9 +676,7 @@ expand_si_desc (tdecl, type)
|
|||
pop_obstacks ();
|
||||
}
|
||||
|
||||
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
|
||||
decay_conversion (fn), elems, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (fn) = 1;
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
expand_expr_stmt (fn);
|
||||
}
|
||||
|
||||
|
@ -668,7 +717,7 @@ expand_class_desc (tdecl, type)
|
|||
(FIELD_DECL, NULL_TREE,
|
||||
build_pointer_type (build_type_variant (type_info_type_node, 1, 0)));
|
||||
fields [1] = build_lang_field_decl
|
||||
(FIELD_DECL, NULL_TREE, sizetype);
|
||||
(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
|
||||
DECL_BIT_FIELD (fields[1]) = 1;
|
||||
DECL_FIELD_SIZE (fields[1]) = 29;
|
||||
|
||||
|
@ -805,9 +854,7 @@ expand_class_desc (tdecl, type)
|
|||
pop_obstacks ();
|
||||
}
|
||||
|
||||
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
|
||||
decay_conversion (fn), elems, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (fn) = 1;
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
expand_expr_stmt (fn);
|
||||
}
|
||||
|
||||
|
@ -854,9 +901,7 @@ expand_ptr_desc (tdecl, type)
|
|||
pop_obstacks ();
|
||||
}
|
||||
|
||||
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
|
||||
decay_conversion (fn), elems, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (fn) = 1;
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
expand_expr_stmt (fn);
|
||||
}
|
||||
|
||||
|
@ -905,9 +950,7 @@ expand_attr_desc (tdecl, type)
|
|||
pop_obstacks ();
|
||||
}
|
||||
|
||||
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
|
||||
decay_conversion (fn), elems, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (fn) = 1;
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
expand_expr_stmt (fn);
|
||||
}
|
||||
|
||||
|
@ -947,9 +990,7 @@ expand_generic_desc (tdecl, type, fnname)
|
|||
pop_obstacks ();
|
||||
}
|
||||
|
||||
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
|
||||
decay_conversion (fn), elems, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (fn) = 1;
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
expand_expr_stmt (fn);
|
||||
}
|
||||
|
||||
|
@ -994,10 +1035,12 @@ synthesize_tinfo_fn (fndecl)
|
|||
tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node, 1);
|
||||
expand_start_cond (tmp, 0);
|
||||
|
||||
if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
|
||||
expand_attr_desc (tdecl, type);
|
||||
if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
expand_generic_desc (tdecl, type, "__rtti_func");
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
expand_generic_desc (tdecl, type, "__rtti_array");
|
||||
else if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
|
||||
expand_attr_desc (tdecl, type);
|
||||
else if (TREE_CODE (type) == POINTER_TYPE)
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
|
||||
|
@ -1022,8 +1065,6 @@ synthesize_tinfo_fn (fndecl)
|
|||
}
|
||||
else if (TREE_CODE (type) == ENUMERAL_TYPE)
|
||||
expand_generic_desc (tdecl, type, "__rtti_user");
|
||||
else if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
expand_generic_desc (tdecl, type, "__rtti_func");
|
||||
else
|
||||
my_friendly_abort (252);
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
|
||||
// Copyright (C) 1994, 1996 Free Software Foundation
|
||||
|
||||
// This file is part of GNU CC.
|
||||
|
||||
// GNU CC is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// GNU CC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with GNU CC; see the file COPYING. If not, write to
|
||||
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
|
||||
// As a special exception, if you link this library with other files,
|
||||
// some of which are compiled with GCC, to produce an executable,
|
||||
// this library does not by itself cause the resulting executable
|
||||
// to be covered by the GNU General Public License.
|
||||
// This exception does not however invalidate any other reasons why
|
||||
// the executable file might be covered by the GNU General Public License.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "tinfo.h"
|
||||
#include "new" // for placement new
|
||||
|
||||
// This file contains the minimal working set necessary to link with code
|
||||
// that uses virtual functions and -frtti but does not actually use RTTI
|
||||
// functionality.
|
||||
|
||||
type_info::
|
||||
~type_info ()
|
||||
{ }
|
||||
|
||||
extern "C" void
|
||||
__rtti_class (void *addr, const char *name,
|
||||
const __class_type_info::base_info *bl, size_t bn)
|
||||
{ new (addr) __class_type_info (name, bl, bn); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_si (void *addr, const char *n, const type_info *ti)
|
||||
{
|
||||
new (addr) __si_type_info
|
||||
(n, static_cast <const __user_type_info &> (*ti));
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__rtti_user (void *addr, const char *name)
|
||||
{ new (addr) __user_type_info (name); }
|
||||
|
||||
// dynamic_cast helper methods.
|
||||
// Returns a pointer to the desired sub-object or 0.
|
||||
|
||||
void * __user_type_info::
|
||||
dcast (const type_info& to, int, void *addr, const type_info *, void *) const
|
||||
{ return (*this == to) ? addr : 0; }
|
||||
|
||||
void * __si_type_info::
|
||||
dcast (const type_info& to, int require_public, void *addr,
|
||||
const type_info *sub, void *subptr) const
|
||||
{
|
||||
if (*this == to)
|
||||
return addr;
|
||||
return base.dcast (to, require_public, addr, sub, subptr);
|
||||
}
|
||||
|
||||
void* __class_type_info::
|
||||
dcast (const type_info& desired, int is_public, void *objptr,
|
||||
const type_info *sub, void *subptr) const
|
||||
{
|
||||
if (*this == desired)
|
||||
return objptr;
|
||||
|
||||
void *match_found = 0;
|
||||
for (int i = 0; i < n_bases; i++)
|
||||
{
|
||||
if (is_public && base_list[i].access != PUBLIC)
|
||||
continue;
|
||||
|
||||
void *p = (char *)objptr + base_list[i].offset;
|
||||
if (base_list[i].is_virtual)
|
||||
p = *(void **)p;
|
||||
p = base_list[i].base->dcast (desired, is_public, p, sub, subptr);
|
||||
if (p)
|
||||
{
|
||||
if (match_found == 0)
|
||||
match_found = p;
|
||||
else if (match_found != p)
|
||||
{
|
||||
if (sub)
|
||||
{
|
||||
// Perhaps we're downcasting from *sub to desired; see if
|
||||
// subptr is a subobject of exactly one of {match_found,p}.
|
||||
|
||||
const __user_type_info &d =
|
||||
static_cast <const __user_type_info &> (desired);
|
||||
|
||||
void *os = d.dcast (*sub, 1, match_found);
|
||||
void *ns = d.dcast (*sub, 1, p);
|
||||
|
||||
if (os == ns)
|
||||
/* ambiguous -- subptr is a virtual base */;
|
||||
else if (os == subptr)
|
||||
continue;
|
||||
else if (ns == subptr)
|
||||
{
|
||||
match_found = p;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// base found at two different pointers,
|
||||
// conversion is not unique
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return match_found;
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
|
||||
// Copyright (C) 1994, 1996 Free Software Foundation
|
||||
|
||||
// This file is part of GNU CC.
|
||||
|
||||
// GNU CC is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// GNU CC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with GNU CC; see the file COPYING. If not, write to
|
||||
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
|
||||
// As a special exception, if you link this library with other files,
|
||||
// some of which are compiled with GCC, to produce an executable,
|
||||
// this library does not by itself cause the resulting executable
|
||||
// to be covered by the GNU General Public License.
|
||||
// This exception does not however invalidate any other reasons why
|
||||
// the executable file might be covered by the GNU General Public License.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "tinfo.h"
|
||||
#include "new" // for placement new
|
||||
|
||||
// service function for comparing types by name.
|
||||
|
||||
static inline int
|
||||
fast_compare (const char *n1, const char *n2) {
|
||||
int c;
|
||||
if (n1 == n2) return 0;
|
||||
if (n1 == 0) return *n2;
|
||||
else if (n2 == 0) return *n1;
|
||||
|
||||
c = (int)*n1++ - (int)*n2++;
|
||||
return c == 0 ? strcmp (n1, n2) : c;
|
||||
};
|
||||
|
||||
bool
|
||||
type_info::before (const type_info &arg)
|
||||
{
|
||||
return fast_compare (name (), arg.name ()) < 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
bool type_info::
|
||||
operator== (const type_info& arg) const
|
||||
{
|
||||
return fast_compare (name (), arg.name ()) == 0;
|
||||
}
|
||||
|
||||
bool type_info::
|
||||
operator!= (const type_info& arg) const
|
||||
{
|
||||
return fast_compare (name (), arg.name ()) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// type info for pointer type.
|
||||
|
||||
struct __pointer_type_info : public type_info {
|
||||
const type_info& type;
|
||||
|
||||
__pointer_type_info (const char *n, const type_info& ti)
|
||||
: type_info (n), type (ti) {}
|
||||
};
|
||||
|
||||
// type info for attributes
|
||||
|
||||
struct __attr_type_info : public type_info {
|
||||
enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 };
|
||||
|
||||
const type_info& type;
|
||||
cv attr;
|
||||
|
||||
__attr_type_info (const char *n, cv a, const type_info& t)
|
||||
: type_info (n), type (t), attr (a) {}
|
||||
};
|
||||
|
||||
// type_info for builtin type
|
||||
|
||||
struct __builtin_type_info : public type_info {
|
||||
__builtin_type_info (const char *n): type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for function.
|
||||
|
||||
struct __func_type_info : public type_info {
|
||||
__func_type_info (const char *n) : type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for pointer to member function.
|
||||
|
||||
struct __ptmf_type_info : public type_info {
|
||||
__ptmf_type_info (const char *n) : type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for pointer to data member.
|
||||
|
||||
struct __ptmd_type_info : public type_info {
|
||||
__ptmd_type_info (const char *n): type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for array.
|
||||
|
||||
struct __array_type_info : public type_info {
|
||||
__array_type_info (const char *n): type_info (n) {}
|
||||
};
|
||||
|
||||
// Entry points for the compiler.
|
||||
|
||||
/* Low level match routine used by compiler to match types of catch
|
||||
variables and thrown objects. */
|
||||
|
||||
extern "C" void*
|
||||
__throw_type_match_rtti (void *catch_type_r, void *throw_type_r, void *objptr)
|
||||
{
|
||||
const type_info &catch_type = *(const type_info *)catch_type_r;
|
||||
const type_info &throw_type = *(const type_info *)throw_type_r;
|
||||
|
||||
if (catch_type == throw_type)
|
||||
return objptr;
|
||||
|
||||
#if 0
|
||||
printf ("We want to match a %s against a %s!\n",
|
||||
throw_type.name (), catch_type.name ());
|
||||
#endif
|
||||
|
||||
void *new_objptr = 0;
|
||||
|
||||
if (const __user_type_info *p
|
||||
= dynamic_cast <const __user_type_info *> (&throw_type))
|
||||
{
|
||||
/* The 1 skips conversions to private bases. */
|
||||
new_objptr = p->dcast (catch_type, 1, objptr);
|
||||
}
|
||||
else if (const __pointer_type_info *fr =
|
||||
dynamic_cast <const __pointer_type_info *> (&throw_type))
|
||||
{
|
||||
const __pointer_type_info *to =
|
||||
dynamic_cast <const __pointer_type_info *> (&catch_type);
|
||||
|
||||
if (! to)
|
||||
goto fail;
|
||||
|
||||
const type_info *subfr = &fr->type, *subto = &to->type;
|
||||
__attr_type_info::cv cvfrom, cvto;
|
||||
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subfr))
|
||||
{
|
||||
cvfrom = at->attr;
|
||||
subfr = &at->type;
|
||||
}
|
||||
else
|
||||
cvfrom = __attr_type_info::NONE;
|
||||
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subto))
|
||||
{
|
||||
cvto = at->attr;
|
||||
subto = &at->type;
|
||||
}
|
||||
else
|
||||
cvto = __attr_type_info::NONE;
|
||||
|
||||
if (((cvfrom & __attr_type_info::CONST)
|
||||
> (cvto & __attr_type_info::CONST))
|
||||
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||
> (cvto & __attr_type_info::VOLATILE)))
|
||||
goto fail;
|
||||
|
||||
if (*subto == *subfr)
|
||||
new_objptr = objptr;
|
||||
else if (*subto == typeid (void)
|
||||
&& dynamic_cast <const __func_type_info *> (subfr) == 0)
|
||||
new_objptr = objptr;
|
||||
else if (const __user_type_info *p
|
||||
= dynamic_cast <const __user_type_info *> (subfr))
|
||||
{
|
||||
/* The 1 skips conversions to private bases. */
|
||||
new_objptr = p->dcast (*subto, 1, objptr);
|
||||
}
|
||||
else if (const __pointer_type_info *pfr
|
||||
= dynamic_cast <const __pointer_type_info *> (subfr))
|
||||
{
|
||||
// Multi-level pointer conversion.
|
||||
|
||||
const __pointer_type_info *pto
|
||||
= dynamic_cast <const __pointer_type_info *> (subto);
|
||||
|
||||
if (! pto)
|
||||
goto fail;
|
||||
|
||||
bool constp = (cvto & __attr_type_info::CONST);
|
||||
for (subto = &pto->type, subfr = &pfr->type; ;
|
||||
subto = &pto->type, subfr = &pfr->type)
|
||||
{
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subfr))
|
||||
{
|
||||
cvfrom = at->attr;
|
||||
subfr = &at->type;
|
||||
}
|
||||
else
|
||||
cvfrom = __attr_type_info::NONE;
|
||||
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subto))
|
||||
{
|
||||
cvto = at->attr;
|
||||
subto = &at->type;
|
||||
}
|
||||
else
|
||||
cvto = __attr_type_info::NONE;
|
||||
|
||||
if (((cvfrom & __attr_type_info::CONST)
|
||||
> (cvto & __attr_type_info::CONST))
|
||||
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||
> (cvto & __attr_type_info::VOLATILE)))
|
||||
goto fail;
|
||||
|
||||
if (! constp
|
||||
&& (((cvfrom & __attr_type_info::CONST)
|
||||
< (cvto & __attr_type_info::CONST))
|
||||
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||
< (cvto & __attr_type_info::VOLATILE))))
|
||||
goto fail;
|
||||
|
||||
if (*subto == *subfr)
|
||||
{
|
||||
new_objptr = objptr;
|
||||
break;
|
||||
}
|
||||
|
||||
pto = dynamic_cast <const __pointer_type_info *> (subto);
|
||||
pfr = dynamic_cast <const __pointer_type_info *> (subfr);
|
||||
if (! pto || ! pfr)
|
||||
goto fail;
|
||||
|
||||
if (! (cvto & __attr_type_info::CONST))
|
||||
constp = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
fail:
|
||||
|
||||
#if 0
|
||||
if (new_objptr)
|
||||
printf ("It converts, delta is %d\n", new_objptr-objptr);
|
||||
#endif
|
||||
return new_objptr;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__rtti_ptr (void *addr, const char *n, const type_info *ti)
|
||||
{ new (addr) __pointer_type_info (n, *ti); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti)
|
||||
{
|
||||
new (addr) __attr_type_info
|
||||
(n, static_cast <__attr_type_info::cv> (attrval), *ti);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__rtti_func (void *addr, const char *name)
|
||||
{ new (addr) __func_type_info (name); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_ptmf (void *addr, const char *name)
|
||||
{ new (addr) __ptmf_type_info (name); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_ptmd (void *addr, const char *name)
|
||||
{ new (addr) __ptmd_type_info (name); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_array (void *addr, const char *name)
|
||||
{ new (addr) __array_type_info (name); }
|
||||
|
||||
extern "C" void *
|
||||
__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
|
||||
int require_public, void *address,
|
||||
const type_info & (*sub)(void), void *subptr)
|
||||
{
|
||||
return static_cast <const __user_type_info &> (from ()).dcast
|
||||
(to (), require_public, address, &(sub ()), subptr);
|
||||
}
|
||||
|
||||
// type_info nodes and functions for the builtin types. The mangling here
|
||||
// must match the mangling in gcc/cp/rtti.c.
|
||||
|
||||
#define BUILTIN(mangled) \
|
||||
unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
|
||||
__attribute__ ((aligned (__alignof__ (void *)))); \
|
||||
extern "C" const type_info &__tf##mangled (void) { \
|
||||
if ((*(void **) __ti##mangled) == 0) \
|
||||
new (__ti##mangled) __builtin_type_info (#mangled); \
|
||||
return *(type_info *)__ti##mangled; \
|
||||
}
|
||||
|
||||
BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b);
|
||||
BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
|
||||
BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);
|
|
@ -356,6 +356,7 @@ break_out_calls (exp)
|
|||
extern struct obstack *current_obstack;
|
||||
extern struct obstack permanent_obstack, class_obstack;
|
||||
extern struct obstack *saveable_obstack;
|
||||
extern struct obstack *expression_obstack;
|
||||
|
||||
/* Here is how primitive or already-canonicalized types' hash
|
||||
codes are made. MUST BE CONSISTENT WITH tree.c !!! */
|
||||
|
@ -421,7 +422,7 @@ build_cplus_array_type_1 (elt_type, index_type)
|
|||
saveable_obstack = &permanent_obstack;
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
t = make_node (ARRAY_TYPE);
|
||||
TREE_TYPE (t) = elt_type;
|
||||
|
@ -1615,7 +1616,7 @@ mapcar (t, func)
|
|||
mapcar (TYPE_ARG_TYPES (t), func));
|
||||
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
|
||||
case ARRAY_TYPE:
|
||||
tmp = build_array_type (mapcar (TREE_TYPE (t), func),
|
||||
tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func),
|
||||
mapcar (TYPE_DOMAIN (t), func));
|
||||
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
|
||||
case INTEGER_TYPE:
|
||||
|
@ -1632,6 +1633,11 @@ mapcar (t, func)
|
|||
mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
|
||||
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
|
||||
|
||||
case CONSTRUCTOR:
|
||||
t = copy_node (t);
|
||||
CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
|
||||
return t;
|
||||
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_PTRMEMFUNC_P (t))
|
||||
return build_ptrmemfunc_type
|
||||
|
@ -1673,20 +1679,20 @@ copy_to_permanent (t)
|
|||
{
|
||||
register struct obstack *ambient_obstack = current_obstack;
|
||||
register struct obstack *ambient_saveable_obstack = saveable_obstack;
|
||||
int resume;
|
||||
register struct obstack *ambient_expression_obstack = expression_obstack;
|
||||
|
||||
if (t == NULL_TREE || TREE_PERMANENT (t))
|
||||
return t;
|
||||
|
||||
saveable_obstack = &permanent_obstack;
|
||||
current_obstack = saveable_obstack;
|
||||
resume = suspend_momentary ();
|
||||
expression_obstack = saveable_obstack;
|
||||
|
||||
t = mapcar (t, perm_manip);
|
||||
|
||||
resume_momentary (resume);
|
||||
current_obstack = ambient_obstack;
|
||||
saveable_obstack = ambient_saveable_obstack;
|
||||
expression_obstack = ambient_expression_obstack;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ require_complete_type (value)
|
|||
{
|
||||
tree type;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return value;
|
||||
|
||||
type = TREE_TYPE (value);
|
||||
|
@ -132,8 +132,7 @@ complete_type (type)
|
|||
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
|
||||
{
|
||||
tree t = complete_type (TREE_TYPE (type));
|
||||
if (TYPE_SIZE (t) != NULL_TREE
|
||||
&& current_template_parms == NULL_TREE)
|
||||
if (TYPE_SIZE (t) != NULL_TREE && ! processing_template_decl)
|
||||
layout_type (type);
|
||||
TYPE_NEEDS_CONSTRUCTING (type)
|
||||
= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
|
||||
|
@ -1275,7 +1274,7 @@ c_sizeof (type)
|
|||
enum tree_code code = TREE_CODE (type);
|
||||
tree t;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min (SIZEOF_EXPR, sizetype, type);
|
||||
|
||||
if (code == FUNCTION_TYPE)
|
||||
|
@ -1341,7 +1340,7 @@ tree
|
|||
expr_sizeof (e)
|
||||
tree e;
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min (SIZEOF_EXPR, sizetype, e);
|
||||
|
||||
if (TREE_CODE (e) == COMPONENT_REF
|
||||
|
@ -1623,7 +1622,7 @@ build_object_ref (datum, basetype, field)
|
|||
{
|
||||
tree binfo = binfo_or_else (basetype, dtype);
|
||||
if (binfo)
|
||||
return build_component_ref (build_scoped_ref (datum, basetype),
|
||||
return build_x_component_ref (build_scoped_ref (datum, basetype),
|
||||
field, binfo, 1);
|
||||
}
|
||||
return error_mark_node;
|
||||
|
@ -1709,7 +1708,7 @@ build_component_ref (datum, component, basetype_path, protect)
|
|||
register tree field = NULL;
|
||||
register tree ref;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (COMPONENT_REF, datum, component);
|
||||
|
||||
/* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference
|
||||
|
@ -1937,6 +1936,22 @@ build_component_ref (datum, component, basetype_path, protect)
|
|||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* Variant of build_component_ref for use in expressions, which should
|
||||
never have REFERENCE_TYPE. */
|
||||
|
||||
tree
|
||||
build_x_component_ref (datum, component, basetype_path, protect)
|
||||
tree datum, component, basetype_path;
|
||||
int protect;
|
||||
{
|
||||
tree t = build_component_ref (datum, component, basetype_path, protect);
|
||||
|
||||
if (! processing_template_decl)
|
||||
t = convert_from_reference (t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Given an expression PTR for a pointer, return an expression
|
||||
for the value pointed to.
|
||||
|
@ -1952,7 +1967,7 @@ build_x_indirect_ref (ptr, errorstring)
|
|||
{
|
||||
tree rval;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (INDIRECT_REF, ptr);
|
||||
|
||||
rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE, NULL_TREE);
|
||||
|
@ -2213,7 +2228,7 @@ build_x_function_call (function, params, decl)
|
|||
if (function == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (CALL_EXPR, function, params, NULL_TREE);
|
||||
|
||||
type = TREE_TYPE (function);
|
||||
|
@ -2908,7 +2923,7 @@ build_x_binary_op (code, arg1, arg2)
|
|||
{
|
||||
tree rval;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (code, arg1, arg2);
|
||||
|
||||
if (flag_ansi_overloading)
|
||||
|
@ -3958,7 +3973,7 @@ build_x_unary_op (code, xarg)
|
|||
enum tree_code code;
|
||||
tree xarg;
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (code, xarg, NULL_TREE);
|
||||
|
||||
/* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
|
||||
|
@ -4005,7 +4020,7 @@ condition_conversion (expr)
|
|||
tree expr;
|
||||
{
|
||||
tree t;
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return expr;
|
||||
t = convert (boolean_type_node, expr);
|
||||
t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
|
||||
|
@ -4653,7 +4668,7 @@ build_x_conditional_expr (ifexp, op1, op2)
|
|||
{
|
||||
tree rval = NULL_TREE;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (COND_EXPR, ifexp, op1, op2);
|
||||
|
||||
if (flag_ansi_overloading)
|
||||
|
@ -4988,7 +5003,7 @@ build_x_compound_expr (list)
|
|||
tree rest = TREE_CHAIN (list);
|
||||
tree result;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (COMPOUND_EXPR, list, NULL_TREE);
|
||||
|
||||
if (rest == NULL_TREE)
|
||||
|
@ -5068,7 +5083,7 @@ build_static_cast (type, expr)
|
|||
if (TREE_CODE (expr) == OFFSET_REF)
|
||||
expr = resolve_offset_ref (expr);
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
tree t = build_min (STATIC_CAST_EXPR, type, expr);
|
||||
return t;
|
||||
|
@ -5160,7 +5175,7 @@ build_reinterpret_cast (type, expr)
|
|||
if (TREE_CODE (expr) == OFFSET_REF)
|
||||
expr = resolve_offset_ref (expr);
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
|
||||
return t;
|
||||
|
@ -5252,7 +5267,7 @@ build_const_cast (type, expr)
|
|||
if (TREE_CODE (expr) == OFFSET_REF)
|
||||
expr = resolve_offset_ref (expr);
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
tree t = build_min (CONST_CAST_EXPR, type, expr);
|
||||
return t;
|
||||
|
@ -5361,7 +5376,7 @@ build_c_cast (type, expr, allow_nonconverting)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
tree t = build_min (CAST_EXPR, type,
|
||||
min_tree_cons (NULL_TREE, value, NULL_TREE));
|
||||
|
@ -5993,7 +6008,7 @@ build_x_modify_expr (lhs, modifycode, rhs)
|
|||
enum tree_code modifycode;
|
||||
tree rhs;
|
||||
{
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (MODOP_EXPR, lhs,
|
||||
build_min_nt (modifycode, NULL_TREE, NULL_TREE), rhs);
|
||||
|
||||
|
@ -7022,7 +7037,7 @@ c_expand_return (retval)
|
|||
return;
|
||||
}
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
{
|
||||
add_tree (build_min_nt (RETURN_STMT, retval));
|
||||
return;
|
||||
|
|
|
@ -607,6 +607,10 @@ store_init_value (decl, init)
|
|||
}
|
||||
}
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (type) && TREE_CODE (init) == CONSTRUCTOR
|
||||
&& TREE_TYPE (init) == NULL_TREE)
|
||||
cp_pedwarn ("initializer list for `%T'", type);
|
||||
|
||||
/* End of special C++ code. */
|
||||
|
||||
/* Digest the specified initializer into an expression. */
|
||||
|
@ -1011,9 +1015,6 @@ process_init_constructor (type, init, elts)
|
|||
sorry ("initializer list for object using virtual functions");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
cp_pedwarn ("initializer list for `%T'", type);
|
||||
}
|
||||
|
||||
for (field = TYPE_FIELDS (type); field && tail;
|
||||
|
@ -1262,7 +1263,7 @@ build_x_arrow (datum)
|
|||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (ARROW_EXPR, rval);
|
||||
|
||||
if (TREE_CODE (rval) == OFFSET_REF)
|
||||
|
@ -1338,7 +1339,7 @@ build_m_component_ref (datum, component)
|
|||
tree rettype;
|
||||
tree binfo;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (DOTSTAR_EXPR, datum, component);
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
|
||||
|
@ -1423,7 +1424,7 @@ build_functional_cast (exp, parms)
|
|||
else
|
||||
type = exp;
|
||||
|
||||
if (current_template_parms)
|
||||
if (processing_template_decl)
|
||||
return build_min (CAST_EXPR, type, parms);
|
||||
|
||||
if (IS_SIGNATURE (type))
|
||||
|
|
Loading…
Reference in New Issue