#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
-#include "real.h"
-#include "rtl.h"
#include "toplev.h"
-#include "insn-config.h"
-#include "integrate.h"
#include "tree-inline.h"
#include "debug.h"
-#include "target.h"
#include "convert.h"
#include "tree-flow.h"
+#include "cgraph.h"
+#include "splay-tree.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 *);
AGGR_INIT_EXPR_ARGP (init));
TREE_SIDE_EFFECTS (rval) = 1;
AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
+ TREE_NOTHROW (rval) = TREE_NOTHROW (init);
}
else
rval = init;
if (error_operand_p (expr))
return expr;
+ expr = mark_rvalue_use (expr);
+
/* [basic.lval]
Non-class rvalues always have cv-unqualified types. */
type = TREE_TYPE (expr);
- if (!CLASS_TYPE_P (type) && cp_type_quals (type))
- type = cp_build_qualified_type (type, TYPE_UNQUALIFIED);
+ if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
+ type = cv_unqualified (type);
/* We need to do this for rvalue refs as well to get the right answer
from decltype; see c++/36628. */
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. */
return result;
}
+/* Return TYPE with const and volatile removed. */
+
+tree
+cv_unqualified (tree 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);
+}
+
/* Builds a qualified variant of T that is not a typedef variant.
E.g. consider the following declarations:
typedef const int ConstInt;
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,
+ TYPE_RAISES_EXCEPTIONS (t));
}
break;
default:
if (!result)
result = TYPE_MAIN_VARIANT (t);
+ if (TYPE_ATTRIBUTES (t))
+ result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
return cp_build_qualified_type (result, cp_type_quals (t));
}
+/* Setup a TYPE_DECL node as a typedef representation.
+ See comments of set_underlying_type in c-common.c. */
+
+void
+cp_set_underlying_type (tree t)
+{
+ set_underlying_type (t);
+ /* If T is a template type parm, make it require structural equality.
+ This is useful when comparing two template type parms,
+ because it forces the comparison of the template parameters of their
+ decls. */
+ if (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
+ SET_TYPE_STRUCTURAL_EQUALITY (TREE_TYPE (t));
+}
+
\f
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
graph dominated by T. If BINFO is NULL, TYPE is a dependent base,
}
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. */
tree
build_exception_variant (tree type, tree raises)
{
- tree v = TYPE_MAIN_VARIANT (type);
- int type_quals = TYPE_QUALS (type);
+ tree v;
+ int type_quals;
+
+ if (comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (type), ce_exact))
+ return type;
- for (; v; v = TYPE_NEXT_VARIANT (v))
+ type_quals = TYPE_QUALS (type);
+ for (v = TYPE_MAIN_VARIANT (type); v; v = TYPE_NEXT_VARIANT (v))
if (check_qualified_type (v, type, type_quals)
- && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1))
+ && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), ce_exact))
return v;
/* Need to build a new variant. */
TEMPLATE_TYPE_PARM_INDEX (t2) = copy_node (TEMPLATE_TYPE_PARM_INDEX (t));
TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (t2)) = decl;
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)
- = tree_cons (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t),
- newargs, NULL_TREE);
+ = build_template_info (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t), newargs);
TREE_TYPE (decl) = t2;
TYPE_NAME (t2) = decl;
/* 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:
case TEMPLATE_PARM_INDEX:
return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
&& TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
+ && (TEMPLATE_PARM_PARAMETER_PACK (t1)
+ == TEMPLATE_PARM_PARAMETER_PACK (t2))
&& same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
build_dummy_object (tree type)
{
tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node);
- return cp_build_indirect_ref (decl, NULL, tf_warning_or_error);
+ return cp_build_indirect_ref (decl, RO_NULL, tf_warning_or_error);
}
/* We've gotten a reference to a member of TYPE. Return *this if appropriate,
{
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
new_type = build_type_attribute_variant (type, attributes);
if (TREE_CODE (new_type) == FUNCTION_TYPE
- && (TYPE_RAISES_EXCEPTIONS (new_type)
- != TYPE_RAISES_EXCEPTIONS (type)))
+ || TREE_CODE (new_type) == METHOD_TYPE)
new_type = build_exception_variant (new_type,
TYPE_RAISES_EXCEPTIONS (type));
gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE);
return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea),
- TYPE_RAISES_EXCEPTIONS (typeb), 1);
+ TYPE_RAISES_EXCEPTIONS (typeb), ce_exact);
}
/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
exp = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error);
init_expr = get_target_expr (exp);
exp = TARGET_EXPR_SLOT (init_expr);
- exp = cp_build_indirect_ref (exp, 0, tf_warning_or_error);
+ exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
}
*initp = init_expr;
if (!gimple_has_body_p (decl)
&& !DECL_THUNK_P (decl)
&& !DECL_EXTERNAL (decl))
- return true;
+ {
+ struct cgraph_node *node = cgraph_get_node (decl);
+
+ /* Don't fix same_body aliases. Although they don't have their own
+ CFG, they share it with what they alias to. */
+ if (!node
+ || node->decl == decl
+ || !node->same_body)
+ return true;
+ }
return false;
}
DECL_EXTERNAL (t) = 1;
TREE_STATIC (t) = 0;
}
+ if (CP_AGGREGATE_TYPE_P (t)
+ && TYPE_NAME (t))
+ {
+ tree name = TYPE_NAME (t);
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = DECL_NAME (name);
+ /* Drop anonymous names. */
+ if (name != NULL_TREE
+ && ANON_AGGRNAME_P (name))
+ TYPE_NAME (t) = NULL_TREE;
+ }
+}
+
+/* Stub for c-common. Please keep in sync with c-decl.c.
+ FIXME: If address space support is target specific, then this
+ should be a C target hook. But currently this is not possible,
+ because this function is called via REGISTER_TARGET_PRAGMAS. */
+void
+c_register_addr_space (const char *word ATTRIBUTE_UNUSED,
+ addr_space_t as ATTRIBUTE_UNUSED)
+{
}
\f