+ /* If not NULL, the original type of an expression. This will
+ differ from the type of the value field for an enum constant.
+ The type of an enum constant is a plain integer type, but this
+ field will be the enum type. */
+ tree original_type;
+};
+
+/* A kind of type specifier. Note that this information is currently
+ only used to distinguish tag definitions, tag references and typeof
+ uses. */
+enum c_typespec_kind {
+ /* A reserved keyword type specifier. */
+ ctsk_resword,
+ /* A reference to a tag, previously declared, such as "struct foo".
+ This includes where the previous declaration was as a different
+ kind of tag, in which case this is only valid if shadowing that
+ tag in an inner scope. */
+ ctsk_tagref,
+ /* A reference to a tag, not previously declared in a visible
+ scope. */
+ ctsk_tagfirstref,
+ /* A definition of a tag such as "struct foo { int a; }". */
+ ctsk_tagdef,
+ /* A typedef name. */
+ ctsk_typedef,
+ /* An ObjC-specific kind of type specifier. */
+ ctsk_objc,
+ /* A typeof specifier. */
+ ctsk_typeof
+};
+
+/* A type specifier: this structure is created in the parser and
+ passed to declspecs_add_type only. */
+struct c_typespec {
+ /* What kind of type specifier this is. */
+ enum c_typespec_kind kind;
+ /* The specifier itself. */
+ tree spec;
+ /* An expression to be evaluated before the type specifier, in the
+ case of typeof specifiers, or NULL otherwise or if no such
+ expression is required for a particular typeof specifier. In
+ particular, when typeof is applied to an expression of variably
+ modified type, that expression must be evaluated in order to
+ determine array sizes that form part of the type, but the
+ expression itself (as opposed to the array sizes) forms no part
+ of the type and so needs to be recorded separately. */
+ tree expr;
+ /* Whether the expression has operands suitable for use in constant
+ expressions. */
+ bool expr_const_operands;
+};
+
+/* A storage class specifier. */
+enum c_storage_class {
+ csc_none,
+ csc_auto,
+ csc_extern,
+ csc_register,
+ csc_static,
+ csc_typedef
+};
+
+/* A type specifier keyword "void", "_Bool", "char", "int", "float",
+ "double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum",
+ or none of these. */
+enum c_typespec_keyword {
+ cts_none,
+ cts_void,
+ cts_bool,
+ cts_char,
+ cts_int,
+ cts_float,
+ cts_double,
+ cts_dfloat32,
+ cts_dfloat64,
+ cts_dfloat128,
+ cts_fract,
+ cts_accum