Implemented project structure

This commit is contained in:
Fabio Scotto di Santolo
2025-11-29 18:39:57 +01:00
commit c59b4004e5
6024 changed files with 1100108 additions and 0 deletions

View File

@@ -0,0 +1,305 @@
/* Definitions for C++ contract levels. Implements functionality described in
the N4820 working draft version of contracts, P1290, P1332, and P1429.
Copyright (C) 2020-2023 Free Software Foundation, Inc.
Contributed by Jeff Chapman II (jchapman@lock3software.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_CP_CONTRACT_H
#define GCC_CP_CONTRACT_H
/* Contract levels approximate the complexity of the expression. */
enum contract_level
{
CONTRACT_INVALID,
CONTRACT_DEFAULT,
CONTRACT_AUDIT,
CONTRACT_AXIOM
};
/* The concrete semantics determine the behavior of a contract. */
enum contract_semantic
{
CCS_INVALID,
CCS_IGNORE,
CCS_ASSUME,
CCS_NEVER,
CCS_MAYBE
};
/* True if the contract is unchecked. */
inline bool
unchecked_contract_p (contract_semantic cs)
{
return cs == CCS_IGNORE || cs == CCS_ASSUME;
}
/* True if the contract is checked. */
inline bool
checked_contract_p (contract_semantic cs)
{
return cs >= CCS_NEVER;
}
/* Must match std::contract_violation_continuation_mode in <contract>. */
enum contract_continuation
{
NEVER_CONTINUE,
MAYBE_CONTINUE
};
/* Assertion role info. */
struct contract_role
{
const char *name;
contract_semantic default_semantic;
contract_semantic audit_semantic;
contract_semantic axiom_semantic;
};
/* Information for configured contract semantics. */
struct contract_configuration
{
contract_level level;
contract_role* role;
};
/* A contract mode contains information used to derive the checking
and assumption semantics of a contract. This is either a dynamic
configuration, meaning it derives from the build mode, or it is
explicitly specified. */
struct contract_mode
{
contract_mode () : kind(cm_invalid) {}
contract_mode (contract_level level, contract_role *role = NULL)
: kind(cm_dynamic)
{
contract_configuration cc;
cc.level = level;
cc.role = role;
u.config = cc;
}
contract_mode (contract_semantic semantic) : kind(cm_explicit)
{
u.semantic = semantic;
}
contract_level get_level () const
{
gcc_assert (kind == cm_dynamic);
return u.config.level;
}
contract_role *get_role () const
{
gcc_assert (kind == cm_dynamic);
return u.config.role;
}
contract_semantic get_semantic () const
{
gcc_assert (kind == cm_explicit);
return u.semantic;
}
enum { cm_invalid, cm_dynamic, cm_explicit } kind;
union
{
contract_configuration config;
contract_semantic semantic;
} u;
};
extern contract_role *get_contract_role (const char *);
extern contract_role *add_contract_role (const char *,
contract_semantic,
contract_semantic,
contract_semantic,
bool = true);
extern void validate_contract_role (contract_role *);
extern void setup_default_contract_role (bool = true);
extern contract_semantic lookup_concrete_semantic (const char *);
/* Map a source level semantic or level name to its value, or invalid. */
extern contract_semantic map_contract_semantic (const char *);
extern contract_level map_contract_level (const char *);
/* Check if an attribute is a cxx contract attribute. */
extern bool cxx_contract_attribute_p (const_tree);
extern bool cp_contract_assertion_p (const_tree);
/* Returns the default role. */
inline contract_role *
get_default_contract_role ()
{
return get_contract_role ("default");
}
/* Handle various command line arguments related to semantic mapping. */
extern void handle_OPT_fcontract_build_level_ (const char *);
extern void handle_OPT_fcontract_assumption_mode_ (const char *);
extern void handle_OPT_fcontract_continuation_mode_ (const char *);
extern void handle_OPT_fcontract_role_ (const char *);
extern void handle_OPT_fcontract_semantic_ (const char *);
enum contract_matching_context
{
cmc_declaration,
cmc_override
};
/* True if NODE is any kind of contract. */
#define CONTRACT_P(NODE) \
(TREE_CODE (NODE) == ASSERTION_STMT \
|| TREE_CODE (NODE) == PRECONDITION_STMT \
|| TREE_CODE (NODE) == POSTCONDITION_STMT)
/* True if NODE is a contract condition. */
#define CONTRACT_CONDITION_P(NODE) \
(TREE_CODE (NODE) == PRECONDITION_STMT \
|| TREE_CODE (NODE) == POSTCONDITION_STMT)
/* True if NODE is a precondition. */
#define PRECONDITION_P(NODE) \
(TREE_CODE (NODE) == PRECONDITION_STMT)
/* True if NODE is a postcondition. */
#define POSTCONDITION_P(NODE) \
(TREE_CODE (NODE) == POSTCONDITION_STMT)
#define CONTRACT_CHECK(NODE) \
(TREE_CHECK3 (NODE, ASSERTION_STMT, PRECONDITION_STMT, POSTCONDITION_STMT))
/* True iff the FUNCTION_DECL NODE currently has any contracts. */
#define DECL_HAS_CONTRACTS_P(NODE) \
(DECL_CONTRACTS (NODE) != NULL_TREE)
/* For a FUNCTION_DECL of a guarded function, this points to a list of the pre
and post contracts of the first decl of NODE in original order. */
#define DECL_CONTRACTS(NODE) \
(find_contract (DECL_ATTRIBUTES (NODE)))
/* The next contract (if any) after this one in an attribute list. */
#define CONTRACT_CHAIN(NODE) \
(find_contract (TREE_CHAIN (NODE)))
/* The wrapper of the original source location of a list of contracts. */
#define CONTRACT_SOURCE_LOCATION_WRAPPER(NODE) \
(TREE_PURPOSE (TREE_VALUE (NODE)))
/* The original source location of a list of contracts. */
#define CONTRACT_SOURCE_LOCATION(NODE) \
(EXPR_LOCATION (CONTRACT_SOURCE_LOCATION_WRAPPER (NODE)))
/* The actual code _STMT for a contract attribute. */
#define CONTRACT_STATEMENT(NODE) \
(TREE_VALUE (TREE_VALUE (NODE)))
/* True if the contract semantic was specified literally. If true, the
contract mode is an identifier containing the semantic. Otherwise,
it is a TREE_LIST whose TREE_VALUE is the level and whose TREE_PURPOSE
is the role. */
#define CONTRACT_LITERAL_MODE_P(NODE) \
(CONTRACT_MODE (NODE) != NULL_TREE \
&& TREE_CODE (CONTRACT_MODE (NODE)) == IDENTIFIER_NODE)
/* The identifier denoting the literal semantic of the contract. */
#define CONTRACT_LITERAL_SEMANTIC(NODE) \
(TREE_OPERAND (NODE, 0))
/* The written "mode" of the contract. Either an IDENTIFIER with the
literal semantic or a TREE_LIST containing the level and role. */
#define CONTRACT_MODE(NODE) \
(TREE_OPERAND (CONTRACT_CHECK (NODE), 0))
/* The identifier denoting the build level of the contract. */
#define CONTRACT_LEVEL(NODE) \
(TREE_VALUE (CONTRACT_MODE (NODE)))
/* The identifier denoting the role of the contract */
#define CONTRACT_ROLE(NODE) \
(TREE_PURPOSE (CONTRACT_MODE (NODE)))
/* The parsed condition of the contract. */
#define CONTRACT_CONDITION(NODE) \
(TREE_OPERAND (CONTRACT_CHECK (NODE), 1))
/* True iff the condition of the contract NODE is not yet parsed. */
#define CONTRACT_CONDITION_DEFERRED_P(NODE) \
(TREE_CODE (CONTRACT_CONDITION (NODE)) == DEFERRED_PARSE)
/* The raw comment of the contract. */
#define CONTRACT_COMMENT(NODE) \
(TREE_OPERAND (CONTRACT_CHECK (NODE), 2))
/* The VAR_DECL of a postcondition result. For deferred contracts, this
is an IDENTIFIER. */
#define POSTCONDITION_IDENTIFIER(NODE) \
(TREE_OPERAND (POSTCONDITION_STMT_CHECK (NODE), 3))
/* For a FUNCTION_DECL of a guarded function, this holds the function decl
where pre contract checks are emitted. */
#define DECL_PRE_FN(NODE) \
(get_precondition_function ((NODE)))
/* For a FUNCTION_DECL of a guarded function, this holds the function decl
where post contract checks are emitted. */
#define DECL_POST_FN(NODE) \
(get_postcondition_function ((NODE)))
/* True iff the FUNCTION_DECL is the pre function for a guarded function. */
#define DECL_IS_PRE_FN_P(NODE) \
(DECL_ABSTRACT_ORIGIN (NODE) && DECL_PRE_FN (DECL_ABSTRACT_ORIGIN (NODE)) == NODE)
/* True iff the FUNCTION_DECL is the post function for a guarded function. */
#define DECL_IS_POST_FN_P(NODE) \
(DECL_ABSTRACT_ORIGIN (NODE) && DECL_POST_FN (DECL_ABSTRACT_ORIGIN (NODE)) == NODE)
extern void remove_contract_attributes (tree);
extern void copy_contract_attributes (tree, tree);
extern void remap_contracts (tree, tree, tree, bool);
extern void maybe_update_postconditions (tree);
extern void rebuild_postconditions (tree);
extern bool check_postcondition_result (tree, tree, location_t);
extern tree get_precondition_function (tree);
extern tree get_postcondition_function (tree);
extern void duplicate_contracts (tree, tree);
extern void match_deferred_contracts (tree);
extern void defer_guarded_contract_match (tree, tree, tree);
extern bool diagnose_misapplied_contracts (tree);
extern tree finish_contract_attribute (tree, tree);
extern tree invalidate_contract (tree);
extern void update_late_contract (tree, tree, tree);
extern tree splice_out_contracts (tree);
extern bool all_attributes_are_contracts_p (tree);
extern void inherit_base_contracts (tree, tree);
extern tree apply_postcondition_to_return (tree);
extern void start_function_contracts (tree);
extern void finish_function_contracts (tree);
extern void set_contract_functions (tree, tree, tree);
extern tree build_contract_check (tree);
extern void emit_assertion (tree);
#endif /* ! GCC_CP_CONTRACT_H */

