PLATE_DECL, this is
       DECL_CLONED_FUNCTION.  */
    tree GTY ((tag ("0"))) cloned_function;

    /* In a FUNCTION_DECL for which THUNK_P holds this is the
       THUNK_FIXED_OFFSET.  */
    HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset;
  } GTY ((desc ("%1.thunk_p"))) u5;

  union lang_decl_u3
  {
    struct cp_token_cache * GTY ((tag ("1"))) pending_inline_info;
    struct language_function * GTY ((tag ("0")))
      saved_language_function;
  } GTY ((desc ("%1.pending_inline_p"))) u;

};

/* DECL_LANG_SPECIFIC for namespaces.  */

struct GTY(()) lang_decl_ns {
  struct lang_decl_base base;
  cp_binding_level *level;
  tree ns_using;
  tree ns_users;
};

/* DECL_LANG_SPECIFIC for parameters.  */

struct GTY(()) lang_decl_parm {
  struct lang_decl_base base;
  int level;
  int index;
};

/* DECL_LANG_SPECIFIC for all types.  It would be nice to just make this a
   union rather than a struct containing a union as its only field, but
   tree.h declares it as a struct.  */

struct GTY(()) lang_decl {
  union GTY((desc ("%h.base.selector"))) lang_decl_u {
    struct lang_decl_base GTY ((default)) base;
    struct lang_decl_min GTY((tag ("0"))) min;
    struct lang_decl_fn GTY ((tag ("1"))) fn;
    struct lang_decl_ns GTY((tag ("2"))) ns;
    struct lang_decl_parm GTY((tag ("3"))) parm;
  } u;
};

/* Looks through a template (if present) to find what it declares.  */
#define STRIP_TEMPLATE(NODE) \
  (TREE_CODE (NODE) == TEMPLATE_DECL ? DECL_TEMPLATE_RESULT (NODE) : NODE)

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

#define LANG_DECL_MIN_CHECK(NODE) __extension__			\
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);		\
   if (!LANG_DECL_HAS_MIN (NODE))				\
     lang_check_failed (__FILE__, __LINE__, __FUNCTION__);	\
   &lt->u.min; })

/* We want to be able to check DECL_CONSTRUCTOR_P and such on a function
   template, not just on a FUNCTION_DECL.  So when looking for things in
   lang_decl_fn, look down through a TEMPLATE_DECL into its result.  */
#define LANG_DECL_FN_CHECK(NODE) __extension__				\
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE));	\
   if (!DECL_DECLARES_FUNCTION_P (NODE) || lt->u.base.selector != 1)	\
     lang_check_failed (__FILE__, __LINE__, __FUNCTION__);		\
   &lt->u.fn; })

#define LANG_DECL_NS_CHECK(NODE) __extension__				\
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);			\
   if (TREE_CODE (NODE) != NAMESPACE_DECL || lt->u.base.selector != 2)	\
     lang_check_failed (__FILE__, __LINE__, __FUNCTION__);		\
   &lt->u.ns; })

#define LANG_DECL_PARM_CHECK(NODE) __extension__		\
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);		\
  if (TREE_CODE (NODE) != PARM_DECL)				\
    lang_check_failed (__FILE__, __LINE__, __FUNCTION__);	\
  &lt->u.parm; })

#define LANG_DECL_U2_CHECK(NODE, TF) __extension__		\
({  struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);		\
    if (!LANG_DECL_HAS_MIN (NODE) || lt->u.base.u2sel != TF)	\
      lang_check_failed (__FILE__, __LINE__, __FUNCTION__);	\
    &lt->u.min.u2; })

#else

#define LANG_DECL_MIN_CHECK(NODE) \
  (&DECL_LANG_SPECIFIC (NODE)->u.min)

#define LANG_DECL_FN_CHECK(NODE) \
  (&DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE))->u.fn)

#define LANG_DECL_NS_CHECK(NODE) \
  (&DECL_LANG_SPECIFIC (NODE)->u.ns)

#define LANG_DECL_PARM_CHECK(NODE) \
  (&DECL_LANG_SPECIFIC (NODE)->u.parm)

#define LANG_DECL_U2_CHECK(NODE, TF) \
  (&DECL_LANG_SPECIFIC (NODE)->u.min.u2)

#endif /* ENABLE_TREE_CHECKING */

/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
   declaration.  Some entities (like a member function in a local
   class, or a local variable) do not have linkage at all, and this
   macro should not be used in those cases.

   Implementation note: A FUNCTION_DECL without DECL_LANG_SPECIFIC was
   created by language-independent code, and has C linkage.  Most
   VAR_DECLs have C++ linkage, and do not have DECL_LANG_SPECIFIC, but
   we do create DECL_LANG_SPECIFIC for variables with non-C++ linkage.  */
#define DECL_LANGUAGE(NODE)				\
  (DECL_LANG_SPECIFIC (NODE)				\
   ? DECL_LANG_SPECIFIC (NODE)->u.base.language		\
   : (TREE_CODE (NODE) == FUNCTION_DECL			\
      ? lang_c : lang_cplusplus))

/* Set the language linkage for NODE to LANGUAGE.  */
#define SET_DECL_LANGUAGE(NODE, LANGUAGE) \
  (DECL_LANG_SPECIFIC (NODE)->u.base.language = (LANGUAGE))

/* For FUNCTION_DECLs and TEMPLATE_DECLs: nonzero means that this function
   is a constructor.  */
#define DECL_CONSTRUCTOR_P(NODE) \
  DECL_CXX_CONSTRUCTOR_P (STRIP_TEMPLATE (NODE))

/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete
   object.  */
#define DECL_COMPLETE_CONSTRUCTOR_P(NODE)		\
  (DECL_CONSTRUCTOR_P (NODE)				\
   && DECL_NAME (NODE) == complete_ctor_identifier)

/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a base
   object.  */
#define DECL_BASE_CONSTRUCTOR_P(NODE)		\
  (DECL_CONSTRUCTOR_P (NODE)			\
   && DECL_NAME (NODE) == base_ctor_identifier)

/* Nonzero if NODE (a FUNCTION_DECL) is a constructor, but not either the
   specialized in-charge constructor or the specialized not-in-charge
   constructor.  */
#define DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P(NODE)		\
  (DECL_DECLARES_FUNCTION_P (NODE) && DECL_CONSTRUCTOR_P (NODE) \
   && !DECL_CLONED_FUNCTION_P (NODE))

/* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor.  */
#define DECL_COPY_CONSTRUCTOR_P(NODE) \
  (DECL_CONSTRUCTOR_P (NODE) && copy_fn_p (NODE) > 0)

/* Nonzero if NODE (a FUNCTION_DECL) is a move constructor.  */
#define DECL_MOVE_CONSTRUCTOR_P(NODE) \
  (DECL_CONSTRUCTOR_P (NODE) && move_fn_p (NODE))

/* Nonzero if NODE (a FUNCTION_DECL or TEMPLATE_DECL)
   is a destructor.  */
#define DECL_DESTRUCTOR_P(NODE)				\
  DECL_CXX_DESTRUCTOR_P (STRIP_TEMPLATE (NODE))

/* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
   specialized in-charge constructor, in-charge deleting constructor,
   or the base destructor.  */
#define DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P(NODE)			\
  (DECL_DECLARES_FUNCTION_P (NODE) && DECL_DESTRUCTOR_P (NODE)	\
   && !DECL_CLONED_FUNCTION_P (NODE))

/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
   object.  */
#define DECL_COMPLETE_DESTRUCTOR_P(NODE)		\
  (DECL_DESTRUCTOR_P (NODE)				\
   && DECL_NAME (NODE) == complete_dtor_identifier)

/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a base
   object.  */
#define DECL_BASE_DESTRUCTOR_P(NODE)		\
  (DECL_DESTRUCTOR_P (NODE)			\
   && DECL_NAME (NODE) == base_dtor_identifier)

/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
   object that deletes the object after it has been destroyed.  */
#define DECL_DELETING_DESTRUCTOR_P(NODE)		\
  (DECL_DESTRUCTOR_P (NODE)				\
   && DECL_NAME (NODE) == deleting_dtor_identifier)

/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or
   destructor.  */
#define DECL_CLONED_FUNCTION_P(NODE) (!!decl_cloned_function_p (NODE, true))

/* If DECL_CLONED_FUNCTION_P holds, this is the function that was
   cloned.  */
#define DECL_CLONED_FUNCTION(NODE) (*decl_cloned_function_p (NODE, false))

/* Perform an action for each clone of FN, if FN is a function with
   clones.  This macro should be used like:

      FOR_EACH_CLONE (clone, fn)
	{ ... }

  */
#define FOR_EACH_CLONE(CLONE, FN)			\
  if (!(TREE_CODE (FN) == FUNCTION_DECL			\
	&& (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (FN)	\
	    || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (FN))))\
    ;							\
  else							\
    for (CLONE = DECL_CHAIN (FN);			\
	 CLONE && DECL_CLONED_FUNCTION_P (CLONE);	\
	 CLONE = DECL_CHAIN (CLONE))

/* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS.  */
#define DECL_DISCRIMINATOR_P(NODE)	\
  (VAR_P (NODE) && DECL_FUNCTION_SCOPE_P (NODE))

/* Discriminator for name mangling.  */
#define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator)

/* True iff DECL_DISCRIMINATOR is set for a DECL_DISCRIMINATOR_P decl.  */
#define DECL_DISCRIMINATOR_SET_P(NODE) \
  (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->u.base.u2sel == 1)

/* The index of a user-declared parameter in its function, starting at 1.
   All artificial parameters will have index 0.  */
#define DECL_PARM_INDEX(NODE) \
  (LANG_DECL_PARM_CHECK (NODE)->index)

/* The level of a user-declared parameter in its function, starting at 1.
   A parameter of the function will have level 1; a parameter of the first
   nested function declarator (i.e. t in void f (void (*p)(T t))) will have
   level 2.  */
#define DECL_PARM_LEVEL(NODE) \
  (LANG_DECL_PARM_CHECK (NODE)->level)

/* Nonzero if the VTT parm has been added to NODE.  */
#define DECL_HAS_VTT_PARM_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)

/* Nonzero if NODE is a FUNCTION_DECL for which a VTT parameter is
   required.  */
#define DECL_NEEDS_VTT_PARM_P(NODE)			\
  (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (NODE))		\
   && (DECL_BASE_CONSTRUCTOR_P (NODE)			\
       || DECL_BASE_DESTRUCTOR_P (NODE)))

/* Nonzero if NODE is a user-defined conversion operator.  */
#define DECL_CONV_FN_P(NODE) \
  (DECL_NAME (NODE) && IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)))

/* If FN is a conversion operator, the type to which it converts.
   Otherwise, NULL_TREE.  */
#define DECL_CONV_FN_TYPE(FN) \
  (DECL_CONV_FN_P (FN) ? TREE_TYPE (DECL_NAME (FN)) : NULL_TREE)

/* Nonzero if NODE, which is a TEMPLATE_DECL, is a template
   conversion operator to a type dependent on the innermost template
   args.  */
#define DECL_TEMPLATE_CONV_FN_P(NODE) \
  (DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE))->u.base.template_conv_p)

/* Nonzero if NODE, a static data member, was declared in its class as an
   array of unknown bound.  */
#define VAR_HAD_UNKNOWN_BOUND(NODE)			\
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))		\
   ? DECL_LANG_SPECIFIC (NODE)->u.base.template_conv_p	\
   : false)
#define SET_VAR_HAD_UNKNOWN_BOUND(NODE) \
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.template_conv_p = true)

/* Set the overloaded operator code for NODE to CODE.  */
#define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
  (LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE))

/* If NODE is an overloaded operator, then this returns the TREE_CODE
   associated with the overloaded operator.
   DECL_ASSIGNMENT_OPERATOR_P must also be checked to determine
   whether or not NODE is an assignment operator.  If NODE is not an
   overloaded operator, ERROR_MARK is returned.  Since the numerical
   value of ERROR_MARK is zero, this macro can be used as a predicate
   to test whether or not NODE is an overloaded operator.  */
#define DECL_OVERLOADED_OPERATOR_P(NODE)		\
  (IDENTIFIER_OPNAME_P (DECL_NAME (NODE))		\
   ? LANG_DECL_FN_CHECK (NODE)->operator_code : ERROR_MARK)

/* Nonzero if NODE is an assignment operator (including += and such).  */
#define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->assignment_operator_p)

/* For FUNCTION_DECLs: nonzero means that this function is a
   constructor or a destructor with an extra in-charge parameter to
   control whether or not virtual bases are constructed.  */
#define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->has_in_charge_parm_p)

/* Nonzero if DECL is a declaration of __builtin_constant_p.  */
#define DECL_IS_BUILTIN_CONSTANT_P(NODE)		\
 (TREE_CODE (NODE) == FUNCTION_DECL			\
  && DECL_BUILT_IN_CLASS (NODE) == BUILT_IN_NORMAL	\
  && DECL_FUNCTION_CODE (NODE) == BUILT_IN_CONSTANT_P)

/* Nonzero for _DECL means that this decl appears in (or will appear
   in) as a member in a RECORD_TYPE or UNION_TYPE node.  It is also for
   detecting circularity in case members are multiply defined.  In the
   case of a VAR_DECL, it is also used to determine how program storage
   should be allocated.  */
#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE))

/* Nonzero for a VAR_DECL means that the variable's initialization (if
   any) has been processed.  (In general, DECL_INITIALIZED_P is
   !DECL_EXTERNAL, but static data members may be initialized even if
   not defined.)  */
#define DECL_INITIALIZED_P(NODE) \
   (TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE)))

/* Nonzero for a VAR_DECL iff an explicit initializer was provided
   or a non-trivial constructor is called.  */
#define DECL_NONTRIVIALLY_INITIALIZED_P(NODE)	\
   (TREE_LANG_FLAG_3 (VAR_DECL_CHECK (NODE)))

/* Nonzero for a VAR_DECL that was initialized with a
   constant-expression.  */
#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
  (TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE)))

/* Nonzero if the DECL was initialized in the class definition itself,
   rather than outside the class.  This is used for both static member
   VAR_DECLS, and FUNCTION_DECLS that are defined in the class.  */
#define DECL_INITIALIZED_IN_CLASS_P(DECL) \
  (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
   ->u.base.initialized_in_class)

/* Nonzero if the DECL is used in the sense of 3.2 [basic.def.odr].
   Only available for decls with DECL_LANG_SPECIFIC.  */
