#define abi_node			cp_global_trees[CPTI_ABI]
#define const_type_info_type_node	cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE]
#define type_info_ptr_type		cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
#define abort_fndecl			cp_global_trees[CPTI_ABORT_FNDECL]
#define current_aggr			cp_global_trees[CPTI_AGGR_TAG]
#define nullptr_node			cp_global_trees[CPTI_NULLPTR]
#define nullptr_type_node		cp_global_trees[CPTI_NULLPTR_TYPE]
/* std::align_val_t */
#define align_type_node			cp_global_trees[CPTI_ALIGN_TYPE]

/* We cache these tree nodes so as to call get_identifier less
   frequently.  */

/* The name of a constructor that takes an in-charge parameter to
   decide whether or not to construct virtual base classes.  */
#define ctor_identifier			cp_global_trees[CPTI_CTOR_IDENTIFIER]
/* The name of a constructor that constructs virtual base classes.  */
#define complete_ctor_identifier	cp_global_trees[CPTI_COMPLETE_CTOR_IDENTIFIER]
/* The name of a constructor that does not construct virtual base classes.  */
#define base_ctor_identifier		cp_global_trees[CPTI_BASE_CTOR_IDENTIFIER]
/* The name of a destructor that takes an in-charge parameter to
   decide whether or not to destroy virtual base classes and whether
   or not to delete the object.  */
#define dtor_identifier			cp_global_trees[CPTI_DTOR_IDENTIFIER]
/* The name of a destructor that destroys virtual base classes.  */
#define complete_dtor_identifier	cp_global_trees[CPTI_COMPLETE_DTOR_IDENTIFIER]
/* The name of a destructor that does not destroy virtual base
   classes.  */
#define base_dtor_identifier		cp_global_trees[CPTI_BASE_DTOR_IDENTIFIER]
/* The name of a destructor that destroys virtual base classes, and
   then deletes the entire object.  */
#define deleting_dtor_identifier	cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER]
#define delta_identifier		cp_global_trees[CPTI_DELTA_IDENTIFIER]
#define in_charge_identifier		cp_global_trees[CPTI_IN_CHARGE_IDENTIFIER]
/* The name of the parameter that contains a pointer to the VTT to use
   for this subobject constructor or destructor.  */
#define vtt_parm_identifier		cp_global_trees[CPTI_VTT_PARM_IDENTIFIER]
#define nelts_identifier		cp_global_trees[CPTI_NELTS_IDENTIFIER]
#define this_identifier			cp_global_trees[CPTI_THIS_IDENTIFIER]
#define pfn_identifier			cp_global_trees[CPTI_PFN_IDENTIFIER]
#define vptr_identifier			cp_global_trees[CPTI_VPTR_IDENTIFIER]
/* The name of the std namespace.  */
#define std_identifier			cp_global_trees[CPTI_STD_IDENTIFIER]
/* auto and declspec(auto) identifiers.  */
#define auto_identifier			cp_global_trees[CPTI_AUTO_IDENTIFIER]
#define decltype_auto_identifier	cp_global_trees[CPTI_DECLTYPE_AUTO_IDENTIFIER]
/* The name of a C++17 deduction guide.  */
#define lang_name_c			cp_global_trees[CPTI_LANG_NAME_C]
#define lang_name_cplusplus		cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]

/* Exception specifiers used for throw(), noexcept(true) and
   noexcept(false).  We rely on these being uncloned.  */
#define empty_except_spec		cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC]
#define noexcept_true_spec		cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC]
#define noexcept_false_spec		cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC]

/* The declaration for `std::terminate'.  */
#define terminate_node			cp_global_trees[CPTI_TERMINATE]

/* The declaration for "__cxa_call_unexpected".  */
#define call_unexpected_node		cp_global_trees[CPTI_CALL_UNEXPECTED]

/* The type of the function-pointer argument to "__cxa_atexit" (or
   "std::atexit", if "__cxa_atexit" is not being used).  */
#define atexit_fn_ptr_type_node         cp_global_trees[CPTI_ATEXIT_FN_PTR_TYPE]

/* A pointer to `std::atexit'.  */
#define atexit_node			cp_global_trees[CPTI_ATEXIT]

/* A pointer to `__dso_handle'.  */
#define dso_handle_node			cp_global_trees[CPTI_DSO_HANDLE]

/* The declaration of the dynamic_cast runtime.  */
#define dynamic_cast_node		cp_global_trees[CPTI_DCAST]

/* The type of a destructor.  */
#define cleanup_type			cp_global_trees[CPTI_CLEANUP_TYPE]

/* The type of the vtt parameter passed to subobject constructors and
   destructors.  */
#define vtt_parm_type			cp_global_trees[CPTI_VTT_PARM_TYPE]

