parent
5345f91a0b
commit
a0a339271a
297
gcc/cp/ChangeLog
297
gcc/cp/ChangeLog
|
@ -1,3 +1,289 @@
|
|||
Fri Jun 3 02:10:56 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* cvt.c (cp_convert): Replace constants with their values before
|
||||
converting.
|
||||
|
||||
Thu Jun 2 03:53:30 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* typeck2.c (build_x_arrow): Resolve OFFSET_REFs first.
|
||||
|
||||
Wed Jun 1 18:57:35 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* typeck2.c (digest_init): Handle initializing a pmf with an
|
||||
overloaded method.
|
||||
* typeck.c (build_ptrmemfunc): Handle overloaded methods.
|
||||
|
||||
* decl.c (pushtag): Use build_decl to make TYPE_DECLs.
|
||||
(xref_defn_tag): Ditto.
|
||||
* pt.c (process_template_parm): Ditto.
|
||||
(lookup_template_class): Ditto.
|
||||
(push_template_decls): Ditto.
|
||||
(instantiate_class_template): Ditto.
|
||||
(create_nested_upt): Ditto.
|
||||
* class.c (finish_struct): Don't try to set DECL_CLASS_CONTEXT on
|
||||
TYPE_DECLs.
|
||||
|
||||
* typeck.c (convert_arguments): Make sure type is not NULL before
|
||||
checking its TREE_CODE.
|
||||
|
||||
Wed Jun 1 17:40:39 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* class.c (get_derived_offset): New routine.
|
||||
* class.c (finish_base_struct): Make sure we set BINFO_VTABLE and
|
||||
BINFO_VIRTUALS when we choose a new base class to inherit from.
|
||||
* class.c (modify_one_vtable): Use get_derived_offset to get the
|
||||
offset to the most base class subobject that we derived this binfo
|
||||
from.
|
||||
* class.c (finish_struct): Move code to calculate the
|
||||
DECL_FIELD_BITPOS of the vfield up, as we need might need it for
|
||||
new calls to get_derived_offset in modify_one_vtable.
|
||||
|
||||
Wed Jun 1 16:50:59 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* init.c (build_member_call): Use build_pointer_type instead of
|
||||
TYPE_POINTER_TO.
|
||||
|
||||
Wed Jun 1 11:11:15 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
|
||||
|
||||
* decl.c (grokdeclarator): Make sure we have a DNAME set before we
|
||||
try to use it in an error.
|
||||
|
||||
Wed Jun 1 09:48:49 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* typeck.c (convert_arguments, convert_for_initialization): Don't
|
||||
strip NOP_EXPRs, when we are converting to a reference.
|
||||
|
||||
Wed Jun 1 01:11:38 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* typeck.c (build_modify_expr): Don't dereference references when
|
||||
initializing them.
|
||||
|
||||
* decl2.c (grokfield): Don't check for grokdeclarator returning
|
||||
error_mark_node any more.
|
||||
|
||||
* decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node.
|
||||
(start_method): Return void_type_node instead of error_mark_node.
|
||||
|
||||
* typeck.c (build_modify_expr): Resolve offset refs earlier.
|
||||
|
||||
Tue May 31 16:06:58 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* call.c (build_method_call): Resolve OFFSET_REFs in the object.
|
||||
|
||||
* typeck.c (build_modify_expr): Dereference references before trying
|
||||
to assign to them.
|
||||
|
||||
* call.c (build_method_call): Don't confuse type conversion
|
||||
operators with constructors.
|
||||
* typeck2.c (build_functional_cast): Just call build_c_cast if there
|
||||
was only one parameter.
|
||||
* method.c (build_typename_overload): Don't set
|
||||
IDENTIFIER_GLOBAL_VALUE on these identifiers.
|
||||
* decl.c (grok_op_properties): Warn about defining a type conversion
|
||||
operator that converts to a base class (or reference to it).
|
||||
* cvt.c (cp_convert): Don't try to use a type conversion operator
|
||||
when converting to a base class.
|
||||
(build_type_conversion_1): Don't call constructor_name_full on an
|
||||
identifier.
|
||||
* cp-tree.h (DERIVED_FROM_P): Should be self-explanatory.
|
||||
|
||||
* decl.c (start_decl): Don't complain that error_mark_node is an
|
||||
incomplete type.
|
||||
(finish_decl): Check for type == error_mark_node.
|
||||
|
||||
Mon May 30 23:38:55 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (start_function): Set DECL_DEFER_OUTPUT on implicit
|
||||
instantiations and inline members.
|
||||
|
||||
* spew.c (yylex): Set looking_for_template if the next token is a '<'.
|
||||
|
||||
* lex.h: Declare looking_for_template.
|
||||
|
||||
* decl.c (lookup_name_real): Use looking_for_template to arbitrate
|
||||
between type and template interpretations of an identifier.
|
||||
|
||||
Sat May 28 04:07:40 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* pt.c (instantiate_template): Zero out p if we found a
|
||||
specialization.
|
||||
|
||||
* decl.c (grokdeclarator): Elucidate warning.
|
||||
(grokdeclarator): If pedantic AND -ansi, complain about long long.
|
||||
|
||||
Make explicit instantiation work reasonably. It is now appropriate
|
||||
to deprecate the use of -fexternal-templates.
|
||||
* pt.c (instantiate_template): Set DECL_TEMPLATE_SPECIALIZATION or
|
||||
DECL_IMPLICIT_INSTANTIATION on fndecl as appropriate.
|
||||
(end_template_instantiation): Reflect changes in USE_TEMPLATE
|
||||
semantics.
|
||||
(do_pending_expansions): if (!flag_implicit_templates) DECIDE(0);
|
||||
(do_function_instantiation): Don't set EXPLICIT_INST if
|
||||
flag_external_templates is set. Do set TREE_PUBLIC and DECL_EXTERN
|
||||
appropriately otherwise.
|
||||
(do_type_instantiation): Set interface info for class. Set
|
||||
TREE_PUBLIC and DECL_EXTERN for methods. Do none of this if
|
||||
flag_external_templates is set.
|
||||
* parse.y: Reflect changes in USE_TEMPLATE semantics.
|
||||
* decl2.c: New flag flag_implicit_templates determines whether or
|
||||
not implicit instantiations get emitted. This flag currently
|
||||
defaults to true, and must be true for -fexternal-templates to work.
|
||||
(finish_file): Consider flag_implement_inlines when
|
||||
setting DECL_EXTERNAL. Consider flag_implicit_templates when
|
||||
deciding whether or not to emit a static copy.
|
||||
* decl.c (start_function): Set TREE_PUBLIC and DECL_EXTERNAL
|
||||
properly for template instantiations.
|
||||
(start_method): Set DECL_IMPLICIT_INSTANTIATION on methods of a
|
||||
template class.
|
||||
* cp-tree.h (CLASSTYPE_USE_TEMPLATE): Change semantics.
|
||||
(DECL_USE_TEMPLATE): Parallel macro for FUNCTION and VAR_DECLs.
|
||||
(various others): Accessor macros for the above.
|
||||
|
||||
Fri May 27 13:57:40 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* typeck.c (build_binary_op_nodefault): Division by constant zero is
|
||||
an error.
|
||||
|
||||
Fri May 27 13:50:15 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* class.c (override_one_vtable): Don't modify things we don't own.
|
||||
|
||||
Fri May 27 01:42:58 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (finish_decl): Don't postpone processing the initializer of
|
||||
a decl with DECL_EXTERNAL set, and do call rest_of_compilation for a
|
||||
PUBLIC const at toplevel.
|
||||
(grokdeclarator): pedwarn about initializing non-const or
|
||||
non-integral statics in the class body.
|
||||
|
||||
* decl.c (pushtag): Don't try to set DECL_CLASS_CONTEXT on a
|
||||
TYPE_DECL.
|
||||
|
||||
* call.c (convert_harshness): Dereference reference on rhs before
|
||||
proceeding, properly grok passing const things to non-const
|
||||
references.
|
||||
|
||||
* typeck.c (build_unary_op): Soften error about taking the address
|
||||
of main() to a pedwarn.
|
||||
|
||||
* lex.c (default_copy_constructor_body): Unambiguously specify base
|
||||
classes (i.e. A((const class ::A&)_ctor_arg) ).
|
||||
(default_assign_ref_body): Ditto.
|
||||
|
||||
Thu May 26 13:13:55 1994 Gerald Baumgartner (gb@mexican.cygnus.com)
|
||||
|
||||
* decl2.c (grokfield): Don't complain about local signature
|
||||
method declaration without definition.
|
||||
|
||||
* call.c (convert_harshness): If `type' is a signature pointer
|
||||
and `parmtype' is a pointer to a signature, just return 0. We
|
||||
don't really convert in this case; it's a result of making the
|
||||
`this' parameter of a signature method a signature pointer.
|
||||
|
||||
* call.c (build_method_call): Distinguish calling the default copy
|
||||
constructor of a signature pointer/reference from a signature
|
||||
member function call.
|
||||
|
||||
Thu May 26 12:56:25 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl2.c (grokfield): Don't set TREE_PUBLIC on member function
|
||||
declarations.
|
||||
|
||||
* decl.c (duplicate_decls): A previous function declaration as
|
||||
static overrides a subsequent non-static definition.
|
||||
(grokdeclarator): Don't set TREE_PUBLIC on inline method
|
||||
declarations.
|
||||
|
||||
Wed May 25 14:36:38 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (grokdeclarator): Handle initialization of static const
|
||||
members.
|
||||
(finish_decl): Ditto.
|
||||
|
||||
* decl2.c (grokfield): Allow initialization of static const members
|
||||
even when pedantic.
|
||||
|
||||
* decl2.c (grokfield): Deal with grokdeclarator returning
|
||||
error_mark_node.
|
||||
|
||||
* decl.c (grok_ctor_properties): Return 0 for A(A) constructor.
|
||||
(grokfndecl): Check the return value of grok_ctor_properties.
|
||||
(start_method): Ditto.
|
||||
|
||||
* parse.y (absdcl): Expand type_quals inline.
|
||||
|
||||
Tue May 24 19:10:32 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (pushtag): Use IS_AGGR_TYPE rather than checking for a
|
||||
RECORD_TYPE.
|
||||
|
||||
Tue May 24 18:09:16 1994 Per Bothner (bothner@kalessin.cygnus.com)
|
||||
|
||||
* cp-tree.h (VTABLE_NAME_FORMAT): If flag_vtable_thunks,
|
||||
always use "__vt_%s".
|
||||
* decl2.c (finish_vtable_vardecl): Don't consider abstract virtuals
|
||||
when looking for a "sentinal" method (to decide on emitting vtables).
|
||||
* decl2.c (finish_file): Scan all decls for thunks that need
|
||||
to be emitted.
|
||||
* decl2.c (finish_vtable_vardecl): Don't bother calling emit_thunk.
|
||||
* method.c (make_thunk): Use a more meaningful label. If there
|
||||
exists a matching top-level THUNK_DECL re-use it; otherwise
|
||||
create a new THUNK_DECL (and declare it).
|
||||
* method.c (emit_thunk): Make thunk external/public depending
|
||||
on the underlying method.
|
||||
|
||||
Tue May 24 00:22:04 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* pt.c (tsubst): Use lookup_name_nonclass to find guiding decls, not
|
||||
lookup_name.
|
||||
|
||||
* call.c (build_overload_call_real): Don't immediately pick a
|
||||
function which matches perfectly.
|
||||
|
||||
* decl.c (grokdeclarator): Use c_build_type_variant for arrays.
|
||||
(grokdeclarator): Warn about, and throw away, cv-quals attached to a
|
||||
reference (like 'int &const j').
|
||||
|
||||
* typeck.c (convert_arguments): Don't mess with i for methods.
|
||||
* call.c (build_method_call): Pass the function decl to
|
||||
convert_arguments.
|
||||
|
||||
* typeck.c (comp_ptr_ttypes_real): New function. Implements the
|
||||
checking for which multi-level pointer conversions are allowed.
|
||||
(comp_target_types): Call it.
|
||||
(convert_for_assignment): Check const parity on the ultimate target
|
||||
type, too. And make those warnings pedwarns.
|
||||
|
||||
Mon May 23 14:11:24 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* error.c (dump_char): Use TARGET_* for character constants.
|
||||
|
||||
Mon May 23 13:03:03 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
|
||||
|
||||
* tree.c (debug_no_list_hash): Make static.
|
||||
|
||||
* decl.c (decls_match): Say the types don't match if newdecl ends up
|
||||
with a null type, after we've checked if olddecl does.
|
||||
(pushdecl): Check if the decls themselves match before looking for
|
||||
an extern redeclared as static, to avoid inappropriate and incorrect
|
||||
warnings.
|
||||
|
||||
Fri May 20 14:04:34 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (grokdeclarator): Make warning about duplicate short, etc.
|
||||
a pedwarn.
|
||||
|
||||
* typeck.c (build_c_cast): Casting to function or method type is an
|
||||
error.
|
||||
|
||||
* class.c (finish_struct): Make warning for anonymous class with no
|
||||
instances a pedwarn.
|
||||
|
||||
* Makefile.in (stamp-parse): Expect a s/r conflict.
|
||||
|
||||
* typeck.c (build_modify_expr): pedwarn about using a non-lvalue
|
||||
cast as an lvalue.
|
||||
|
||||
Thu May 19 12:08:48 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* cvt.c (type_promotes_to): Make sure bool promotes to int rather
|
||||
|
@ -30,17 +316,6 @@ Wed May 18 14:27:06 1994 Jason Merrill (jason@deneb.cygnus.com)
|
|||
|
||||
* class.c (finish_struct): Allow bool bitfields.
|
||||
|
||||
Wed May 18 14:41:59 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* class.c (finish_base_struct): Make sure we set BINFO_VTABLE and
|
||||
BINFO_VIRTUALS when we choose a new base class to inherit from.
|
||||
* class.c (modify_one_vtable): Use get_vfield_offset to get the
|
||||
offset to the most base class subobject that we derived this binfo
|
||||
from.
|
||||
* class.c (finish_struct): Move code to calculate the
|
||||
DECL_FIELD_BITPOS of the vfield up, as we need might need it for
|
||||
new calls to get_vfield_offset in modify_one_vtable.
|
||||
|
||||
Wed May 18 12:35:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
||||
* Make-lang.in (c++.install-man): Get g++.1 from $(srcdir)/cp.
|
||||
|
|
|
@ -41,6 +41,15 @@ CXX_FLAGS_TO_PASS = \
|
|||
"CXXFLAGS=$(CXXFLAGS)" \
|
||||
"CXX_FOR_TARGET=$(CXX_FOR_TARGET)"
|
||||
|
||||
# Actual names to use when installing a native compiler.
|
||||
CXX_INSTALL_NAME = c++
|
||||
GXX_INSTALL_NAME = g++
|
||||
|
||||
# Actual names to use when installing a cross-compiler.
|
||||
CXX_CROSS_NAME = $(target)-c++
|
||||
GXX_CROSS_NAME = $(target)-g++
|
||||
|
||||
|
||||
# Define the names for selecting c++ in LANGUAGES.
|
||||
# Note that it would be nice to move the dependency on g++
|
||||
# into the C++ rule, but that needs a little bit of work
|
||||
|
@ -90,17 +99,17 @@ c++.install-normal:
|
|||
c++.install-common:
|
||||
-if [ -f cc1plus ] ; then \
|
||||
if [ -f g++-cross ] ; then \
|
||||
rm -f $(bindir)/$(target)-g++; \
|
||||
$(INSTALL_PROGRAM) g++-cross $(bindir)/$(target)-g++; \
|
||||
chmod a+x $(bindir)/$(target)-g++; \
|
||||
rm -f $(bindir)/$(target)-c++; \
|
||||
ln $(bindir)/$(target)-g++ $(bindir)/$(target)-c++; \
|
||||
rm -f $(bindir)/$(GXX_CROSS_NAME); \
|
||||
$(INSTALL_PROGRAM) g++-cross $(bindir)/$(GXX_CROSS_NAME); \
|
||||
chmod a+x $(bindir)/$(GXX_CROSS_NAME); \
|
||||
rm -f $(bindir)/$(CXX_CROSS_NAME); \
|
||||
ln $(bindir)/$(GXX_CROSS_NAME) $(bindir)/$(CXX_CROSS_NAME); \
|
||||
else \
|
||||
rm -f $(bindir)/g++; \
|
||||
$(INSTALL_PROGRAM) g++ $(bindir)/g++; \
|
||||
chmod a+x $(bindir)/g++; \
|
||||
rm -f $(bindir)/c++; \
|
||||
ln $(bindir)/g++ $(bindir)/c++; \
|
||||
rm -f $(bindir)/$(GXX_INSTALL_NAME); \
|
||||
$(INSTALL_PROGRAM) g++ $(bindir)/$(GXX_INSTALL_NAME); \
|
||||
chmod a+x $(bindir)/$(GXX_INSTALL_NAME); \
|
||||
rm -f $(bindir)/$(CXX_INSTALL_NAME); \
|
||||
ln $(bindir)/$(GXX_INSTALL_NAME) $(bindir)/$(CXX_INSTALL_NAME); \
|
||||
fi ; \
|
||||
fi
|
||||
|
||||
|
@ -113,8 +122,10 @@ c++.install-man: $(srcdir)/cp/g++.1
|
|||
else true; fi
|
||||
|
||||
c++.uninstall:
|
||||
-rm -rf $(bindir)/g++ $(bindir)/c++
|
||||
-rm -rf $(bindir)/$(target)-g++ $(bindir)/$(target)-c++
|
||||
-rm -rf $(bindir)/$(CXX_INSTALL_NAME)
|
||||
-rm -rf $(bindir)/$(CXX_CROSS_NAME)
|
||||
-rm -rf $(bindir)/$(GXX_INSTALL_NAME)
|
||||
-rm -rf $(bindir)/$(GXX_CROSS_NAME)
|
||||
-rm -rf $(mandir)/g++$(manext)
|
||||
|
||||
# Clean hooks:
|
||||
|
|
|
@ -193,7 +193,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
|
|||
`echo $(srcdir)/parse.c | sed 's,^\./,,'`
|
||||
|
||||
$(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y
|
||||
@echo expect 33 reduce/reduce conflicts.
|
||||
@echo expect 1 shift/reduce confict and 33 reduce/reduce conflicts.
|
||||
cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
|
||||
cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h
|
||||
|
||||
|
|
339
gcc/cp/call.c
339
gcc/cp/call.c
|
@ -131,6 +131,13 @@ convert_harshness (type, parmtype, parm)
|
|||
if (TYPE_PTRMEMFUNC_P (parmtype))
|
||||
parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
|
||||
|
||||
if (TREE_CODE (parmtype) == REFERENCE_TYPE)
|
||||
{
|
||||
if (parm)
|
||||
parm = convert_from_reference (parm);
|
||||
parmtype = TREE_TYPE (parmtype);
|
||||
}
|
||||
|
||||
codel = TREE_CODE (type);
|
||||
coder = TREE_CODE (parmtype);
|
||||
|
||||
|
@ -474,196 +481,138 @@ convert_harshness (type, parmtype, parm)
|
|||
}
|
||||
}
|
||||
|
||||
/* C++: one of the types must be a reference type. */
|
||||
{
|
||||
tree ttl, ttr;
|
||||
register tree intype = TYPE_MAIN_VARIANT (parmtype);
|
||||
register enum tree_code form = TREE_CODE (intype);
|
||||
int penalty = 0;
|
||||
/* C++: Since the `this' parameter of a signature member function
|
||||
is represented as a signature pointer to handle default implementations
|
||||
correctly, we can have the case that `type' is a signature pointer
|
||||
while `parmtype' is a pointer to a signature table. We don't really
|
||||
do any conversions in this case, so just return 0. */
|
||||
|
||||
if (codel == REFERENCE_TYPE || coder == REFERENCE_TYPE)
|
||||
{
|
||||
ttl = TYPE_MAIN_VARIANT (type);
|
||||
if (codel == RECORD_TYPE && coder == POINTER_TYPE
|
||||
&& IS_SIGNATURE_POINTER (type) && IS_SIGNATURE (TREE_TYPE (parmtype)))
|
||||
return ZERO_RETURN (h);
|
||||
|
||||
if (codel == REFERENCE_TYPE)
|
||||
{
|
||||
ttl = TREE_TYPE (ttl);
|
||||
if (codel == REFERENCE_TYPE)
|
||||
{
|
||||
tree ttl, ttr;
|
||||
int constp = parm ? TREE_READONLY (parm) : TYPE_READONLY (parmtype);
|
||||
int volatilep = (parm ? TREE_THIS_VOLATILE (parm)
|
||||
: TYPE_VOLATILE (parmtype));
|
||||
register tree intype = TYPE_MAIN_VARIANT (parmtype);
|
||||
register enum tree_code form = TREE_CODE (intype);
|
||||
int penalty = 0;
|
||||
|
||||
/* When passing a non-const argument into a const reference,
|
||||
dig it a little, so a non-const reference is preferred over
|
||||
this one. (mrs) */
|
||||
if (parm && TREE_READONLY (ttl) && ! TREE_READONLY (parm))
|
||||
penalty = 2;
|
||||
else
|
||||
penalty = 0;
|
||||
ttl = TREE_TYPE (type);
|
||||
|
||||
ttl = TYPE_MAIN_VARIANT (ttl);
|
||||
/* When passing a non-const argument into a const reference (or vice
|
||||
versa), dig it a little, so a non-const reference is preferred
|
||||
over this one. (mrs) */
|
||||
if (TYPE_READONLY (ttl) != constp
|
||||
|| TYPE_VOLATILE (ttl) != volatilep)
|
||||
penalty = 2;
|
||||
else
|
||||
penalty = 0;
|
||||
|
||||
if (form == OFFSET_TYPE)
|
||||
{
|
||||
intype = TREE_TYPE (intype);
|
||||
form = TREE_CODE (intype);
|
||||
}
|
||||
ttl = TYPE_MAIN_VARIANT (ttl);
|
||||
|
||||
if (form == REFERENCE_TYPE)
|
||||
{
|
||||
intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype));
|
||||
if (form == OFFSET_TYPE)
|
||||
{
|
||||
intype = TREE_TYPE (intype);
|
||||
form = TREE_CODE (intype);
|
||||
}
|
||||
|
||||
if (ttl == intype)
|
||||
return ZERO_RETURN (h);
|
||||
penalty = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Can reference be built up? */
|
||||
if (ttl == intype && penalty == 0) {
|
||||
/* Because the READONLY and VIRTUAL bits are not always in
|
||||
the type, this extra check is necessary. The problem
|
||||
should be fixed someplace else, and this extra code
|
||||
removed.
|
||||
if (ttl == intype && penalty == 0)
|
||||
return ZERO_RETURN (h);
|
||||
else
|
||||
penalty = 2;
|
||||
|
||||
Also, if type if a reference, the readonly bits could
|
||||
either be in the outer type (with reference) or on the
|
||||
inner type (the thing being referenced). (mrs) */
|
||||
if (parm
|
||||
&& ((TREE_READONLY (parm)
|
||||
&& ! (TYPE_READONLY (type)
|
||||
|| (TREE_CODE (type) == REFERENCE_TYPE
|
||||
&& TYPE_READONLY (TREE_TYPE (type)))))
|
||||
|| (TREE_SIDE_EFFECTS (parm)
|
||||
&& ! (TYPE_VOLATILE (type)
|
||||
|| (TREE_CODE (type) == REFERENCE_TYPE
|
||||
&& TYPE_VOLATILE (TREE_TYPE (type)))))))
|
||||
penalty = 2;
|
||||
else
|
||||
return ZERO_RETURN (h);
|
||||
}
|
||||
else
|
||||
penalty = 2;
|
||||
}
|
||||
}
|
||||
else if (form == REFERENCE_TYPE)
|
||||
{
|
||||
if (parm)
|
||||
{
|
||||
tree tmp = convert_from_reference (parm);
|
||||
intype = TYPE_MAIN_VARIANT (TREE_TYPE (tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
intype = parmtype;
|
||||
do
|
||||
intype = TREE_TYPE (intype);
|
||||
while (TREE_CODE (intype) == REFERENCE_TYPE);
|
||||
intype = TYPE_MAIN_VARIANT (intype);
|
||||
}
|
||||
if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
|
||||
{
|
||||
ttl = unsigned_type (ttl);
|
||||
intype = unsigned_type (intype);
|
||||
penalty += 2;
|
||||
}
|
||||
|
||||
if (ttl == intype)
|
||||
return ZERO_RETURN (h);
|
||||
else
|
||||
penalty = 2;
|
||||
}
|
||||
ttr = intype;
|
||||
|
||||
if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
|
||||
{
|
||||
ttl = unsigned_type (ttl);
|
||||
intype = unsigned_type (intype);
|
||||
penalty += 2;
|
||||
}
|
||||
/* If the initializer is not an lvalue, then it does not
|
||||
matter if we make life easier for the programmer
|
||||
by creating a temporary variable with which to
|
||||
hold the result. */
|
||||
if (parm && (INTEGRAL_CODE_P (coder)
|
||||
|| coder == REAL_TYPE)
|
||||
&& ! lvalue_p (parm))
|
||||
{
|
||||
h = convert_harshness (ttl, ttr, NULL_TREE);
|
||||
if (penalty > 2 || h.code != 0)
|
||||
h.code |= STD_CODE;
|
||||
else
|
||||
h.code |= TRIVIAL_CODE;
|
||||
h.distance = 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
ttr = intype;
|
||||
|
||||
/* If the initializer is not an lvalue, then it does not
|
||||
matter if we make life easier for the programmer
|
||||
by creating a temporary variable with which to
|
||||
hold the result. */
|
||||
if (parm && (INTEGRAL_CODE_P (coder)
|
||||
|| coder == REAL_TYPE)
|
||||
&& ! lvalue_p (parm))
|
||||
{
|
||||
h = convert_harshness (ttl, ttr, NULL_TREE);
|
||||
if (penalty > 2 || h.code != 0)
|
||||
h.code |= STD_CODE;
|
||||
else
|
||||
h.code |= TRIVIAL_CODE;
|
||||
h.distance = 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
if (ttl == ttr)
|
||||
{
|
||||
if (penalty > 2)
|
||||
{
|
||||
h.code = STD_CODE;
|
||||
h.distance = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
h.code = TRIVIAL_CODE;
|
||||
/* We set this here so that build_overload_call_real will be
|
||||
able to see the penalty we found, rather than just looking
|
||||
at a TRIVIAL_CODE with no other information. */
|
||||
h.int_penalty = penalty;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Pointers to voids always convert for pointers. But
|
||||
make them less natural than more specific matches. */
|
||||
if (TREE_CODE (ttl) == POINTER_TYPE && TREE_CODE (ttr) == POINTER_TYPE)
|
||||
{
|
||||
if (TREE_TYPE (ttl) == void_type_node
|
||||
|| TREE_TYPE (ttr) == void_type_node)
|
||||
{
|
||||
h.code = STD_CODE;
|
||||
h.distance = 0;
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
if (parm && codel != REFERENCE_TYPE)
|
||||
{
|
||||
h = convert_harshness (ttl, ttr, NULL_TREE);
|
||||
if (penalty == 2)
|
||||
h.code |= QUAL_CODE;
|
||||
else if (penalty == 4)
|
||||
h.code |= STD_CODE;
|
||||
h.distance = 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Here it does matter. If this conversion is from derived to base,
|
||||
allow it. Otherwise, types must be compatible in the strong sense. */
|
||||
if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
|
||||
{
|
||||
int b_or_d = get_base_distance (ttl, ttr, 0, 0);
|
||||
if (b_or_d < 0)
|
||||
{
|
||||
b_or_d = get_base_distance (ttr, ttl, 0, 0);
|
||||
if (b_or_d < 0)
|
||||
return EVIL_RETURN (h);
|
||||
h.distance = -b_or_d;
|
||||
}
|
||||
/* Say that this conversion is relatively painless.
|
||||
If it turns out that there is a user-defined X(X&)
|
||||
constructor, then that will be invoked, but that's
|
||||
preferable to dealing with other user-defined conversions
|
||||
that may produce surprising results. */
|
||||
else
|
||||
h.distance = b_or_d;
|
||||
h.code = STD_CODE;
|
||||
return h;
|
||||
}
|
||||
|
||||
if (comp_target_types (ttl, intype, 1))
|
||||
{
|
||||
if (penalty)
|
||||
if (ttl == ttr)
|
||||
{
|
||||
if (penalty > 2)
|
||||
{
|
||||
h.code = STD_CODE;
|
||||
h.distance = 0;
|
||||
return h;
|
||||
}
|
||||
}
|
||||
}
|
||||
h.distance = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
h.code = TRIVIAL_CODE;
|
||||
/* We set this here so that build_overload_call_real will be
|
||||
able to see the penalty we found, rather than just looking
|
||||
at a TRIVIAL_CODE with no other information. */
|
||||
h.int_penalty = penalty;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Pointers to voids always convert for pointers. But
|
||||
make them less natural than more specific matches. */
|
||||
if (TREE_CODE (ttl) == POINTER_TYPE && TREE_CODE (ttr) == POINTER_TYPE)
|
||||
{
|
||||
if (TREE_TYPE (ttl) == void_type_node
|
||||
|| TREE_TYPE (ttr) == void_type_node)
|
||||
{
|
||||
h.code = STD_CODE;
|
||||
h.distance = 0;
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
/* Here it does matter. If this conversion is from derived to base,
|
||||
allow it. Otherwise, types must be compatible in the strong sense. */
|
||||
if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
|
||||
{
|
||||
int b_or_d = get_base_distance (ttl, ttr, 0, 0);
|
||||
if (b_or_d < 0)
|
||||
{
|
||||
b_or_d = get_base_distance (ttr, ttl, 0, 0);
|
||||
if (b_or_d < 0)
|
||||
return EVIL_RETURN (h);
|
||||
h.distance = -b_or_d;
|
||||
}
|
||||
/* Say that this conversion is relatively painless.
|
||||
If it turns out that there is a user-defined X(X&)
|
||||
constructor, then that will be invoked, but that's
|
||||
preferable to dealing with other user-defined conversions
|
||||
that may produce surprising results. */
|
||||
else
|
||||
h.distance = b_or_d;
|
||||
h.code = STD_CODE;
|
||||
return h;
|
||||
}
|
||||
|
||||
if (comp_target_types (ttl, intype, 1))
|
||||
{
|
||||
if (penalty)
|
||||
h.code = STD_CODE;
|
||||
h.distance = 0;
|
||||
return h;
|
||||
}
|
||||
}
|
||||
if (codel == RECORD_TYPE && coder == RECORD_TYPE)
|
||||
{
|
||||
int b_or_d = get_base_distance (type, parmtype, 0, 0);
|
||||
|
@ -1789,6 +1738,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
&& TREE_CODE (TREE_OPERAND (instance, 0)) == NOP_EXPR
|
||||
&& TREE_OPERAND (TREE_OPERAND (instance, 0), 0) == error_mark_node);
|
||||
|
||||
if (TREE_CODE (instance) == OFFSET_REF)
|
||||
instance = resolve_offset_ref (instance);
|
||||
|
||||
/* the base type of an instance variable is pointer to class */
|
||||
basetype = TREE_TYPE (instance);
|
||||
|
||||
|
@ -1808,8 +1760,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
if (! IS_AGGR_TYPE (basetype))
|
||||
goto non_aggr_error;
|
||||
|
||||
if (IS_SIGNATURE_POINTER (basetype)
|
||||
|| IS_SIGNATURE_REFERENCE (basetype))
|
||||
/* If `instance' is a signature pointer/reference and `name' is
|
||||
not a constructor, we are calling a signature member function.
|
||||
In that case set the `basetype' to the signature type. */
|
||||
if ((IS_SIGNATURE_POINTER (basetype)
|
||||
|| IS_SIGNATURE_REFERENCE (basetype))
|
||||
&& TYPE_IDENTIFIER (basetype) != name)
|
||||
basetype = SIGNATURE_TYPE (basetype);
|
||||
|
||||
if ((IS_SIGNATURE (basetype)
|
||||
|
@ -2001,8 +1957,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
/* Look up function name in the structure type definition. */
|
||||
|
||||
if ((IDENTIFIER_HAS_TYPE_VALUE (name)
|
||||
&& ! IDENTIFIER_OPNAME_P (name)
|
||||
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name))
|
||||
&& TREE_CODE(IDENTIFIER_TYPE_VALUE (name)) != UNINSTANTIATED_P_TYPE)
|
||||
&& TREE_CODE (IDENTIFIER_TYPE_VALUE (name)) != UNINSTANTIATED_P_TYPE)
|
||||
|| name == constructor_name (basetype))
|
||||
{
|
||||
tree tmp = NULL_TREE;
|
||||
|
@ -2494,11 +2451,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* We do not pass FUNCTION into `convert_arguments', because by
|
||||
now everything should be ok. If not, then we have a serious error. */
|
||||
if (DECL_STATIC_FUNCTION_P (function))
|
||||
parms = convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype),
|
||||
TREE_CHAIN (parms), NULL_TREE, LOOKUP_NORMAL);
|
||||
TREE_CHAIN (parms), function, LOOKUP_NORMAL);
|
||||
else if (need_vtbl == unneeded)
|
||||
{
|
||||
int sub_flags = DECL_CONSTRUCTOR_P (function) ? flags : LOOKUP_NORMAL;
|
||||
|
@ -2511,7 +2466,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
instance = build_indirect_ref (instance_ptr, NULL_PTR);
|
||||
}
|
||||
parms = tree_cons (NULL_TREE, instance_ptr,
|
||||
convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), NULL_TREE, sub_flags));
|
||||
convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), function, sub_flags));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2559,7 +2514,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
instance = build_indirect_ref (instance_ptr, NULL_PTR);
|
||||
}
|
||||
parms = tree_cons (NULL_TREE, instance_ptr,
|
||||
convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), NULL_TREE, LOOKUP_NORMAL));
|
||||
convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), function, LOOKUP_NORMAL));
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -2861,18 +2816,6 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
|
|||
if ((cp[0].h.code & EVIL_CODE) == 0)
|
||||
{
|
||||
cp[1].h.code = EVIL_CODE;
|
||||
|
||||
/* int_penalty is set by convert_harshness_ansi for cases
|
||||
where we need to know about any penalties that would
|
||||
otherwise make a TRIVIAL_CODE pass. */
|
||||
if (final_cp
|
||||
&& template_cost == 0
|
||||
&& cp[0].h.code <= TRIVIAL_CODE
|
||||
&& cp[0].h.int_penalty == 0)
|
||||
{
|
||||
final_cp[0].h = cp[0].h;
|
||||
return function;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1123,6 +1123,24 @@ get_vfield_offset (binfo)
|
|||
BINFO_OFFSET (binfo));
|
||||
}
|
||||
|
||||
/* Get the offset to the start of the original binfo that we derived this
|
||||
binfo from. */
|
||||
tree get_derived_offset (binfo)
|
||||
tree binfo;
|
||||
{
|
||||
tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
|
||||
tree offset2;
|
||||
int i;
|
||||
while (BINFO_BASETYPES (binfo)
|
||||
&& (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
|
||||
{
|
||||
tree binfos = BINFO_BASETYPES (binfo);
|
||||
binfo = TREE_VEC_ELT (binfos, i);
|
||||
}
|
||||
offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
|
||||
return size_binop (MINUS_EXPR, offset1, offset2);
|
||||
}
|
||||
|
||||
/* If FOR_TYPE needs to reinitialize virtual function table pointers
|
||||
for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST.
|
||||
Returns BASE_INIT_LIST appropriately modified. */
|
||||
|
@ -2171,8 +2189,13 @@ modify_one_vtable (binfo, t, fndecl, pfn)
|
|||
/* Find the right offset for the this pointer based on the
|
||||
base class we just found. We have to take into
|
||||
consideration the virtual base class pointers that we
|
||||
stick in before the virtual function table pointer. */
|
||||
base_offset = get_vfield_offset (binfo);
|
||||
stick in before the virtual function table pointer.
|
||||
|
||||
Also, we want just the delta bewteen the most base class
|
||||
that we derived this vfield from and us. */
|
||||
base_offset = size_binop (PLUS_EXPR,
|
||||
get_derived_offset (binfo),
|
||||
BINFO_OFFSET (binfo));
|
||||
this_offset = size_binop (MINUS_EXPR, offset, base_offset);
|
||||
|
||||
/* Make sure we can modify the derived association with immunity. */
|
||||
|
@ -2374,8 +2397,8 @@ override_one_vtable (binfo, old, t)
|
|||
override_one_vtable (binfo, old, t);
|
||||
return;
|
||||
}
|
||||
TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
|
||||
}
|
||||
TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2547,7 +2570,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
int ref_sans_init = 0;
|
||||
int nonprivate_method = 0;
|
||||
tree t_binfo = TYPE_BINFO (t);
|
||||
tree access_decls = 0;
|
||||
tree access_decls = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
{
|
||||
|
@ -2578,7 +2601,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
}
|
||||
|
||||
if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (name))
|
||||
warning ("anonymous class type not used to declare any objects");
|
||||
pedwarn ("anonymous class type not used to declare any objects");
|
||||
|
||||
if (TYPE_SIZE (t))
|
||||
{
|
||||
|
@ -2599,7 +2622,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
/* If this type was previously laid out as a forward reference,
|
||||
make sure we lay it out again. */
|
||||
|
||||
TYPE_SIZE (t) = 0;
|
||||
TYPE_SIZE (t) = NULL_TREE;
|
||||
CLASSTYPE_GOT_SEMICOLON (t) = 0;
|
||||
|
||||
/* A signature type will contain the fields of the signature table.
|
||||
|
@ -3025,7 +3048,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
|
||||
if (code == UNION_TYPE)
|
||||
{
|
||||
char * fie = 0;
|
||||
char *fie = NULL;
|
||||
if (TYPE_NEEDS_CONSTRUCTING (type))
|
||||
fie = "constructor";
|
||||
else if (TYPE_NEEDS_DESTRUCTOR (type))
|
||||
|
@ -3252,9 +3275,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
|
||||
{
|
||||
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
||||
cp_error_at ("because of local method `%#D' with same name",
|
||||
cp_error_at (" because of local method `%#D' with same name",
|
||||
TREE_VEC_ELT (method_vec, i));
|
||||
fdecl = 0;
|
||||
fdecl = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3265,8 +3288,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
if (DECL_NAME (tmp) == name)
|
||||
{
|
||||
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
||||
cp_error_at ("because of local field `%#D' with same name", tmp);
|
||||
fdecl = 0;
|
||||
cp_error_at (" because of local field `%#D' with same name", tmp);
|
||||
fdecl = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3315,7 +3338,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
}
|
||||
else if (last_x)
|
||||
{
|
||||
my_friendly_assert (TREE_CHAIN (last_x) == 0, 175);
|
||||
my_friendly_assert (TREE_CHAIN (last_x) == NULL_TREE, 175);
|
||||
TREE_CHAIN (last_x) = vfield;
|
||||
last_x = vfield;
|
||||
}
|
||||
|
@ -3378,7 +3401,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
moved into the type of this field, but nothing seems to break
|
||||
by doing this. */
|
||||
|
||||
if (DECL_NAME (field) == 0
|
||||
if (DECL_NAME (field) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
|
||||
{
|
||||
tree uelt = TYPE_FIELDS (TREE_TYPE (field));
|
||||
|
@ -3405,7 +3428,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
TYPE_ALIGN (pseudo_basetype) = CLASSTYPE_ALIGN (t);
|
||||
DECL_ALIGN (base_layout_decl) = TYPE_ALIGN (pseudo_basetype);
|
||||
/* Don't re-use old size. */
|
||||
DECL_SIZE (base_layout_decl) = 0;
|
||||
DECL_SIZE (base_layout_decl) = NULL_TREE;
|
||||
}
|
||||
|
||||
layout_type (t);
|
||||
|
@ -3432,7 +3455,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
moved into the type of this field, but nothing seems to break
|
||||
by doing this. */
|
||||
|
||||
if (DECL_NAME (field) == 0
|
||||
if (DECL_NAME (field) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
|
||||
{
|
||||
tree uelt = TYPE_FIELDS (TREE_TYPE (field));
|
||||
|
@ -3709,12 +3732,11 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
while (x)
|
||||
{
|
||||
#if 0 /* What's wrong with using the decl the type already has? */
|
||||
tree tag = build_lang_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x));
|
||||
tree tag = build_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x));
|
||||
DECL_CONTEXT (tag) = t;
|
||||
#else
|
||||
tree tag = TYPE_NAME (TREE_VALUE (x));
|
||||
#endif
|
||||
DECL_CLASS_CONTEXT (tag) = t;
|
||||
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
|
@ -3729,7 +3751,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
x = TREE_CHAIN (x);
|
||||
last_x = chainon (last_x, tag);
|
||||
}
|
||||
if (TYPE_FIELDS (t) == 0)
|
||||
if (TYPE_FIELDS (t) == NULL_TREE)
|
||||
TYPE_FIELDS (t) = last_x;
|
||||
CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
|
||||
}
|
||||
|
@ -4220,7 +4242,9 @@ popclass (modify)
|
|||
{
|
||||
if (CLASSTYPE_VTBL_PTR (current_class_type))
|
||||
{
|
||||
current_vtable_decl = lookup_name (DECL_NAME (CLASSTYPE_VTBL_PTR (current_class_type)), 0);
|
||||
current_vtable_decl
|
||||
= lookup_name (DECL_NAME (CLASSTYPE_VTBL_PTR (current_class_type)),
|
||||
0);
|
||||
if (current_vtable_decl)
|
||||
current_vtable_decl = build_indirect_ref (current_vtable_decl,
|
||||
NULL_PTR);
|
||||
|
@ -4525,9 +4549,10 @@ instantiate_type (lhstype, rhs, complain)
|
|||
{
|
||||
if (complain)
|
||||
{
|
||||
cp_error ("cannot resolve overload to target type `%#T';", lhstype);
|
||||
cp_error_at ("ambiguity between `%#D'", save_elem);
|
||||
cp_error_at ("and `%#D', at least", elem);
|
||||
cp_error ("cannot resolve overload to target type `%#T'",
|
||||
lhstype);
|
||||
cp_error_at (" ambiguity between `%#D'", save_elem);
|
||||
cp_error_at (" and `%#D', at least", elem);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
|
@ -4547,9 +4572,9 @@ instantiate_type (lhstype, rhs, complain)
|
|||
}
|
||||
if (complain)
|
||||
{
|
||||
cp_error ("cannot resolve overload to target type `%#T';",
|
||||
cp_error ("cannot resolve overload to target type `%#T'",
|
||||
lhstype);
|
||||
cp_error ("no suitable overload of function `%D' exists",
|
||||
cp_error (" because no suitable overload of function `%D' exists",
|
||||
TREE_PURPOSE (rhs));
|
||||
}
|
||||
return error_mark_node;
|
||||
|
@ -4631,10 +4656,12 @@ instantiate_type (lhstype, rhs, complain)
|
|||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case COMPOUND_EXPR:
|
||||
TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
|
||||
TREE_OPERAND (rhs, 0)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
|
||||
if (TREE_OPERAND (rhs, 0) == error_mark_node)
|
||||
return error_mark_node;
|
||||
TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
|
||||
TREE_OPERAND (rhs, 1)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
|
||||
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -4701,10 +4728,12 @@ instantiate_type (lhstype, rhs, complain)
|
|||
error ("not enough type information");
|
||||
return error_mark_node;
|
||||
}
|
||||
TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
|
||||
TREE_OPERAND (rhs, 1)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
|
||||
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
TREE_OPERAND (rhs, 2) = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain);
|
||||
TREE_OPERAND (rhs, 2)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain);
|
||||
if (TREE_OPERAND (rhs, 2) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -4712,7 +4741,8 @@ instantiate_type (lhstype, rhs, complain)
|
|||
return rhs;
|
||||
|
||||
case MODIFY_EXPR:
|
||||
TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
|
||||
TREE_OPERAND (rhs, 1)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
|
||||
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -4730,8 +4760,8 @@ instantiate_type (lhstype, rhs, complain)
|
|||
}
|
||||
TREE_TYPE (rhs) = lhstype;
|
||||
lhstype = TREE_TYPE (lhstype);
|
||||
TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0),
|
||||
complain);
|
||||
TREE_OPERAND (rhs, 0)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
|
||||
if (TREE_OPERAND (rhs, 0) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
|
|
@ -362,6 +362,7 @@ enum languages { lang_c, lang_cplusplus };
|
|||
#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) >= 0)
|
||||
#define ACCESSIBLY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, -1, (tree *)0) >= 0)
|
||||
#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0)
|
||||
#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1)
|
||||
|
||||
enum conversion_type { ptr_conv, constptr_conv, int_conv,
|
||||
real_conv, last_conversion_type };
|
||||
|
@ -497,8 +498,11 @@ struct lang_type
|
|||
union tree_node *signature_reference_to;
|
||||
};
|
||||
|
||||
/* Indicates whether a template should be (or has been) expanded for this
|
||||
class definition. 0=do, 1=did, 2=don't, 3=didn't. */
|
||||
/* Indicates whether or not (and how) a template was expanded for this class.
|
||||
0=no information yet/non-template class
|
||||
1=implicit template instantiation
|
||||
2=explicit template specialization
|
||||
3=explicit template instantiation */
|
||||
#define CLASSTYPE_USE_TEMPLATE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.use_template)
|
||||
|
||||
/* Fields used for storing information before the class is defined.
|
||||
|
@ -931,7 +935,9 @@ struct lang_decl_flags
|
|||
unsigned mutable_flag : 1;
|
||||
unsigned is_default_implementation : 1;
|
||||
unsigned saved_inline : 1;
|
||||
unsigned dummy : 10;
|
||||
unsigned use_template : 2;
|
||||
|
||||
unsigned dummy : 8;
|
||||
|
||||
tree access;
|
||||
tree context;
|
||||
|
@ -1101,7 +1107,7 @@ struct lang_decl
|
|||
|
||||
#if 0
|
||||
/* Same, but tells if this field is private in current context. */
|
||||
#define DECL_PRIVATE(NODE) NOTHING
|
||||
#define DECL_PRIVATE(NODE) (DECL_LANG_FLAG_5 (NODE))
|
||||
|
||||
/* Same, but tells if this field is private in current context. */
|
||||
#define DECL_PROTECTED(NODE) (DECL_LANG_FLAG_6 (NODE))
|
||||
|
@ -1266,11 +1272,39 @@ struct lang_decl
|
|||
#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE)
|
||||
#define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE)
|
||||
|
||||
/* Macros for a DECL or TYPE generated from a template to indicate that it
|
||||
was explicitly instantiated. */
|
||||
#define DECL_EXPLICITLY_INSTANTIATED(NODE) (DECL_LANG_FLAG_5 (NODE))
|
||||
#define CLASSTYPE_EXPLICITLY_INSTANTIATED(NODE) \
|
||||
(DECL_EXPLICITLY_INSTANTIATED (TYPE_NAME (NODE)))
|
||||
/* Indicates whether or not (and how) a template was expanded for this
|
||||
FUNCTION_DECL or VAR_DECL.
|
||||
0=normal declaration, e.g. int min (int, int);
|
||||
1=implicit template instantiation
|
||||
2=explicit template specialization, e.g. int min<int> (int, int);
|
||||
3=explicit template instantiation, e.g. template int min<int> (int, int);
|
||||
*/
|
||||
#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.use_template)
|
||||
|
||||
#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
|
||||
#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE (NODE) & 1)
|
||||
|
||||
#define DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) == 2)
|
||||
#define SET_DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) = 2)
|
||||
#define CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE (NODE) == 2)
|
||||
#define SET_CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE (NODE) = 2)
|
||||
|
||||
#define DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 1)
|
||||
#define SET_DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 1)
|
||||
#define CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE(NODE) == 1)
|
||||
#define SET_CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE(NODE) = 1)
|
||||
|
||||
#define DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 3)
|
||||
#define SET_DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 3)
|
||||
#define CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE(NODE) == 3)
|
||||
#define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE(NODE) = 3)
|
||||
|
||||
#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i)
|
||||
|
||||
|
@ -1309,6 +1343,7 @@ extern void check_function_format PROTO((tree, tree, tree));
|
|||
/* Print an error message for invalid operands to arith operation CODE.
|
||||
NOP_EXPR is used as a special case (see truthvalue_conversion). */
|
||||
extern void binary_op_error PROTO((enum tree_code));
|
||||
extern tree c_build_type_variant PROTO((tree, int, int));
|
||||
extern void c_expand_expr_stmt PROTO((tree));
|
||||
/* Validate the expression after `case' and apply default promotions. */
|
||||
extern tree check_case_value PROTO((tree));
|
||||
|
@ -1462,7 +1497,7 @@ extern int current_function_parms_stored;
|
|||
#define AUTO_TEMP_NAME "_$tmp_"
|
||||
#define AUTO_TEMP_FORMAT "_$tmp_%d"
|
||||
#define VTABLE_BASE "$vb"
|
||||
#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "_VT$%s" : "_vt$%s")
|
||||
#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt$%s")
|
||||
#define VFIELD_BASE "$vf"
|
||||
#define VFIELD_NAME "_vptr$"
|
||||
#define VFIELD_NAME_FORMAT "_vptr$%s"
|
||||
|
@ -1484,7 +1519,7 @@ extern int current_function_parms_stored;
|
|||
#define AUTO_TEMP_NAME "_.tmp_"
|
||||
#define AUTO_TEMP_FORMAT "_.tmp_%d"
|
||||
#define VTABLE_BASE ".vb"
|
||||
#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "_VT.%s" : "_vt.%s")
|
||||
#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt.%s")
|
||||
#define VFIELD_BASE ".vf"
|
||||
#define VFIELD_NAME "_vptr."
|
||||
#define VFIELD_NAME_FORMAT "_vptr.%s"
|
||||
|
@ -1513,7 +1548,7 @@ extern int current_function_parms_stored;
|
|||
#define AUTO_TEMP_FORMAT "__tmp_%d"
|
||||
#define VTABLE_BASE "__vtb"
|
||||
#define VTABLE_NAME "__vt_"
|
||||
#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "_VT_%s" : "_vt_%s")
|
||||
#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt_%s")
|
||||
#define VTABLE_NAME_P(ID_NODE) \
|
||||
(!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
|
||||
sizeof (VTABLE_NAME) - 1))
|
||||
|
@ -1668,6 +1703,11 @@ extern int flag_gc;
|
|||
|
||||
extern int flag_dossier;
|
||||
|
||||
/* Nonzero means do emit exported implementations of functions even if
|
||||
they can be inlined. */
|
||||
|
||||
extern int flag_implement_inlines;
|
||||
|
||||
/* Nonzero means templates obey #pragma interface and implementation. */
|
||||
|
||||
extern int flag_external_templates;
|
||||
|
@ -1676,6 +1716,10 @@ extern int flag_external_templates;
|
|||
|
||||
extern int flag_alt_external_templates;
|
||||
|
||||
/* Nonzero means implicit template instantatiations are emitted. */
|
||||
|
||||
extern int flag_implicit_templates;
|
||||
|
||||
/* Current end of entries in the gc obstack for stack pointer variables. */
|
||||
|
||||
extern int current_function_obstack_index;
|
||||
|
@ -1875,7 +1919,7 @@ extern tree lookup_name_current_level PROTO((tree));
|
|||
extern void init_decl_processing PROTO((void));
|
||||
/* skipped define_function */
|
||||
extern void shadow_tag PROTO((tree));
|
||||
extern void grok_ctor_properties PROTO((tree, tree));
|
||||
extern int grok_ctor_properties PROTO((tree, tree));
|
||||
extern tree groktypename PROTO((tree));
|
||||
extern tree start_decl PROTO((tree, tree, int, tree));
|
||||
extern void finish_decl PROTO((tree, tree, tree, int));
|
||||
|
|
14
gcc/cp/cvt.c
14
gcc/cp/cvt.c
|
@ -1226,6 +1226,9 @@ cp_convert (type, expr, convtype, flags)
|
|||
else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
|
||||
e = convert_from_reference (e);
|
||||
|
||||
if (TREE_READONLY_DECL_P (e))
|
||||
e = decl_constant_value (e);
|
||||
|
||||
if (INTEGRAL_CODE_P (code))
|
||||
{
|
||||
tree intype = TREE_TYPE (expr);
|
||||
|
@ -1332,8 +1335,12 @@ cp_convert (type, expr, convtype, flags)
|
|||
{
|
||||
tree binfo;
|
||||
|
||||
tree conversion = TYPE_HAS_CONVERSION (dtype)
|
||||
? build_type_conversion (CONVERT_EXPR, type, e, 1) : NULL_TREE;
|
||||
tree conversion;
|
||||
|
||||
if (! DERIVED_FROM_P (type, dtype) && TYPE_HAS_CONVERSION (dtype))
|
||||
conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
|
||||
else
|
||||
conversion = NULL_TREE;
|
||||
|
||||
if (TYPE_HAS_CONSTRUCTOR (type))
|
||||
{
|
||||
|
@ -1493,8 +1500,7 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
|
|||
else
|
||||
flags = LOOKUP_NORMAL;
|
||||
|
||||
rval = build_method_call (first_arg, constructor_name_full (typename),
|
||||
NULL_TREE, NULL_TREE, flags);
|
||||
rval = build_method_call (first_arg, typename, NULL_TREE, NULL_TREE, flags);
|
||||
if (rval == error_mark_node)
|
||||
{
|
||||
if (for_sure == 0)
|
||||
|
|
238
gcc/cp/decl.c
238
gcc/cp/decl.c
|
@ -410,11 +410,6 @@ extern int flag_short_double;
|
|||
|
||||
extern int flag_no_builtin;
|
||||
|
||||
/* Nonzero means do emit exported implementations of functions even if
|
||||
they can be inlined. */
|
||||
|
||||
extern int flag_implement_inlines;
|
||||
|
||||
/* Nonzero means disable GNU extensions. */
|
||||
|
||||
extern int flag_ansi;
|
||||
|
@ -1791,7 +1786,7 @@ pushtag (name, type, globalize)
|
|||
{
|
||||
/* Make nested declarations go into class-level scope. */
|
||||
newdecl = 1;
|
||||
d = build_lang_field_decl (TYPE_DECL, name, type);
|
||||
d = build_decl (TYPE_DECL, name, type);
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
{
|
||||
|
@ -1832,14 +1827,13 @@ pushtag (name, type, globalize)
|
|||
}
|
||||
/* else if (TYPE_SIZE (current_class_type) == NULL_TREE)
|
||||
*/
|
||||
else if (context && TREE_CODE (context) == RECORD_TYPE)
|
||||
else if (context && IS_AGGR_TYPE (context))
|
||||
{
|
||||
/* Class-nested class. */
|
||||
set_nested_typename (d, DECL_NESTED_TYPENAME (c_decl),
|
||||
name, type);
|
||||
/* This builds the links for classes nested in type scope. */
|
||||
DECL_CONTEXT (d) = context;
|
||||
DECL_CLASS_CONTEXT (d) = context;
|
||||
}
|
||||
TYPE_CONTEXT (type) = DECL_CONTEXT (d);
|
||||
if (newdecl)
|
||||
|
@ -2021,6 +2015,8 @@ decls_match (newdecl, olddecl)
|
|||
types_match = TREE_TYPE (olddecl) == error_mark_node;
|
||||
else if (TREE_TYPE (olddecl) == NULL_TREE)
|
||||
types_match = TREE_TYPE (newdecl) == NULL_TREE;
|
||||
else if (TREE_TYPE (newdecl) == NULL_TREE)
|
||||
types_match = 0;
|
||||
else
|
||||
types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 1);
|
||||
}
|
||||
|
@ -2441,18 +2437,7 @@ duplicate_decls (newdecl, olddecl)
|
|||
TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
|
||||
DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
|
||||
|
||||
/* For functions, static overrides non-static. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
|
||||
/* This is since we don't automatically
|
||||
copy the attributes of NEWDECL into OLDDECL. */
|
||||
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
|
||||
/* If this clears `static', clear it in the identifier too. */
|
||||
if (! TREE_PUBLIC (olddecl))
|
||||
TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0;
|
||||
}
|
||||
else
|
||||
if (TREE_CODE (newdecl) != FUNCTION_DECL)
|
||||
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
|
||||
}
|
||||
else
|
||||
|
@ -2464,7 +2449,20 @@ duplicate_decls (newdecl, olddecl)
|
|||
&& TREE_READONLY (newdecl) && TREE_STATIC (newdecl)
|
||||
&& ! DECL_THIS_EXTERN (newdecl))
|
||||
TREE_PUBLIC (newdecl) = 0;
|
||||
else if (TREE_CODE (newdecl) != FUNCTION_DECL)
|
||||
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
|
||||
}
|
||||
|
||||
/* For functions, static overrides non-static. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
|
||||
/* This is since we don't automatically
|
||||
copy the attributes of NEWDECL into OLDDECL. */
|
||||
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
|
||||
/* If this clears `static', clear it in the identifier too. */
|
||||
if (! TREE_PUBLIC (olddecl))
|
||||
TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0;
|
||||
}
|
||||
|
||||
/* If either decl says `inline', this fn is inline,
|
||||
|
@ -2854,7 +2852,8 @@ pushdecl (x)
|
|||
|
||||
/* If new decl is `static' and an `extern' was seen previously,
|
||||
warn about it. */
|
||||
warn_extern_redeclared_static (x, t);
|
||||
if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t))
|
||||
warn_extern_redeclared_static (x, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3964,20 +3963,13 @@ lookup_name_real (name, prefer_type, nonclass)
|
|||
done:
|
||||
if (val)
|
||||
{
|
||||
/* Arbitrate between finding a TYPE_DECL and finding
|
||||
other kinds of _DECLs. */
|
||||
if (TREE_CODE (val) == TYPE_DECL || prefer_type < 0)
|
||||
if ((TREE_CODE (val) == TEMPLATE_DECL && looking_for_template)
|
||||
|| TREE_CODE (val) == TYPE_DECL || prefer_type <= 0)
|
||||
return val;
|
||||
|
||||
if (IDENTIFIER_HAS_TYPE_VALUE (name))
|
||||
{
|
||||
register tree val_as_type = TYPE_NAME (IDENTIFIER_TYPE_VALUE (name));
|
||||
return TYPE_NAME (IDENTIFIER_TYPE_VALUE (name));
|
||||
|
||||
if (val == val_as_type || prefer_type > 0)
|
||||
return val_as_type;
|
||||
|
||||
return val;
|
||||
}
|
||||
if (TREE_TYPE (val) == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
@ -5312,7 +5304,9 @@ start_decl (declarator, declspecs, initialized, raises)
|
|||
default:
|
||||
/* Don't allow initializations for incomplete types except for
|
||||
arrays which might be completed by the initialization. */
|
||||
if (TYPE_SIZE (type) != NULL_TREE)
|
||||
if (type == error_mark_node)
|
||||
; /* Don't complain again. */
|
||||
else if (TYPE_SIZE (type) != NULL_TREE)
|
||||
; /* A complete type is ok. */
|
||||
else if (TREE_CODE (type) != ARRAY_TYPE)
|
||||
{
|
||||
|
@ -5768,7 +5762,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
|||
TREE_TYPE (decl) = type = TREE_TYPE (init);
|
||||
DECL_INITIAL (decl) = init = NULL_TREE;
|
||||
}
|
||||
if (IS_AGGR_TYPE (type) && DECL_NAME (decl))
|
||||
if (type != error_mark_node
|
||||
&& IS_AGGR_TYPE (type) && DECL_NAME (decl))
|
||||
{
|
||||
if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
|
||||
cp_warning ("shadowing previous type declaration of `%#D'", decl);
|
||||
|
@ -5856,7 +5851,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
|||
|
||||
GNU_xref_decl (current_function_decl, decl);
|
||||
|
||||
if (TREE_CODE (decl) == FIELD_DECL || DECL_EXTERNAL (decl))
|
||||
if (TREE_CODE (decl) == FIELD_DECL)
|
||||
;
|
||||
else if (TREE_CODE (decl) == CONST_DECL)
|
||||
{
|
||||
|
@ -5960,6 +5955,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
|||
DECL_INITIAL (decl) = error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (DECL_EXTERNAL (decl))
|
||||
;
|
||||
else if (TREE_CODE_CLASS (TREE_CODE (type)) == 't'
|
||||
&& (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type)))
|
||||
{
|
||||
|
@ -6185,11 +6182,11 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
|||
store_expr (DECL_INITIAL (decl), DECL_RTL (decl), 0);
|
||||
TREE_ASM_WRITTEN (decl) = 1;
|
||||
}
|
||||
else if (toplev)
|
||||
else if (toplev && ! TREE_PUBLIC (decl))
|
||||
{
|
||||
/* If this is a static const, change its apparent linkage
|
||||
if it belongs to a #pragma interface. */
|
||||
if (TREE_STATIC (decl) && !interface_unknown)
|
||||
if (!interface_unknown)
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = interface_only;
|
||||
|
@ -6681,7 +6678,9 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
grokclassfn (ctype, declarator, decl, flags, quals);
|
||||
if (check)
|
||||
check_classfn (ctype, declarator, decl);
|
||||
grok_ctor_properties (ctype, decl);
|
||||
if (! grok_ctor_properties (ctype, decl))
|
||||
return NULL_TREE;
|
||||
|
||||
if (check == 0 && ! current_function_decl)
|
||||
{
|
||||
/* FIXME: this should only need to look at
|
||||
|
@ -7393,18 +7392,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
{
|
||||
if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits))
|
||||
{
|
||||
#if 0
|
||||
if (pedantic)
|
||||
pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
|
||||
else
|
||||
#endif
|
||||
if (longlong)
|
||||
error ("`long long long' is too long for GCC");
|
||||
if (pedantic && flag_ansi)
|
||||
pedwarn ("duplicate `long'");
|
||||
else if (longlong)
|
||||
error ("`long long long' is too long for GCC");
|
||||
else
|
||||
longlong = 1;
|
||||
}
|
||||
else if (RIDBIT_SETP (i, specbits))
|
||||
warning ("duplicate `%s'", IDENTIFIER_POINTER (id));
|
||||
pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
|
||||
RIDBIT_SET (i, specbits);
|
||||
goto found;
|
||||
}
|
||||
|
@ -7619,7 +7615,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
warning ("duplicate `volatile'");
|
||||
virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
|
||||
|
||||
/* operators new and delete are implicitly static. */
|
||||
if (RIDBIT_SETP (RID_STATIC, specbits))
|
||||
staticp = 1 + (decl_context == FIELD);
|
||||
|
||||
|
@ -8049,8 +8044,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
else
|
||||
{
|
||||
if (flag_ansi)
|
||||
cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",
|
||||
dname);
|
||||
{
|
||||
if (dname)
|
||||
cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",
|
||||
dname);
|
||||
else
|
||||
cp_pedwarn ("ANSI C++ forbids variable-size array");
|
||||
}
|
||||
dont_grok_size:
|
||||
itype =
|
||||
build_binary_op (MINUS_EXPR, size, integer_one_node, 1);
|
||||
|
@ -8070,8 +8070,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
|
||||
type = build_cplus_array_type (type, itype);
|
||||
if (constp || volatilep)
|
||||
/* Should this be c_build_type_variant? -jason */
|
||||
type = build_type_variant (type, constp, volatilep);
|
||||
type = c_build_type_variant (type, constp, volatilep);
|
||||
|
||||
ctype = NULL_TREE;
|
||||
}
|
||||
|
@ -8383,9 +8382,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
}
|
||||
}
|
||||
if (constp > 1)
|
||||
warning ("duplicate `const'");
|
||||
pedwarn ("duplicate `const'");
|
||||
if (volatilep > 1)
|
||||
warning ("duplicate `volatile'");
|
||||
pedwarn ("duplicate `volatile'");
|
||||
if (TREE_CODE (declarator) == ADDR_EXPR
|
||||
&& (constp || volatilep))
|
||||
{
|
||||
if (constp)
|
||||
warning ("discarding `const' applied to a reference");
|
||||
if (volatilep)
|
||||
warning ("discarding `volatile' applied to a reference");
|
||||
constp = volatilep = 0;
|
||||
}
|
||||
}
|
||||
declarator = TREE_OPERAND (declarator, 0);
|
||||
ctype = NULL_TREE;
|
||||
|
@ -8841,7 +8849,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
|
||||
/* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
|
||||
publicp = (RIDBIT_SETP (RID_EXTERN, specbits)
|
||||
|| (ctype != NULL_TREE && funcdef_flag >= 0)
|
||||
|| (ctype != NULL_TREE
|
||||
&& funcdef_flag >= 0
|
||||
&& RIDBIT_NOTSETP (RID_INLINE, specbits))
|
||||
|| (friendp
|
||||
&& ! funcdef_flag
|
||||
&& RIDBIT_NOTSETP (RID_STATIC, specbits)
|
||||
|
@ -8921,14 +8931,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
|
||||
if (decl == NULL_TREE)
|
||||
{
|
||||
/* ANSI C++ June 5 1992 WP 9.2.2 and 9.4.2. A member-declarator
|
||||
cannot have an initializer, and a static member declaration must
|
||||
be defined elsewhere. */
|
||||
if (initialized)
|
||||
{
|
||||
/* Motion 10 at San Diego: If a static const integral data
|
||||
member is initialized with an integral constant
|
||||
expression, the initializer may appear either in the
|
||||
declaration (within the class), or in the definition,
|
||||
but not both. If it appears in the class, the member is
|
||||
a member constant. The file-scope definition is always
|
||||
required. */
|
||||
if (staticp)
|
||||
error ("static member `%s' must be defined separately from its declaration",
|
||||
IDENTIFIER_POINTER (declarator));
|
||||
{
|
||||
if (pedantic)
|
||||
{
|
||||
if (! constp)
|
||||
cp_pedwarn ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
|
||||
declarator);
|
||||
|
||||
else if (! INTEGRAL_TYPE_P (type))
|
||||
cp_pedwarn ("ANSI C++ forbids member constant `%D' of non-integral type `%T'", declarator, type);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that initialization of const members is prohibited
|
||||
by the draft ANSI standard, though it appears to be in
|
||||
common practice. 12.6.2: The argument list is used to
|
||||
|
@ -8936,9 +8960,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
initializer list) is the only way to initialize
|
||||
nonstatic const and reference members. */
|
||||
else if (flag_ansi || ! constp)
|
||||
pedwarn ("ANSI C++ forbids initialization of %s `%s'",
|
||||
constp ? "const member" : "member",
|
||||
IDENTIFIER_POINTER (declarator));
|
||||
cp_pedwarn ("ANSI C++ forbids initialization of %s `%D'",
|
||||
constp ? "const member" : "member", declarator);
|
||||
}
|
||||
|
||||
if (staticp || (constp && initialized))
|
||||
|
@ -8952,7 +8975,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
TREE_STATIC (decl) = 1;
|
||||
/* In class context, static means public access. */
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = !initialized;
|
||||
DECL_EXTERNAL (decl) = !!staticp;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -9472,7 +9495,7 @@ grokparms (first_parm, funcdef_flag)
|
|||
`grok_op_properties' takes notice of the various forms of
|
||||
operator= which are defined, as well as what sorts of type conversion
|
||||
may apply. Both functions take a FUNCTION_DECL as an argument. */
|
||||
void
|
||||
int
|
||||
grok_ctor_properties (ctype, decl)
|
||||
tree ctype, decl;
|
||||
{
|
||||
|
@ -9509,14 +9532,21 @@ grok_ctor_properties (ctype, decl)
|
|||
{
|
||||
if (TREE_CHAIN (parmtypes) != NULL_TREE
|
||||
&& TREE_CHAIN (parmtypes) == void_list_node)
|
||||
cp_error ("invalid constructor; you probably meant `%T (%T&)'",
|
||||
ctype, ctype);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype);
|
||||
TYPE_GETS_INIT_AGGR (ctype) = 1;
|
||||
{
|
||||
cp_error ("invalid constructor; you probably meant `%T (%T&)'",
|
||||
ctype, ctype);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
TYPE_GETS_INIT_AGGR (ctype) = 1;
|
||||
}
|
||||
else if (TREE_CODE (parmtype) == VOID_TYPE
|
||||
|| TREE_PURPOSE (parmtypes) != NULL_TREE)
|
||||
TYPE_HAS_DEFAULT_CONSTRUCTOR (ctype) = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* An operator with this name can be either unary or binary. */
|
||||
|
@ -9660,10 +9690,30 @@ grok_op_properties (decl, virtualp, friendp)
|
|||
|| name == ansi_opname[(int) METHOD_CALL_EXPR])
|
||||
return; /* no restrictions on args */
|
||||
|
||||
if (IDENTIFIER_TYPENAME_P (name)
|
||||
&& TREE_CODE (TREE_TYPE (name)) == VOID_TYPE)
|
||||
error ("void is not a valid type conversion operator");
|
||||
|
||||
if (IDENTIFIER_TYPENAME_P (name))
|
||||
{
|
||||
tree t = TREE_TYPE (name);
|
||||
if (TREE_CODE (t) == VOID_TYPE)
|
||||
pedwarn ("void is not a valid type conversion operator");
|
||||
else if (! friendp)
|
||||
{
|
||||
int ref = (TREE_CODE (t) == REFERENCE_TYPE);
|
||||
char *what = 0;
|
||||
if (ref)
|
||||
t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
|
||||
|
||||
if (t == current_class_type)
|
||||
what = "the same type";
|
||||
else if (IS_AGGR_TYPE (t)
|
||||
&& DERIVED_FROM_P (t, current_class_type))
|
||||
what = "a base class";
|
||||
|
||||
if (what)
|
||||
warning ("conversion to %s%s will never use a type conversion operator",
|
||||
ref ? "a reference to " : "", what);
|
||||
}
|
||||
}
|
||||
|
||||
if (name == ansi_opname[(int) MODIFY_EXPR])
|
||||
{
|
||||
tree parmtype;
|
||||
|
@ -9810,12 +9860,12 @@ xref_defn_tag (code_type_node, name, binfo)
|
|||
#endif
|
||||
#if 0
|
||||
IDENTIFIER_LOCAL_VALUE (name) =
|
||||
build_lang_decl (TYPE_DECL, ncp, NULL_TREE);
|
||||
build_decl (TYPE_DECL, ncp, NULL_TREE);
|
||||
#endif
|
||||
rv = xref_tag (code_type_node, name, binfo, 0);
|
||||
if (! ANON_AGGRNAME_P (name))
|
||||
{
|
||||
register tree type_decl = build_lang_decl (TYPE_DECL, ncp, rv);
|
||||
register tree type_decl = build_decl (TYPE_DECL, ncp, rv);
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
/* Mark the TYPE_DECL node created just above as a gratuitous one
|
||||
so that dwarfout.c will know not to generate a TAG_typedef DIE
|
||||
|
@ -9875,10 +9925,10 @@ xref_tag (code_type_node, name, binfo, globalize)
|
|||
|
||||
/* If a cross reference is requested, look up the type
|
||||
already defined for this tag and return it. */
|
||||
if ((t = IDENTIFIER_TYPE_VALUE(name)))
|
||||
{
|
||||
if (TREE_CODE(t) != code) t = NULL_TREE;
|
||||
}
|
||||
t = IDENTIFIER_TYPE_VALUE (name);
|
||||
if (t && TREE_CODE (t) != code)
|
||||
t = NULL_TREE;
|
||||
|
||||
if (xref_next_defn)
|
||||
{
|
||||
/* If we know we are defining this tag, only look it up in this scope
|
||||
|
@ -10694,15 +10744,29 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
|
|||
{
|
||||
TREE_PUBLIC (decl1) = 1;
|
||||
DECL_EXTERNAL (decl1)
|
||||
= ((interface_only && !DECL_EXPLICITLY_INSTANTIATED (decl1))
|
||||
= (interface_only
|
||||
|| (DECL_INLINE (decl1) && ! flag_implement_inlines));
|
||||
}
|
||||
else if (DECL_EXPLICIT_INSTANTIATION (decl1))
|
||||
{
|
||||
TREE_PUBLIC (decl1) = 1;
|
||||
DECL_EXTERNAL (decl1) = (DECL_INLINE (decl1)
|
||||
&& ! flag_implement_inlines);
|
||||
}
|
||||
else
|
||||
/* This is a definition, not a reference.
|
||||
So normally clear DECL_EXTERNAL.
|
||||
However, `extern inline' acts like a declaration except for
|
||||
defining how to inline. So set DECL_EXTERNAL in that case. */
|
||||
DECL_EXTERNAL (decl1) = current_extern_inline;
|
||||
{
|
||||
/* This is a definition, not a reference.
|
||||
So normally clear DECL_EXTERNAL.
|
||||
However, `extern inline' acts like a declaration except for
|
||||
defining how to inline. So set DECL_EXTERNAL in that case. */
|
||||
DECL_EXTERNAL (decl1) = current_extern_inline;
|
||||
|
||||
#if 0
|
||||
DECL_DEFER_OUTPUT (decl1)
|
||||
= (DECL_INLINE (decl1) && (DECL_IMPLICIT_INSTANTIATION (decl1)
|
||||
|| DECL_FUNCTION_MEMBER_P (decl1)));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Record the decl so that the function name is defined.
|
||||
If we already have a decl for this name, and it is a FUNCTION_DECL,
|
||||
|
@ -11703,6 +11767,9 @@ start_method (declspecs, declarator, raises)
|
|||
if (flag_default_inline)
|
||||
DECL_INLINE (fndecl) = 1;
|
||||
|
||||
if (processing_template_defn)
|
||||
SET_DECL_IMPLICIT_INSTANTIATION (fndecl);
|
||||
|
||||
/* We read in the parameters on the maybepermanent_obstack,
|
||||
but we won't be getting back to them until after we
|
||||
may have clobbered them. So the call to preserve_data
|
||||
|
@ -11726,7 +11793,10 @@ start_method (declspecs, declarator, raises)
|
|||
}
|
||||
|
||||
if (DECL_CONSTRUCTOR_P (fndecl))
|
||||
grok_ctor_properties (current_class_type, fndecl);
|
||||
{
|
||||
if (! grok_ctor_properties (current_class_type, fndecl))
|
||||
return void_type_node;
|
||||
}
|
||||
else if (IDENTIFIER_OPNAME_P (DECL_NAME (fndecl)))
|
||||
grok_op_properties (fndecl, DECL_VIRTUAL_P (fndecl), 0);
|
||||
}
|
||||
|
|
|
@ -116,6 +116,10 @@ int flag_external_templates = 0;
|
|||
|
||||
int flag_alt_external_templates = 0;
|
||||
|
||||
/* Nonzero means that implicit instantiations will be emitted if needed. */
|
||||
|
||||
int flag_implicit_templates = 1;
|
||||
|
||||
/* Nonzero means warn about implicit declarations. */
|
||||
|
||||
int warn_implicit = 1;
|
||||
|
@ -352,6 +356,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
|
|||
{"nonnull-objects", &flag_assume_nonnull_objects, 1},
|
||||
{"implement-inlines", &flag_implement_inlines, 1},
|
||||
{"external-templates", &flag_external_templates, 1},
|
||||
{"implicit-templates", &flag_implicit_templates, 1},
|
||||
{"huge-objects", &flag_huge_objects, 1},
|
||||
{"conserve-space", &flag_conserve_space, 1},
|
||||
{"vtable-thunks", &flag_vtable_thunks, 1},
|
||||
|
@ -1181,7 +1186,7 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
|
|||
|
||||
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, raises);
|
||||
if (! value)
|
||||
return NULL_TREE; /* friends went bad. */
|
||||
return value; /* friend or constructor went bad. */
|
||||
|
||||
/* Pass friendly classes back. */
|
||||
if (TREE_CODE (value) == VOID_TYPE)
|
||||
|
@ -1236,21 +1241,13 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
|
|||
grok_function_init (value, init);
|
||||
init = NULL_TREE;
|
||||
}
|
||||
else if (pedantic)
|
||||
{
|
||||
#if 0
|
||||
/* Already warned in grokdeclarator. */
|
||||
if (DECL_NAME (value))
|
||||
pedwarn ("ANSI C++ forbids initialization of member `%s'",
|
||||
IDENTIFIER_POINTER (DECL_NAME (value)));
|
||||
else
|
||||
pedwarn ("ANSI C++ forbids initialization of fields");
|
||||
#endif
|
||||
init = NULL_TREE;
|
||||
}
|
||||
else if (pedantic && ! TREE_STATIC (value))
|
||||
/* Already complained in grokdeclarator. */
|
||||
init = NULL_TREE;
|
||||
else
|
||||
{
|
||||
/* We allow initializers to become parameters to base initializers. */
|
||||
/* We allow initializers to become parameters to base
|
||||
initializers. */
|
||||
if (TREE_CODE (init) == TREE_LIST)
|
||||
{
|
||||
if (TREE_CHAIN (init) == NULL_TREE)
|
||||
|
@ -1352,8 +1349,6 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
|
|||
}
|
||||
if (TREE_CODE (value) == FUNCTION_DECL)
|
||||
{
|
||||
/* grokdeclarator defers setting this. */
|
||||
TREE_PUBLIC (value) = 1;
|
||||
if (DECL_CHAIN (value) != NULL_TREE)
|
||||
{
|
||||
/* Need a fresh node here so that we don't get circularity
|
||||
|
@ -1368,7 +1363,7 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
|
|||
if (DECL_FRIEND_P (value))
|
||||
return void_type_node;
|
||||
|
||||
if (current_function_decl)
|
||||
if (current_function_decl && ! IS_SIGNATURE (current_class_type))
|
||||
cp_error ("method `%#D' of local class must be defined in class body",
|
||||
value);
|
||||
|
||||
|
@ -2345,7 +2340,8 @@ finish_vtable_vardecl (prev, vars)
|
|||
for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
|
||||
method = DECL_NEXT_METHOD (method))
|
||||
{
|
||||
if (DECL_VINDEX (method) != NULL_TREE && !DECL_SAVED_INSNS (method))
|
||||
if (DECL_VINDEX (method) != NULL_TREE && !DECL_SAVED_INSNS (method)
|
||||
&& !DECL_ABSTRACT_VIRTUAL_P (method))
|
||||
{
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
|
||||
CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
|
||||
|
@ -2376,20 +2372,6 @@ finish_vtable_vardecl (prev, vars)
|
|||
mark_vtable_entries (vars);
|
||||
if (TREE_TYPE (DECL_INITIAL (vars)) == 0)
|
||||
store_init_value (vars, DECL_INITIAL (vars));
|
||||
if (flag_vtable_thunks)
|
||||
{
|
||||
tree list = CONSTRUCTOR_ELTS (DECL_INITIAL (vars));
|
||||
for (; list; list = TREE_CHAIN (list))
|
||||
{
|
||||
tree vfunc = TREE_VALUE (list);
|
||||
if (TREE_CODE (vfunc) == ADDR_EXPR)
|
||||
{
|
||||
vfunc = TREE_OPERAND (vfunc, 0);
|
||||
if (TREE_CODE (vfunc) == THUNK_DECL)
|
||||
emit_thunk (vfunc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
|
@ -2737,6 +2719,12 @@ finish_file ()
|
|||
|
||||
walk_vtables ((void (*)())0, finish_vtable_vardecl);
|
||||
|
||||
for (vars = getdecls (); vars; vars = TREE_CHAIN (vars))
|
||||
{
|
||||
if (TREE_CODE (vars) == THUNK_DECL)
|
||||
emit_thunk (vars);
|
||||
}
|
||||
|
||||
/* Now write out inline functions which had their addresses taken
|
||||
and which were not declared virtual and which were not declared
|
||||
`extern inline'. */
|
||||
|
@ -2752,12 +2740,16 @@ finish_file ()
|
|||
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = CLASSTYPE_INTERFACE_ONLY (ctype);
|
||||
DECL_EXTERNAL (decl)
|
||||
= (CLASSTYPE_INTERFACE_ONLY (ctype)
|
||||
|| (DECL_INLINE (decl) && ! flag_implement_inlines));
|
||||
}
|
||||
}
|
||||
if (TREE_PUBLIC (decl) || TREE_ADDRESSABLE (decl))
|
||||
{
|
||||
if (DECL_EXTERNAL (decl))
|
||||
if (DECL_EXTERNAL (decl)
|
||||
|| (DECL_IMPLICIT_INSTANTIATION (decl)
|
||||
&& ! flag_implicit_templates))
|
||||
assemble_external (decl);
|
||||
else
|
||||
{
|
||||
|
|
|
@ -837,25 +837,25 @@ dump_char (c)
|
|||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
case TARGET_NEWLINE:
|
||||
OB_PUTS ("\\n");
|
||||
break;
|
||||
case '\t':
|
||||
case TARGET_TAB:
|
||||
OB_PUTS ("\\t");
|
||||
break;
|
||||
case '\v':
|
||||
case TARGET_VT:
|
||||
OB_PUTS ("\\v");
|
||||
break;
|
||||
case '\b':
|
||||
case TARGET_BS:
|
||||
OB_PUTS ("\\b");
|
||||
break;
|
||||
case '\r':
|
||||
case TARGET_CR:
|
||||
OB_PUTS ("\\r");
|
||||
break;
|
||||
case '\f':
|
||||
case TARGET_FF:
|
||||
OB_PUTS ("\\f");
|
||||
break;
|
||||
case '\a':
|
||||
case TARGET_BELL:
|
||||
OB_PUTS ("\\a");
|
||||
break;
|
||||
case '\\':
|
||||
|
|
|
@ -1866,7 +1866,7 @@ build_member_call (cname, name, parmlist)
|
|||
{
|
||||
tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),
|
||||
TYPE_VOLATILE (oldtype));
|
||||
decl = convert_force (TYPE_POINTER_TO (newtype), olddecl);
|
||||
decl = convert_force (build_pointer_type (newtype), olddecl);
|
||||
}
|
||||
else
|
||||
decl = olddecl;
|
||||
|
|
16
gcc/cp/lex.c
16
gcc/cp/lex.c
|
@ -1936,15 +1936,17 @@ default_assign_ref_body (bufp, lenp, type, fields)
|
|||
name = TYPE_NESTED_NAME (btype);
|
||||
s = IDENTIFIER_POINTER (name);
|
||||
|
||||
tneed = (2 * strlen (s)) + 33;
|
||||
tneed = (2 * strlen (s)) + 42;
|
||||
if (tgot < tneed)
|
||||
{
|
||||
tgot = tneed;
|
||||
tbuf = (char *) alloca (tgot);
|
||||
}
|
||||
|
||||
sprintf (tbuf, "%s::operator=((%s%s&)_ctor_arg);", s,
|
||||
TYPE_READONLY (type) ? "const " : "", s);
|
||||
sprintf (tbuf, "%s::operator=((%s%s ::%s&)_ctor_arg);", s,
|
||||
TYPE_READONLY (type) ? "const " : "",
|
||||
CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
|
||||
s);
|
||||
obstack_grow (&body, tbuf, strlen (tbuf));
|
||||
}
|
||||
}
|
||||
|
@ -2101,15 +2103,17 @@ default_copy_constructor_body (bufp, lenp, type, fields)
|
|||
name = TYPE_NESTED_NAME (btype);
|
||||
s = IDENTIFIER_POINTER (name);
|
||||
|
||||
tneed = (2 * strlen (s)) + 30;
|
||||
tneed = (2 * strlen (s)) + 39;
|
||||
if (tgot < tneed)
|
||||
{
|
||||
tgot = tneed;
|
||||
tbuf = (char *) alloca (tgot);
|
||||
}
|
||||
|
||||
sprintf (tbuf, "%c%s((%s%s&)_ctor_arg)", sep, s,
|
||||
TYPE_READONLY (type) ? "const " : "", s);
|
||||
sprintf (tbuf, "%c%s((%s%s ::%s&)_ctor_arg)", sep, s,
|
||||
TYPE_READONLY (type) ? "const " : "",
|
||||
CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
|
||||
s);
|
||||
sep = ',';
|
||||
obstack_grow (&prologue, tbuf, strlen (tbuf));
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ extern char *token_buffer; /* Pointer to token buffer. */
|
|||
|
||||
/* Back-door communication channel to the lexer. */
|
||||
extern int looking_for_typename;
|
||||
extern int looking_for_template;
|
||||
|
||||
/* Tell the lexer where to look for names. */
|
||||
extern tree got_scope;
|
||||
|
|
|
@ -938,7 +938,9 @@ build_typename_overload (type)
|
|||
build_overload_name (type, 0, 1);
|
||||
id = get_identifier (obstack_base (&scratch_obstack));
|
||||
IDENTIFIER_OPNAME_P (id) = 1;
|
||||
#if 0
|
||||
IDENTIFIER_GLOBAL_VALUE (id) = TYPE_NAME (type);
|
||||
#endif
|
||||
TREE_TYPE (id) = type;
|
||||
return id;
|
||||
}
|
||||
|
@ -1676,8 +1678,9 @@ make_thunk (function, delta)
|
|||
int delta;
|
||||
{
|
||||
char buffer[250];
|
||||
tree thunk_fndecl;
|
||||
tree thunk_fndecl, thunk_id;
|
||||
tree thunk;
|
||||
char *func_name;
|
||||
static int thunk_number = 0;
|
||||
tree func_decl;
|
||||
if (TREE_CODE (function) != ADDR_EXPR)
|
||||
|
@ -1685,14 +1688,26 @@ make_thunk (function, delta)
|
|||
func_decl = TREE_OPERAND (function, 0);
|
||||
if (TREE_CODE (func_decl) != FUNCTION_DECL)
|
||||
abort ();
|
||||
sprintf (buffer, "__thunk_%d_%d", -delta, thunk_number++);
|
||||
thunk = build_decl (THUNK_DECL, get_identifier (buffer),
|
||||
TREE_TYPE (func_decl));
|
||||
DECL_RESULT (thunk)
|
||||
= build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (vtable_entry_type));
|
||||
make_function_rtl (thunk);
|
||||
DECL_INITIAL (thunk) = function;
|
||||
THUNK_DELTA (thunk) = delta;
|
||||
func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));
|
||||
sprintf (buffer, "__thunk_%d_%s", -delta, func_name);
|
||||
thunk_id = get_identifier (buffer);
|
||||
thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
|
||||
if (thunk && TREE_CODE (thunk) != THUNK_DECL)
|
||||
{
|
||||
error_with_decl ("implementation-reserved name `%s' used");
|
||||
IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
|
||||
}
|
||||
if (thunk == NULL_TREE)
|
||||
{
|
||||
thunk = build_decl (THUNK_DECL, thunk_id, TREE_TYPE (func_decl));
|
||||
DECL_RESULT (thunk)
|
||||
= build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (vtable_entry_type));
|
||||
make_function_rtl (thunk);
|
||||
DECL_INITIAL (thunk) = function;
|
||||
THUNK_DELTA (thunk) = delta;
|
||||
/* So that finish_file can write out any thunks that need to be: */
|
||||
pushdecl_top_level (thunk);
|
||||
}
|
||||
return thunk;
|
||||
}
|
||||
|
||||
|
@ -1725,6 +1740,19 @@ emit_thunk (thunk_fndecl)
|
|||
if (TREE_ASM_WRITTEN (thunk_fndecl))
|
||||
return;
|
||||
|
||||
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
|
||||
|
||||
if (TREE_PUBLIC (function))
|
||||
{
|
||||
TREE_PUBLIC (thunk_fndecl) = 1;
|
||||
if (DECL_EXTERNAL (function))
|
||||
{
|
||||
DECL_EXTERNAL (thunk_fndecl) = 1;
|
||||
assemble_external (thunk_fndecl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
decl_printable_name = thunk_printable_name;
|
||||
if (current_function_decl)
|
||||
abort ();
|
||||
|
@ -1833,8 +1861,6 @@ emit_thunk (thunk_fndecl)
|
|||
expand_end_bindings (NULL, 1, 0);
|
||||
poplevel (0, 0, 0);
|
||||
|
||||
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
|
||||
|
||||
/* From now on, allocate rtl in current_obstack, not in saveable_obstack.
|
||||
Note that that may have been done above, in save_for_inline_copying.
|
||||
The call to resume_temporary_allocation near the end of this function
|
||||
|
@ -1848,10 +1874,6 @@ emit_thunk (thunk_fndecl)
|
|||
|
||||
unshare_all_rtl (insns);
|
||||
|
||||
/* Instantiate all virtual registers. */
|
||||
|
||||
instantiate_virtual_regs (current_function_decl, get_insns ());
|
||||
|
||||
/* We are no longer anticipating cse in this function, at least. */
|
||||
|
||||
cse_not_expected = 1;
|
||||
|
|
|
@ -543,11 +543,12 @@ datadef:
|
|||
&& TREE_PURPOSE (t) == NULL_TREE)
|
||||
{
|
||||
t = TREE_VALUE (t);
|
||||
if (TREE_CODE (t) == RECORD_TYPE)
|
||||
if (IS_AGGR_TYPE (t)
|
||||
&& IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (t)))
|
||||
{
|
||||
if (CLASSTYPE_USE_TEMPLATE (t) == 0)
|
||||
CLASSTYPE_USE_TEMPLATE (t) = 2;
|
||||
else if (CLASSTYPE_USE_TEMPLATE (t) == 1)
|
||||
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
|
||||
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
|
||||
error ("override declaration for already-expanded template");
|
||||
}
|
||||
}
|
||||
|
@ -2914,14 +2915,18 @@ absdcl:
|
|||
{ $$ = make_pointer_declarator ($2, $3); }
|
||||
| '*' absdcl
|
||||
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
|
||||
| '*' type_quals %prec EMPTY
|
||||
| '*' nonempty_type_quals %prec EMPTY
|
||||
{ $$ = make_pointer_declarator ($2, NULL_TREE); }
|
||||
| '*' %prec EMPTY
|
||||
{ $$ = make_pointer_declarator (NULL_TREE, NULL_TREE); }
|
||||
| '&' nonempty_type_quals absdcl
|
||||
{ $$ = make_reference_declarator ($2, $3); }
|
||||
| '&' absdcl
|
||||
{ $$ = make_reference_declarator (NULL_TREE, $2); }
|
||||
| '&' type_quals %prec EMPTY
|
||||
| '&' nonempty_type_quals %prec EMPTY
|
||||
{ $$ = make_reference_declarator ($2, NULL_TREE); }
|
||||
| '&' %prec EMPTY
|
||||
{ $$ = make_reference_declarator (NULL_TREE, NULL_TREE); }
|
||||
| ptr_to_mem type_quals %prec EMPTY
|
||||
{ tree arg = make_pointer_declarator ($2, NULL_TREE);
|
||||
$$ = build_parse_node (SCOPE_REF, $1, arg);
|
||||
|
|
50
gcc/cp/pt.c
50
gcc/cp/pt.c
|
@ -116,7 +116,7 @@ process_template_parm (list, next)
|
|||
else
|
||||
{
|
||||
tree t = make_node (TEMPLATE_TYPE_PARM);
|
||||
decl = build_lang_decl (TYPE_DECL, TREE_PURPOSE (parm), t);
|
||||
decl = build_decl (TYPE_DECL, TREE_PURPOSE (parm), t);
|
||||
TYPE_NAME (t) = decl;
|
||||
TREE_VALUE (parm) = t;
|
||||
}
|
||||
|
@ -581,7 +581,7 @@ lookup_template_class (d1, arglist, in_decl)
|
|||
tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
|
||||
tree d;
|
||||
id = make_anon_name ();
|
||||
d = build_lang_decl (TYPE_DECL, id, t);
|
||||
d = build_decl (TYPE_DECL, id, t);
|
||||
TYPE_NAME (t) = d;
|
||||
TYPE_VALUES (t) = build_tree_list (template, arglist);
|
||||
pushdecl_top_level (d);
|
||||
|
@ -635,7 +635,7 @@ push_template_decls (parmlist, arglist, class_level)
|
|||
}
|
||||
decl = arg;
|
||||
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 't', 273);
|
||||
decl = build_lang_decl (TYPE_DECL, parm, decl);
|
||||
decl = build_decl (TYPE_DECL, parm, decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -987,7 +987,7 @@ instantiate_class_template (classname, setup_parse)
|
|||
if (!TREE_TYPE (classname))
|
||||
{
|
||||
tree t = make_lang_type (RECORD_TYPE);
|
||||
tree d = build_lang_decl (TYPE_DECL, classname, t);
|
||||
tree d = build_decl (TYPE_DECL, classname, t);
|
||||
DECL_NAME (d) = classname;
|
||||
TYPE_NAME (t) = d;
|
||||
pushdecl (d);
|
||||
|
@ -1320,7 +1320,7 @@ tsubst (t, args, nargs, in_decl)
|
|||
tree decls;
|
||||
int got_it = 0;
|
||||
|
||||
decls = lookup_name (r, 0);
|
||||
decls = lookup_name_nonclass (r);
|
||||
if (decls == NULL_TREE)
|
||||
/* no match */;
|
||||
else if (TREE_CODE (decls) == TREE_LIST)
|
||||
|
@ -1645,11 +1645,18 @@ instantiate_template (tmpl, targ_ptr)
|
|||
DECL_ARGUMENTS (fndecl) = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
|
||||
}
|
||||
|
||||
t = DECL_TEMPLATE_INFO (tmpl);
|
||||
|
||||
/* If we have a preexisting version of this function, don't expand
|
||||
the template version, use the other instead. */
|
||||
t = DECL_TEMPLATE_INFO (tmpl);
|
||||
if (t->text && !(DECL_INLINE (fndecl) && DECL_SAVED_INSNS (fndecl)))
|
||||
if (DECL_INLINE (fndecl) && DECL_SAVED_INSNS (fndecl))
|
||||
{
|
||||
SET_DECL_TEMPLATE_SPECIALIZATION (fndecl);
|
||||
p = (struct pending_inline *)0;
|
||||
}
|
||||
else if (t->text)
|
||||
{
|
||||
SET_DECL_IMPLICIT_INSTANTIATION (fndecl);
|
||||
p = (struct pending_inline *) permalloc (sizeof (struct pending_inline));
|
||||
p->parm_vec = t->parm_vec;
|
||||
p->bindings = targs;
|
||||
|
@ -1819,7 +1826,7 @@ end_template_instantiation (name)
|
|||
my_friendly_assert (t != NULL_TREE
|
||||
&& TREE_CODE_CLASS (TREE_CODE (t)) == 't',
|
||||
287);
|
||||
CLASSTYPE_USE_TEMPLATE (t) = 2;
|
||||
SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
|
||||
/* Make methods of template classes static, unless
|
||||
-fexternal-templates is given. */
|
||||
if (!flag_external_templates)
|
||||
|
@ -2227,8 +2234,10 @@ do_pending_expansions ()
|
|||
if (TREE_ASM_WRITTEN (t))
|
||||
DECIDE (0);
|
||||
|
||||
if (DECL_EXPLICITLY_INSTANTIATED (t))
|
||||
if (DECL_EXPLICIT_INSTANTIATION (t))
|
||||
DECIDE (1);
|
||||
else if (! flag_implicit_templates)
|
||||
DECIDE (0);
|
||||
|
||||
/* If it's a method, let the class type decide it.
|
||||
@@ What if the method template is in a separate file?
|
||||
|
@ -2357,7 +2366,12 @@ do_function_instantiation (declspecs, declarator)
|
|||
if (! result)
|
||||
cp_error ("no matching template for `%D' found", decl);
|
||||
|
||||
DECL_EXPLICITLY_INSTANTIATED (result) = 1;
|
||||
if (flag_external_templates)
|
||||
return;
|
||||
|
||||
SET_DECL_EXPLICIT_INSTANTIATION (result);
|
||||
TREE_PUBLIC (result) = 1;
|
||||
DECL_EXTERNAL (result) = DECL_INLINE (result) && ! flag_implement_inlines;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2366,14 +2380,24 @@ do_type_instantiation (name)
|
|||
{
|
||||
tree t = TREE_TYPE (name);
|
||||
|
||||
CLASSTYPE_EXPLICITLY_INSTANTIATED (t) = 1;
|
||||
if (flag_external_templates)
|
||||
return;
|
||||
|
||||
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1;
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (t);
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = 0;
|
||||
|
||||
/* this should really be done by instantiate_member_templates */
|
||||
{
|
||||
tree method = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
|
||||
for (; method; method = TREE_CHAIN (method))
|
||||
DECL_EXPLICITLY_INSTANTIATED (method) = 1;
|
||||
{
|
||||
SET_DECL_EXPLICIT_INSTANTIATION (method);
|
||||
TREE_PUBLIC (method) = 1;
|
||||
DECL_EXTERNAL (method) = (DECL_INLINE (method)
|
||||
&& ! flag_implement_inlines);
|
||||
}
|
||||
}
|
||||
|
||||
/* and data member templates, too */
|
||||
|
@ -2384,7 +2408,7 @@ create_nested_upt (scope, name)
|
|||
tree scope, name;
|
||||
{
|
||||
tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
|
||||
tree d = build_lang_decl (TYPE_DECL, name, t);
|
||||
tree d = build_decl (TYPE_DECL, name, t);
|
||||
|
||||
TYPE_NAME (t) = d;
|
||||
TYPE_VALUES (t) = TYPE_VALUES (scope);
|
||||
|
|
|
@ -512,8 +512,8 @@ build_signature_table_constructor (sig_ty, rhs)
|
|||
{
|
||||
if (! IS_DEFAULT_IMPLEMENTATION (sig_method))
|
||||
{
|
||||
cp_error ("class `%T' does not contain method `%s'",
|
||||
rhstype, (int) IDENTIFIER_POINTER (sig_mname));
|
||||
cp_error ("class `%T' does not contain method `%D'",
|
||||
rhstype, sig_mname);
|
||||
undo_casts (sig_ty);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
|
|
@ -236,6 +236,7 @@ probe_obstack (h, obj, nlevels)
|
|||
a typename (when it may be a local variable or a class variable).
|
||||
Value is 0 if we treat this name in a default fashion. */
|
||||
extern int looking_for_typename;
|
||||
int looking_for_template;
|
||||
|
||||
extern struct obstack *current_obstack, *saveable_obstack;
|
||||
tree got_scope;
|
||||
|
@ -298,6 +299,8 @@ yylex()
|
|||
if (nth_token (1)->yychar == SCOPE)
|
||||
/* Don't interfere with the setting from an 'aggr' prefix. */
|
||||
looking_for_typename++;
|
||||
else if (nth_token (1)->yychar == '<')
|
||||
looking_for_template = 1;
|
||||
|
||||
trrr = lookup_name (tmp_token.yylval.ttype, -2);
|
||||
|
||||
|
@ -334,6 +337,7 @@ yylex()
|
|||
consume_token ();
|
||||
if (looking_for_typename > 0)
|
||||
looking_for_typename--;
|
||||
looking_for_template = 0;
|
||||
break;
|
||||
|
||||
case SCSPEC:
|
||||
|
|
|
@ -860,7 +860,7 @@ list_hash_add (hashcode, list)
|
|||
This function frees the list you pass in if it is a duplicate. */
|
||||
|
||||
/* Set to 1 to debug without canonicalization. Never set by program. */
|
||||
int debug_no_list_hash = 0;
|
||||
static int debug_no_list_hash = 0;
|
||||
|
||||
tree
|
||||
list_hash_canon (hashcode, list)
|
||||
|
|
232
gcc/cp/typeck.c
232
gcc/cp/typeck.c
|
@ -542,7 +542,9 @@ comp_array_types (cmp, t1, t2, strict)
|
|||
2 : strict, except that if one type is a reference and
|
||||
the other is not, compare the target type of the
|
||||
reference to the type that's not a reference (ARM, p308).
|
||||
This is used for checking for illegal overloading.
|
||||
1 : strict (compared according to ANSI C)
|
||||
This is used for checking whether two function decls match.
|
||||
0 : <= (compared according to C++)
|
||||
-1: <= or >= (relaxed)
|
||||
|
||||
|
@ -608,7 +610,7 @@ comptypes (type1, type2, strict)
|
|||
|
||||
if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
|
||||
return 0;
|
||||
if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
|
||||
if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
|
||||
return 0;
|
||||
|
||||
/* Allow for two different type nodes which have essentially the same
|
||||
|
@ -739,7 +741,13 @@ comp_target_types (ttl, ttr, nptrs)
|
|||
return 0;
|
||||
|
||||
if (TREE_CODE (ttr) == POINTER_TYPE)
|
||||
return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs - 1);
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (ttl)) == POINTER_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (ttl)) == ARRAY_TYPE)
|
||||
return comp_ptr_ttypes (TREE_TYPE (ttl), TREE_TYPE (ttr));
|
||||
else
|
||||
return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs - 1);
|
||||
}
|
||||
|
||||
if (TREE_CODE (ttr) == REFERENCE_TYPE)
|
||||
return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs);
|
||||
|
@ -2425,12 +2433,9 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
|
|||
called_thing = "constructor";
|
||||
else
|
||||
called_thing = "member function";
|
||||
i -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
called_thing = "function";
|
||||
}
|
||||
called_thing = "function";
|
||||
}
|
||||
|
||||
for (valtail = values, typetail = typelist;
|
||||
|
@ -2510,7 +2515,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
|
|||
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
||||
Strip such NOP_EXPRs, since VAL is used in non-lvalue context. */
|
||||
if (TREE_CODE (val) == NOP_EXPR
|
||||
&& TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0)))
|
||||
&& TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
|
||||
&& (type == 0 || TREE_CODE (type) != REFERENCE_TYPE))
|
||||
val = TREE_OPERAND (val, 0);
|
||||
|
||||
if ((type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
|
||||
|
@ -2886,6 +2892,17 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
|
|||
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
|
||||
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
|
||||
{
|
||||
if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
|
||||
{
|
||||
error ("division by zero");
|
||||
op1 = integer_one_node;
|
||||
}
|
||||
else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
|
||||
{
|
||||
error ("division by zero");
|
||||
op1 = build_real (TREE_TYPE (op1), dconst1);
|
||||
}
|
||||
|
||||
if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
|
||||
resultcode = RDIV_EXPR;
|
||||
else
|
||||
|
@ -2936,6 +2953,17 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
|
|||
|
||||
case TRUNC_MOD_EXPR:
|
||||
case FLOOR_MOD_EXPR:
|
||||
if (code1 == INTEGER_TYPE && integer_zerop (op1))
|
||||
{
|
||||
error ("division by zero");
|
||||
op1 = integer_one_node;
|
||||
}
|
||||
else if (code1 == REAL_TYPE && real_zerop (op1))
|
||||
{
|
||||
error ("division by zero");
|
||||
op1 = build_real (TREE_TYPE (op1), dconst1);
|
||||
}
|
||||
|
||||
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
|
||||
{
|
||||
/* Although it would be tempting to shorten always here, that loses
|
||||
|
@ -4001,17 +4029,15 @@ build_unary_op (code, xarg, noconvert)
|
|||
TREE_REFERENCE_EXPR (arg) = 1;
|
||||
return arg;
|
||||
}
|
||||
else if (TREE_CODE (arg) == FUNCTION_DECL
|
||||
else if (pedantic
|
||||
&& TREE_CODE (arg) == FUNCTION_DECL
|
||||
&& DECL_NAME (arg)
|
||||
&& DECL_CONTEXT (arg) == NULL_TREE
|
||||
&& IDENTIFIER_LENGTH (DECL_NAME (arg)) == 4
|
||||
&& IDENTIFIER_POINTER (DECL_NAME (arg))[0] == 'm'
|
||||
&& ! strcmp (IDENTIFIER_POINTER (DECL_NAME (arg)), "main"))
|
||||
{
|
||||
/* ARM $3.4 */
|
||||
error ("attempt to take address of function `main'");
|
||||
return error_mark_node;
|
||||
}
|
||||
/* ARM $3.4 */
|
||||
pedwarn ("taking address of function `main'");
|
||||
|
||||
/* Let &* cancel out to simplify resulting code. */
|
||||
if (TREE_CODE (arg) == INDIRECT_REF)
|
||||
|
@ -4911,6 +4937,13 @@ build_c_cast (type, expr)
|
|||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == FUNCTION_TYPE
|
||||
|| TREE_CODE (type) == METHOD_TYPE)
|
||||
{
|
||||
cp_error ("casting to function type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (IS_SIGNATURE (type))
|
||||
{
|
||||
error ("cast specifies signature type");
|
||||
|
@ -5396,6 +5429,33 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (lhs) == OFFSET_REF)
|
||||
{
|
||||
if (TREE_OPERAND (lhs, 0) == NULL_TREE)
|
||||
{
|
||||
/* Static class member? */
|
||||
tree member = TREE_OPERAND (lhs, 1);
|
||||
if (TREE_CODE (member) == VAR_DECL)
|
||||
lhs = member;
|
||||
else
|
||||
{
|
||||
compiler_error ("invalid static class member");
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
lhs = resolve_offset_ref (lhs);
|
||||
|
||||
olhstype = lhstype = TREE_TYPE (lhs);
|
||||
}
|
||||
|
||||
if (TREE_CODE (lhstype) == REFERENCE_TYPE
|
||||
&& modifycode != INIT_EXPR)
|
||||
{
|
||||
lhs = convert_from_reference (lhs);
|
||||
olhstype = lhstype = TREE_TYPE (lhs);
|
||||
}
|
||||
|
||||
/* If a binary op has been requested, combine the old LHS value with the RHS
|
||||
producing the value we should actually store into the LHS. */
|
||||
|
||||
|
@ -5413,9 +5473,6 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
}
|
||||
else if (modifycode == NOP_EXPR)
|
||||
{
|
||||
/* must deal with overloading of `operator=' here. */
|
||||
if (TREE_CODE (lhstype) == REFERENCE_TYPE)
|
||||
lhstype = TREE_TYPE (lhstype);
|
||||
#if 1
|
||||
/* `operator=' is not an inheritable operator. */
|
||||
if (TYPE_LANG_SPECIFIC (lhstype) && TYPE_HAS_ASSIGNMENT (lhstype))
|
||||
|
@ -5490,7 +5547,6 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
newrhs = build_binary_op (modifycode, lhs, rhs, 1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Handle a cast used as an "lvalue".
|
||||
We have already performed any binary operator using the value as cast.
|
||||
Now convert the result to the cast type of the lhs,
|
||||
|
@ -5515,6 +5571,9 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
{
|
||||
tree inner_lhs = TREE_OPERAND (lhs, 0);
|
||||
tree result;
|
||||
if (! lvalue_p (lhs) && pedantic)
|
||||
pedwarn ("cast to non-reference type used as lvalue");
|
||||
|
||||
result = build_modify_expr (inner_lhs, NOP_EXPR,
|
||||
convert (TREE_TYPE (inner_lhs),
|
||||
convert (lhstype, newrhs)));
|
||||
|
@ -5523,25 +5582,6 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
return convert_force (TREE_TYPE (lhs), result);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TREE_CODE (lhs) == OFFSET_REF)
|
||||
{
|
||||
if (TREE_OPERAND (lhs, 0) == NULL_TREE)
|
||||
{
|
||||
/* Static class member? */
|
||||
tree member = TREE_OPERAND (lhs, 1);
|
||||
if (TREE_CODE (member) == VAR_DECL)
|
||||
lhs = member;
|
||||
else
|
||||
{
|
||||
compiler_error ("invalid static class member");
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
lhs = resolve_offset_ref (lhs);
|
||||
}
|
||||
|
||||
/* Now we have handled acceptable kinds of LHS that are not truly lvalues.
|
||||
Reject anything strange now. */
|
||||
|
@ -5576,7 +5616,18 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
&& (TREE_CODE (lhstype) == INTEGER_TYPE
|
||||
|| TREE_CODE (lhstype) == REAL_TYPE
|
||||
|| TREE_CODE (lhstype) == ENUMERAL_TYPE))
|
||||
lhstype = TREE_TYPE (get_unwidened (lhs, 0));
|
||||
{
|
||||
lhstype = TREE_TYPE (get_unwidened (lhs, 0));
|
||||
|
||||
/* If storing in a field that is in actuality a short or narrower
|
||||
than one, we must store in the field in its actual type. */
|
||||
|
||||
if (lhstype != TREE_TYPE (lhs))
|
||||
{
|
||||
lhs = copy_node (lhs);
|
||||
TREE_TYPE (lhs) = lhstype;
|
||||
}
|
||||
}
|
||||
|
||||
/* check to see if there is an assignment to `this' */
|
||||
if (lhs == current_class_decl)
|
||||
|
@ -5734,15 +5785,6 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* If storing in a field that is in actuality a short or narrower than one,
|
||||
we must store in the field in its actual type. */
|
||||
|
||||
if (lhstype != TREE_TYPE (lhs))
|
||||
{
|
||||
lhs = copy_node (lhs);
|
||||
TREE_TYPE (lhs) = lhstype;
|
||||
}
|
||||
|
||||
/* Convert new value to destination type. */
|
||||
|
||||
if (TREE_CODE (lhstype) == ARRAY_TYPE)
|
||||
|
@ -6081,6 +6123,14 @@ build_ptrmemfunc (type, pfn, force)
|
|||
return digest_init (TYPE_GET_PTRMEMFUNC_TYPE (type), u, (tree*)0);
|
||||
}
|
||||
|
||||
if (TREE_CODE (pfn) == TREE_LIST)
|
||||
{
|
||||
pfn = instantiate_type (type, pfn, 1);
|
||||
if (pfn == error_mark_node)
|
||||
return error_mark_node;
|
||||
pfn = build_unary_op (ADDR_EXPR, pfn, 0);
|
||||
}
|
||||
|
||||
/* Allow pointer to member conversions here. */
|
||||
delta = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (pfn))),
|
||||
TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
|
||||
|
@ -6399,45 +6449,63 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
|
|||
}
|
||||
else
|
||||
{
|
||||
int const_parity = TYPE_READONLY (type) ^ TYPE_READONLY (rhstype);
|
||||
int volatile_parity = TYPE_VOLATILE (type) ^ TYPE_VOLATILE (rhstype);
|
||||
int add_quals = 0, const_parity = 0, volatile_parity = 0;
|
||||
int left_const = 1;
|
||||
int unsigned_parity;
|
||||
int nptrs = 0;
|
||||
|
||||
while (TREE_CODE (ttl) == POINTER_TYPE
|
||||
&& TREE_CODE (ttr) == POINTER_TYPE)
|
||||
/* This code is basically a duplicate of comp_ptr_ttypes_real. */
|
||||
for (; ; ttl = TREE_TYPE (ttl), ttr = TREE_TYPE (ttr))
|
||||
{
|
||||
nptrs -= 1;
|
||||
const_parity |= TYPE_READONLY (ttl) ^ TYPE_READONLY (ttr);
|
||||
volatile_parity |= TYPE_VOLATILE (ttl) ^ TYPE_VOLATILE (ttr);
|
||||
ttl = TREE_TYPE (ttl);
|
||||
ttr = TREE_TYPE (ttr);
|
||||
const_parity |= TYPE_READONLY (ttl) < TYPE_READONLY (ttr);
|
||||
volatile_parity |= TYPE_VOLATILE (ttl) < TYPE_VOLATILE (ttr);
|
||||
|
||||
if (! left_const
|
||||
&& (TYPE_READONLY (ttl) > TYPE_READONLY (ttr)
|
||||
|| TYPE_VOLATILE (ttl) > TYPE_VOLATILE (ttr)))
|
||||
add_quals = 1;
|
||||
left_const &= TYPE_READONLY (ttl);
|
||||
|
||||
if (TREE_CODE (ttl) != POINTER_TYPE)
|
||||
break;
|
||||
}
|
||||
unsigned_parity = TREE_UNSIGNED (ttl) - TREE_UNSIGNED (ttr);
|
||||
if (unsigned_parity)
|
||||
if (TREE_UNSIGNED (ttl))
|
||||
ttr = unsigned_type (ttr);
|
||||
else
|
||||
ttl = unsigned_type (ttl);
|
||||
{
|
||||
if (TREE_UNSIGNED (ttl))
|
||||
ttr = unsigned_type (ttr);
|
||||
else
|
||||
ttl = unsigned_type (ttl);
|
||||
}
|
||||
|
||||
if (comp_target_types (ttl, ttr, nptrs))
|
||||
{
|
||||
if (add_quals)
|
||||
{
|
||||
if (fndecl)
|
||||
cp_pedwarn ("passing `%T' as argument %P of `%D' adds cv-quals without intervening `const'",
|
||||
rhstype, parmnum, fndecl);
|
||||
else
|
||||
cp_pedwarn ("%s to `%T' from `%T' adds cv-quals without intervening `const'",
|
||||
errtype, type, rhstype);
|
||||
}
|
||||
if (const_parity)
|
||||
{
|
||||
if (fndecl)
|
||||
cp_warning ("passing `%T' as argument %P of `%D' discards const",
|
||||
cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
|
||||
rhstype, parmnum, fndecl);
|
||||
else
|
||||
cp_warning ("%s to `%T' from `%T' discards const",
|
||||
cp_pedwarn ("%s to `%T' from `%T' discards const",
|
||||
errtype, type, rhstype);
|
||||
}
|
||||
if (volatile_parity)
|
||||
{
|
||||
if (fndecl)
|
||||
cp_warning ("passing `%T' as argument %P of `%D' discards volatile",
|
||||
cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
|
||||
rhstype, parmnum, fndecl);
|
||||
else
|
||||
cp_warning ("%s to `%T' from `%T' discards volatile",
|
||||
cp_pedwarn ("%s to `%T' from `%T' discards volatile",
|
||||
errtype, type, rhstype);
|
||||
}
|
||||
if (unsigned_parity > 0)
|
||||
|
@ -6591,7 +6659,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
|
|||
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
||||
Strip such NOP_EXPRs, since RHS is used in non-lvalue context. */
|
||||
if (TREE_CODE (rhs) == NOP_EXPR
|
||||
&& TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0)))
|
||||
&& TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
|
||||
&& codel != REFERENCE_TYPE)
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
|
||||
if (rhs == error_mark_node
|
||||
|
@ -7143,3 +7212,40 @@ c_expand_start_case (exp)
|
|||
|
||||
return exp;
|
||||
}
|
||||
|
||||
/* CONSTP remembers whether or not all the intervening pointers in the `to'
|
||||
type have been const. */
|
||||
int
|
||||
comp_ptr_ttypes_real (to, from, constp)
|
||||
tree to, from;
|
||||
int constp;
|
||||
{
|
||||
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
|
||||
{
|
||||
if (TREE_CODE (to) != TREE_CODE (from))
|
||||
return 0;
|
||||
|
||||
if (TYPE_READONLY (from) > TYPE_READONLY (to)
|
||||
|| TYPE_VOLATILE (from) > TYPE_VOLATILE (to))
|
||||
return 0;
|
||||
|
||||
if (! constp
|
||||
&& (TYPE_READONLY (to) > TYPE_READONLY (from)
|
||||
|| TYPE_VOLATILE (to) > TYPE_READONLY (from)))
|
||||
return 0;
|
||||
constp &= TYPE_READONLY (to);
|
||||
|
||||
if (TREE_CODE (to) != POINTER_TYPE)
|
||||
return comptypes (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* When comparing, say, char ** to char const **, this function takes the
|
||||
'char *' and 'char const *'. Do not pass non-pointer types to this
|
||||
function. */
|
||||
int
|
||||
comp_ptr_ttypes (to, from)
|
||||
tree to, from;
|
||||
{
|
||||
return comp_ptr_ttypes_real (to, from, 1);
|
||||
}
|
||||
|
|
135
gcc/cp/typeck2.c
135
gcc/cp/typeck2.c
|
@ -655,6 +655,7 @@ digest_init (type, init, tail)
|
|||
&& ((TREE_CODE (init) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_TYPE (init)) == POINTER_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (TREE_TYPE (init))) == METHOD_TYPE)
|
||||
|| TREE_CODE (init) == TREE_LIST
|
||||
|| integer_zerop (init)
|
||||
|| (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init)))))
|
||||
{
|
||||
|
@ -1237,6 +1238,12 @@ build_x_arrow (datum)
|
|||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (rval) == OFFSET_REF)
|
||||
{
|
||||
rval = resolve_offset_ref (datum);
|
||||
type = TREE_TYPE (rval);
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
rval = convert_from_reference (rval);
|
||||
|
@ -1268,7 +1275,6 @@ build_x_arrow (datum)
|
|||
else
|
||||
last_rval = default_conversion (rval);
|
||||
|
||||
more:
|
||||
/* Signature pointers are not dereferenced. */
|
||||
if (TYPE_LANG_SPECIFIC (TREE_TYPE (last_rval))
|
||||
&& IS_SIGNATURE_POINTER (TREE_TYPE (last_rval)))
|
||||
|
@ -1277,20 +1283,6 @@ build_x_arrow (datum)
|
|||
if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE)
|
||||
return build_indirect_ref (last_rval, NULL_PTR);
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (last_rval)) == OFFSET_TYPE)
|
||||
{
|
||||
if (TREE_CODE (last_rval) == OFFSET_REF
|
||||
&& TREE_STATIC (TREE_OPERAND (last_rval, 1)))
|
||||
{
|
||||
last_rval = TREE_OPERAND (last_rval, 1);
|
||||
if (TREE_CODE (TREE_TYPE (last_rval)) == REFERENCE_TYPE)
|
||||
last_rval = convert_from_reference (last_rval);
|
||||
goto more;
|
||||
}
|
||||
compiler_error ("invalid member type in build_x_arrow");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (types_memoized)
|
||||
error ("result of `operator->()' yields non-pointer result");
|
||||
else
|
||||
|
@ -1372,7 +1364,6 @@ build_functional_cast (exp, parms)
|
|||
or a C cast in C++'s `functional' notation. */
|
||||
tree type, name = NULL_TREE;
|
||||
tree expr_as_ctor = NULL_TREE;
|
||||
tree expr_as_conversion = NULL_TREE;
|
||||
|
||||
if (exp == error_mark_node || parms == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
@ -1423,7 +1414,12 @@ build_functional_cast (exp, parms)
|
|||
/* this must build a C cast */
|
||||
if (parms == NULL_TREE)
|
||||
return build1 (NOP_EXPR, type, integer_zero_node);
|
||||
return build_c_cast (type, build_compound_expr (parms));
|
||||
else if (TREE_CHAIN (parms) != NULL_TREE)
|
||||
{
|
||||
pedwarn ("initializer list being treated as compound expression");
|
||||
parms = build_compound_expr (parms);
|
||||
}
|
||||
return build_c_cast (type, parms);
|
||||
}
|
||||
|
||||
if (TYPE_SIZE (type) == NULL_TREE)
|
||||
|
@ -1433,90 +1429,45 @@ build_functional_cast (exp, parms)
|
|||
}
|
||||
|
||||
if (parms && TREE_CHAIN (parms) == NULL_TREE)
|
||||
expr_as_conversion
|
||||
= build_type_conversion (CONVERT_EXPR, type, TREE_VALUE (parms), 0);
|
||||
|
||||
if (! TYPE_HAS_CONSTRUCTOR (type) && parms != NULL_TREE)
|
||||
{
|
||||
char *msg = 0;
|
||||
return build_c_cast (type, parms);
|
||||
|
||||
if (parms == NULL_TREE)
|
||||
msg = "argument missing in cast to `%T' type";
|
||||
else if (TREE_CHAIN (parms) == NULL_TREE)
|
||||
{
|
||||
if (expr_as_conversion == NULL_TREE)
|
||||
msg = "conversion to type `%T' failed";
|
||||
}
|
||||
else msg = "type `%T' does not have a constructor";
|
||||
expr_as_ctor = build_method_call (NULL_TREE, name, parms,
|
||||
NULL_TREE, LOOKUP_NORMAL);
|
||||
|
||||
if (expr_as_conversion)
|
||||
return expr_as_conversion;
|
||||
if (expr_as_ctor == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
cp_error (msg, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (current_function_decl)
|
||||
return build_cplus_new (type, expr_as_ctor, 0);
|
||||
|
||||
{
|
||||
int flags = LOOKUP_SPECULATIVELY|LOOKUP_NORMAL;
|
||||
register tree parm = TREE_OPERAND (expr_as_ctor, 1);
|
||||
|
||||
if (parms && TREE_CHAIN (parms) == NULL_TREE)
|
||||
flags |= LOOKUP_NO_CONVERSION;
|
||||
|
||||
expr_as_ctor = build_method_call (NULL_TREE, name, parms,
|
||||
NULL_TREE, flags);
|
||||
|
||||
if (expr_as_ctor == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
else if (expr_as_ctor)
|
||||
{
|
||||
if (expr_as_conversion && expr_as_conversion != error_mark_node)
|
||||
{
|
||||
/* ANSI C++ June 5 1992 WP 12.3.2.6.1 */
|
||||
cp_error ("ambiguity between conversion to `%T' and constructor",
|
||||
type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (current_function_decl)
|
||||
return build_cplus_new (type, expr_as_ctor, 0);
|
||||
|
||||
{
|
||||
register tree parm = TREE_OPERAND (expr_as_ctor, 1);
|
||||
|
||||
/* Initializers for static variables and parameters have
|
||||
to handle doing the initialization and cleanup themselves. */
|
||||
my_friendly_assert (TREE_CODE (expr_as_ctor) == CALL_EXPR, 322);
|
||||
/* Initializers for static variables and parameters have
|
||||
to handle doing the initialization and cleanup themselves. */
|
||||
my_friendly_assert (TREE_CODE (expr_as_ctor) == CALL_EXPR, 322);
|
||||
#if 0
|
||||
/* The following assertion fails in cases where we are initializing
|
||||
a static member variable of a particular instance of a template
|
||||
class with a call to a constructor of the given instance, as in:
|
||||
|
||||
TMPL<int> object = TMPL<int>();
|
||||
|
||||
Curiously, the assertion does not fail if we do the same thing
|
||||
for a static member of a non-template class, as in:
|
||||
|
||||
T object = T();
|
||||
|
||||
I can't see why we should care here whether or not the initializer
|
||||
expression involves a call to `new', so for the time being, it
|
||||
seems best to just avoid doing this assertion. */
|
||||
my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)), 323);
|
||||
/* The following assertion fails in cases where we are initializing
|
||||
a static member variable of a particular instance of a template
|
||||
class with a call to a constructor of the given instance, as in:
|
||||
|
||||
TMPL<int> object = TMPL<int>();
|
||||
|
||||
Curiously, the assertion does not fail if we do the same thing
|
||||
for a static member of a non-template class, as in:
|
||||
|
||||
T object = T();
|
||||
|
||||
I can't see why we should care here whether or not the initializer
|
||||
expression involves a call to `new', so for the time being, it
|
||||
seems best to just avoid doing this assertion. */
|
||||
my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)), 323);
|
||||
#endif
|
||||
TREE_VALUE (parm) = NULL_TREE;
|
||||
expr_as_ctor = build_indirect_ref (expr_as_ctor, NULL_PTR);
|
||||
TREE_HAS_CONSTRUCTOR (expr_as_ctor) = 1;
|
||||
}
|
||||
return expr_as_ctor;
|
||||
}
|
||||
|
||||
if (expr_as_conversion)
|
||||
return expr_as_conversion;
|
||||
|
||||
cp_error ("no suitable conversion to `%T' exists", type);
|
||||
return error_mark_node;
|
||||
TREE_VALUE (parm) = NULL_TREE;
|
||||
expr_as_ctor = build_indirect_ref (expr_as_ctor, NULL_PTR);
|
||||
TREE_HAS_CONSTRUCTOR (expr_as_ctor) = 1;
|
||||
}
|
||||
return expr_as_ctor;
|
||||
}
|
||||
|
||||
/* Return the character string for the name that encodes the
|
||||
|
|
Loading…
Reference in New Issue