#include "toplev.h"
#include "expr.h"
#include "diagnostic.h"
+#include "intl.h"
extern int inhibit_warnings;
static tree build_object_call (tree, tree);
static tree resolve_args (tree);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
+static void print_z_candidate (const char *, struct z_candidate *);
static void print_z_candidates (struct z_candidate *);
static tree build_this (tree);
static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
if (i != 0)
return NULL;
- fn = instantiate_template (tmpl, targs);
+ fn = instantiate_template (tmpl, targs, tf_none);
if (fn == error_mark_node)
return NULL;
return fn1 == fn2;
}
-/* Print information about one overload candidate CANDIDATE. STR is the
- text to print before the candidate itself and ERRFN is the routine
- (i.e. error, warning or pedwarn) used to do the printing. */
+/* Print information about one overload candidate CANDIDATE. MSGSTR
+ is the text to print before the candidate itself.
+
+ NOTE: Unlike most diagnostic functions in GCC, MSGSTR is expected
+ to have been run through gettext by the caller. This wart makes
+ life simpler in print_z_candidates and for the translators. */
static void
-print_z_candidate (const char *str, struct z_candidate *candidate,
- void (*errfn)(const char *, ...))
+print_z_candidate (const char *msgstr, struct z_candidate *candidate)
{
if (TREE_CODE (candidate->fn) == IDENTIFIER_NODE)
{
if (TREE_VEC_LENGTH (candidate->convs) == 3)
- errfn ("%s %D(%T, %T, %T) <built-in>", str, candidate->fn,
- TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
- TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)),
- TREE_TYPE (TREE_VEC_ELT (candidate->convs, 2)));
+ inform ("%s %D(%T, %T, %T) <built-in>", msgstr, candidate->fn,
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)),
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 2)));
else if (TREE_VEC_LENGTH (candidate->convs) == 2)
- errfn ("%s %D(%T, %T) <built-in>", str, candidate->fn,
- TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
- TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)));
+ inform ("%s %D(%T, %T) <built-in>", msgstr, candidate->fn,
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)));
else
- errfn ("%s %D(%T) <built-in>", str, candidate->fn,
- TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)));
+ inform ("%s %D(%T) <built-in>", msgstr, candidate->fn,
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)));
}
else if (TYPE_P (candidate->fn))
- errfn ("%s %T <conversion>", str, candidate->fn);
+ inform ("%s %T <conversion>", msgstr, candidate->fn);
+ else if (candidate->viable == -1)
+ inform ("%H%s %+#D <near match>",
+ &DECL_SOURCE_LOCATION (candidate->fn), msgstr, candidate->fn);
else
- errfn ("%H%s %+#D%s", &DECL_SOURCE_LOCATION (candidate->fn), str,
- candidate->fn, candidate->viable == -1 ? " <near match>" : "");
+ inform ("%H%s %+#D",
+ &DECL_SOURCE_LOCATION (candidate->fn), msgstr, candidate->fn);
}
static void
}
}
- str = "candidates are:";
- for (; candidates; candidates = candidates->next)
+ if (!candidates)
+ return;
+
+ str = _("candidates are:");
+ print_z_candidate (str, candidates);
+ if (candidates->next)
{
- print_z_candidate (str, candidates, error);
- str = " ";
+ /* Indent successive candidates by the width of the translation
+ of the above string. */
+ size_t len = gcc_gettext_width (str) + 1;
+ char *spaces = alloca (len);
+ memset (spaces, ' ', len-1);
+ spaces[len] = '\0';
+
+ candidates = candidates->next;
+ do
+ {
+ print_z_candidate (spaces, candidates);
+ candidates = candidates->next;
+ }
+ while (candidates);
}
}
We use ocp_convert rather than build_user_type_conversion because the
latter returns NULL_TREE on failure, while the former gives an error. */
- if (IS_AGGR_TYPE (TREE_TYPE (arg2)))
- arg2 = ocp_convert (TREE_TYPE (arg2), arg2,
- CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
- else
- arg2 = decay_conversion (arg2);
+ arg2 = force_rvalue (arg2);
arg2_type = TREE_TYPE (arg2);
- if (IS_AGGR_TYPE (TREE_TYPE (arg3)))
- arg3 = ocp_convert (TREE_TYPE (arg3), arg3,
- CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
- else
- arg3 = decay_conversion (arg3);
+ arg3 = force_rvalue (arg3);
arg3_type = TREE_TYPE (arg3);
if (arg2 == error_mark_node || arg3 == error_mark_node)
else
fn = build_addr_func (fn);
+ return build_cxx_call (fn, args, converted_args);
+}
+
+/* Build and return a call to FN, using the the CONVERTED_ARGS. ARGS
+ gives the original form of the arguments. This function performs
+ no overload resolution, conversion, or other high-level
+ operations. */
+
+tree
+build_cxx_call(tree fn, tree args, tree converted_args)
+{
+ tree fndecl;
+
/* Recognize certain built-in functions so we can make tree-codes
other than CALL_EXPR. We do this when it enables fold-const.c
to do something useful. */
-
if (TREE_CODE (fn) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
&& DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
return exp;
}
- /* Some built-in function calls will be evaluated at
- compile-time in fold (). */
- fn = fold (build_call (fn, converted_args));
+ fn = build_call (fn, converted_args);
+
+ /* If this call might throw an exception, note that fact. */
+ fndecl = get_callee_fndecl (fn);
+ if ((!fndecl || !TREE_NOTHROW (fndecl))
+ && at_function_scope_p ()
+ && cfun)
+ cp_function_chain->can_throw = 1;
+
+ /* Some built-in function calls will be evaluated at compile-time in
+ fold (). */
+ fn = fold (fn);
+
if (VOID_TYPE_P (TREE_TYPE (fn)))
return fn;
+
fn = require_complete_type (fn);
if (fn == error_mark_node)
return error_mark_node;
+
if (IS_AGGR_TYPE (TREE_TYPE (fn)))
fn = build_cplus_new (TREE_TYPE (fn), fn);
return convert_from_reference (fn);
{
if (warn)
{
- print_z_candidate ("ISO C++ says that ", w, pedwarn);
- print_z_candidate (" and ", l, pedwarn);
- pedwarn ("are ambiguous even though the worst conversion \
-for the former is better than the worst conversion for the latter");
+ pedwarn ("\
+ISO C++ says that these are ambiguous, even \
+though the worst conversion for the first is better than \
+the worst conversion for the second:");
+ print_z_candidate (_("candidate 1:"), w);
+ print_z_candidate (_("candidate 2:"), l);
}
else
add_warning (w, l);