module gcctree; import lm.lmd; import lm.licenseGnuGPLv2; extern(C) element gcctrace(char[] s, element code); /* This file contains the definitions and documentation for the tree codes used in GCC. Copyright (C) 1987, 1988, 1993, 1995, 1997, 1998, 2000, 2001, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* For tcc_references, tcc_expression, tcc_comparison, tcc_unary, tcc_binary, and tcc_statement nodes, which use struct tree_exp, the 4th element is the number of argument slots to allocate. This determines the size of the tree node object. Other nodes use different structures, and the size is determined by the tree_union member structure; the 4th element should be zero. Languages that define language-specific tcc_exceptional or tcc_constant codes must define the tree_size langhook to say how big they are. These tree codes have been sorted so that the macros in tree.h that check for various tree codes are optimized into range checks. This gives a measurable performance improvement. When adding a new code, consider its placement in relation to the other codes. */ /* Any erroneous construct is parsed into a node of this type. This type of node is accepted without complaint in all contexts by later parsing activities, to avoid multiple error messages for one error. No fields in these nodes are used except the TREE_CODE. */ /* code name: ERROR_MARK code class: tcc_exceptional count: 0 */ extern(C) element error_mark(inout stream s, element code){ // operations that yield a new code value gcctrace("error_mark", code); return code; } /* Used to represent a name (such as, in the DECL_NAME of a decl node). Internally it looks like a STRING_CST node. There is only one IDENTIFIER_NODE ever made for any particular name. Use `get_identifier' to get it (or create it, the first time). */ /* code name: IDENTIFIER_NODE code class: tcc_exceptional count: 0 */ extern(C) element identifier_node(inout stream s, element code){ // operations that yield a new code value gcctrace("identifier_node", code); return code; } /* Has the TREE_VALUE and TREE_PURPOSE fields. */ /* These nodes are made into lists by chaining through the TREE_CHAIN field. The elements of the list live in the TREE_VALUE fields, while TREE_PURPOSE fields are occasionally used as well to get the effect of Lisp association lists. */ /* code name: TREE_LIST code class: tcc_exceptional count: 0 */ extern(C) element tree_list(inout stream s, element code){ // operations that yield a new code value gcctrace("tree_list", code); return code; } /* These nodes contain an array of tree nodes. */ /* code name: TREE_VEC code class: tcc_exceptional count: 0 */ extern(C) element tree_vec(inout stream s, element code){ // operations that yield a new code value gcctrace("tree_vec", code); return code; } /* A symbol binding block. These are arranged in a tree, where the BLOCK_SUBBLOCKS field contains a chain of subblocks chained through the BLOCK_CHAIN field. BLOCK_SUPERCONTEXT points to the parent block. For a block which represents the outermost scope of a function, it points to the FUNCTION_DECL node. BLOCK_VARS points to a chain of decl nodes. BLOCK_TYPE_TAGS points to a chain of types which have their own names. BLOCK_CHAIN points to the next BLOCK at the same level. BLOCK_ABSTRACT_ORIGIN points to the original (abstract) tree node which this block is an instance of, or else is NULL to indicate that this block is not an instance of anything else. When non-NULL, the value could either point to another BLOCK node or it could point to a FUNCTION_DECL node (e.g. in the case of a block representing the outermost scope of a particular inlining of a function). BLOCK_ABSTRACT is nonzero if the block represents an abstract instance of a block (i.e. one which is nested within an abstract instance of an inline function). TREE_ASM_WRITTEN is nonzero if the block was actually referenced in the generated assembly. */ /* code name: BLOCK code class: tcc_exceptional count: 0 */ extern(C) element block(inout stream s, element code){ // operations that yield a new code value gcctrace("block", code); return code; } /* Each data type is represented by a tree node whose code is one of the following: */ /* Each node that represents a data type has a component TYPE_SIZE containing a tree that is an expression for the size in bits. The TYPE_MODE contains the machine mode for values of this type. The TYPE_POINTER_TO field contains a type for a pointer to this type, or zero if no such has been created yet. The TYPE_NEXT_VARIANT field is used to chain together types that are variants made by type modifiers such as "const" and "volatile". The TYPE_MAIN_VARIANT field, in any member of such a chain, points to the start of the chain. The TYPE_NONCOPIED_PARTS field is a list specifying which parts of an object of this type should *not* be copied by assignment. The TREE_VALUE of each is a FIELD_DECL that should not be copied. The TREE_PURPOSE is an initial value for that field when an object of this type is initialized via an INIT_EXPR. It may be NULL if no special value is required. Even the things in this list are copied if the right-hand side of an assignment is known to be a complete object (rather than being, perhaps, a subobject of some other object.) The determination of what constitutes a complete object is done by fixed_type_p. The TYPE_NAME field contains info on the name used in the program for this type (for GDB symbol table output). It is either a TYPE_DECL node, for types that are typedefs, or an IDENTIFIER_NODE in the case of structs, unions or enums that are known with a tag, or zero for types that have no special name. The TYPE_CONTEXT for any sort of type which could have a name or which could have named members (e.g. tagged types in C/C++) will point to the node which represents the scope of the given type, or will be NULL_TREE if the type has "file scope". For most types, this will point to a BLOCK node or a FUNCTION_DECL node, but it could also point to a FUNCTION_TYPE node (for types whose scope is limited to the formal parameter list of some function type specification) or it could point to a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE node (for C++ "member" types). For non-tagged-types, TYPE_CONTEXT need not be set to anything in particular, since any type which is of some type category (e.g. an array type or a function type) which cannot either have a name itself or have named members doesn't really have a "scope" per se. The TREE_CHAIN field is used as a forward-references to names for ENUMERAL_TYPE, RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE nodes; see below. */ /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the compiler. OFFSET_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, CHAR_TYPE, INTEGER_TYPE, REAL_TYPE, POINTER_TYPE. */ /* An offset is a pointer relative to an object. The TREE_TYPE field is the type of the object at the offset. The TYPE_OFFSET_BASETYPE points to the node for the type of object that the offset is relative to. */ /* code name: OFFSET_TYPE code class: tcc_type count: 0 */ extern(C) element offset_type(inout stream s, element code){ // operations that yield a new code value gcctrace("offset_type", code); return code; } /* C enums. The type node looks just like an INTEGER_TYPE node. The symbols for the values of the enum type are defined by CONST_DECL nodes, but the type does not point to them; however, the TYPE_VALUES is a list in which each element's TREE_PURPOSE is a name and the TREE_VALUE is the value (an INTEGER_CST node). */ /* A forward reference `enum foo' when no enum named foo is defined yet has zero (a null pointer) in its TYPE_SIZE. The tag name is in the TYPE_NAME field. If the type is later defined, the normal fields are filled in. RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE forward refs are treated similarly. */ /* code name: ENUMERAL_TYPE code class: tcc_type count: 0 */ extern(C) element enumeral_type(inout stream s, element code){ // operations that yield a new code value gcctrace("enumeral_type", code); return code; } /* Boolean type (true or false are the only values). Looks like an INTEGRAL_TYPE. */ /* code name: BOOLEAN_TYPE code class: tcc_type count: 0 */ extern(C) element boolean_type(inout stream s, element code){ // operations that yield a new code value gcctrace("boolean_type", code); return code; } /* CHAR in Java; not used in C. Looks like an INTEGRAL_TYPE. */ /* code name: CHAR_TYPE code class: tcc_type count: 0 */ extern(C) element char_type(inout stream s, element code){ // operations that yield a new code value gcctrace("char_type", code); return code; } /* Integer types in all languages, including char in C. Also used for sub-ranges of other discrete types. Has components TYPE_MIN_VALUE, TYPE_MAX_VALUE (expressions, inclusive) and TYPE_PRECISION (number of bits used by this type). In the case of a subrange type in Pascal, the TREE_TYPE of this will point at the supertype (another INTEGER_TYPE, or an ENUMERAL_TYPE, CHAR_TYPE, or BOOLEAN_TYPE). Otherwise, the TREE_TYPE is zero. */ /* code name: INTEGER_TYPE code class: tcc_type count: 0 */ extern(C) element integer_type(inout stream s, element code){ // operations that yield a new code value gcctrace("integer_type", code); return code; } /* C's float and double. Different floating types are distinguished by machine mode and by the TYPE_SIZE and the TYPE_PRECISION. */ /* code name: REAL_TYPE code class: tcc_type count: 0 */ extern(C) element real_type(inout stream s, element code){ // operations that yield a new code value gcctrace("real_type", code); return code; } /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the compiler. POINTER_TYPE, REFERENCE_TYPE. Note that this range overlaps the previous range of ordered types. */ /* All pointer-to-x types have code POINTER_TYPE. The TREE_TYPE points to the node for the type pointed to. */ /* code name: POINTER_TYPE code class: tcc_type count: 0 */ extern(C) element pointer_type(inout stream s, element code){ // operations that yield a new code value gcctrace("pointer_type", code); return code; } /* A reference is like a pointer except that it is coerced automatically to the value it points to. Used in C++. */ /* code name: REFERENCE_TYPE code class: tcc_type count: 0 */ extern(C) element reference_type(inout stream s, element code){ // operations that yield a new code value gcctrace("reference_type", code); return code; } /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the compiler. COMPLEX_TYPE, VECTOR_TYPE, ARRAY_TYPE. */ /* Complex number types. The TREE_TYPE field is the data type of the real and imaginary parts. */ /* code name: COMPLEX_TYPE code class: tcc_type count: 0 */ extern(C) element complex_type(inout stream s, element code){ // operations that yield a new code value gcctrace("complex_type", code); return code; } /* Vector types. The TREE_TYPE field is the data type of the vector elements. The TYPE_PRECISION field is the number of subparts of the vector. */ /* code name: VECTOR_TYPE code class: tcc_type count: 0 */ extern(C) element vector_type(inout stream s, element code){ // operations that yield a new code value gcctrace("vector_type", code); return code; } /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the compiler. ARRAY_TYPE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE. Note that this range overlaps the previous range. */ /* Types of arrays. Special fields: TREE_TYPE Type of an array element. TYPE_DOMAIN Type to index by. Its range of values specifies the array length. The field TYPE_POINTER_TO (TREE_TYPE (array_type)) is always nonzero and holds the type to coerce a value of that array type to in C. TYPE_STRING_FLAG indicates a string (in contrast to an array of chars) in languages (such as Chill) that make a distinction. */ /* Array types in C or Pascal */ /* code name: ARRAY_TYPE code class: tcc_type count: 0 */ extern(C) element array_type(inout stream s, element code){ // operations that yield a new code value gcctrace("array_type", code); return code; } /* Struct in C, or record in Pascal. */ /* Special fields: TYPE_FIELDS chain of FIELD_DECLs for the fields of the struct, and VAR_DECLs, TYPE_DECLs and CONST_DECLs for record-scope variables, types and enumerators. A few may need to be added for Pascal. */ /* See the comment above, before ENUMERAL_TYPE, for how forward references to struct tags are handled in C. */ /* code name: RECORD_TYPE code class: tcc_type count: 0 */ extern(C) element record_type(inout stream s, element code){ // operations that yield a new code value gcctrace("record_type", code); return code; } /* Union in C. Like a struct, except that the offsets of the fields will all be zero. */ /* See the comment above, before ENUMERAL_TYPE, for how forward references to union tags are handled in C. */ /* code name: UNION_TYPE code class: tcc_type count: 0 */ extern(C) element union_type(inout stream s, element code){ // operations that yield a new code value gcctrace("union_type", code); return code; } /* C union type */ /* Similar to UNION_TYPE, except that the expressions in DECL_QUALIFIER in each FIELD_DECL determine what the union contains. The first field whose DECL_QUALIFIER expression is true is deemed to occupy the union. */ /* code name: QUAL_UNION_TYPE code class: tcc_type count: 0 */ extern(C) element qual_union_type(inout stream s, element code){ // operations that yield a new code value gcctrace("qual_union_type", code); return code; } /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the compiler. VOID_TYPE, FUNCTION_TYPE, METHOD_TYPE. */ /* The void type in C */ /* code name: VOID_TYPE code class: tcc_type count: 0 */ extern(C) element void_type(inout stream s, element code){ // operations that yield a new code value gcctrace("void_type", code); return code; } /* Type of functions. Special fields: TREE_TYPE type of value returned. TYPE_ARG_TYPES list of types of arguments expected. this list is made of TREE_LIST nodes. Types of "Procedures" in languages where they are different from functions have code FUNCTION_TYPE also, but then TREE_TYPE is zero or void type. */ /* code name: FUNCTION_TYPE code class: tcc_type count: 0 */ extern(C) element function_type(inout stream s, element code){ // operations that yield a new code value gcctrace("function_type", code); return code; } /* METHOD_TYPE is the type of a function which takes an extra first argument for "self", which is not present in the declared argument list. The TREE_TYPE is the return type of the method. The TYPE_METHOD_BASETYPE is the type of "self". TYPE_ARG_TYPES is the real argument list, which includes the hidden argument for "self". */ /* code name: METHOD_TYPE code class: tcc_type count: 0 */ extern(C) element method_type(inout stream s, element code){ // operations that yield a new code value gcctrace("method_type", code); return code; } /* This is a language-specific kind of type. Its meaning is defined by the language front end. layout_type does not know how to lay this out, so the front-end must do so manually. */ /* code name: LANG_TYPE code class: tcc_type count: 0 */ extern(C) element lang_type(inout stream s, element code){ // operations that yield a new code value gcctrace("lang_type", code); return code; } /* Expressions */ /* First, the constants. */ /* Contents are in TREE_INT_CST_LOW and TREE_INT_CST_HIGH fields, 32 bits each, giving us a 64 bit constant capability. INTEGER_CST nodes can be shared, and therefore should be considered read only. They should be copied, before setting a flag such as TREE_OVERFLOW. If an INTEGER_CST has TREE_OVERFLOW or TREE_CONSTANT_OVERFLOW already set, it is known to be unique. INTEGER_CST nodes are created for the integral types, for pointer types and for vector and float types in some circumstances. */ /* code name: INTEGER_CST code class: tcc_constant count: 0 */ extern(C) element integer_cst(inout stream s, element code){ // operations that yield a new code value gcctrace("integer_cst", code); return code; } /* Contents are in TREE_REAL_CST field. */ /* code name: REAL_CST code class: tcc_constant count: 0 */ extern(C) element real_cst(inout stream s, element code){ // operations that yield a new code value gcctrace("real_cst", code); return code; } /* Contents are in TREE_REALPART and TREE_IMAGPART fields, whose contents are other constant nodes. */ /* code name: COMPLEX_CST code class: tcc_constant count: 0 */ extern(C) element complex_cst(inout stream s, element code){ // operations that yield a new code value gcctrace("complex_cst", code); return code; } /* Contents are in TREE_VECTOR_CST_ELTS field. */ /* code name: VECTOR_CST code class: tcc_constant count: 0 */ extern(C) element vector_cst(inout stream s, element code){ // operations that yield a new code value gcctrace("vector_cst", code); return code; } /* Contents are TREE_STRING_LENGTH and the actual contents of the string. */ /* code name: STRING_CST code class: tcc_constant count: 0 */ extern(C) element string_cst(inout stream s, element code){ // operations that yield a new code value gcctrace("string_cst", code); return code; } /* Declarations. All references to names are represented as ..._DECL nodes. The decls in one binding context are chained through the TREE_CHAIN field. Each DECL has a DECL_NAME field which contains an IDENTIFIER_NODE. (Some decls, most often labels, may have zero as the DECL_NAME). DECL_CONTEXT points to the node representing the context in which this declaration has its scope. For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL, and CONST_DECL nodes, this points to either the FUNCTION_DECL for the containing function, the RECORD_TYPE or UNION_TYPE for the containing type, or NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file scope". DECL_ABSTRACT_ORIGIN, if non-NULL, points to the original (abstract) ..._DECL node of which this decl is an (inlined or template expanded) instance. The TREE_TYPE field holds the data type of the object, when relevant. LABEL_DECLs have no data type. For TYPE_DECL, the TREE_TYPE field contents are the type whose name is being declared. The DECL_ALIGN, DECL_SIZE, and DECL_MODE fields exist in decl nodes just as in type nodes. They are unused in LABEL_DECL, TYPE_DECL and CONST_DECL nodes. DECL_FIELD_BIT_OFFSET holds an integer number of bits offset for the location. DECL_VOFFSET holds an expression for a variable offset; it is to be multiplied by DECL_VOFFSET_UNIT (an integer). These fields are relevant only in FIELD_DECLs and PARM_DECLs. DECL_INITIAL holds the value to initialize a variable to, or the value of a constant. For a function, it holds the body (a node of type BLOCK representing the function's binding contour and whose body contains the function's statements.) For a LABEL_DECL in C, it is a flag, nonzero if the label's definition has been seen. PARM_DECLs use a special field: DECL_ARG_TYPE is the type in which the argument is actually passed, which may be different from its type within the function. FUNCTION_DECLs use four special fields: DECL_ARGUMENTS holds a chain of PARM_DECL nodes for the arguments. DECL_RESULT holds a RESULT_DECL node for the value of a function, or it is 0 for a function that returns no value. (C functions returning void have zero here.) The TREE_TYPE field is the type in which the result is actually returned. This is usually the same as the return type of the FUNCTION_DECL, but it may be a wider integer type because of promotion. DECL_FUNCTION_CODE is a code number that is nonzero for built-in functions. Its value is an enum built_in_function that says which built-in function it is. DECL_SOURCE_FILE holds a filename string and DECL_SOURCE_LINE holds a line number. In some cases these can be the location of a reference, if no definition has been seen. DECL_ABSTRACT is nonzero if the decl represents an abstract instance of a decl (i.e. one which is nested within an abstract instance of a inline function. */ /* code name: FUNCTION_DECL code class: tcc_declaration count: 0 */ extern(C) element function_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("function_decl", code); return code; } /* code name: LABEL_DECL code class: tcc_declaration count: 0 */ extern(C) element label_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("label_decl", code); return code; } /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the compiler. FIELD_DECL, VAR_DECL, CONST_DECL, PARM_DECL, TYPE_DECL. */ /* code name: FIELD_DECL code class: tcc_declaration count: 0 */ extern(C) element field_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("field_decl", code); return code; } /* code name: VAR_DECL code class: tcc_declaration count: 0 */ extern(C) element var_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("var_decl", code); return code; } /* code name: CONST_DECL code class: tcc_declaration count: 0 */ extern(C) element const_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("const_decl", code); return code; } /* code name: PARM_DECL code class: tcc_declaration count: 0 */ extern(C) element parm_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("parm_decl", code); return code; } /* code name: TYPE_DECL code class: tcc_declaration count: 0 */ extern(C) element type_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("type_decl", code); return code; } /* code name: RESULT_DECL code class: tcc_declaration count: 0 */ extern(C) element result_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("result_decl", code); return code; } /* A namespace declaration. Namespaces appear in DECL_CONTEXT of other _DECLs, providing a hierarchy of names. */ /* code name: NAMESPACE_DECL code class: tcc_declaration count: 0 */ extern(C) element namespace_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("namespace_decl", code); return code; } /* A translation unit. This is not technically a declaration, since it can't be looked up, but it's close enough. */ /* code name: TRANSLATION_UNIT_DECL code class: tcc_declaration count: 0 */ extern(C) element translation_unit_decl(inout stream s, element code){ // operations that yield a new code value gcctrace("translation_unit_decl", code); return code; } /* References to storage. */ /* Value is structure or union component. Operand 0 is the structure or union (an expression). Operand 1 is the field (a node of type FIELD_DECL). Operand 2, if present, is the value of DECL_FIELD_OFFSET, measured in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. */ /* code name: COMPONENT_REF code class: tcc_reference count: 3 */ extern(C) element component_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("component_ref", code); return code; } /* Reference to a group of bits within an object. Similar to COMPONENT_REF except the position is given explicitly rather than via a FIELD_DECL. Operand 0 is the structure or union expression; operand 1 is a tree giving the number of bits being referenced; operand 2 is a tree giving the position of the first referenced bit. The field can be either a signed or unsigned field; BIT_FIELD_REF_UNSIGNED says which. */ /* code name: BIT_FIELD_REF code class: tcc_reference count: 3 */ extern(C) element bit_field_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("bit_field_ref", code); return code; } /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the compiler. INDIRECT_REF, ALIGN_INDIRECT_REF, MISALIGNED_INDIRECT_REF. */ /* C unary `*' or Pascal `^'. One operand, an expression for a pointer. */ /* code name: INDIRECT_REF code class: tcc_reference count: 1 */ extern(C) element indirect_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("indirect_ref", code); return code; } /* Like above, but aligns the referenced address (i.e, if the address in P is not aligned on TYPE_ALIGN boundary, then &(*P) != P). */ /* code name: ALIGN_INDIRECT_REF code class: tcc_reference count: 1 */ extern(C) element align_indirect_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("align_indirect_ref", code); return code; } /* Same as INDIRECT_REF, but also specifies the alignment of the referenced address: Operand 0 is the referenced address (a pointer); Operand 1 is an INTEGER_CST which represents the alignment of the address, or 0 if the alignment is unknown. */ /* code name: MISALIGNED_INDIRECT_REF code class: tcc_reference count: 2 */ extern(C) element misaligned_indirect_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("misaligned_indirect_ref", code); return code; } /* Array indexing. Operand 0 is the array; operand 1 is a (single) array index. Operand 2, if present, is a copy of TYPE_MIN_VALUE of the index. Operand 3, if present, is the element size, measured in units of the alignment of the element type. */ /* code name: ARRAY_REF code class: tcc_reference count: 4 */ extern(C) element array_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("array_ref", code); return code; } /* Likewise, except that the result is a range ("slice") of the array. The starting index of the resulting array is taken from operand 1 and the size of the range is taken from the type of the expression. */ /* code name: ARRAY_RANGE_REF code class: tcc_reference count: 4 */ extern(C) element array_range_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("array_range_ref", code); return code; } /* Used to represent lookup of runtime type dependent data. Often this is a reference to a vtable, but it needn't be. Operands are: OBJ_TYPE_REF_EXPR: An expression that evaluates the value to use. OBJ_TYPE_REF_OBJECT: Is the object on whose behalf the lookup is being performed. Through this the optimizers may be able to statically determine the dynamic type of the object. OBJ_TYPE_REF_TOKEN: Something front-end specific used to resolve the reference to something simpler, usually to the address of a DECL. Never touched by the middle-end. Good choices would be either an identifier or a vtable index. */ /* code name: OBJ_TYPE_REF code class: tcc_expression count: 3 */ extern(C) element obj_type_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("obj_type_ref", code); return code; } /* The exception object from the runtime. */ /* code name: EXC_PTR_EXPR code class: tcc_expression count: 0 */ extern(C) element exc_ptr_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("exc_ptr_expr", code); return code; } /* The filter object from the runtime. */ /* code name: FILTER_EXPR code class: tcc_expression count: 0 */ extern(C) element filter_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("filter_expr", code); return code; } /* Constructor: return an aggregate value made from specified components. In C, this is used only for structure and array initializers. The operand is a sequence of component values made out of a VEC of struct constructor_elt. For ARRAY_TYPE: The field INDEX of each constructor_elt is the corresponding index. If the index is a RANGE_EXPR, it is a short-hand for many nodes, one for each index in the range. (If the corresponding field VALUE has side-effects, they are evaluated once for each element. Wrap the value in a SAVE_EXPR if you want to evaluate side effects only once.) For RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE: The field INDEX of each node is a FIELD_DECL. */ /* code name: CONSTRUCTOR code class: tcc_exceptional count: 0 */ extern(C) element constructor(inout stream s, element code){ // operations that yield a new code value gcctrace("constructor", code); return code; } /* The expression types are mostly straightforward, with the fourth argument of DEFTREECODE saying how many operands there are. Unless otherwise specified, the operands are expressions and the types of all the operands and the expression must all be the same. */ /* Contains two expressions to compute, one followed by the other. the first value is ignored. The second one's value is used. The type of the first expression need not agree with the other types. */ /* code name: COMPOUND_EXPR code class: tcc_expression count: 2 */ extern(C) element compound_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("compound_expr", code); return code; } /* Assignment expression. Operand 0 is the what to set; 1, the new value. */ /* code name: MODIFY_EXPR code class: tcc_expression count: 2 */ extern(C) element modify_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("modify_expr", code); return code; } /* Initialization expression. Operand 0 is the variable to initialize; Operand 1 is the initializer. */ /* code name: INIT_EXPR code class: tcc_expression count: 2 */ extern(C) element init_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("init_expr", code); return code; } /* For TARGET_EXPR, operand 0 is the target of an initialization, operand 1 is the initializer for the target, which may be void if simply expanding it initializes the target. operand 2 is the cleanup for this node, if any. operand 3 is the saved initializer after this node has been expanded once; this is so we can re-expand the tree later. */ /* code name: TARGET_EXPR code class: tcc_expression count: 4 */ extern(C) element target_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("target_expr", code); return code; } /* Conditional expression ( ... ? ... : ... in C). Operand 0 is the condition. Operand 1 is the then-value. Operand 2 is the else-value. Operand 0 may be of any type. Operand 1 must have the same type as the entire expression, unless it unconditionally throws an exception, in which case it should have VOID_TYPE. The same constraints apply to operand 2. */ /* code name: COND_EXPR code class: tcc_expression count: 3 */ extern(C) element cond_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("cond_expr", code); return code; } /* Vector conditional expression. It is like COND_EXPR, but with vector operands. A = VEC_COND_EXPR ( X < Y, B, C) means for (i=0; i.BAR to calculate TYPE_SIZE (FOO), just substitute above with a PLACEHOLDER_EXPR whose TREE_TYPE is FOO. Then construct your COMPONENT_REF with the PLACEHOLDER_EXPR as the first operand (which has the correct type). Later, when the size is needed in the program, the back-end will find this PLACEHOLDER_EXPR and generate code to calculate the actual size at run-time. In the following, we describe how this calculation is done. When we wish to evaluate a size or offset, we check whether it contains a PLACEHOLDER_EXPR. If it does, we call substitute_placeholder_in_expr passing both that tree and an expression within which the object may be found. The latter expression is the object itself in the simple case of an Ada record with discriminant, but it can be the array in the case of an unconstrained array. In the latter case, we need the fat pointer, because the bounds of the array can only be accessed from it. However, we rely here on the fact that the expression for the array contains the dereference of the fat pointer that obtained the array pointer. */ /* Denotes a record to later be substituted before evaluating this expression. The type of this expression is used to find the record to replace it. */ /* code name: PLACEHOLDER_EXPR code class: tcc_exceptional count: 0 */ extern(C) element placeholder_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("placeholder_expr", code); return code; } /* Simple arithmetic. */ /* code name: PLUS_EXPR code class: tcc_binary count: 2 */ extern(C) element plus_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("plus_expr", code); return code; } /* code name: MINUS_EXPR code class: tcc_binary count: 2 */ extern(C) element minus_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("minus_expr", code); return code; } /* code name: MULT_EXPR code class: tcc_binary count: 2 */ extern(C) element mult_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("mult_expr", code); return code; } /* Division for integer result that rounds the quotient toward zero. */ /* code name: TRUNC_DIV_EXPR code class: tcc_binary count: 2 */ extern(C) element trunc_div_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("trunc_div_expr", code); return code; } /* Division for integer result that rounds the quotient toward infinity. */ /* code name: CEIL_DIV_EXPR code class: tcc_binary count: 2 */ extern(C) element ceil_div_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("ceil_div_expr", code); return code; } /* Division for integer result that rounds toward minus infinity. */ /* code name: FLOOR_DIV_EXPR code class: tcc_binary count: 2 */ extern(C) element floor_div_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("floor_div_expr", code); return code; } /* Division for integer result that rounds toward nearest integer. */ /* code name: ROUND_DIV_EXPR code class: tcc_binary count: 2 */ extern(C) element round_div_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("round_div_expr", code); return code; } /* Four kinds of remainder that go with the four kinds of division. */ /* code name: TRUNC_MOD_EXPR code class: tcc_binary count: 2 */ extern(C) element trunc_mod_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("trunc_mod_expr", code); return code; } /* code name: CEIL_MOD_EXPR code class: tcc_binary count: 2 */ extern(C) element ceil_mod_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("ceil_mod_expr", code); return code; } /* code name: FLOOR_MOD_EXPR code class: tcc_binary count: 2 */ extern(C) element floor_mod_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("floor_mod_expr", code); return code; } /* code name: ROUND_MOD_EXPR code class: tcc_binary count: 2 */ extern(C) element round_mod_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("round_mod_expr", code); return code; } /* Division for real result. */ /* code name: RDIV_EXPR code class: tcc_binary count: 2 */ extern(C) element rdiv_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("rdiv_expr", code); return code; } /* Division which is not supposed to need rounding. Used for pointer subtraction in C. */ /* code name: EXACT_DIV_EXPR code class: tcc_binary count: 2 */ extern(C) element exact_div_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("exact_div_expr", code); return code; } /* Conversion of real to fixed point: four ways to round, like the four ways to divide. CONVERT_EXPR can also be used to convert a real to an integer, and that is what is used in languages that do not have ways of specifying which of these is wanted. Maybe these are not needed. */ /* code name: FIX_TRUNC_EXPR code class: tcc_unary count: 1 */ extern(C) element fix_trunc_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("fix_trunc_expr", code); return code; } /* code name: FIX_CEIL_EXPR code class: tcc_unary count: 1 */ extern(C) element fix_ceil_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("fix_ceil_expr", code); return code; } /* code name: FIX_FLOOR_EXPR code class: tcc_unary count: 1 */ extern(C) element fix_floor_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("fix_floor_expr", code); return code; } /* code name: FIX_ROUND_EXPR code class: tcc_unary count: 1 */ extern(C) element fix_round_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("fix_round_expr", code); return code; } /* Conversion of an integer to a real. */ /* code name: FLOAT_EXPR code class: tcc_unary count: 1 */ extern(C) element float_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("float_expr", code); return code; } /* Unary negation. */ /* code name: NEGATE_EXPR code class: tcc_unary count: 1 */ extern(C) element negate_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("negate_expr", code); return code; } /* Minimum and maximum values. When used with floating point, if both operands are zeros, or if either operand is NaN, then it is unspecified which of the two operands is returned as the result. */ /* code name: MIN_EXPR code class: tcc_binary count: 2 */ extern(C) element min_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("min_expr", code); return code; } /* code name: MAX_EXPR code class: tcc_binary count: 2 */ extern(C) element max_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("max_expr", code); return code; } /* Represents the absolute value of the operand. An ABS_EXPR must have either an INTEGER_TYPE or a REAL_TYPE. The operand of the ABS_EXPR must have the same type. */ /* code name: ABS_EXPR code class: tcc_unary count: 1 */ extern(C) element abs_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("abs_expr", code); return code; } /* Shift operations for shift and rotate. Shift means logical shift if done on an unsigned type, arithmetic shift if done on a signed type. The second operand is the number of bits to shift by; it need not be the same type as the first operand and result. Note that the result is undefined if the second operand is larger than or equal to the first operand's type size. */ /* code name: LSHIFT_EXPR code class: tcc_binary count: 2 */ extern(C) element lshift_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("lshift_expr", code); return code; } /* code name: RSHIFT_EXPR code class: tcc_binary count: 2 */ extern(C) element rshift_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("rshift_expr", code); return code; } /* code name: LROTATE_EXPR code class: tcc_binary count: 2 */ extern(C) element lrotate_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("lrotate_expr", code); return code; } /* code name: RROTATE_EXPR code class: tcc_binary count: 2 */ extern(C) element rrotate_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("rrotate_expr", code); return code; } /* Bitwise operations. Operands have same mode as result. */ /* code name: BIT_IOR_EXPR code class: tcc_binary count: 2 */ extern(C) element bit_ior_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("bit_ior_expr", code); return code; } /* code name: BIT_XOR_EXPR code class: tcc_binary count: 2 */ extern(C) element bit_xor_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("bit_xor_expr", code); return code; } /* code name: BIT_AND_EXPR code class: tcc_binary count: 2 */ extern(C) element bit_and_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("bit_and_expr", code); return code; } /* code name: BIT_NOT_EXPR code class: tcc_unary count: 1 */ extern(C) element bit_not_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("bit_not_expr", code); return code; } /* ANDIF and ORIF allow the second operand not to be computed if the value of the expression is determined from the first operand. AND, OR, and XOR always compute the second operand whether its value is needed or not (for side effects). The operand may have BOOLEAN_TYPE or INTEGER_TYPE. In either case, the argument will be either zero or one. For example, a TRUTH_NOT_EXPR will never have an INTEGER_TYPE VAR_DECL as its argument; instead, a NE_EXPR will be used to compare the VAR_DECL to zero, thereby obtaining a node with value zero or one. */ /* code name: TRUTH_ANDIF_EXPR code class: tcc_expression count: 2 */ extern(C) element truth_andif_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("truth_andif_expr", code); return code; } /* code name: TRUTH_ORIF_EXPR code class: tcc_expression count: 2 */ extern(C) element truth_orif_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("truth_orif_expr", code); return code; } /* code name: TRUTH_AND_EXPR code class: tcc_expression count: 2 */ extern(C) element truth_and_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("truth_and_expr", code); return code; } /* code name: TRUTH_OR_EXPR code class: tcc_expression count: 2 */ extern(C) element truth_or_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("truth_or_expr", code); return code; } /* code name: TRUTH_XOR_EXPR code class: tcc_expression count: 2 */ extern(C) element truth_xor_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("truth_xor_expr", code); return code; } /* code name: TRUTH_NOT_EXPR code class: tcc_expression count: 1 */ extern(C) element truth_not_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("truth_not_expr", code); return code; } /* Relational operators. `EQ_EXPR' and `NE_EXPR' are allowed for any types. The others are allowed only for integer (or pointer or enumeral) or real types. In all cases the operands will have the same type, and the value is always the type used by the language for booleans. */ /* code name: LT_EXPR code class: tcc_comparison count: 2 */ extern(C) element lt_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("lt_expr", code); return code; } /* code name: LE_EXPR code class: tcc_comparison count: 2 */ extern(C) element le_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("le_expr", code); return code; } /* code name: GT_EXPR code class: tcc_comparison count: 2 */ extern(C) element gt_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("gt_expr", code); return code; } /* code name: GE_EXPR code class: tcc_comparison count: 2 */ extern(C) element ge_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("ge_expr", code); return code; } /* code name: EQ_EXPR code class: tcc_comparison count: 2 */ extern(C) element eq_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("eq_expr", code); return code; } /* code name: NE_EXPR code class: tcc_comparison count: 2 */ extern(C) element ne_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("ne_expr", code); return code; } /* Additional relational operators for floating point unordered. */ /* code name: UNORDERED_EXPR code class: tcc_comparison count: 2 */ extern(C) element unordered_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("unordered_expr", code); return code; } /* code name: ORDERED_EXPR code class: tcc_comparison count: 2 */ extern(C) element ordered_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("ordered_expr", code); return code; } /* These are equivalent to unordered or ... */ /* code name: UNLT_EXPR code class: tcc_comparison count: 2 */ extern(C) element unlt_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("unlt_expr", code); return code; } /* code name: UNLE_EXPR code class: tcc_comparison count: 2 */ extern(C) element unle_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("unle_expr", code); return code; } /* code name: UNGT_EXPR code class: tcc_comparison count: 2 */ extern(C) element ungt_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("ungt_expr", code); return code; } /* code name: UNGE_EXPR code class: tcc_comparison count: 2 */ extern(C) element unge_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("unge_expr", code); return code; } /* code name: UNEQ_EXPR code class: tcc_comparison count: 2 */ extern(C) element uneq_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("uneq_expr", code); return code; } /* This is the reverse of uneq_expr. */ /* code name: LTGT_EXPR code class: tcc_comparison count: 2 */ extern(C) element ltgt_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("ltgt_expr", code); return code; } /* code name: RANGE_EXPR code class: tcc_binary count: 2 */ extern(C) element range_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("range_expr", code); return code; } /* Represents a conversion of type of a value. All conversions, including implicit ones, must be represented by CONVERT_EXPR or NOP_EXPR nodes. */ /* code name: CONVERT_EXPR code class: tcc_unary count: 1 */ extern(C) element convert_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("convert_expr", code); return code; } /* Represents a conversion expected to require no code to be generated. */ /* code name: NOP_EXPR code class: tcc_unary count: 1 */ extern(C) element nop_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("nop_expr", code); return code; } /* Value is same as argument, but guaranteed not an lvalue. */ /* code name: NON_LVALUE_EXPR code class: tcc_unary count: 1 */ extern(C) element non_lvalue_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("non_lvalue_expr", code); return code; } /* Represents viewing something of one type as being of a second type. This corresponds to an "Unchecked Conversion" in Ada and roughly to the idiom *(type2 *)&X in C. The only operand is the value to be viewed as being of another type. It is undefined if the type of the input and of the expression have different sizes. This code may also be used within the LHS of a MODIFY_EXPR, in which case no actual data motion may occur. TREE_ADDRESSABLE will be set in this case and GCC must abort if it could not do the operation without generating insns. */ /* code name: VIEW_CONVERT_EXPR code class: tcc_reference count: 1 */ extern(C) element view_convert_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("view_convert_expr", code); return code; } /* Represents something we computed once and will use multiple times. First operand is that expression. After it is evaluated once, it will be replaced by the temporary variable that holds the value. */ /* code name: SAVE_EXPR code class: tcc_expression count: 1 */ extern(C) element save_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("save_expr", code); return code; } /* & in C. Value is the address at which the operand's value resides. Operand may have any mode. Result mode is Pmode. */ /* code name: ADDR_EXPR code class: tcc_expression count: 1 */ extern(C) element addr_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("addr_expr", code); return code; } /* Operand0 is a function constant; result is part N of a function descriptor of type ptr_mode. */ /* code name: FDESC_EXPR code class: tcc_expression count: 2 */ extern(C) element fdesc_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("fdesc_expr", code); return code; } /* Given two real or integer operands of the same type, returns a complex value of the corresponding complex type. */ /* code name: COMPLEX_EXPR code class: tcc_binary count: 2 */ extern(C) element complex_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("complex_expr", code); return code; } /* Complex conjugate of operand. Used only on complex types. */ /* code name: CONJ_EXPR code class: tcc_unary count: 1 */ extern(C) element conj_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("conj_expr", code); return code; } /* Used only on an operand of complex type, these return a value of the corresponding component type. */ /* code name: REALPART_EXPR code class: tcc_reference count: 1 */ extern(C) element realpart_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("realpart_expr", code); return code; } /* code name: IMAGPART_EXPR code class: tcc_reference count: 1 */ extern(C) element imagpart_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("imagpart_expr", code); return code; } /* Nodes for ++ and -- in C. The second arg is how much to increment or decrement by. For a pointer, it would be the size of the object pointed to. */ /* code name: PREDECREMENT_EXPR code class: tcc_expression count: 2 */ extern(C) element predecrement_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("predecrement_expr", code); return code; } /* code name: PREINCREMENT_EXPR code class: tcc_expression count: 2 */ extern(C) element preincrement_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("preincrement_expr", code); return code; } /* code name: POSTDECREMENT_EXPR code class: tcc_expression count: 2 */ extern(C) element postdecrement_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("postdecrement_expr", code); return code; } /* code name: POSTINCREMENT_EXPR code class: tcc_expression count: 2 */ extern(C) element postincrement_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("postincrement_expr", code); return code; } /* Used to implement `va_arg'. */ /* code name: VA_ARG_EXPR code class: tcc_expression count: 1 */ extern(C) element va_arg_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("va_arg_expr", code); return code; } /* Evaluate operand 1. If and only if an exception is thrown during the evaluation of operand 1, evaluate operand 2. This differs from TRY_FINALLY_EXPR in that operand 2 is not evaluated on a normal or jump exit, only on an exception. */ /* code name: TRY_CATCH_EXPR code class: tcc_statement count: 2 */ extern(C) element try_catch_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("try_catch_expr", code); return code; } /* Evaluate the first operand. The second operand is a cleanup expression which is evaluated on any exit (normal, exception, or jump out) from this expression. */ /* code name: TRY_FINALLY_EXPR code class: tcc_statement count: 2 */ extern(C) element try_finally(inout stream s, element code){ // operations that yield a new code value gcctrace("try_finally", code); return code; } /* These types of expressions have no useful value, and always have side effects. */ /* Used to represent a local declaration. The operand is DECL_EXPR_DECL. */ /* code name: DECL_EXPR code class: tcc_statement count: 1 */ extern(C) element decl_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("decl_expr", code); return code; } /* A label definition, encapsulated as a statement. Operand 0 is the LABEL_DECL node for the label that appears here. The type should be void and the value should be ignored. */ /* code name: LABEL_EXPR code class: tcc_statement count: 1 */ extern(C) element label_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("label_expr", code); return code; } /* GOTO. Operand 0 is a LABEL_DECL node or an expression. The type should be void and the value should be ignored. */ /* code name: GOTO_EXPR code class: tcc_statement count: 1 */ extern(C) element goto_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("goto_expr", code); return code; } /* RETURN. Evaluates operand 0, then returns from the current function. Presumably that operand is an assignment that stores into the RESULT_DECL that hold the value to be returned. The operand may be null. The type should be void and the value should be ignored. */ /* code name: RETURN_EXPR code class: tcc_statement count: 1 */ extern(C) element return_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("return_expr", code); return code; } /* Exit the inner most loop conditionally. Operand 0 is the condition. The type should be void and the value should be ignored. */ /* code name: EXIT_EXPR code class: tcc_statement count: 1 */ extern(C) element exit_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("exit_expr", code); return code; } /* A loop. Operand 0 is the body of the loop. It must contain an EXIT_EXPR or is an infinite loop. The type should be void and the value should be ignored. */ /* code name: LOOP_EXPR code class: tcc_statement count: 1 */ extern(C) element loop_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("loop_expr", code); return code; } /* Switch expression. TREE_TYPE is the original type of the condition, before any language required type conversions. It may be NULL, in which case the original type and final types are assumed to be the same. Operand 0 is the expression used to perform the branch, Operand 1 is the body of the switch, which probably contains CASE_LABEL_EXPRs. It may also be NULL, in which case operand 2 must not be NULL. Operand 2 is either NULL_TREE or a TREE_VEC of the CASE_LABEL_EXPRs of all the cases. */ /* code name: SWITCH_EXPR code class: tcc_statement count: 3 */ extern(C) element switch_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("switch_expr", code); return code; } /* Used to represent a case label. The operands are CASE_LOW and CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a 'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case label. CASE_LABEL is the corresponding LABEL_DECL. */ /* code name: CASE_LABEL_EXPR code class: tcc_statement count: 3 */ extern(C) element case_label_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("case_label_expr", code); return code; } /* RESX. Resume execution after an exception. Operand 0 is a number indicating the exception region that is being left. */ /* code name: RESX_EXPR code class: tcc_statement count: 1 */ extern(C) element resx_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("resx_expr", code); return code; } /* Used to represent an inline assembly statement. ASM_STRING returns a STRING_CST for the instruction (e.g., "mov x, y"). ASM_OUTPUTS, ASM_INPUTS, and ASM_CLOBBERS represent the outputs, inputs, and clobbers for the statement. */ /* code name: ASM_EXPR code class: tcc_statement count: 4 */ extern(C) element asm_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("asm_expr", code); return code; } /* Variable references for SSA analysis. New SSA names are created every time a variable is assigned a new value. The SSA builder uses SSA_NAME nodes to implement SSA versioning. */ /* code name: SSA_NAME code class: tcc_exceptional count: 0 */ extern(C) element ssa_name(inout stream s, element code){ // operations that yield a new code value gcctrace("ssa_name", code); return code; } /* SSA PHI operator. PHI_RESULT is the new SSA_NAME node created by the PHI node. PHI_ARG_LENGTH is the number of arguments. PHI_ARG_ELT returns the Ith tuple from the argument list. Each tuple contains the incoming reaching definition (SSA_NAME node) and the edge via which that definition is coming through. */ /* code name: PHI_NODE code class: tcc_exceptional count: 0 */ extern(C) element phi_node(inout stream s, element code){ // operations that yield a new code value gcctrace("phi_node", code); return code; } /* Used to represent a typed exception handler. CATCH_TYPES is the type (or list of types) handled, and CATCH_BODY is the code for the handler. */ /* code name: CATCH_EXPR code class: tcc_statement count: 2 */ extern(C) element catch_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("catch_expr", code); return code; } /* Used to represent an exception specification. EH_FILTER_TYPES is a list of allowed types, and EH_FILTER_FAILURE is an expression to evaluate on failure. EH_FILTER_MUST_NOT_THROW controls which range type to use when expanding. */ /* code name: EH_FILTER_EXPR code class: tcc_statement count: 2 */ extern(C) element eh_filter_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("eh_filter_expr", code); return code; } /* Node used for describing a property that is known at compile time. */ /* code name: SCEV_KNOWN code class: tcc_expression count: 0 */ extern(C) element scev_known(inout stream s, element code){ // operations that yield a new code value gcctrace("scev_known", code); return code; } /* Node used for describing a property that is not known at compile time. */ /* code name: SCEV_NOT_KNOWN code class: tcc_expression count: 0 */ extern(C) element scev_not_known(inout stream s, element code){ // operations that yield a new code value gcctrace("scev_not_known", code); return code; } /* Polynomial chains of recurrences. Under the form: cr = {CHREC_LEFT (cr), +, CHREC_RIGHT (cr)}. */ /* code name: POLYNOMIAL_CHREC code class: tcc_expression count: 3 */ extern(C) element polynomial_chrec(inout stream s, element code){ // operations that yield a new code value gcctrace("polynomial_chrec", code); return code; } /* Used to chain children of container statements together. Use the interface in tree-iterator.h to access this node. */ /* code name: STATEMENT_LIST code class: tcc_exceptional count: 0 */ extern(C) element statement_list(inout stream s, element code){ // operations that yield a new code value gcctrace("statement_list", code); return code; } /* Value handles. Artificial nodes to represent expressions in partial redundancy elimination (tree-ssa-pre.c). These nodes are used for expression canonicalization. If two expressions compute the same value, they will be assigned the same value handle. */ /* code name: VALUE_HANDLE code class: tcc_exceptional count: 0 */ extern(C) element value_handle(inout stream s, element code){ // operations that yield a new code value gcctrace("value_handle", code); return code; } /* Predicate assertion. Artificial expression generated by the optimizers to keep track of predicate values. This expression may only appear on the RHS of assignments. Given X = ASSERT_EXPR , the optimizers can infer two things: 1- X is a copy of Y. 2- EXPR is a GIMPLE conditional expression (as defined by is_gimple_condexpr) and is known to be true. The type of the expression is the same as Y. */ /* code name: ASSERT_EXPR code class: tcc_expression count: 2 */ extern(C) element assert_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("assert_expr", code); return code; } /* Base class information. Holds information about a class as a baseclass of itself or another class. */ /* code name: TREE_BINFO code class: tcc_exceptional count: 0 */ extern(C) element tree_binfo(inout stream s, element code){ // operations that yield a new code value gcctrace("tree_binfo", code); return code; } /* Records the size for an expression of variable size type. This is for use in contexts in which we are accessing the entire object, such as for a function call, or block copy. Operand 0 is the real expression. Operand 1 is the size of the type in the expression. */ /* code name: WITH_SIZE_EXPR code class: tcc_expression count: 2 */ extern(C) element with_size_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("with_size_expr", code); return code; } /* Extract elements from two input vectors Operand 0 and Operand 1 size VS, according to the offset OFF defined by Operand 2 as follows: If OFF > 0, the last VS - OFF elements of vector OP0 are concatenated to the first OFF elements of the vector OP1. If OFF == 0, then the returned vector is OP1. On different targets OFF may take different forms; It can be an address, in which case its low log2(VS)-1 bits define the offset, or it can be a mask generated by the builtin targetm.vectorize.mask_for_load_builtin_decl. */ /* code name: REALIGN_LOAD_EXPR code class: tcc_expression count: 3 */ extern(C) element realign_load(inout stream s, element code){ // operations that yield a new code value gcctrace("realign_load", code); return code; } /* Low-level memory addressing. Operands are SYMBOL (static or global variable), BASE (register), INDEX (register), STEP (integer constant), OFFSET (integer constant). Corresponding address is SYMBOL + BASE + STEP * INDEX + OFFSET. Only variations and values valid on the target are allowed. The sixth argument is the reference to the original memory access, which is preserved for the purposes of the RTL alias analysis. The seventh argument is a tag representing results of the tree level alias analysis. */ /* code name: TARGET_MEM_REF code class: tcc_reference count: 7 */ extern(C) element target_mem_ref(inout stream s, element code){ // operations that yield a new code value gcctrace("target_mem_ref", code); return code; } /* Reduction operations. Operations that take a vector of elements and "reduce" it to a scalar result (e.g. summing the elements of the vector, finding the minimum over the vector elements, etc). Operand 0 is a vector; the first element in the vector has the result. Operand 1 is a vector. */ /* code name: REDUC_MAX_EXPR code class: tcc_unary count: 1 */ extern(C) element reduc_max_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("reduc_max_expr", code); return code; } /* code name: REDUC_MIN_EXPR code class: tcc_unary count: 1 */ extern(C) element reduc_min_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("reduc_min_expr", code); return code; } /* code name: REDUC_PLUS_EXPR code class: tcc_unary count: 1 */ extern(C) element reduc_plus_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("reduc_plus_expr", code); return code; } /* Whole vector left/right shift in bytes. Operand 0 is a vector to be shifted. Operand 1 is an integer shift amount in bits. */ /* code name: VEC_LSHIFT_EXPR code class: tcc_binary count: 2 */ extern(C) element vec_lshift_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("vec_lshift_expr", code); return code; } /* code name: VEC_RSHIFT_EXPR code class: tcc_binary count: 2 */ extern(C) element vec_rshift_expr(inout stream s, element code){ // operations that yield a new code value gcctrace("vec_rshift_expr", code); return code; } /* Local variables: mode:c End: */