View File

@@ -0,0 +1,108 @@
/* This file contains the definitions for C++-specific built-in traits.
Copyright The GNU Toolchain Authors.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Add a DEFTRAIT_EXPR (CODE, NAME, N) line to this file to define an
expression-yielding built-in trait that has internal code name CODE, is
spelled as NAME and takes N type arguments (where N is either 1, 2, or
the special value -1 which denotes that it takes at least one argument).
Such traits are represented as TRAIT_EXPR tree whose TRAIT_EXPR_KIND is
CPTK_CODE. Define the behavior of the trait in finish_trait_expr. */
/* Add a DEFTRAIT_TYPE (CODE, NAME, N) line to this file to define a
type-yielding built-in trait as described above. Such traits are
generally represented as a TRAIT_TYPE tree whose TRAIT_TYPE_KIND is
CPTK_CODE (exceptions are BASES and DIRECT_BASES below). Define the
behavior of the trait in finish_trait_type. */
#ifdef DEFTRAIT
#define DEFTRAIT_EXPR(CODE, NAME, ARITY) DEFTRAIT(tcc_expression, CODE, NAME, ARITY)
#define DEFTRAIT_TYPE(CODE, NAME, ARITY) DEFTRAIT(tcc_type, CODE, NAME, ARITY)
#define DEFTRAIT_EXPR_DEFAULTED
#define DEFTRAIT_TYPE_DEFAULTED
#endif
#ifndef DEFTRAIT_EXPR
#define DEFTRAIT_EXPR(CODE, NAME, ARITY)
#define DEFTRAIT_EXPR_DEFAULTED
#endif
#ifndef DEFTRAIT_TYPE
#define DEFTRAIT_TYPE(CODE, NAME, ARITY)
#define DEFTRAIT_TYPE_DEFAULTED
#endif
DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
DEFTRAIT_EXPR (HAS_TRIVIAL_ASSIGN, "__has_trivial_assign", 1)
DEFTRAIT_EXPR (HAS_TRIVIAL_CONSTRUCTOR, "__has_trivial_constructor", 1)
DEFTRAIT_EXPR (HAS_TRIVIAL_COPY, "__has_trivial_copy", 1)
DEFTRAIT_EXPR (HAS_TRIVIAL_DESTRUCTOR, "__has_trivial_destructor", 1)
DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, "__has_unique_object_representations", 1)
DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, "__is_pointer_interconvertible_base_of", 2)
DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
/* FIXME Added space to avoid direct usage in GCC 13. */
DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
/* These traits yield a type pack, not a type, and are represented by
cp_parser_trait as a special BASES tree instead of a TRAIT_TYPE tree. */
DEFTRAIT_TYPE (BASES, "__bases", 1)
DEFTRAIT_TYPE (DIRECT_BASES, "__direct_bases", 1)
#ifdef DEFTRAIT_EXPR_DEFAULTED
#undef DEFTRAIT_EXPR
#undef DEFTRAIT_EXPR_DEFAULTED
#endif
#ifdef DEFTRAIT_TYPE_DEFAULTED
#undef DEFTRAIT_TYPE
#undef DEFTRAIT_TYPE_DEFAULTED
#endif

View File

