aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-tree.cc304
-rw-r--r--gcc/rust/backend/rust-tree.h149
2 files changed, 439 insertions, 14 deletions
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 4b63499..4359c3d 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -1117,9 +1117,6 @@ is_overloaded_fn (tree x)
if (TREE_CODE (x) == COMPONENT_REF)
x = TREE_OPERAND (x, 1);
- if ((TREE_CODE (x) == OVERLOAD && !OVL_SINGLE_P (x)))
- return 2;
-
return OVL_P (x);
}
@@ -1165,4 +1162,305 @@ lookup_add (tree fns, tree lookup)
return lookup;
}
+
+// forked from gcc/cp/typeck.cc type_memfn_quals
+
+/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
+ METHOD_TYPE. */
+
+int
+type_memfn_quals (const_tree type)
+{
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ return TYPE_QUALS (type);
+ else if (TREE_CODE (type) == METHOD_TYPE)
+ return rs_type_quals (class_of_this_parm (type));
+ else
+ gcc_unreachable ();
+}
+
+// forked from gcc/cp/pt.cc find_parameter_pack_data
+
+/* Structure used to track the progress of find_parameter_packs_r. */
+struct find_parameter_pack_data
+{
+ /* TREE_LIST that will contain all of the parameter packs found by
+ the traversal. */
+ tree *parameter_packs;
+
+ /* Set of AST nodes that have been visited by the traversal. */
+ hash_set<tree> *visited;
+
+ /* True iff we're making a type pack expansion. */
+ bool type_pack_expansion_p;
+
+ /* True iff we found a subtree that has the extra args mechanism. */
+ bool found_extra_args_tree_p = false;
+};
+
+// forked from gcc/cp/lex.cc conv_type_hasher
+
+/* Hasher for the conversion operator name hash table. */
+struct conv_type_hasher : ggc_ptr_hash<tree_node>
+{
+ /* Hash NODE, an identifier node in the table. TYPE_UID is
+ suitable, as we're not concerned about matching canonicalness
+ here. */
+ static hashval_t hash (tree node)
+ {
+ return (hashval_t) TYPE_UID (TREE_TYPE (node));
+ }
+
+ /* Compare NODE, an identifier node in the table, against TYPE, an
+ incoming TYPE being looked up. */
+ static bool equal (tree node, tree type) { return TREE_TYPE (node) == type; }
+};
+
+static GTY (()) hash_table<conv_type_hasher> *conv_type_names;
+
+// forked from gcc/cp/lex.cc make_conv_op_name
+
+/* Return an identifier for a conversion operator to TYPE. We can get
+ from the returned identifier to the type. We store TYPE, which is
+ not necessarily the canonical type, which allows us to report the
+ form the user used in error messages. All these identifiers are
+ not in the identifier hash table, and have the same string name.
+ These IDENTIFIERS are not in the identifier hash table, and all
+ have the same IDENTIFIER_STRING. */
+
+tree
+make_conv_op_name (tree type)
+{
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (conv_type_names == NULL)
+ conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
+
+ tree *slot
+ = conv_type_names->find_slot_with_hash (type, (hashval_t) TYPE_UID (type),
+ INSERT);
+ tree identifier = *slot;
+ if (!identifier)
+ {
+ /* Create a raw IDENTIFIER outside of the identifier hash
+ table. */
+ identifier = copy_node (conv_op_identifier);
+
+ /* Just in case something managed to bind. */
+ IDENTIFIER_BINDING (identifier) = NULL;
+
+ /* Hang TYPE off the identifier so it can be found easily later
+ when performing conversions. */
+ TREE_TYPE (identifier) = type;
+
+ *slot = identifier;
+ }
+
+ return identifier;
+}
+
+// forked from gcc/cp/pt.cc builtin_pack_fn_p
+
+/* True iff FN is a function representing a built-in variadic parameter
+ pack. */
+
+bool
+builtin_pack_fn_p (tree fn)
+{
+ if (!fn || TREE_CODE (fn) != FUNCTION_DECL
+ || !DECL_IS_UNDECLARED_BUILTIN (fn))
+ return false;
+
+ if (id_equal (DECL_NAME (fn), "__integer_pack"))
+ return true;
+
+ return false;
+}
+
+// forked from gcc/cp/pt.cc builtin_pack_call_p
+
+/* True iff CALL is a call to a function representing a built-in variadic
+ parameter pack. */
+
+static bool
+builtin_pack_call_p (tree call)
+{
+ if (TREE_CODE (call) != CALL_EXPR)
+ return false;
+ return builtin_pack_fn_p (CALL_EXPR_FN (call));
+}
+
+// forked from gcc/cp/pt.cc has_extra_args_mechanism_p
+
+/* Return true if the tree T has the extra args mechanism for
+ avoiding partial instantiation. */
+
+static bool
+has_extra_args_mechanism_p (const_tree t)
+{
+ return false;
+}
+
+// forked from gcc/cp/pt.cc find_parameter_packs_r
+
+/* Identifies all of the argument packs that occur in a template
+ argument and appends them to the TREE_LIST inside DATA, which is a
+ find_parameter_pack_data structure. This is a subroutine of
+ make_pack_expansion and uses_parameter_packs. */
+static tree
+find_parameter_packs_r (tree *tp, int *walk_subtrees, void *data)
+{
+ tree t = *tp;
+ struct find_parameter_pack_data *ppd
+ = (struct find_parameter_pack_data *) data;
+ bool parameter_pack_p = false;
+
+#define WALK_SUBTREE(NODE) \
+ rs_walk_tree (&(NODE), &find_parameter_packs_r, ppd, ppd->visited)
+
+ /* Don't look through typedefs; we are interested in whether a
+ parameter pack is actually written in the expression/type we're
+ looking at, not the target type. */
+ if (TYPE_P (t) && typedef_variant_p (t))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ /* Identify whether this is a parameter pack or not. */
+ switch (TREE_CODE (t))
+ {
+ case FIELD_DECL:
+ case PARM_DECL:
+ break;
+
+ case VAR_DECL:
+ break;
+
+ case CALL_EXPR:
+ if (builtin_pack_call_p (t))
+ parameter_pack_p = true;
+ break;
+
+ case BASES:
+ parameter_pack_p = true;
+ break;
+ default:
+ /* Not a parameter pack. */
+ break;
+ }
+
+ if (parameter_pack_p)
+ {
+ /* Add this parameter pack to the list. */
+ *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
+ }
+
+ if (TYPE_P (t))
+ rs_walk_tree (&TYPE_CONTEXT (t), &find_parameter_packs_r, ppd,
+ ppd->visited);
+
+ /* This switch statement will return immediately if we don't find a
+ parameter pack. ??? Should some of these be in cp_walk_subtrees? */
+ switch (TREE_CODE (t))
+ {
+ case DECL_EXPR: {
+ tree decl = DECL_EXPR_DECL (t);
+ if (is_typedef_decl (decl))
+ /* Since we stop at typedefs above, we need to look through them at
+ the point of the DECL_EXPR. */
+ rs_walk_tree (&DECL_ORIGINAL_TYPE (decl), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ return NULL_TREE;
+ }
+
+ case INTEGER_TYPE:
+ rs_walk_tree (&TYPE_MAX_VALUE (t), &find_parameter_packs_r, ppd,
+ ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case IDENTIFIER_NODE:
+ rs_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case DECLTYPE_TYPE: {
+ /* When traversing a DECLTYPE_TYPE_EXPR, we need to set
+ type_pack_expansion_p to false so that any placeholders
+ within the expression don't get marked as parameter packs. */
+ bool type_pack_expansion_p = ppd->type_pack_expansion_p;
+ ppd->type_pack_expansion_p = false;
+ rs_walk_tree (&DECLTYPE_TYPE_EXPR (t), &find_parameter_packs_r, ppd,
+ ppd->visited);
+ ppd->type_pack_expansion_p = type_pack_expansion_p;
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ case IF_STMT:
+ rs_walk_tree (&IF_COND (t), &find_parameter_packs_r, ppd, ppd->visited);
+ rs_walk_tree (&THEN_CLAUSE (t), &find_parameter_packs_r, ppd,
+ ppd->visited);
+ rs_walk_tree (&ELSE_CLAUSE (t), &find_parameter_packs_r, ppd,
+ ppd->visited);
+ /* Don't walk into IF_STMT_EXTRA_ARGS. */
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ WALK_SUBTREE (TYPE_RAISES_EXCEPTIONS (t));
+ break;
+
+ default:
+ return NULL_TREE;
+ }
+
+#undef WALK_SUBTREE
+
+ return NULL_TREE;
+}
+
+// forked from gcc/cp/typeck.cc type_memfn_rqual
+
+/* Returns the function-ref-qualifier for TYPE */
+
+rs_ref_qualifier
+type_memfn_rqual (const_tree type)
+{
+ gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
+
+ if (!FUNCTION_REF_QUALIFIED (type))
+ return REF_QUAL_NONE;
+ else if (FUNCTION_RVALUE_QUALIFIED (type))
+ return REF_QUAL_RVALUE;
+ else
+ return REF_QUAL_LVALUE;
+}
+
+// forked from gcc/cp/lex.cc maybe_add_lang_type_raw
+
+/* Add a raw lang_type to T, a type, should it need one. */
+
+bool
+maybe_add_lang_type_raw (tree t)
+{
+ if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
+ return false;
+
+ auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc (
+ sizeof (struct lang_type)));
+ TYPE_LANG_SPECIFIC (t) = lt;
+
+ if (GATHER_STATISTICS)
+ {
+ tree_node_counts[(int) lang_type] += 1;
+ tree_node_sizes[(int) lang_type] += sizeof (struct lang_type);
+ }
+
+ return true;
+}
+
} // namespace Rust
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 8d9b9f0..99ec33c 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -22,6 +22,7 @@
#include "rust-system.h"
#include "coretypes.h"
#include "tree.h"
+#include "cpplib.h"
/* Returns true if NODE is a pointer. */
#define TYPE_PTR_P(NODE) (TREE_CODE (NODE) == POINTER_TYPE)
@@ -664,6 +665,74 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
order. */
#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T))
+/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */
+#define FUNCTION_REF_QUALIFIED(NODE) \
+ TREE_LANG_FLAG_4 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* 1 iff FUNCTION_TYPE or METHOD_TYPE has &&-ref-qualifier. */
+#define FUNCTION_RVALUE_QUALIFIED(NODE) \
+ TREE_LANG_FLAG_5 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* Get the POINTER_TYPE to the METHOD_TYPE associated with this
+ pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true,
+ before using this macro. */
+#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) \
+ (cp_build_qualified_type (TREE_TYPE (TYPE_FIELDS (NODE)), \
+ rs_type_quals (NODE)))
+
+/* As above, but can be used in places that want an lvalue at the expense
+ of not necessarily having the correct cv-qualifiers. */
+#define TYPE_PTRMEMFUNC_FN_TYPE_RAW(NODE) (TREE_TYPE (TYPE_FIELDS (NODE)))
+
+/* True if this type is dependent. This predicate is only valid if
+ TYPE_DEPENDENT_P_VALID is true. */
+#define TYPE_DEPENDENT_P(NODE) TYPE_LANG_FLAG_0 (NODE)
+
+/* True if dependent_type_p has been called for this type, with the
+ result that TYPE_DEPENDENT_P is valid. */
+#define TYPE_DEPENDENT_P_VALID(NODE) TYPE_LANG_FLAG_6 (NODE)
+
+/* Nonzero for _TYPE node means that this type does not have a trivial
+ destructor. Therefore, destroying an object of this type will
+ involve a call to a destructor. This can apply to objects of
+ ARRAY_TYPE if the type of the elements needs a destructor. */
+#define TYPE_HAS_NONTRIVIAL_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_4 (NODE))
+
+/* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that
+ this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE
+ will be NULL_TREE to indicate a throw specification of `()', or
+ no exceptions allowed. For a noexcept specification, TREE_VALUE
+ is NULL_TREE and TREE_PURPOSE is the constant-expression. For
+ a deferred noexcept-specification, TREE_PURPOSE is a DEFERRED_NOEXCEPT
+ (for templates) or an OVERLOAD list of functions (for implicitly
+ declared functions). */
+#define TYPE_RAISES_EXCEPTIONS(NODE) \
+ TYPE_LANG_SLOT_1 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* Identifiers map directly to block or class-scope bindings.
+ Namespace-scope bindings are held in hash tables on the respective
+ namespaces. The identifier bindings are the innermost active
+ binding, from whence you can get the decl and/or implicit-typedef
+ of an elaborated type. When not bound to a local entity the
+ values are NULL. */
+#define IDENTIFIER_BINDING(NODE) (LANG_IDENTIFIER_CAST (NODE)->bindings)
+
+#define LANG_IDENTIFIER_CAST(NODE) \
+ ((struct lang_identifier *) IDENTIFIER_NODE_CHECK (NODE))
+
+/* IF_STMT accessors. These give access to the condition of the if
+ statement, the then block of the if statement, and the else block
+ of the if statement if it exists. */
+#define IF_COND(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 0)
+#define THEN_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
+#define ELSE_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
+#define IF_SCOPE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 3)
+#define IF_STMT_CONSTEXPR_P(NODE) TREE_LANG_FLAG_0 (IF_STMT_CHECK (NODE))
+#define IF_STMT_CONSTEVAL_P(NODE) TREE_LANG_FLAG_2 (IF_STMT_CHECK (NODE))
+
+/* The expression in question for a DECLTYPE_TYPE. */
+#define DECLTYPE_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (DECLTYPE_TYPE_CHECK (NODE)))
+
// Below macros are copied from gcc/c-family/c-common.h
/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */
@@ -689,17 +758,6 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
((rs_type_quals (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \
== TYPE_QUAL_CONST)
-/* [basic.fundamental]
-
- Types bool, char, wchar_t, and the signed and unsigned integer types
- are collectively called integral types.
-
- Note that INTEGRAL_TYPE_P, as defined in tree.h, allows enumeration
- types as well, which is incorrect in C++. Keep these checks in
- ascending code order. */
-#define RS_INTEGRAL_TYPE_P(TYPE) \
- (TREE_CODE (TYPE) == BOOLEAN_TYPE || TREE_CODE (TYPE) == INTEGER_TYPE)
-
/* Returns true if TYPE is an integral or enumeration name. Keep
these checks in ascending code order. */
#define INTEGRAL_OR_ENUMERATION_TYPE_P(TYPE) \
@@ -740,6 +798,44 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
// Above macros are copied from gcc/cp/name-lookup.cc
+// forked from gcc/cp/name-lookup.h
+
+/* Datatype that represents binding established by a declaration between
+ a name and a C++ entity. */
+struct GTY (()) cxx_binding
+{
+ /* Link to chain together various bindings for this name. */
+ cxx_binding *previous;
+ /* The non-type entity this name is bound to. */
+ tree value;
+ /* The type entity this name is bound to. */
+ tree type;
+
+ bool value_is_inherited : 1;
+ bool is_local : 1;
+ bool type_is_hidden : 1;
+};
+
+// forked from gcc/c-family/c-common.h c_common_identifier
+
+/* Identifier part common to the C front ends. Inherits from
+ tree_identifier, despite appearances. */
+struct GTY (()) c_common_identifier
+{
+ struct tree_common common;
+ struct cpp_hashnode node; // from cpplib.h
+};
+
+// forked from gcc/cp/cp-tree.h lang_identifier
+
+/* Language-dependent contents of an identifier. */
+
+struct GTY (()) lang_identifier
+{
+ struct c_common_identifier c_common;
+ cxx_binding *bindings;
+};
+
// forked from gcc/cp/cp-tree.h tree_overload
/* OVL_HIDDEN_P nodes come before other nodes. */
@@ -953,6 +1049,15 @@ struct GTY (()) lang_type
namespace Rust {
+// forked from gcc/cp/cp-tree.h cp_ref_qualifier
+
+enum rs_ref_qualifier
+{
+ REF_QUAL_NONE = 0,
+ REF_QUAL_LVALUE = 1,
+ REF_QUAL_RVALUE = 2
+};
+
// forked from gcc/cp/cp-tree.h tsubst_flags
/* Bitmask flags to control type substitution. */
@@ -1227,6 +1332,28 @@ ovl_first (tree node)
return node;
}
+// forked from gcc/cp/cp-tree.h type_of_this_parm
+
+/* Return the type of the `this' parameter of FNTYPE. */
+
+inline tree
+type_of_this_parm (const_tree fntype)
+{
+ function_args_iterator iter;
+ gcc_assert (TREE_CODE (fntype) == METHOD_TYPE);
+ function_args_iter_init (&iter, fntype);
+ return function_args_iter_cond (&iter);
+}
+
+// forked from gcc/cp/cp-tree.h class_of_this_parm
+
+/* Return the class of the `this' parameter of FNTYPE. */
+
+inline tree
+class_of_this_parm (const_tree fntype)
+{
+ return TREE_TYPE (type_of_this_parm (fntype));
+}
} // namespace Rust
#endif // RUST_TREE