aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-tree.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/backend/rust-tree.h')
-rw-r--r--gcc/rust/backend/rust-tree.h2904
1 files changed, 2891 insertions, 13 deletions
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index a667cbf..378254c 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -22,6 +22,8 @@
#include "rust-system.h"
#include "coretypes.h"
#include "tree.h"
+#include "cpplib.h"
+#include "splay-tree.h"
/* Returns true if NODE is a pointer. */
#define TYPE_PTR_P(NODE) (TREE_CODE (NODE) == POINTER_TYPE)
@@ -156,6 +158,1454 @@
#define VAR_OR_FUNCTION_DECL_CHECK(NODE) \
TREE_CHECK2 (NODE, VAR_DECL, FUNCTION_DECL)
+// forked from gcc/cp/c-common.h c_tree_index
+
+/* Standard named or nameless data types of the C compiler. */
+
+enum c_tree_index
+{
+ CTI_CHAR8_TYPE,
+ CTI_CHAR16_TYPE,
+ CTI_CHAR32_TYPE,
+ CTI_WCHAR_TYPE,
+ CTI_UNDERLYING_WCHAR_TYPE,
+ CTI_WINT_TYPE,
+ CTI_SIGNED_SIZE_TYPE, /* For format checking only. */
+ CTI_UNSIGNED_PTRDIFF_TYPE, /* For format checking only. */
+ CTI_INTMAX_TYPE,
+ CTI_UINTMAX_TYPE,
+ CTI_WIDEST_INT_LIT_TYPE,
+ CTI_WIDEST_UINT_LIT_TYPE,
+
+ /* Types for <stdint.h>, that may not be defined on all
+ targets. */
+ CTI_SIG_ATOMIC_TYPE,
+ CTI_INT8_TYPE,
+ CTI_INT16_TYPE,
+ CTI_INT32_TYPE,
+ CTI_INT64_TYPE,
+ CTI_UINT8_TYPE,
+ CTI_UINT16_TYPE,
+ CTI_UINT32_TYPE,
+ CTI_UINT64_TYPE,
+ CTI_INT_LEAST8_TYPE,
+ CTI_INT_LEAST16_TYPE,
+ CTI_INT_LEAST32_TYPE,
+ CTI_INT_LEAST64_TYPE,
+ CTI_UINT_LEAST8_TYPE,
+ CTI_UINT_LEAST16_TYPE,
+ CTI_UINT_LEAST32_TYPE,
+ CTI_UINT_LEAST64_TYPE,
+ CTI_INT_FAST8_TYPE,
+ CTI_INT_FAST16_TYPE,
+ CTI_INT_FAST32_TYPE,
+ CTI_INT_FAST64_TYPE,
+ CTI_UINT_FAST8_TYPE,
+ CTI_UINT_FAST16_TYPE,
+ CTI_UINT_FAST32_TYPE,
+ CTI_UINT_FAST64_TYPE,
+ CTI_INTPTR_TYPE,
+ CTI_UINTPTR_TYPE,
+
+ CTI_CHAR_ARRAY_TYPE,
+ CTI_CHAR8_ARRAY_TYPE,
+ CTI_CHAR16_ARRAY_TYPE,
+ CTI_CHAR32_ARRAY_TYPE,
+ CTI_WCHAR_ARRAY_TYPE,
+ CTI_STRING_TYPE,
+ CTI_CONST_STRING_TYPE,
+
+ /* Type for boolean expressions (bool in C++, int in C). */
+ CTI_TRUTHVALUE_TYPE,
+ CTI_TRUTHVALUE_TRUE,
+ CTI_TRUTHVALUE_FALSE,
+
+ CTI_DEFAULT_FUNCTION_TYPE,
+
+ CTI_NULL,
+
+ /* These are not types, but we have to look them up all the time. */
+ CTI_FUNCTION_NAME_DECL,
+ CTI_PRETTY_FUNCTION_NAME_DECL,
+ CTI_C99_FUNCTION_NAME_DECL,
+
+ CTI_MODULE_HWM,
+ /* Below here entities change during compilation. */
+
+ CTI_SAVED_FUNCTION_NAME_DECLS,
+
+ CTI_MAX
+};
+
+// forked from gcc/c-family/c-common.h c_tree_index
+
+extern GTY (()) tree c_global_trees[CTI_MAX];
+
+// forked from gcc/cp/cp-tree.h cp_tree_index
+
+enum cp_tree_index
+{
+ CPTI_WCHAR_DECL,
+ CPTI_VTABLE_ENTRY_TYPE,
+ CPTI_DELTA_TYPE,
+ CPTI_VTABLE_INDEX_TYPE,
+ CPTI_CLEANUP_TYPE,
+ CPTI_VTT_PARM_TYPE,
+
+ CPTI_CLASS_TYPE,
+ CPTI_UNKNOWN_TYPE,
+ CPTI_INIT_LIST_TYPE,
+ CPTI_EXPLICIT_VOID_LIST,
+ CPTI_VTBL_TYPE,
+ CPTI_VTBL_PTR_TYPE,
+ CPTI_GLOBAL,
+ CPTI_ABORT_FNDECL,
+ CPTI_AGGR_TAG,
+ CPTI_CONV_OP_MARKER,
+
+ CPTI_CTOR_IDENTIFIER,
+ CPTI_COMPLETE_CTOR_IDENTIFIER,
+ CPTI_BASE_CTOR_IDENTIFIER,
+ CPTI_DTOR_IDENTIFIER,
+ CPTI_COMPLETE_DTOR_IDENTIFIER,
+ CPTI_BASE_DTOR_IDENTIFIER,
+ CPTI_DELETING_DTOR_IDENTIFIER,
+ CPTI_CONV_OP_IDENTIFIER,
+ CPTI_DELTA_IDENTIFIER,
+ CPTI_IN_CHARGE_IDENTIFIER,
+ CPTI_VTT_PARM_IDENTIFIER,
+ CPTI_AS_BASE_IDENTIFIER,
+ CPTI_THIS_IDENTIFIER,
+ CPTI_PFN_IDENTIFIER,
+ CPTI_VPTR_IDENTIFIER,
+ CPTI_GLOBAL_IDENTIFIER,
+ CPTI_ANON_IDENTIFIER,
+ CPTI_AUTO_IDENTIFIER,
+ CPTI_DECLTYPE_AUTO_IDENTIFIER,
+ CPTI_INIT_LIST_IDENTIFIER,
+ CPTI_FOR_RANGE__IDENTIFIER,
+ CPTI_FOR_BEGIN__IDENTIFIER,
+ CPTI_FOR_END__IDENTIFIER,
+ CPTI_FOR_RANGE_IDENTIFIER,
+ CPTI_FOR_BEGIN_IDENTIFIER,
+ CPTI_FOR_END_IDENTIFIER,
+ CPTI_ABI_TAG_IDENTIFIER,
+ CPTI_ALIGNED_IDENTIFIER,
+ CPTI_BEGIN_IDENTIFIER,
+ CPTI_END_IDENTIFIER,
+ CPTI_GET_IDENTIFIER,
+ CPTI_GNU_IDENTIFIER,
+ CPTI_TUPLE_ELEMENT_IDENTIFIER,
+ CPTI_TUPLE_SIZE_IDENTIFIER,
+ CPTI_TYPE_IDENTIFIER,
+ CPTI_VALUE_IDENTIFIER,
+ CPTI_FUN_IDENTIFIER,
+ CPTI_CLOSURE_IDENTIFIER,
+ CPTI_HEAP_UNINIT_IDENTIFIER,
+ CPTI_HEAP_IDENTIFIER,
+ CPTI_HEAP_DELETED_IDENTIFIER,
+ CPTI_HEAP_VEC_UNINIT_IDENTIFIER,
+ CPTI_HEAP_VEC_IDENTIFIER,
+ CPTI_OMP_IDENTIFIER,
+
+ CPTI_LANG_NAME_C,
+ CPTI_LANG_NAME_CPLUSPLUS,
+
+ CPTI_EMPTY_EXCEPT_SPEC,
+ CPTI_NOEXCEPT_TRUE_SPEC,
+ CPTI_NOEXCEPT_FALSE_SPEC,
+ CPTI_NOEXCEPT_DEFERRED_SPEC,
+
+ CPTI_NULLPTR,
+ CPTI_NULLPTR_TYPE,
+
+ CPTI_ANY_TARG,
+
+ CPTI_MODULE_HWM,
+ /* Nodes after here change during compilation, or should not be in
+ the module's global tree table. Such nodes must be locatable
+ via name lookup or type-construction, as those are the only
+ cross-TU matching capabilities remaining. */
+
+ /* We must find these via the global namespace. */
+ CPTI_STD,
+ CPTI_ABI,
+
+ /* These are created at init time, but the library/headers provide
+ definitions. */
+ CPTI_ALIGN_TYPE,
+ CPTI_TERMINATE_FN,
+ CPTI_CALL_UNEXPECTED_FN,
+
+ /* These are lazily inited. */
+ CPTI_CONST_TYPE_INFO_TYPE,
+ CPTI_GET_EXCEPTION_PTR_FN,
+ CPTI_BEGIN_CATCH_FN,
+ CPTI_END_CATCH_FN,
+ CPTI_ALLOCATE_EXCEPTION_FN,
+ CPTI_FREE_EXCEPTION_FN,
+ CPTI_THROW_FN,
+ CPTI_RETHROW_FN,
+ CPTI_ATEXIT_FN_PTR_TYPE,
+ CPTI_ATEXIT,
+ CPTI_DSO_HANDLE,
+ CPTI_DCAST,
+
+ CPTI_SOURCE_LOCATION_IMPL,
+
+ CPTI_FALLBACK_DFLOAT32_TYPE,
+ CPTI_FALLBACK_DFLOAT64_TYPE,
+ CPTI_FALLBACK_DFLOAT128_TYPE,
+
+ CPTI_MAX
+};
+
+// forked from gcc/cp/cp-tree.h cp_global_trees
+
+extern GTY (()) tree cp_global_trees[CPTI_MAX];
+
+#define wchar_decl_node cp_global_trees[CPTI_WCHAR_DECL]
+#define vtable_entry_type cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]
+/* The type used to represent an offset by which to adjust the `this'
+ pointer in pointer-to-member types. */
+#define delta_type_node cp_global_trees[CPTI_DELTA_TYPE]
+/* The type used to represent an index into the vtable. */
+#define vtable_index_type cp_global_trees[CPTI_VTABLE_INDEX_TYPE]
+
+#define class_type_node cp_global_trees[CPTI_CLASS_TYPE]
+#define unknown_type_node cp_global_trees[CPTI_UNKNOWN_TYPE]
+#define init_list_type_node cp_global_trees[CPTI_INIT_LIST_TYPE]
+#define explicit_void_list_node cp_global_trees[CPTI_EXPLICIT_VOID_LIST]
+#define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE]
+#define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE]
+#define std_node cp_global_trees[CPTI_STD]
+#define abi_node cp_global_trees[CPTI_ABI]
+#define global_namespace cp_global_trees[CPTI_GLOBAL]
+#define const_type_info_type_node cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE]
+#define conv_op_marker cp_global_trees[CPTI_CONV_OP_MARKER]
+#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
+#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
+#define nullptr_node cp_global_trees[CPTI_NULLPTR]
+#define nullptr_type_node cp_global_trees[CPTI_NULLPTR_TYPE]
+/* std::align_val_t */
+#define align_type_node cp_global_trees[CPTI_ALIGN_TYPE]
+
+#define char8_type_node c_global_trees[CTI_CHAR8_TYPE]
+#define char16_type_node c_global_trees[CTI_CHAR16_TYPE]
+#define char32_type_node c_global_trees[CTI_CHAR32_TYPE]
+#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE]
+#define underlying_wchar_type_node c_global_trees[CTI_UNDERLYING_WCHAR_TYPE]
+#define wint_type_node c_global_trees[CTI_WINT_TYPE]
+#define signed_size_type_node c_global_trees[CTI_SIGNED_SIZE_TYPE]
+#define unsigned_ptrdiff_type_node c_global_trees[CTI_UNSIGNED_PTRDIFF_TYPE]
+#define intmax_type_node c_global_trees[CTI_INTMAX_TYPE]
+#define uintmax_type_node c_global_trees[CTI_UINTMAX_TYPE]
+#define widest_integer_literal_type_node c_global_trees[CTI_WIDEST_INT_LIT_TYPE]
+#define widest_unsigned_literal_type_node \
+ c_global_trees[CTI_WIDEST_UINT_LIT_TYPE]
+
+#define sig_atomic_type_node c_global_trees[CTI_SIG_ATOMIC_TYPE]
+#define int8_type_node c_global_trees[CTI_INT8_TYPE]
+#define int16_type_node c_global_trees[CTI_INT16_TYPE]
+#define int32_type_node c_global_trees[CTI_INT32_TYPE]
+#define int64_type_node c_global_trees[CTI_INT64_TYPE]
+#define uint8_type_node c_global_trees[CTI_UINT8_TYPE]
+#define c_uint16_type_node c_global_trees[CTI_UINT16_TYPE]
+#define c_uint32_type_node c_global_trees[CTI_UINT32_TYPE]
+#define c_uint64_type_node c_global_trees[CTI_UINT64_TYPE]
+#define int_least8_type_node c_global_trees[CTI_INT_LEAST8_TYPE]
+#define int_least16_type_node c_global_trees[CTI_INT_LEAST16_TYPE]
+#define int_least32_type_node c_global_trees[CTI_INT_LEAST32_TYPE]
+#define int_least64_type_node c_global_trees[CTI_INT_LEAST64_TYPE]
+#define uint_least8_type_node c_global_trees[CTI_UINT_LEAST8_TYPE]
+#define uint_least16_type_node c_global_trees[CTI_UINT_LEAST16_TYPE]
+#define uint_least32_type_node c_global_trees[CTI_UINT_LEAST32_TYPE]
+#define uint_least64_type_node c_global_trees[CTI_UINT_LEAST64_TYPE]
+#define int_fast8_type_node c_global_trees[CTI_INT_FAST8_TYPE]
+#define int_fast16_type_node c_global_trees[CTI_INT_FAST16_TYPE]
+#define int_fast32_type_node c_global_trees[CTI_INT_FAST32_TYPE]
+#define int_fast64_type_node c_global_trees[CTI_INT_FAST64_TYPE]
+#define uint_fast8_type_node c_global_trees[CTI_UINT_FAST8_TYPE]
+#define uint_fast16_type_node c_global_trees[CTI_UINT_FAST16_TYPE]
+#define uint_fast32_type_node c_global_trees[CTI_UINT_FAST32_TYPE]
+#define uint_fast64_type_node c_global_trees[CTI_UINT_FAST64_TYPE]
+#define intptr_type_node c_global_trees[CTI_INTPTR_TYPE]
+#define uintptr_type_node c_global_trees[CTI_UINTPTR_TYPE]
+
+#define truthvalue_type_node c_global_trees[CTI_TRUTHVALUE_TYPE]
+#define truthvalue_true_node c_global_trees[CTI_TRUTHVALUE_TRUE]
+#define truthvalue_false_node c_global_trees[CTI_TRUTHVALUE_FALSE]
+
+#define char_array_type_node c_global_trees[CTI_CHAR_ARRAY_TYPE]
+#define char8_array_type_node c_global_trees[CTI_CHAR8_ARRAY_TYPE]
+#define char16_array_type_node c_global_trees[CTI_CHAR16_ARRAY_TYPE]
+#define char32_array_type_node c_global_trees[CTI_CHAR32_ARRAY_TYPE]
+#define wchar_array_type_node c_global_trees[CTI_WCHAR_ARRAY_TYPE]
+#define string_type_node c_global_trees[CTI_STRING_TYPE]
+#define const_string_type_node c_global_trees[CTI_CONST_STRING_TYPE]
+
+#define default_function_type c_global_trees[CTI_DEFAULT_FUNCTION_TYPE]
+
+#define function_name_decl_node c_global_trees[CTI_FUNCTION_NAME_DECL]
+#define pretty_function_name_decl_node \
+ c_global_trees[CTI_PRETTY_FUNCTION_NAME_DECL]
+#define c99_function_name_decl_node c_global_trees[CTI_C99_FUNCTION_NAME_DECL]
+#define saved_function_name_decls c_global_trees[CTI_SAVED_FUNCTION_NAME_DECLS]
+
+/* The node for C++ `__null'. */
+#define null_node c_global_trees[CTI_NULL]
+
+/* We cache these tree nodes so as to call get_identifier less frequently.
+ For identifiers for functions, including special member functions such
+ as ctors and assignment operators, the nodes can be used (among other
+ things) to iterate over their overloads defined by/for a type. For
+ example:
+
+ tree ovlid = assign_op_identifier;
+ tree overloads = get_class_binding (type, ovlid);
+ for (ovl_iterator it (overloads); it; ++it) { ... }
+
+ iterates over the set of implicitly and explicitly defined overloads
+ of the assignment operator for type (including the copy and move
+ assignment operators, whether deleted or not). */
+
+/* The name of a constructor that takes an in-charge parameter to
+ decide whether or not to construct virtual base classes. */
+#define ctor_identifier cp_global_trees[CPTI_CTOR_IDENTIFIER]
+/* The name of a constructor that constructs virtual base classes. */
+#define complete_ctor_identifier cp_global_trees[CPTI_COMPLETE_CTOR_IDENTIFIER]
+/* The name of a constructor that does not construct virtual base classes. */
+#define base_ctor_identifier cp_global_trees[CPTI_BASE_CTOR_IDENTIFIER]
+/* The name of a destructor that takes an in-charge parameter to
+ decide whether or not to destroy virtual base classes and whether
+ or not to delete the object. */
+#define dtor_identifier cp_global_trees[CPTI_DTOR_IDENTIFIER]
+/* The name of a destructor that destroys virtual base classes. */
+#define complete_dtor_identifier cp_global_trees[CPTI_COMPLETE_DTOR_IDENTIFIER]
+/* The name of a destructor that does not destroy virtual base
+ classes. */
+#define base_dtor_identifier cp_global_trees[CPTI_BASE_DTOR_IDENTIFIER]
+/* The name of a destructor that destroys virtual base classes, and
+ then deletes the entire object. */
+#define deleting_dtor_identifier cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER]
+
+/* The name used for conversion operators -- but note that actual
+ conversion functions use special identifiers outside the identifier
+ table. */
+#define conv_op_identifier cp_global_trees[CPTI_CONV_OP_IDENTIFIER]
+
+#define delta_identifier cp_global_trees[CPTI_DELTA_IDENTIFIER]
+#define in_charge_identifier cp_global_trees[CPTI_IN_CHARGE_IDENTIFIER]
+/* The name of the parameter that contains a pointer to the VTT to use
+ for this subobject constructor or destructor. */
+#define vtt_parm_identifier cp_global_trees[CPTI_VTT_PARM_IDENTIFIER]
+#define as_base_identifier cp_global_trees[CPTI_AS_BASE_IDENTIFIER]
+#define this_identifier cp_global_trees[CPTI_THIS_IDENTIFIER]
+#define pfn_identifier cp_global_trees[CPTI_PFN_IDENTIFIER]
+#define vptr_identifier cp_global_trees[CPTI_VPTR_IDENTIFIER]
+/* The name of the ::, std & anon namespaces. */
+#define global_identifier cp_global_trees[CPTI_GLOBAL_IDENTIFIER]
+#define anon_identifier cp_global_trees[CPTI_ANON_IDENTIFIER]
+/* auto and declspec(auto) identifiers. */
+#define auto_identifier cp_global_trees[CPTI_AUTO_IDENTIFIER]
+#define decltype_auto_identifier cp_global_trees[CPTI_DECLTYPE_AUTO_IDENTIFIER]
+#define init_list_identifier cp_global_trees[CPTI_INIT_LIST_IDENTIFIER]
+#define for_range__identifier cp_global_trees[CPTI_FOR_RANGE__IDENTIFIER]
+#define for_begin__identifier cp_global_trees[CPTI_FOR_BEGIN__IDENTIFIER]
+#define for_end__identifier cp_global_trees[CPTI_FOR_END__IDENTIFIER]
+#define for_range_identifier cp_global_trees[CPTI_FOR_RANGE_IDENTIFIER]
+#define for_begin_identifier cp_global_trees[CPTI_FOR_BEGIN_IDENTIFIER]
+#define for_end_identifier cp_global_trees[CPTI_FOR_END_IDENTIFIER]
+#define abi_tag_identifier cp_global_trees[CPTI_ABI_TAG_IDENTIFIER]
+#define aligned_identifier cp_global_trees[CPTI_ALIGNED_IDENTIFIER]
+#define begin_identifier cp_global_trees[CPTI_BEGIN_IDENTIFIER]
+#define end_identifier cp_global_trees[CPTI_END_IDENTIFIER]
+#define get__identifier cp_global_trees[CPTI_GET_IDENTIFIER]
+#define gnu_identifier cp_global_trees[CPTI_GNU_IDENTIFIER]
+#define tuple_element_identifier cp_global_trees[CPTI_TUPLE_ELEMENT_IDENTIFIER]
+#define tuple_size_identifier cp_global_trees[CPTI_TUPLE_SIZE_IDENTIFIER]
+#define type_identifier cp_global_trees[CPTI_TYPE_IDENTIFIER]
+#define value_identifier cp_global_trees[CPTI_VALUE_IDENTIFIER]
+#define fun_identifier cp_global_trees[CPTI_FUN_IDENTIFIER]
+#define closure_identifier cp_global_trees[CPTI_CLOSURE_IDENTIFIER]
+#define heap_uninit_identifier cp_global_trees[CPTI_HEAP_UNINIT_IDENTIFIER]
+#define heap_identifier cp_global_trees[CPTI_HEAP_IDENTIFIER]
+#define heap_deleted_identifier cp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]
+#define heap_vec_uninit_identifier \
+ cp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER]
+#define heap_vec_identifier cp_global_trees[CPTI_HEAP_VEC_IDENTIFIER]
+#define omp_identifier cp_global_trees[CPTI_OMP_IDENTIFIER]
+#define lang_name_c cp_global_trees[CPTI_LANG_NAME_C]
+#define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]
+
+/* Exception specifiers used for throw(), noexcept(true),
+ noexcept(false) and deferred noexcept. We rely on these being
+ uncloned. */
+#define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC]
+#define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC]
+#define noexcept_false_spec cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC]
+#define noexcept_deferred_spec cp_global_trees[CPTI_NOEXCEPT_DEFERRED_SPEC]
+
+/* Exception handling function declarations. */
+#define terminate_fn cp_global_trees[CPTI_TERMINATE_FN]
+#define call_unexpected_fn cp_global_trees[CPTI_CALL_UNEXPECTED_FN]
+#define get_exception_ptr_fn cp_global_trees[CPTI_GET_EXCEPTION_PTR_FN]
+#define begin_catch_fn cp_global_trees[CPTI_BEGIN_CATCH_FN]
+#define end_catch_fn cp_global_trees[CPTI_END_CATCH_FN]
+#define allocate_exception_fn cp_global_trees[CPTI_ALLOCATE_EXCEPTION_FN]
+#define free_exception_fn cp_global_trees[CPTI_FREE_EXCEPTION_FN]
+#define throw_fn cp_global_trees[CPTI_THROW_FN]
+#define rethrow_fn cp_global_trees[CPTI_RETHROW_FN]
+
+/* The type of the function-pointer argument to "__cxa_atexit" (or
+ "std::atexit", if "__cxa_atexit" is not being used). */
+#define atexit_fn_ptr_type_node cp_global_trees[CPTI_ATEXIT_FN_PTR_TYPE]
+
+/* A pointer to `std::atexit'. */
+#define atexit_node cp_global_trees[CPTI_ATEXIT]
+
+/* A pointer to `__dso_handle'. */
+#define dso_handle_node cp_global_trees[CPTI_DSO_HANDLE]
+
+/* The declaration of the dynamic_cast runtime. */
+#define dynamic_cast_node cp_global_trees[CPTI_DCAST]
+
+/* The type of a destructor. */
+#define cleanup_type cp_global_trees[CPTI_CLEANUP_TYPE]
+
+/* The type of the vtt parameter passed to subobject constructors and
+ destructors. */
+#define vtt_parm_type cp_global_trees[CPTI_VTT_PARM_TYPE]
+
+/* A node which matches any template argument. */
+#define any_targ_node cp_global_trees[CPTI_ANY_TARG]
+
+/* std::source_location::__impl class. */
+#define source_location_impl cp_global_trees[CPTI_SOURCE_LOCATION_IMPL]
+
+/* These two accessors should only be used by OVL manipulators.
+ Other users should use iterators and convenience functions. */
+#define OVL_FUNCTION(NODE) \
+ (((struct tree_overload *) OVERLOAD_CHECK (NODE))->function)
+#define OVL_CHAIN(NODE) \
+ (((struct tree_overload *) OVERLOAD_CHECK (NODE))->common.chain)
+
+/* If set, this or a subsequent overload contains decls that need deduping. */
+#define OVL_DEDUP_P(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE))
+/* If set, this was imported in a using declaration. */
+#define OVL_USING_P(NODE) TREE_LANG_FLAG_1 (OVERLOAD_CHECK (NODE))
+/* If set, this overload is a hidden decl. */
+#define OVL_HIDDEN_P(NODE) TREE_LANG_FLAG_2 (OVERLOAD_CHECK (NODE))
+/* If set, this overload contains a nested overload. */
+#define OVL_NESTED_P(NODE) TREE_LANG_FLAG_3 (OVERLOAD_CHECK (NODE))
+/* If set, this overload was constructed during lookup. */
+#define OVL_LOOKUP_P(NODE) TREE_LANG_FLAG_4 (OVERLOAD_CHECK (NODE))
+/* If set, this OVL_USING_P overload is exported. */
+#define OVL_EXPORT_P(NODE) TREE_LANG_FLAG_5 (OVERLOAD_CHECK (NODE))
+
+/* The first decl of an overload. */
+#define OVL_FIRST(NODE) ovl_first (NODE)
+/* The name of the overload set. */
+#define OVL_NAME(NODE) DECL_NAME (OVL_FIRST (NODE))
+
+/* Whether this is a set of overloaded functions. TEMPLATE_DECLS are
+ always wrapped in an OVERLOAD, so we don't need to check them
+ here. */
+#define OVL_P(NODE) \
+ (TREE_CODE (NODE) == FUNCTION_DECL || TREE_CODE (NODE) == OVERLOAD)
+/* Whether this is a single member overload. */
+#define OVL_SINGLE_P(NODE) (TREE_CODE (NODE) != OVERLOAD || !OVL_CHAIN (NODE))
+
+/* Nonzero means that this type has an X() constructor. */
+#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_default_ctor)
+
+/* Nonzero means that NODE (a class type) has a default constructor --
+ but that it has not yet been declared. */
+#define CLASSTYPE_LAZY_DEFAULT_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_default_ctor)
+
+/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These
+ are the constructors that take an in-charge parameter. */
+#define CLASSTYPE_CONSTRUCTORS(NODE) \
+ (get_class_binding_direct (NODE, ctor_identifier))
+
+/* 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))
+
+/* In a TREE_LIST for a parameter-declaration-list, indicates that all the
+ parameters in the list have declarators enclosed in (). */
+#define PARENTHESIZED_LIST_P(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+
+/* 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) DECL_RESULT_FLD (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))
+
+/* True if member using decl NODE refers to a non-inherited NODE. */
+#define USING_DECL_UNRELATED_P(NODE) DECL_LANG_FLAG_2 (USING_DECL_CHECK (NODE))
+
+/* Nonzero if NODE declares a function. */
+#define DECL_DECLARES_FUNCTION_P(NODE) (TREE_CODE (NODE) == FUNCTION_DECL)
+
+/* Nonzero for a NODE which declares a type. */
+#define DECL_DECLARES_TYPE_P(NODE) (TREE_CODE (NODE) == TYPE_DECL)
+
+/* Kind bits. */
+#define IDENTIFIER_KIND_BIT_0(NODE) \
+ TREE_LANG_FLAG_0 (IDENTIFIER_NODE_CHECK (NODE))
+#define IDENTIFIER_KIND_BIT_1(NODE) \
+ TREE_LANG_FLAG_1 (IDENTIFIER_NODE_CHECK (NODE))
+#define IDENTIFIER_KIND_BIT_2(NODE) \
+ TREE_LANG_FLAG_2 (IDENTIFIER_NODE_CHECK (NODE))
+
+/* Used by various search routines. */
+#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_4 (IDENTIFIER_NODE_CHECK (NODE))
+
+/* Nonzero if this identifier is used as a virtual function name somewhere
+ (optimizes searches). */
+#define IDENTIFIER_VIRTUAL_P(NODE) \
+ TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (NODE))
+
+/* True if this identifier is a reserved word. C_RID_CODE (node) is
+ then the RID_* value of the keyword. Value 1. */
+#define IDENTIFIER_KEYWORD_P(NODE) \
+ ((!IDENTIFIER_KIND_BIT_2 (NODE)) & (!IDENTIFIER_KIND_BIT_1 (NODE)) \
+ & IDENTIFIER_KIND_BIT_0 (NODE))
+
+/* True if this identifier is the name of a constructor or
+ destructor. Value 2 or 3. */
+#define IDENTIFIER_CDTOR_P(NODE) \
+ ((!IDENTIFIER_KIND_BIT_2 (NODE)) & IDENTIFIER_KIND_BIT_1 (NODE))
+
+/* True if this identifier is the name of a constructor. Value 2. */
+#define IDENTIFIER_CTOR_P(NODE) \
+ (IDENTIFIER_CDTOR_P (NODE) & (!IDENTIFIER_KIND_BIT_0 (NODE)))
+
+/* True if this identifier is the name of a destructor. Value 3. */
+#define IDENTIFIER_DTOR_P(NODE) \
+ (IDENTIFIER_CDTOR_P (NODE) & IDENTIFIER_KIND_BIT_0 (NODE))
+
+/* True if this identifier is for any operator name (including
+ conversions). Value 4, 5, 6 or 7. */
+#define IDENTIFIER_ANY_OP_P(NODE) (IDENTIFIER_KIND_BIT_2 (NODE))
+
+/* True if this identifier is for an overloaded operator. Values 4, 5. */
+#define IDENTIFIER_OVL_OP_P(NODE) \
+ (IDENTIFIER_ANY_OP_P (NODE) & (!IDENTIFIER_KIND_BIT_1 (NODE)))
+
+/* True if this identifier is for any assignment. Values 5. */
+#define IDENTIFIER_ASSIGN_OP_P(NODE) \
+ (IDENTIFIER_OVL_OP_P (NODE) & IDENTIFIER_KIND_BIT_0 (NODE))
+
+/* True if this identifier is the name of a type-conversion
+ operator. Value 7. */
+#define IDENTIFIER_CONV_OP_P(NODE) \
+ (IDENTIFIER_ANY_OP_P (NODE) & IDENTIFIER_KIND_BIT_1 (NODE) \
+ & (!IDENTIFIER_KIND_BIT_0 (NODE)))
+
+/* True if this identifier is a new or delete operator. */
+#define IDENTIFIER_NEWDEL_OP_P(NODE) \
+ (IDENTIFIER_OVL_OP_P (NODE) \
+ && IDENTIFIER_OVL_OP_FLAGS (NODE) & OVL_OP_FLAG_ALLOC)
+
+/* True if this identifier is a new operator. */
+#define IDENTIFIER_NEW_OP_P(NODE) \
+ (IDENTIFIER_OVL_OP_P (NODE) \
+ && (IDENTIFIER_OVL_OP_FLAGS (NODE) \
+ & (OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE)) \
+ == OVL_OP_FLAG_ALLOC)
+
+/* Nonzero if the class NODE has multiple paths to the same (virtual)
+ base object. */
+#define CLASSTYPE_DIAMOND_SHAPED_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->diamond_shaped)
+
+/* Nonzero if the class NODE has multiple instances of the same base
+ type. */
+#define CLASSTYPE_REPEATED_BASE_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->repeated_base)
+
+/* The member function with which the vtable will be emitted:
+ the first noninline non-pure-virtual member function. NULL_TREE
+ if there is no key function or if this is a class template */
+#define CLASSTYPE_KEY_METHOD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->key_method)
+
+/* Vector of members. During definition, it is unordered and only
+ member functions are present. After completion it is sorted and
+ contains both member functions and non-functions. STAT_HACK is
+ involved to preserve oneslot per name invariant. */
+#define CLASSTYPE_MEMBER_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->members)
+
+/* For class templates, this is a TREE_LIST of all member data,
+ functions, types, and friends in the order of declaration.
+ The TREE_PURPOSE of each TREE_LIST is NULL_TREE for a friend,
+ and the RECORD_TYPE for the class template otherwise. */
+#define CLASSTYPE_DECL_LIST(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->decl_list)
+
+/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These
+ are the constructors that take an in-charge parameter. */
+#define CLASSTYPE_CONSTRUCTORS(NODE) \
+ (get_class_binding_direct (NODE, ctor_identifier))
+
+/* A FUNCTION_DECL for the destructor for NODE. This is the
+ destructors that take an in-charge parameter. If
+ CLASSTYPE_LAZY_DESTRUCTOR is true, then this entry will be NULL
+ until the destructor is created with lazily_declare_fn. */
+#define CLASSTYPE_DESTRUCTOR(NODE) \
+ (get_class_binding_direct (NODE, dtor_identifier))
+
+/* Nonzero if NODE has a primary base class, i.e., a base class with
+ which it shares the virtual function table pointer. */
+#define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \
+ (CLASSTYPE_PRIMARY_BINFO (NODE) != NULL_TREE)
+
+/* If non-NULL, this is the binfo for the primary base class, i.e.,
+ the base class which contains the virtual function table pointer
+ for this class. */
+#define CLASSTYPE_PRIMARY_BINFO(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->primary_base)
+
+/* A vector of BINFOs for the direct and indirect virtual base classes
+ that this type uses in a post-order depth-first left-to-right
+ order. (In other words, these bases appear in the order that they
+ should be initialized.) */
+#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)
+
+/* The type corresponding to NODE when NODE is used as a base class,
+ i.e., NODE without virtual base classes or tail padding. */
+#define CLASSTYPE_AS_BASE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->as_base)
+
+/* Nonzero if NODE is a user-defined conversion operator. */
+#define DECL_CONV_FN_P(NODE) IDENTIFIER_CONV_OP_P (DECL_NAME (NODE))
+
+/* The type to which conversion operator FN converts to. */
+#define DECL_CONV_FN_TYPE(FN) \
+ TREE_TYPE ((gcc_checking_assert (DECL_CONV_FN_P (FN)), DECL_NAME (FN)))
+
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual
+ sense of `same'. */
+#define same_type_p(TYPE1, TYPE2) comptypes ((TYPE1), (TYPE2), COMPARE_STRICT)
+
+/* Nonzero if T is a type that could resolve to any kind of concrete type
+ at instantiation time. */
+#define WILDCARD_TYPE_P(T) \
+ (TREE_CODE (T) == TEMPLATE_TYPE_PARM || TREE_CODE (T) == TYPENAME_TYPE \
+ || TREE_CODE (T) == TYPEOF_TYPE \
+ || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM \
+ || TREE_CODE (T) == DECLTYPE_TYPE \
+ || TREE_CODE (T) == DEPENDENT_OPERATOR_TYPE)
+
+/* Nonzero if T is a class (or struct or union) type. Also nonzero
+ for template type parameters, typename types, and instantiated
+ template template parameters. Keep these checks in ascending code
+ order. */
+#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T))
+
+/* 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))
+
+/* 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) \
+ (rs_build_qualified_type (TREE_TYPE (TYPE_FIELDS (NODE)), \
+ rs_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)))
+
+/* True if this type is dependent. This predicate is only valid if
+ TYPE_DEPENDENT_P_VALID is true. */
+#define TYPE_DEPENDENT_P(NODE) TYPE_LANG_FLAG_0 (NODE)
+
+/* True if dependent_type_p has been called for this type, with the
+ result that TYPE_DEPENDENT_P is valid. */
+#define TYPE_DEPENDENT_P_VALID(NODE) TYPE_LANG_FLAG_6 (NODE)
+
+/* Nonzero 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 if the type of the elements needs a destructor. */
+#define TYPE_HAS_NONTRIVIAL_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_4 (NODE))
+
+/* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that
+ this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE
+ will be NULL_TREE to indicate a throw specification of `()', or
+ no exceptions allowed. For a noexcept specification, TREE_VALUE
+ is NULL_TREE and TREE_PURPOSE is the constant-expression. For
+ a deferred noexcept-specification, TREE_PURPOSE is a DEFERRED_NOEXCEPT
+ (for templates) or an OVERLOAD list of functions (for implicitly
+ declared functions). */
+#define TYPE_RAISES_EXCEPTIONS(NODE) \
+ TYPE_LANG_SLOT_1 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* Identifiers map directly to block or class-scope bindings.
+ Namespace-scope bindings are held in hash tables on the respective
+ namespaces. The identifier bindings are the innermost active
+ binding, from whence you can get the decl and/or implicit-typedef
+ of an elaborated type. When not bound to a local entity the
+ values are NULL. */
+#define IDENTIFIER_BINDING(NODE) (LANG_IDENTIFIER_CAST (NODE)->bindings)
+
+#define LANG_IDENTIFIER_CAST(NODE) \
+ ((struct lang_identifier *) IDENTIFIER_NODE_CHECK (NODE))
+
+/* 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))
+#define IF_STMT_CONSTEVAL_P(NODE) TREE_LANG_FLAG_2 (IF_STMT_CHECK (NODE))
+
+/* The expression in question for a DECLTYPE_TYPE. */
+#define DECLTYPE_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (DECLTYPE_TYPE_CHECK (NODE)))
+
+#define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE, X) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = !!(X))
+
+/* Nonzero if this class is included from a header file which employs
+ `#pragma interface', and it is not included in its implementation file. */
+#define CLASSTYPE_INTERFACE_ONLY(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_only)
+
+#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE)))
+#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE)))
+
+/* Whether a PARM_DECL represents a local parameter in a
+ requires-expression. */
+#define CONSTRAINT_VAR_P(NODE) DECL_LANG_FLAG_2 (TREE_CHECK (NODE, PARM_DECL))
+
+/* 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))
+
+/* 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)
+
+/* These flags are used by the conversion code.
+ CONV_IMPLICIT : Perform implicit conversions (standard and user-defined).
+ CONV_STATIC : Perform the explicit conversions for static_cast.
+ CONV_CONST : Perform the explicit conversions for const_cast.
+ CONV_REINTERPRET: Perform the explicit conversions for reinterpret_cast.
+ CONV_PRIVATE : Perform upcasts to private bases.
+ CONV_FORCE_TEMP : Require a new temporary when converting to the same
+ aggregate type. */
+
+#define CONV_IMPLICIT 1
+#define CONV_STATIC 2
+#define CONV_CONST 4
+#define CONV_REINTERPRET 8
+#define CONV_PRIVATE 16
+#define CONV_FORCE_TEMP 32
+#define CONV_FOLD 64
+#define CONV_OLD_CONVERT \
+ (CONV_IMPLICIT | CONV_STATIC | CONV_CONST | CONV_REINTERPRET)
+#define CONV_C_CAST \
+ (CONV_IMPLICIT | CONV_STATIC | CONV_CONST | CONV_REINTERPRET | CONV_PRIVATE \
+ | CONV_FORCE_TEMP)
+#define CONV_BACKEND_CONVERT (CONV_OLD_CONVERT | CONV_FOLD)
+
+/* Used by build_expr_type_conversion to indicate which types are
+ acceptable as arguments to the expression under consideration. */
+
+#define WANT_INT 1 /* integer types, including bool */
+#define WANT_FLOAT 2 /* floating point types */
+#define WANT_ENUM 4 /* enumerated types */
+#define WANT_POINTER 8 /* pointer types */
+#define WANT_NULL 16 /* null pointer constant */
+#define WANT_VECTOR_OR_COMPLEX 32 /* vector or complex types */
+#define WANT_ARITH (WANT_INT | WANT_FLOAT | WANT_VECTOR_OR_COMPLEX)
+
+/* Used with comptypes, and related functions, to guide type
+ comparison. */
+
+#define COMPARE_STRICT \
+ 0 /* Just check if the types are the \
+ same. */
+#define COMPARE_BASE \
+ 1 /* Check to see if the second type is \
+ derived from the first. */
+#define COMPARE_DERIVED \
+ 2 /* Like COMPARE_BASE, but in \
+ reverse. */
+#define COMPARE_REDECLARATION \
+ 4 /* The comparison is being done when \
+ another declaration of an existing \
+ entity is seen. */
+#define COMPARE_STRUCTURAL \
+ 8 /* The comparison is intended to be \
+ structural. The actual comparison \
+ will be identical to \
+ COMPARE_STRICT. */
+
+/* Used with start function. */
+#define SF_DEFAULT 0 /* No flags. */
+#define SF_PRE_PARSED \
+ 1 /* The function declaration has \
+ already been parsed. */
+#define SF_INCLASS_INLINE \
+ 2 /* The function is an inline, defined \
+ in the class body. */
+
+/* Used with start_decl's initialized parameter. */
+#define SD_UNINITIALIZED 0
+#define SD_INITIALIZED 1
+/* Like SD_INITIALIZED, but also mark the new decl as DECL_DECOMPOSITION_P. */
+#define SD_DECOMPOSITION 2
+#define SD_DEFAULTED 3
+#define SD_DELETED 4
+
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual
+ sense of `same'. */
+#define same_type_p(TYPE1, TYPE2) comptypes ((TYPE1), (TYPE2), COMPARE_STRICT)
+
+/* Returns true if NODE is a pointer-to-data-member. */
+#define TYPE_PTRDATAMEM_P(NODE) (TREE_CODE (NODE) == OFFSET_TYPE)
+
+/* Nonzero if this type is const-qualified. */
+#define RS_TYPE_CONST_P(NODE) ((rs_type_quals (NODE) & TYPE_QUAL_CONST) != 0)
+
+/* The _DECL for this _TYPE. */
+#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (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_6 (VAR_DECL_CHECK (NODE)))
+
+/* Nonzero if DECL was declared with '= default' (maybe implicitly). */
+#define DECL_DEFAULTED_FN(DECL) (LANG_DECL_FN_CHECK (DECL)->defaulted_p)
+
+/* 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))
+
+/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These
+ are the constructors that take an in-charge parameter. */
+#define CLASSTYPE_CONSTRUCTORS(NODE) \
+ (get_class_binding_direct (NODE, ctor_identifier))
+
+/* 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 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 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)
+
+/* 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 the VTT parm has been added to NODE. */
+#define DECL_HAS_VTT_PARM_P(NODE) (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
+
+/* Given a FUNCTION_DECL, returns the first TREE_LIST out of TYPE_ARG_TYPES
+ which refers to a user-written parameter. */
+#define FUNCTION_FIRST_USER_PARMTYPE(NODE) \
+ skip_artificial_parms_for ((NODE), TYPE_ARG_TYPES (TREE_TYPE (NODE)))
+
+/* Similarly, but for DECL_ARGUMENTS. */
+#define FUNCTION_FIRST_USER_PARM(NODE) \
+ skip_artificial_parms_for ((NODE), DECL_ARGUMENTS (NODE))
+
+/* For FUNCTION_DECLs and TEMPLATE_DECLs: nonzero means that this function
+ is a constructor. */
+#define DECL_CONSTRUCTOR_P(NODE) DECL_CXX_CONSTRUCTOR_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)
+
+/* 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 FNDECL is an immediate function. */
+#define DECL_IMMEDIATE_FUNCTION_P(NODE) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE)) \
+ ? LANG_DECL_FN_CHECK (NODE)->immediate_fn_p \
+ : false)
+#define SET_DECL_IMMEDIATE_FUNCTION_P(NODE) \
+ (retrofit_lang_decl (FUNCTION_DECL_CHECK (NODE)), \
+ LANG_DECL_FN_CHECK (NODE)->immediate_fn_p = true)
+
+/* 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)))
+
+/* 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)
+
+/* Indicates whether a COMPONENT_REF or a SCOPE_REF has been parenthesized, an
+ INDIRECT_REF comes from parenthesizing a _DECL, or a PAREN_EXPR identifies a
+ parenthesized initializer relevant for decltype(auto). Currently only set
+ some of the time in C++14 mode. */
+
+#define REF_PARENTHESIZED_P(NODE) \
+ TREE_LANG_FLAG_2 (TREE_CHECK5 ((NODE), COMPONENT_REF, INDIRECT_REF, \
+ SCOPE_REF, VIEW_CONVERT_EXPR, PAREN_EXPR))
+
+/* 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))
+
+/* Nonzero if NODE is an artificial VAR_DECL for a C++17 structured binding
+ declaration or one of VAR_DECLs for the user identifiers in it. */
+#define DECL_DECOMPOSITION_P(NODE) \
+ (VAR_P (NODE) && DECL_LANG_SPECIFIC (NODE) \
+ ? DECL_LANG_SPECIFIC (NODE)->u.base.selector == lds_decomp \
+ : false)
+
+/* The underlying artificial VAR_DECL for structured binding. */
+#define DECL_DECOMP_BASE(NODE) (LANG_DECL_DECOMP_CHECK (NODE)->base)
+
+/* Nonzero if either DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P or
+ DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P is true of NODE. */
+#define DECL_MAYBE_IN_CHARGE_CDTOR_P(NODE) \
+ (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (NODE) \
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (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_NAME (NODE) == dtor_identifier)
+
+/* Nonzero if NODE (a _DECL) is a cloned constructor or
+ destructor. */
+#define DECL_CLONED_FUNCTION_P(NODE) \
+ (DECL_NAME (NODE) && IDENTIFIER_CDTOR_P (DECL_NAME (NODE)) \
+ && !DECL_MAYBE_IN_CHARGE_CDTOR_P (NODE))
+
+/* If DECL_CLONED_FUNCTION_P holds, this is the function that was
+ cloned. */
+#define DECL_CLONED_FUNCTION(NODE) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))->u.fn.u5.cloned_function)
+
+/* Nonzero if NODE (a _DECL) is a cloned constructor or
+ destructor. */
+#define DECL_CLONED_FUNCTION_P(NODE) \
+ (DECL_NAME (NODE) && IDENTIFIER_CDTOR_P (DECL_NAME (NODE)) \
+ && !DECL_MAYBE_IN_CHARGE_CDTOR_P (NODE))
+
+/* 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_NAME (NODE) == ctor_identifier)
+
+/* The current C++-specific per-function global variables. */
+
+#define cp_function_chain (cfun->language)
+
+/* In a constructor destructor, the point at which all derived class
+ destroying/construction has been done. I.e., just before a
+ constructor returns, or before any base class destroying will be done
+ in a destructor. */
+
+#define cdtor_label cp_function_chain->x_cdtor_label
+
+/* When we're processing a member function, current_class_ptr is the
+ PARM_DECL for the `this' pointer. The current_class_ref is an
+ expression for `*this'. */
+
+#define current_class_ptr \
+ (*(cfun && cp_function_chain ? &cp_function_chain->x_current_class_ptr \
+ : &scope_chain->x_current_class_ptr))
+#define current_class_ref \
+ (*(cfun && cp_function_chain ? &cp_function_chain->x_current_class_ref \
+ : &scope_chain->x_current_class_ref))
+
+/* The EH_SPEC_BLOCK for the exception-specifiers for the current
+ function, if any. */
+
+#define current_eh_spec_block cp_function_chain->x_eh_spec_block
+
+/* The `__in_chrg' parameter for the current function. Only used for
+ constructors and destructors. */
+
+#define current_in_charge_parm cp_function_chain->x_in_charge_parm
+
+/* The `__vtt_parm' parameter for the current function. Only used for
+ constructors and destructors. */
+
+#define current_vtt_parm cp_function_chain->x_vtt_parm
+
+/* A boolean flag to control whether we need to clean up the return value if a
+ local destructor throws. Only used in functions that return by value a
+ class with a destructor. Which 'tors don't, so we can use the same
+ field as current_vtt_parm. */
+
+#define current_retval_sentinel current_vtt_parm
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a return statement that specifies a return value is seen. */
+
+#define current_function_returns_value cp_function_chain->returns_value
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a return statement with no argument is seen. */
+
+#define current_function_returns_null cp_function_chain->returns_null
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a call to a noreturn function is seen. */
+
+#define current_function_returns_abnormally \
+ cp_function_chain->returns_abnormally
+
+/* Set to 0 at beginning of a function definition, set to 1 if we see an
+ obvious infinite loop. This can have false positives and false
+ negatives, so it should only be used as a heuristic. */
+
+#define current_function_infinite_loop cp_function_chain->infinite_loop
+
+/* Nonzero if we are processing a base initializer. Zero elsewhere. */
+#define in_base_initializer cp_function_chain->x_in_base_initializer
+
+#define in_function_try_handler cp_function_chain->x_in_function_try_handler
+
+/* Expression always returned from function, or error_mark_node
+ otherwise, for use by the automatic named return value optimization. */
+
+#define current_function_return_value (cp_function_chain->x_return_value)
+
+#define current_class_type scope_chain->class_type
+
+#define in_discarded_stmt scope_chain->discarded_stmt
+#define in_consteval_if_p scope_chain->consteval_if_p
+
+/* Nonzero means that this type is being defined. I.e., the left brace
+ starting the definition of this type has been seen. */
+#define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined)
+
+/* Nonzero 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 if NODE is the target for genericization of 'return' stmts
+ in constructors/destructors of targetm.cxx.cdtor_returns_this targets. */
+#define LABEL_DECL_CDTOR(NODE) DECL_LANG_FLAG_2 (LABEL_DECL_CHECK (NODE))
+
+/* Nonzero if this NOP_EXPR is a reinterpret_cast. Such conversions
+ are not constexprs. Other NOP_EXPRs are. */
+#define REINTERPRET_CAST_P(NODE) TREE_LANG_FLAG_0 (NOP_EXPR_CHECK (NODE))
+
+/* 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) \
+ (!TYPE_REF_P (NODE) && !VOID_TYPE_P (NODE) && !FUNC_OR_METHOD_TYPE_P (NODE))
+
+/* 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)))
+
+/* True if this CONSTRUCTOR contains PLACEHOLDER_EXPRs referencing the
+ CONSTRUCTOR's type not nested inside another CONSTRUCTOR marked with
+ CONSTRUCTOR_PLACEHOLDER_BOUNDARY. */
+#define CONSTRUCTOR_PLACEHOLDER_BOUNDARY(NODE) \
+ (TREE_LANG_FLAG_5 (CONSTRUCTOR_CHECK (NODE)))
+
+#define AGGR_INIT_EXPR_SLOT(NODE) TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 2)
+
+/* 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))
+
+/* 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)
+
+/* True iff this represents an lvalue being treated as an rvalue during return
+ or throw as per [class.copy.elision]. */
+#define IMPLICIT_RVALUE_P(NODE) \
+ TREE_LANG_FLAG_3 (TREE_CHECK2 ((NODE), NON_LVALUE_EXPR, STATIC_CAST_EXPR))
+
+/* 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 means that no definition has been seen, even
+ if an initializer has been. */
+#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE))
+
+/* Nonzero means that this class type is a non-standard-layout class. */
+#define CLASSTYPE_NON_STD_LAYOUT(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_std_layout)
+
+/* Nonzero 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 if TYPE is an anonymous union type. */
+#define ANON_UNION_TYPE_P(NODE) \
+ (TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE))
+
+/* For an ANON_AGGR_TYPE_P the single FIELD_DECL it is used with. */
+#define ANON_AGGR_TYPE_FIELD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->typeinfo_var)
+
+/* 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 T is a class type but not a union. */
+#define NON_UNION_CLASS_TYPE_P(T) \
+ (TREE_CODE (T) == RECORD_TYPE && TYPE_LANG_FLAG_5 (T))
+
+/* 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))
+
+/* Nonzero if this type is volatile-qualified. */
+#define RS_TYPE_VOLATILE_P(NODE) \
+ ((rs_type_quals (NODE) & TYPE_QUAL_VOLATILE) != 0)
+
+/* Nonzero means that this type is either complete or being defined, so we
+ can do lookup in it. */
+#define COMPLETE_OR_OPEN_TYPE_P(NODE) \
+ (COMPLETE_TYPE_P (NODE) || (CLASS_TYPE_P (NODE) && TYPE_BEING_DEFINED (NODE)))
+
+/* 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))
+
+/* Returns nonzero iff NODE is a declaration for the global function
+ `main'. */
+#define DECL_MAIN_P(NODE) \
+ (DECL_NAME (NODE) != NULL_TREE && MAIN_NAME_P (DECL_NAME (NODE)) \
+ && flag_hosted)
+
+/* 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 RS_DECL_THREAD_LOCAL_P(NODE) (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)))
+
+#define COND_EXPR_IS_VEC_DELETE(NODE) TREE_LANG_FLAG_0 (COND_EXPR_CHECK (NODE))
+
+/* 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_UNROLL(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 4)
+#define RANGE_FOR_INIT_STMT(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 5)
+#define RANGE_FOR_IVDEP(NODE) TREE_LANG_FLAG_6 (RANGE_FOR_STMT_CHECK (NODE))
+
+#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))
+
+/* Nonzero if NODE is the std namespace. */
+#define DECL_NAMESPACE_STD_P(NODE) ((NODE) == std_node)
+
+/* Whether the namepace is an inline namespace. */
+#define DECL_NAMESPACE_INLINE_P(NODE) \
+ TREE_LANG_FLAG_0 (NAMESPACE_DECL_CHECK (NODE))
+
+#define CP_DECL_CONTEXT(NODE) \
+ (!DECL_FILE_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : global_namespace)
+
+/* Based off of TYPE_UNNAMED_P. */
+#define LAMBDA_TYPE_P(NODE) \
+ (TREE_CODE (NODE) == RECORD_TYPE && TYPE_LINKAGE_IDENTIFIER (NODE) \
+ && IDENTIFIER_LAMBDA_P (TYPE_LINKAGE_IDENTIFIER (NODE)))
+
+/* Macros to make error reporting functions' lives easier. */
+#define TYPE_LINKAGE_IDENTIFIER(NODE) \
+ (TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (NODE)))
+
+/* Identifiers used for lambda types are almost anonymous. Use this
+ spare flag to distinguish them (they also have the anonymous flag). */
+#define IDENTIFIER_LAMBDA_P(NODE) \
+ (IDENTIFIER_NODE_CHECK (NODE)->base.protected_flag)
+
+/* 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)
+
+/* True if the class type TYPE is a literal type. */
+#define CLASSTYPE_LITERAL_P(TYPE) (LANG_TYPE_CLASS_CHECK (TYPE)->is_literal)
+
+/* Nonzero if NODE (a FUNCTION_DECL or TEMPLATE_DECL)
+ is a destructor. */
+#define DECL_DESTRUCTOR_P(NODE) DECL_CXX_DESTRUCTOR_P (NODE)
+
+/* 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 means that NODE (a class type) has a destructor -- but that
+ it has not yet been declared. */
+#define CLASSTYPE_LAZY_DESTRUCTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_destructor)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete
+ object. */
+#define DECL_COMPLETE_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_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_NAME (NODE) == ctor_identifier)
+
+/* 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) 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_NAME (NODE) == dtor_identifier)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
+ object. */
+#define DECL_COMPLETE_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_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_NAME (NODE) == deleting_dtor_identifier)
+
+/* Nonzero if either DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P or
+ DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P is true of NODE. */
+#define DECL_MAYBE_IN_CHARGE_CDTOR_P(NODE) \
+ (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (NODE) \
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (NODE))
+
+/* Nonzero if NODE (a _DECL) is a cloned constructor or
+ destructor. */
+#define DECL_CLONED_FUNCTION_P(NODE) \
+ (DECL_NAME (NODE) && IDENTIFIER_CDTOR_P (DECL_NAME (NODE)) \
+ && !DECL_MAYBE_IN_CHARGE_CDTOR_P (NODE))
+
+/* If DECL_CLONED_FUNCTION_P holds, this is the function that was
+ cloned. */
+#define DECL_CLONED_FUNCTION(NODE) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))->u.fn.u5.cloned_function)
+
+/* Nonzero means that an object of this type cannot 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 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 if this class has a constexpr constructor other than a copy/move
+ constructor. Note that a class can have constexpr constructors for
+ static initialization even if it isn't a literal class. */
+#define TYPE_HAS_CONSTEXPR_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_constexpr_ctor)
+
+/* Nonzero if there is no trivial default constructor for this class. */
+#define TYPE_HAS_COMPLEX_DFLT(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt)
+
+/* [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) \
+ (gnu_vector_type_p (TYPE) || TREE_CODE (TYPE) == ARRAY_TYPE \
+ || (CLASS_TYPE_P (TYPE) && COMPLETE_TYPE_P (TYPE) \
+ && !CLASSTYPE_NON_AGGREGATE (TYPE)))
+
+/* Nonzero for a FIELD_DECL means that this member object type
+ is mutable. */
+#define DECL_MUTABLE_P(NODE) (DECL_LANG_FLAG_0 (FIELD_DECL_CHECK (NODE)))
+
+#if defined ENABLE_TREE_CHECKING
+
+#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 (NODE); \
+ if (!DECL_DECLARES_FUNCTION_P (NODE) || lt->u.base.selector != lds_fn) \
+ 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 != lds_ns) \
+ 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 || lt->u.base.selector != lds_parm) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.parm; \
+ })
+
+#define LANG_DECL_DECOMP_CHECK(NODE) \
+ __extension__({ \
+ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
+ if (!VAR_P (NODE) || lt->u.base.selector != lds_decomp) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.decomp; \
+ })
+
+#else
+
+#define LANG_DECL_MIN_CHECK(NODE) (&DECL_LANG_SPECIFIC (NODE)->u.min)
+
+#define LANG_DECL_FN_CHECK(NODE) (&DECL_LANG_SPECIFIC (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_DECOMP_CHECK(NODE) (&DECL_LANG_SPECIFIC (NODE)->u.decomp)
+
+#endif /* ENABLE_TREE_CHECKING */
+
// Below macros are copied from gcc/c-family/c-common.h
/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */
@@ -181,17 +1631,6 @@
((rs_type_quals (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \
== TYPE_QUAL_CONST)
-/* [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 RS_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) \
@@ -202,8 +1641,898 @@
#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
(TREE_LANG_FLAG_2 (VAR_DECL_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)
+
+/* 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)
+
+#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)
+
+/* 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))
+
// Above macros are copied from gcc/c-family/c-common.h
+// Below macros are copied from gcc/cp/name-lookup.h
+
+/* Lookup walker marking. */
+#define LOOKUP_SEEN_P(NODE) TREE_VISITED (NODE)
+#define LOOKUP_FOUND_P(NODE) \
+ TREE_LANG_FLAG_4 (TREE_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, ENUMERAL_TYPE, \
+ NAMESPACE_DECL))
+
+// Above macros are copied from gcc/cp/name-lookup.h
+
+// Below macros are copied from gcc/cp/name-lookup.cc
+
+/* Create an overload suitable for recording an artificial TYPE_DECL
+ and another decl. We use this machanism to implement the struct
+ stat hack. */
+
+#define STAT_HACK_P(N) ((N) && TREE_CODE (N) == OVERLOAD && OVL_LOOKUP_P (N))
+#define STAT_TYPE_VISIBLE_P(N) TREE_USED (OVERLOAD_CHECK (N))
+#define STAT_TYPE(N) TREE_TYPE (N)
+#define STAT_DECL(N) OVL_FUNCTION (N)
+#define STAT_VISIBLE(N) OVL_CHAIN (N)
+#define MAYBE_STAT_DECL(N) (STAT_HACK_P (N) ? STAT_DECL (N) : N)
+#define MAYBE_STAT_TYPE(N) (STAT_HACK_P (N) ? STAT_TYPE (N) : NULL_TREE)
+
+/* When a STAT_HACK_P is true, OVL_USING_P and OVL_EXPORT_P are valid
+ and apply to the hacked type. */
+
+/* For regular (maybe) overloaded functions, we have OVL_HIDDEN_P.
+ But we also need to indicate hiddenness on implicit type decls
+ (injected friend classes), and (coming soon) decls injected from
+ block-scope externs. It is too awkward to press the existing
+ overload marking for that. If we have a hidden non-function, we
+ always create a STAT_HACK, and use these two markers as needed. */
+#define STAT_TYPE_HIDDEN_P(N) OVL_HIDDEN_P (N)
+#define STAT_DECL_HIDDEN_P(N) OVL_DEDUP_P (N)
+
+/* The binding level currently in effect. */
+
+#define current_binding_level \
+ (*(cfun && cp_function_chain && cp_function_chain->bindings \
+ ? &cp_function_chain->bindings \
+ : &scope_chain->bindings))
+
+// Above macros are copied from gcc/cp/name-lookup.cc
+
+/* 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. */
+ /* The following are ordered, for use by member synthesis fns. */
+ sfk_destructor, /* A destructor. */
+ sfk_constructor, /* A constructor. */
+ sfk_inheriting_constructor, /* An inheriting 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. */
+ /* The following are unordered. */
+ 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_comparison, /* A comparison operator (e.g. ==, <, <=>). */
+ sfk_virtual_destructor /* Used by member synthesis fns. */
+};
+
+/* Places where an lvalue, or modifiable lvalue, may be required.
+ Used to select diagnostic messages in lvalue_error and
+ readonly_error. */
+enum lvalue_use
+{
+ lv_assign,
+ lv_increment,
+ lv_decrement,
+ lv_addressof,
+ lv_asm
+};
+
+/* A class for recording information about access failures (e.g. private
+ fields), so that we can potentially supply a fix-it hint about
+ an accessor (from a context in which the constness of the object
+ is known). */
+
+class access_failure_info
+{
+public:
+ access_failure_info ()
+ : m_was_inaccessible (false), m_basetype_path (NULL_TREE),
+ m_decl (NULL_TREE), m_diag_decl (NULL_TREE)
+ {}
+
+ void record_access_failure (tree basetype_path, tree decl, tree diag_decl);
+
+ bool was_inaccessible_p () const { return m_was_inaccessible; }
+ tree get_decl () const { return m_decl; }
+ tree get_diag_decl () const { return m_diag_decl; }
+ tree get_any_accessor (bool const_p) const;
+ void maybe_suggest_accessor (bool const_p) const;
+ static void add_fixit_hint (rich_location *richloc, tree accessor);
+
+private:
+ bool m_was_inaccessible;
+ tree m_basetype_path;
+ tree m_decl;
+ tree m_diag_decl;
+};
+
+/* 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 representation of a deferred access check. */
+
+struct GTY (()) deferred_access_check
+{
+ /* The base class in which the declaration is referenced. */
+ tree binfo;
+ /* The declaration whose access must be checked. */
+ tree decl;
+ /* The declaration that should be used in the error message. */
+ tree diag_decl;
+ /* The location of this access. */
+ location_t loc;
+};
+
+struct GTY (()) tree_template_info
+{
+ struct tree_base base;
+ tree tmpl;
+ tree args;
+ vec<deferred_access_check, va_gc> *deferred_access_checks;
+};
+
+/* 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. */
+ clk_implicit_rval = 1 << 5 /* An lvalue being treated as an xvalue. */
+};
+
+/* 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;
+
+// forked from gcc/cp/name_lookup.h scope_kind
+
+/* The kinds of scopes we recognize. */
+enum scope_kind
+{
+ sk_block = 0, /* An ordinary block scope. This enumerator must
+ have the value zero because "cp_binding_level"
+ is initialized by using "memset" to set the
+ contents to zero, and the default scope kind
+ is "sk_block". */
+ sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is
+ pseudo in that it is transparent to name lookup
+ activities. */
+ sk_try, /* A try-block. */
+ sk_catch, /* A catch-block. */
+ sk_for, /* The scope of the variable declared in a
+ init-statement. */
+ sk_cond, /* The scope of the variable declared in the condition
+ of an if or switch statement. */
+ sk_function_parms, /* The scope containing function parameters. */
+ sk_class, /* The scope containing the members of a class. */
+ sk_scoped_enum, /* The scope containing the enumerators of a C++11
+ scoped enumeration. */
+ sk_namespace, /* The scope containing the members of a
+ namespace, including the global scope. */
+ sk_template_parms, /* A scope for template parameters. */
+ sk_template_spec, /* Like sk_template_parms, but for an explicit
+ specialization. Since, by definition, an
+ explicit specialization is introduced by
+ "template <>", this scope is always empty. */
+ sk_transaction, /* A synchronized or atomic statement. */
+ sk_omp /* An OpenMP structured block. */
+};
+
+// forked from gcc/cp/cp-tree.h cp_built_in_function
+
+/* BUILT_IN_FRONTEND function codes. */
+enum cp_built_in_function
+{
+ CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+ CP_BUILT_IN_INTEGER_PACK,
+ CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
+ CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
+ CP_BUILT_IN_SOURCE_LOCATION,
+ CP_BUILT_IN_LAST
+};
+
+// forked from gcc/cp/cp-tree.h warning_sentinel
+
+/* RAII sentinel to disable certain warnings during template substitution
+ and elsewhere. */
+
+class warning_sentinel
+{
+public:
+ int &flag;
+ int val;
+ warning_sentinel (int &flag, bool suppress = true) : flag (flag), val (flag)
+ {
+ if (suppress)
+ flag = 0;
+ }
+ ~warning_sentinel () { flag = val; }
+};
+
+// forked from gcc/cp/cp-tree.h uid_sensitive_constexpr_evaluation_checker
+
+/* Used to determine whether uid_sensitive_constexpr_evaluation_p was
+ called and returned true, indicating that we've restricted constexpr
+ evaluation in order to avoid UID generation. We use this to control
+ updates to the fold_cache and cv_cache. */
+
+struct uid_sensitive_constexpr_evaluation_checker
+{
+ const unsigned saved_counter;
+ uid_sensitive_constexpr_evaluation_checker ();
+ bool evaluation_restricted_p () const;
+};
+
+// forked from gcc/cp/cp-tree.h iloc_sentinel
+
+/* RAII sentinel to temporarily override input_location. This will not set
+ input_location to UNKNOWN_LOCATION or BUILTINS_LOCATION. */
+
+class iloc_sentinel
+{
+ location_t saved_loc;
+
+public:
+ iloc_sentinel (location_t loc) : saved_loc (input_location)
+ {
+ if (loc >= RESERVED_LOCATION_COUNT)
+ input_location = loc;
+ }
+ ~iloc_sentinel () { input_location = saved_loc; }
+};
+
+// forked from gcc/cp/cp-tree.h ptrmem_cst
+
+struct GTY (()) ptrmem_cst
+{
+ struct tree_common common;
+ tree member;
+ location_t locus;
+};
+typedef struct ptrmem_cst *ptrmem_cst_t;
+
+// forked from gcc/cp/cp-tree.h named_decl_hash
+
+/* hash traits for declarations. Hashes potential overload sets via
+ DECL_NAME. */
+
+struct named_decl_hash : ggc_remove<tree>
+{
+ typedef tree value_type; /* A DECL or OVERLOAD */
+ typedef tree compare_type; /* An identifier. */
+
+ inline static hashval_t hash (const value_type decl);
+ inline static bool equal (const value_type existing, compare_type candidate);
+
+ static const bool empty_zero_p = true;
+ static inline void mark_empty (value_type &p) { p = NULL_TREE; }
+ static inline bool is_empty (value_type p) { return !p; }
+
+ /* Nothing is deletable. Everything is insertable. */
+ static bool is_deleted (value_type) { return false; }
+ static void mark_deleted (value_type) { gcc_unreachable (); }
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl_selector
+
+/* Discriminator values for lang_decl. */
+
+enum lang_decl_selector
+{
+ lds_min,
+ lds_fn,
+ lds_ns,
+ lds_parm,
+ lds_decomp
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl_base
+
+/* Flags shared by all forms of DECL_LANG_SPECIFIC.
+
+ Some of the flags live here only to make lang_decl_min/fn smaller. Do
+ not make this struct larger than 32 bits. */
+
+struct GTY (()) lang_decl_base
+{
+ ENUM_BITFIELD (lang_decl_selector) selector : 3;
+ unsigned use_template : 2;
+ unsigned not_really_extern : 1; /* var or fn */
+ unsigned initialized_in_class : 1; /* var or fn */
+
+ unsigned threadprivate_or_deleted_p : 1; /* var or fn */
+ /* anticipated_p is no longer used for anticipated_decls (fn, type
+ or template). It is used as DECL_OMP_PRIVATIZED_MEMBER in
+ var. */
+ unsigned anticipated_p : 1;
+ unsigned friend_or_tls : 1; /* var, fn, type or template */
+ unsigned unknown_bound_p : 1; /* var */
+ unsigned odr_used : 1; /* var or fn */
+ unsigned concept_p : 1; /* applies to vars and functions */
+ unsigned var_declared_inline_p : 1; /* var */
+ unsigned dependent_init_p : 1; /* var */
+
+ /* The following apply to VAR, FUNCTION, TYPE, CONCEPT, & NAMESPACE
+ decls. */
+ unsigned module_purview_p : 1; /* in module purview (not GMF) */
+ unsigned module_import_p : 1; /* from an import */
+ unsigned module_entity_p : 1; /* is in the entitity ary &
+ hash. */
+ /* VAR_DECL or FUNCTION_DECL has attached decls. */
+ unsigned module_attached_p : 1;
+
+ /* 12 spare bits. */
+};
+
+/* True for DECL codes which have template info and access. */
+#define LANG_DECL_HAS_MIN(NODE) \
+ (VAR_OR_FUNCTION_DECL_P (NODE) || TREE_CODE (NODE) == FIELD_DECL \
+ || TREE_CODE (NODE) == CONST_DECL || TREE_CODE (NODE) == TYPE_DECL \
+ || TREE_CODE (NODE) == TEMPLATE_DECL || TREE_CODE (NODE) == USING_DECL \
+ || TREE_CODE (NODE) == CONCEPT_DECL)
+
+// forked from gcc/c-family-common.h stmt_tree_s
+
+/* Information about a statement tree. */
+
+struct GTY (()) stmt_tree_s
+{
+ /* A stack of statement lists being collected. */
+ vec<tree, va_gc> *x_cur_stmt_list;
+
+ /* In C++, Nonzero if we should treat statements as full
+ expressions. In particular, this variable is non-zero if at the
+ end of a statement we should destroy any temporaries created
+ during that statement. Similarly, if, at the end of a block, we
+ should destroy any local variables in this block. Normally, this
+ variable is nonzero, since those are the normal semantics of
+ C++.
+
+ This flag has no effect in C. */
+ int stmts_are_full_exprs_p;
+};
+
+// forked from gcc/c-family-common.h stmt_tree_s
+
+typedef struct stmt_tree_s *stmt_tree;
+
+// forked from gcc/c-family-common.h c_language_function
+
+/* Global state pertinent to the current function. Some C dialects
+ extend this structure with additional fields. */
+
+struct GTY (()) c_language_function
+{
+ /* While we are parsing the function, this contains information
+ about the statement-tree that we are building. */
+ struct stmt_tree_s x_stmt_tree;
+
+ /* Vector of locally defined typedefs, for
+ -Wunused-local-typedefs. */
+ vec<tree, va_gc> *local_typedefs;
+};
+
+// forked from gcc/cp/cp-tree.h omp_declare_target_attr
+
+struct GTY (()) omp_declare_target_attr
+{
+ bool attr_syntax;
+};
+
+// forked from gcc/cp/name-lookup.h cxx_binding
+
+/* Datatype that represents binding established by a declaration between
+ a name and a C++ entity. */
+struct GTY (()) cxx_binding
+{
+ /* Link to chain together various bindings for this name. */
+ cxx_binding *previous;
+ /* The non-type entity this name is bound to. */
+ tree value;
+ /* The type entity this name is bound to. */
+ tree type;
+
+ bool value_is_inherited : 1;
+ bool is_local : 1;
+ bool type_is_hidden : 1;
+};
+
+// forked from gcc/cp/name-lookup.h cxx_saved_binding
+
+/* Datatype used to temporarily save C++ bindings (for implicit
+ instantiations purposes and like). Implemented in decl.cc. */
+struct GTY (()) cxx_saved_binding
+{
+ /* The name of the current binding. */
+ tree identifier;
+ /* The binding we're saving. */
+ cxx_binding *binding;
+ tree real_type_value;
+};
+
+// forked from gcc/cp/cp-tree.h saved_scope
+
+/* Global state. */
+
+struct GTY (()) saved_scope
+{
+ vec<cxx_saved_binding, va_gc> *old_bindings;
+ tree old_namespace;
+ vec<tree, va_gc> *decl_ns_list;
+ tree class_name;
+ tree class_type;
+ tree access_specifier;
+ tree function_decl;
+ vec<tree, va_gc> *lang_base;
+ tree lang_name;
+ tree template_parms;
+ tree x_saved_tree;
+
+ /* Only used for uses of this in trailing return type. */
+ tree x_current_class_ptr;
+ tree x_current_class_ref;
+
+ int x_processing_template_decl;
+ int x_processing_specialization;
+ int x_processing_constraint;
+ int suppress_location_wrappers;
+ BOOL_BITFIELD x_processing_explicit_instantiation : 1;
+ BOOL_BITFIELD need_pop_function_context : 1;
+
+ /* Nonzero if we are parsing the discarded statement of a constexpr
+ if-statement. */
+ BOOL_BITFIELD discarded_stmt : 1;
+ /* Nonzero if we are parsing or instantiating the compound-statement
+ of consteval if statement. Also set while processing an immediate
+ invocation. */
+ BOOL_BITFIELD consteval_if_p : 1;
+
+ int unevaluated_operand;
+ int inhibit_evaluation_warnings;
+ int noexcept_operand;
+ int ref_temp_count;
+
+ struct stmt_tree_s x_stmt_tree;
+
+ hash_map<tree, tree> *GTY ((skip)) x_local_specializations;
+ vec<omp_declare_target_attr, va_gc> *omp_declare_target_attribute;
+
+ struct saved_scope *prev;
+};
+
+extern GTY (()) struct saved_scope *scope_chain;
+
+// forked from gcc/cp/cp-tree.h named_label_hash
+
+struct named_label_entry; /* Defined in decl.cc. */
+
+struct named_label_hash : ggc_remove<named_label_entry *>
+{
+ typedef named_label_entry *value_type;
+ typedef tree compare_type; /* An identifier. */
+
+ inline static hashval_t hash (value_type);
+ inline static bool equal (const value_type, compare_type);
+
+ static const bool empty_zero_p = true;
+ inline static void mark_empty (value_type &p) { p = NULL; }
+ inline static bool is_empty (value_type p) { return !p; }
+
+ /* Nothing is deletable. Everything is insertable. */
+ inline static bool is_deleted (value_type) { return false; }
+ inline static void mark_deleted (value_type) { gcc_unreachable (); }
+};
+
+// forked from gcc/cp/cp-tree.h
+
+/* Global state pertinent to the current function. */
+
+struct GTY (()) language_function
+{
+ struct c_language_function base;
+
+ tree x_cdtor_label;
+ tree x_current_class_ptr;
+ tree x_current_class_ref;
+ tree x_eh_spec_block;
+ tree x_in_charge_parm;
+ tree x_vtt_parm;
+ tree x_return_value;
+
+ BOOL_BITFIELD returns_value : 1;
+ BOOL_BITFIELD returns_null : 1;
+ BOOL_BITFIELD returns_abnormally : 1;
+ BOOL_BITFIELD infinite_loop : 1;
+ BOOL_BITFIELD x_in_function_try_handler : 1;
+ BOOL_BITFIELD x_in_base_initializer : 1;
+
+ /* True if this function can throw an exception. */
+ BOOL_BITFIELD can_throw : 1;
+
+ BOOL_BITFIELD invalid_constexpr : 1;
+ BOOL_BITFIELD throwing_cleanup : 1;
+
+ hash_table<named_label_hash> *x_named_labels;
+
+ /* Tracking possibly infinite loops. This is a vec<tree> only because
+ vec<bool> doesn't work with gtype. */
+ vec<tree, va_gc> *infinite_loops;
+};
+
+// forked from gcc/c-family/c-common.h ref_operator
+
+/* The various name of operator that appears in error messages. */
+enum ref_operator
+{
+ /* NULL */
+ RO_NULL,
+ /* array indexing */
+ RO_ARRAY_INDEXING,
+ /* unary * */
+ RO_UNARY_STAR,
+ /* -> */
+ RO_ARROW,
+ /* implicit conversion */
+ RO_IMPLICIT_CONVERSION,
+ /* ->* */
+ RO_ARROW_STAR
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl_min
+
+/* DECL_LANG_SPECIFIC for the above codes. */
+
+struct GTY (()) lang_decl_min
+{
+ struct lang_decl_base base; /* 32-bits. */
+
+ /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
+ THUNK_ALIAS.
+ In a FUNCTION_DECL for which DECL_THUNK_P does not hold,
+ VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is
+ DECL_TEMPLATE_INFO. */
+ tree template_info;
+
+ /* In a DECL_THUNK_P FUNCTION_DECL, this is THUNK_VIRTUAL_OFFSET.
+ In a lambda-capture proxy VAR_DECL, this is DECL_CAPTURED_VARIABLE.
+ In a function-scope TREE_STATIC VAR_DECL or IMPLICIT_TYPEDEF_P TYPE_DECL,
+ this is DECL_DISCRIMINATOR.
+ In a DECL_LOCAL_DECL_P decl, this is the namespace decl it aliases.
+ Otherwise, in a class-scope DECL, this is DECL_ACCESS. */
+ tree access;
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl_fn
+
+/* Additional DECL_LANG_SPECIFIC information for functions. */
+
+struct GTY (()) lang_decl_fn
+{
+ struct lang_decl_min min;
+
+ /* In a overloaded operator, this is the compressed operator code. */
+ unsigned ovl_op_code : 6;
+ unsigned global_ctor_p : 1;
+ unsigned global_dtor_p : 1;
+
+ unsigned static_function : 1;
+ unsigned pure_virtual : 1;
+ unsigned defaulted_p : 1;
+ unsigned has_in_charge_parm_p : 1;
+ unsigned has_vtt_parm_p : 1;
+ unsigned pending_inline_p : 1;
+ unsigned nonconverting : 1;
+ unsigned thunk_p : 1;
+
+ unsigned this_thunk_p : 1;
+ unsigned omp_declare_reduction_p : 1;
+ unsigned has_dependent_explicit_spec_p : 1;
+ unsigned immediate_fn_p : 1;
+ unsigned maybe_deleted : 1;
+ unsigned coroutine_p : 1;
+ unsigned implicit_constexpr : 1;
+
+ unsigned spare : 9;
+
+ /* 32-bits padding on 64-bit host. */
+
+ /* For a non-thunk function decl, this is a tree list of
+ friendly classes. For a thunk function decl, it is the
+ thunked to function decl. */
+ tree befriending_classes;
+
+ /* For a virtual FUNCTION_DECL for which
+ DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both
+ this pointer and result pointer adjusting thunks are
+ chained here. This pointer thunks to return pointer thunks
+ will be chained on the return pointer thunk.
+ For a DECL_CONSTUCTOR_P FUNCTION_DECL, this is the base from
+ whence we inherit. Otherwise, it is the class in which a
+ (namespace-scope) friend is defined (if any). */
+ tree context;
+
+ union lang_decl_u5
+ {
+ /* In a non-thunk FUNCTION_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;
+ tree GTY ((tag ("0"))) saved_auto_return_type;
+ } GTY ((desc ("%1.pending_inline_p"))) u;
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl_ns
+
+/* DECL_LANG_SPECIFIC for namespaces. */
+
+struct GTY (()) lang_decl_ns
+{
+ struct lang_decl_base base; /* 32 bits. */
+
+ /* Inline children. Needs to be va_gc, because of PCH. */
+ vec<tree, va_gc> *inlinees;
+
+ /* Hash table of bound decls. It'd be nice to have this inline, but
+ as the hash_map has a dtor, we can't then put this struct into a
+ union (until moving to c++11). */
+ hash_table<named_decl_hash> *bindings;
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl_parm
+
+/* DECL_LANG_SPECIFIC for parameters. */
+
+struct GTY (()) lang_decl_parm
+{
+ struct lang_decl_base base; /* 32 bits. */
+ int level;
+ int index;
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl_decomp
+
+/* Additional DECL_LANG_SPECIFIC information for structured bindings. */
+
+struct GTY (()) lang_decl_decomp
+{
+ struct lang_decl_min min;
+ /* The artificial underlying "e" variable of the structured binding
+ variable. */
+ tree base;
+};
+
+// forked from gcc/cp/cp-tree.h lang_decl
+
+/* 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
+ {
+ /* Nothing of only the base type exists. */
+ struct lang_decl_base GTY ((default)) base;
+ struct lang_decl_min GTY ((tag ("lds_min"))) min;
+ struct lang_decl_fn GTY ((tag ("lds_fn"))) fn;
+ struct lang_decl_ns GTY ((tag ("lds_ns"))) ns;
+ struct lang_decl_parm GTY ((tag ("lds_parm"))) parm;
+ struct lang_decl_decomp GTY ((tag ("lds_decomp"))) decomp;
+ } u;
+};
+
+// forked from gcc/c-family/c-common.h c_fileinfo
+
+/* Information recorded about each file examined during compilation. */
+
+struct c_fileinfo
+{
+ int time; /* Time spent in the file. */
+
+ /* Flags used only by C++.
+ INTERFACE_ONLY nonzero means that we are in an "interface" section
+ of the compiler. INTERFACE_UNKNOWN nonzero means we cannot trust
+ the value of INTERFACE_ONLY. If INTERFACE_UNKNOWN is zero and
+ INTERFACE_ONLY is zero, it means that we are responsible for
+ exporting definitions that others might need. */
+ short interface_only;
+ short interface_unknown;
+};
+
+// forked from gcc/c-family/c-common.h c_common_identifier
+
+/* Identifier part common to the C front ends. Inherits from
+ tree_identifier, despite appearances. */
+struct GTY (()) c_common_identifier
+{
+ struct tree_common common;
+ struct cpp_hashnode node; // from cpplib.h
+};
+
+// forked from gcc/cp/cp-tree.h lang_identifier
+
+/* Language-dependent contents of an identifier. */
+
+struct GTY (()) lang_identifier
+{
+ struct c_common_identifier c_common;
+ cxx_binding *bindings;
+};
+
+// forked from gcc/cp/cp-tree.h tree_overload
+
+/* OVL_HIDDEN_P nodes come before other nodes. */
+
+struct GTY (()) tree_overload
+{
+ struct tree_common common;
+ tree function;
+};
+
+// forked from gcc/cp/cp-tree.h ovl_iterator
+
+class ovl_iterator
+{
+ tree ovl;
+ const bool allow_inner; /* Only used when checking. */
+
+public:
+ explicit ovl_iterator (tree o, bool allow = false)
+ : ovl (o), allow_inner (allow)
+ {}
+
+public:
+ operator bool () const { return ovl; }
+ ovl_iterator &operator++ ()
+ {
+ ovl = TREE_CODE (ovl) != OVERLOAD ? NULL_TREE : OVL_CHAIN (ovl);
+ return *this;
+ }
+ tree operator* () const
+ {
+ tree fn = TREE_CODE (ovl) != OVERLOAD ? ovl : OVL_FUNCTION (ovl);
+
+ /* Check this is not an unexpected 2-dimensional overload. */
+ gcc_checking_assert (allow_inner || TREE_CODE (fn) != OVERLOAD);
+
+ return fn;
+ }
+ bool operator== (const ovl_iterator &o) const { return ovl == o.ovl; }
+ tree get_using () const
+ {
+ gcc_checking_assert (using_p ());
+ return ovl;
+ }
+
+public:
+ /* Whether this overload was introduced by a using decl. */
+ bool using_p () const
+ {
+ return (TREE_CODE (ovl) == USING_DECL
+ || (TREE_CODE (ovl) == OVERLOAD && OVL_USING_P (ovl)));
+ }
+ /* Whether this using is being exported. */
+ bool exporting_p () const { return OVL_EXPORT_P (get_using ()); }
+
+ bool hidden_p () const
+ {
+ return TREE_CODE (ovl) == OVERLOAD && OVL_HIDDEN_P (ovl);
+ }
+
+public:
+ tree remove_node (tree head) { return remove_node (head, ovl); }
+ tree reveal_node (tree head) { return reveal_node (head, ovl); }
+
+protected:
+ /* If we have a nested overload, point at the inner overload and
+ return the next link on the outer one. */
+ tree maybe_push ()
+ {
+ tree r = NULL_TREE;
+
+ if (ovl && TREE_CODE (ovl) == OVERLOAD && OVL_NESTED_P (ovl))
+ {
+ r = OVL_CHAIN (ovl);
+ ovl = OVL_FUNCTION (ovl);
+ }
+ return r;
+ }
+ /* Restore an outer nested overload. */
+ void pop (tree outer)
+ {
+ gcc_checking_assert (!ovl);
+ ovl = outer;
+ }
+
+private:
+ /* We make these static functions to avoid the address of the
+ iterator escaping the local context. */
+ static tree remove_node (tree head, tree node);
+ static tree reveal_node (tree ovl, tree node);
+};
+
+// forked from gcc/cp/cp-tree.h lkp_iterator
+
+/* Iterator over a (potentially) 2 dimensional overload, which is
+ produced by name lookup. */
+
+class lkp_iterator : public ovl_iterator
+{
+ typedef ovl_iterator parent;
+
+ tree outer;
+
+public:
+ explicit lkp_iterator (tree o) : parent (o, true), outer (maybe_push ()) {}
+
+public:
+ lkp_iterator &operator++ ()
+ {
+ bool repush = !outer;
+
+ if (!parent::operator++ () && !repush)
+ {
+ pop (outer);
+ repush = true;
+ }
+
+ if (repush)
+ outer = maybe_push ();
+
+ return *this;
+ }
+};
+
// forked from gcc/cp/cp-tree.h treee_pair_s
struct GTY (()) tree_pair_s
@@ -325,6 +2654,80 @@ struct GTY (()) lang_type
namespace Rust {
+// forked from gcc/cp/cp-tree.h cp_ref_qualifier
+
+enum rs_ref_qualifier
+{
+ REF_QUAL_NONE = 0,
+ REF_QUAL_LVALUE = 1,
+ REF_QUAL_RVALUE = 2
+};
+
+// forked from gcc/cp/cp-tree.h tsubst_flags
+
+/* 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) */
+ tf_norm = 1 << 11, /* Build diagnostic information during
+ constraint normalization. */
+ /* Convenient substitution flags combinations. */
+ tf_warning_or_error = tf_warning | tf_error
+};
+
+// forked from gcc/cp/cp-tree.h cp_identifier_kind
+
+/* Kinds of identifiers. Values are carefully chosen. */
+enum cp_identifier_kind
+{
+ cik_normal = 0, /* Not a special identifier. */
+ cik_keyword = 1, /* A keyword. */
+ cik_ctor = 2, /* Constructor (in-chg, complete or base). */
+ cik_dtor = 3, /* Destructor (in-chg, deleting, complete or
+ base). */
+ cik_simple_op = 4, /* Non-assignment operator name. */
+ cik_assign_op = 5, /* An assignment operator name. */
+ cik_conv_op = 6, /* Conversion operator name. */
+ cik_reserved_for_udlit = 7, /* Not yet in use */
+ cik_max
+};
+
+// forked from gcc/cp/cp-tree.h tag_types
+
+/* 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 :: */
+};
+
// forked from gcc/cp/cp-tree.h tsubst_flags_t
/* This type is used for parameters and variables which hold
@@ -375,6 +2778,18 @@ enum rs_built_in_function
RS_BUILT_IN_LAST
};
+// forked from gcc/cp/cp-tree.h compare_bounds_t
+
+/* in typeck.cc */
+/* Says how we should behave when comparing two arrays one of which
+ has unknown bounds. */
+enum compare_bounds_t
+{
+ bounds_none,
+ bounds_either,
+ bounds_first
+};
+
extern tree
convert_to_void (tree expr, impl_conv_void implicit);
@@ -411,8 +2826,8 @@ mark_use (tree expr, bool rvalue_p, bool read_p, location_t loc,
// function with no library fallback (or any of its bits, such as in
// a conversion to bool).
extern tree
-mark_rvalue_use (tree e, location_t loc /* = UNKNOWN_LOCATION */,
- bool reject_builtin /* = true */);
+mark_rvalue_use (tree, location_t = UNKNOWN_LOCATION,
+ bool reject_builtin = true);
// Called whenever an expression is used in an lvalue context.
extern tree
@@ -475,8 +2890,271 @@ extern bool var_in_maybe_constexpr_fn (tree);
extern int
rs_type_quals (const_tree type);
+inline bool type_unknown_p (const_tree);
+
extern bool decl_maybe_constant_var_p (tree);
+extern void
+init_modules ();
+
+extern bool var_in_constexpr_fn (tree);
+
+inline tree ovl_first (tree) ATTRIBUTE_PURE;
+
+inline bool type_unknown_p (const_tree);
+
+extern tree
+lookup_add (tree fns, tree lookup);
+
+extern tree
+ovl_make (tree fn, tree next = NULL_TREE);
+
+extern int is_overloaded_fn (tree) ATTRIBUTE_PURE;
+
+extern bool maybe_add_lang_type_raw (tree);
+
+extern rs_ref_qualifier type_memfn_rqual (const_tree);
+
+extern bool builtin_pack_fn_p (tree);
+
+extern tree make_conv_op_name (tree);
+
+extern int type_memfn_quals (const_tree);
+
+struct c_fileinfo *
+get_fileinfo (const char *);
+
+extern tree
+cxx_make_type (enum tree_code CXX_MEM_STAT_INFO);
+
+extern tree
+build_cplus_array_type (tree, tree, int is_dep = -1);
+
+extern bool is_byte_access_type (tree);
+
+extern bool
+comptypes (tree, tree, int);
+
+extern tree canonical_eh_spec (tree);
+
+extern int cp_tree_operand_length (const_tree);
+
+extern bool rs_tree_equal (tree, tree);
+
+extern bool compparms (const_tree, const_tree);
+
+extern tree
+rs_build_qualified_type_real (tree, int, tsubst_flags_t);
+#define rs_build_qualified_type(TYPE, QUALS) \
+ rs_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error)
+extern bool cv_qualified_p (const_tree);
+
+extern bool similar_type_p (tree, tree);
+
+extern bool rs_tree_equal (tree, tree);
+
+extern bool
+vector_targets_convertible_p (const_tree t1, const_tree t2);
+
+extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree);
+
+extern bool comp_ptr_ttypes_const (tree, tree, compare_bounds_t);
+
+extern tree
+get_class_binding_direct (tree, tree, bool want_type = false);
+
+extern tree skip_artificial_parms_for (const_tree, tree);
+
+extern void
+lang_check_failed (const char *, int,
+ const char *) ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
+
+extern tree default_init_uninitialized_part (tree);
+
+extern bool type_has_non_user_provided_default_constructor (tree);
+
+extern bool default_ctor_p (const_tree);
+
+extern bool user_provided_p (tree);
+
+extern bool sufficient_parms_p (const_tree);
+
+extern tree next_initializable_field (tree);
+
+extern tree in_class_defaulted_default_constructor (tree);
+
+extern bool is_instantiation_of_constexpr (tree);
+
+extern bool
+check_for_uninitialized_const_var (tree, bool, tsubst_flags_t);
+
+extern bool reduced_constant_expression_p (tree);
+
+extern tree cv_unqualified (tree);
+
+extern tree cp_get_callee (tree);
+extern tree rs_get_callee_fndecl_nofold (tree);
+
+extern bool is_nondependent_static_init_expression (tree);
+
+extern tree build_nop (tree, tree);
+
+extern bool scalarish_type_p (const_tree);
+
+extern tree is_bitfield_expr_with_lowered_type (const_tree);
+
+extern tree convert_bitfield_to_declared_type (tree);
+
+extern tree
+cp_fold_maybe_rvalue (tree, bool);
+
+extern tree maybe_undo_parenthesized_ref (tree);
+
+extern tree
+fold_offsetof (tree, tree = size_type_node, tree_code ctx = ERROR_MARK);
+
+extern tree cp_truthvalue_conversion (tree, tsubst_flags_t);
+
+extern tree
+fold_non_dependent_expr (tree, tsubst_flags_t = tf_warning_or_error,
+ bool = false, tree = NULL_TREE);
+
+extern int char_type_p (tree);
+
+extern bool instantiation_dependent_expression_p (tree);
+
+extern bool type_has_nontrivial_copy_init (const_tree);
+
+extern tree build_local_temp (tree);
+
+extern bool is_normal_capture_proxy (tree);
+
+extern bool reject_gcc_builtin (const_tree, location_t = UNKNOWN_LOCATION);
+
+extern tree resolve_nondeduced_context (tree, tsubst_flags_t);
+
+extern void cxx_incomplete_type_diagnostic (location_t, const_tree, const_tree,
+ diagnostic_t);
+
+extern void cxx_incomplete_type_error (location_t, const_tree, const_tree);
+
+extern bool invalid_nonstatic_memfn_p (location_t, tree, tsubst_flags_t);
+
+extern bool really_overloaded_fn (tree) ATTRIBUTE_PURE;
+
+extern tree resolve_nondeduced_context_or_error (tree, tsubst_flags_t);
+
+extern tree instantiate_non_dependent_or_null (tree);
+
+extern void cxx_incomplete_type_inform (const_tree);
+
+extern tree strip_top_quals (tree);
+
+extern bool undeduced_auto_decl (tree);
+
+extern bool require_deduced_type (tree, tsubst_flags_t = tf_warning_or_error);
+
+extern bool decl_constant_var_p (tree);
+
+extern tree build_new_constexpr_heap_type (tree, tree, tree);
+
+extern bool is_empty_field (tree);
+
+extern bool
+in_immediate_context ();
+
+extern tree cp_get_callee_fndecl_nofold (tree);
+
+extern bool
+cxx_mark_addressable (tree, bool = false);
+
+extern tree fold_builtin_source_location (location_t);
+
+extern tree build_address (tree);
+
+extern bool bitfield_p (const_tree);
+
+extern tree rvalue (tree);
+
+extern bool glvalue_p (const_tree);
+
+extern cp_lvalue_kind lvalue_kind (const_tree);
+
+extern tree
+decl_constant_value (tree, bool);
+
+extern tree lookup_enumerator (tree, tree);
+
+extern int
+is_class_type (tree, int);
+
+extern tree braced_lists_to_strings (tree, tree);
+
+extern tree
+fold_builtin_is_pointer_inverconvertible_with_class (location_t, int, tree *);
+
+extern bool layout_compatible_type_p (tree, tree);
+
+extern tree finish_underlying_type (tree);
+
+extern tree
+c_common_type_for_mode (machine_mode, int);
+
+extern bool std_layout_type_p (const_tree);
+
+extern tree complete_type (tree);
+
+extern tree complete_type_or_else (tree, tree);
+
+extern void note_failed_type_completion_for_satisfaction (tree);
+
+extern tree complete_type_or_maybe_complain (tree, tree, tsubst_flags_t);
+
+extern bool
+next_common_initial_seqence (tree &, tree &);
+
+extern bool null_member_pointer_value_p (tree);
+
+extern tree
+fold_builtin_is_corresponding_member (location_t, int, tree *);
+
+extern tree cp_fold_rvalue (tree);
+
+extern tree
+maybe_constant_value (tree, tree = NULL_TREE, bool = false);
+
+extern tree lvalue_type (tree);
+
+extern void lvalue_error (location_t, enum lvalue_use);
+
+extern tree
+cp_fold_maybe_rvalue (tree, bool);
+
+extern tree get_first_fn (tree) ATTRIBUTE_PURE;
+
+extern void explain_non_literal_class (tree);
+
+extern bool reference_related_p (tree, tree);
+
+extern bool ordinary_char_type_p (tree);
+
+extern bool array_string_literal_compatible_p (tree, tree);
+
+// forked from gcc/cp/cp-tree.h
+
+enum
+{
+ ce_derived,
+ ce_type,
+ ce_normal,
+ ce_exact
+};
+
+extern tree
+rs_build_qualified_type_real (tree, int, tsubst_flags_t);
+#define rs_build_qualified_type(TYPE, QUALS) \
+ rs_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error)
+
extern tree
rs_walk_subtrees (tree *, int *, walk_tree_fn, void *, hash_set<tree> *);
#define rs_walk_tree(tp, func, data, pset) \
@@ -503,6 +3181,206 @@ rs_expr_loc_or_input_loc (const_tree t)
return rs_expr_loc_or_loc (t, input_location);
}
+// forked from gcc/cp/cp-tree.h type_unknown_p
+
+inline bool
+type_unknown_p (const_tree expr)
+{
+ return TREE_TYPE (expr) == unknown_type_node;
+}
+
+// forked from gcc/cp/cp-tree.h ovl_first
+
+/* Inline bodies. */
+
+inline tree
+ovl_first (tree node)
+{
+ while (TREE_CODE (node) == OVERLOAD)
+ node = OVL_FUNCTION (node);
+ return node;
+}
+
+// forked from gcc/cp/cp-tree.h type_of_this_parm
+
+/* Return the type of the `this' parameter of FNTYPE. */
+
+inline tree
+type_of_this_parm (const_tree fntype)
+{
+ function_args_iterator iter;
+ gcc_assert (TREE_CODE (fntype) == METHOD_TYPE);
+ function_args_iter_init (&iter, fntype);
+ return function_args_iter_cond (&iter);
+}
+
+// forked from gcc/cp/cp-tree.h class_of_this_parm
+
+/* Return the class of the `this' parameter of FNTYPE. */
+
+inline tree
+class_of_this_parm (const_tree fntype)
+{
+ return TREE_TYPE (type_of_this_parm (fntype));
+}
+
+// forked from gcc/cp/cp-tree.h identifier_p
+
+/* Return a typed pointer version of T if it designates a
+ C++ front-end identifier. */
+inline lang_identifier *
+identifier_p (tree t)
+{
+ if (TREE_CODE (t) == IDENTIFIER_NODE)
+ return (lang_identifier *) t;
+ return NULL;
+}
+
+// forked from gcc/c-family/c-common.h gnu_vector_type_p
+
+/* Return true if TYPE is a vector type that should be subject to the GNU
+ vector extensions (as opposed to a vector type that is used only for
+ the purposes of defining target-specific built-in functions). */
+
+inline bool
+gnu_vector_type_p (const_tree type)
+{
+ return TREE_CODE (type) == VECTOR_TYPE && !TYPE_INDIVISIBLE_P (type);
+}
+
+extern vec<tree, va_gc> *
+make_tree_vector (void);
+
+extern void
+release_tree_vector (vec<tree, va_gc> *);
+
+/* Simplified unique_ptr clone to release a tree vec on exit. */
+
+class releasing_vec
+{
+public:
+ typedef vec<tree, va_gc> vec_t;
+
+ releasing_vec (vec_t *v) : v (v) {}
+ releasing_vec () : v (make_tree_vector ()) {}
+
+ /* Copy ops are deliberately declared but not defined,
+ copies must always be elided. */
+ releasing_vec (const releasing_vec &);
+ releasing_vec &operator= (const releasing_vec &);
+
+ vec_t &operator* () const { return *v; }
+ vec_t *operator-> () const { return v; }
+ vec_t *get () const { return v; }
+ operator vec_t * () const { return v; }
+ vec_t **operator& () { return &v; }
+
+ /* Breaks pointer/value consistency for convenience. This takes ptrdiff_t
+ rather than unsigned to avoid ambiguity with the built-in operator[]
+ (bootstrap/91828). */
+ tree &operator[] (ptrdiff_t i) const { return (*v)[i]; }
+
+ tree *begin () { return ::begin (v); }
+ tree *end () { return ::end (v); }
+
+ void release ()
+ {
+ release_tree_vector (v);
+ v = NULL;
+ }
+
+ ~releasing_vec () { release_tree_vector (v); }
+
+private:
+ vec_t *v;
+};
+
+inline tree *
+vec_safe_push (releasing_vec &r, const tree &t CXX_MEM_STAT_INFO)
+{
+ return vec_safe_push (*&r, t PASS_MEM_STAT);
+}
+
+inline bool
+vec_safe_reserve (releasing_vec &r, unsigned n,
+ bool e = false CXX_MEM_STAT_INFO)
+{
+ return vec_safe_reserve (*&r, n, e PASS_MEM_STAT);
+}
+inline unsigned
+vec_safe_length (releasing_vec &r)
+{
+ return r->length ();
+}
+inline void
+vec_safe_splice (releasing_vec &r, vec<tree, va_gc> *p CXX_MEM_STAT_INFO)
+{
+ vec_safe_splice (*&r, p PASS_MEM_STAT);
+}
+
+inline bool
+null_node_p (const_tree expr)
+{
+ STRIP_ANY_LOCATION_WRAPPER (expr);
+ return expr == null_node;
+}
+
+inline void
+cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
+ diagnostic_t diag_kind)
+{
+ cxx_incomplete_type_diagnostic (rs_expr_loc_or_input_loc (value), value, type,
+ diag_kind);
+}
+
+inline void
+cxx_incomplete_type_error (const_tree value, const_tree type)
+{
+ cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+}
+
+extern location_t
+location_of (tree t);
+
+/* Helpers for IMPLICIT_RVALUE_P to look through automatic dereference. */
+
+inline bool
+implicit_rvalue_p (const_tree t)
+{
+ if (REFERENCE_REF_P (t))
+ t = TREE_OPERAND (t, 0);
+ return ((TREE_CODE (t) == NON_LVALUE_EXPR) && IMPLICIT_RVALUE_P (t));
+}
+inline tree
+set_implicit_rvalue_p (tree ot)
+{
+ tree t = ot;
+ if (REFERENCE_REF_P (t))
+ t = TREE_OPERAND (t, 0);
+ IMPLICIT_RVALUE_P (t) = 1;
+ return ot;
+}
+
+namespace Compile {
+extern tree
+maybe_constant_init (tree, tree = NULL_TREE, bool = false);
+
+extern void
+explain_invalid_constexpr_fn (tree fun);
+
+extern bool potential_constant_expression (tree);
+
+extern bool
+literal_type_p (tree t);
+
+extern bool
+maybe_constexpr_fn (tree t);
+
+extern tree
+fold_non_dependent_init (tree, tsubst_flags_t = tf_warning_or_error,
+ bool = false, tree = NULL_TREE);
+} // namespace Compile
+
} // namespace Rust
#endif // RUST_TREE