|| TREE_CODE (basetype) == ENUMERAL_TYPE)
&& name == constructor_name (basetype))
return true;
- else
- name = get_type_value (name);
+
+ /* Otherwise lookup the name, it could be an unrelated typedef
+ of the correct type. */
+ name = lookup_name (name, LOOK_want::TYPE);
+ if (!name)
+ return false;
+ name = TREE_TYPE (name);
+ if (name == error_mark_node)
+ return false;
}
else
{
return false;
}
- if (!name || name == error_mark_node)
- return false;
return same_type_p (TYPE_MAIN_VARIANT (basetype), TYPE_MAIN_VARIANT (name));
}
CPTI_VTBL_TYPE,
CPTI_VTBL_PTR_TYPE,
CPTI_GLOBAL,
- CPTI_GLOBAL_TYPE,
CPTI_ABORT_FNDECL,
CPTI_AGGR_TAG,
CPTI_CONV_OP_MARKER,
#define std_node cp_global_trees[CPTI_STD]
#define abi_node cp_global_trees[CPTI_ABI]
#define global_namespace cp_global_trees[CPTI_GLOBAL]
-#define global_type_node cp_global_trees[CPTI_GLOBAL_TYPE]
#define const_type_info_type_node cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE]
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
#define conv_op_marker cp_global_trees[CPTI_CONV_OP_MARKER]
/* Macros for access to language-specific slots in an identifier. */
-/* The IDENTIFIER_BINDING is the innermost cxx_binding for the
- identifier. Its PREVIOUS is the next outermost binding. Each
- VALUE field is a DECL for the associated declaration. Thus,
- name lookup consists simply of pulling off the node at the front
- of the list (modulo oddities for looking up the names of types,
- and such.) You can use SCOPE field to determine the scope
- that bound the name. */
+/* Identifiers map directly to block or class-scope bindings.
+ Namespace-scope bindings are held in hash tables on the respective
+ namespaces. The identifier bindings are the innermost active
+ binding, from whence you can get the decl and/or implicit-typedef
+ of an elaborated type. When not bound to a local entity the
+ values are NULL. */
#define IDENTIFIER_BINDING(NODE) \
(LANG_IDENTIFIER_CAST (NODE)->bindings)
-
-/* TREE_TYPE only indicates on local and class scope the current
- type. For namespace scope, the presence of a type in any namespace
- is indicated with global_type_node, and the real type behind must
- be found through lookup. */
-#define IDENTIFIER_TYPE_VALUE(NODE) identifier_type_value (NODE)
#define REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE)
#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE))
-#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0)
/* Kinds of identifiers. Values are carefully chosen. */
enum cp_identifier_kind {
extern tree build_aggr_init (tree, tree, int,
tsubst_flags_t);
extern int is_class_type (tree, int);
-extern tree get_type_value (tree);
extern tree build_zero_init (tree, tree, bool);
extern tree build_value_init (tree, tsubst_flags_t);
extern tree build_value_init_noctor (tree, tsubst_flags_t);
abi_node = current_namespace;
pop_namespace ();
- global_type_node = make_node (LANG_TYPE);
- record_unknown_type (global_type_node, "global type");
-
any_targ_node = make_node (LANG_TYPE);
record_unknown_type (any_targ_node, "any type");
decl_attributes (decl, attributes, flags, last_decl);
}
- if (TREE_CODE (*decl) == TYPE_DECL)
- SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
-
/* Propagate deprecation out to the template. */
if (TREE_DEPRECATED (*decl))
if (tree ti = get_template_info (*decl))
return 1;
}
-tree
-get_type_value (tree name)
-{
- if (name == error_mark_node)
- return NULL_TREE;
-
- if (IDENTIFIER_HAS_TYPE_VALUE (name))
- return IDENTIFIER_TYPE_VALUE (name);
- else
- return NULL_TREE;
-}
-
/* Build a reference to a member of an aggregate. This is not a C++
`&', but really something which can have its address taken, and
then act as a pointer to member, for example TYPE :: FIELD can have
if (iter.using_p ())
;
else if (tree match = duplicate_decls (decl, *iter, hiding))
- {
- if (TREE_CODE (match) == TYPE_DECL)
- /* The IDENTIFIER will have the type referring to the
- now-smashed TYPE_DECL, because ...? Reset it. */
- SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (match));
-
- return match;
- }
+ return match;
}
if (TREE_PUBLIC (scope) && TREE_PUBLIC (decl) && !not_module_p ()
tree match = *iter;
if (duplicate_decls (decl, match, hiding))
- {
- if (TREE_CODE (match) == TYPE_DECL)
- SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (match));
- return match;
- }
+ return match;
}
}
if (match == error_mark_node)
;
else if (TREE_CODE (match) == TYPE_DECL)
- /* The IDENTIFIER will have the type referring to the
- now-smashed TYPE_DECL, because ...? Reset it. */
- SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (match));
+ {
+ auto *l = level;
+ while (l->kind == sk_template_parms)
+ l = l->level_chain;
+ gcc_checking_assert (REAL_IDENTIFIER_TYPE_VALUE (name)
+ == (l->kind == sk_namespace
+ ? NULL_TREE : TREE_TYPE (match)));
+ }
else if (iter.hidden_p () && !hiding)
{
/* Unhiding a previously hidden decl. */
print_binding_level (NAMESPACE_LEVEL (global_namespace));
}
\f
-/* Return the type associated with ID. */
-
-static tree
-identifier_type_value_1 (tree id)
-{
- /* There is no type with that name, anywhere. */
- if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
- return NULL_TREE;
- /* This is not the type marker, but the real thing. */
- if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
- return REAL_IDENTIFIER_TYPE_VALUE (id);
- /* Have to search for it. It must be on the global level, now.
- Ask lookup_name not to return non-types. */
- id = lookup_name (id, LOOK_where::BLOCK_NAMESPACE, LOOK_want::TYPE);
- if (id)
- return TREE_TYPE (id);
- return NULL_TREE;
-}
-
-/* Wrapper for identifier_type_value_1. */
-
-tree
-identifier_type_value (tree id)
-{
- tree ret;
- timevar_start (TV_NAME_LOOKUP);
- ret = identifier_type_value_1 (id);
- timevar_stop (TV_NAME_LOOKUP);
- return ret;
-}
-
/* Push a definition of struct, union or enum tag named ID. into
binding_level B. DECL is a TYPE_DECL for the type. DECL has
already been pushed into its binding level. This is bookkeeping to
static void
set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b)
{
- tree type;
+ while (b->kind == sk_template_parms)
+ b = b->level_chain;
- if (b->kind != sk_namespace)
- {
- /* Shadow the marker, not the real thing, so that the marker
- gets restored later. */
- tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
- b->type_shadowed = tree_cons (id, old_type_value, b->type_shadowed);
- type = decl ? TREE_TYPE (decl) : NULL_TREE;
- TREE_TYPE (b->type_shadowed) = type;
- }
+ if (b->kind == sk_namespace)
+ /* At namespace scope we should not see an identifier type value. */
+ gcc_checking_assert (!REAL_IDENTIFIER_TYPE_VALUE (id));
else
{
- gcc_assert (decl);
-
- /* Store marker instead of real type. */
- type = global_type_node;
+ /* Push the current type value, so we can restore it later */
+ tree old = REAL_IDENTIFIER_TYPE_VALUE (id);
+ b->type_shadowed = tree_cons (id, old, b->type_shadowed);
+ tree type = decl ? TREE_TYPE (decl) : NULL_TREE;
+ TREE_TYPE (b->type_shadowed) = type;
+ SET_IDENTIFIER_TYPE_VALUE (id, type);
}
-
- SET_IDENTIFIER_TYPE_VALUE (id, type);
}
/* As set_identifier_type_value_with_scope, but using
(*debug_hooks->early_global_decl) (alias);
}
-/* Like pushdecl, only it places X in the current namespace,
+/* Like pushdecl, only it places DECL in the current namespace,
if appropriate. */
tree
-pushdecl_namespace_level (tree x, bool hiding)
+pushdecl_namespace_level (tree decl, bool hiding)
{
- cp_binding_level *b = current_binding_level;
- tree t;
-
bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
- t = do_pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), hiding);
-
- /* Now, the type_shadowed stack may screw us. Munge it so it does
- what we want. */
- if (TREE_CODE (t) == TYPE_DECL)
- {
- tree name = DECL_NAME (t);
- tree newval;
- tree *ptr = (tree *)0;
- for (; !global_scope_p (b); b = b->level_chain)
- {
- tree shadowed = b->type_shadowed;
- for (; shadowed; shadowed = TREE_CHAIN (shadowed))
- if (TREE_PURPOSE (shadowed) == name)
- {
- ptr = &TREE_VALUE (shadowed);
- /* Can't break out of the loop here because sometimes
- a binding level will have duplicate bindings for
- PT names. It's gross, but I haven't time to fix it. */
- }
- }
- newval = TREE_TYPE (t);
- if (ptr == (tree *)0)
- {
- /* @@ This shouldn't be needed. My test case "zstring.cc" trips
- up here if this is changed to an assertion. --KR */
- SET_IDENTIFIER_TYPE_VALUE (name, t);
- }
- else
- {
- *ptr = newval;
- }
- }
+ tree res = do_pushdecl_with_scope (decl, NAMESPACE_LEVEL (current_namespace),
+ hiding);
timevar_cond_stop (TV_NAME_LOOKUP, subtime);
- return t;
+ return res;
}
/* Wrapper around push_local_binding to push the bindings for
{
tree decl;
+ gcc_assert (identifier_p (name));
+
cp_binding_level *b = current_binding_level;
while (true)
{
break;
}
- gcc_assert (identifier_p (name));
-
/* Do C++ gratuitous typedefing. */
- if (identifier_type_value_1 (name) != type)
+ if (REAL_IDENTIFIER_TYPE_VALUE (name) != type)
{
tree tdef;
tree context = TYPE_CONTEXT (type);
#define BINDING_VECTOR_PENDING_IS_PARTITION_P(NODE) \
(BINDING_VECTOR_CHECK (NODE)->base.private_flag)
-extern tree identifier_type_value (tree);
extern void set_identifier_type_value (tree, tree);
extern void push_binding (tree, tree, cp_binding_level*);
extern void pop_local_binding (tree, tree);
instantiation, but the TYPE is not.) */
CLASSTYPE_USE_TEMPLATE (newtag) = 0;
- /* Now, we call pushtag to put this NEWTAG into the scope of
- TYPE. We first set up the IDENTIFIER_TYPE_VALUE to avoid
- pushtag calling push_template_decl. We don't have to do
- this for enums because it will already have been done in
- tsubst_enum. */
- if (name)
- SET_IDENTIFIER_TYPE_VALUE (name, newtag);
- pushtag (name, newtag);
+ /* Now, install the tag. We don't use pushtag
+ because that does too much work -- creating an
+ implicit typedef, which we've already done. */
+ set_identifier_type_value (name, TYPE_NAME (newtag));
+ maybe_add_class_template_decl_list (type, newtag, false);
+ TREE_PUBLIC (TYPE_NAME (newtag)) = true;
+ determine_visibility (TYPE_NAME (newtag));
}
}
else if (DECL_DECLARES_FUNCTION_P (t))
code = TREE_CODE (t);
- if (code == IDENTIFIER_NODE)
- type = IDENTIFIER_TYPE_VALUE (t);
- else
- type = TREE_TYPE (t);
+ gcc_assert (code != IDENTIFIER_NODE);
+ type = TREE_TYPE (t);
gcc_assert (type != unknown_type_node);
if (type == error_mark_node)
return false;
- /* Getting here with global_type_node means we improperly called this
- function on the TREE_TYPE of an IDENTIFIER_NODE. */
- gcc_checking_assert (type != global_type_node);
-
/* If we have not already computed the appropriate value for TYPE,
do so now. */
if (!TYPE_DEPENDENT_P_VALID (type))
if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
{
if (DECL_NAME (fndecl) == NULL_TREE
- || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
+ || (DECL_NAME (fndecl)
+ == DECL_NAME (TYPE_NAME (DECL_CONTEXT (fndecl)))))
error_at (loc,
too_many_p
? G_("too many arguments to constructor %q#D")
--- /dev/null
+// PR 99039, we need to remove the namespace-scope meaning of
+// IDENTIFIER_TYPE_VALUE.
+
+namespace std
+{
+typedef long unsigned int size_t;
+
+template<typename _CharT>
+struct char_traits
+{
+ typedef _CharT char_type;
+
+ template<typename U>
+ static int
+ compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
+};
+
+template<typename _CharT>
+template<typename U>
+int
+char_traits<_CharT>::
+compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
+{
+ return 0;
+}
+
+}
+
+struct CHAR_TRAITS;
+namespace std
+{
+typedef long unsigned int size_t;
+
+struct CHAR_TRAITS
+{
+ typedef char char_type;
+
+ static int
+ compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
+};
+
+int
+CHAR_TRAITS::
+compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
+{
+ return 0;
+}
+
+}
+
+struct CHAR_TRAITS;