#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
-#include "real.h"
#include "rtl.h"
#include "toplev.h"
#include "insn-config.h"
static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *);
-static tree build_cplus_array_type_1 (tree, tree);
static int list_hash_eq (const void *, const void *);
static hashval_t list_hash_pieces (tree, tree, tree);
static hashval_t list_hash (const void *);
if (error_operand_p (expr))
return expr;
+ expr = mark_rvalue_use (expr);
+
/* [basic.lval]
Non-class rvalues always have cv-unqualified types. */
return (TREE_TYPE (t1) == t2->type && TYPE_DOMAIN (t1) == t2->domain);
}
-/* Hash table containing all of the C++ array types, including
- dependent array types and array types whose element type is
- cv-qualified. */
+/* Hash table containing dependent array types, which are unsuitable for
+ the language-independent type hash table. */
static GTY ((param_is (union tree_node))) htab_t cplus_array_htab;
+/* Like build_array_type, but handle special C++ semantics. */
-static tree
-build_cplus_array_type_1 (tree elt_type, tree index_type)
+tree
+build_cplus_array_type (tree elt_type, tree index_type)
{
tree t;
else
t = build_array_type (elt_type, index_type);
+ /* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the
+ element type as well, so fix it up if needed. */
+ if (elt_type != TYPE_MAIN_VARIANT (elt_type))
+ {
+ tree m = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
+ index_type);
+ if (TYPE_MAIN_VARIANT (t) != m)
+ {
+ TYPE_MAIN_VARIANT (t) = m;
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
+ TYPE_NEXT_VARIANT (m) = t;
+ }
+ }
+
/* Push these needs up so that initialization takes place
more easily. */
TYPE_NEEDS_CONSTRUCTING (t)
return t;
}
-tree
-build_cplus_array_type (tree elt_type, tree index_type)
-{
- tree t;
- int type_quals = cp_type_quals (elt_type);
-
- if (type_quals != TYPE_UNQUALIFIED)
- elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
-
- t = build_cplus_array_type_1 (elt_type, index_type);
-
- if (type_quals != TYPE_UNQUALIFIED)
- t = cp_build_qualified_type (t, type_quals);
-
- return t;
-}
-
/* Return an ARRAY_TYPE with element type ELT and length N. */
tree
if (element_type == error_mark_node)
return error_mark_node;
- /* See if we already have an identically qualified type. */
+ /* See if we already have an identically qualified type. Tests
+ should be equivalent to those in check_qualified_type. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
if (cp_type_quals (t) == type_quals
&& TYPE_NAME (t) == TYPE_NAME (type)
- && TYPE_CONTEXT (t) == TYPE_CONTEXT (type))
+ && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+ && attribute_list_equal (TYPE_ATTRIBUTES (t),
+ TYPE_ATTRIBUTES (type)))
break;
if (!t)
- {
- t = build_cplus_array_type_1 (element_type, TYPE_DOMAIN (type));
+ {
+ t = build_cplus_array_type (element_type, TYPE_DOMAIN (type));
- if (TYPE_MAIN_VARIANT (t) != TYPE_MAIN_VARIANT (type))
- {
- /* Set the main variant of the newly-created ARRAY_TYPE
- (with cv-qualified element type) to the main variant of
- the unqualified ARRAY_TYPE we started with. */
- tree last_variant = t;
- tree m = TYPE_MAIN_VARIANT (type);
-
- /* Find the last variant on the new ARRAY_TYPEs list of
- variants, setting the main variant of each of the other
- types to the main variant of our unqualified
- ARRAY_TYPE. */
- while (TYPE_NEXT_VARIANT (last_variant))
- {
- TYPE_MAIN_VARIANT (last_variant) = m;
- last_variant = TYPE_NEXT_VARIANT (last_variant);
- }
-
- /* Splice in the newly-created variants. */
- TYPE_NEXT_VARIANT (last_variant) = TYPE_NEXT_VARIANT (m);
- TYPE_NEXT_VARIANT (m) = t;
- TYPE_MAIN_VARIANT (last_variant) = m;
- }
- }
+ /* Keep the typedef name. */
+ if (TYPE_NAME (t) != TYPE_NAME (type))
+ {
+ t = build_variant_type_copy (t);
+ TYPE_NAME (t) = TYPE_NAME (type);
+ }
+ }
/* Even if we already had this variant, we update
TYPE_NEEDS_CONSTRUCTING and TYPE_HAS_NONTRIVIAL_DESTRUCTOR in case
}
/* A reference or method type shall not be cv-qualified.
- [dcl.ref], [dcl.fct] */
+ [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295
+ (in CD1) we always ignore extra cv-quals on functions. */
if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
&& (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE))
{
- bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
}
+ /* But preserve any function-cv-quals on a FUNCTION_TYPE. */
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ type_quals |= type_memfn_quals (type);
+
/* A restrict-qualified type must be a pointer (or reference)
to object or incomplete type. */
if ((type_quals & TYPE_QUAL_RESTRICT)
type_quals &= ~TYPE_QUAL_RESTRICT;
}
- if (bad_quals == TYPE_UNQUALIFIED)
+ if (bad_quals == TYPE_UNQUALIFIED
+ || (complain & tf_ignore_bad_quals))
/*OK*/;
- else if (!(complain & (tf_error | tf_ignore_bad_quals)))
+ else if (!(complain & tf_error))
return error_mark_node;
else
{
- if (complain & tf_ignore_bad_quals)
- /* We're not going to warn about constifying things that can't
- be constified. */
- bad_quals &= ~TYPE_QUAL_CONST;
- if (bad_quals)
- {
- tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
-
- if (!(complain & tf_ignore_bad_quals))
- error ("%qV qualifiers cannot be applied to %qT",
- bad_type, type);
- }
+ tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+ error ("%qV qualifiers cannot be applied to %qT",
+ bad_type, type);
}
/* Retrieve (or create) the appropriately qualified variant. */
tree
cv_unqualified (tree type)
{
- int quals = TYPE_QUALS (type);
+ int quals;
+
+ if (type == error_mark_node)
+ return type;
+
+ quals = cp_type_quals (type);
quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
return cp_build_qualified_type (type, quals);
}
TREE_CHAIN (arg_types));
}
else
+ {
result = build_function_type (type,
arg_types);
+ result = apply_memfn_quals (result, type_memfn_quals (t));
+ }
if (TYPE_RAISES_EXCEPTIONS (t))
result = build_exception_variant (result,
}
tree
-get_first_fn (tree from)
+get_fns (tree from)
{
gcc_assert (is_overloaded_fn (from));
/* A baselink is also considered an overloaded function. */
from = BASELINK_FUNCTIONS (from);
if (TREE_CODE (from) == TEMPLATE_ID_EXPR)
from = TREE_OPERAND (from, 0);
- return OVL_CURRENT (from);
+ return from;
+}
+
+tree
+get_first_fn (tree from)
+{
+ return OVL_CURRENT (get_fns (from));
}
/* Return a new OVL node, concatenating it with the old one. */
/* Fall through. */
case ENUMERAL_TYPE:
/* Only treat anonymous types as having no linkage if they're at
- namespace scope. This doesn't have a core issue number yet. */
+ namespace scope. This is core issue 966. */
if (TYPE_ANONYMOUS_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
return t;
return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
else if (TREE_CODE (r) == FUNCTION_DECL)
{
- if (!relaxed_p || !vague_linkage_fn_p (r))
+ if (!relaxed_p || !vague_linkage_p (r))
return t;
else
r = CP_DECL_CONTEXT (r);
{
print_search_statistics ();
print_class_statistics ();
+ print_template_statistics ();
#ifdef GATHER_STATISTICS
fprintf (stderr, "maximum template instantiation depth reached: %d\n",
depth_reached);
return t;
}
-/* Similar to `build_call_list', but for template definitions of non-dependent
- expressions. NON_DEP is the non-dependent expression that has been
- built. */
+/* Similar to `build_nt_call_vec', but for template definitions of
+ non-dependent expressions. NON_DEP is the non-dependent expression
+ that has been built. */
tree
build_min_non_dep_call_vec (tree non_dep, tree fn, VEC(tree,gc) *argvec)
arg2 = next_call_expr_arg (&iter2))
if (!cp_tree_equal (arg1, arg2))
return false;
- return (arg1 || arg2);
+ if (arg1 || arg2)
+ return false;
+ return true;
}
case TARGET_EXPR:
{
tree decl, context;
tree binfo;
+ tree current = current_nonlambda_class_type ();
- if (current_class_type
- && (binfo = lookup_base (current_class_type, type,
- ba_unique | ba_quiet, NULL)))
- context = current_class_type;
+ if (current
+ && (binfo = lookup_base (current, type, ba_any, NULL)))
+ context = current;
else
{
/* Reference from a nested class member function. */
&& same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)),
current_class_type))
decl = current_class_ref;
+ else if (current != current_class_type
+ && context == nonlambda_method_basetype ())
+ /* In a lambda, need to go through 'this' capture. */
+ decl = (cp_build_indirect_ref
+ ((lambda_expr_this_capture
+ (CLASSTYPE_LAMBDA_EXPR (current_class_type))),
+ RO_NULL, tf_warning_or_error));
else
decl = build_dummy_object (context);
argument unmodified and we assign it to a const_tree. */
t = strip_array_types (CONST_CAST_TREE(t));
- if (CLASS_TYPE_P (t))
+ if (!CLASS_TYPE_P (t))
+ return scalarish_type_p (t);
+ else if (cxx_dialect > cxx98)
/* [class]/10: A POD struct is a class that is both a trivial class and a
standard-layout class, and has no non-static data members of type
non-POD struct, non-POD union (or array of such types).
non-std-layout or non-trivial, the class will be too. */
return (std_layout_type_p (t) && trivial_type_p (t));
else
- return scalarish_type_p (t);
+ /* The C++98 definition of POD is different. */
+ return !CLASSTYPE_NON_LAYOUT_POD_P (t);
}
/* Returns true iff T is POD for the purpose of layout, as defined in the