@@ -0,0 +1,600 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the GNU C++ compiler (see tree.def
for the standard codes).
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* An OFFSET_REF is used in two situations:
1. An expression of the form `A::m' where `A' is a class and `m' is
a non-static member. In this case, operand 0 will be a TYPE
(corresponding to `A') and operand 1 will be a FIELD_DECL,
BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
The expression is a pointer-to-member if its address is taken,
but simply denotes a member of the object if its address is not
taken.
This form is only used during the parsing phase; once semantic
analysis has taken place they are eliminated.
2. An expression of the form `x.*p'. In this case, operand 0 will
be an expression corresponding to `x' and operand 1 will be an
expression with pointer-to-member type. */
DEFTREECODE (OFFSET_REF, "offset_ref", tcc_reference, 2)
/* A pointer-to-member constant. For a pointer-to-member constant
`X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
PTRMEM_CST_MEMBER is the _DECL for `Y'. */
DEFTREECODE (PTRMEM_CST, "ptrmem_cst", tcc_constant, 0)
/* For NEW_EXPR, operand 0 is the placement list.
Operand 1 is the new-declarator.
Operand 2 is the number of elements in the array.
Operand 3 is the initializer. */
DEFTREECODE (NEW_EXPR, "nw_expr", tcc_expression, 4)
DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", tcc_expression, 3)
/* For DELETE_EXPR, operand 0 is the store to be destroyed.
Operand 1 is the value to pass to the destroying function
saying whether the store should be deallocated as well. */
DEFTREECODE (DELETE_EXPR, "dl_expr", tcc_expression, 2)
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", tcc_expression, 2)
/* Value is reference to particular overloaded class method.
Operand 0 is the class, operand 1 is the field
The COMPLEXITY field holds the class level (usually 0). */
DEFTREECODE (SCOPE_REF, "scope_ref", tcc_reference, 2)
/* When composing an object with a member, this is the result.
Operand 0 is the object. Operand 1 is the member (usually
a dereferenced pointer to member). */
DEFTREECODE (MEMBER_REF, "member_ref", tcc_reference, 2)
/* Type conversion operator in C++. TREE_TYPE is type that this
operator converts to. Operand is expression to be converted. */
DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1)
/* AGGR_INIT_EXPRs have a variably-sized representation similar to
that of CALL_EXPRs. Operand 0 is an INTEGER_CST node containing the
operand count, operand 1 is the function which performs initialization,
operand 2 is the slot which was allocated for this expression, and
the remaining operands are the arguments to the initialization function. */
DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3)
/* Initialization of an array from another array, expressed at a high level
so that it works with TARGET_EXPR. Operand 0 is the target, operand 1
is the initializer. */
DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2)
/* A throw expression. operand 0 is the expression, if there was one,
else it is NULL_TREE. */
DEFTREECODE (THROW_EXPR, "throw_expr", tcc_expression, 1)
/* An empty class object. The TREE_TYPE gives the class type. We use
these to avoid actually creating instances of the empty classes. */
DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", tcc_expression, 0)
/* A reference to a member function or member functions from a base
class. BASELINK_FUNCTIONS gives the FUNCTION_DECL,
TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
functions. BASELINK_BINFO gives the base from which the functions
come, i.e., the base to which the `this' pointer must be converted
before the functions are called. BASELINK_ACCESS_BINFO gives the
base used to name the functions.
A BASELINK is an expression; the TREE_TYPE of the BASELINK gives
the type of the expression. This type is either a FUNCTION_TYPE,
METHOD_TYPE, or `unknown_type_node' indicating that the function is
overloaded. */
DEFTREECODE (BASELINK, "baselink", tcc_exceptional, 0)
/* Template definition. The following fields have the specified uses,
although there are other macros in cp-tree.h that should be used for
accessing this data.
DECL_ARGUMENTS template parm vector
DECL_TEMPLATE_INFO template text &c
DECL_VINDEX list of instantiations already produced;
only done for functions so far
For class template:
DECL_INITIAL associated templates (methods &c)
DECL_TEMPLATE_RESULT null
For non-class templates:
TREE_TYPE type of object to be constructed
DECL_TEMPLATE_RESULT decl for object to be created
(e.g., FUNCTION_DECL with tmpl parms used)
*/
DEFTREECODE (TEMPLATE_DECL, "template_decl", tcc_declaration, 0)
/* Index into a template parameter list. The TEMPLATE_PARM_IDX gives
the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL
gives the level (from 1) of the parameter.
Here's an example:
template <class T> // Index 0, Level 1.
struct S
{
template <class U, // Index 0, Level 2.
class V> // Index 1, Level 2.
void f();
};
The DESCENDANTS will be a chain of TEMPLATE_PARM_INDEXs descended
from this one. The first descendant will have the same IDX, but
its LEVEL will be one less. The TREE_CHAIN field is used to chain
together the descendants. The TEMPLATE_PARM_DECL is the
declaration of this parameter, either a TYPE_DECL or CONST_DECL.
The TEMPLATE_PARM_ORIG_LEVEL is the LEVEL of the most distant
parent, i.e., the LEVEL that the parameter originally had when it
was declared. For example, if we instantiate S<int>, we will have:
struct S<int>
{
template <class U, // Index 0, Level 1, Orig Level 2
class V> // Index 1, Level 1, Orig Level 2
void f();
};
The LEVEL is the level of the parameter when we are worrying about
the types of things; the ORIG_LEVEL is the level when we are
worrying about instantiating things. */
DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", tcc_exceptional, 0)
/* Index into a template parameter list for template template parameters.
This parameter must be a type. The TYPE_FIELDS value will be a
TEMPLATE_PARM_INDEX.
It is used without template arguments like TT in C<TT>,
TYPE_NAME is a TEMPLATE_DECL. */
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", tcc_type, 0)
/* The ordering of the following codes is optimized for the checking
macros in tree.h. Changing the order will degrade the speed of the
compiler. TEMPLATE_TYPE_PARM, TYPENAME_TYPE, TYPEOF_TYPE,
BOUND_TEMPLATE_TEMPLATE_PARM. */
/* Index into a template parameter list. This parameter must be a type.
The type.values field will be a TEMPLATE_PARM_INDEX. */
DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0)
/* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via
template-id, TYPENAME_TYPE_FULLNAME will hold the TEMPLATE_ID_EXPR.
TREE_TYPE is always NULL. */
DEFTREECODE (TYPENAME_TYPE, "typename_type", tcc_type, 0)
/* A type designated by `__typeof (expr)'. TYPEOF_TYPE_EXPR is the
expression in question. */
DEFTREECODE (TYPEOF_TYPE, "typeof_type", tcc_type, 0)
/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments
like TT<int>.
In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the
template name and its bound arguments. TYPE_NAME is a TYPE_DECL. */
DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm",
tcc_type, 0)
/* For template template argument of the form `T::template C'.
TYPE_CONTEXT is `T', the template parameter dependent object.
TYPE_NAME is a TEMPLATE_DECL, whose DECL_TEMPLATE_PARMS are any
template parms of the instantiation. That decl's DECL_NAME is the
IDENTIFIER_NODE for `C', the member class template. */
DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0)
/* A using declaration. USING_DECL_SCOPE contains the specified
scope. In a variadic using-declaration, this is a TYPE_PACK_EXPANSION.
In a member using decl, unless DECL_DEPENDENT_P is true,
USING_DECL_DECLS contains the _DECL or OVERLOAD so named. This is
not an alias, but is later expanded into multiple aliases. */
DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0)
/* A using directive. The operand is USING_STMT_NAMESPACE. */
DEFTREECODE (USING_STMT, "using_stmt", tcc_statement, 1)
/* An un-parsed operand. Holds a vector of input tokens and
a vector of places where the argument was instantiated before
parsing had occurred. This is used for default arguments, delayed
NSDMIs, and noexcept-specifier parsing. */
DEFTREECODE (DEFERRED_PARSE, "deferred_parse", tcc_exceptional, 0)
/* An uninstantiated/unevaluated noexcept-specification. For the
uninstantiated case, DEFERRED_NOEXCEPT_PATTERN is the pattern from the
template, and DEFERRED_NOEXCEPT_ARGS are the template arguments to
substitute into the pattern when needed. For the unevaluated case,
those slots are NULL_TREE and we use get_defaulted_eh_spec to find
the exception-specification. */
DEFTREECODE (DEFERRED_NOEXCEPT, "deferred_noexcept", tcc_exceptional, 0)
/* A template-id, like foo<int>. The first operand is the template.
The second is NULL if there are no explicit arguments, or a
TREE_VEC of arguments. The template will be a FUNCTION_DECL,
TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
member template, the template may be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", tcc_expression, 2)
/* One of a set of overloaded functions. */
DEFTREECODE (OVERLOAD, "overload", tcc_exceptional, 0)
/* A vector of binding slots. */
DEFTREECODE (BINDING_VECTOR, "binding_vector", tcc_exceptional, 0)
/* A pseudo-destructor, of the form "OBJECT.~DESTRUCTOR" or
"OBJECT.SCOPE::~DESTRUCTOR. The first operand is the OBJECT. The
second operand (if non-NULL) is the SCOPE. The third operand is
the TYPE node corresponding to the DESTRUCTOR. The type of the
first operand will always be a scalar type.
The type of a PSEUDO_DTOR_EXPR is always "void", even though it can
be used as if it were a zero-argument function. We handle the
function-call case specially, and giving it "void" type prevents it
being used in expressions in ways that are not permitted. */
DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", tcc_expression, 3)
/* A whole bunch of tree codes for the initial, superficial parsing of
templates. */
DEFTREECODE (MODOP_EXPR, "modop_expr", tcc_expression, 3)
DEFTREECODE (CAST_EXPR, "cast_expr", tcc_unary, 1)
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", tcc_unary, 1)
DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", tcc_unary, 1)
DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1)
DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1)
DEFTREECODE (IMPLICIT_CONV_EXPR, "implicit_conv_expr", tcc_unary, 1)
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2)
DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1)
DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
DEFTREECODE (SPACESHIP_EXPR, "spaceship_expr", tcc_expression, 2)
/* A placeholder for an expression that is not type-dependent, but
does occur in a template. When an expression that is not
type-dependent appears in a larger expression, we must compute the
type of that larger expression. That computation would normally
modify the original expression, which would change the mangling of
that expression if it appeared in a template argument list. In
that situation, we create a NON_DEPENDENT_EXPR to take the place of
the original expression. The expression is the only operand -- it
is only needed for diagnostics. */
DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1)
/* CTOR_INITIALIZER is a placeholder in template code for a call to
setup_vtbl_pointer (and appears in all functions, not just ctors). */
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1)
DEFTREECODE (TRY_BLOCK, "try_block", tcc_statement, 2)
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", tcc_statement, 2)
/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
CATCH_ALL_TYPE, then the handler catches all types. The declaration of
the catch variable is in HANDLER_PARMS, and the body block in
HANDLER_BODY. */
DEFTREECODE (HANDLER, "handler", tcc_statement, 2)
/* A MUST_NOT_THROW_EXPR wraps an expression that may not
throw, and must call terminate if it does. The second argument
is a condition, used in templates to express noexcept (condition). */
DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 2)
/* A CLEANUP_STMT marks the point at which a declaration is fully
constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
when CLEANUP_BODY completes. */
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", tcc_statement, 3)
/* Represents an 'if' statement. The operands are IF_COND,
THEN_CLAUSE, and ELSE_CLAUSE, and the current scope, respectively. */
/* ??? It is currently still necessary to distinguish between IF_STMT
and COND_EXPR for the benefit of templates. */
DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 4)
/* Used to represent a range-based `for' statement. The operands are
RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, RANGE_FOR_SCOPE,
RANGE_FOR_UNROLL, and RANGE_FOR_INIT_STMT, respectively. Only used in
templates. */
DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 6)
/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
obtain the expression. */
DEFTREECODE (EXPR_STMT, "expr_stmt", tcc_expression, 1)
DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0)
/* Represents an 'offsetof' expression during template expansion. */
DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 2)
/* Represents an '__builtin_addressof' expression during template
expansion. This is similar to ADDR_EXPR, but it doesn't invoke
overloaded & operators. */
DEFTREECODE (ADDRESSOF_EXPR, "addressof_expr", tcc_expression, 1)
/* Represents the -> operator during template expansion. */
DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1)
/* Represents an '__alignof__' expression during template
expansion. */
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_expression, 1)
/* Represents an Objective-C++ '@encode' expression during template
expansion. */
DEFTREECODE (AT_ENCODE_EXPR, "at_encode_expr", tcc_expression, 1)
/* A STMT_EXPR represents a statement-expression during template
expansion. This is the GCC extension { ( ... ) }. The
STMT_EXPR_STMT is the statement given by the expression. */
DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1)
/* Unary plus. Operand 0 is the expression to which the unary plus
is applied. */
DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1)
/** C++11 extensions. */
/* A static assertion. This is a C++11 extension.
STATIC_ASSERT_CONDITION contains the condition that is being
checked. STATIC_ASSERT_MESSAGE contains the message (a string
literal) to be displayed if the condition fails to hold. */
DEFTREECODE (STATIC_ASSERT, "static_assert", tcc_exceptional, 0)
/* Represents an argument pack of types (or templates). An argument
pack stores zero or more arguments that will be used to instantiate
a parameter pack.
ARGUMENT_PACK_ARGS retrieves the arguments stored in the argument
pack.
Example:
template<typename... Values>
class tuple { ... };
tuple<int, float, double> t;
Values is a (template) parameter pack. When tuple<int, float,
double> is instantiated, the Values parameter pack is instantiated
with the argument pack <int, float, double>. ARGUMENT_PACK_ARGS will
be a TREE_VEC containing int, float, and double. */
DEFTREECODE (TYPE_ARGUMENT_PACK, "type_argument_pack", tcc_type, 0)
/* Represents an argument pack of values, which can be used either for
non-type template arguments or function call arguments.
NONTYPE_ARGUMENT_PACK plays precisely the same role as
TYPE_ARGUMENT_PACK, but will be used for packing non-type template
arguments (e.g., "int... Dimensions") or function arguments ("const
Args&... args"). */
DEFTREECODE (NONTYPE_ARGUMENT_PACK, "nontype_argument_pack", tcc_expression, 1)
/* Represents a type expression that will be expanded into a list of
types when instantiated with one or more argument packs.
PACK_EXPANSION_PATTERN retrieves the expansion pattern. This is
the type or expression that we will substitute into with each
argument in an argument pack.
PACK_EXPANSION_PARAMETER_PACKS contains a TREE_LIST of the parameter
packs that are used in this pack expansion.
Example:
template<typename... Values>
struct tied : tuple<Values&...> {
// ...
};
The derivation from tuple contains a TYPE_PACK_EXPANSION for the
template arguments. Its PACK_EXPANSION_PATTERN is "Values&" and its
PACK_EXPANSION_PARAMETER_PACKS will contain "Values". */
DEFTREECODE (TYPE_PACK_EXPANSION, "type_pack_expansion", tcc_type, 0)
/* Represents an expression that will be expanded into a list of
expressions when instantiated with one or more argument packs.
EXPR_PACK_EXPANSION plays precisely the same role as TYPE_PACK_EXPANSION,
but will be used for expressions. */
DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 3)
/* Selects the Ith parameter out of an argument pack. This node will
be used when instantiating pack expansions; see
tsubst_pack_expansion.
ARGUMENT_PACK_SELECT_FROM_PACK contains the *_ARGUMENT_PACK node
from which the argument will be selected.
ARGUMENT_PACK_SELECT_INDEX contains the index into the argument
pack that will be returned by this ARGUMENT_PACK_SELECT node. The
index is a machine integer. */
DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0)
/* Fold expressions allow the expansion of a template argument pack
over a binary operator.
FOLD_EXPR_MOD_P is true when the fold operation is a compound assignment
operator.
FOLD_EXPR_OP is an INTEGER_CST storing the tree code for the folded
expression. Note that when FOLDEXPR_MOD_P is true, the operator is
a compound assignment operator for that kind of expression.
FOLD_EXPR_PACK is an expression containing an unexpanded parameter pack;
when expanded, each term becomes an argument of the folded expression.
In a BINARY_FOLD_EXPRESSION, FOLD_EXPR_INIT is the non-pack argument. */
DEFTREECODE (UNARY_LEFT_FOLD_EXPR, "unary_left_fold_expr", tcc_expression, 2)
DEFTREECODE (UNARY_RIGHT_FOLD_EXPR, "unary_right_fold_expr", tcc_expression, 2)
DEFTREECODE (BINARY_LEFT_FOLD_EXPR, "binary_left_fold_expr", tcc_expression, 3)
DEFTREECODE (BINARY_RIGHT_FOLD_EXPR, "binary_right_fold_expr", tcc_expression, 3)
/* Represents the __builtin_bit_cast (type, expr) expression.
The type is in TREE_TYPE, expression in TREE_OPERAND (bitcast, 0). */
DEFTREECODE (BIT_CAST_EXPR, "bit_cast_expr", tcc_expression, 1)
/** C++ extensions. */
/* Represents a templated trait that yields an expression. */
DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0)
/* Represents a templated trait that yields a type. */
DEFTREECODE (TRAIT_TYPE, "trait_type", tcc_type, 0)
/* A lambda expression. This is a C++0x extension.
LAMBDA_EXPR_DEFAULT_CAPTURE_MODE is an enum for the default, which may be
none.
LAMBDA_EXPR_CAPTURE_LIST holds the capture-list, including `this'.
LAMBDA_EXPR_THIS_CAPTURE goes straight to the capture of `this', if it exists.
LAMBDA_EXPR_PENDING_PROXIES is a vector of capture proxies which need to
be pushed once scope returns to the lambda.
LAMBDA_EXPR_MUTABLE_P signals whether this lambda was declared mutable. */
DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0)
/* The declared type of an expression. This is a C++0x extension.
DECLTYPE_TYPE_EXPR is the expression whose type we are computing.
DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P states whether the
expression was parsed as an id-expression or a member access
expression. When false, it was parsed as a full expression.
DECLTYPE_FOR_LAMBDA_CAPTURE is set if we want lambda capture semantics.
DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */
DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0)
/* A type designated by one of the bases type traits.
BASES_TYPE is the type in question. */
DEFTREECODE (BASES, "bases", tcc_type, 0)
/* Dependent operator expressions are given this type rather than a NULL_TREE
type so that we have somewhere to stash the result of phase 1 name lookup
(namely into DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS). */
DEFTREECODE (DEPENDENT_OPERATOR_TYPE, "dependent_operator_type", tcc_type, 0)
/* Used to represent the template information stored by template
specializations.
The accessors are:
TI_TEMPLATE the template declaration associated to the specialization
TI_ARGS the arguments of the template specialization
TI_TYPEDEFS_NEEDING_ACCESS_CHECKING the vector of typedefs used in
the pattern of the template for which access check is needed at template
instantiation time. */
DEFTREECODE (TEMPLATE_INFO, "template_info", tcc_exceptional, 0)
/* OpenMP - #pragma omp depobj
Operand 0: OMP_DEPOBJ_DEPOBJ: Depobj expression
Operand 1: OMP_DEPOBJ_CLAUSES: List of clauses. */
DEFTREECODE (OMP_DEPOBJ, "omp_depobj", tcc_statement, 2)
/* Extensions for Concepts. */
/* Used to represent information associated with constrained declarations. */
DEFTREECODE (CONSTRAINT_INFO, "constraint_info", tcc_exceptional, 0)
/* A wildcard declaration is a placeholder for a template parameter
used to resolve constrained-type-names in concepts. During
resolution, the matching argument is saved as the TREE_TYPE
of the wildcard. */
DEFTREECODE (WILDCARD_DECL, "wildcard_decl", tcc_declaration, 0)
/* A requires-expr has three operands. The first operand is
its parameter list (possibly NULL). The second is a list of
requirements, which are denoted by the _REQ* tree codes
below. The third is a TREE_VEC of template arguments to
be applied when substituting into the parameter list and
requirements, set by tsubst_requires_expr for partial instantiations. */
DEFTREECODE (REQUIRES_EXPR, "requires_expr", tcc_expression, 3)
/* A requirement for an expression. */
DEFTREECODE (SIMPLE_REQ, "simple_req", tcc_expression, 1)
/* A requirement for a type. */
DEFTREECODE (TYPE_REQ, "type_req", tcc_expression, 1)
/* A requirement for an expression and its properties. The
first operand is the expression, and the 2nd is its type.
The accessor COMPOUND_REQ_NOEXCEPT determines whether
the noexcept keyword was present. */
DEFTREECODE (COMPOUND_REQ, "compound_req", tcc_expression, 2)
/* A requires clause within a requires expression. */
DEFTREECODE (NESTED_REQ, "nested_req", tcc_expression, 1)
/* Constraints are modeled as kinds of expressions.
The operands of a constraint can be either types or expressions.
Unlike expressions, constraints do not have a type. */
/* An atomic constraint evaluates an expression E. The operand of the
constraint is its parameter mapping. The actual expression is stored
in the context.
ATOMIC_CONSTR_INFO provides source info to support diagnostics.
ATOMIC_CONSTR_EXPR has the expression to be evaluated.
ATOMIC_CONSTR_PARMS is the parameter mapping for the atomic constraint
and is stored in the type field. */
DEFTREECODE (ATOMIC_CONSTR, "atomic_constr", tcc_expression, 1)
/* The conjunction and disjunction of two constraints, respectively.
Operands are accessed using TREE_OPERAND. The third operand provides
source info for diagnostics.
CONJ_CONSTR_INFO and DISJ_CONSTR_INFO provide access to the source
information of constraints, which is stored in the TREE_TYPE. */
DEFTREECODE (CONJ_CONSTR, "conj_constr", tcc_expression, 2)
DEFTREECODE (DISJ_CONSTR, "disj_constr", tcc_expression, 2)
/* A check constraint represents the checking of a concept
C. It has two operands: the template defining the concept
and a sequence of template arguments.
CHECK_CONSTR_CONCEPT has the concept definition
CHECK_CONSTR_ARGUMENTS are the template arguments */
DEFTREECODE (CHECK_CONSTR, "check_constr", tcc_expression, 2)
/* The co_await expression is used to support coroutines.
Op 0 is the cast expresssion (potentially modified by the
promise "await_transform()" method).
Op1 is a proxy for the temp / coro frame slot 'e' value.
Op2 is the initialiser for Op1 (Op0, potentially modified by any
applicable 'co_await' operator).
Op3 is a vector of the [0] e.ready, [1] e.suspend and [2] e.resume calls.
Op4 is a mode : 0 (await) 1 (yield) 2 (initial) 3 (final) */
DEFTREECODE (CO_AWAIT_EXPR, "co_await", tcc_expression, 5)
/* The co_yield expression is used to support coroutines.
Op0 is the original expr (for use in diagnostics)
Op2 is the co_await derived from this. */
DEFTREECODE (CO_YIELD_EXPR, "co_yield", tcc_expression, 2)
/* The co_return expression is used to support coroutines.
Op0 is the original expr, can be void (for use in diagnostics)
Op1 is the promise return_xxxx call for for the expression given. */
DEFTREECODE (CO_RETURN_EXPR, "co_return", tcc_statement, 2)
/* Different flavors of contracts.
Assertions and preconditions have two operands: a node containing
the their mode and condition. Postconditions have an additional
operand to store the optional name for the result value.
CONTRACT_SEMANTIC has the computed behavior of the contract. */
DEFTREECODE (ASSERTION_STMT, "assertion_stmt", tcc_statement, 3)
DEFTREECODE (PRECONDITION_STMT, "precondition_stmt", tcc_statement, 3)
DEFTREECODE (POSTCONDITION_STMT, "postcondition_stmt", tcc_statement, 4)
/*
Local variables:
mode:c
End:
*/