#define DECL_ODR_USED(DECL) \
  (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
   ->u.base.odr_used)

/* Nonzero for DECL means that this decl is just a friend declaration,
   and should not be added to the list of members for this class.  */
#define DECL_FRIEND_P(NODE) \
  (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \
   ->u.base.friend_or_tls)

/* Nonzero if the thread-local variable was declared with __thread as
   opposed to thread_local.  */
#define DECL_GNU_TLS_P(NODE)				\
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))		\
   && DECL_LANG_SPECIFIC (NODE)->u.base.friend_or_tls)
#define SET_DECL_GNU_TLS_P(NODE)				\
  (retrofit_lang_decl (VAR_DECL_CHECK (NODE)),			\
   DECL_LANG_SPECIFIC (NODE)->u.base.friend_or_tls = true)

/* A TREE_LIST of the types which have befriended this FUNCTION_DECL.  */
#define DECL_BEFRIENDING_CLASSES(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->befriending_classes)

/* Nonzero for FUNCTION_DECL means that this decl is a static
   member function.  */
#define DECL_STATIC_FUNCTION_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->static_function)

/* Nonzero for FUNCTION_DECL means that this decl is a non-static
   member function.  */
#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \
  (TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE)

/* Nonzero for FUNCTION_DECL means that this decl is a member function
   (static or non-static).  */
#define DECL_FUNCTION_MEMBER_P(NODE) \
  (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))

/* Nonzero for FUNCTION_DECL means that this member function
   has `this' as const X *const.  */
#define DECL_CONST_MEMFUNC_P(NODE)					 \
  (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)				 \
   && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE				 \
				  (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))

/* Nonzero for FUNCTION_DECL means that this member function
   has `this' as volatile X *const.  */
#define DECL_VOLATILE_MEMFUNC_P(NODE)					 \
  (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)				 \
   && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE				 \
				  (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))

/* Nonzero for a DECL means that this member is a non-static member.  */
#define DECL_NONSTATIC_MEMBER_P(NODE)		\
  (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)	\
   || TREE_CODE (NODE) == FIELD_DECL)

/* Nonzero for _DECL means that this member object type
   is mutable.  */
#define DECL_MUTABLE_P(NODE) (DECL_LANG_FLAG_0 (NODE))

/* Nonzero for _DECL means that this constructor or conversion function is
   non-converting.  */
#define DECL_NONCONVERTING_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->nonconverting)

/* Nonzero for FUNCTION_DECL means that this member function is a pure
   virtual function.  */
#define DECL_PURE_VIRTUAL_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->pure_virtual)

/* True (in a FUNCTION_DECL) if NODE is a virtual function that is an
   invalid overrider for a function from a base class.  Once we have
   complained about an invalid overrider we avoid complaining about it
   again.  */
#define DECL_INVALID_OVERRIDER_P(NODE) \
  (DECL_LANG_FLAG_4 (NODE))

/* True (in a FUNCTION_DECL) if NODE is a function declared with
   an override virt-specifier */
#define DECL_OVERRIDE_P(NODE) (TREE_LANG_FLAG_0 (NODE))

/* The thunks associated with NODE, a FUNCTION_DECL.  */
#define DECL_THUNKS(NODE) \
  (DECL_VIRTUAL_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)

/* Set DECL_THUNKS.  */
#define SET_DECL_THUNKS(NODE,THUNKS) \
  (LANG_DECL_FN_CHECK (NODE)->context = (THUNKS))

/* If NODE, a FUNCTION_DECL, is a C++11 inheriting constructor, then this
   is the constructor it inherits from.  */
#define DECL_INHERITED_CTOR(NODE) \
  (DECL_DECLARES_FUNCTION_P (NODE) && DECL_CONSTRUCTOR_P (NODE) \
   ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)

/* And this is the base that constructor comes from.  */
#define DECL_INHERITED_CTOR_BASE(NODE)			\
  (DECL_INHERITED_CTOR (NODE)				\
   ? DECL_CONTEXT (flag_new_inheriting_ctors		\
		   ? strip_inheriting_ctors (NODE)	\
		   : DECL_INHERITED_CTOR (NODE))	\
   : NULL_TREE)

/* Set the inherited base.  */
#define SET_DECL_INHERITED_CTOR(NODE,INH) \
  (LANG_DECL_FN_CHECK (NODE)->context = (INH))

/* Nonzero if NODE is a thunk, rather than an ordinary function.  */
#define DECL_THUNK_P(NODE)			\
  (TREE_CODE (NODE) == FUNCTION_DECL		\
   && DECL_LANG_SPECIFIC (NODE)			\
   && LANG_DECL_FN_CHECK (NODE)->thunk_p)

/* Set DECL_THUNK_P for node.  */
#define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING)			\
  (LANG_DECL_FN_CHECK (NODE)->thunk_p = 1,			\
   LANG_DECL_FN_CHECK (NODE)->this_thunk_p = (THIS_ADJUSTING))

/* Nonzero if NODE is a this pointer adjusting thunk.  */
#define DECL_THIS_THUNK_P(NODE)			\
  (DECL_THUNK_P (NODE) && LANG_DECL_FN_CHECK (NODE)->this_thunk_p)

/* Nonzero if NODE is a result pointer adjusting thunk.  */
#define DECL_RESULT_THUNK_P(NODE)			\
  (DECL_THUNK_P (NODE) && !LANG_DECL_FN_CHECK (NODE)->this_thunk_p)

/* Nonzero if NODE is a FUNCTION_DECL, but not a thunk.  */
#define DECL_NON_THUNK_FUNCTION_P(NODE)				\
  (TREE_CODE (NODE) == FUNCTION_DECL && !DECL_THUNK_P (NODE))

/* Nonzero if NODE is `extern "C"'.  */
#define DECL_EXTERN_C_P(NODE) \
  (DECL_LANGUAGE (NODE) == lang_c)

/* Nonzero if NODE is an `extern "C"' function.  */
#define DECL_EXTERN_C_FUNCTION_P(NODE) \
  (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE))

/* True iff DECL is an entity with vague linkage whose definition is
   available in this translation unit.  */
#define DECL_REPO_AVAILABLE_P(NODE) \
  (DECL_LANG_SPECIFIC (NODE)->u.base.repo_available_p)

/* True if DECL is declared 'constexpr'.  */
#define DECL_DECLARED_CONSTEXPR_P(DECL) \
  DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (STRIP_TEMPLATE (DECL)))

// True if NODE was declared as 'concept'.  The flag implies that the
// declaration is constexpr, that the declaration cannot be specialized or
// refined, and that the result type must be convertible to bool.
#define DECL_DECLARED_CONCEPT_P(NODE) \
  (DECL_LANG_SPECIFIC (NODE)->u.base.concept_p)

/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
   template function.  */
#define DECL_PRETTY_FUNCTION_P(NODE) \
  (DECL_NAME (NODE) \
   && !strcmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__PRETTY_FUNCTION__"))

/* Nonzero if the variable was declared to be thread-local.
   We need a special C++ version of this test because the middle-end
   DECL_THREAD_LOCAL_P uses the symtab, so we can't use it for
   templates.  */
#define CP_DECL_THREAD_LOCAL_P(NODE) \
  (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)))

/* The _TYPE context in which this _DECL appears.  This field holds the
   class where a virtual function instance is actually defined.  */
#define DECL_CLASS_CONTEXT(NODE) \
  (DECL_CLASS_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : NULL_TREE)

/* For a non-member friend function, the class (if any) in which this
   friend was defined.  For example, given:

     struct S { friend void f (); };

   the DECL_FRIEND_CONTEXT for `f' will be `S'.  */
#define DECL_FRIEND_CONTEXT(NODE)				\
  ((DECL_DECLARES_FUNCTION_P (NODE)				\
    && DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE))	\
   ? LANG_DECL_FN_CHECK (NODE)->context				\
   : NULL_TREE)

/* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT.  */
#define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \
  (LANG_DECL_FN_CHECK (NODE)->context = (CONTEXT))

#define CP_DECL_CONTEXT(NODE) \
  (!DECL_FILE_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : global_namespace)
#define CP_TYPE_CONTEXT(NODE) \
  (!TYPE_FILE_SCOPE_P (NODE) ? TYPE_CONTEXT (NODE) : global_namespace)
#define FROB_CONTEXT(NODE) \
  ((NODE) == global_namespace ? DECL_CONTEXT (NODE) : (NODE))

/* 1 iff NODE has namespace scope, including the global namespace.  */
#define DECL_NAMESPACE_SCOPE_P(NODE)				\
  (!DECL_TEMPLATE_PARM_P (NODE)					\
   && TREE_CODE (CP_DECL_CONTEXT (NODE)) == NAMESPACE_DECL)

#define TYPE_NAMESPACE_SCOPE_P(NODE) \
  (TREE_CODE (CP_TYPE_CONTEXT (NODE)) == NAMESPACE_DECL)

#define NAMESPACE_SCOPE_P(NODE) \
  ((DECL_P (NODE) && DECL_NAMESPACE_SCOPE_P (NODE)) \
   || (TYPE_P (NODE) && TYPE_NAMESPACE_SCOPE_P (NODE)))

/* 1 iff NODE is a class member.  */
#define DECL_CLASS_SCOPE_P(NODE) \
  (DECL_CONTEXT (NODE) && TYPE_P (DECL_CONTEXT (NODE)))

#define TYPE_CLASS_SCOPE_P(NODE) \
  (TYPE_CONTEXT (NODE) && TYPE_P (TYPE_CONTEXT (NODE)))

/* 1 iff NODE is function-local.  */
#define DECL_FUNCTION_SCOPE_P(NODE) \
  (DECL_CONTEXT (NODE) \
   && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL)

#define TYPE_FUNCTION_SCOPE_P(NODE) \
  (TYPE_CONTEXT (NODE) && TREE_CODE (TYPE_CONTEXT (NODE)) == FUNCTION_DECL)

/* 1 iff VAR_DECL node NODE is a type-info decl.  This flag is set for
   both the primary typeinfo object and the associated NTBS name.  */
#define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))

/* 1 iff VAR_DECL node NODE is virtual table or VTT.  */
#define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE))

/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */
#define FUNCTION_REF_QUALIFIED(NODE) \
  TREE_LANG_FLAG_4 (FUNC_OR_METHOD_CHECK (NODE))

/* 1 iff FUNCTION_TYPE or METHOD_TYPE has &&-ref-qualifier.  */
#define FUNCTION_RVALUE_QUALIFIED(NODE) \
  TREE_LANG_FLAG_5 (FUNC_OR_METHOD_CHECK (NODE))

/* Returns 1 iff VAR_DECL is a construction virtual table.
   DECL_VTABLE_OR_VTT_P will be true in this case and must be checked
   before using this macro.  */
#define DECL_CONSTRUCTION_VTABLE_P(NODE) \
  TREE_LANG_FLAG_6 (VAR_DECL_CHECK (NODE))

/* 1 iff NODE is function-local, but for types.  */
#define LOCAL_CLASS_P(NODE)				\
  (decl_function_context (TYPE_MAIN_DECL (NODE)) != NULL_TREE)

/* For a NAMESPACE_DECL: the list of using namespace directives
   The PURPOSE is the used namespace, the value is the namespace
   that is the common ancestor.  */
#define DECL_NAMESPACE_USING(NODE) (LANG_DECL_NS_CHECK (NODE)->ns_using)

/* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users
   of a namespace, to record the transitive closure of using namespace.  */
#define DECL_NAMESPACE_USERS(NODE) (LANG_DECL_NS_CHECK (NODE)->ns_users)

/* In a NAMESPACE_DECL, the list of namespaces which have associated
   themselves with this one.  */
#define DECL_NAMESPACE_ASSOCIATIONS(NODE) \
  DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE))

/* In a NAMESPACE_DECL, points to the original namespace if this is
   a namespace alias.  */
#define DECL_NAMESPACE_ALIAS(NODE) \
	DECL_ABSTRACT_ORIGIN (NAMESPACE_DECL_CHECK (NODE))
#define ORIGINAL_NAMESPACE(NODE)  \
  (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE))

/* Nonzero if NODE is the std namespace.  */
#define DECL_NAMESPACE_STD_P(NODE)			\
  (TREE_CODE (NODE) == NAMESPACE_DECL			\
   && CP_DECL_CONTEXT (NODE) == global_namespace	\
   && DECL_NAME (NODE) == std_identifier)

/* In a TREE_LIST concatenating using directives, indicate indirect
   directives  */
#define TREE_INDIRECT_USING(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))

/* In a TREE_LIST in an attribute list, indicates that the attribute
   must be applied at instantiation time.  */
#define ATTR_IS_DEPENDENT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))

/* In a TREE_LIST in the argument of attribute abi_tag, indicates that the tag
   was inherited from a template parameter, not explicitly indicated.  */
#define ABI_TAG_IMPLICIT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))

extern tree decl_shadowed_for_var_lookup (tree);
extern void decl_shadowed_for_var_insert (tree, tree);

/* Non zero if this is a using decl for a dependent scope. */
#define DECL_DEPENDENT_P(NODE) DECL_LANG_FLAG_0 (USING_DECL_CHECK (NODE))

/* The scope named in a using decl.  */
#define USING_DECL_SCOPE(NODE) TREE_TYPE (USING_DECL_CHECK (NODE))

/* The decls named by a using decl.  */
#define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))

/* Non zero if the using decl refers to a dependent type.  */
#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE))

/* In a VAR_DECL, true if we have a shadowed local variable
   in the shadowed var table for this VAR_DECL.  */
#define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \
  (VAR_DECL_CHECK (NODE)->decl_with_vis.shadowed_for_var_p)

/* In a VAR_DECL for a variable declared in a for statement,
   this is the shadowed (local) variable.  */
#define DECL_SHADOWED_FOR_VAR(NODE) \
  (DECL_HAS_SHADOWED_FOR_VAR_P(NODE) ? decl_shadowed_for_var_lookup (NODE) : NULL)

#define SET_DECL_SHADOWED_FOR_VAR(NODE, VAL) \
  (decl_shadowed_for_var_insert (NODE, VAL))

/* In a FUNCTION_DECL, this is nonzero if this function was defined in
   the class definition.  We have saved away the text of the function,
   but have not yet processed it.  */
#define DECL_PENDING_INLINE_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->pending_inline_p)

/* If DECL_PENDING_INLINE_P holds, this is the saved text of the
   function.  */