/* A TREE_LIST of the dynamic classes whose vtables may have to be
   emitted in this translation unit.  */

#define keyed_classes			cp_global_trees[CPTI_KEYED_CLASSES]

/* A node which matches any template argument.  */
#define any_targ_node			cp_global_trees[CPTI_ANY_TARG]

/* Node to indicate default access. This must be distinct from the
   access nodes in tree.h.  */

#define access_default_node		null_node

/* Global state.  */

struct GTY(()) saved_scope {
  vec<cxx_saved_binding, va_gc> *old_bindings;
  tree old_namespace;
  vec<tree, va_gc> *decl_ns_list;
  tree class_name;
  tree class_type;
  tree access_specifier;
  tree function_decl;
  vec<tree, va_gc> *lang_base;
  tree lang_name;
  tree template_parms;
  cp_binding_level *x_previous_class_level;
  tree x_saved_tree;

  /* Only used for uses of this in trailing return type.  */
  tree x_current_class_ptr;
  tree x_current_class_ref;

  int x_processing_template_decl;
  int x_processing_specialization;
  BOOL_BITFIELD x_processing_explicit_instantiation : 1;
  BOOL_BITFIELD need_pop_function_context : 1;

/* Nonzero if we are parsing the discarded statement of a constexpr
   if-statement.  */
  BOOL_BITFIELD discarded_stmt : 1;

  int unevaluated_operand;
  int inhibit_evaluation_warnings;
  int noexcept_operand;
  /* If non-zero, implicit "omp declare target" attribute is added into the
     attribute lists.  */
  int omp_declare_target_attribute;

  struct stmt_tree_s x_stmt_tree;

  cp_binding_level *class_bindings;
  cp_binding_level *bindings;

  hash_map<tree, tree> *GTY((skip)) x_local_specializations;

  struct saved_scope *prev;
};

extern GTY(()) struct saved_scope *scope_chain;

/* The current open namespace.  */

#define current_namespace scope_chain->old_namespace

/* The stack for namespaces of current declarations.  */

#define decl_namespace_list scope_chain->decl_ns_list

/* IDENTIFIER_NODE: name of current class */

#define current_class_name scope_chain->class_name

/* _TYPE: the type of the current class */

#define current_class_type scope_chain->class_type

/* When parsing a class definition, the access specifier most recently
   given by the user, or, if no access specifier was given, the
   default value appropriate for the kind of class (i.e., struct,
   class, or union).  */

#define current_access_specifier scope_chain->access_specifier

/* Pointer to the top of the language name stack.  */

#define current_lang_base scope_chain->lang_base
#define current_lang_name scope_chain->lang_name

/* When parsing a template declaration, a TREE_LIST represents the
   active template parameters.  Each node in the list represents one
   level of template parameters.  The innermost level is first in the
   list.  The depth of each level is stored as an INTEGER_CST in the
   TREE_PURPOSE of each node.  The parameters for that level are
   stored in the TREE_VALUE.  */

#define current_template_parms scope_chain->template_parms

#define processing_template_decl scope_chain->x_processing_template_decl
#define processing_specialization scope_chain->x_processing_specialization
#define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation

#define in_discarded_stmt scope_chain->discarded_stmt

/* RAII sentinel to handle clearing processing_template_decl and restoring
   it when done.  */

struct processing_template_decl_sentinel
{
  int saved;
  processing_template_decl_sentinel (bool reset = true)
    : saved (processing_template_decl)
  {
    if (reset)
      processing_template_decl = 0;
  }
  ~processing_template_decl_sentinel()
  {
    processing_template_decl = saved;
  }
};

/* RAII sentinel to disable certain warnings during template substitution
   and elsewhere.  */

struct warning_sentinel
{
  int &flag;
  int val;
  warning_sentinel(int& flag, bool suppress=true)
    : flag(flag), val(flag) { if (suppress) flag = 0; }
  ~warning_sentinel() { flag = val; }
};

/* The cached class binding level, from the most recently exited
   class, or NULL if none.  */

#define previous_class_level scope_chain->x_previous_class_level

/* A map from local variable declarations in the body of the template
   presently being instantiated to the corresponding instantiated
   local variables.  */

#define local_specializations scope_chain->x_local_specializations

/* Nonzero if we are parsing the operand of a noexcept operator.  */

#define cp_noexcept_operand scope_chain->noexcept_operand

/* A list of private types mentioned, for deferred access checking.  */

struct GTY((for_user)) cxx_int_tree_map {
  unsigned int uid;
  tree to;
};

struct cxx_int_tree_map_hasher : ggc_ptr_hash<cxx_int_tree_map>
{
  static hashval_t hash (cxx_int_tree_map *);
  static bool equal (cxx_int_tree_map *, cxx_int_tree_map *);
};

struct named_label_entry;

