Caution: bcs we traveling during RTL pass some of tree types already was removed so it is unlikely to meet TYPE_BINFO/BINFO_VIRTUALS etc
Main structure is tree_base, it included as first field in all other types - for example tree_type_non_common has first field with type tree_type_with_lang_specific,
which has field common with type tree_type_common,
which again has field common with type tree_common,
which has field typed with type tree_typed,
which has field base with type tree_base
Kind of ancient inheritance in pure C
Caution 2: many fields has totally different meaning for concrete types, so GCC strictly stimulate to use macros from tree.h to access all fields
Type of TREE can be obtained with CODE_TREE and name of code with function get_tree_code_name
CODE_TREE returns enum tree_code and it has a lot of values - MAX_TREE_CODES eq 0x175. So lets check only important subset
XXX_CST
represent some constant
- STRING_CST - literal constant, length can be obtained with TREE_STRING_LENGTH and content with TREE_STRING_POINTER. Warning - types and declaration names are not literal constants!
- INTEGER_CST- integer constant, value can be obtained with wi::to_wide call
- POLY_INT_CST- also integer constant, but split to several elements. Count of such values can be extracted with NUM_POLY_INT_COEFFS and each value via POLY_INT_CST_COEFF
BLOCK
represent some block (usually contains VAR & labels declarations and inlined functions). Variables can be obtained with BLOCK_VARS and BLOCK_NONLOCALIZED_VAR (don`t ask me why there is two kind of vars), embedded blocks with BLOCK_SUBBLOCKS and next block with BLOCK_CHAIN (there should be some joke about cryptocurrencies here)
See sample of traveling on function tree in dump_func_tree
XXX_DECL
represent declaration of structure, union, var etc. Often can have name - you should use DECL_NAME which return another tree with code IDENTIFIER_TREE or NULL_TREE. In first case you can get name via IDENTIFIER_POINTER and check if name is really presented via DECL_NAMELESS
Variables can have initial values - you can check this with DECL_INITIAL
Type of declaration can be extracted with TREE_TYPE
For functions you can access first argument with DECL_ARGUMENTS (and remained with DECL_CHAIN) and result with DECL_RESULT
Fields of records can be extracted with TYPE_FIELDS
Offset of field can be extracted with DECL_FIELD_OFFSET
One remarkable declaration is
LABEL_DECL
has type tree_label_decl and contains rtx for some code label which can be extracted with DECL_RTL_IF_SET
XXX_TYPE
represent some type. This is huge topic so I cover only basic things
You can get types name with TYPE_NAME. It again returns another tree with code IDENTIFIER_TREE or NULL_TREE
You can quickly check if some type is function/record/union with XXX_TYPE_P macros like RECORD_OR_UNION_TYPE_P, FUNC_OR_METHOD_TYPE_P, POINTER_TYPE_P etc
Size of type can be extracted with TYPE_SIZE - it returns tree usually with type INTEGER_CST
Enum values can be extracted with TYPE_VALUES
Fields of record/union can be extracted with TYPE_FIELDS
for pointers and references you can extract base type with TREE_TYPE