#define DECL_PENDING_INLINE_INFO(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info)

/* Nonzero for TYPE_DECL means that it was written 'using name = type'.  */
#define TYPE_DECL_ALIAS_P(NODE) \
  DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE))

/* Nonzero for TEMPLATE_DECL means that it is a 'complex' alias template.  */
#define TEMPLATE_DECL_COMPLEX_ALIAS_P(NODE) \
  DECL_LANG_FLAG_2 (TEMPLATE_DECL_CHECK (NODE))

/* Nonzero for a type which is an alias for another type; i.e, a type
   which declaration was written 'using name-of-type =
   another-type'.  */
#define TYPE_ALIAS_P(NODE)			\
  (TYPE_P (NODE)				\
   && TYPE_NAME (NODE)				\
   && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL	\
   && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE)))

/* For a class type: if this structure has many fields, we'll sort them
   and put them into a TREE_VEC.  */
#define CLASSTYPE_SORTED_FIELDS(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->sorted_fields)

/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
   TEMPLATE_DECL, the entity is either a template specialization (if
   DECL_USE_TEMPLATE is nonzero) or the abstract instance of the
   template itself.

   In either case, DECL_TEMPLATE_INFO is a TREE_LIST, whose
   TREE_PURPOSE is the TEMPLATE_DECL of which this entity is a
   specialization or abstract instance.  The TREE_VALUE is the
   template arguments used to specialize the template.
   
   Consider:

      template <typename T> struct S { friend void f(T) {} };

   In this case, S<int>::f is, from the point of view of the compiler,
   an instantiation of a template -- but, from the point of view of
   the language, each instantiation of S results in a wholly unrelated
   global function f.  In this case, DECL_TEMPLATE_INFO for S<int>::f
   will be non-NULL, but DECL_USE_TEMPLATE will be zero.  */
#define DECL_TEMPLATE_INFO(NODE) \
  (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK (NODE)) \
   ->u.min.template_info)

/* For a VAR_DECL, indicates that the variable is actually a
   non-static data member of anonymous union that has been promoted to
   variable status.  */
#define DECL_ANON_UNION_VAR_P(NODE) \
  (DECL_LANG_FLAG_4 (VAR_DECL_CHECK (NODE)))

/* Template information for a RECORD_TYPE or UNION_TYPE.  */
#define CLASSTYPE_TEMPLATE_INFO(NODE) \
  (LANG_TYPE_CLASS_CHECK (RECORD_OR_UNION_CHECK (NODE))->template_info)

/* Template information for an ENUMERAL_TYPE.  Although an enumeration may
   not be a primary template, it may be declared within the scope of a
   primary template and the enumeration constants may depend on
   non-type template parameters.  */
#define ENUM_TEMPLATE_INFO(NODE) \
  (TYPE_LANG_SLOT_1 (ENUMERAL_TYPE_CHECK (NODE)))

/* Template information for a template template parameter.  */
#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \
  (LANG_TYPE_CLASS_CHECK (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \
   ->template_info)

/* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or
   BOUND_TEMPLATE_TEMPLATE_PARM type.  This ignores any alias
   templateness of NODE.  */
#define TYPE_TEMPLATE_INFO(NODE)					\
  (TREE_CODE (NODE) == ENUMERAL_TYPE					\
   ? ENUM_TEMPLATE_INFO (NODE)						\
   : (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM			\
      ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE)			\
      : (CLASS_TYPE_P (NODE)						\
	 ? CLASSTYPE_TEMPLATE_INFO (NODE)				\
	 : NULL_TREE)))

/* Template information (if any) for an alias type.  */
#define TYPE_ALIAS_TEMPLATE_INFO(NODE)					\
  (DECL_LANG_SPECIFIC (TYPE_NAME (NODE))				\
   ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE))				\
   : NULL_TREE)

/* If NODE is a type alias, this accessor returns the template info
   for the alias template (if any).  Otherwise behave as
   TYPE_TEMPLATE_INFO.  */
#define TYPE_TEMPLATE_INFO_MAYBE_ALIAS(NODE)				\
  (TYPE_ALIAS_P (NODE)							\
   ? TYPE_ALIAS_TEMPLATE_INFO (NODE)					\
   : TYPE_TEMPLATE_INFO (NODE))

/* Set the template information for an ENUMERAL_, RECORD_, or
   UNION_TYPE to VAL.  */
#define SET_TYPE_TEMPLATE_INFO(NODE, VAL)				\
  (TREE_CODE (NODE) == ENUMERAL_TYPE					\
   ? (ENUM_TEMPLATE_INFO (NODE) = (VAL))				\
   : ((CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE))			\
      ? (CLASSTYPE_TEMPLATE_INFO (NODE) = (VAL))			\
      : (DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) = (VAL))))

#define TI_TEMPLATE(NODE) TREE_TYPE (TEMPLATE_INFO_CHECK (NODE))
#define TI_ARGS(NODE) TREE_CHAIN (TEMPLATE_INFO_CHECK (NODE))
#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
/* For a given TREE_VEC containing a template argument list,
   this property contains the number of arguments that are not
   defaulted.  */
#define NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) TREE_CHAIN (TREE_VEC_CHECK (NODE))
/* Below are the setter and getter of the NON_DEFAULT_TEMPLATE_ARGS_COUNT
   property.  */
#define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \
  NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) = build_int_cst (NULL_TREE, INT_VALUE)
#if CHECKING_P
#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
    int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE))
#else
#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
  NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE) \
  ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \
  : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
#endif
/* The list of typedefs - used in the template - that need
   access checking at template instantiation time.

   FIXME this should be associated with the TEMPLATE_DECL, not the
   TEMPLATE_INFO.  */
#define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \
  ((struct tree_template_info*)TEMPLATE_INFO_CHECK \
     (NODE))->typedefs_needing_access_checking

/* We use TREE_VECs to hold template arguments.  If there is only one
   level of template arguments, then the TREE_VEC contains the
   arguments directly.  If there is more than one level of template
   arguments, then each entry in the TREE_VEC is itself a TREE_VEC,
   containing the template arguments for a single level.  The first
   entry in the outer TREE_VEC is the outermost level of template
   parameters; the last is the innermost.

   It is incorrect to ever form a template argument vector containing
   only one level of arguments, but which is a TREE_VEC containing as
   its only entry the TREE_VEC for that level.

   For each TREE_VEC containing the template arguments for a single
   level, it's possible to get or set the number of non defaulted
   template arguments by using the accessor macros
   GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT or
   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT.  */

/* Nonzero if the template arguments is actually a vector of vectors,
   rather than just a vector.  */
#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE)		     \
  (NODE && TREE_VEC_LENGTH (NODE) && TREE_VEC_ELT (NODE, 0)  \
   && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)

/* The depth of a template argument vector.  When called directly by
   the parser, we use a TREE_LIST rather than a TREE_VEC to represent
   template arguments.  In fact, we may even see NULL_TREE if there
   are no template arguments.  In both of those cases, there is only
   one level of template arguments.  */
#define TMPL_ARGS_DEPTH(NODE)					\
  (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1)

/* The LEVELth level of the template ARGS.  The outermost level of
   args is level 1, not level 0.  */
#define TMPL_ARGS_LEVEL(ARGS, LEVEL)		\
  (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS)	\
   ? TREE_VEC_ELT (ARGS, (LEVEL) - 1) : (ARGS))

/* Set the LEVELth level of the template ARGS to VAL.  This macro does
   not work with single-level argument vectors.  */
#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL)	\
  (TREE_VEC_ELT (ARGS, (LEVEL) - 1) = (VAL))

/* Accesses the IDXth parameter in the LEVELth level of the ARGS.  */
#define TMPL_ARG(ARGS, LEVEL, IDX)				\
  (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX))

/* Given a single level of template arguments in NODE, return the
   number of arguments.  */
#define NUM_TMPL_ARGS(NODE)				\
  (TREE_VEC_LENGTH (NODE))

/* Returns the innermost level of template arguments in ARGS.  */
#define INNERMOST_TEMPLATE_ARGS(NODE) \
  (get_innermost_template_args ((NODE), 1))

/* The number of levels of template parameters given by NODE.  */
#define TMPL_PARMS_DEPTH(NODE) \
  ((HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_PURPOSE (NODE)))

/* The TEMPLATE_DECL instantiated or specialized by NODE.  This
   TEMPLATE_DECL will be the immediate parent, not the most general
   template.  For example, in:

      template <class T> struct S { template <class U> void f(U); }

   the FUNCTION_DECL for S<int>::f<double> will have, as its
   DECL_TI_TEMPLATE, `template <class U> S<int>::f<U>'.

   As a special case, for a member friend template of a template
   class, this value will not be a TEMPLATE_DECL, but rather an
   IDENTIFIER_NODE or OVERLOAD indicating the name of the template and
   any explicit template arguments provided.  For example, in:

     template <class T> struct S { friend void f<int>(int, double); }

   the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the
   DECL_TI_ARGS will be {int}.

   For a FIELD_DECL with a non-static data member initializer, this value
   is the FIELD_DECL it was instantiated from.  */
#define DECL_TI_TEMPLATE(NODE)      TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))

/* The template arguments used to obtain this decl from the most
   general form of DECL_TI_TEMPLATE.  For the example given for
   DECL_TI_TEMPLATE, the DECL_TI_ARGS will be {int, double}.  These
   are always the full set of arguments required to instantiate this
   declaration from the most general template specialized here.  */
#define DECL_TI_ARGS(NODE)	    TI_ARGS (DECL_TEMPLATE_INFO (NODE))

/* The TEMPLATE_DECL associated with NODE, a class type.  Even if NODE
   will be generated from a partial specialization, the TEMPLATE_DECL
   referred to here will be the original template.  For example,
   given:

      template <typename T> struct S {};
      template <typename T> struct S<T*> {};
      
   the CLASSTPYE_TI_TEMPLATE for S<int*> will be S, not the S<T*>.  */
#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_ARGS(NODE)     TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE))

/* For a template instantiation TYPE, returns the TYPE corresponding
   to the primary template.  Otherwise returns TYPE itself.  */
#define CLASSTYPE_PRIMARY_TEMPLATE_TYPE(TYPE)				\
  ((CLASSTYPE_USE_TEMPLATE ((TYPE))					\
    && !CLASSTYPE_TEMPLATE_SPECIALIZATION ((TYPE)))			\
   ? TREE_TYPE (DECL_TEMPLATE_RESULT (DECL_PRIMARY_TEMPLATE		\
				      (CLASSTYPE_TI_TEMPLATE ((TYPE))))) \
   : (TYPE))

/* Like CLASS_TI_TEMPLATE, but also works for ENUMERAL_TYPEs.  */
#define TYPE_TI_TEMPLATE(NODE)			\
  (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))

/* Like DECL_TI_ARGS, but for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
#define TYPE_TI_ARGS(NODE)			\
  (TI_ARGS (TYPE_TEMPLATE_INFO (NODE)))

#define INNERMOST_TEMPLATE_PARMS(NODE)  TREE_VALUE (NODE)

/* Nonzero if NODE (a TEMPLATE_DECL) is a member template, in the
   sense of [temp.mem].  */
#define DECL_MEMBER_TEMPLATE_P(NODE) \
  (DECL_LANG_FLAG_1 (TEMPLATE_DECL_CHECK (NODE)))

/* Nonzero if the NODE corresponds to the template parameters for a
   member template, whose inline definition is being processed after
   the class definition is complete.  */
#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)

/* Determine if a declaration (PARM_DECL or FIELD_DECL) is a pack.  */
#define DECL_PACK_P(NODE) \
  (DECL_P (NODE) && PACK_EXPANSION_P (TREE_TYPE (NODE)))

/* Determines if NODE is an expansion of one or more parameter packs,
   e.g., a TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION.  */
#define PACK_EXPANSION_P(NODE)                 \
  (TREE_CODE (NODE) == TYPE_PACK_EXPANSION     \
   || TREE_CODE (NODE) == EXPR_PACK_EXPANSION)

/* Extracts the type or expression pattern from a TYPE_PACK_EXPANSION or
   EXPR_PACK_EXPANSION.  */
#define PACK_EXPANSION_PATTERN(NODE)                            \
  (TREE_CODE (NODE) == TYPE_PACK_EXPANSION? TREE_TYPE (NODE)    \
   : TREE_OPERAND (NODE, 0))

/* Sets the type or expression pattern for a TYPE_PACK_EXPANSION or
   EXPR_PACK_EXPANSION.  */
#define SET_PACK_EXPANSION_PATTERN(NODE,VALUE)  \
  if (TREE_CODE (NODE) == TYPE_PACK_EXPANSION)  \
    TREE_TYPE (NODE) = VALUE;                   \
  else                                          \
    TREE_OPERAND (NODE, 0) = VALUE

/* The list of parameter packs used in the PACK_EXPANSION_* node. The
   TREE_VALUE of each TREE_LIST contains the parameter packs.  */
#define PACK_EXPANSION_PARAMETER_PACKS(NODE)		\
  *(TREE_CODE (NODE) == EXPR_PACK_EXPANSION		\
    ? &TREE_OPERAND (NODE, 1)				\
    : &TYPE_MINVAL (TYPE_PACK_EXPANSION_CHECK (NODE)))

/* Any additional template args to be applied when substituting into
   the pattern, set by tsubst_pack_expansion for partial instantiations.  */
#define PACK_EXPANSION_EXTRA_ARGS(NODE)		\
  *(TREE_CODE (NODE) == TYPE_PACK_EXPANSION	\
    ? &TYPE_MAXVAL (NODE)			\
    : &TREE_OPERAND ((NODE), 2))

/* True iff this pack expansion is within a function context.  */
#define PACK_EXPANSION_LOCAL_P(NODE) TREE_LANG_FLAG_0 (NODE)

/* True iff this pack expansion is for sizeof....  */
#define PACK_EXPANSION_SIZEOF_P(NODE) TREE_LANG_FLAG_1 (NODE)

/* True iff the wildcard can match a template parameter pack.  */
#define WILDCARD_PACK_P(NODE) TREE_LANG_FLAG_0 (NODE)

/* Determine if this is an argument pack.  */
#define ARGUMENT_PACK_P(NODE)                          \
  (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK              \
   || TREE_CODE (NODE) == NONTYPE_ARGUMENT_PACK)

/* The arguments stored in an argument pack. Arguments are stored in a
   TREE_VEC, which may have length zero.  */