struct named_label_hasher : ggc_ptr_hash<named_label_entry>
{
  static hashval_t hash (named_label_entry *);
  static bool equal (named_label_entry *, named_label_entry *);
};

/* Global state pertinent to the current function.  */

struct GTY(()) language_function {
  struct c_language_function base;

  tree x_cdtor_label;
  tree x_current_class_ptr;
  tree x_current_class_ref;
  tree x_eh_spec_block;
  tree x_in_charge_parm;
  tree x_vtt_parm;
  tree x_return_value;
  tree x_auto_return_pattern;

  BOOL_BITFIELD returns_value : 1;
  BOOL_BITFIELD returns_null : 1;
  BOOL_BITFIELD returns_abnormally : 1;
  BOOL_BITFIELD infinite_loop: 1;
  BOOL_BITFIELD x_in_function_try_handler : 1;
  BOOL_BITFIELD x_in_base_initializer : 1;

  /* True if this function can throw an exception.  */
  BOOL_BITFIELD can_throw : 1;

  BOOL_BITFIELD invalid_constexpr : 1;

  hash_table<named_label_hasher> *x_named_labels;
  cp_binding_level *bindings;
  vec<tree, va_gc> *x_local_names;
  /* Tracking possibly infinite loops.  This is a vec<tree> only because
     vec<bool> doesn't work with gtype.  */
  vec<tree, va_gc> *infinite_loops;
  hash_table<cxx_int_tree_map_hasher> *extern_decl_map;
};

/* The current C++-specific per-function global variables.  */

#define cp_function_chain (cfun->language)

/* In a constructor destructor, the point at which all derived class
   destroying/construction has been done.  I.e., just before a
   constructor returns, or before any base class destroying will be done
   in a destructor.  */

#define cdtor_label cp_function_chain->x_cdtor_label

/* When we're processing a member function, current_class_ptr is the
   PARM_DECL for the `this' pointer.  The current_class_ref is an
   expression for `*this'.  */

#define current_class_ptr			\
  (*(cfun && cp_function_chain			\
     ? &cp_function_chain->x_current_class_ptr	\
     : &scope_chain->x_current_class_ptr))
#define current_class_ref			\
  (*(cfun && cp_function_chain			\
     ? &cp_function_chain->x_current_class_ref	\
     : &scope_chain->x_current_class_ref))

/* The EH_SPEC_BLOCK for the exception-specifiers for the current
   function, if any.  */

#define current_eh_spec_block cp_function_chain->x_eh_spec_block

/* The `__in_chrg' parameter for the current function.  Only used for
   constructors and destructors.  */

#define current_in_charge_parm cp_function_chain->x_in_charge_parm

/* The `__vtt_parm' parameter for the current function.  Only used for
   constructors and destructors.  */

#define current_vtt_parm cp_function_chain->x_vtt_parm

/* Set to 0 at beginning of a function definition, set to 1 if
   a return statement that specifies a return value is seen.  */

#define current_function_returns_value cp_function_chain->returns_value

/* Set to 0 at beginning of a function definition, set to 1 if
   a return statement with no argument is seen.  */

#define current_function_returns_null cp_function_chain->returns_null

/* Set to 0 at beginning of a function definition, set to 1 if
   a call to a noreturn function is seen.  */

#define current_function_returns_abnormally \
  cp_function_chain->returns_abnormally

/* Set to 0 at beginning of a function definition, set to 1 if we see an
   obvious infinite loop.  This can have false positives and false
   negatives, so it should only be used as a heuristic.  */

#define current_function_infinite_loop cp_function_chain->infinite_loop

/* Nonzero if we are processing a base initializer.  Zero elsewhere.  */
#define in_base_initializer cp_function_chain->x_in_base_initializer

#define in_function_try_handler cp_function_chain->x_in_function_try_handler

/* Expression always returned from function, or error_mark_node
   otherwise, for use by the automatic named return value optimization.  */

#define current_function_return_value \
  (cp_function_chain->x_return_value)

/* A type involving 'auto' to be used for return type deduction.  */

#define current_function_auto_return_pattern \
  (cp_function_chain->x_auto_return_pattern)

/* True if NAME is the IDENTIFIER_NODE for an overloaded "operator
   new" or "operator delete".  */
#define NEW_DELETE_OPNAME_P(NAME)		\
  ((NAME) == cp_operator_id (NEW_EXPR)		\
   || (NAME) == cp_operator_id (VEC_NEW_EXPR)	\
   || (NAME) == cp_operator_id (DELETE_EXPR)	\
   || (NAME) == cp_operator_id (VEC_DELETE_EXPR))

#define cp_operator_id(CODE) \
  (operator_name_info[(int) (CODE)].identifier)
#define cp_assignment_operator_id(CODE) \
  (assignment_operator_name_info[(int) (CODE)].identifier)
