+/* Handle overload resolution for initializing an object of class type from
+ an initializer list. First we look for a suitable constructor that
+ takes a std::initializer_list; if we don't find one, we then look for a
+ non-list constructor.
+
+ Parameters are as for add_candidates, except that the arguments are in
+ the form of a CONSTRUCTOR (the initializer list) rather than a VEC, and
+ the RETURN_TYPE parameter is replaced by TOTYPE, the desired type. */
+
+static void
+add_list_candidates (tree fns, tree first_arg,
+ tree init_list, tree totype,
+ tree explicit_targs, bool template_only,
+ tree conversion_path, tree access_path,
+ int flags,
+ struct z_candidate **candidates)
+{
+ VEC(tree,gc) *args;
+
+ gcc_assert (*candidates == NULL);
+
+ /* For list-initialization we consider explicit constructors, but
+ give an error if one is selected. */
+ flags &= ~LOOKUP_ONLYCONVERTING;
+ /* And we don't allow narrowing conversions. We also use this flag to
+ avoid the copy constructor call for copy-list-initialization. */
+ flags |= LOOKUP_NO_NARROWING;
+
+ /* Always use the default constructor if the list is empty (DR 990). */
+ if (CONSTRUCTOR_NELTS (init_list) == 0
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
+ ;
+ /* If the class has a list ctor, try passing the list as a single
+ argument first, but only consider list ctors. */
+ else if (TYPE_HAS_LIST_CTOR (totype))
+ {
+ flags |= LOOKUP_LIST_ONLY;
+ args = make_tree_vector_single (init_list);
+ add_candidates (fns, first_arg, args, NULL_TREE,
+ explicit_targs, template_only, conversion_path,
+ access_path, flags, candidates);
+ if (any_strictly_viable (*candidates))
+ return;
+ }
+
+ args = ctor_to_vec (init_list);
+
+ /* We aren't looking for list-ctors anymore. */
+ flags &= ~LOOKUP_LIST_ONLY;
+ /* We allow more user-defined conversions within an init-list. */
+ flags &= ~LOOKUP_NO_CONVERSION;
+ /* But not for the copy ctor. */
+ flags |= LOOKUP_NO_COPY_CTOR_CONVERSION;
+
+ add_candidates (fns, first_arg, args, NULL_TREE,
+ explicit_targs, template_only, conversion_path,
+ access_path, flags, candidates);
+}
+