diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-25 14:35:59 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-25 14:35:59 +0000 |
commit | 1416b85322cd9cd74c7a79e3270bb334ceb3a44c (patch) | |
tree | e6d175fcec2b7f252b82a163460768deb7db2f03 /gcc/rust/backend/rust-tree.h | |
parent | 5b3c4be73fb72cb87d9a135415ed421a0808ff3b (diff) | |
parent | 43b7dd91fb0df9cdb7708581089bd3cd36f14a43 (diff) | |
download | gcc-1416b85322cd9cd74c7a79e3270bb334ceb3a44c.zip gcc-1416b85322cd9cd74c7a79e3270bb334ceb3a44c.tar.gz gcc-1416b85322cd9cd74c7a79e3270bb334ceb3a44c.tar.bz2 |
Merge #1499
1499: Constant folding in gccrs: port over rest of the code from CP frontend r=philberty a=abbasfaisal
Co-authored-by: Faisal Abbas <90.abbasfaisal@gmail.com>
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend/rust-tree.h')
-rw-r--r-- | gcc/rust/backend/rust-tree.h | 2904 |
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__); \ + <->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__); \ + <->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__); \ + <->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__); \ + <->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__); \ + <->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 |