aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1994-06-03 21:42:31 +0000
committerMike Stump <mrs@gcc.gnu.org>1994-06-03 21:42:31 +0000
commita0a339271ae588299147928769ca073a198d53c7 (patch)
tree2bfb1009d1a11061dfd6aad7e84a40e551c0af50 /gcc/cp
parent5345f91a0be605ab09f2f42abecd1a0fc5083f47 (diff)
downloadgcc-a0a339271ae588299147928769ca073a198d53c7.zip
gcc-a0a339271ae588299147928769ca073a198d53c7.tar.gz
gcc-a0a339271ae588299147928769ca073a198d53c7.tar.bz2
39th Cygnus<->FSF merge
From-SVN: r7439
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog297
-rw-r--r--gcc/cp/Make-lang.in35
-rw-r--r--gcc/cp/Makefile.in2
-rw-r--r--gcc/cp/call.c337
-rw-r--r--gcc/cp/class.c92
-rw-r--r--gcc/cp/cp-tree.h70
-rw-r--r--gcc/cp/cvt.c14
-rw-r--r--gcc/cp/decl.c238
-rw-r--r--gcc/cp/decl2.c60
-rw-r--r--gcc/cp/error.c14
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/lex.c16
-rw-r--r--gcc/cp/lex.h1
-rw-r--r--gcc/cp/method.c52
-rw-r--r--gcc/cp/parse.y15
-rw-r--r--gcc/cp/pt.c50
-rw-r--r--gcc/cp/sig.c4
-rw-r--r--gcc/cp/spew.c4
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/cp/typeck.c232
-rw-r--r--gcc/cp/typeck2.c135
21 files changed, 1080 insertions, 592 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f4b1424..385d239 100644
--- a/gcc/cp/ChangeLog
+++ b/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.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 0bf1b78..b888289 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -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:
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index 120e330..231d1a3 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e957776..6d2b26c 100644
--- a/gcc/cp/call.c
+++ b/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;
-
- if (codel == REFERENCE_TYPE || coder == REFERENCE_TYPE)
- {
- ttl = TYPE_MAIN_VARIANT (type);
-
- if (codel == REFERENCE_TYPE)
- {
- ttl = TREE_TYPE (ttl);
+ /* 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. */
- /* 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;
+ if (codel == RECORD_TYPE && coder == POINTER_TYPE
+ && IS_SIGNATURE_POINTER (type) && IS_SIGNATURE (TREE_TYPE (parmtype)))
+ return ZERO_RETURN (h);
- ttl = TYPE_MAIN_VARIANT (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;
+
+ ttl = TREE_TYPE (type);
+
+ /* 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.
-
- 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 (ttl == intype)
- return ZERO_RETURN (h);
- else
- penalty = 2;
- }
+ if (ttl == intype && penalty == 0)
+ return ZERO_RETURN (h);
+ else
+ penalty = 2;
- if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
- {
- ttl = unsigned_type (ttl);
- intype = unsigned_type (intype);
- penalty += 2;
- }
+ if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
+ {
+ ttl = unsigned_type (ttl);
+ intype = unsigned_type (intype);
+ penalty += 2;
+ }
- ttr = intype;
+ 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 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;
- }
+ 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;
- }
- }
+ /* 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;
+ }
- /* 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;
+ if (comp_target_types (ttl, intype, 1))
+ {
+ if (penalty)
h.code = STD_CODE;
- return h;
- }
-
- if (comp_target_types (ttl, intype, 1))
- {
- if (penalty)
- h.code = STD_CODE;
- h.distance = 0;
- return h;
- }
- }
- }
+ 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++;
}
}
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 4fab523..638fedf 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 061c7f1..7ae511f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 7bfe802..fc8d261 100644
--- a/gcc/cp/cvt.c
+++ b/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)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fd73388..10e9d0e 100644
--- a/gcc/cp/decl.c
+++ b/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));
-
- if (val == val_as_type || prefer_type > 0)
- return val_as_type;
+ return TYPE_NAME (IDENTIFIER_TYPE_VALUE (name));
- 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);
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 55414df..fa05063 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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
{
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 6d2ec7f..f431f6a 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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 '\\':
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1867414..084eebd 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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;
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 595ba82..68f801e 100644
--- a/gcc/cp/lex.c
+++ b/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));
}
diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h
index a9ea60e..3da4635 100644
--- a/gcc/cp/lex.h
+++ b/gcc/cp/lex.h
@@ -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;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index d0b847e..bdc040c 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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;
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 30e076c..cb2046d 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 997941c..36248be 100644
--- a/gcc/cp/pt.c
+++ b/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);
diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c
index 979d7aa..cd2eead 100644
--- a/gcc/cp/sig.c
+++ b/gcc/cp/sig.c
@@ -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;
}
diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c
index e85be53..ea00ba2 100644
--- a/gcc/cp/spew.c
+++ b/gcc/cp/spew.c
@@ -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:
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index b4712a6..98cbd41 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index f2b375b..ffc6fd7 100644
--- a/gcc/cp/typeck.c
+++ b/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);
+}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index baf55a4..237d02a 100644
--- a/gcc/cp/typeck2.c
+++ b/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;
-
- if (parms && TREE_CHAIN (parms) == NULL_TREE)
- flags |= LOOKUP_NO_CONVERSION;
+ register tree parm = TREE_OPERAND (expr_as_ctor, 1);
- 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