/* In parser.c.  */
extern tree cp_literal_operator_id (const char *);

/* TRUE if a tree code represents a statement.  */
extern bool statement_code_p[MAX_TREE_CODES];

#define STATEMENT_CODE_P(CODE) statement_code_p[(int) (CODE)]

enum languages { lang_c, lang_cplusplus };

/* Macros to make error reporting functions' lives easier.  */
#define TYPE_LINKAGE_IDENTIFIER(NODE) \
  (TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (NODE)))
#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE)))
#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE)))

/* Nonzero if NODE has no name for linkage purposes.  */
#define TYPE_UNNAMED_P(NODE) \
  (OVERLOAD_TYPE_P (NODE) && anon_aggrname_p (TYPE_LINKAGE_IDENTIFIER (NODE)))

/* The _DECL for this _TYPE.  */
#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))

/* Nonzero if T is a type that could resolve to any kind of concrete type
   at instantiation time.  */
#define WILDCARD_TYPE_P(T)				\
  (TREE_CODE (T) == TEMPLATE_TYPE_PARM			\
   || TREE_CODE (T) == TYPENAME_TYPE			\
   || TREE_CODE (T) == TYPEOF_TYPE			\
   || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM	\
   || TREE_CODE (T) == DECLTYPE_TYPE)

/* Nonzero if T is a class (or struct or union) type.  Also nonzero
   for template type parameters, typename types, and instantiated
   template template parameters.  Keep these checks in ascending code
   order.  */
#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T))

/* Set CLASS_TYPE_P for T to VAL.  T must be a class, struct, or
   union type.  */
#define SET_CLASS_TYPE_P(T, VAL) \
  (TYPE_LANG_FLAG_5 (T) = (VAL))

/* Nonzero if T is a class type.  Zero for template type parameters,
   typename types, and so forth.  */
#define CLASS_TYPE_P(T) \
  (RECORD_OR_UNION_CODE_P (TREE_CODE (T)) && TYPE_LANG_FLAG_5 (T))

/* Nonzero if T is a class type but not an union.  */
#define NON_UNION_CLASS_TYPE_P(T) \
  (CLASS_TYPE_P (T) && TREE_CODE (T) != UNION_TYPE)

/* Keep these checks in ascending code order.  */
#define RECORD_OR_UNION_CODE_P(T)	\
  ((T) == RECORD_TYPE || (T) == UNION_TYPE)
#define OVERLOAD_TYPE_P(T) \
  (CLASS_TYPE_P (T) || TREE_CODE (T) == ENUMERAL_TYPE)

/* True if this type is dependent.  This predicate is only valid if
   TYPE_DEPENDENT_P_VALID is true.  */
#define TYPE_DEPENDENT_P(NODE) TYPE_LANG_FLAG_0 (NODE)

/* True if dependent_type_p has been called for this type, with the
   result that TYPE_DEPENDENT_P is valid.  */
#define TYPE_DEPENDENT_P_VALID(NODE) TYPE_LANG_FLAG_6(NODE)

/* Nonzero if this type is const-qualified.  */
#define CP_TYPE_CONST_P(NODE)				\
  ((cp_type_quals (NODE) & TYPE_QUAL_CONST) != 0)

/* Nonzero if this type is volatile-qualified.  */
#define CP_TYPE_VOLATILE_P(NODE)			\
  ((cp_type_quals (NODE) & TYPE_QUAL_VOLATILE) != 0)

/* Nonzero if this type is restrict-qualified.  */
#define CP_TYPE_RESTRICT_P(NODE)			\
  ((cp_type_quals (NODE) & TYPE_QUAL_RESTRICT) != 0)

/* Nonzero if this type is const-qualified, but not
   volatile-qualified.  Other qualifiers are ignored.  This macro is
   used to test whether or not it is OK to bind an rvalue to a
   reference.  */
#define CP_TYPE_CONST_NON_VOLATILE_P(NODE)				\
  ((cp_type_quals (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))	\
   == TYPE_QUAL_CONST)

#define FUNCTION_ARG_CHAIN(NODE) \
  TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE)))

/* Given a FUNCTION_DECL, returns the first TREE_LIST out of TYPE_ARG_TYPES
   which refers to a user-written parameter.  */
#define FUNCTION_FIRST_USER_PARMTYPE(NODE) \
  skip_artificial_parms_for ((NODE), TYPE_ARG_TYPES (TREE_TYPE (NODE)))

/* Similarly, but for DECL_ARGUMENTS.  */
#define FUNCTION_FIRST_USER_PARM(NODE) \
  skip_artificial_parms_for ((NODE), DECL_ARGUMENTS (NODE))

/* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and
   ambiguity issues.  */
#define DERIVED_FROM_P(PARENT, TYPE) \
  (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_none) != NULL_TREE)