View File

@@ -0,0 +1,117 @@
/* Interface for the GNU C++ pretty-printer.
Copyright (C) 2003-2023 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_CXX_PRETTY_PRINT_H
#define GCC_CXX_PRETTY_PRINT_H
#include "c-family/c-pretty-print.h"
enum cxx_pretty_printer_flags
{
/* Ask for a qualified-id. */
pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
};
class cxx_pretty_printer : public c_pretty_printer
{
public:
cxx_pretty_printer ();
pretty_printer *clone () const override;
void constant (tree) final override;
void id_expression (tree) final override;
void primary_expression (tree) final override;
void postfix_expression (tree) final override;
void unary_expression (tree) final override;
void multiplicative_expression (tree) final override;
void conditional_expression (tree) final override;
void assignment_expression (tree) final override;
void expression (tree) final override;
void type_id (tree) final override;
void statement (tree) final override;
void declaration (tree) final override;
void declaration_specifiers (tree) final override;
void simple_type_specifier (tree) final override;
void function_specifier (tree) final override;
void declarator (tree) final override;
void direct_declarator (tree) final override;
void abstract_declarator (tree) final override;
void direct_abstract_declarator (tree) final override;
/* This is the enclosing scope of the entity being pretty-printed. */
tree enclosing_scope;
};
#define pp_cxx_cv_qualifier_seq(PP, T) \
pp_c_type_qualifier_list (PP, T)
#define pp_cxx_cv_qualifiers(PP, CV, FT) \
pp_c_cv_qualifiers (PP, CV, FT)
#define pp_cxx_whitespace(PP) pp_c_whitespace (PP)
#define pp_cxx_left_paren(PP) pp_c_left_paren (PP)
#define pp_cxx_right_paren(PP) pp_c_right_paren (PP)
#define pp_cxx_left_brace(PP) pp_c_left_brace (PP)
#define pp_cxx_right_brace(PP) pp_c_right_brace (PP)
#define pp_cxx_left_bracket(PP) pp_c_left_bracket (PP)
#define pp_cxx_right_bracket(PP) pp_c_right_bracket (PP)
#define pp_cxx_dot(PP) pp_c_dot (PP)
#define pp_cxx_ampersand(PP) pp_c_ampersand (PP)
#define pp_cxx_star(PP) pp_c_star (PP)
#define pp_cxx_arrow(PP) pp_c_arrow (PP)
#define pp_cxx_semicolon(PP) pp_c_semicolon (PP)
#define pp_cxx_complement(PP) pp_c_complement (PP)
#define pp_cxx_ws_string(PP, I) pp_c_ws_string (PP, I)
#define pp_cxx_identifier(PP, I) pp_c_identifier (PP, I)
#define pp_cxx_tree_identifier(PP, T) \
pp_c_tree_identifier (PP, T)
void pp_cxx_begin_template_argument_list (cxx_pretty_printer *);
void pp_cxx_end_template_argument_list (cxx_pretty_printer *);
void pp_cxx_colon_colon (cxx_pretty_printer *);
void pp_cxx_separate_with (cxx_pretty_printer *, int);
void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree);
void pp_cxx_trait (cxx_pretty_printer *, tree);
void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree);
void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree);
void pp_cxx_addressof_expression (cxx_pretty_printer *, tree);
void pp_cxx_userdef_literal (cxx_pretty_printer *, tree);
void pp_cxx_requires_clause (cxx_pretty_printer *, tree);
void pp_cxx_requires_expr (cxx_pretty_printer *, tree);
void pp_cxx_simple_requirement (cxx_pretty_printer *, tree);
void pp_cxx_type_requirement (cxx_pretty_printer *, tree);
void pp_cxx_compound_requirement (cxx_pretty_printer *, tree);
void pp_cxx_nested_requirement (cxx_pretty_printer *, tree);
void pp_cxx_predicate_constraint (cxx_pretty_printer *, tree);
void pp_cxx_expression_constraint (cxx_pretty_printer *, tree);
void pp_cxx_type_constraint (cxx_pretty_printer *, tree);
void pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *, tree);
void pp_cxx_argument_deduction_constraint (cxx_pretty_printer *, tree);
void pp_cxx_exception_constraint (cxx_pretty_printer *, tree);
void pp_cxx_parameterized_constraint (cxx_pretty_printer *, tree);
void pp_cxx_conjunction (cxx_pretty_printer *, tree);
void pp_cxx_disjunction (cxx_pretty_printer *, tree);
void pp_cxx_constraint (cxx_pretty_printer *, tree);
void pp_cxx_constrained_type_spec (cxx_pretty_printer *, tree);
void pp_cxx_parameter_mapping (cxx_pretty_printer *, tree);
#endif /* GCC_CXX_PRETTY_PRINT_H */

