EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT)
STMT_EXPR_NO_SCOPE (in STMT_EXPR)
BIND_EXPR_TRY_BLOCK (in BIND_EXPR)
- TYPENAME_IS_ENUM_P (in TYPENAME_TYPE)
+ TYPENAME_TYPE_TAG_BIT_0 (in TYPENAME_TYPE)
OMP_FOR_GIMPLIFYING_P (in OMP_FOR, OMP_SIMD, OMP_DISTRIBUTE,
and OMP_TASKLOOP)
BASELINK_QUALIFIED_P (in BASELINK)
DELETE_EXPR_USE_VEC (in DELETE_EXPR).
ICS_ELLIPSIS_FLAG (in _CONV)
DECL_INITIALIZED_P (in VAR_DECL)
- TYPENAME_IS_CLASS_P (in TYPENAME_TYPE)
+ TYPENAME_TYPE_TAG_BIT_1 (in TYPENAME_TYPE)
STMT_IS_FULL_EXPR_P (in _STMT)
TARGET_EXPR_LIST_INIT_P (in TARGET_EXPR)
DECL_FINAL_P (in FUNCTION_DECL)
ICS_THIS_FLAG (in _CONV)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
STATEMENT_LIST_TRY_BLOCK (in STATEMENT_LIST)
- TYPENAME_IS_RESOLVING_P (in TYPENAME_TYPE)
+ TYPENAME_TYPE_TAG_BIT_2 (in TYPENAME_TYPE)
TYPE_POLYMORPHIC_P (in RECORD_TYPE and UNION_TYPE)
TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
FNDECL_USED_AUTO (in FUNCTION_DECL)
TARGET_EXPR_ELIDING_P (in TARGET_EXPR)
IF_STMT_VACUOUS_INIT_P (IF_STMT)
contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT)
- TYPENAME_IS_UNION_P (in TYPENAME_TYPE)
+ TYPENAME_IS_RESOLVING_P (in TYPENAME_TYPE)
4: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
CALL_EXPR, or FIELD_DECL).
#define TYPENAME_TYPE_FULLNAME(NODE) \
(TYPE_VALUES_RAW (TYPENAME_TYPE_CHECK (NODE)))
+/* Storage for the tag type of a TYPENAME_TYPE. */
+#define TYPENAME_TYPE_TAG_BIT_0(NODE) \
+ (TREE_LANG_FLAG_0 (TYPENAME_TYPE_CHECK (NODE)))
+#define TYPENAME_TYPE_TAG_BIT_1(NODE) \
+ (TREE_LANG_FLAG_1 (TYPENAME_TYPE_CHECK (NODE)))
+#define TYPENAME_TYPE_TAG_BIT_2(NODE) \
+ (TREE_LANG_FLAG_2 (TYPENAME_TYPE_CHECK (NODE)))
+
/* True if a TYPENAME_TYPE was declared as an "enum". */
#define TYPENAME_IS_ENUM_P(NODE) \
- (TREE_LANG_FLAG_0 (TYPENAME_TYPE_CHECK (NODE)))
+ (get_typename_tag (NODE) == enum_type)
/* True if a TYPENAME_TYPE was declared as a "class" or "struct". */
-#define TYPENAME_IS_CLASS_P(NODE) \
- (TREE_LANG_FLAG_1 (TYPENAME_TYPE_CHECK (NODE)))
+#define TYPENAME_IS_CLASS_OR_STRUCT_P(NODE) \
+ (get_typename_tag (NODE) == class_type \
+ || get_typename_tag (NODE) == record_type)
/* True if a TYPENAME_TYPE was declared as a "union". */
#define TYPENAME_IS_UNION_P(NODE) \
- (TREE_LANG_FLAG_3 (TYPENAME_TYPE_CHECK (NODE)))
+ (get_typename_tag (NODE) == union_type)
/* True if a TYPENAME_TYPE is in the process of being resolved. */
#define TYPENAME_IS_RESOLVING_P(NODE) \
- (TREE_LANG_FLAG_2 (TYPENAME_TYPE_CHECK (NODE)))
+ (TREE_LANG_FLAG_3 (TYPENAME_TYPE_CHECK (NODE)))
/* [class.virtual]
scope_type /* namespace or tagged type name followed by :: */
};
+/* Return the tag type of the given TYPENAME_TYPE. */
+
+inline tag_types
+get_typename_tag (tree t)
+{
+ unsigned bit0 = TYPENAME_TYPE_TAG_BIT_0 (t);
+ unsigned bit1 = TYPENAME_TYPE_TAG_BIT_1 (t);
+ unsigned bit2 = TYPENAME_TYPE_TAG_BIT_2 (t);
+ return tag_types ((bit2 << 2) | (bit1 << 1) | bit0);
+}
+
+/* Set the tag type of the given TYPENAME_TYPE. */
+
+inline void
+set_typename_tag (tree t, tag_types tag)
+{
+ gcc_checking_assert ((tag & 7) == tag);
+ TYPENAME_TYPE_TAG_BIT_0 (t) = (tag >> 0) & 1;
+ TYPENAME_TYPE_TAG_BIT_1 (t) = (tag >> 1) & 1;
+ TYPENAME_TYPE_TAG_BIT_2 (t) = (tag >> 2) & 1;
+}
+
/* The various kinds of lvalues we distinguish. */
enum cp_lvalue_kind_flags {
clk_none = 0, /* Things that are not an lvalue. */
extern void do_push_parm_decls (tree, tree, tree *);
extern tree do_aggregate_paren_init (tree, tree);
extern void maybe_mark_function_versioned (tree);
+extern const char *tag_name (enum tag_types);
/* in decl2.cc */
extern void record_mangling (tree, bool);
static void record_unknown_type (tree, const char *);
static int member_function_or_else (tree, tree, enum overload_flags);
static tree local_variable_p_walkfn (tree *, int *, void *);
-static const char *tag_name (enum tag_types);
static tree lookup_and_check_tag (enum tag_types, tree, TAG_how, bool);
static void maybe_deduce_size_from_array_init (tree, tree);
static void layout_var_decl (tree);
tree scope;
tree name;
tree template_id;
- bool enum_p;
- bool class_p;
- bool union_p;
+ tag_types tag_type;
};
struct typename_hasher : ggc_ptr_hash<tree_node>
return (TYPE_IDENTIFIER (t1) == t2->name
&& TYPE_CONTEXT (t1) == t2->scope
&& TYPENAME_TYPE_FULLNAME (t1) == t2->template_id
- && TYPENAME_IS_ENUM_P (t1) == t2->enum_p
- && TYPENAME_IS_CLASS_P (t1) == t2->class_p
- && TYPENAME_IS_UNION_P (t1) == t2->union_p);
+ && get_typename_tag (t1) == t2->tag_type);
}
};
ti.scope = FROB_CONTEXT (context);
ti.name = name;
ti.template_id = fullname;
- ti.enum_p = tag_type == enum_type;
- ti.class_p = (tag_type == class_type || tag_type == record_type);
- ti.union_p = tag_type == union_type;
+ ti.tag_type = tag_type;
hashval_t hash = typename_hasher::hash (&ti);
/* See if we already have this type. */
t = cxx_make_type (TYPENAME_TYPE);
TYPE_CONTEXT (t) = ti.scope;
TYPENAME_TYPE_FULLNAME (t) = ti.template_id;
- TYPENAME_IS_ENUM_P (t) = ti.enum_p;
- TYPENAME_IS_CLASS_P (t) = ti.class_p;
- TYPENAME_IS_UNION_P (t) = ti.union_p;
+ set_typename_tag (t, ti.tag_type);
/* Build the corresponding TYPE_DECL. */
tree d = build_decl (input_location, TYPE_DECL, name, t);
\f
/* Return a string giving the keyword associate with CODE. */
-static const char *
+const char *
tag_name (enum tag_types code)
{
switch (code)
return "enum";
case typename_type:
return "typename";
- default:
- gcc_unreachable ();
+ case none_type:
+ case scope_type:
+ return nullptr;
}
+ gcc_unreachable ();
}
/* Name lookup in an elaborated-type-specifier (after the keyword
return error_mark_node;
}
- /* FIXME: TYPENAME_IS_CLASS_P conflates 'class' vs 'struct' tags.
- TYPENAME_TYPE should probably remember the exact tag that
- was written for -Wmismatched-tags. */
- enum tag_types tag_type
- = (TYPENAME_IS_CLASS_P (t) ? class_type
- : TYPENAME_IS_UNION_P (t) ? union_type
- : TYPENAME_IS_ENUM_P (t) ? enum_type
- : typename_type);
+ enum tag_types tag_type = get_typename_tag (t);
tsubst_flags_t tcomplain = complain | tf_keep_type_decl;
tcomplain |= tst_ok_flag | qualifying_scope_flag;
f = make_typename_type (ctx, f, tag_type, tcomplain);
else
return error_mark_node;
}
- else if (TYPENAME_IS_CLASS_P (t) && !NON_UNION_CLASS_TYPE_P (f))
+ else if (TYPENAME_IS_CLASS_OR_STRUCT_P (t)
+ && !NON_UNION_CLASS_TYPE_P (f))
{
if (complain & tf_error)
error ("%qT resolves to %qT, which is not a non-union "