/* Gives the visibility specification for a class type.  */
#define CLASSTYPE_VISIBILITY(TYPE)		\
	DECL_VISIBILITY (TYPE_MAIN_DECL (TYPE))
#define CLASSTYPE_VISIBILITY_SPECIFIED(TYPE)	\
	DECL_VISIBILITY_SPECIFIED (TYPE_MAIN_DECL (TYPE))

struct GTY (()) tree_pair_s {
  tree purpose;
  tree value;
};
typedef tree_pair_s *tree_pair_p;

/* This is a few header flags for 'struct lang_type'.  Actually,
   all but the first are used only for lang_type_class; they
   are put in this structure to save space.  */
struct GTY(()) lang_type_header {
  BOOL_BITFIELD is_lang_type_class : 1;

  BOOL_BITFIELD has_type_conversion : 1;
  BOOL_BITFIELD has_copy_ctor : 1;
  BOOL_BITFIELD has_default_ctor : 1;
  BOOL_BITFIELD const_needs_init : 1;
  BOOL_BITFIELD ref_needs_init : 1;
  BOOL_BITFIELD has_const_copy_assign : 1;

  BOOL_BITFIELD spare : 1;
};

/* This structure provides additional information above and beyond
   what is provide in the ordinary tree_type.  In the past, we used it
   for the types of class types, template parameters types, typename
   types, and so forth.  However, there can be many (tens to hundreds
   of thousands) of template parameter types in a compilation, and
   there's no need for this additional information in that case.
   Therefore, we now use this data structure only for class types.

   In the past, it was thought that there would be relatively few
   class types.  However, in the presence of heavy use of templates,
   many (i.e., thousands) of classes can easily be generated.
   Therefore, we should endeavor to keep the size of this structure to
   a minimum.  */
struct GTY(()) lang_type_class {
  struct lang_type_header h;

  unsigned char align;

  unsigned has_mutable : 1;
  unsigned com_interface : 1;
  unsigned non_pod_class : 1;
  unsigned nearly_empty_p : 1;
  unsigned user_align : 1;
  unsigned has_copy_assign : 1;
  unsigned has_new : 1;
  unsigned has_array_new : 1;

  unsigned gets_delete : 2;
  unsigned interface_only : 1;
  unsigned interface_unknown : 1;
  unsigned contains_empty_class_p : 1;
  unsigned anon_aggr : 1;
  unsigned non_zero_init : 1;
  unsigned empty_p : 1;

  unsigned vec_new_uses_cookie : 1;
  unsigned declared_class : 1;
  unsigned diamond_shaped : 1;
  unsigned repeated_base : 1;
  unsigned being_defined : 1;
  unsigned debug_requested : 1;
  unsigned fields_readonly : 1;
  unsigned ptrmemfunc_flag : 1;

  unsigned use_template : 2;
  unsigned was_anonymous : 1;
  unsigned lazy_default_ctor : 1;
  unsigned lazy_copy_ctor : 1;
  unsigned lazy_copy_assign : 1;
  unsigned lazy_destructor : 1;
  unsigned has_const_copy_ctor : 1;

  unsigned has_complex_copy_ctor : 1;
  unsigned has_complex_copy_assign : 1;
  unsigned non_aggregate : 1;
  unsigned has_complex_dflt : 1;
  unsigned has_list_ctor : 1;
  unsigned non_std_layout : 1;
  unsigned is_literal : 1;
  unsigned lazy_move_ctor : 1;

  unsigned lazy_move_assign : 1;
  unsigned has_complex_move_ctor : 1;
  unsigned has_complex_move_assign : 1;
  unsigned has_constexpr_ctor : 1;
  unsigned unique_obj_representations : 1;
  unsigned unique_obj_representations_set : 1;

  /* When adding a flag here, consider whether or not it ought to
     apply to a template instance if it applies to the template.  If
     so, make sure to copy it in instantiate_class_template!  */

  /* There are some bits left to fill out a 32-bit word.  Keep track
     of this by updating the size of this bitfield whenever you add or
     remove a flag.  */
  unsigned dummy : 2;

  tree primary_base;
  vec<tree_pair_s, va_gc> *vcall_indices;
  tree vtables;
  tree typeinfo_var;
  vec<tree, va_gc> *vbases;
  binding_table nested_udts;
  tree as_base;
  vec<tree, va_gc> *pure_virtuals;
  tree friend_classes;
  vec<tree, va_gc> * GTY((reorder ("resort_type_method_vec"))) methods;
  tree key_method;
  tree decl_list;
  tree template_info;
  tree befriending_classes;
  /* In a RECORD_TYPE, information specific to Objective-C++, such
     as a list of adopted protocols or a pointer to a corresponding
     @interface.  See objc/objc-act.h for details.  */
  tree objc_info;
  /* sorted_fields is sorted based on a pointer, so we need to be able
     to resort it if pointers get rearranged.  */
  struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields")))
    sorted_fields;
  /* FIXME reuse another field?  */
  tree lambda_expr;
};