#define ARGUMENT_PACK_ARGS(NODE)                               \
  (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK? TREE_TYPE (NODE)    \
   : TREE_OPERAND (NODE, 0))

/* Set the arguments stored in an argument pack. VALUE must be a
   TREE_VEC.  */
#define SET_ARGUMENT_PACK_ARGS(NODE,VALUE)     \
  if (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK)  \
    TREE_TYPE (NODE) = VALUE;                           \
  else                                                  \
    TREE_OPERAND (NODE, 0) = VALUE

/* Whether the argument pack is "incomplete", meaning that more
   arguments can still be deduced. Incomplete argument packs are only
   used when the user has provided an explicit template argument list
   for a variadic function template. Some of the explicit template
   arguments will be placed into the beginning of the argument pack,
   but additional arguments might still be deduced.  */
#define ARGUMENT_PACK_INCOMPLETE_P(NODE)        \
  TREE_ADDRESSABLE (ARGUMENT_PACK_ARGS (NODE))

/* When ARGUMENT_PACK_INCOMPLETE_P, stores the explicit template
   arguments used to fill this pack.  */
#define ARGUMENT_PACK_EXPLICIT_ARGS(NODE)       \
  TREE_TYPE (ARGUMENT_PACK_ARGS (NODE))

/* In an ARGUMENT_PACK_SELECT, the argument pack from which an
   argument will be selected.  */
#define ARGUMENT_PACK_SELECT_FROM_PACK(NODE)				\
  (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->argument_pack)

/* In an ARGUMENT_PACK_SELECT, the index of the argument we want to
   select.  */
#define ARGUMENT_PACK_SELECT_INDEX(NODE)				\
  (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->index)
  
/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the
   ARGUMENT_PACK_SELECT represents. */
#define ARGUMENT_PACK_SELECT_ARG(NODE)					\
  TREE_VEC_ELT (ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (NODE)), \
	        ARGUMENT_PACK_SELECT_INDEX (NODE))

#define FOLD_EXPR_CHECK(NODE)						\
  TREE_CHECK4 (NODE, UNARY_LEFT_FOLD_EXPR, UNARY_RIGHT_FOLD_EXPR,	\
	       BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR)

#define BINARY_FOLD_EXPR_CHECK(NODE) \
  TREE_CHECK2 (NODE, BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR)

/* True if NODE is UNARY_FOLD_EXPR or a BINARY_FOLD_EXPR */
#define FOLD_EXPR_P(NODE)				\
  (TREE_CODE (NODE) == UNARY_LEFT_FOLD_EXPR		\
   || TREE_CODE (NODE) == UNARY_RIGHT_FOLD_EXPR		\
   || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR		\
   || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR)

/* True when NODE is a fold over a compound assignment operator. */
#define FOLD_EXPR_MODIFY_P(NODE) \
  TREE_LANG_FLAG_0 (FOLD_EXPR_CHECK (NODE))

/* An INTEGER_CST containing the tree code of the folded operator. */
#define FOLD_EXPR_OP(NODE) \
  TREE_OPERAND (FOLD_EXPR_CHECK (NODE), 0)

/* The expression containing an unexpanded parameter pack. */
#define FOLD_EXPR_PACK(NODE) \
  TREE_OPERAND (FOLD_EXPR_CHECK (NODE), 1)

/* In a binary fold expression, the argument with no unexpanded
   parameter packs. */
#define FOLD_EXPR_INIT(NODE) \
  TREE_OPERAND (BINARY_FOLD_EXPR_CHECK (NODE), 2)

/* In a FUNCTION_DECL, the saved language-specific per-function data.  */
#define DECL_SAVED_FUNCTION_DATA(NODE)			\
  (LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE))	\
   ->u.saved_language_function)

/* True if NODE is an implicit INDIRECT_EXPR from convert_from_reference.  */
#define REFERENCE_REF_P(NODE)				\
  (INDIRECT_REF_P (NODE)				\
   && TREE_TYPE (TREE_OPERAND (NODE, 0))		\
   && (TREE_CODE (TREE_TYPE (TREE_OPERAND ((NODE), 0)))	\
       == REFERENCE_TYPE))

/* True if NODE is a REFERENCE_TYPE which is OK to instantiate to be a
   reference to VLA type, because it's used for VLA capture.  */
#define REFERENCE_VLA_OK(NODE) \
  (TYPE_LANG_FLAG_5 (REFERENCE_TYPE_CHECK (NODE)))

#define NEW_EXPR_USE_GLOBAL(NODE) \
  TREE_LANG_FLAG_0 (NEW_EXPR_CHECK (NODE))
#define DELETE_EXPR_USE_GLOBAL(NODE) \
  TREE_LANG_FLAG_0 (DELETE_EXPR_CHECK (NODE))
#define DELETE_EXPR_USE_VEC(NODE) \
  TREE_LANG_FLAG_1 (DELETE_EXPR_CHECK (NODE))

#define CALL_OR_AGGR_INIT_CHECK(NODE) \
  TREE_CHECK2 ((NODE), CALL_EXPR, AGGR_INIT_EXPR)

/* Indicates that this is a non-dependent COMPOUND_EXPR which will
   resolve to a function call.  */
#define COMPOUND_EXPR_OVERLOADED(NODE) \
  TREE_LANG_FLAG_0 (COMPOUND_EXPR_CHECK (NODE))

/* In a CALL_EXPR appearing in a template, true if Koenig lookup
   should be performed at instantiation time.  */
#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0 (CALL_EXPR_CHECK (NODE))

/* True if the arguments to NODE should be evaluated in left-to-right
   order regardless of PUSH_ARGS_REVERSED.  */
#define CALL_EXPR_ORDERED_ARGS(NODE) \
  TREE_LANG_FLAG_3 (CALL_OR_AGGR_INIT_CHECK (NODE))

/* True if the arguments to NODE should be evaluated in right-to-left
   order regardless of PUSH_ARGS_REVERSED.  */
#define CALL_EXPR_REVERSE_ARGS(NODE) \
  TREE_LANG_FLAG_5 (CALL_OR_AGGR_INIT_CHECK (NODE))

/* True if CALL_EXPR was written as an operator expression, not a function
   call.  */
#define CALL_EXPR_OPERATOR_SYNTAX(NODE) \
  TREE_LANG_FLAG_6 (CALL_OR_AGGR_INIT_CHECK (NODE))

/* Indicates whether a string literal has been parenthesized. Such
   usages are disallowed in certain circumstances.  */

#define PAREN_STRING_LITERAL_P(NODE) \
  TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE))

/* Indicates whether a COMPONENT_REF or a SCOPE_REF has been parenthesized, or
   an INDIRECT_REF comes from parenthesizing a _DECL.  Currently only set some
   of the time in C++14 mode.  */

#define REF_PARENTHESIZED_P(NODE) \
  TREE_LANG_FLAG_2 (TREE_CHECK3 ((NODE), COMPONENT_REF, INDIRECT_REF, SCOPE_REF))

/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
   constructor call, rather than an ordinary function call.  */
#define AGGR_INIT_VIA_CTOR_P(NODE) \
  TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE))

/* Nonzero if expanding this AGGR_INIT_EXPR should first zero-initialize
   the object.  */
#define AGGR_INIT_ZERO_FIRST(NODE) \
  TREE_LANG_FLAG_2 (AGGR_INIT_EXPR_CHECK (NODE))

/* Nonzero means that the call is the jump from a thunk to the
   thunked-to function.  */
#define AGGR_INIT_FROM_THUNK_P(NODE) \
  (AGGR_INIT_EXPR_CHECK (NODE)->base.protected_flag)

/* AGGR_INIT_EXPR accessors.  These are equivalent to the CALL_EXPR
   accessors, except for AGGR_INIT_EXPR_SLOT (which takes the place of
   CALL_EXPR_STATIC_CHAIN).  */

#define AGGR_INIT_EXPR_FN(NODE) TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 1)
#define AGGR_INIT_EXPR_SLOT(NODE) \
  TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 2)
#define AGGR_INIT_EXPR_ARG(NODE, I) \
  TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), (I) + 3)
#define aggr_init_expr_nargs(NODE) (VL_EXP_OPERAND_LENGTH(NODE) - 3)

/* AGGR_INIT_EXPR_ARGP returns a pointer to the argument vector for NODE.
   We can't use &AGGR_INIT_EXPR_ARG (NODE, 0) because that will complain if
   the argument count is zero when checking is enabled.  Instead, do
   the pointer arithmetic to advance past the 3 fixed operands in a
   AGGR_INIT_EXPR.  That produces a valid pointer to just past the end of
   the operand array, even if it's not valid to dereference it.  */
#define AGGR_INIT_EXPR_ARGP(NODE) \
  (&(TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 0)) + 3)

/* Abstract iterators for AGGR_INIT_EXPRs.  */

/* Structure containing iterator state.  */
struct aggr_init_expr_arg_iterator {
  tree t;	/* the aggr_init_expr */
  int n;	/* argument count */
  int i;	/* next argument index */
};

/* Initialize the abstract argument list iterator object ITER with the
   arguments from AGGR_INIT_EXPR node EXP.  */
inline void
init_aggr_init_expr_arg_iterator (tree exp,
				       aggr_init_expr_arg_iterator *iter)
{
  iter->t = exp;
  iter->n = aggr_init_expr_nargs (exp);
  iter->i = 0;
}

/* Return the next argument from abstract argument list iterator object ITER,
   and advance its state.  Return NULL_TREE if there are no more arguments.  */
inline tree
next_aggr_init_expr_arg (aggr_init_expr_arg_iterator *iter)
{
  tree result;
  if (iter->i >= iter->n)
    return NULL_TREE;
  result = AGGR_INIT_EXPR_ARG (iter->t, iter->i);
  iter->i++;
  return result;
}

/* Initialize the abstract argument list iterator object ITER, then advance
   past and return the first argument.  Useful in for expressions, e.g.
     for (arg = first_aggr_init_expr_arg (exp, &iter); arg;
          arg = next_aggr_init_expr_arg (&iter))   */
inline tree
first_aggr_init_expr_arg (tree exp, aggr_init_expr_arg_iterator *iter)
{
  init_aggr_init_expr_arg_iterator (exp, iter);
  return next_aggr_init_expr_arg (iter);
}

/* Test whether there are more arguments in abstract argument list iterator
   ITER, without changing its state.  */
inline bool
more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
{
  return (iter->i < iter->n);
}

/* Iterate through each argument ARG of AGGR_INIT_EXPR CALL, using variable
   ITER (of type aggr_init_expr_arg_iterator) to hold the iteration state.  */
#define FOR_EACH_AGGR_INIT_EXPR_ARG(arg, iter, call)			\
  for ((arg) = first_aggr_init_expr_arg ((call), &(iter)); (arg);	\
       (arg) = next_aggr_init_expr_arg (&(iter)))

/* VEC_INIT_EXPR accessors.  */
#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 0)
#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 1)

/* Indicates that a VEC_INIT_EXPR is a potential constant expression.
   Only set when the current function is constexpr.  */
#define VEC_INIT_EXPR_IS_CONSTEXPR(NODE) \
  TREE_LANG_FLAG_0 (VEC_INIT_EXPR_CHECK (NODE))

/* Indicates that a VEC_INIT_EXPR is expressing value-initialization.  */
#define VEC_INIT_EXPR_VALUE_INIT(NODE) \
  TREE_LANG_FLAG_1 (VEC_INIT_EXPR_CHECK (NODE))

/* The condition under which this MUST_NOT_THROW_EXPR actually blocks
   exceptions.  NULL_TREE means 'true'.  */
#define MUST_NOT_THROW_COND(NODE) \
  TREE_OPERAND (MUST_NOT_THROW_EXPR_CHECK (NODE), 1)

/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
   TEMPLATE_DECL.  This macro determines whether or not a given class
   type is really a template type, as opposed to an instantiation or
   specialization of one.  */
#define CLASSTYPE_IS_TEMPLATE(NODE)  \
  (CLASSTYPE_TEMPLATE_INFO (NODE)    \
   && !CLASSTYPE_USE_TEMPLATE (NODE) \
   && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))

/* The name used by the user to name the typename type.  Typically,
   this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
   corresponding TYPE_DECL.  However, this may also be a
   TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'.  */
#define TYPENAME_TYPE_FULLNAME(NODE) \
  (TYPE_VALUES_RAW (TYPENAME_TYPE_CHECK (NODE)))

/* True if a TYPENAME_TYPE was declared as an "enum".  */
#define TYPENAME_IS_ENUM_P(NODE) \
  (TREE_LANG_FLAG_0 (TYPENAME_TYPE_CHECK (NODE)))

/* True if a TYPENAME_TYPE was declared as a "class", "struct", or
   "union".  */
#define TYPENAME_IS_CLASS_P(NODE) \
  (TREE_LANG_FLAG_1 (TYPENAME_TYPE_CHECK (NODE)))

/* True if a TYPENAME_TYPE is in the process of being resolved.  */
#define TYPENAME_IS_RESOLVING_P(NODE) \
  (TREE_LANG_FLAG_2 (TYPENAME_TYPE_CHECK (NODE)))

/* [class.virtual]

   A class that declares or inherits a virtual function is called a
   polymorphic class.  */
#define TYPE_POLYMORPHIC_P(NODE) (TREE_LANG_FLAG_2 (NODE))

/* Nonzero if this class has a virtual function table pointer.  */
#define TYPE_CONTAINS_VPTR_P(NODE)		\
  (TYPE_POLYMORPHIC_P (NODE) || CLASSTYPE_VBASECLASSES (NODE))

/* This flag is true of a local VAR_DECL if it was declared in a for
   statement, but we are no longer in the scope of the for.  */
#define DECL_DEAD_FOR_LOCAL(NODE) DECL_LANG_FLAG_7 (VAR_DECL_CHECK (NODE))

/* This flag is set on a VAR_DECL that is a DECL_DEAD_FOR_LOCAL
   if we already emitted a warning about using it.  */
#define DECL_ERROR_REPORTED(NODE) DECL_LANG_FLAG_0 (VAR_DECL_CHECK (NODE))

/* Nonzero if NODE is a FUNCTION_DECL (for a function with global
   scope) declared in a local scope.  */
#define DECL_LOCAL_FUNCTION_P(NODE) \
  DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE))

/* Nonzero if NODE is the target for genericization of 'break' stmts.  */
#define LABEL_DECL_BREAK(NODE) \
  DECL_LANG_FLAG_0 (LABEL_DECL_CHECK (NODE))

