*/ #define EXPR_STMT_STMT_EXPR_RESULT(NODE) \ TREE_LANG_FLAG_0 (EXPR_STMT_CHECK (NODE)) /* Nonzero if this statement-expression does not have an associated scope. */ #define STMT_EXPR_NO_SCOPE(NODE) \ TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE)) #define COND_EXPR_IS_VEC_DELETE(NODE) \ TREE_LANG_FLAG_0 (COND_EXPR_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 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 nonzero iff NODE is a declaration for the global function `main'. */ #define DECL_MAIN_ANY_P(NODE) \ (DECL_EXTERN_C_FUNCTION_P (NODE) \ && DECL_NAME (NODE) != NULL_TREE \ && MAIN_NAME_P (DECL_NAME (NODE))) /* Nonzero iff NODE is a declaration for `int main', or we are hosted. */ #define DECL_MAIN_FREESTANDING_P(NODE) \ (DECL_MAIN_ANY_P(NODE) \ && (flag_hosted \ || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (NODE))) \ == integer_type_node)) /* Nonzero iff NODE is a declaration for `main', and we are hosted. */ #define DECL_MAIN_P(NODE) (DECL_MAIN_ANY_P(NODE) && flag_hosted) /* 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)) /* 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)) /* OVL_HIDDEN_P nodes come before other nodes. */ struct GTY(()) tree_overload { struct tree_common common; tree function; }; /* Iterator for a 1 dimensional overload. Permits iterating over the outer level of a 2-d overload when explicitly enabled. */ 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); }; /* Treat a tree as a range of ovl_iterator, e.g. for (tree f : ovl_range (fns)) { ... } */ class ovl_range { tree t; bool allow; public: explicit ovl_range (tree t, bool allow = false): t(t), allow(allow) { } ovl_iterator begin() { return ovl_iterator (t, allow); } ovl_iterator end() { return ovl_iterator (NULL_TREE, allow); } }; /* 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; } }; /* Treat a tree as a range of lkp_iterator, e.g. for (tree f : lkp_range (fns)) { ... } */ class lkp_range { tree t; public: lkp_range (tree t): t(t) { } lkp_iterator begin() { return lkp_iterator (t); } lkp_iterator end() { return lkp_iterator (NULL_TREE); } }; /* hash traits for declarations. Hashes potential overload sets via DECL_NAME. */ struct named_decl_hash : ggc_remove { 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 (); } }; /* Simplified unique_ptr clone to release a tree vec on exit. */ class releasing_vec { public: typedef vec 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; }; /* Forwarding functions for vec_safe_* that might reallocate. */ 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 *p CXX_MEM_STAT_INFO) { vec_safe_splice (*&r, p PASS_MEM_STAT); } void release_tree_vector (releasing_vec &); // cause link error struct GTY(()) tree_template_decl { struct tree_decl_common common; tree arguments; tree result; }; /* Returns true iff NODE is a BASELINK. */ #define BASELINK_P(NODE) \ (TREE_CODE (NODE) == BASELINK) /* The BINFO indicating the base in which lookup found the BASELINK_FUNCTIONS. */ #define BASELINK_BINFO(NODE) \ (((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo) /* The functions referred to by the BASELINK; either a FUNCTION_DECL, a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */ #define BASELINK_FUNCTIONS(NODE) \ (((struct tree_baselink*) BASELINK_CHECK (NODE))->functions) /* If T is a BASELINK, grab the functions, otherwise just T, which is expected to already be a (list of) functions. */ #define MAYBE_BASELINK_FUNCTIONS(T) \ (BASELINK_P (T) ? BASELINK_FUNCTIONS (T) : T) /* The BINFO in which the search for the functions indicated by this baselink began. This base is used to determine the accessibility of functions selected by overload resolution. */ #define BASELINK_ACCESS_BINFO(NODE) \ (((struct tree_baselink*) BASELINK_CHECK (NODE))->access_binfo) /* For a type-conversion operator, the BASELINK_OPTYPE indicates the type to which the conversion should occur. This value is important if the BASELINK_FUNCTIONS include a template conversion operator -- the BASELINK_OPTYPE can be used to determine what type the user requested. */ #define BASELINK_OPTYPE(NODE) \ (TREE_CHAIN (BASELINK_CHECK (NODE))) /* Nonzero if this baselink was from a qualified lookup. */ #define BASELINK_QUALIFIED_P(NODE) \ TREE_LANG_FLAG_0 (BASELINK_CHECK (NODE)) /* Nonzero if the overload set for this baselink might be incomplete due to the lookup being performed from an incomplete-class context. */ #define BASELINK_FUNCTIONS_MAYBE_INCOMPLETE_P(NODE) \ TREE_LANG_FLAG_1 (BASELINK_CHECK (NODE)) struct GTY(()) tree_baselink { struct tree_common common; tree binfo; tree functions; tree access_binfo; }; /* The different kinds of ids that we encounter. */ enum cp_id_kind { /* Not an id at all. */ CP_ID_KIND_NONE, /* An unqualified-id that is not a template-id. */ CP_ID_KIND_UNQUALIFIED, /* An unqualified-id that is a dependent name. */ CP_ID_KIND_UNQUALIFIED_DEPENDENT, /* An unqualified template-id. */ CP_ID_KIND_TEMPLATE_ID, /* A qualified-id. */ CP_ID_KIND_QUALIFIED }; /* The various kinds of C++0x warnings we encounter. */ enum cpp0x_warn_str { /* extended initializer lists */ CPP0X_INITIALIZER_LISTS, /* explicit conversion operators */ CPP0X_EXPLICIT_CONVERSION, /* variadic templates */ CPP0X_VARIADIC_TEMPLATES, /* lambda expressions */ CPP0X_LAMBDA_EXPR, /* C++0x auto */ CPP0X_AUTO, /* scoped enums */ CPP0X_SCOPED_ENUMS, /* defaulted and deleted functions */ CPP0X_DEFAULTED_DELETED, /* inline namespaces */ CPP0X_INLINE_NAMESPACES, /* override controls, override/final */ CPP0X_OVERRIDE_CONTROLS, /* non-static data member initializers */ CPP0X_NSDMI, /* user defined literals */ CPP0X_USER_DEFINED_LITERALS, /* delegating constructors */ CPP0X_DELEGATING_CTORS, /* inheriting constructors */ CPP0X_INHERITING_CTORS, /* C++11 attributes */ CPP0X_ATTRIBUTES, /* ref-qualified member functions */ CPP0X_REF_QUALIFIER }; /* The various kinds of operation used by composite_pointer_type. */ enum composite_pointer_operation { /* comparison */ CPO_COMPARISON, /* conversion */ CPO_CONVERSION, /* conditional expression */ CPO_CONDITIONAL_EXPR }; /* Possible cases of expression list used by build_x_compound_expr_from_list. */ enum expr_list_kind { ELK_INIT, /* initializer */ ELK_MEM_INIT, /* member initializer */ ELK_FUNC_CAST /* functional cast */ }; /* Possible cases of implicit bad rhs conversions. */ enum impl_conv_rhs { ICR_DEFAULT_ARGUMENT, /* default argument */ ICR_CONVERTING, /* converting */ ICR_INIT, /* initialization */ ICR_ARGPASS, /* argument passing */ ICR_RETURN, /* return */ ICR_ASSIGN /* assignment */ }; /* Possible cases of implicit or explicit bad conversions to void. */ enum impl_conv_void { ICV_CAST, /* (explicit) conversion to void */ ICV_SECOND_OF_COND, /* second operand of conditional expression */ ICV_THIRD_OF_COND, /* third operand of conditional expression */ ICV_RIGHT_OF_COMMA, /* right operand of comma operator */ ICV_LEFT_OF_COMMA, /* left operand of comma operator */ ICV_STATEMENT, /* statement */ ICV_THIRD_IN_FOR /* for increment expression */ }; /* Possible invalid uses of an abstract class that might not have a specific associated declaration. */ enum GTY(()) abstract_class_use { ACU_UNKNOWN, /* unknown or decl provided */ ACU_CAST, /* cast to abstract class */ ACU_NEW, /* new-expression of abstract class */ ACU_THROW, /* throw-expression of abstract class */ ACU_CATCH, /* catch-parameter of abstract class */ ACU_ARRAY, /* array of abstract class */ ACU_RETURN, /* return type of abstract class */ ACU_PARM /* parameter type of abstract class */ }; /* Macros for access to language-specific slots in an identifier. */ /* 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 REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE) #define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE)) /* 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 }; /* 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) /* Access a C++-specific index for identifier NODE. Used to optimize operator mappings etc. */ #define IDENTIFIER_CP_INDEX(NODE) \ (IDENTIFIER_NODE_CHECK(NODE)->base.u.bits.address_space) /* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ #define C_TYPE_FIELDS_READONLY(TYPE) \ (LANG_TYPE_CLASS_CHECK (TYPE)->fields_readonly) /* The tokens stored in the unparsed operand. */ #define DEFPARSE_TOKENS(NODE) \ (((struct tree_deferred_parse *)DEFERRED_PARSE_CHECK (NODE))->tokens) #define DEFPARSE_INSTANTIATIONS(NODE) \ (((struct tree_deferred_parse *)DEFERRED_PARSE_CHECK (NODE))->instantiations) struct GTY (()) tree_deferred_parse { struct tree_base base; struct cp_token_cache *tokens; vec *instantiations; }; #define DEFERRED_NOEXCEPT_PATTERN(NODE) \ (((struct tree_deferred_noexcept *)DEFERRED_NOEXCEPT_CHECK (NODE))->pattern) #define DEFERRED_NOEXCEPT_ARGS(NODE) \ (((struct tree_deferred_noexcept *)DEFERRED_NOEXCEPT_CHECK (NODE))->args) #define DEFERRED_NOEXCEPT_SPEC_P(NODE) \ ((NODE) && (TREE_PURPOSE (NODE)) \ && (TREE_CODE (TREE_PURPOSE (NODE)) == DEFERRED_NOEXCEPT)) #define UNEVALUATED_NOEXCEPT_SPEC_P(NODE) \ (DEFERRED_NOEXCEPT_SPEC_P (NODE) \ && DEFERRED_NOEXCEPT_PATTERN (TREE_PURPOSE (NODE)) == NULL_TREE) #define UNPARSED_NOEXCEPT_SPEC_P(NODE) \ ((NODE) && (TREE_PURPOSE (NODE)) \ && (TREE_CODE (TREE_PURPOSE (NODE)) == DEFERRED_PARSE)) struct GTY (()) tree_deferred_noexcept { struct tree_base base; tree pattern; tree args; }; /* The condition associated with the static assertion. This must be an integral constant expression. */ #define STATIC_ASSERT_CONDITION(NODE) \ (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->condition) /* The message associated with the static assertion. This must be a string constant, which will be emitted as an error message when the static assert condition is false. */ #define STATIC_ASSERT_MESSAGE(NODE) \ (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->message) /* Source location information for a static assertion. */ #define STATIC_ASSERT_SOURCE_LOCATION(NODE) \ (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->location) struct GTY (()) tree_static_assert { struct tree_common common; tree condition; tree message; location_t location; }; struct GTY (()) tree_argument_pack_select { struct tree_common common; tree argument_pack; int index; }; /* The different kinds of traits that we encounter. */ enum cp_trait_kind { #define DEFTRAIT(TCC, CODE, NAME, ARITY) \ CPTK_##CODE, #include "cp-trait.def" #undef DEFTRAIT }; /* The types that we are processing. */ #define TRAIT_EXPR_TYPE1(NODE) \ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type1) #define TRAIT_EXPR_TYPE2(NODE) \ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type2) /* The specific trait that we are processing. */ #define TRAIT_EXPR_KIND(NODE) \ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->kind) #define TRAIT_EXPR_LOCATION(NODE) \ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->locus) struct GTY (()) tree_trait_expr { struct tree_common common; tree type1; tree type2; location_t locus; enum cp_trait_kind kind; }; /* An INTEGER_CST containing the kind of the trait type NODE. */ #define TRAIT_TYPE_KIND_RAW(NODE) \ TYPE_VALUES_RAW (TRAIT_TYPE_CHECK (NODE)) /* The kind of the trait type NODE. */ #define TRAIT_TYPE_KIND(NODE) \ ((enum cp_trait_kind) TREE_INT_CST_LOW (TRAIT_TYPE_KIND_RAW (NODE))) /* The first argument of the trait type NODE. */ #define TRAIT_TYPE_TYPE1(NODE) \ TYPE_MIN_VALUE_RAW (TRAIT_TYPE_CHECK (NODE)) /* The rest of the arguments of the trait type NODE. */ #define TRAIT_TYPE_TYPE2(NODE) \ TYPE_MAX_VALUE_RAW (TRAIT_TYPE_CHECK (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) /* 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))) /* Test if FUNCTION_DECL is a lambda function. */ #define LAMBDA_FUNCTION_P(FNDECL) \ (DECL_DECLARES_FUNCTION_P (FNDECL) \ && DECL_OVERLOADED_OPERATOR_P (FNDECL) \ && DECL_OVERLOADED_OPERATOR_IS (FNDECL, CALL_EXPR) \ && LAMBDA_TYPE_P (CP_DECL_CONTEXT (FNDECL))) enum cp_lambda_default_capture_mode_type { CPLD_NONE, CPLD_COPY, CPLD_REFERENCE }; /* The method of default capture, if any. */ #define LAMBDA_EXPR_DEFAULT_CAPTURE_MODE(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->default_capture_mode) /* The capture-list, including `this'. Each capture is stored as a FIELD_DECL * so that the name, type, and field are all together, whether or not it has * been added to the lambda's class type. TREE_LIST: TREE_PURPOSE: The FIELD_DECL for this capture. TREE_VALUE: The initializer. This is part of a GNU extension. */ #define LAMBDA_EXPR_CAPTURE_LIST(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->capture_list) /* During parsing of the lambda-introducer, the node in the capture-list that holds the 'this' capture. During parsing of the body, the capture proxy for that node. */ #define LAMBDA_EXPR_THIS_CAPTURE(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->this_capture) /* Predicate tracking whether `this' is in the effective capture set. */ #define LAMBDA_EXPR_CAPTURES_THIS_P(NODE) \ LAMBDA_EXPR_THIS_CAPTURE(NODE) /* Predicate tracking whether the lambda was declared 'mutable'. */ #define LAMBDA_EXPR_MUTABLE_P(NODE) \ TREE_LANG_FLAG_1 (LAMBDA_EXPR_CHECK (NODE)) /* True iff uses of a const variable capture were optimized away. */ #define LAMBDA_EXPR_CAPTURE_OPTIMIZED(NODE) \ TREE_LANG_FLAG_2 (LAMBDA_EXPR_CHECK (NODE)) /* Predicate tracking whether the lambda was declared 'static'. */ #define LAMBDA_EXPR_STATIC_P(NODE) \ TREE_LANG_FLAG_3 (LAMBDA_EXPR_CHECK (NODE)) /* True if this TREE_LIST in LAMBDA_EXPR_CAPTURE_LIST is for an explicit capture. */ #define LAMBDA_CAPTURE_EXPLICIT_P(NODE) \ TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE)) /* The source location of the lambda. */ #define LAMBDA_EXPR_LOCATION(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->locus) /* The mangling scope for the lambda: FUNCTION_DECL, PARM_DECL, VAR_DECL, FIELD_DECL or NULL_TREE. If this is NULL_TREE, we have no linkage. */ #define LAMBDA_EXPR_EXTRA_SCOPE(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_scope) /* Lambdas in the same extra scope might need a discriminating count. For ABI 17, we have single per-scope count, for ABI 18, we have per-scope, per-signature numbering. */ #define LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_scope) #define LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_sig) /* During parsing of the lambda, a vector of capture proxies which need to be pushed once we're done processing a nested lambda. */ #define LAMBDA_EXPR_PENDING_PROXIES(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->pending_proxies) /* If NODE was regenerated via tsubst_lambda_expr, this is a TEMPLATE_INFO whose TI_TEMPLATE is the immediate LAMBDA_EXPR from which NODE was regenerated, and TI_ARGS is the full set of template arguments used to regenerate NODE from the most general lambda. */ #define LAMBDA_EXPR_REGEN_INFO(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->regen_info) /* The closure type of the lambda, which is also the type of the LAMBDA_EXPR. */ #define LAMBDA_EXPR_CLOSURE(NODE) \ (TREE_TYPE (LAMBDA_EXPR_CHECK (NODE))) struct GTY (()) tree_lambda_expr { struct tree_typed typed; tree capture_list; tree this_capture; tree extra_scope; tree regen_info; vec *pending_proxies; location_t locus; enum cp_lambda_default_capture_mode_type default_capture_mode : 2; unsigned discriminator_scope : 15; // Per-scope discriminator unsigned discriminator_sig : 15; // Per-scope, per-signature discriminator }; /* Non-zero if this template specialization has access violations that should be rechecked when the function is instantiated outside argument deduction. */ #define TINFO_HAS_ACCESS_ERRORS(NODE) \ (TREE_LANG_FLAG_0 (TEMPLATE_INFO_CHECK (NODE))) #define FNDECL_HAS_ACCESS_ERRORS(NODE) \ (TINFO_HAS_ACCESS_ERRORS (DECL_TEMPLATE_INFO (NODE))) /* Non-zero if this variable template specialization was specified using a template-id, so it's a partial or full specialization and not a definition of the member template of a particular class specialization. */ #define TINFO_USED_TEMPLATE_ID(NODE) \ (TREE_LANG_FLAG_1 (TEMPLATE_INFO_CHECK (NODE))) /* 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_checks; }; // Constraint information for a C++ declaration. Constraint information is // comprised of: // // - a constraint expression introduced by the template header // - a constraint expression introduced by a function declarator // - the associated constraints, which are the conjunction of those, // and used for declaration matching // // The template and declarator requirements are kept to support pretty // printing constrained declarations. struct GTY(()) tree_constraint_info { struct tree_base base; tree template_reqs; tree declarator_reqs; tree associated_constr; }; // Require that pointer P is non-null before returning. template inline T* check_nonnull (T* p) { gcc_assert (p); return p; } /* Returns true iff T is non-null and represents constraint info. */ inline tree_constraint_info * check_constraint_info (tree t) { if (t && TREE_CODE (t) == CONSTRAINT_INFO) return (tree_constraint_info *)t; return NULL; } /* Access the expression describing the template constraints. This may be null if no constraints were introduced in the template parameter list, a requirements clause after the template parameter list, or constraints through a constrained-type-specifier. */ #define CI_TEMPLATE_REQS(NODE) \ check_constraint_info (check_nonnull (NODE))->template_reqs /* Access the expression describing the trailing constraints. This is non-null for any implicit instantiation of a constrained declaration. For a templated declaration it is non-null only when a trailing requires-clause was specified. */ #define CI_DECLARATOR_REQS(NODE) \ check_constraint_info (check_nonnull (NODE))->declarator_reqs /* The computed associated constraint expression for a declaration. */ #define CI_ASSOCIATED_CONSTRAINTS(NODE) \ check_constraint_info (check_nonnull (NODE))->associated_constr /* Access the constraint-expression introduced by the requires-clause associate the template parameter list NODE. */ #define TEMPLATE_PARMS_CONSTRAINTS(NODE) \ TREE_TYPE (TREE_LIST_CHECK (NODE)) /* Access the logical constraints on the template parameter declaration indicated by NODE. */ #define TEMPLATE_PARM_CONSTRAINTS(NODE) \ TREE_TYPE (TREE_LIST_CHECK (NODE)) /* Non-zero if the noexcept is present in a compound requirement. */ #define COMPOUND_REQ_NOEXCEPT_P(NODE) \ TREE_LANG_FLAG_0 (TREE_CHECK (NODE, COMPOUND_REQ)) /* A TREE_LIST whose TREE_VALUE is the constraints on the 'auto' placeholder type NODE, used in an argument deduction constraint. The TREE_PURPOSE holds the set of template parameters that were in-scope when this 'auto' was formed. */ #define PLACEHOLDER_TYPE_CONSTRAINTS_INFO(NODE) \ DECL_SIZE_UNIT (TYPE_NAME (NODE)) /* The constraints on the 'auto' placeholder type NODE. */ #define PLACEHOLDER_TYPE_CONSTRAINTS(NODE) \ (PLACEHOLDER_TYPE_CONSTRAINTS_INFO (NODE) \ ? TREE_VALUE (PLACEHOLDER_TYPE_CONSTRAINTS_INFO (NODE)) \ : NULL_TREE) /* True if NODE is a constraint. */ #define CONSTR_P(NODE) \ (TREE_CODE (NODE) == ATOMIC_CONSTR \ || TREE_CODE (NODE) == CONJ_CONSTR \ || TREE_CODE (NODE) == DISJ_CONSTR) /* Valid for any normalized constraint. */ #define CONSTR_CHECK(NODE) \ TREE_CHECK3 (NODE, ATOMIC_CONSTR, CONJ_CONSTR, DISJ_CONSTR) /* The CONSTR_INFO stores normalization data for a constraint. It refers to the original expression and the expression or declaration from which the constraint was normalized. This is TREE_LIST whose TREE_PURPOSE is the original expression and whose TREE_VALUE is a list of contexts. */ #define CONSTR_INFO(NODE) \ TREE_TYPE (CONSTR_CHECK (NODE)) /* The expression evaluated by the constraint. */ #define CONSTR_EXPR(NODE) \ TREE_PURPOSE (CONSTR_INFO (NODE)) /* The expression or declaration from which this constraint was normalized. This is a TREE_LIST whose TREE_VALUE is either a template-id expression denoting a concept check or the declaration introducing the constraint. These are chained to other context objects. */ #define CONSTR_CONTEXT(NODE) \ TREE_VALUE (CONSTR_INFO (NODE)) /* The parameter mapping for an atomic constraint. */ #define ATOMIC_CONSTR_MAP(NODE) \ TREE_OPERAND (TREE_CHECK (NODE, ATOMIC_CONSTR), 0) /* Whether the parameter mapping of this atomic constraint is already instantiated with concrete template arguments. Used only in satisfy_atom and in the satisfaction cache. */ #define ATOMIC_CONSTR_MAP_INSTANTIATED_P(NODE) \ TREE_LANG_FLAG_0 (ATOMIC_CONSTR_CHECK (NODE)) /* Whether the expression for this atomic constraint belongs to a concept definition. */ #define ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P(NODE) \ TREE_LANG_FLAG_1 (ATOMIC_CONSTR_CHECK (NODE)) /* The expression of an atomic constraint. */ #define ATOMIC_CONSTR_EXPR(NODE) \ CONSTR_EXPR (ATOMIC_CONSTR_CHECK (NODE)) /* The concept of a concept check. */ #define CHECK_CONSTR_CONCEPT(NODE) \ TREE_OPERAND (TREE_CHECK (NODE, CHECK_CONSTR), 0) /* The template arguments of a concept check. */ #define CHECK_CONSTR_ARGS(NODE) \ TREE_OPERAND (TREE_CHECK (NODE, CHECK_CONSTR), 1) /* 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)) /* The concept constraining this constrained template-parameter. */ #define CONSTRAINED_PARM_CONCEPT(NODE) \ DECL_SIZE_UNIT (TYPE_DECL_CHECK (NODE)) /* Any extra template arguments specified for a constrained template-parameter. */ #define CONSTRAINED_PARM_EXTRA_ARGS(NODE) \ DECL_SIZE (TYPE_DECL_CHECK (NODE)) /* The first template parameter of CONSTRAINED_PARM_CONCEPT to be used as a prototype for the constrained parameter in finish_shorthand_constraint, attached for convenience. */ #define CONSTRAINED_PARM_PROTOTYPE(NODE) \ DECL_INITIAL (TYPE_DECL_CHECK (NODE)) /* Module flags on FUNCTION,VAR,TYPE,CONCEPT or NAMESPACE A TEMPLATE_DECL holds them on the DECL_TEMPLATE_RESULT object -- it's just not practical to keep them consistent. */ #define DECL_MODULE_CHECK(NODE) \ TREE_NOT_CHECK (NODE, TEMPLATE_DECL) /* In the purview of a named module (or in the purview of the header-unit being compiled). */ #define DECL_MODULE_PURVIEW_P(N) \ (DECL_LANG_SPECIFIC (DECL_MODULE_CHECK (N))->u.base.module_purview_p) /* Attached to the named module it is in the purview of. Decls attached to the global module will have this false. */ #define DECL_MODULE_ATTACH_P(N) \ (DECL_LANG_SPECIFIC (DECL_MODULE_CHECK (N))->u.base.module_attach_p) /* True if the live version of the decl was imported. */ #define DECL_MODULE_IMPORT_P(NODE) \ (DECL_LANG_SPECIFIC (DECL_MODULE_CHECK (NODE))->u.base.module_import_p) /* True if this decl is in the entity hash & array. This means that some variant was imported, even if DECL_MODULE_IMPORT_P is false. */ #define DECL_MODULE_ENTITY_P(NODE) \ (DECL_LANG_SPECIFIC (DECL_MODULE_CHECK (NODE))->u.base.module_entity_p) /* DECL that has attached decls for ODR-relatedness. */ #define DECL_MODULE_KEYED_DECLS_P(NODE) \ (DECL_LANG_SPECIFIC (TREE_CHECK2(NODE,FUNCTION_DECL,VAR_DECL))\ ->u.base.module_keyed_decls_p) /* Whether this is an exported DECL. Held on any decl that can appear at namespace scope (function, var, type, template, const or namespace). templates copy from their template_result, consts have it for unscoped enums. */ #define DECL_MODULE_EXPORT_P(NODE) TREE_LANG_FLAG_3 (NODE)