View File

@@ -0,0 +1,502 @@
/* Declarations for -*- C++ -*- name lookup routines.
Copyright (C) 2003-2023 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_CP_NAME_LOOKUP_H
#define GCC_CP_NAME_LOOKUP_H
#include "c-family/c-common.h"
/* The datatype used to implement C++ scope. */
struct cp_binding_level;
/* Nonzero if this binding is for a local scope, as opposed to a class
or namespace scope. */
#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
/* True if NODE->value is from a base class of the class which is
currently being defined. */
#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
/* The IMPLICIT_TYPEDEF is hidden from ordinary name lookup (it was
injected via a local class's friend decl). The typdef may be in the
VALUE or the TYPE slot. We do not get the situation where the
value and type slots are both filled and both hidden. */
#define HIDDEN_TYPE_BINDING_P(NODE) ((NODE)->type_is_hidden)
/* 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;
/* The scope at which this binding was made. */
cp_binding_level *scope;
bool value_is_inherited : 1;
bool is_local : 1;
bool type_is_hidden : 1;
};
/* 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;
};
/* To support lazy module loading, we squirrel away a section number
(and a couple of flags) in the binding slot of unloaded bindings.
We rely on pointers being aligned and setting the bottom bit to
mark a lazy value. GTY doesn't like an array of union, so we have
a containing struct. */
struct GTY(()) binding_slot {
union GTY((desc ("%1.is_lazy ()"))) binding_slot_lazy {
tree GTY((tag ("false"))) binding;
} u;
operator tree & ()
{
gcc_checking_assert (!is_lazy ());
return u.binding;
}
binding_slot &operator= (tree t)
{
u.binding = t;
return *this;
}
bool is_lazy () const
{
return bool (uintptr_t (u.binding) & 1);
}
void set_lazy (unsigned snum)
{
gcc_checking_assert (!u.binding);
u.binding = tree (uintptr_t ((snum << 1) | 1));
}
void or_lazy (unsigned snum)
{
gcc_checking_assert (is_lazy ());
u.binding = tree (uintptr_t (u.binding) | (snum << 1));
}
unsigned get_lazy () const
{
gcc_checking_assert (is_lazy ());
return unsigned (uintptr_t (u.binding) >> 1);
}
};
/* Bindings for modules are held in a sparse array. There is always a
current TU slot, others are allocated as needed. By construction
of the importing mechanism we only ever need to append to the
array. Rather than have straight index/slot tuples, we bunch them
up for greater packing.
The cluster representation packs well on a 64-bit system. */
#define BINDING_VECTOR_SLOTS_PER_CLUSTER 2
struct binding_index {
unsigned short base;
unsigned short span;
};
struct GTY(()) binding_cluster
{
binding_index GTY((skip)) indices[BINDING_VECTOR_SLOTS_PER_CLUSTER];
binding_slot slots[BINDING_VECTOR_SLOTS_PER_CLUSTER];
};
/* These two fields overlay lang flags. So don't use those. */
#define BINDING_VECTOR_ALLOC_CLUSTERS(NODE) \
(BINDING_VECTOR_CHECK (NODE)->base.u.dependence_info.clique)
#define BINDING_VECTOR_NUM_CLUSTERS(NODE) \
(BINDING_VECTOR_CHECK (NODE)->base.u.dependence_info.base)
#define BINDING_VECTOR_CLUSTER_BASE(NODE) \
(((tree_binding_vec *)BINDING_VECTOR_CHECK (NODE))->vec)
#define BINDING_VECTOR_CLUSTER_LAST(NODE) \
(&BINDING_VECTOR_CLUSTER (NODE, BINDING_VECTOR_NUM_CLUSTERS (NODE) - 1))
#define BINDING_VECTOR_CLUSTER(NODE,IX) \
(((tree_binding_vec *)BINDING_VECTOR_CHECK (NODE))->vec[IX])
struct GTY(()) tree_binding_vec {
struct tree_base base;
tree name;
binding_cluster GTY((length ("%h.base.u.dependence_info.base"))) vec[1];
};
/* The name of a module vector. */
#define BINDING_VECTOR_NAME(NODE) \
(((tree_binding_vec *)BINDING_VECTOR_CHECK (NODE))->name)
/* tree_binding_vec does uses base.u.dependence_info.base field for
length. It does not have lang_flag etc available! */
/* These two flags note if a module-vector contains deduplicated
bindings (i.e. multiple declarations in different imports). */
/* This binding contains duplicate references to a global module
entity. */
#define BINDING_VECTOR_GLOBAL_DUPS_P(NODE) \
(BINDING_VECTOR_CHECK (NODE)->base.static_flag)
/* This binding contains duplicate references to a partioned module
entity. */
#define BINDING_VECTOR_PARTITION_DUPS_P(NODE) \
(BINDING_VECTOR_CHECK (NODE)->base.volatile_flag)
/* These two flags indicate the provenence of the bindings on this
particular vector slot. We can of course determine this from slot
number, but that's a relatively expensive lookup. This avoids
that when iterating. */
/* This slot is part of the global module (a header unit). */
#define MODULE_BINDING_GLOBAL_P(NODE) \
(OVERLOAD_CHECK (NODE)->base.static_flag)
/* This slot is part of the current module (a partition or primary). */
#define MODULE_BINDING_PARTITION_P(NODE) \
(OVERLOAD_CHECK (NODE)->base.volatile_flag)
extern void set_identifier_type_value (tree, tree);
extern void push_binding (tree, tree, cp_binding_level*);
extern void pop_local_binding (tree, tree);
extern void pop_bindings_and_leave_scope (void);
extern tree constructor_name (tree);
extern bool constructor_name_p (tree, tree);
/* 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_stmt_expr, /* GNU statement expression block. */
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. */
};
struct GTY(()) cp_class_binding {
cxx_binding *base;
/* The bound name. */
tree identifier;
};
/* For each binding contour we allocate a binding_level structure
which records the names defined in that contour.
Contours include:
0) the global one
1) one for each function definition,
where internal declarations of the parameters appear.
2) one for each compound statement,
to record its declarations.
The current meaning of a name can be found by searching the levels
from the current one out to the global one.
Off to the side, may be the class_binding_level. This exists only
to catch class-local declarations. It is otherwise nonexistent.
Also there may be binding levels that catch cleanups that must be
run when exceptions occur. Thus, to see whether a name is bound in
the current scope, it is not enough to look in the
CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
instead. */
struct GTY(()) cp_binding_level {
/* A chain of _DECL nodes for all variables, constants, functions,
and typedef types. These are in the reverse of the order
supplied. There may be OVERLOADs on this list, too, but they
are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
tree names;
/* Using directives. */
vec<tree, va_gc> *using_directives;
/* For the binding level corresponding to a class, the entities
declared in the class or its base classes. */
vec<cp_class_binding, va_gc> *class_shadowed;
/* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
is used for all binding levels. The TREE_PURPOSE is the name of
the entity, the TREE_TYPE is the associated type. In addition
the TREE_VALUE is the IDENTIFIER_TYPE_VALUE before we entered
the class. */
tree type_shadowed;
/* For each level (except not the global one),
a chain of BLOCK nodes for all the levels
that were entered and exited one level down. */
tree blocks;
/* The entity (namespace, class, function) the scope of which this
binding contour corresponds to. Otherwise NULL. */
tree this_entity;
/* The binding level which this one is contained in (inherits from). */
cp_binding_level *level_chain;
/* STATEMENT_LIST for statements in this binding contour.
Only used at present for SK_CLEANUP temporary bindings. */
tree statement_list;
/* Binding depth at which this level began. */
int binding_depth;
/* The kind of scope that this object represents. However, a
SK_TEMPLATE_SPEC scope is represented with KIND set to
SK_TEMPLATE_PARMS and EXPLICIT_SPEC_P set to true. */
ENUM_BITFIELD (scope_kind) kind : 4;
/* True if this scope is an SK_TEMPLATE_SPEC scope. This field is
only valid if KIND == SK_TEMPLATE_PARMS. */
BOOL_BITFIELD explicit_spec_p : 1;
/* true means make a BLOCK for this level regardless of all else. */
unsigned keep : 1;
/* Nonzero if this level can safely have additional
cleanup-needing variables added to it. */
unsigned more_cleanups_ok : 1;
unsigned have_cleanups : 1;
/* Transient state set if this scope is of sk_class kind
and is in the process of defining 'this_entity'. Reset
on leaving the class definition to allow for the scope
to be subsequently re-used as a non-defining scope for
'this_entity'. */
unsigned defining_class_p : 1;
/* True for SK_FUNCTION_PARMS of a requires-expression. */
unsigned requires_expression: 1;
/* 22 bits left to fill a 32-bit word. */
};
/* 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))
/* The binding level of the current class, if any. */
#define class_binding_level scope_chain->class_bindings
/* True if SCOPE designates the global scope binding contour. */
#define global_scope_p(SCOPE) \
((SCOPE) == NAMESPACE_LEVEL (global_namespace))
extern cp_binding_level *leave_scope (void);
extern bool kept_level_p (void);
extern bool global_bindings_p (void);
extern bool toplevel_bindings_p (void);
extern bool namespace_bindings_p (void);
extern bool local_bindings_p (void);
extern bool template_parm_scope_p (void);
extern scope_kind innermost_scope_kind (void);
extern cp_binding_level *begin_scope (scope_kind, tree);
extern void print_binding_stack (void);
extern void pop_everything (void);
extern void keep_next_level (bool);
extern bool is_ancestor (tree ancestor, tree descendant);
extern bool is_nested_namespace (tree parent, tree descendant,
bool inline_only = false);
extern tree push_scope (tree);
extern void pop_scope (tree);
extern tree push_inner_scope (tree);
extern void pop_inner_scope (tree, tree);
extern void push_binding_level (cp_binding_level *);
extern bool handle_namespace_attrs (tree, tree);
extern void pushlevel_class (void);
extern void poplevel_class (void);
/* What kind of scopes name lookup looks in. An enum class so we
don't accidentally mix integers. */
enum class LOOK_where
{
BLOCK = 1 << 0, /* Consider block scopes. */
CLASS = 1 << 1, /* Consider class scopes. */
NAMESPACE = 1 << 2, /* Consider namespace scopes. */
ALL = BLOCK | CLASS | NAMESPACE,
BLOCK_NAMESPACE = BLOCK | NAMESPACE,
CLASS_NAMESPACE = CLASS | NAMESPACE,
};
constexpr LOOK_where operator| (LOOK_where a, LOOK_where b)
{
return LOOK_where (unsigned (a) | unsigned (b));
}
constexpr LOOK_where operator& (LOOK_where a, LOOK_where b)
{
return LOOK_where (unsigned (a) & unsigned (b));
}
enum class LOOK_want
{
NORMAL = 0, /* Normal lookup -- non-types can hide implicit types. */
TYPE = 1 << 1, /* We only want TYPE_DECLS. */
NAMESPACE = 1 << 2, /* We only want NAMESPACE_DECLS. */
HIDDEN_FRIEND = 1 << 3, /* See hidden friends. */
HIDDEN_LAMBDA = 1 << 4, /* See lambda-ignored entities. */
TYPE_NAMESPACE = TYPE | NAMESPACE, /* Either NAMESPACE or TYPE. */
};
constexpr LOOK_want operator| (LOOK_want a, LOOK_want b)
{
return LOOK_want (unsigned (a) | unsigned (b));
}
constexpr LOOK_want operator& (LOOK_want a, LOOK_want b)
{
return LOOK_want (unsigned (a) & unsigned (b));
}
extern tree lookup_name (tree, LOOK_where, LOOK_want = LOOK_want::NORMAL);
/* Also declared in c-family/c-common.h. */
extern tree lookup_name (tree name);
inline tree lookup_name (tree name, LOOK_want want)
{
return lookup_name (name, LOOK_where::ALL, want);
}
enum class TAG_how
{
CURRENT_ONLY = 0, // Look and insert only in current scope
GLOBAL = 1, // Unqualified lookup, innermost-non-class insertion
INNERMOST_NON_CLASS = 2, // Look and insert only into
// innermost-non-class
HIDDEN_FRIEND = 3, // As INNERMOST_NON_CLASS, but hide it
};
extern tree lookup_elaborated_type (tree, TAG_how);
extern tree get_namespace_binding (tree ns, tree id);
extern void set_global_binding (tree decl);
inline tree get_global_binding (tree id)
{
return get_namespace_binding (NULL_TREE, id);
}
extern tree lookup_qualified_name (tree scope, tree name,
LOOK_want = LOOK_want::NORMAL,
bool = true);
extern tree lookup_qualified_name (tree scope, const char *name,
LOOK_want = LOOK_want::NORMAL,
bool = true);
extern bool pushdecl_class_level (tree);
extern tree pushdecl_namespace_level (tree, bool hiding = false);
extern bool push_class_level_binding (tree, tree);
extern tree get_local_decls ();
extern int function_parm_depth (void);
extern tree cp_namespace_decls (tree);
extern void set_decl_namespace (tree, tree, bool);
extern void push_decl_namespace (tree);
extern void pop_decl_namespace (void);
extern void do_namespace_alias (tree, tree);
extern tree do_class_using_decl (tree, tree);
extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
extern tree search_anon_aggr (tree, tree, bool = false);
extern tree get_class_binding_direct (tree, tree, bool want_type = false);
extern tree get_class_binding (tree, tree, bool want_type = false);
extern tree *find_member_slot (tree klass, tree name);
extern tree *add_member_slot (tree klass, tree name);
extern void resort_type_member_vec (void *, void *,
gt_pointer_operator, void *);
extern vec<tree, va_gc> *set_class_bindings (tree, int extra = 0);
extern void insert_late_enum_def_bindings (tree, tree);
extern tree innermost_non_namespace_value (tree);
extern cxx_binding *outer_binding (tree, cxx_binding *, bool);
extern void cp_emit_debug_info_for_using (tree, tree);
extern void finish_nonmember_using_decl (tree scope, tree name);
extern void finish_using_directive (tree target, tree attribs);
void push_local_extern_decl_alias (tree decl);
extern tree pushdecl (tree, bool hiding = false);
extern tree pushdecl_outermost_localscope (tree);
extern tree pushdecl_top_level (tree);
extern tree pushdecl_top_level_and_finish (tree, tree);
extern tree pushtag (tree, tree, TAG_how = TAG_how::CURRENT_ONLY);
extern int push_namespace (tree, bool make_inline = false);
extern void pop_namespace (void);
extern void push_nested_namespace (tree);
extern void pop_nested_namespace (tree);
extern void push_to_top_level (void);
extern void pop_from_top_level (void);
extern bool maybe_push_to_top_level (tree);
extern void maybe_pop_from_top_level (bool);
extern void push_using_decl_bindings (tree, tree);
/* Lower level interface for modules. */
extern tree *mergeable_namespace_slots (tree ns, tree name, bool is_attached,
tree *mvec);
extern void add_mergeable_namespace_entity (tree *slot, tree decl);
extern tree lookup_class_binding (tree ctx, tree name);
extern bool import_module_binding (tree ctx, tree name, unsigned mod,
unsigned snum);
extern bool set_module_binding (tree ctx, tree name, unsigned mod,
int mod_glob_flag,
tree value, tree type, tree visible);
extern void add_module_namespace_decl (tree ns, tree decl);
enum WMB_Flags
{
WMB_None = 0,
WMB_Dups = 1 << 0,
WMB_Export = 1 << 1,
WMB_Using = 1 << 2,
WMB_Hidden = 1 << 3,
};
extern unsigned walk_module_binding (tree binding, bitmap partitions,
bool (*)(tree decl, WMB_Flags, void *data),
void *data);
extern tree add_imported_namespace (tree ctx, tree name, location_t,
unsigned module,
bool inline_p, bool visible_p);
extern const char *get_cxx_dialect_name (enum cxx_dialect dialect);
#endif /* GCC_CP_NAME_LOOKUP_H */