/* Nonzero if NODE is the target for genericization of 'continue' stmts.  */
#define LABEL_DECL_CONTINUE(NODE) \
  DECL_LANG_FLAG_1 (LABEL_DECL_CHECK (NODE))

/* True if NODE was declared with auto in its return type, but it has
   started compilation and so the return type might have been changed by
   return type deduction; its declared return type should be found in
   DECL_STRUCT_FUNCTION(NODE)->language->x_auto_return_pattern.  */
#define FNDECL_USED_AUTO(NODE) \
  TREE_LANG_FLAG_2 (FUNCTION_DECL_CHECK (NODE))

/* Nonzero if NODE is a DECL which we know about but which has not
   been explicitly declared, such as a built-in function or a friend
   declared inside a class.  In the latter case DECL_HIDDEN_FRIEND_P
   will be set.  */
#define DECL_ANTICIPATED(NODE) \
  (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \
   ->u.base.anticipated_p)

/* True for artificial decls added for OpenMP privatized non-static
   data members.  */
#define DECL_OMP_PRIVATIZED_MEMBER(NODE) \
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.anticipated_p)

/* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend
   within a class but has not been declared in the surrounding scope.
   The function is invisible except via argument dependent lookup.  */
#define DECL_HIDDEN_FRIEND_P(NODE) \
  (LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)

/* Nonzero if NODE is an artificial FUNCTION_DECL for
   #pragma omp declare reduction.  */
#define DECL_OMP_DECLARE_REDUCTION_P(NODE) \
  (LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->omp_declare_reduction_p)

/* Nonzero if DECL has been declared threadprivate by
   #pragma omp threadprivate.  */
#define CP_DECL_THREADPRIVATE_P(DECL) \
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p)

/* Nonzero if NODE is a VAR_DECL which has been declared inline.  */
#define DECL_VAR_DECLARED_INLINE_P(NODE) \
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))			\
   ? DECL_LANG_SPECIFIC (NODE)->u.base.var_declared_inline_p	\
   : false)
#define SET_DECL_VAR_DECLARED_INLINE_P(NODE) \
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.var_declared_inline_p \
   = true)

/* Nonzero if NODE is an artificial VAR_DECL for a C++17 decomposition
   declaration.  */
#define DECL_DECOMPOSITION_P(NODE) \
  (VAR_P (NODE) && DECL_LANG_SPECIFIC (NODE)			\
   ? DECL_LANG_SPECIFIC (NODE)->u.base.decomposition_p		\
   : false)
#define SET_DECL_DECOMPOSITION_P(NODE) \
  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.decomposition_p \
   = true)

/* Nonzero if NODE is an inline VAR_DECL.  In C++17, static data members
   declared with constexpr specifier are implicitly inline variables.  */
#define DECL_INLINE_VAR_P(NODE) \
  (DECL_VAR_DECLARED_INLINE_P (NODE)				\
   || (cxx_dialect >= cxx1z					\
       && DECL_DECLARED_CONSTEXPR_P (NODE)			\
       && DECL_CLASS_SCOPE_P (NODE)))

/* Nonzero if DECL was declared with '= delete'.  */
#define DECL_DELETED_FN(DECL) \
  (LANG_DECL_FN_CHECK (DECL)->min.base.threadprivate_or_deleted_p)

/* Nonzero if DECL was declared with '= default' (maybe implicitly).  */
#define DECL_DEFAULTED_FN(DECL) \
  (LANG_DECL_FN_CHECK (DECL)->defaulted_p)

/* Nonzero if DECL is explicitly defaulted in the class body.  */
#define DECL_DEFAULTED_IN_CLASS_P(DECL)					\
  (DECL_DEFAULTED_FN (DECL) && DECL_INITIALIZED_IN_CLASS_P (DECL))
/* Nonzero if DECL was defaulted outside the class body.  */
#define DECL_DEFAULTED_OUTSIDE_CLASS_P(DECL)				\
  (DECL_DEFAULTED_FN (DECL)						\
   && !(DECL_ARTIFICIAL (DECL) || DECL_INITIALIZED_IN_CLASS_P (DECL)))

/* Record whether a typedef for type `int' was actually `signed int'.  */
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)

/* Returns nonzero if DECL has external linkage, as specified by the
   language standard.  (This predicate may hold even when the
   corresponding entity is not actually given external linkage in the
   object file; see decl_linkage for details.)  */
#define DECL_EXTERNAL_LINKAGE_P(DECL) \
  (decl_linkage (DECL) == lk_external)

/* Keep these codes in ascending code order.  */

#define INTEGRAL_CODE_P(CODE)	\
  ((CODE) == ENUMERAL_TYPE	\
   || (CODE) == BOOLEAN_TYPE	\
   || (CODE) == INTEGER_TYPE)

/* [basic.fundamental]

   Types  bool, char, wchar_t, and the signed and unsigned integer types
   are collectively called integral types.

   Note that INTEGRAL_TYPE_P, as defined in tree.h, allows enumeration
   types as well, which is incorrect in C++.  Keep these checks in
   ascending code order.  */
#define CP_INTEGRAL_TYPE_P(TYPE)		\
  (TREE_CODE (TYPE) == BOOLEAN_TYPE		\
   || TREE_CODE (TYPE) == INTEGER_TYPE)

/* Returns true if TYPE is an integral or enumeration name.  Keep
   these checks in ascending code order.  */
#define INTEGRAL_OR_ENUMERATION_TYPE_P(TYPE) \
   (TREE_CODE (TYPE) == ENUMERAL_TYPE || CP_INTEGRAL_TYPE_P (TYPE))

/* Returns true if TYPE is an integral or unscoped enumeration type.  */
#define INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P(TYPE) \
   (UNSCOPED_ENUM_P (TYPE) || CP_INTEGRAL_TYPE_P (TYPE))

/* True if the class type TYPE is a literal type.  */
#define CLASSTYPE_LITERAL_P(TYPE)              \
   (LANG_TYPE_CLASS_CHECK (TYPE)->is_literal)

/* [basic.fundamental]

   Integral and floating types are collectively called arithmetic
   types.  

   As a GNU extension, we also accept complex types.

   Keep these checks in ascending code order.  */
#define ARITHMETIC_TYPE_P(TYPE) \
  (CP_INTEGRAL_TYPE_P (TYPE) \
   || TREE_CODE (TYPE) == REAL_TYPE \
   || TREE_CODE (TYPE) == COMPLEX_TYPE)

/* True iff TYPE is cv decltype(nullptr).  */
#define NULLPTR_TYPE_P(TYPE) (TREE_CODE (TYPE) == NULLPTR_TYPE)

/* [basic.types]

   Arithmetic types, enumeration types, pointer types,
   pointer-to-member types, and std::nullptr_t are collectively called
   scalar types.
   
   Keep these checks in ascending code order.  */
#define SCALAR_TYPE_P(TYPE)			\
  (TYPE_PTRDATAMEM_P (TYPE)			\
   || TREE_CODE (TYPE) == ENUMERAL_TYPE		\
   || ARITHMETIC_TYPE_P (TYPE)			\
   || TYPE_PTR_P (TYPE)				\
   || TYPE_PTRMEMFUNC_P (TYPE)                  \
   || NULLPTR_TYPE_P (TYPE))

/* Determines whether this type is a C++0x scoped enumeration
   type. Scoped enumerations types are introduced via "enum class" or
   "enum struct", e.g.,

     enum class Color {
       Red, Green, Blue
     };

   Scoped enumeration types are different from normal (unscoped)
   enumeration types in several ways:
   
     - The enumerators of a scoped enumeration type are only available
       within the scope of the enumeration type and not in the
       enclosing scope. For example, the Red color can be referred to
       with "Color::Red" but not "Red".

     - Scoped enumerators and enumerations do not implicitly convert
       to integers or 'bool'.

     - The underlying type of the enum is well-defined.  */
#define SCOPED_ENUM_P(TYPE)                                             \
  (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_SCOPED (TYPE))

/* Determine whether this is an unscoped enumeration type.  */
#define UNSCOPED_ENUM_P(TYPE)                                           \
  (TREE_CODE (TYPE) == ENUMERAL_TYPE && !ENUM_IS_SCOPED (TYPE))

/* Set the flag indicating whether an ENUMERAL_TYPE is a C++0x scoped
   enumeration type (1) or a normal (unscoped) enumeration type
   (0).  */
#define SET_SCOPED_ENUM_P(TYPE, VAL)                    \
  (ENUM_IS_SCOPED (TYPE) = (VAL))

#define SET_OPAQUE_ENUM_P(TYPE, VAL)                    \
  (ENUM_IS_OPAQUE (TYPE) = (VAL))

#define OPAQUE_ENUM_P(TYPE)				\
  (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_OPAQUE (TYPE))

/* Determines whether an ENUMERAL_TYPE has an explicit
   underlying type.  */
#define ENUM_FIXED_UNDERLYING_TYPE_P(NODE) (TYPE_LANG_FLAG_5 (NODE))

/* Returns the underlying type of the given enumeration type. The
   underlying type is determined in different ways, depending on the
   properties of the enum:

     - In C++0x, the underlying type can be explicitly specified, e.g.,

         enum E1 : char { ... } // underlying type is char

     - In a C++0x scoped enumeration, the underlying type is int
       unless otherwises specified:

         enum class E2 { ... } // underlying type is int

     - Otherwise, the underlying type is determined based on the
       values of the enumerators. In this case, the
       ENUM_UNDERLYING_TYPE will not be set until after the definition
       of the enumeration is completed by finish_enum.  */
#define ENUM_UNDERLYING_TYPE(TYPE) \
  TREE_TYPE (ENUMERAL_TYPE_CHECK (TYPE))

/* [dcl.init.aggr]

   An aggregate is an array or a class with no user-provided
   constructors, no brace-or-equal-initializers for non-static data
   members, no private or protected non-static data members, no
   base classes, and no virtual functions.

   As an extension, we also treat vectors as aggregates.  Keep these
   checks in ascending code order.  */
#define CP_AGGREGATE_TYPE_P(TYPE)				\
  (TREE_CODE (TYPE) == VECTOR_TYPE				\
   ||TREE_CODE (TYPE) == ARRAY_TYPE				\
   || (CLASS_TYPE_P (TYPE) && !CLASSTYPE_NON_AGGREGATE (TYPE)))

/* Nonzero for a class type means that the class type has a
   user-declared constructor.  */
#define TYPE_HAS_USER_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE))

/* Nonzero means that the FUNCTION_TYPE or METHOD_TYPE has a
   late-specified return type.  */
#define TYPE_HAS_LATE_RETURN_TYPE(NODE) \
  (TYPE_LANG_FLAG_2 (FUNC_OR_METHOD_CHECK (NODE)))

/* When appearing in an INDIRECT_REF, it means that the tree structure
   underneath is actually a call to a constructor.  This is needed
   when the constructor must initialize local storage (which can
   be automatically destroyed), rather than allowing it to allocate
   space from the heap.

   When appearing in a SAVE_EXPR, it means that underneath
   is a call to a constructor.

   When appearing in a CONSTRUCTOR, the expression is a
   compound literal.

   When appearing in a FIELD_DECL, it means that this field
   has been duly initialized in its constructor.  */
#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE))

/* True if NODE is a brace-enclosed initializer.  */
#define BRACE_ENCLOSED_INITIALIZER_P(NODE) \
  (TREE_CODE (NODE) == CONSTRUCTOR && TREE_TYPE (NODE) == init_list_type_node)

/* True if NODE is a compound-literal, i.e., a brace-enclosed
   initializer cast to a particular type.  */
#define COMPOUND_LITERAL_P(NODE) \
  (TREE_CODE (NODE) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (NODE))

#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
				   && vec_safe_is_empty(CONSTRUCTOR_ELTS(NODE))\
				   && !TREE_HAS_CONSTRUCTOR (NODE))

/* True if NODE is a init-list used as a direct-initializer, i.e.
   B b{1,2}, not B b({1,2}) or B b = {1,2}.  */
#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE)))

/* True if an uninitialized element in NODE should not be treated as
   implicitly value-initialized.  Only used in constexpr evaluation.  */
#define CONSTRUCTOR_NO_IMPLICIT_ZERO(NODE) \
  (TREE_LANG_FLAG_1 (CONSTRUCTOR_CHECK (NODE)))

/* True if this CONSTRUCTOR should not be used as a variable initializer
   because it was loaded from a constexpr variable with mutable fields.  */
#define CONSTRUCTOR_MUTABLE_POISON(NODE) \
  (TREE_LANG_FLAG_2 (CONSTRUCTOR_CHECK (NODE)))

#define DIRECT_LIST_INIT_P(NODE) \
   (BRACE_ENCLOSED_INITIALIZER_P (NODE) && CONSTRUCTOR_IS_DIRECT_INIT (NODE))

/* True if NODE represents a conversion for direct-initialization in a
   template.  Set by perform_implicit_conversion_flags.  */
#define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \
  (TREE_LANG_FLAG_0 (IMPLICIT_CONV_EXPR_CHECK (NODE)))

/* Nonzero means that an object of this type can not be initialized using
   an initializer list.  */
#define CLASSTYPE_NON_AGGREGATE(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate)
#define TYPE_NON_AGGREGATE_CLASS(NODE) \
  (CLASS_TYPE_P (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))

/* Nonzero if there is a non-trivial X::op=(cv X&) for this class.  */
#define TYPE_HAS_COMPLEX_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_assign)

/* Nonzero if there is a non-trivial X::X(cv X&) for this class.  */
#define TYPE_HAS_COMPLEX_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_ctor)

/* Nonzero if there is a non-trivial X::op=(X&&) for this class.  */
#define TYPE_HAS_COMPLEX_MOVE_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_assign)

/* Nonzero if there is a non-trivial X::X(X&&) for this class.  */
#define TYPE_HAS_COMPLEX_MOVE_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_ctor)

/* Nonzero if there is no trivial default constructor for this class.  */
#define TYPE_HAS_COMPLEX_DFLT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt)

/* Nonzero if TYPE has a trivial destructor.  From [class.dtor]:

     A destructor is trivial if it is an implicitly declared
     destructor and if:

       - all of the direct base classes of its class have trivial
	 destructors,

       - for all of the non-static data members of its class that are
	 of class type (or array thereof), each such class has a
	 trivial destructor.  */
