break;
case COND_EXPR:
- op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
+ op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1)
+ ? TREE_OPERAND (ref, 1)
+ : TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
treat_class_rvalues_as_lvalues);
const_tree const t1 = (const_tree) k1;
const cplus_array_info *const t2 = (const cplus_array_info*) k2;
- if (!comptypes (TREE_TYPE (t1), t2->type, COMPARE_STRUCTURAL))
- return 0;
-
- if (!TYPE_DOMAIN (t1))
- return !t2->domain;
-
- if (!t2->domain)
- return 0;
-
- return comptypes (TYPE_DOMAIN (t1), t2->domain, COMPARE_STRUCTURAL);
+ 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. */
static GTY ((param_is (union tree_node))) htab_t cplus_array_htab;
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- if (dependent_type_p (elt_type)
- || (index_type
- && value_dependent_expression_p (TYPE_MAX_VALUE (index_type))))
+ if (processing_template_decl
+ && (dependent_type_p (elt_type)
+ || (index_type && !TREE_CONSTANT (TYPE_MAX_VALUE (index_type)))))
{
void **e;
cplus_array_info cai;
hashval_t hash;
-
+
if (cplus_array_htab == NULL)
cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
&cplus_array_compare, NULL);
e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT);
if (*e)
- /* We have found the type: we're done. */
+ /* We have found the type: we're done. */
return (tree) *e;
else
{
- /* Build a new array type. */
+ /* Build a new array type. */
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
TYPE_DOMAIN (t) = index_type;
- /* Complete building the array type. */
+ /* Store it in the hash table. */
+ *e = t;
+
+ /* Set the canonical type for this new node. */
if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
|| (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (elt_type) != elt_type
|| (index_type
&& TYPE_CANONICAL (index_type) != index_type))
- TYPE_CANONICAL (t)
- = TYPE_CANONICAL
- (build_cplus_array_type_1 (TYPE_CANONICAL (elt_type),
- index_type?
- TYPE_CANONICAL (index_type)
- : index_type));
-
- /* Store it in the hash table. */
- *e = t;
+ TYPE_CANONICAL (t)
+ = build_cplus_array_type
+ (TYPE_CANONICAL (elt_type),
+ index_type ? TYPE_CANONICAL (index_type) : index_type);
+ else
+ TYPE_CANONICAL (t) = t;
}
}
else
}
+/* Used by the C++ front end to build qualified array types. However,
+ the C version of this function does not properly maintain canonical
+ types (which are not used in C). */
+tree
+c_build_qualified_type (tree type, int type_quals)
+{
+ return cp_build_qualified_type (type, type_quals);
+}
\f
/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles
if (!t)
{
- tree domain = TYPE_DOMAIN (type);
+ tree index_type = TYPE_DOMAIN (type);
+ void **e;
+ cplus_array_info cai;
+ hashval_t hash;
+
+ if (cplus_array_htab == NULL)
+ cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
+ &cplus_array_compare,
+ NULL);
+
+ hash = (htab_hash_pointer (element_type)
+ ^ htab_hash_pointer (index_type));
+ cai.type = element_type;
+ cai.domain = index_type;
+
+ e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT);
+ if (*e)
+ /* We have found the type: we're done. */
+ return (tree) *e;
- /* Make a new array type, just like the old one, but with the
- appropriately qualified element type. */
+ /* Build a new array type and add it into the table. */
t = build_variant_type_copy (type);
TREE_TYPE (t) = element_type;
+ *e = t;
- /* This is a new type. */
- TYPE_CANONICAL (t) = t;
-
- if (dependent_type_p (element_type)
- || (domain
- && value_dependent_expression_p (TYPE_MAX_VALUE (domain))))
- {
- /* The new dependent array type we just created might be
- equivalent to an existing dependent array type, so we
- need to keep track of this new array type with a
- lookup into CPLUS_ARRAY_HTAB. Note that we cannot
- directly call build_cplus_array_type (that would
- recurse) or build_cplus_array_type_1 (that would lose
- attributes). */
- void **e;
- cplus_array_info cai;
- hashval_t hash;
-
- if (cplus_array_htab == NULL)
- cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
- &cplus_array_compare,
- NULL);
-
- hash = (htab_hash_pointer (element_type)
- ^ htab_hash_pointer (domain));
- cai.type = element_type;
- cai.domain = domain;
-
- e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash,
- INSERT);
- if (! *e)
- /* Save this new type. */
- *e = t;
- }
-
- if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t))
- || (TYPE_DOMAIN (t)
- && TYPE_STRUCTURAL_EQUALITY_P (TYPE_DOMAIN (t))))
+ /* Set the canonical type for this new node. */
+ if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
+ || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (element_type) != element_type
+ || (index_type
+ && TYPE_CANONICAL (index_type) != index_type)
+ || TYPE_CANONICAL (type) != type)
+ TYPE_CANONICAL (t)
+ = build_cplus_array_type
+ (TYPE_CANONICAL (element_type),
+ index_type? TYPE_CANONICAL (index_type) : index_type);
else
- TYPE_CANONICAL (t)
- = TYPE_CANONICAL
- (build_array_type (TYPE_CANONICAL (TREE_TYPE (t)),
- TYPE_DOMAIN (t)?
- TYPE_CANONICAL (TYPE_DOMAIN(t))
- : TYPE_DOMAIN (t)));
+ TYPE_CANONICAL (t) = t;
}
/* Even if we already had this variant, we update
t = cp_build_qualified_type_real (t, type_quals, complain);
return build_ptrmemfunc_type (t);
}
+ else if (TREE_CODE (type) == TYPE_PACK_EXPANSION)
+ {
+ tree t = PACK_EXPANSION_PATTERN (type);
+
+ t = cp_build_qualified_type_real (t, type_quals, complain);
+ return make_pack_expansion (t);
+ }
/* A reference or method type shall not be cv qualified.
[dcl.ref], [dct.fct] */
tree
canonical_type_variant (tree t)
{
+ if (t == error_mark_node)
+ return error_mark_node;
+
return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), cp_type_quals (t));
}
\f
const char *
cxx_printable_name (tree decl, int v)
{
- static tree decl_ring[PRINT_RING_SIZE];
+ static unsigned int uid_ring[PRINT_RING_SIZE];
static char *print_ring[PRINT_RING_SIZE];
static int ring_counter;
int i;
/* See if this print name is lying around. */
for (i = 0; i < PRINT_RING_SIZE; i++)
- if (decl_ring[i] == decl)
+ if (uid_ring[i] == DECL_UID (decl))
/* yes, so return it. */
return print_ring[i];
if (current_function_decl != NULL_TREE)
{
- if (decl_ring[ring_counter] == current_function_decl)
+ if (uid_ring[ring_counter] == DECL_UID (current_function_decl))
ring_counter += 1;
if (ring_counter == PRINT_RING_SIZE)
ring_counter = 0;
- gcc_assert (decl_ring[ring_counter] != current_function_decl);
+ gcc_assert (uid_ring[ring_counter] != DECL_UID (current_function_decl));
}
if (print_ring[ring_counter])
free (print_ring[ring_counter]);
print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v));
- decl_ring[ring_counter] = decl;
+ uid_ring[ring_counter] = DECL_UID (decl);
return print_ring[ring_counter];
}
\f
int
pod_type_p (const_tree t)
{
- t = const_strip_array_types (t);
+ /* This CONST_CAST is okay because strip_array_types returns it's
+ argument unmodified and we assign it to a const_tree. */
+ t = strip_array_types (CONST_CAST_TREE(t));
if (t == error_mark_node)
return 1;
int
zero_init_p (const_tree t)
{
- t = const_strip_array_types (t);
+ /* This CONST_CAST is okay because strip_array_types returns it's
+ argument unmodified and we assign it to a const_tree. */
+ t = strip_array_types (CONST_CAST_TREE(t));
if (t == error_mark_node)
return 1;
}
/* Build a variant of TYPE that has the indicated ATTRIBUTES. May
- return an existing type of an appropriate type already exists. */
+ return an existing type if an appropriate type already exists. */
tree
cp_build_type_attribute_variant (tree type, tree attributes)
return new_type;
}
+/* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
+ Called only after doing all language independent checks. Only
+ to check TYPE_RAISES_EXCEPTIONS for FUNCTION_TYPE, the rest is already
+ compared in type_hash_eq. */
+
+bool
+cxx_type_hash_eq (const_tree typea, const_tree typeb)
+{
+ gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE);
+
+ return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea),
+ TYPE_RAISES_EXCEPTIONS (typeb), 1);
+}
+
/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
traversal. Called from walk_tree. */
*walk_subtrees_p = 0;
break;
+ case USING_DECL:
+ WALK_SUBTREE (DECL_NAME (*tp));
+ WALK_SUBTREE (USING_DECL_SCOPE (*tp));
+ WALK_SUBTREE (USING_DECL_DECLS (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (*tp))
WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (*tp));
if (!DECL_NAME (decl))
return lk_none;
+ /* Fields have no linkage. */
+ if (TREE_CODE (decl) == FIELD_DECL)
+ return lk_none;
+
/* Things that are TREE_PUBLIC have external linkage. */
if (TREE_PUBLIC (decl))
return lk_external;
/* Members of the anonymous namespace also have TREE_PUBLIC unset, but
are considered to have external linkage for language purposes. DECLs
really meant to have internal linkage have DECL_THIS_STATIC set. */
- if (TREE_CODE (decl) == TYPE_DECL
- || ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
- && !DECL_THIS_STATIC (decl)))
+ if (TREE_CODE (decl) == TYPE_DECL)
return lk_external;
+ if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (!DECL_THIS_STATIC (decl))
+ return lk_external;
+
+ /* Static data members and static member functions from classes
+ in anonymous namespace also don't have TREE_PUBLIC set. */
+ if (DECL_CLASS_CONTEXT (decl))
+ return lk_external;
+ }
/* Everything else has internal linkage. */
return lk_internal;
int i;
int nargs = call_expr_nargs (call);
- if (call == error_mark_node)
- return;
+ if (call == error_mark_node || processing_template_decl)
+ {
+ *initp = NULL_TREE;
+ return;
+ }
gcc_assert (TREE_CODE (call) == CALL_EXPR);
*initp = NULL_TREE;
- if (t == error_mark_node)
+ if (t == error_mark_node || processing_template_decl)
return true;
if (TREE_CODE (t) == INIT_EXPR