Next: Scopes, Previous: Tree overview, Up: Trees
9.3 Types
All types have corresponding tree nodes. However, you should not assume that there is exactly one tree node corresponding to each type. There are often several nodes each of which correspond to the same type.
For the most part, different kinds of types have different tree codes.
(For example, pointer types use a POINTER_TYPE code while arrays
use an ARRAY_TYPE code.) However, pointers to member functions
use the RECORD_TYPE code. Therefore, when writing a
switch statement that depends on the code associated with a
particular type, you should take care to handle pointers to member
functions under the RECORD_TYPE case label.
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 ints.
The following functions and macros deal with cv-qualification of types:
CP_TYPE_QUALS- This macro returns the set of type qualifiers applied to this type.
This value is
TYPE_UNQUALIFIEDif no qualifiers have been applied. TheTYPE_QUAL_CONSTbit is set if the type isconst-qualified. TheTYPE_QUAL_VOLATILEbit is set if the type isvolatile-qualified. TheTYPE_QUAL_RESTRICTbit is set if the type isrestrict-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 notvolatile-qualified; other cv-qualifiers are ignored as well: only theconst-ness is tested. TYPE_MAIN_VARIANT- This macro returns the unqualified version of a type. It may be applied to an unqualified type, but it is not always the identity function in that case.
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_SIZEwill beNULL_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 aIDENTIFIER_NODE, as you might expect, given its name!) You can look at theDECL_NAMEof theTYPE_DECLto obtain the actual name of the type. TheTYPE_NAMEwill beNULL_TREEfor 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 useTYPE_PTROBV_Pto test for a pointer to object type as well asvoid *. same_type_p- This predicate takes two types as input, and holds if they are the same
type. For example, if one type is a
typedeffor the other, or both aretypedefs for the same type. This predicate also holds if the two trees given as input are simply copies of one another; i.e., there is no difference between them at the source level, but, for whatever reason, a duplicate has been made in the representation. You should never use==(pointer equality) to compare types; always usesame_type_pinstead.
Detailed below are the various kinds of types, and the macros that can be used to access them. Although other kinds of types are used elsewhere in G++, the types described here are the only ones that you will encounter while examining the intermediate representation.
VOID_TYPE- Used to represent the
voidtype. INTEGER_TYPE- Used to represent the various integral types, including
char,short,int,long, andlong long. This code is not used for enumeration types, nor for thebooltype. TheTYPE_PRECISIONis the number of bits used in the representation, represented as anunsigned int. (Note that in the general case this is not the same value asTYPE_SIZE; suppose that there were a 24-bit integer type, but that alignment requirements for the ABI required 32-bit alignment. Then,TYPE_SIZEwould be anINTEGER_CSTfor 32, whileTYPE_PRECISIONwould be 24.) The integer type is unsigned ifTYPE_UNSIGNEDholds; otherwise, it is signed.The
TYPE_MIN_VALUEis anINTEGER_CSTfor the smallest integer that may be represented by this type. Similarly, theTYPE_MAX_VALUEis anINTEGER_CSTfor the largest integer that may be represented by this type. REAL_TYPE- Used to represent the
float,double, andlong doubletypes. The number of bits in the floating-point representation is given byTYPE_PRECISION, as in theINTEGER_TYPEcase. COMPLEX_TYPE- Used to represent GCC built-in
__complex__data types. TheTREE_TYPEis the type of the real and imaginary parts. ENUMERAL_TYPE- Used to represent an enumeration type. The
TYPE_PRECISIONgives (as anint), the number of bits used to represent the type. If there are no negative enumeration constants,TYPE_UNSIGNEDwill hold. The minimum and maximum enumeration constants may be obtained withTYPE_MIN_VALUEandTYPE_MAX_VALUE, respectively; each of these macros returns anINTEGER_CST.The actual enumeration constants themselves may be obtained by looking at the
TYPE_VALUES. This macro will return aTREE_LIST, containing the constants. TheTREE_PURPOSEof each node will be anIDENTIFIER_NODEgiving the name of the constant; theTREE_VALUEwill be anINTEGER_CSTgiving the value assigned to that constant. These constants will appear in the order in which they were declared. TheTREE_TYPEof each of these constants will be the type of enumeration type itself. BOOLEAN_TYPE- Used to represent the
booltype. POINTER_TYPE- Used to represent pointer types, and pointer to data member types. The
TREE_TYPEgives the type to which this type points. If the type is a pointer to data member type, thenTYPE_PTRMEM_Pwill hold. For a pointer to data member type of the form `T X::*',TYPE_PTRMEM_CLASS_TYPEwill be the typeX, whileTYPE_PTRMEM_POINTED_TO_TYPEwill be the typeT. REFERENCE_TYPE- Used to represent reference types. The
TREE_TYPEgives the type to which this type refers. FUNCTION_TYPE- Used to represent the type of non-member functions and of static member
functions. The
TREE_TYPEgives the return type of the function. TheTYPE_ARG_TYPESare aTREE_LISTof the argument types. TheTREE_VALUEof each node in this list is the type of the corresponding argument; theTREE_PURPOSEis an expression for the default argument value, if any. If the last node in the list isvoid_list_node(aTREE_LISTnode whoseTREE_VALUEis thevoid_type_node), then functions of this type do not take variable arguments. Otherwise, they do take a variable number of arguments.Note that in C (but not in C++) a function declared like
void f()is an unprototyped function taking a variable number of arguments; theTYPE_ARG_TYPESof such a function will beNULL. METHOD_TYPE- Used to represent the type of a non-static member function. Like a
FUNCTION_TYPE, the return type is given by theTREE_TYPE. The type of*this, i.e., the class of which functions of this type are a member, is given by theTYPE_METHOD_BASETYPE. TheTYPE_ARG_TYPESis the parameter list, as for aFUNCTION_TYPE, and includes thethisargument. ARRAY_TYPE- Used to represent array types. The
TREE_TYPEgives the type of the elements in the array. If the array-bound is present in the type, theTYPE_DOMAINis anINTEGER_TYPEwhoseTYPE_MIN_VALUEandTYPE_MAX_VALUEwill be the lower and upper bounds of the array, respectively. TheTYPE_MIN_VALUEwill always be anINTEGER_CSTfor zero, while theTYPE_MAX_VALUEwill be one less than the number of elements in the array, i.e., the highest value which may be used to index an element in the array. RECORD_TYPE- Used to represent
structandclasstypes, as well as pointers to member functions and similar constructs in other languages.TYPE_FIELDScontains the items contained in this type, each of which can be aFIELD_DECL,VAR_DECL,CONST_DECL, orTYPE_DECL. You may not make any assumptions about the ordering of the fields in the type or whether one or more of them overlap. IfTYPE_PTRMEMFUNC_Pholds, then this type is a pointer-to-member type. In that case, theTYPE_PTRMEMFUNC_FN_TYPEis aPOINTER_TYPEpointing to aMETHOD_TYPE. TheMETHOD_TYPEis the type of a function pointed to by the pointer-to-member function. IfTYPE_PTRMEMFUNC_Pdoes not hold, this type is a class type. For more information, see see Classes. UNION_TYPE- Used to represent
uniontypes. Similar toRECORD_TYPEexcept that allFIELD_DECLnodes inTYPE_FIELDstart at bit position zero. QUAL_UNION_TYPE- Used to represent part of a variant record in Ada. Similar to
UNION_TYPEexcept that eachFIELD_DECLhas aDECL_QUALIFIERfield, which contains a boolean expression that indicates whether the field is present in the object. The type will only have one field, so each field'sDECL_QUALIFIERis only evaluated if none of the expressions in the previous fields inTYPE_FIELDSare nonzero. Normally these expressions will reference a field in the outer object using aPLACEHOLDER_EXPR. UNKNOWN_TYPE- This node is used to represent a type the knowledge of which is
insufficient for a sound processing.
OFFSET_TYPE- This node is used to represent a pointer-to-data member. For a data
member
X::mtheTYPE_OFFSET_BASETYPEisXand theTREE_TYPEis the type ofm. TYPENAME_TYPE- Used to represent a construct of the form
typename T::A. TheTYPE_CONTEXTisT; theTYPE_NAMEis anIDENTIFIER_NODEforA. If the type is specified via a template-id, thenTYPENAME_TYPE_FULLNAMEyields aTEMPLATE_ID_EXPR. TheTREE_TYPEis non-NULLif the node is implicitly generated in support for the implicit typename extension; in which case theTREE_TYPEis a type node for the base-class. TYPEOF_TYPE- Used to represent the
__typeof__extension. TheTYPE_FIELDSis the expression the type of which is being represented.
There are variables whose values represent some of the basic types. These include:
void_type_node- A node for
void. integer_type_node- A node for
int. unsigned_type_node.- A node for
unsigned int. char_type_node.- A node for
char.
same_type_p.