/* Functions related to building classes and their related objects.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
{
expr = build_nop (build_pointer_type (target_type), expr);
if (!want_pointer)
- expr = build_indirect_ref (EXPR_LOCATION (expr), expr, NULL);
+ expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
return expr;
}
interesting to the optimizers anyway. */
&& !has_empty)
{
- expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
+ expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
expr = build_simple_base_path (expr, binfo);
if (want_pointer)
expr = build_address (expr);
t = TREE_TYPE (TYPE_VFIELD (current_class_type));
t = build_pointer_type (t);
v_offset = convert (t, current_vtt_parm);
- v_offset = cp_build_indirect_ref (v_offset, NULL,
+ v_offset = cp_build_indirect_ref (v_offset, RO_NULL,
tf_warning_or_error);
}
else
- v_offset = build_vfield_ref (cp_build_indirect_ref (expr, NULL,
+ v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
tf_warning_or_error),
TREE_TYPE (TREE_TYPE (expr)));
v_offset = build1 (NOP_EXPR,
build_pointer_type (ptrdiff_type_node),
v_offset);
- v_offset = cp_build_indirect_ref (v_offset, NULL, tf_warning_or_error);
+ v_offset = cp_build_indirect_ref (v_offset, RO_NULL, tf_warning_or_error);
TREE_CONSTANT (v_offset) = 1;
offset = convert_to_integer (ptrdiff_type_node,
null_test = NULL;
if (!want_pointer)
- expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
+ expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
out:
if (null_test)
in the back end. */
temp = unary_complex_lvalue (ADDR_EXPR, expr);
if (temp)
- expr = cp_build_indirect_ref (temp, NULL, tf_warning_or_error);
+ expr = cp_build_indirect_ref (temp, RO_NULL, tf_warning_or_error);
return expr;
}
assumed to be non-NULL. */
tree
-convert_to_base (tree object, tree type, bool check_access, bool nonnull)
+convert_to_base (tree object, tree type, bool check_access, bool nonnull,
+ tsubst_flags_t complain)
{
tree binfo;
tree object_type;
+ base_access access;
if (TYPE_PTR_P (TREE_TYPE (object)))
{
else
object_type = TREE_TYPE (object);
+ access = check_access ? ba_check : ba_unique;
+ if (!(complain & tf_error))
+ access |= ba_quiet;
binfo = lookup_base (object_type, type,
- check_access ? ba_check : ba_unique,
+ access,
NULL);
if (!binfo || binfo == error_mark_node)
return error_mark_node;
/* First, convert to the requested type. */
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
datum = convert_to_base (datum, type, /*check_access=*/false,
- /*nonnull=*/true);
+ /*nonnull=*/true, tf_warning_or_error);
/* Second, the requested type may not be the owner of its own vptr.
If not, convert to the base class that owns it. We cannot use
{
tree aref;
- aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, 0,
+ aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, RO_NULL,
tf_warning_or_error),
idx);
&& ! DECL_STATIC_FUNCTION_P (method)
&& TREE_TYPE (TREE_VALUE (parms1)) != error_mark_node
&& TREE_TYPE (TREE_VALUE (parms2)) != error_mark_node
- && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
- != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
+ && (cp_type_quals (TREE_TYPE (TREE_VALUE (parms1)))
+ != cp_type_quals (TREE_TYPE (TREE_VALUE (parms2)))))
continue;
/* For templates, the return type and template parameters
tree types, base_types;
types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
- if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types)))
- == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types))))
+ if ((cp_type_quals (TREE_TYPE (TREE_VALUE (base_types)))
+ == cp_type_quals (TREE_TYPE (TREE_VALUE (types))))
&& compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
return 1;
}
CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
}
+ /* Currently only lambdas get a lazy move ctor, but N2987 adds them for
+ other classes. */
+ if (LAMBDA_TYPE_P (t))
+ CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
+
/* If there is no assignment operator, one will be created if and
when it is needed. For now, just record whether or not the type
of the parameter to the assignment operator will be a const or
&& TREE_CODE (type) != BOOLEAN_TYPE)
warning (0, "width of %q+D exceeds its type", field);
else if (TREE_CODE (type) == ENUMERAL_TYPE
- && (0 > compare_tree_int (w,
- tree_int_cst_min_precision
- (TYPE_MIN_VALUE (type),
- TYPE_UNSIGNED (type)))
- || 0 > compare_tree_int (w,
- tree_int_cst_min_precision
- (TYPE_MAX_VALUE (type),
- TYPE_UNSIGNED (type)))))
+ && (0 > (compare_tree_int
+ (w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type))))))
warning (0, "%q+D is too small to hold all values of %q#T", field, type);
}
VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
}
/* All user-provided destructors are non-trivial. */
- if (DECL_DESTRUCTOR_P (x) && !DECL_DEFAULTED_FN (x))
+ if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
}
}
/* A default parameter has been added. Adjust the
clone's parameters. */
tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
+ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (clone));
tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
tree type;
clone_parms);
if (exceptions)
type = build_exception_variant (type, exceptions);
+ if (attrs)
+ type = cp_build_type_attribute_variant (type, attrs);
TREE_TYPE (clone) = type;
clone_parms = NULL_TREE;
return false;
}
+/* Returns the defaulted constructor if T has one. Otherwise, returns
+ NULL_TREE. */
+
+tree
+in_class_defaulted_default_constructor (tree t)
+{
+ tree fns, args;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return NULL_TREE;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (DECL_DEFAULTED_IN_CLASS_P (fn))
+ {
+ args = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ while (args && TREE_PURPOSE (args))
+ args = TREE_CHAIN (args);
+ if (!args || args == void_list_node)
+ return fn;
+ }
+ }
+
+ return NULL_TREE;
+}
+
/* Returns true iff FN is a user-provided function, i.e. user-declared
- and not defaulted at its first declaration. */
+ and not defaulted at its first declaration; or explicit, private,
+ protected, or non-const. */
-static bool
+bool
user_provided_p (tree fn)
{
if (TREE_CODE (fn) == TEMPLATE_DECL)
return true;
else
return (!DECL_ARTIFICIAL (fn)
- && !(DECL_DEFAULTED_FN (fn)
- && DECL_INITIALIZED_IN_CLASS_P (fn)));
+ && !DECL_DEFAULTED_IN_CLASS_P (fn));
}
/* Returns true iff class T has a user-provided constructor. */
return false;
}
-/* Returns true if FN can be explicitly defaulted. */
-
-bool
-defaultable_fn_p (tree fn)
-{
- if (DECL_CONSTRUCTOR_P (fn))
- {
- if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
- return true;
- else if (copy_fn_p (fn) > 0
- && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
- == void_list_node))
- return true;
- else
- return false;
- }
- else if (DECL_DESTRUCTOR_P (fn))
- return true;
- else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
- && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
- return copy_fn_p (fn);
- else
- return false;
-}
-
/* Remove all zero-width bit-fields from T. */
static void
{
if (TREE_CODE (*fieldsp) == FIELD_DECL
&& DECL_C_BIT_FIELD (*fieldsp)
- && DECL_INITIAL (*fieldsp))
+ /* We should not be confused by the fact that grokbitfield
+ temporarily sets the width of the bit field into
+ DECL_INITIAL (*fieldsp).
+ check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
+ to that width. */
+ && integer_zerop (DECL_SIZE (*fieldsp)))
*fieldsp = TREE_CHAIN (*fieldsp);
else
fieldsp = &TREE_CHAIN (*fieldsp);
tree access_decls;
bool saved_complex_asn_ref;
bool saved_nontrivial_dtor;
+ tree fn;
/* By default, we use const reference arguments and generate default
constructors. */
cant_have_const_ctor,
no_const_asn_ref);
+ /* Check defaulted declarations here so we have cant_have_const_ctor
+ and don't need to worry about clones. */
+ for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
+ if (DECL_DEFAULTED_IN_CLASS_P (fn))
+ {
+ int copy = copy_fn_p (fn);
+ if (copy > 0)
+ {
+ bool imp_const_p
+ = (DECL_CONSTRUCTOR_P (fn) ? !cant_have_const_ctor
+ : !no_const_asn_ref);
+ bool fn_const_p = (copy == 2);
+
+ if (fn_const_p && !imp_const_p)
+ /* If the function is defaulted outside the class, we just
+ give the synthesis error. */
+ error ("%q+D declared to take const reference, but implicit "
+ "declaration would take non-const", fn);
+ else if (imp_const_p && !fn_const_p)
+ error ("%q+D declared to take non-const reference cannot be "
+ "defaulted in the class body", fn);
+ }
+ defaulted_late_check (fn);
+ }
+
+ if (LAMBDA_TYPE_P (t))
+ {
+ /* "The closure type associated with a lambda-expression has a deleted
+ default constructor and a deleted copy assignment operator." */
+ TYPE_NEEDS_CONSTRUCTING (t) = 1;
+ TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
+ CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 0;
+ TYPE_HAS_ASSIGN_REF (t) = 0;
+ CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 0;
+
+ /* "This class type is not an aggregate." */
+ CLASSTYPE_NON_AGGREGATE (t) = 1;
+ }
+
/* Create the in-charge and not-in-charge variants of constructors
and destructors. */
clone_constructors_and_destructors (t);
DECL_ARTIFICIAL (field) = 1;
DECL_FIELD_CONTEXT (field) = t;
DECL_FCONTEXT (field) = t;
+ if (TYPE_PACKED (t))
+ DECL_PACKED (field) = 1;
TYPE_VFIELD (t) = field;
/* G++ used to use DECL_FIELD_OFFSET as if it were the byte
offset of the field. */
if (warn_abi
+ && !abi_version_at_least (2)
&& !tree_int_cst_equal (DECL_FIELD_OFFSET (field),
byte_position (field))
&& contains_empty_class_p (TREE_TYPE (field)))
TYPE_UNSIGNED (ftype));
TREE_TYPE (field)
= cp_build_qualified_type (TREE_TYPE (field),
- TYPE_QUALS (ftype));
+ cp_type_quals (ftype));
}
}
build_decl (input_location,
FIELD_DECL, NULL_TREE, char_type_node));
+ /* If this is a non-POD, declaring it packed makes a difference to how it
+ can be used as a field; don't let finalize_record_size undo it. */
+ if (TYPE_PACKED (t) && !layout_pod_type_p (t))
+ rli->packed_maybe_necessary = true;
+
/* Let the back end lay out the type. */
finish_record_layout (rli, /*free_p=*/true);
if (DECL_PURE_VIRTUAL_P (x))
VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
complete_vars (t);
+
+ /* Remember current #pragma pack value. */
+ TYPE_PRECISION (t) = maximum_field_alignment;
}
else
finish_struct_1 (t);
if (!CLASS_TYPE_P (t))
return false;
+ t = TYPE_MAIN_VARIANT (t);
+
/* We start looking from 1 because entry 0 is from global scope,
and has no type. */
for (i = current_class_depth; i > 0; --i)
return NULL_TREE;
}
+/* Returns the innermost class type which is not a lambda closure type. */
+
+tree
+current_nonlambda_class_type (void)
+{
+ int i;
+
+ /* We start looking from 1 because entry 0 is from global scope,
+ and has no type. */
+ for (i = current_class_depth; i > 0; --i)
+ {
+ tree c;
+ if (i == current_class_depth)
+ c = current_class_type;
+ else
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ c = current_class_stack[i].type;
+ }
+ if (!c)
+ continue;
+ if (!LAMBDA_TYPE_P (c))
+ return c;
+ }
+ return NULL_TREE;
+}
+
/* When entering a class scope, all enclosing class scopes' names with
static meaning (static variables, static functions, types and
enumerators) have to be visible. This recursive function calls
selected function. */
int is_ptrmem = 0;
- int is_reference = 0;
/* We store the matches in a TREE_LIST rooted here. The functions
are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
interoperability with most_specialized_instantiation. */
tree matches = NULL_TREE;
tree fn;
+ tree target_fn_type;
/* By the time we get here, we should be seeing only real
pointer-to-member types, not the internal POINTER_TYPE to
/* This is OK, too. */
is_ptrmem = 1;
else if (TREE_CODE (target_type) == FUNCTION_TYPE)
- {
- /* This is OK, too. This comes from a conversion to reference
- type. */
- target_type = build_reference_type (target_type);
- is_reference = 1;
- }
+ /* This is OK, too. This comes from a conversion to reference
+ type. */
+ target_type = build_reference_type (target_type);
else
{
if (flags & tf_error)
return error_mark_node;
}
+ /* Non-member functions and static member functions match targets of type
+ "pointer-to-function" or "reference-to-function." Nonstatic member
+ functions match targets of type "pointer-to-member-function;" the
+ function type of the pointer to member is used to select the member
+ function from the set of overloaded member functions.
+
+ So figure out the FUNCTION_TYPE that we want to match against. */
+ target_fn_type = static_fn_type (target_type);
+
/* If we can find a non-template function that matches, we can just
use it. There's no point in generating template instantiations
if we're just going to throw them out anyhow. But, of course, we
for (fns = overload; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
- tree fntype;
if (TREE_CODE (fn) == TEMPLATE_DECL)
/* We're not looking for templates just yet. */
continue;
/* See if there's a match. */
- fntype = TREE_TYPE (fn);
- if (is_ptrmem)
- fntype = build_ptrmemfunc_type (build_pointer_type (fntype));
- else if (!is_reference)
- fntype = build_pointer_type (fntype);
-
- if (can_convert_arg (target_type, fntype, fn, LOOKUP_NORMAL))
+ if (same_type_p (target_fn_type, static_fn_type (fn)))
matches = tree_cons (fn, NULL_TREE, matches);
}
}
match we need to look at them, too. */
if (!matches)
{
- tree target_fn_type;
tree target_arg_types;
tree target_ret_type;
tree fns;
unsigned int nargs, ia;
tree arg;
- if (is_ptrmem)
- target_fn_type
- = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type));
- else
- target_fn_type = TREE_TYPE (target_type);
target_arg_types = TYPE_ARG_TYPES (target_fn_type);
target_ret_type = TREE_TYPE (target_fn_type);
- /* Never do unification on the 'this' parameter. */
- if (TREE_CODE (target_fn_type) == METHOD_TYPE)
- target_arg_types = TREE_CHAIN (target_arg_types);
-
nargs = list_length (target_arg_types);
args = XALLOCAVEC (tree, nargs);
for (arg = target_arg_types, ia = 0;
{
tree fn = OVL_CURRENT (fns);
tree instantiation;
- tree instantiation_type;
tree targs;
if (TREE_CODE (fn) != TEMPLATE_DECL)
continue;
/* See if there's a match. */
- instantiation_type = TREE_TYPE (instantiation);
- if (is_ptrmem)
- instantiation_type =
- build_ptrmemfunc_type (build_pointer_type (instantiation_type));
- else if (!is_reference)
- instantiation_type = build_pointer_type (instantiation_type);
- if (can_convert_arg (target_type, instantiation_type, instantiation,
- LOOKUP_NORMAL))
+ if (same_type_p (target_fn_type, static_fn_type (instantiation)))
matches = tree_cons (instantiation, fn, matches);
}
flags &= ~tf_ptrmem_ok;
- if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
+ if (lhstype == unknown_type_node)
{
if (flags & tf_error)
error ("not enough type information");
DECL_CONTEXT (value) = current_class_type;
DECL_ARTIFICIAL (value) = 1;
SET_DECL_SELF_REFERENCE_P (value);
+ cp_set_underlying_type (value);
if (processing_template_decl)
value = push_template_decl (value);
/* If we're not defining a class, there's nothing to do. */
if (!(innermost_scope_kind() == sk_class
- && TYPE_BEING_DEFINED (current_class_type)))
+ && TYPE_BEING_DEFINED (current_class_type)
+ && !LAMBDA_TYPE_P (current_class_type)))
return;
/* If there's already a binding for this NAME, then we don't have
{
tree b;
tree t;
- tree basetype;
tree offset;
tree decl;
tree init;
- basetype = BINFO_TYPE (binfo);
t = BINFO_TYPE (vid->rtti_binfo);
/* To find the complete object, we will first convert to our most