#### 11.10.1 Types for C++

In C++, an array type is not qualified; rather the type of the array elements is qualified. This situation is reflected in the intermediate representation. The macros described here will always examine the qualification of the underlying element type when applied to an array type. (If the element type is itself an array, then the recursion continues until a non-array type is found, and the qualification of this type is examined.) So, for example, `CP_TYPE_CONST_P` will hold of the type `const int ()[7]`, denoting an array of seven `int`s.

The following functions and macros deal with cv-qualification of types:

`cp_type_quals`
  This function returns the set of type qualifiers applied to this type. This value is `TYPE_UNQUALIFIED` if no qualifiers have been applied. The `TYPE_QUAL_CONST` bit is set if the type is `const`-qualified. The `TYPE_QUAL_VOLATILE` bit is set if the type is `volatile`-qualified. The `TYPE_QUAL_RESTRICT` bit is set if the type is `restrict`-qualified.
`CP_TYPE_CONST_P`
  This macro holds if the type is `const`-qualified.
`CP_TYPE_VOLATILE_P`
  This macro holds if the type is `volatile`-qualified.
`CP_TYPE_RESTRICT_P`
  This macro holds if the type is `restrict`-qualified.
`CP_TYPE_CONST_NON_VOLATILE_P`
  This predicate holds for a type that is `const`-qualified, but not `volatile`-qualified; other cv-qualifiers are ignored as well: only the `const`-ness is tested.

A few other macros and functions are usable with all types:

`TYPE_SIZE`
  The number of bits required to represent the type, represented as an `INTEGER_CST`. For an incomplete type, `TYPE_SIZE` will be `NULL_TREE`.
`TYPE_ALIGN`
  The alignment of the type, in bits, represented as an `int`.
`TYPE_NAME`
  This macro returns a declaration (in the form of a `TYPE_DECL`) for the type. (Note this macro does not return an `IDENTIFIER_NODE`, as you might expect, given its name!) You can look at the `DECL_NAME` of the `TYPE_DECL` to obtain the actual name of the type. The `TYPE_NAME` will be `NULL_TREE` for a type that is not a built-in type, the result of a typedef, or a named class type.
`CP_INTEGRAL_TYPE`
  This predicate holds if the type is an integral type. Notice that in C++, enumerations are not integral types.
`ARITHMETIC_TYPE_P`
  This predicate holds if the type is an integral type (in the C++ sense) or a floating point type.
`CLASS_TYPE_P`
  This predicate holds for a class-type.
`TYPE_BUILT_IN`
  This predicate holds for a built-in type.
`TYPE_PTRMEM_P`
  This predicate holds if the type is a pointer to data member.
`TYPE_PTR_P`
  This predicate holds if the type is a pointer type, and the pointee is not a data member.
`TYPE_PTRFN_P`
  This predicate holds for a pointer to function type.
`TYPE_PTROB_P`
  This predicate holds for a pointer to object type. Note however that it does not hold for the generic pointer to object type `void *`. You may use `TYPE_PTROBV_P` to test for a pointer to object type as well as `void *`.

The table below describes types specific to C and C++ as well as language-dependent info about GENERIC types.

`POINTER_TYPE`
  Used to represent pointer types, and pointer to data member types. If `TREE_TYPE` is a pointer to data member type, then `TYPE_PTRMEM_P` will hold. For a pointer to data member type of the form ‘`T X::*`’, `TYPE_PTRMEM_CLASS_TYPE` will be the type `X`, while `TYPE_PTRMEM_POINTED_TO_TYPE` will be the type `T`.
`RECORD_TYPE`
  Used to represent `struct` and `class` types in C and C++. If `TYPE_PTRMEMFUNC_P` holds, then this type is a pointer-to-member type. In that case, the `TYPE_PTRMEMFUNC_FN_TYPE` is a `POINTER_TYPE` pointing to a `METHOD_TYPE`. The `METHOD_TYPE` is the type of a function pointed to by the pointer-to-member function. If `TYPE_PTRMEMFUNC_P` does not hold, this type is a class type. For more information, see Classes.
`UNKNOWN_TYPE`
  This node is used to represent a type the knowledge of which is insufficient for a sound processing.
`TYPENAME_TYPE`
  Used to represent a construct of the form `typename T::A`. The `TYPE_CONTEXT` is `T`; the `TYPE_NAME` is an `IDENTIFIER_NODE` for `A`. If the type is specified via a template-id, then `TYPENAME_TYPE_FULLNAME` yields a `TEMPLATE_ID_EXPR`. The `TREE_TYPE` is non-`NULL` if the node is implicitly generated in support for the implicit typename extension; in which case the `TREE_TYPE` is a type node for the base-class.
`TYPEOF_TYPE`
  Used to represent the `__typeof__` extension. The `TYPE_FIELDS` is the expression the type of which is being represented.