struct GTY(()) lang_type_ptrmem {
  struct lang_type_header h;
  tree record;
};

struct GTY(()) lang_type {
  union lang_type_u
  {
    struct lang_type_header GTY((skip (""))) h;
    struct lang_type_class  GTY((tag ("1"))) c;
    struct lang_type_ptrmem GTY((tag ("0"))) ptrmem;
  } GTY((desc ("%h.h.is_lang_type_class"))) u;
};

#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)

#define LANG_TYPE_CLASS_CHECK(NODE) __extension__		\
({  struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE);		\
    if (! lt->u.h.is_lang_type_class)				\
      lang_check_failed (__FILE__, __LINE__, __FUNCTION__);	\
    &lt->u.c; })

#define LANG_TYPE_PTRMEM_CHECK(NODE) __extension__		\
({  struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE);		\
    if (lt->u.h.is_lang_type_class)				\
      lang_check_failed (__FILE__, __LINE__, __FUNCTION__);	\
    &lt->u.ptrmem; })

#else

#define LANG_TYPE_CLASS_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.c)
#define LANG_TYPE_PTRMEM_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.ptrmem)

#endif /* ENABLE_TREE_CHECKING */

/* Nonzero for _CLASSTYPE means that operator delete is defined.  */
#define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete)
#define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)

/* Nonzero if `new NODE[x]' should cause the allocation of extra
   storage to indicate how many array elements are in use.  */
#define TYPE_VEC_NEW_USES_COOKIE(NODE)			\
  (CLASS_TYPE_P (NODE)					\
   && LANG_TYPE_CLASS_CHECK (NODE)->vec_new_uses_cookie)

/* Nonzero means that this _CLASSTYPE node defines ways of converting
   itself to other types.  */
#define TYPE_HAS_CONVERSION(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion)

/* Nonzero means that NODE (a class type) has a default constructor --
   but that it has not yet been declared.  */
#define CLASSTYPE_LAZY_DEFAULT_CTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_default_ctor)

/* Nonzero means that NODE (a class type) has a copy constructor --
   but that it has not yet been declared.  */
#define CLASSTYPE_LAZY_COPY_CTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_ctor)

/* Nonzero means that NODE (a class type) has a move constructor --
   but that it has not yet been declared.  */
#define CLASSTYPE_LAZY_MOVE_CTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_move_ctor)

/* Nonzero means that NODE (a class type) has an assignment operator
   -- but that it has not yet been declared.  */
#define CLASSTYPE_LAZY_COPY_ASSIGN(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_assign)

/* Nonzero means that NODE (a class type) has an assignment operator
   -- but that it has not yet been declared.  */
#define CLASSTYPE_LAZY_MOVE_ASSIGN(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_move_assign)

/* Nonzero means that NODE (a class type) has a destructor -- but that
   it has not yet been declared.  */
#define CLASSTYPE_LAZY_DESTRUCTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_destructor)

/* Nonzero means that NODE (a class type) is final */
#define CLASSTYPE_FINAL(NODE) \
  TYPE_FINAL_P (NODE)


/* Nonzero means that this _CLASSTYPE node overloads operator=(X&).  */
#define TYPE_HAS_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_copy_assign)

/* True iff the class type NODE has an "operator =" whose parameter
   has a parameter of type "const X&".  */
#define TYPE_HAS_CONST_COPY_ASSIGN(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_copy_assign)

/* Nonzero means that this _CLASSTYPE node has an X(X&) constructor.  */
#define TYPE_HAS_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_copy_ctor)
#define TYPE_HAS_CONST_COPY_CTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->has_const_copy_ctor)

/* Nonzero if this class has an X(initializer_list<T>) constructor.  */
#define TYPE_HAS_LIST_CTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->has_list_ctor)

/* Nonzero if this class has a constexpr constructor other than a copy/move
   constructor.  Note that a class can have constexpr constructors for
   static initialization even if it isn't a literal class.  */
#define TYPE_HAS_CONSTEXPR_CTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->has_constexpr_ctor)

/* Nonzero if this class defines an overloaded operator new.  (An
   operator new [] doesn't count.)  */
#define TYPE_HAS_NEW_OPERATOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->has_new)

/* Nonzero if this class defines an overloaded operator new[].  */
#define TYPE_HAS_ARRAY_NEW_OPERATOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->has_array_new)

/* Nonzero means that this type is being defined.  I.e., the left brace
   starting the definition of this type has been seen.  */
#define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined)

/* Nonzero means that this type is either complete or being defined, so we
   can do lookup in it.  */
