/* tree node types */
typedef enum node_type_e {
	/* statements */
	T_STATEMENT,     /* statement arg: expr|if|switch|while|do|for|break|continue|goto|return */
		/* asm: usually satement but might appear in weird places */
		/* mark empty statement: 'if (c) ;' '.. label: ; }' */
		/* gcc statement expression: 'i = ({foo; bar;})' */
		/* do statement has a statement and a condition child */
	T_BLOCK,         /* compound statement */
	T_ASM,           /* asm("...") child: SCONST */
		/* some asm child nodes aren't supported by c99tree */
/*
gcc extended inline assembly:
           asm ( assembler template
               : output operands              // optional
               : input operands               // optional
               : list of clobbered registers  // optional
               );
example:
            asm ("cld\n\t"
                 "rep\n\t"
                 "stosl"
                 :   // no output registers
                 : "c" (count), "a" (fill_value), "D" (dest)
                 : "%ecx", "%edi"
                 );
*/
	T_LABEL,         /* jump and switch labels */
	T_TYPEDEF,       /* typedef (subtree structure is similar to decl) */
	T_DECL,          /* declaration (child nodes: type, id+) */
		/* the children of ids need to be handled together with the type */
	T_FUNCDEF,       /* function definition */
		/* K&R defn have two ARGLIST child */
	T_CONDITION,     /* condition section of while, for, if,... statements */
	T_THEN,
	T_ELSE,
	/* declaration and type specific nodes */
	T_TYPE,          /* type container for qualifiers, specifier, typenames, attribs */
	T_CLASS,         /* storage class specifier (arg: static|extern|auto|register|inline) */
		/* inline is actually a specifier only avail for funcs, not class */
		/* typedef is a storage class in c grammar, but behaves differently */
	T_QUALIFIER,     /* type qualifier (arg: const|volatile|restrict) */
	T_TYPESPEC,      /* long|short|signed|unsigned|_Complex|_Imaginary */
	T_TYPENAME,      /* builtin type name (int, float,...) */
		/* standard does not make difference between typename and typespec */
	T_TYPECUSTOM,    /* typedef'd type name */
	T_TYPEOF,        /* typeof() can appear wherever TYPENAME can */
	T_ARGLIST        /* function arguments (appears in decl/type/id, defn/type/id or call) */
	T_ARG,           /* a specific argument */
	T_ELLIPSIS,      /* ... in arg (gcc: case 3...5, {[2]=4, [3...5]=8}) */
	T_PTR,           /* pointer type (can appear under type or id) */
	T_INDEX,         /* array type (can appear under type or id) */
		/* ptr, index can be unified: T_DECOR *|[] */
	T_ENUM,
	T_UNION,
	T_STRUCT,
		/* struct fields are declarations */
	T_BITS,          /* :X part of a bitfield */
	T_FIELD,         /* field of a struct, union or enum */
		/* field is only used in initializer list or complit */
		/* field in enum does not seem necessary */
		/* field in struct/union is always '.' prefixed */
	T_INIT,          /* initializer value (int i = 1;) */
		/* init is the '=' in decl, and the right side of = is its child */
		/* array init: id/init/initlist/... */
		/* value init: id/init/iconst/1 */
	T_INITLIST,      /* initializer list (int a[] = {1, 2}; ) */
	T_DESLIST        /* designator list, like {[0].x = 2} in an initializer */
		/* deslist needs cleanup */
/*
struct {int x;} s[] = {[0].x = 2};

assignment syntax with <anonymous> id:
DECL
 TYPE
  STRUCT
   DECL
    TYPE
     TYPENAME int
    ID x
 ID s
  INDEX
  INIT
   INITLIST
    OP =
     OP .
      OP INDEX
       ID <anonymous>
       ICONST 0
      ID x
     ICONST 2

exploiting that only '.id' or '[expr]' can appear:
DECL
 TYPE
  STRUCT
   DECL
    TYPE
     TYPENAME int
    ID x
 ID s
  INDEX
  INIT
   INITLIST
    OP =
     DESLIST
      INDEX
       ICONST 0
      ID x
     ICONST 2
*/

	/* expressions */
	T_CALL,          /* function call expression */
	T_OP,            /* operator expression arg: PTR|INDEX|-|+|... */
		/* CALL can be made into OP () */
		/* maybe it can be marked if '('')' is required by precedence rules */
		/* marking () is also useful for decl PTR, INDEX,.. */
	T_EXPRLIST,      /* comma separated list of expressions (1,2,3) */

	T_ID,            /* identifier in declaration, or expression */
	T_ICONST,        /* integer constant */
	T_FCONST,        /* floating point constant */
	T_SCONST,        /* string constant */
		/* multiple sconst can be after each other */
		/* in those cases maybe an sconstlist would be useful */
		/* otherwise it is surprising when arg, init.. has multiple children */

	/* attributes */
	T_ATTRLIST       /* (was T_ATTRIBUTES) */
	T_ATTR,

	/* preproc nodes */
	T_PREPROC,       /* in a merged tree, this is the parent of any preprocessor nodes */
	T_PRAGMA,
		/* node for preproc directives? */
	T_COMMENT,

	T_DEBUG,         /* for debugging - release versions should never emit */
} node_type_t;