#define TYPE_HAS_TRIVIAL_DESTRUCTOR(NODE) \
  (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (NODE))

/* Nonzero for _TYPE node means that this type does not have a trivial
   destructor.  Therefore, destroying an object of this type will
   involve a call to a destructor.  This can apply to objects of
   ARRAY_TYPE is the type of the elements needs a destructor.  */
#define TYPE_HAS_NONTRIVIAL_DESTRUCTOR(NODE) \
  (TYPE_LANG_FLAG_4 (NODE))

/* Nonzero for class type means that the default constructor is trivial.  */
#define TYPE_HAS_TRIVIAL_DFLT(NODE) \
  (TYPE_HAS_DEFAULT_CONSTRUCTOR (NODE) && ! TYPE_HAS_COMPLEX_DFLT (NODE))

/* Nonzero for class type means that copy initialization of this type can use
   a bitwise copy.  */
#define TYPE_HAS_TRIVIAL_COPY_CTOR(NODE) \
  (TYPE_HAS_COPY_CTOR (NODE) && ! TYPE_HAS_COMPLEX_COPY_CTOR (NODE))

/* Nonzero for class type means that assignment of this type can use
   a bitwise copy.  */
#define TYPE_HAS_TRIVIAL_COPY_ASSIGN(NODE) \
  (TYPE_HAS_COPY_ASSIGN (NODE) && ! TYPE_HAS_COMPLEX_COPY_ASSIGN (NODE))

/* Returns true if NODE is a pointer-to-data-member.  */
#define TYPE_PTRDATAMEM_P(NODE)			\
  (TREE_CODE (NODE) == OFFSET_TYPE)
/* Returns true if NODE is a pointer.  */
#define TYPE_PTR_P(NODE)			\
  (TREE_CODE (NODE) == POINTER_TYPE)

/* Returns true if NODE is an object type:

     [basic.types]

     An object type is a (possibly cv-qualified) type that is not a
     function type, not a reference type, and not a void type.

   Keep these checks in ascending order, for speed.  */
#define TYPE_OBJ_P(NODE)			\
  (TREE_CODE (NODE) != REFERENCE_TYPE		\
   && !VOID_TYPE_P (NODE)  		        \
   && TREE_CODE (NODE) != FUNCTION_TYPE		\
   && TREE_CODE (NODE) != METHOD_TYPE)

/* Returns true if NODE is a pointer to an object.  Keep these checks
   in ascending tree code order.  */
#define TYPE_PTROB_P(NODE)					\
  (TYPE_PTR_P (NODE) && TYPE_OBJ_P (TREE_TYPE (NODE)))

/* Returns true if NODE is a reference to an object.  Keep these checks
   in ascending tree code order.  */
#define TYPE_REF_OBJ_P(NODE)					\
  (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE)))

/* Returns true if NODE is a pointer to an object, or a pointer to
   void.  Keep these checks in ascending tree code order.  */
#define TYPE_PTROBV_P(NODE)					\
  (TYPE_PTR_P (NODE)						\
   && !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE		\
	|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))

/* Returns true if NODE is a pointer to function type.  */
#define TYPE_PTRFN_P(NODE)				\
  (TYPE_PTR_P (NODE)			                \
   && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)

/* Returns true if NODE is a reference to function type.  */
#define TYPE_REFFN_P(NODE)				\
  (TREE_CODE (NODE) == REFERENCE_TYPE			\
   && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)

/* Returns true if NODE is a pointer to member function type.  */
#define TYPE_PTRMEMFUNC_P(NODE)		\
  (TREE_CODE (NODE) == RECORD_TYPE	\
   && TYPE_PTRMEMFUNC_FLAG (NODE))

#define TYPE_PTRMEMFUNC_FLAG(NODE) \
  (TYPE_LANG_FLAG_2 (RECORD_TYPE_CHECK (NODE)))

/* Returns true if NODE is a pointer-to-member.  */
#define TYPE_PTRMEM_P(NODE) \
  (TYPE_PTRDATAMEM_P (NODE) || TYPE_PTRMEMFUNC_P (NODE))

/* Returns true if NODE is a pointer or a pointer-to-member.  */
#define TYPE_PTR_OR_PTRMEM_P(NODE) \
  (TYPE_PTR_P (NODE) || TYPE_PTRMEM_P (NODE))

/* Indicates when overload resolution may resolve to a pointer to
   member function. [expr.unary.op]/3 */
#define PTRMEM_OK_P(NODE) \
  TREE_LANG_FLAG_0 (TREE_CHECK3 ((NODE), ADDR_EXPR, OFFSET_REF, SCOPE_REF))

/* Get the POINTER_TYPE to the METHOD_TYPE associated with this
   pointer to member function.  TYPE_PTRMEMFUNC_P _must_ be true,
   before using this macro.  */
#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) \
  (cp_build_qualified_type (TREE_TYPE (TYPE_FIELDS (NODE)),\
			    cp_type_quals (NODE)))

/* As above, but can be used in places that want an lvalue at the expense
   of not necessarily having the correct cv-qualifiers.  */
#define TYPE_PTRMEMFUNC_FN_TYPE_RAW(NODE) \
  (TREE_TYPE (TYPE_FIELDS (NODE)))

/* Returns `A' for a type like `int (A::*)(double)' */
#define TYPE_PTRMEMFUNC_OBJECT_TYPE(NODE) \
  TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE)))

/* These are use to manipulate the canonical RECORD_TYPE from the
   hashed POINTER_TYPE, and can only be used on the POINTER_TYPE.  */
#define TYPE_GET_PTRMEMFUNC_TYPE(NODE) \
  (TYPE_LANG_SPECIFIC (NODE) ? LANG_TYPE_PTRMEM_CHECK (NODE)->record : NULL)
#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE)				\
  do {									\
    if (TYPE_LANG_SPECIFIC (NODE) == NULL)				\
      {									\
	TYPE_LANG_SPECIFIC (NODE)                                       \
	= (struct lang_type *) ggc_internal_cleared_alloc		\
	 (sizeof (struct lang_type_ptrmem));				\
	TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0;	\
      }									\
    TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE);		\
  } while (0)

/* For a pointer-to-member type of the form `T X::*', this is `X'.
   For a type like `void (X::*)() const', this type is `X', not `const
   X'.  To get at the `const X' you have to look at the
   TYPE_PTRMEM_POINTED_TO_TYPE; there, the first parameter will have
   type `const X*'.  */
#define TYPE_PTRMEM_CLASS_TYPE(NODE)			\
  (TYPE_PTRDATAMEM_P (NODE)					\
   ? TYPE_OFFSET_BASETYPE (NODE)		\
   : TYPE_PTRMEMFUNC_OBJECT_TYPE (NODE))

/* For a pointer-to-member type of the form `T X::*', this is `T'.  */
#define TYPE_PTRMEM_POINTED_TO_TYPE(NODE)		\
   (TYPE_PTRDATAMEM_P (NODE)				\
    ? TREE_TYPE (NODE)					\
    : TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE)))

/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for
   `X'.  */
#define PTRMEM_CST_CLASS(NODE) \
  TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (PTRMEM_CST_CHECK (NODE)))

/* For a pointer-to-member constant `X::Y' this is the _DECL for
   `Y'.  */
#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t)PTRMEM_CST_CHECK (NODE))->member)

/* The expression in question for a TYPEOF_TYPE.  */
#define TYPEOF_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (TYPEOF_TYPE_CHECK (NODE)))

/* The type in question for an UNDERLYING_TYPE.  */
#define UNDERLYING_TYPE_TYPE(NODE) \
  (TYPE_VALUES_RAW (UNDERLYING_TYPE_CHECK (NODE)))

/* The type in question for BASES.  */
#define BASES_TYPE(NODE) \
  (TYPE_VALUES_RAW (BASES_CHECK (NODE)))

#define BASES_DIRECT(NODE) \
  TREE_LANG_FLAG_0 (BASES_CHECK (NODE))

/* The expression in question for a DECLTYPE_TYPE.  */
#define DECLTYPE_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (DECLTYPE_TYPE_CHECK (NODE)))

/* Whether the DECLTYPE_TYPE_EXPR of NODE was originally parsed as an
   id-expression or a member-access expression. When false, it was
   parsed as a full expression.  */
#define DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P(NODE) \
  (DECLTYPE_TYPE_CHECK (NODE))->type_common.string_flag

/* These flags indicate that we want different semantics from normal
   decltype: lambda capture just drops references, init capture
   uses auto semantics, lambda proxies look through implicit dereference.  */
#define DECLTYPE_FOR_LAMBDA_CAPTURE(NODE) \
  TREE_LANG_FLAG_0 (DECLTYPE_TYPE_CHECK (NODE))
#define DECLTYPE_FOR_INIT_CAPTURE(NODE) \
  TREE_LANG_FLAG_1 (DECLTYPE_TYPE_CHECK (NODE))
#define DECLTYPE_FOR_LAMBDA_PROXY(NODE) \
  TREE_LANG_FLAG_2 (DECLTYPE_TYPE_CHECK (NODE))
#define DECLTYPE_FOR_REF_CAPTURE(NODE) \
  TREE_LANG_FLAG_3 (DECLTYPE_TYPE_CHECK (NODE))

/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was
   specified in its declaration.  This can also be set for an
   erroneously declared PARM_DECL.  */
#define DECL_THIS_EXTERN(NODE) \
  DECL_LANG_FLAG_2 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE))

/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was
   specified in its declaration.  This can also be set for an
   erroneously declared PARM_DECL.  */
#define DECL_THIS_STATIC(NODE) \
  DECL_LANG_FLAG_6 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE))

/* Nonzero for FIELD_DECL node means that this field is a lambda capture
   field for an array of runtime bound.  */
#define DECL_VLA_CAPTURE_P(NODE) \
  DECL_LANG_FLAG_1 (FIELD_DECL_CHECK (NODE))

/* Nonzero for PARM_DECL node means that this is an array function
   parameter, i.e, a[] rather than *a.  */
#define DECL_ARRAY_PARAMETER_P(NODE) \
  DECL_LANG_FLAG_1 (PARM_DECL_CHECK (NODE))

/* Nonzero for a FIELD_DECL who's NSMDI is currently being
   instantiated.  */
#define DECL_INSTANTIATING_NSDMI_P(NODE) \
  DECL_LANG_FLAG_2 (FIELD_DECL_CHECK (NODE))

/* Nonzero for FIELD_DECL node means that this field is a base class
   of the parent object, as opposed to a member field.  */
#define DECL_FIELD_IS_BASE(NODE) \
  DECL_LANG_FLAG_6 (FIELD_DECL_CHECK (NODE))

/* Nonzero for FIELD_DECL node means that this field is a simple (no
   explicit initializer) lambda capture field, making it invisible to
   name lookup in unevaluated contexts.  */
#define DECL_NORMAL_CAPTURE_P(NODE) \
  DECL_LANG_FLAG_7 (FIELD_DECL_CHECK (NODE))

/* Nonzero if TYPE is an anonymous union or struct type.  We have to use a
   flag for this because "A union for which objects or pointers are
   declared is not an anonymous union" [class.union].  */
#define ANON_AGGR_TYPE_P(NODE)				\
  (CLASS_TYPE_P (NODE) && LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr)
#define SET_ANON_AGGR_TYPE_P(NODE)			\
  (LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr = 1)

/* Nonzero if TYPE is an anonymous union type.  */
#define ANON_UNION_TYPE_P(NODE) \
  (TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE))

/* Define fields and accessors for nodes representing declared names.  */

/* Nonzero if TYPE is an unnamed class with a typedef for linkage purposes.  */
#define TYPE_WAS_UNNAMED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->was_anonymous)

/* C++: all of these are overloaded!  These apply only to TYPE_DECLs.  */

/* The format of each node in the DECL_FRIENDLIST is as follows:

   The TREE_PURPOSE will be the name of a function, i.e., an
   IDENTIFIER_NODE.  The TREE_VALUE will be itself a TREE_LIST, whose
   TREE_VALUEs are friends with the given name.  */
#define DECL_FRIENDLIST(NODE)		(DECL_INITIAL (NODE))
#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST))
#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))

/* The DECL_ACCESS, if non-NULL, is a TREE_LIST.  The TREE_PURPOSE of
   each node is a type; the TREE_VALUE is the access granted for this
   DECL in that type.  The DECL_ACCESS is set by access declarations.
   For example, if a member that would normally be public in a
   derived class is made protected, then the derived class and the
   protected_access_node will appear in the DECL_ACCESS for the node.  */
#define DECL_ACCESS(NODE) (LANG_DECL_U2_CHECK (NODE, 0)->access)

/* Nonzero if the FUNCTION_DECL is a global constructor.  */
#define DECL_GLOBAL_CTOR_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->global_ctor_p)

/* Nonzero if the FUNCTION_DECL is a global destructor.  */
#define DECL_GLOBAL_DTOR_P(NODE) \
  (LANG_DECL_FN_CHECK (NODE)->global_dtor_p)

/* Accessor macros for C++ template decl nodes.  */

/* The DECL_TEMPLATE_PARMS are a list.  The TREE_PURPOSE of each node
   is a INT_CST whose TREE_INT_CST_LOW indicates the level of the
   template parameters, with 1 being the outermost set of template
   parameters.  The TREE_VALUE is a vector, whose elements are the
   template parameters at each level.  Each element in the vector is a
   TREE_LIST, whose TREE_VALUE is a PARM_DECL (if the parameter is a
   non-type parameter), or a TYPE_DECL (if the parameter is a type
   parameter).  The TREE_PURPOSE is the default value, if any.  The
   TEMPLATE_PARM_INDEX for the parameter is available as the
   DECL_INITIAL (for a PARM_DECL) or as the TREE_TYPE (for a
   TYPE_DECL). 

   FIXME: CONST_CAST_TREE is a hack that hopefully will go away after
   tree is converted to C++ class hiearchy.  */
#define DECL_TEMPLATE_PARMS(NODE)       \
   ((struct tree_template_decl *)CONST_CAST_TREE (TEMPLATE_DECL_CHECK (NODE)))->arguments
#define DECL_INNERMOST_TEMPLATE_PARMS(NODE) \
   INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (NODE))
#define DECL_NTPARMS(NODE) \
   TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE))
/* For function, method, class-data templates.

   FIXME: CONST_CAST_TREE is a hack that hopefully will go away after
   tree is converted to C++ class hiearchy.  */
#define DECL_TEMPLATE_RESULT(NODE)      \
   ((struct tree_template_decl *)CONST_CAST_TREE(TEMPLATE_DECL_CHECK (NODE)))->result
/* For a function template at namespace scope, DECL_TEMPLATE_INSTANTIATIONS
   lists all instantiations and specializations of the function so that
   tsubst_friend_function can reassign them to another template if we find
   that the namespace-scope template is really a partial instantiation of a
   friend template.

   For a class template the DECL_TEMPLATE_INSTANTIATIONS lists holds
   all instantiations and specializations of the class type, including
   partial instantiations and partial specializations, so that if we
   explicitly specialize a partial instantiation we can walk the list
   in maybe_process_partial_specialization and reassign them or complain
   as appropriate.

   In both cases, the TREE_PURPOSE of each node contains the arguments
   used; the TREE_VALUE contains the generated variable.  The template
   arguments are always complete.  For example, given:

      template <class T> struct S1 {
	template <class U> struct S2 {};
	template <class U> struct S2<U*> {};
      };

   the record for the partial specialization will contain, as its
   argument list, { {T}, {U*} }, and will be on the
   DECL_TEMPLATE_INSTANTIATIONS list for `template <class T> template
   <class U> struct S1<T>::S2'.

   This list is not used for other templates.  */
