#define ANON_UNION_TYPE_P(NODE) \
(TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE))
+/* For an ANON_AGGR_TYPE_P the single FIELD_DECL it is used with. */
+#define ANON_AGGR_TYPE_FIELD(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->typeinfo_var)
+
/* Define fields and accessors for nodes representing declared names. */
/* True if TYPE is an unnamed structured type with a typedef for
(*vec)[store++] = elt;
vec_safe_truncate (vec, store);
+ /* Wipe RTTI info. */
+ CLASSTYPE_TYPEINFO_VAR (t) = NULL_TREE;
+
/* Anonymous aggregates cannot have fields with ctors, dtors or complex
assignment operators (because they cannot have these methods themselves).
For anonymous unions this is already checked because they are not allowed
SET_DECL_ASSEMBLER_NAME (vt, name);
reset_decl_linkage (vt);
}
- if (tree ti = CLASSTYPE_TYPEINFO_VAR (type))
- {
- tree name = mangle_typeinfo_for_type (type);
- DECL_NAME (ti) = name;
- SET_DECL_ASSEMBLER_NAME (ti, name);
- TREE_TYPE (name) = type;
- reset_decl_linkage (ti);
- }
+ if (!ANON_AGGR_TYPE_P (type))
+ if (tree ti = CLASSTYPE_TYPEINFO_VAR (type))
+ {
+ tree name = mangle_typeinfo_for_type (type);
+ DECL_NAME (ti) = name;
+ SET_DECL_ASSEMBLER_NAME (ti, name);
+ TREE_TYPE (name) = type;
+ reset_decl_linkage (ti);
+ }
for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
{
tree mem = STRIP_TEMPLATE (m);
{
CLASSTYPE_BEFRIENDING_CLASSES (type_dup)
= CLASSTYPE_BEFRIENDING_CLASSES (type);
- CLASSTYPE_TYPEINFO_VAR (type_dup)
- = CLASSTYPE_TYPEINFO_VAR (type);
+ if (!ANON_AGGR_TYPE_P (type))
+ CLASSTYPE_TYPEINFO_VAR (type_dup)
+ = CLASSTYPE_TYPEINFO_VAR (type);
}
for (tree v = type; v; v = TYPE_NEXT_VARIANT (v))
TYPE_LANG_SPECIFIC (v) = ls;
*chain = decl;
chain = &DECL_CHAIN (decl);
+ if (TREE_CODE (decl) == FIELD_DECL
+ && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
+ ANON_AGGR_TYPE_FIELD
+ (TYPE_MAIN_VARIANT (TREE_TYPE (decl))) = decl;
+
if (TREE_CODE (decl) == USING_DECL
&& TREE_CODE (USING_DECL_SCOPE (decl)) == RECORD_TYPE)
{
if (TREE_CODE (decl) != CONST_DECL)
DECL_CONTEXT (decl) = current_class_type;
+ /* Remember the single FIELD_DECL an anonymous aggregate type is used for. */
+ if (TREE_CODE (decl) == FIELD_DECL
+ && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
+ {
+ gcc_assert (!ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl))));
+ ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl))) = decl;
+ }
+
if (TREE_CODE (decl) == USING_DECL)
/* For now, ignore class-scope USING_DECLS, so that debugging
backends do not see them. */
that are directly reachable. */
tree
-lookup_anon_field (tree t, tree type)
+lookup_anon_field (tree, tree type)
{
tree field;
- t = TYPE_MAIN_VARIANT (t);
-
- for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
- {
- if (TREE_STATIC (field))
- continue;
- if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
- continue;
-
- /* If we find it directly, return the field. */
- if (DECL_NAME (field) == NULL_TREE
- && type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
- {
- return field;
- }
-
- /* Otherwise, it could be nested, search harder. */
- if (DECL_NAME (field) == NULL_TREE
- && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
- {
- tree subfield = lookup_anon_field (TREE_TYPE (field), type);
- if (subfield)
- return subfield;
- }
- }
- return NULL_TREE;
+ type = TYPE_MAIN_VARIANT (type);
+ field = ANON_AGGR_TYPE_FIELD (type);
+ gcc_assert (field);
+ return field;
}
/* Build an expression representing OBJECT.MEMBER. OBJECT is an