#define COMPLETE_OR_OPEN_TYPE_P(NODE) \
  (COMPLETE_TYPE_P (NODE) || (CLASS_TYPE_P (NODE) && TYPE_BEING_DEFINED (NODE)))

/* Mark bits for repeated base checks.  */
#define TYPE_MARKED_P(NODE) TREE_LANG_FLAG_6 (TYPE_CHECK (NODE))

/* Nonzero if the class NODE has multiple paths to the same (virtual)
   base object.  */
#define CLASSTYPE_DIAMOND_SHAPED_P(NODE) \
  (LANG_TYPE_CLASS_CHECK(NODE)->diamond_shaped)

/* Nonzero if the class NODE has multiple instances of the same base
   type.  */
#define CLASSTYPE_REPEATED_BASE_P(NODE) \
  (LANG_TYPE_CLASS_CHECK(NODE)->repeated_base)

/* The member function with which the vtable will be emitted:
   the first noninline non-pure-virtual member function.  NULL_TREE
   if there is no key function or if this is a class template */
#define CLASSTYPE_KEY_METHOD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->key_method)

/* Vector member functions defined in this class.  Each element is
   either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD.  All
   functions with the same name end up in the same slot.  The first
   two elements are for constructors, and destructors, respectively.
   All template conversion operators to innermost template dependent
   types are overloaded on the next slot, if they exist.  Note, the
   names for these functions will not all be the same.  The
   non-template conversion operators & templated conversions to
   non-innermost template types are next, followed by ordinary member
   functions.  There may be empty entries at the end of the vector.
   The conversion operators are unsorted. The ordinary member
   functions are sorted, once the class is complete.  */
#define CLASSTYPE_METHOD_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->methods)

/* For class templates, this is a TREE_LIST of all member data,
   functions, types, and friends in the order of declaration.
   The TREE_PURPOSE of each TREE_LIST is NULL_TREE for a friend,
   and the RECORD_TYPE for the class template otherwise.  */
#define CLASSTYPE_DECL_LIST(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->decl_list)

/* The slot in the CLASSTYPE_METHOD_VEC where constructors go.  */
#define CLASSTYPE_CONSTRUCTOR_SLOT 0

/* The slot in the CLASSTYPE_METHOD_VEC where destructors go.  */
#define CLASSTYPE_DESTRUCTOR_SLOT 1

/* The first slot in the CLASSTYPE_METHOD_VEC where conversion
   operators can appear.  */
#define CLASSTYPE_FIRST_CONVERSION_SLOT 2

/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE.  These
   are the constructors that take an in-charge parameter.  */
#define CLASSTYPE_CONSTRUCTORS(NODE) \
  ((*CLASSTYPE_METHOD_VEC (NODE))[CLASSTYPE_CONSTRUCTOR_SLOT])

/* A FUNCTION_DECL for the destructor for NODE.  These are the
   destructors that take an in-charge parameter.  If
   CLASSTYPE_LAZY_DESTRUCTOR is true, then this entry will be NULL
   until the destructor is created with lazily_declare_fn.  */
#define CLASSTYPE_DESTRUCTORS(NODE) \
  (CLASSTYPE_METHOD_VEC (NODE)						      \
   ? (*CLASSTYPE_METHOD_VEC (NODE))[CLASSTYPE_DESTRUCTOR_SLOT]		      \
   : NULL_TREE)

/* A dictionary of the nested user-defined-types (class-types, or enums)
   found within this class.  This table includes nested member class
   templates.  */
#define CLASSTYPE_NESTED_UTDS(NODE) \
   (LANG_TYPE_CLASS_CHECK (NODE)->nested_udts)

/* Nonzero if NODE has a primary base class, i.e., a base class with
   which it shares the virtual function table pointer.  */
#define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \
  (CLASSTYPE_PRIMARY_BINFO (NODE) != NULL_TREE)

/* If non-NULL, this is the binfo for the primary base class, i.e.,
   the base class which contains the virtual function table pointer
   for this class.  */
#define CLASSTYPE_PRIMARY_BINFO(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->primary_base)

/* A vector of BINFOs for the direct and indirect virtual base classes
   that this type uses in a post-order depth-first left-to-right
   order.  (In other words, these bases appear in the order that they
   should be initialized.)  */
#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)

/* The type corresponding to NODE when NODE is used as a base class,
   i.e., NODE without virtual base classes or tail padding.  */

#define CLASSTYPE_AS_BASE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->as_base)

/* True iff NODE is the CLASSTYPE_AS_BASE version of some type.  */

#define IS_FAKE_BASE_TYPE(NODE)					\
  (TREE_CODE (NODE) == RECORD_TYPE				\
   && TYPE_CONTEXT (NODE) && CLASS_TYPE_P (TYPE_CONTEXT (NODE))	\
   && CLASSTYPE_AS_BASE (TYPE_CONTEXT (NODE)) == (NODE))