#define DECL_TEMPLATE_INSTANTIATIONS(NODE) \
  DECL_SIZE_UNIT (TEMPLATE_DECL_CHECK (NODE))

/* For a class template, this list contains the partial
   specializations of this template.  (Full specializations are not
   recorded on this list.)  The TREE_PURPOSE holds the arguments used
   in the partial specialization (e.g., for `template <class T> struct
   S<T*, int>' this will be `T*, int'.)  The arguments will also include
   any outer template arguments.  The TREE_VALUE holds the TEMPLATE_DECL
   for the partial specialization.  The TREE_TYPE is the _TYPE node for
   the partial specialization.

   This list is not used for other templates.  */
#define DECL_TEMPLATE_SPECIALIZATIONS(NODE)     \
  DECL_SIZE (TEMPLATE_DECL_CHECK (NODE))

/* Nonzero for a DECL which is actually a template parameter.  Keep
   these checks in ascending tree code order.   */
#define DECL_TEMPLATE_PARM_P(NODE)		\
  (DECL_LANG_FLAG_0 (NODE)			\
   && (TREE_CODE (NODE) == CONST_DECL		\
       || TREE_CODE (NODE) == PARM_DECL		\
       || TREE_CODE (NODE) == TYPE_DECL		\
       || TREE_CODE (NODE) == TEMPLATE_DECL))

/* Mark NODE as a template parameter.  */
#define SET_DECL_TEMPLATE_PARM_P(NODE) \
  (DECL_LANG_FLAG_0 (NODE) = 1)

/* Nonzero if NODE is a template template parameter.  */
#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
  (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))

/* Nonzero for a DECL that represents a function template.  */
#define DECL_FUNCTION_TEMPLATE_P(NODE)                          \
  (TREE_CODE (NODE) == TEMPLATE_DECL                            \
   && DECL_TEMPLATE_RESULT (NODE) != NULL_TREE			\
   && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)

/* Nonzero for a DECL that represents a class template or alias
   template.  */
#define DECL_TYPE_TEMPLATE_P(NODE)				\
  (TREE_CODE (NODE) == TEMPLATE_DECL				\
   && DECL_TEMPLATE_RESULT (NODE) != NULL_TREE			\
   && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL)

/* Nonzero for a DECL that represents a class template.  */
#define DECL_CLASS_TEMPLATE_P(NODE)				\
  (DECL_TYPE_TEMPLATE_P (NODE)					\
   && DECL_IMPLICIT_TYPEDEF_P (DECL_TEMPLATE_RESULT (NODE)))

/* Nonzero for a TEMPLATE_DECL that represents an alias template.  */
#define DECL_ALIAS_TEMPLATE_P(NODE)			\
  (DECL_TYPE_TEMPLATE_P (NODE)				\
   && !DECL_ARTIFICIAL (DECL_TEMPLATE_RESULT (NODE)))

/* Nonzero for a NODE which declares a type.  */
#define DECL_DECLARES_TYPE_P(NODE) \
  (TREE_CODE (NODE) == TYPE_DECL || DECL_TYPE_TEMPLATE_P (NODE))

/* Nonzero if NODE declares a function.  */
#define DECL_DECLARES_FUNCTION_P(NODE) \
  (TREE_CODE (NODE) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (NODE))

/* Nonzero if NODE is the typedef implicitly generated for a type when
   the type is declared.  In C++, `struct S {};' is roughly
   equivalent to `struct S {}; typedef struct S S;' in C.
   DECL_IMPLICIT_TYPEDEF_P will hold for the typedef indicated in this
   example.  In C++, there is a second implicit typedef for each
   class, called the injected-class-name, in the scope of `S' itself, so that
   you can say `S::S'.  DECL_SELF_REFERENCE_P will hold for that typedef.  */
#define DECL_IMPLICIT_TYPEDEF_P(NODE) \
  (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_2 (NODE))
#define SET_DECL_IMPLICIT_TYPEDEF_P(NODE) \
  (DECL_LANG_FLAG_2 (NODE) = 1)
#define DECL_SELF_REFERENCE_P(NODE) \
  (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_4 (NODE))
#define SET_DECL_SELF_REFERENCE_P(NODE) \
  (DECL_LANG_FLAG_4 (NODE) = 1)

/* A `primary' template is one that has its own template header and is not
   a partial specialization.  A member function of a class template is a
   template, but not primary.  A member template is primary.  Friend
   templates are primary, too.  */

/* Returns the primary template corresponding to these parameters.  */
#define DECL_PRIMARY_TEMPLATE(NODE) \
  (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE)))

/* Returns nonzero if NODE is a primary template.  */
#define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE))

/* Nonzero iff NODE is a specialization of a template.  The value
   indicates the type of specializations:

     1=implicit instantiation

     2=partial or explicit specialization, e.g.:

        template <> int min<int> (int, int),

     3=explicit instantiation, e.g.:
  
        template int min<int> (int, int);

   Note that NODE will be marked as a specialization even if the
   template it is instantiating is not a primary template.  For
   example, given:

     template <typename T> struct O { 
       void f();
       struct I {}; 
     };
    
   both O<int>::f and O<int>::I will be marked as instantiations.

   If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also
   be non-NULL.  */
#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.use_template)

/* Like DECL_USE_TEMPLATE, but for class types.  */
#define CLASSTYPE_USE_TEMPLATE(NODE) \
  (LANG_TYPE_CLASS_CHECK (NODE)->use_template)

/* True if NODE is a specialization of a primary template.  */
#define CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P(NODE)	\
  (CLASS_TYPE_P (NODE)						\
   && CLASSTYPE_USE_TEMPLATE (NODE)				\
   && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))

#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
  (CLASSTYPE_USE_TEMPLATE (NODE) & 1)

#define DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) == 2)
#define SET_DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) = 2)

/* Returns true for an explicit or partial specialization of a class
   template.  */
#define CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \
  (CLASSTYPE_USE_TEMPLATE (NODE) == 2)
#define SET_CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \
  (CLASSTYPE_USE_TEMPLATE (NODE) = 2)

#define DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 1)
#define SET_DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 1)
#define CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \
  (CLASSTYPE_USE_TEMPLATE (NODE) == 1)
#define SET_CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \
  (CLASSTYPE_USE_TEMPLATE (NODE) = 1)

#define DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 3)
#define SET_DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 3)
#define CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
  (CLASSTYPE_USE_TEMPLATE (NODE) == 3)
#define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
  (CLASSTYPE_USE_TEMPLATE (NODE) = 3)

/* Nonzero if DECL is a friend function which is an instantiation
   from the point of view of the compiler, but not from the point of
   view of the language.  For example given:
      template <class T> struct S { friend void f(T) {}; };
   the declaration of `void f(int)' generated when S<int> is
   instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be
   a DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION.  */
#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
  (DECL_LANG_SPECIFIC (DECL) && DECL_TEMPLATE_INFO (DECL) \
   && !DECL_USE_TEMPLATE (DECL))

/* Nonzero if DECL is a function generated from a function 'temploid',
   i.e. template, member of class template, or dependent friend.  */
#define DECL_TEMPLOID_INSTANTIATION(DECL)		\
  (DECL_TEMPLATE_INSTANTIATION (DECL)			\
   || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (DECL))

/* Nonzero if DECL is either defined implicitly by the compiler or
   generated from a temploid.  */
#define DECL_GENERATED_P(DECL) \
  (DECL_TEMPLOID_INSTANTIATION (DECL) || DECL_DEFAULTED_FN (DECL))

/* Nonzero iff we are currently processing a declaration for an
   entity with its own template parameter list, and which is not a
   full specialization.  */
#define PROCESSING_REAL_TEMPLATE_DECL_P() \
  (processing_template_decl > template_class_depth (current_scope ()))

/* Nonzero if this VAR_DECL or FUNCTION_DECL has already been
   instantiated, i.e. its definition has been generated from the
   pattern given in the template.  */
#define DECL_TEMPLATE_INSTANTIATED(NODE) \
  DECL_LANG_FLAG_1 (VAR_OR_FUNCTION_DECL_CHECK (NODE))

/* We know what we're doing with this decl now.  */
#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)

/* DECL_EXTERNAL must be set on a decl until the decl is actually emitted,
   so that assemble_external will work properly.  So we have this flag to
   tell us whether the decl is really not external.

   This flag does not indicate whether or not the decl is defined in the
   current translation unit; it indicates whether or not we should emit the
   decl at the end of compilation if it is defined and needed.  */
#define DECL_NOT_REALLY_EXTERN(NODE) \
  (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern)

#define DECL_REALLY_EXTERN(NODE) \
  (DECL_EXTERNAL (NODE)				\
   && (!DECL_LANG_SPECIFIC (NODE) || !DECL_NOT_REALLY_EXTERN (NODE)))

/* A thunk is a stub function.

   A thunk is an alternate entry point for an ordinary FUNCTION_DECL.
   The address of the ordinary FUNCTION_DECL is given by the
   DECL_INITIAL, which is always an ADDR_EXPR whose operand is a
   FUNCTION_DECL.  The job of the thunk is to either adjust the this
   pointer before transferring control to the FUNCTION_DECL, or call
   FUNCTION_DECL and then adjust the result value. Note, the result
   pointer adjusting thunk must perform a call to the thunked
   function, (or be implemented via passing some invisible parameter
   to the thunked function, which is modified to perform the
   adjustment just before returning).

   A thunk may perform either, or both, of the following operations:

   o Adjust the this or result pointer by a constant offset.
   o Adjust the this or result pointer by looking up a vcall or vbase offset
     in the vtable.

   A this pointer adjusting thunk converts from a base to a derived
   class, and hence adds the offsets. A result pointer adjusting thunk
   converts from a derived class to a base, and hence subtracts the
   offsets.  If both operations are performed, then the constant
   adjustment is performed first for this pointer adjustment and last
   for the result pointer adjustment.

   The constant adjustment is given by THUNK_FIXED_OFFSET.  If the
   vcall or vbase offset is required, THUNK_VIRTUAL_OFFSET is
   used. For this pointer adjusting thunks, it is the vcall offset
   into the vtable.  For result pointer adjusting thunks it is the
   binfo of the virtual base to convert to.  Use that binfo's vbase
   offset.

   It is possible to have equivalent covariant thunks.  These are
   distinct virtual covariant thunks whose vbase offsets happen to
   have the same value.  THUNK_ALIAS is used to pick one as the
   canonical thunk, which will get all the this pointer adjusting
   thunks attached to it.  */

/* An integer indicating how many bytes should be subtracted from the
   this or result pointer when this function is called.  */
#define THUNK_FIXED_OFFSET(DECL) \
  (DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.fn.u5.fixed_offset)

/* A tree indicating how to perform the virtual adjustment. For a this
   adjusting thunk it is the number of bytes to be added to the vtable
   to find the vcall offset. For a result adjusting thunk, it is the
   binfo of the relevant virtual base.  If NULL, then there is no
   virtual adjust.  (The vptr is always located at offset zero from
   the this or result pointer.)  (If the covariant type is within the
   class hierarchy being laid out, the vbase index is not yet known
   at the point we need to create the thunks, hence the need to use
   binfos.)  */

#define THUNK_VIRTUAL_OFFSET(DECL) \
  (LANG_DECL_U2_CHECK (FUNCTION_DECL_CHECK (DECL), 0)->access)

/* A thunk which is equivalent to another thunk.  */
#define THUNK_ALIAS(DECL) \
  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.min.template_info)

/* For thunk NODE, this is the FUNCTION_DECL thunked to.  It is
   possible for the target to be a thunk too.  */
#define THUNK_TARGET(NODE)				\
  (LANG_DECL_FN_CHECK (NODE)->befriending_classes)

/* True for a SCOPE_REF iff the "template" keyword was used to
   indicate that the qualified name denotes a template.  */
#define QUALIFIED_NAME_IS_TEMPLATE(NODE) \
  (TREE_LANG_FLAG_1 (SCOPE_REF_CHECK (NODE)))

/* True for an OMP_ATOMIC that has dependent parameters.  These are stored
   as an expr in operand 1, and integer_zero_node in operand 0.  */
#define OMP_ATOMIC_DEPENDENT_P(NODE) \
  (TREE_CODE (TREE_OPERAND (OMP_ATOMIC_CHECK (NODE), 0)) == INTEGER_CST)

/* Used while gimplifying continue statements bound to OMP_FOR nodes.  */
#define OMP_FOR_GIMPLIFYING_P(NODE) \
  (TREE_LANG_FLAG_0 (OMP_LOOP_CHECK (NODE)))

/* A language-specific token attached to the OpenMP data clauses to
   hold code (or code fragments) related to ctors, dtors, and op=.
   See semantics.c for details.  */
#define CP_OMP_CLAUSE_INFO(NODE) \
  TREE_TYPE (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_PRIVATE, \
				     OMP_CLAUSE_LINEAR))

/* Nonzero if this transaction expression's body contains statements.  */
#define TRANSACTION_EXPR_IS_STMT(NODE) \
   TREE_LANG_FLAG_0 (TRANSACTION_EXPR_CHECK (NODE))

/* These macros provide convenient access to the various _STMT nodes
   created when parsing template declarations.  */