View File

@@ -0,0 +1,163 @@
/* -*-C-*-
This file contains definitions of the various C++ operators,
including both overloadable operators (like `+') and
non-overloadable operators (like the `?:' ternary operator).
Written by Mark Mitchell <mark@codesourcery.com>
Copyright (C) 2000-2023 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* The DEF_OPERATOR macro takes the following arguments:
NAME
The name of the operator, as a C string, but without the
preceding `operator'. This is the name that would be given in
the source program. For `operator +', for example, this would be
`+'.
CODE
The tree_code for this operator. For `operator +', for example,
this would be PLUS_EXPR. Because there are no tree codes for
assignment operators, the same tree-codes are reused; i.e.,
`operator +' will also have PLUS_EXPR as its CODE.
MANGLING
The mangling prefix for the operator, as a C string, and as
mangled under the new ABI. For `operator +', for example, this
would be "pl".
FLAGS
ovl_op_flags bits. Postincrement and postdecrement operators are
marked as binary.
Before including this file, you should define DEF_OPERATOR
to take these arguments.
There is code (such as in grok_op_properties) that depends on the
order the operators are presented in this file. Unary_ops must
preceed a matching binary op (i.e. '+'). Assignment operators must
be last, after OPERATOR_TRANSITION. */
/* Use DEF_ASSN_OPERATOR to define an assignment operator. Its
arguments are as for DEF_OPERATOR, but there is no need to provide
FLAGS (OVL_OP_FLAG_BINARY). */
#ifndef DEF_ASSN_OPERATOR
#define DEF_ASSN_OPERATOR(NAME, CODE, MANGLING) \
DEF_OPERATOR(NAME, CODE, MANGLING, OVL_OP_FLAG_BINARY)
#endif
/* Memory allocation operators. ARITY has special meaning. */
DEF_OPERATOR ("new", NEW_EXPR, "nw", OVL_OP_FLAG_ALLOC)
DEF_OPERATOR ("new []", VEC_NEW_EXPR, "na",
OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_VEC)
DEF_OPERATOR ("delete", DELETE_EXPR, "dl",
OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE)
DEF_OPERATOR ("delete []", VEC_DELETE_EXPR, "da",
OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE | OVL_OP_FLAG_VEC)
/* Unary operators. */
DEF_OPERATOR ("+", UNARY_PLUS_EXPR, "ps", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("-", NEGATE_EXPR, "ng", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("&", ADDR_EXPR, "ad", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("*", INDIRECT_REF, "de", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("~", BIT_NOT_EXPR, "co", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("!", TRUTH_NOT_EXPR, "nt", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("++", PREINCREMENT_EXPR, "pp", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("--", PREDECREMENT_EXPR, "mm", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("->", COMPONENT_REF, "pt", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("co_await", CO_AWAIT_EXPR, "aw", OVL_OP_FLAG_UNARY)
/* These are extensions. */
DEF_OPERATOR ("alignof", ALIGNOF_EXPR, "az", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", OVL_OP_FLAG_UNARY)
DEF_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", OVL_OP_FLAG_UNARY)
/* Binary operators. */
DEF_OPERATOR ("+", PLUS_EXPR, "pl", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("-", MINUS_EXPR, "mi", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("*", MULT_EXPR, "ml", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("/", TRUNC_DIV_EXPR, "dv", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("%", TRUNC_MOD_EXPR, "rm", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("&", BIT_AND_EXPR, "an", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("|", BIT_IOR_EXPR, "or", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("^", BIT_XOR_EXPR, "eo", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("<<", LSHIFT_EXPR, "ls", OVL_OP_FLAG_BINARY)
DEF_OPERATOR (">>", RSHIFT_EXPR, "rs", OVL_OP_FLAG_BINARY)
/* defaultable_fn_check relies on the ordering of the comparison operators. */
DEF_OPERATOR ("==", EQ_EXPR, "eq", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("!=", NE_EXPR, "ne", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("<", LT_EXPR, "lt", OVL_OP_FLAG_BINARY)
DEF_OPERATOR (">", GT_EXPR, "gt", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("<=", LE_EXPR, "le", OVL_OP_FLAG_BINARY)
DEF_OPERATOR (">=", GE_EXPR, "ge", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("<=>", SPACESHIP_EXPR, "ss", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", OVL_OP_FLAG_BINARY)
DEF_OPERATOR (",", COMPOUND_EXPR, "cm", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("->*", MEMBER_REF, "pm", OVL_OP_FLAG_BINARY)
DEF_OPERATOR (".*", DOTSTAR_EXPR, "ds", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("[]", ARRAY_REF, "ix", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", OVL_OP_FLAG_BINARY)
DEF_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", OVL_OP_FLAG_BINARY)
/* Miscellaneous. */
DEF_OPERATOR ("?:", COND_EXPR, "qu", OVL_OP_FLAG_NONE)
DEF_OPERATOR ("()", CALL_EXPR, "cl", OVL_OP_FLAG_NONE)
/* Operators needed for mangling. */
DEF_OPERATOR (NULL, CAST_EXPR, "cv", OVL_OP_FLAG_UNARY)
DEF_OPERATOR (NULL, DYNAMIC_CAST_EXPR, "dc", OVL_OP_FLAG_UNARY)
DEF_OPERATOR (NULL, REINTERPRET_CAST_EXPR, "rc", OVL_OP_FLAG_UNARY)
DEF_OPERATOR (NULL, CONST_CAST_EXPR, "cc", OVL_OP_FLAG_UNARY)
DEF_OPERATOR (NULL, STATIC_CAST_EXPR, "sc", OVL_OP_FLAG_UNARY)
DEF_OPERATOR (NULL, SCOPE_REF, "sr", OVL_OP_FLAG_NONE)
DEF_OPERATOR (NULL, EXPR_PACK_EXPANSION, "sp", OVL_OP_FLAG_NONE)
DEF_OPERATOR (NULL, UNARY_LEFT_FOLD_EXPR, "fl", OVL_OP_FLAG_NONE)
DEF_OPERATOR (NULL, UNARY_RIGHT_FOLD_EXPR, "fr", OVL_OP_FLAG_NONE)
DEF_OPERATOR (NULL, BINARY_LEFT_FOLD_EXPR, "fL", OVL_OP_FLAG_NONE)
DEF_OPERATOR (NULL, BINARY_RIGHT_FOLD_EXPR, "fR", OVL_OP_FLAG_NONE)
#ifdef OPERATOR_TRANSITION
OPERATOR_TRANSITION
#undef OPERATOR_TRANSITION
#endif
/* Assignment operators. */
DEF_ASSN_OPERATOR ("=", NOP_EXPR, "aS")
DEF_ASSN_OPERATOR ("+=", PLUS_EXPR, "pL")
DEF_ASSN_OPERATOR ("-=", MINUS_EXPR, "mI")
DEF_ASSN_OPERATOR ("*=", MULT_EXPR, "mL")
DEF_ASSN_OPERATOR ("/=", TRUNC_DIV_EXPR, "dV")
DEF_ASSN_OPERATOR ("%=", TRUNC_MOD_EXPR, "rM")
DEF_ASSN_OPERATOR ("&=", BIT_AND_EXPR, "aN")
DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR")
DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO")
DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS")
DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS")
#undef DEF_ASSN_OPERATOR
#undef DEF_OPERATOR

View File

@@ -0,0 +1,54 @@
/* Utilities for querying and manipulating type trees.
Copyright (C) 2013-2023 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_CP_TYPE_UTILS_H
#define GCC_CP_TYPE_UTILS_H
/* Returns the first tree within T that is directly matched by PRED. T may be a
type or PARM_DECL and is incrementally decomposed toward its type-specifier
until a match is found. NULL is returned if PRED does not match any
part of T.
This is primarily intended for detecting whether T uses `auto' or a concept
identifier. Since either of these can only appear as a type-specifier for
the declaration in question, only top-level qualifications are traversed;
find_type_usage does not look through the whole type. */
inline tree
find_type_usage (tree t, bool (*pred) (const_tree))
{
if (pred (t))
return t;
enum tree_code code = TREE_CODE (t);
if (code == POINTER_TYPE || code == REFERENCE_TYPE
|| code == PARM_DECL || code == OFFSET_TYPE
|| code == FUNCTION_TYPE || code == METHOD_TYPE
|| code == ARRAY_TYPE)
return find_type_usage (TREE_TYPE (t), pred);
if (TYPE_PTRMEMFUNC_P (t))
return find_type_usage
(TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
return NULL_TREE;
}
#endif // GCC_CP_TYPE_UTILS_H