/* These are the size and alignment of the type without its virtual
   base classes, for when we use this type as a base itself.  */
#define CLASSTYPE_SIZE(NODE) TYPE_SIZE (CLASSTYPE_AS_BASE (NODE))
#define CLASSTYPE_SIZE_UNIT(NODE) TYPE_SIZE_UNIT (CLASSTYPE_AS_BASE (NODE))
#define CLASSTYPE_ALIGN(NODE) TYPE_ALIGN (CLASSTYPE_AS_BASE (NODE))
#define CLASSTYPE_USER_ALIGN(NODE) TYPE_USER_ALIGN (CLASSTYPE_AS_BASE (NODE))

/* The alignment of NODE, without its virtual bases, in bytes.  */
#define CLASSTYPE_ALIGN_UNIT(NODE) \
  (CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT)

/* A vec<tree> of virtual functions which cannot be inherited by
   derived classes.  When deriving from this type, the derived
   class must provide its own definition for each of these functions.  */
#define CLASSTYPE_PURE_VIRTUALS(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals)

/* Nonzero means that this type is an abstract class type.  */
#define ABSTRACT_CLASS_TYPE_P(NODE) \
  (CLASS_TYPE_P (NODE) && CLASSTYPE_PURE_VIRTUALS(NODE))

/* Nonzero means that this type has an X() constructor.  */
#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)

/* Nonzero means that this type contains a mutable member.  */
#define CLASSTYPE_HAS_MUTABLE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_mutable)
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))

/* Nonzero means that this class type is not POD for the purpose of layout
   (as defined in the ABI).  This is different from the language's POD.  */
#define CLASSTYPE_NON_LAYOUT_POD_P(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->non_pod_class)

/* Nonzero means that this class type is a non-standard-layout class.  */
#define CLASSTYPE_NON_STD_LAYOUT(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->non_std_layout)

/* Nonzero means that this class type does have unique object
   representations.  */
#define CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->unique_obj_representations)

/* Nonzero means that this class type has
   CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS computed.  */
#define CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS_SET(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->unique_obj_representations_set)

/* Nonzero means that this class contains pod types whose default
   initialization is not a zero initialization (namely, pointers to
   data members).  */
#define CLASSTYPE_NON_ZERO_INIT_P(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->non_zero_init)

/* Nonzero if this class is "empty" in the sense of the C++ ABI.  */
#define CLASSTYPE_EMPTY_P(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->empty_p)

/* Nonzero if this class is "nearly empty", i.e., contains only a
   virtual function table pointer.  */
#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->nearly_empty_p)

/* Nonzero if this class contains an empty subobject.  */
#define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->contains_empty_class_p)

/* A list of class types of which this type is a friend.  The
   TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
   case of a template friend.  */
#define CLASSTYPE_FRIEND_CLASSES(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->friend_classes)

/* A list of the classes which grant friendship to this class.  */
#define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->befriending_classes)

/* The associated LAMBDA_EXPR that made this class.  */
#define CLASSTYPE_LAMBDA_EXPR(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->lambda_expr)
/* The extra mangling scope for this closure type.  */
#define LAMBDA_TYPE_EXTRA_SCOPE(NODE) \
  (LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR (NODE)))

/* Say whether this node was declared as a "class" or a "struct".  */
#define CLASSTYPE_DECLARED_CLASS(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->declared_class)

/* Nonzero if this class has const members
   which have no specified initialization.  */
#define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE)	\
  (TYPE_LANG_SPECIFIC (NODE)				\
   ? LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init : 0)
#define SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE, VALUE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init = (VALUE))

/* Nonzero if this class has ref members
   which have no specified initialization.  */
#define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE)		\
  (TYPE_LANG_SPECIFIC (NODE)				\
   ? LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init : 0)
#define SET_CLASSTYPE_REF_FIELDS_NEED_INIT(NODE, VALUE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init = (VALUE))

/* Nonzero if this class is included from a header file which employs
   `#pragma interface', and it is not included in its implementation file.  */
#define CLASSTYPE_INTERFACE_ONLY(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->interface_only)

/* True if we have already determined whether or not vtables, VTTs,
   typeinfo, and other similar per-class data should be emitted in
   this translation unit.  This flag does not indicate whether or not
   these items should be emitted; it only indicates that we know one
   way or the other.  */
#define CLASSTYPE_INTERFACE_KNOWN(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown == 0)
/* The opposite of CLASSTYPE_INTERFACE_KNOWN.  */
#define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown)

#define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) \
  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = !!(X))
#define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 1)
#define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 0)

/* Nonzero if a _DECL node requires us to output debug info for this class.  */
#define CLASSTYPE_DEBUG_REQUESTED(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->debug_requested)