#define TRY_STMTS(NODE)		TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 0)
#define TRY_HANDLERS(NODE)	TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 1)

#define EH_SPEC_STMTS(NODE)	TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 0)
#define EH_SPEC_RAISES(NODE)	TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 1)

#define USING_STMT_NAMESPACE(NODE) TREE_OPERAND (USING_STMT_CHECK (NODE), 0)

/* Nonzero if this try block is a function try block.  */
#define FN_TRY_BLOCK_P(NODE)	TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE))
#define HANDLER_PARMS(NODE)	TREE_OPERAND (HANDLER_CHECK (NODE), 0)
#define HANDLER_BODY(NODE)	TREE_OPERAND (HANDLER_CHECK (NODE), 1)
#define HANDLER_TYPE(NODE)	TREE_TYPE (HANDLER_CHECK (NODE))

/* CLEANUP_STMT accessors.  The statement(s) covered, the cleanup to run
   and the VAR_DECL for which this cleanup exists.  */
#define CLEANUP_BODY(NODE)	TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
#define CLEANUP_EXPR(NODE)	TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
#define CLEANUP_DECL(NODE)	TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 2)

/* IF_STMT accessors. These give access to the condition of the if
   statement, the then block of the if statement, and the else block
   of the if statement if it exists.  */
#define IF_COND(NODE)		TREE_OPERAND (IF_STMT_CHECK (NODE), 0)
#define THEN_CLAUSE(NODE)	TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
#define ELSE_CLAUSE(NODE)	TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
#define IF_SCOPE(NODE)		TREE_OPERAND (IF_STMT_CHECK (NODE), 3)
#define IF_STMT_CONSTEXPR_P(NODE) TREE_LANG_FLAG_0 (IF_STMT_CHECK (NODE))

/* WHILE_STMT accessors. These give access to the condition of the
   while statement and the body of the while statement, respectively.  */
#define WHILE_COND(NODE)	TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0)
#define WHILE_BODY(NODE)	TREE_OPERAND (WHILE_STMT_CHECK (NODE), 1)

/* DO_STMT accessors. These give access to the condition of the do
   statement and the body of the do statement, respectively.  */
#define DO_COND(NODE)		TREE_OPERAND (DO_STMT_CHECK (NODE), 0)
#define DO_BODY(NODE)		TREE_OPERAND (DO_STMT_CHECK (NODE), 1)

/* FOR_STMT accessors. These give access to the init statement,
   condition, update expression, and body of the for statement,
   respectively.  */
#define FOR_INIT_STMT(NODE)	TREE_OPERAND (FOR_STMT_CHECK (NODE), 0)
#define FOR_COND(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 1)
#define FOR_EXPR(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
#define FOR_BODY(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
#define FOR_SCOPE(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 4)

/* RANGE_FOR_STMT accessors. These give access to the declarator,
   expression, body, and scope of the statement, respectively.  */
#define RANGE_FOR_DECL(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 0)
#define RANGE_FOR_EXPR(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 1)
#define RANGE_FOR_BODY(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 2)
#define RANGE_FOR_SCOPE(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 3)
#define RANGE_FOR_IVDEP(NODE)	TREE_LANG_FLAG_6 (RANGE_FOR_STMT_CHECK (NODE))

#define SWITCH_STMT_COND(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
#define SWITCH_STMT_BODY(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
#define SWITCH_STMT_TYPE(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2)
#define SWITCH_STMT_SCOPE(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 3)

/* STMT_EXPR accessor.  */
#define STMT_EXPR_STMT(NODE)	TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)

/* EXPR_STMT accessor. This gives the expression associated with an
   expression statement.  */
#define EXPR_STMT_EXPR(NODE)	TREE_OPERAND (EXPR_STMT_CHECK (NODE), 0)

/* True if this TARGET_EXPR was created by build_cplus_new, and so we can
   discard it if it isn't useful.  */
#define TARGET_EXPR_IMPLICIT_P(NODE) \
  TREE_LANG_FLAG_0 (TARGET_EXPR_CHECK (NODE))

/* True if this TARGET_EXPR is the result of list-initialization of a
   temporary.  */
#define TARGET_EXPR_LIST_INIT_P(NODE) \
  TREE_LANG_FLAG_1 (TARGET_EXPR_CHECK (NODE))

/* True if this TARGET_EXPR expresses direct-initialization of an object
   to be named later.  */
#define TARGET_EXPR_DIRECT_INIT_P(NODE) \
  TREE_LANG_FLAG_2 (TARGET_EXPR_CHECK (NODE))

/* True if NODE is a TARGET_EXPR that just expresses a copy of its INITIAL; if
   the initializer has void type, it's doing something more complicated.  */
#define SIMPLE_TARGET_EXPR_P(NODE)				\
  (TREE_CODE (NODE) == TARGET_EXPR				\
   && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (NODE))))

/* True if EXPR expresses direct-initialization of a TYPE.  */
#define DIRECT_INIT_EXPR_P(TYPE,EXPR)					\
  (TREE_CODE (EXPR) == TARGET_EXPR && TREE_LANG_FLAG_2 (EXPR)		\
   && same_type_ignoring_top_level_qualifiers_p (TYPE, TREE_TYPE (EXPR)))

/* True if this CONVERT_EXPR is for a conversion to virtual base in
   an NSDMI, and should be re-evaluated when used in a constructor.  */
#define CONVERT_EXPR_VBASE_PATH(NODE) \
  TREE_LANG_FLAG_0 (CONVERT_EXPR_CHECK (NODE))

/* True if SIZEOF_EXPR argument is type.  */
#define SIZEOF_EXPR_TYPE_P(NODE) \
  TREE_LANG_FLAG_0 (SIZEOF_EXPR_CHECK (NODE))

/* An enumeration of the kind of tags that C++ accepts.  */
enum tag_types {
  none_type = 0, /* Not a tag type.  */
  record_type,   /* "struct" types.  */
  class_type,    /* "class" types.  */
  union_type,    /* "union" types.  */
  enum_type,     /* "enum" types.  */
  typename_type, /* "typename" types.  */
  scope_type	 /* namespace or tagged type name followed by :: */
};

/* The various kinds of lvalues we distinguish.  */
enum cp_lvalue_kind_flags {
  clk_none = 0,     /* Things that are not an lvalue.  */
  clk_ordinary = 1, /* An ordinary lvalue.  */
  clk_rvalueref = 2,/* An xvalue (rvalue formed using an rvalue reference) */
  clk_class = 4,    /* A prvalue of class or array type.  */
  clk_bitfield = 8, /* An lvalue for a bit-field.  */
  clk_packed = 16   /* An lvalue for a packed field.  */
};

/* This type is used for parameters and variables which hold
   combinations of the flags in enum cp_lvalue_kind_flags.  */
typedef int cp_lvalue_kind;

/* Various kinds of template specialization, instantiation, etc.  */
enum tmpl_spec_kind {
  tsk_none,		   /* Not a template at all.  */
  tsk_invalid_member_spec, /* An explicit member template
			      specialization, but the enclosing
			      classes have not all been explicitly
			      specialized.  */
  tsk_invalid_expl_inst,   /* An explicit instantiation containing
			      template parameter lists.  */
  tsk_excessive_parms,	   /* A template declaration with too many
			      template parameter lists.  */
  tsk_insufficient_parms,  /* A template declaration with too few
			      parameter lists.  */
  tsk_template,		   /* A template declaration.  */
  tsk_expl_spec,	   /* An explicit specialization.  */
  tsk_expl_inst		   /* An explicit instantiation.  */
};

/* The various kinds of access.  BINFO_ACCESS depends on these being
   two bit quantities.  The numerical values are important; they are
   used to initialize RTTI data structures, so changing them changes
   the ABI.  */
enum access_kind {
  ak_none = 0,		   /* Inaccessible.  */
  ak_public = 1,	   /* Accessible, as a `public' thing.  */
  ak_protected = 2,	   /* Accessible, as a `protected' thing.  */
  ak_private = 3	   /* Accessible, as a `private' thing.  */
};

/* The various kinds of special functions.  If you add to this list,
   you should update special_function_p as well.  */
enum special_function_kind {
  sfk_none = 0,		   /* Not a special function.  This enumeral
			      must have value zero; see
			      special_function_p.  */
  sfk_constructor,	   /* A constructor.  */
  sfk_copy_constructor,    /* A copy constructor.  */
  sfk_move_constructor,    /* A move constructor.  */
  sfk_copy_assignment,     /* A copy assignment operator.  */
  sfk_move_assignment,     /* A move assignment operator.  */
  sfk_destructor,	   /* A destructor.  */
  sfk_complete_destructor, /* A destructor for complete objects.  */
  sfk_base_destructor,     /* A destructor for base subobjects.  */
  sfk_deleting_destructor, /* A destructor for complete objects that
			      deletes the object after it has been
			      destroyed.  */
  sfk_conversion,	   /* A conversion operator.  */
  sfk_deduction_guide,	   /* A class template deduction guide.  */
  sfk_inheriting_constructor /* An inheriting constructor */
};

/* The various kinds of linkage.  From [basic.link],

      A name is said to have linkage when it might denote the same
      object, reference, function, type, template, namespace or value
      as a name introduced in another scope:

      -- When a name has external linkage, the entity it denotes can
	 be referred to from scopes of other translation units or from
	 other scopes of the same translation unit.

      -- When a name has internal linkage, the entity it denotes can
	 be referred to by names from other scopes in the same
	 translation unit.

      -- When a name has no linkage, the entity it denotes cannot be
	 referred to by names from other scopes.  */

enum linkage_kind {
  lk_none,			/* No linkage.  */
  lk_internal,			/* Internal linkage.  */
  lk_external			/* External linkage.  */
};

enum duration_kind {
  dk_static,
  dk_thread,
  dk_auto,
  dk_dynamic
};

/* Bitmask flags to control type substitution.  */
enum tsubst_flags {
  tf_none = 0,			 /* nothing special */
  tf_error = 1 << 0,		 /* give error messages  */
  tf_warning = 1 << 1,	 	 /* give warnings too  */
  tf_ignore_bad_quals = 1 << 2,	 /* ignore bad cvr qualifiers */
  tf_keep_type_decl = 1 << 3,	 /* retain typedef type decls
				    (make_typename_type use) */
  tf_ptrmem_ok = 1 << 4,	 /* pointers to member ok (internal
				    instantiate_type use) */
  tf_user = 1 << 5,		 /* found template must be a user template
				    (lookup_template_class use) */
  tf_conv = 1 << 6,		 /* We are determining what kind of
				    conversion might be permissible,
				    not actually performing the
				    conversion.  */
  tf_decltype = 1 << 7,          /* We are the operand of decltype.
				    Used to implement the special rules
				    for calls in decltype (5.2.2/11).  */
  tf_partial = 1 << 8,		 /* Doing initial explicit argument
				    substitution in fn_type_unification.  */
  tf_fndecl_type = 1 << 9,   /* Substituting the type of a function
				declaration.  */
  tf_no_cleanup = 1 << 10,   /* Do not build a cleanup
				(build_target_expr and friends) */
  /* Convenient substitution flags combinations.  */
  tf_warning_or_error = tf_warning | tf_error
};

/* This type is used for parameters and variables which hold
   combinations of the flags in enum tsubst_flags.  */
typedef int tsubst_flags_t;

/* The kind of checking we can do looking in a class hierarchy.  */
enum base_access_flags {
  ba_any = 0,  /* Do not check access, allow an ambiguous base,
		      prefer a non-virtual base */
  ba_unique = 1 << 0,  /* Must be a unique base.  */
  ba_check_bit = 1 << 1,   /* Check access.  */
  ba_check = ba_unique | ba_check_bit,
  ba_ignore_scope = 1 << 2 /* Ignore access allowed by local scope.  */
};

/* This type is used for parameters and variables which hold
   combinations of the flags in enum base_access_flags.  */
typedef int base_access;

/* The various kinds of access check during parsing.  */
enum deferring_kind {
  dk_no_deferred = 0, /* Check access immediately */
  dk_deferred = 1,    /* Deferred check */
  dk_no_check = 2     /* No access check */
};

/* The kind of base we can find, looking in a class hierarchy.
   Values <0 indicate we failed.  */
enum base_kind {
  bk_inaccessible = -3,   /* The base is inaccessible */
  bk_ambig = -2,	  /* The base is ambiguous */
  bk_not_base = -1,	  /* It is not a base */
  bk_same_type = 0,	  /* It is the same type */
  bk_proper_base = 1,	  /* It is a proper base */
  bk_via_virtual = 2	  /* It is a proper base, but via a virtual
			     path. This might not be the canonical
			     binfo.  */
};

/* Node for "pointer to (virtual) function".
   This may be distinct from ptr_type_node so gdb can distinguish them.  */
#define vfunc_ptr_type_node  vtable_entry_type


/* For building calls to `delete'.  */
extern GTY(()) tree integer_two_node;

/* The number of function bodies which we are currently processing.
   (Zero if we are at namespace scope, one inside the body of a
   function, two inside the body of a function in a local class, etc.)  */
extern int function_depth;

/* Nonzero if we are inside eq_specializations, which affects comparison of
   PARM_DECLs in cp_tree_equal.  */
extern int comparing_specializations;

/* In parser.c.  */

/* Nonzero if we are parsing an unevaluated operand: an operand to
   sizeof, typeof, or alignof.  This is a count since operands to
   sizeof can be nested.  */

extern int cp_unevaluated_operand;

/* RAII class used to inhibit the evaluation of operands during parsing
   and template instantiation. Evaluation warnings are also inhibited. */

struct cp_unevaluated
{
  cp_unevaluated ();
  ~cp_unevaluated ();
};

/* in pt.c  */

/* These values are used for the `STRICT' parameter to type_unification and
   fn_type_unification.  Their meanings are described with the
   documentation for fn_type_unification.  */

enum unification_kind_t {
  DEDUCE_CALL,
  DEDUCE_CONV,
  DEDUCE_EXACT
};

// An RAII class used to create a new pointer map for local
// specializations. When the stack goes out of scope, the
// previous pointer map is restored.
struct local_specialization_stack
{
  local_specialization_stack ();
  ~local_specialization_stack ();

  hash_map<tree, tree> *saved;
};

/* in class.c */

extern int current_class_depth;

/* An array of all local classes present in this translation unit, in
   declaration order.  */
extern GTY(()) vec<tree, va_gc> *local_classes;
