+2020-03-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/94172
+ * c-tree.h (C_TYPE_INCOMPLETE_VARS): Define to TYPE_LANG_SLOT_1
+ instead of TYPE_VFIELD, and support it on {RECORD,UNION,ENUMERAL}_TYPE.
+ (TYPE_ACTUAL_ARG_TYPES): Check that it is only used on FUNCTION_TYPEs.
+ * c-decl.c (pushdecl): Push C_TYPE_INCOMPLETE_VARS also to
+ ENUMERAL_TYPEs.
+ (finish_incomplete_vars): New function, moved from finish_struct. Use
+ relayout_decl instead of layout_decl.
+ (finish_struct): Remove obsolete comment about C_TYPE_INCOMPLETE_VARS
+ being TYPE_VFIELD. Use finish_incomplete_vars.
+ (finish_enum): Clear C_TYPE_INCOMPLETE_VARS. Call
+ finish_incomplete_vars.
+ * c-typeck.c (c_build_qualified_type): Clear C_TYPE_INCOMPLETE_VARS
+ also on ENUMERAL_TYPEs.
+
2020-03-16 Jakub Jelinek <jakub@redhat.com>
PR c/94179
element = TREE_TYPE (element);
element = TYPE_MAIN_VARIANT (element);
- if (RECORD_OR_UNION_TYPE_P (element)
+ if ((RECORD_OR_UNION_TYPE_P (element)
+ || TREE_CODE (element) == ENUMERAL_TYPE)
&& (TREE_CODE (x) != TYPE_DECL
|| TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
&& !COMPLETE_TYPE_P (element))
return 1;
}
+/* If this structure or union completes the type of any previous
+ variable declaration, lay it out and output its rtl. */
+static void
+finish_incomplete_vars (tree incomplete_vars, bool toplevel)
+{
+ for (tree x = incomplete_vars; x; x = TREE_CHAIN (x))
+ {
+ tree decl = TREE_VALUE (x);
+ if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ layout_array_type (TREE_TYPE (decl));
+ if (TREE_CODE (decl) != TYPE_DECL)
+ {
+ relayout_decl (decl);
+ if (c_dialect_objc ())
+ objc_check_decl (decl);
+ rest_of_decl_compilation (decl, toplevel, 0);
+ }
+ }
+}
+
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
warning_at (loc, 0, "union cannot be made transparent");
}
- /* Note: C_TYPE_INCOMPLETE_VARS overloads TYPE_VFIELD which is used
- in dwarf2out via rest_of_decl_compilation below and means
- something totally different. Since we will be clearing
- C_TYPE_INCOMPLETE_VARS shortly after we iterate through them,
- clear it ahead of time and avoid problems in dwarf2out. Ideally,
- C_TYPE_INCOMPLETE_VARS should use some language specific
- node. */
tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
{
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel);
- /* If this structure or union completes the type of any previous
- variable declaration, lay it out and output its rtl. */
- for (x = incomplete_vars; x; x = TREE_CHAIN (x))
- {
- tree decl = TREE_VALUE (x);
- if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
- layout_array_type (TREE_TYPE (decl));
- if (TREE_CODE (decl) != TYPE_DECL)
- {
- layout_decl (decl, 0);
- if (c_dialect_objc ())
- objc_check_decl (decl);
- rest_of_decl_compilation (decl, toplevel, 0);
- }
- }
+ finish_incomplete_vars (incomplete_vars, toplevel);
/* If we're inside a function proper, i.e. not file-scope and not still
parsing parameters, then arrange for the size of a variable sized type
TYPE_LANG_SPECIFIC (enumtype) = lt;
/* Fix up all variant types of this enum type. */
+ tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (enumtype));
for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem))
{
+ C_TYPE_INCOMPLETE_VARS (tem) = NULL_TREE;
if (tem == enumtype)
continue;
TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
/* Finish debugging output for this type. */
rest_of_type_compilation (enumtype, toplevel);
+ finish_incomplete_vars (incomplete_vars, toplevel);
+
/* If this enum is defined inside a struct, add it to
struct_types. */
if (warn_cxx_compat
nonzero if the definition of the type has already started. */
#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
-/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable
- declarations whose type would be completed by completing that type. */
-#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE)
+/* In an incomplete RECORD_TYPE, UNION_TYPE or ENUMERAL_TYPE, a list of
+ variable declarations whose type would be completed by completing
+ that type. */
+#define C_TYPE_INCOMPLETE_VARS(TYPE) \
+ TYPE_LANG_SLOT_1 (TREE_CHECK4 (TYPE, RECORD_TYPE, UNION_TYPE, \
+ QUAL_UNION_TYPE, ENUMERAL_TYPE))
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
keyword. C_RID_CODE (node) is then the RID_* value of the keyword. */
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
TYPE_ARG_TYPES for functions with prototypes, but created for functions
without prototypes. */
-#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE)
+#define TYPE_ACTUAL_ARG_TYPES(NODE) \
+ TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE))
/* For a CONSTRUCTOR, whether some initializer contains a
subexpression meaning it is not a constant expression. */