aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-tree.cc248
-rw-r--r--gcc/rust/backend/rust-tree.h398
2 files changed, 628 insertions, 18 deletions
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 22e91f4..e1ab7f1 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -28,12 +28,17 @@
#include "timevar.h"
#include "convert.h"
#include "gimple-expr.h"
+#include "gimplify.h"
+#include "function.h"
+#include "gcc-rich-location.h"
// forked from gcc/c-family/c-common.cc c_global_trees
tree c_global_trees[CTI_MAX];
// forked from gcc/cp/decl.cc cp_global_trees
tree cp_global_trees[CPTI_MAX];
+struct saved_scope *scope_chain;
+
namespace Rust {
void
@@ -3721,4 +3726,247 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
return orig_expr;
}
+
+// forked from gcc/cp/pt.cc instantiate_non_dependent_or_null
+
+/* Like instantiate_non_dependent_expr, but return NULL_TREE rather than
+ an uninstantiated expression. */
+
+tree
+instantiate_non_dependent_or_null (tree expr)
+{
+ if (expr == NULL_TREE)
+ return NULL_TREE;
+
+ return expr;
+}
+
+// forked from gcc/cp/pt.cc resolve_nondeduced_context_or_error
+
+/* As above, but error out if the expression remains overloaded. */
+
+tree
+resolve_nondeduced_context_or_error (tree exp, tsubst_flags_t complain)
+{
+ exp = resolve_nondeduced_context (exp, complain);
+ if (type_unknown_p (exp))
+ {
+ if (complain & tf_error)
+ cxx_incomplete_type_error (exp, TREE_TYPE (exp));
+ return error_mark_node;
+ }
+ return exp;
+}
+
+// forked from gcc/cp/tree.cc really_overloaded_fn
+
+/* Returns true iff X is an expression for an overloaded function
+ whose type cannot be known without performing overload
+ resolution. */
+
+bool
+really_overloaded_fn (tree x)
+{
+ return is_overloaded_fn (x) == 2;
+}
+
+// forked from gcc/cp/typeck..cc invalid_nonstatic_memfn_p
+
+/* EXPR is being used in a context that is not a function call.
+ Enforce:
+
+ [expr.ref]
+
+ The expression can be used only as the left-hand operand of a
+ member function call.
+
+ [expr.mptr.operator]
+
+ If the result of .* or ->* is a function, then that result can be
+ used only as the operand for the function call operator ().
+
+ by issuing an error message if appropriate. Returns true iff EXPR
+ violates these rules. */
+
+bool
+invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain)
+{
+ if (expr == NULL_TREE)
+ return false;
+ /* Don't enforce this in MS mode. */
+ if (flag_ms_extensions)
+ return false;
+ if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
+ expr = get_first_fn (expr);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (expr))
+ {
+ if (complain & tf_error)
+ {
+ if (DECL_P (expr))
+ {
+ error_at (loc, "invalid use of non-static member function %qD",
+ expr);
+ inform (DECL_SOURCE_LOCATION (expr), "declared here");
+ }
+ else
+ error_at (loc,
+ "invalid use of non-static member function of "
+ "type %qT",
+ TREE_TYPE (expr));
+ }
+ return true;
+ }
+ return false;
+}
+
+// forked from gcc/cp/call.cc strip_top_quals
+
+tree
+strip_top_quals (tree t)
+{
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ return t;
+ return rs_build_qualified_type (t, 0);
+}
+
+// forked from gcc/cp/typeck2.cc cxx_incomplete_type_inform
+
+/* Print an inform about the declaration of the incomplete type TYPE. */
+
+void
+cxx_incomplete_type_inform (const_tree type)
+{
+ if (!TYPE_MAIN_DECL (type))
+ return;
+
+ location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type));
+ tree ptype = strip_top_quals (CONST_CAST_TREE (type));
+
+ if (current_class_type && TYPE_BEING_DEFINED (current_class_type)
+ && same_type_p (ptype, current_class_type))
+ inform (loc,
+ "definition of %q#T is not complete until "
+ "the closing brace",
+ ptype);
+ else
+ inform (loc, "forward declaration of %q#T", ptype);
+}
+
+// forked from gcc/cp/typeck2.cc cxx_incomplete_type_diagnostic
+
+/* Print an error message for invalid use of an incomplete type.
+ VALUE is the expression that was used (or 0 if that isn't known)
+ and TYPE is the type that was invalid. DIAG_KIND indicates the
+ type of diagnostic (see diagnostic.def). */
+
+void
+cxx_incomplete_type_diagnostic (location_t loc, const_tree value,
+ const_tree type, diagnostic_t diag_kind)
+{
+ bool is_decl = false, complained = false;
+
+ gcc_assert (diag_kind == DK_WARNING || diag_kind == DK_PEDWARN
+ || diag_kind == DK_ERROR);
+
+ /* Avoid duplicate error message. */
+ if (TREE_CODE (type) == ERROR_MARK)
+ return;
+
+ if (value)
+ {
+ STRIP_ANY_LOCATION_WRAPPER (value);
+
+ if (VAR_P (value) || TREE_CODE (value) == PARM_DECL
+ || TREE_CODE (value) == FIELD_DECL)
+ {
+ complained = emit_diagnostic (diag_kind, DECL_SOURCE_LOCATION (value),
+ 0, "%qD has incomplete type", value);
+ is_decl = true;
+ }
+ }
+retry:
+ /* We must print an error message. Be clever about what it says. */
+
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ if (!is_decl)
+ complained
+ = emit_diagnostic (diag_kind, loc, 0,
+ "invalid use of incomplete type %q#T", type);
+ if (complained)
+ cxx_incomplete_type_inform (type);
+ break;
+
+ case VOID_TYPE:
+ emit_diagnostic (diag_kind, loc, 0, "invalid use of %qT", type);
+ break;
+
+ case ARRAY_TYPE:
+ if (TYPE_DOMAIN (type))
+ {
+ type = TREE_TYPE (type);
+ goto retry;
+ }
+ emit_diagnostic (diag_kind, loc, 0,
+ "invalid use of array with unspecified bounds");
+ break;
+
+ case OFFSET_TYPE:
+ bad_member : {
+ tree member = TREE_OPERAND (value, 1);
+ if (is_overloaded_fn (member))
+ member = get_first_fn (member);
+
+ if (DECL_FUNCTION_MEMBER_P (member) && !flag_ms_extensions)
+ {
+ gcc_rich_location richloc (loc);
+ /* If "member" has no arguments (other than "this"), then
+ add a fix-it hint. */
+ if (type_num_arguments (TREE_TYPE (member)) == 1)
+ richloc.add_fixit_insert_after ("()");
+ emit_diagnostic (diag_kind, &richloc, 0,
+ "invalid use of member function %qD "
+ "(did you forget the %<()%> ?)",
+ member);
+ }
+ else
+ emit_diagnostic (diag_kind, loc, 0,
+ "invalid use of member %qD "
+ "(did you forget the %<&%> ?)",
+ member);
+ }
+ break;
+
+ case LANG_TYPE:
+ if (type == init_list_type_node)
+ {
+ emit_diagnostic (diag_kind, loc, 0,
+ "invalid use of brace-enclosed initializer list");
+ break;
+ }
+ gcc_assert (type == unknown_type_node);
+ if (value && TREE_CODE (value) == COMPONENT_REF)
+ goto bad_member;
+ else if (value && TREE_CODE (value) == ADDR_EXPR)
+ emit_diagnostic (diag_kind, loc, 0,
+ "address of overloaded function with no contextual "
+ "type information");
+ else if (value && TREE_CODE (value) == OVERLOAD)
+ emit_diagnostic (
+ diag_kind, loc, 0,
+ "overloaded function with no contextual type information");
+ else
+ emit_diagnostic (
+ diag_kind, loc, 0,
+ "insufficient contextual information to determine type");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
} // namespace Rust
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 9e8de7c..fc83dc2 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -1098,6 +1098,148 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
/* Returns true if NODE is a pointer or a pointer-to-member. */
#define TYPE_PTR_OR_PTRMEM_P(NODE) (TYPE_PTR_P (NODE) || TYPE_PTRMEM_P (NODE))
+/* Nonzero if NODE is an artificial VAR_DECL for a C++17 structured binding
+ declaration or one of VAR_DECLs for the user identifiers in it. */
+#define DECL_DECOMPOSITION_P(NODE) \
+ (VAR_P (NODE) && DECL_LANG_SPECIFIC (NODE) \
+ ? DECL_LANG_SPECIFIC (NODE)->u.base.selector == lds_decomp \
+ : false)
+
+/* The underlying artificial VAR_DECL for structured binding. */
+#define DECL_DECOMP_BASE(NODE) (LANG_DECL_DECOMP_CHECK (NODE)->base)
+
+/* Nonzero if either DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P or
+ DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P is true of NODE. */
+#define DECL_MAYBE_IN_CHARGE_CDTOR_P(NODE) \
+ (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (NODE) \
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (NODE))
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
+ specialized in-charge constructor, in-charge deleting constructor,
+ or the base destructor. */
+#define DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P(NODE) \
+ (DECL_NAME (NODE) == dtor_identifier)
+
+/* Nonzero if NODE (a _DECL) is a cloned constructor or
+ destructor. */
+#define DECL_CLONED_FUNCTION_P(NODE) \
+ (DECL_NAME (NODE) && IDENTIFIER_CDTOR_P (DECL_NAME (NODE)) \
+ && !DECL_MAYBE_IN_CHARGE_CDTOR_P (NODE))
+
+/* If DECL_CLONED_FUNCTION_P holds, this is the function that was
+ cloned. */
+#define DECL_CLONED_FUNCTION(NODE) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))->u.fn.u5.cloned_function)
+
+/* Nonzero if NODE (a _DECL) is a cloned constructor or
+ destructor. */
+#define DECL_CLONED_FUNCTION_P(NODE) \
+ (DECL_NAME (NODE) && IDENTIFIER_CDTOR_P (DECL_NAME (NODE)) \
+ && !DECL_MAYBE_IN_CHARGE_CDTOR_P (NODE))
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a constructor, but not either the
+ specialized in-charge constructor or the specialized not-in-charge
+ constructor. */
+#define DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P(NODE) \
+ (DECL_NAME (NODE) == ctor_identifier)
+
+/* The current C++-specific per-function global variables. */
+
+#define cp_function_chain (cfun->language)
+
+/* In a constructor destructor, the point at which all derived class
+ destroying/construction has been done. I.e., just before a
+ constructor returns, or before any base class destroying will be done
+ in a destructor. */
+
+#define cdtor_label cp_function_chain->x_cdtor_label
+
+/* When we're processing a member function, current_class_ptr is the
+ PARM_DECL for the `this' pointer. The current_class_ref is an
+ expression for `*this'. */
+
+#define current_class_ptr \
+ (*(cfun && cp_function_chain ? &cp_function_chain->x_current_class_ptr \
+ : &scope_chain->x_current_class_ptr))
+#define current_class_ref \
+ (*(cfun && cp_function_chain ? &cp_function_chain->x_current_class_ref \
+ : &scope_chain->x_current_class_ref))
+
+/* The EH_SPEC_BLOCK for the exception-specifiers for the current
+ function, if any. */
+
+#define current_eh_spec_block cp_function_chain->x_eh_spec_block
+
+/* The `__in_chrg' parameter for the current function. Only used for
+ constructors and destructors. */
+
+#define current_in_charge_parm cp_function_chain->x_in_charge_parm
+
+/* The `__vtt_parm' parameter for the current function. Only used for
+ constructors and destructors. */
+
+#define current_vtt_parm cp_function_chain->x_vtt_parm
+
+/* A boolean flag to control whether we need to clean up the return value if a
+ local destructor throws. Only used in functions that return by value a
+ class with a destructor. Which 'tors don't, so we can use the same
+ field as current_vtt_parm. */
+
+#define current_retval_sentinel current_vtt_parm
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a return statement that specifies a return value is seen. */
+
+#define current_function_returns_value cp_function_chain->returns_value
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a return statement with no argument is seen. */
+
+#define current_function_returns_null cp_function_chain->returns_null
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a call to a noreturn function is seen. */
+
+#define current_function_returns_abnormally \
+ cp_function_chain->returns_abnormally
+
+/* Set to 0 at beginning of a function definition, set to 1 if we see an
+ obvious infinite loop. This can have false positives and false
+ negatives, so it should only be used as a heuristic. */
+
+#define current_function_infinite_loop cp_function_chain->infinite_loop
+
+/* Nonzero if we are processing a base initializer. Zero elsewhere. */
+#define in_base_initializer cp_function_chain->x_in_base_initializer
+
+#define in_function_try_handler cp_function_chain->x_in_function_try_handler
+
+/* Expression always returned from function, or error_mark_node
+ otherwise, for use by the automatic named return value optimization. */
+
+#define current_function_return_value (cp_function_chain->x_return_value)
+
+#define current_class_type scope_chain->class_type
+
+/* Nonzero means that this type is being defined. I.e., the left brace
+ starting the definition of this type has been seen. */
+#define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined)
+
+/* Nonzero for FUNCTION_DECL means that this decl is a static
+ member function. */
+#define DECL_STATIC_FUNCTION_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->static_function)
+
+/* Nonzero for FUNCTION_DECL means that this decl is a non-static
+ member function. */
+#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \
+ (TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE)
+
+/* Nonzero for FUNCTION_DECL means that this decl is a member function
+ (static or non-static). */
+#define DECL_FUNCTION_MEMBER_P(NODE) \
+ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))
+
#if defined ENABLE_TREE_CHECKING
#define LANG_DECL_MIN_CHECK(NODE) \
@@ -1362,6 +1504,213 @@ struct GTY (()) lang_decl_base
|| TREE_CODE (NODE) == TEMPLATE_DECL || TREE_CODE (NODE) == USING_DECL \
|| TREE_CODE (NODE) == CONCEPT_DECL)
+// forked from gcc/c-family-common.h stmt_tree_s
+
+/* Information about a statement tree. */
+
+struct GTY (()) stmt_tree_s
+{
+ /* A stack of statement lists being collected. */
+ vec<tree, va_gc> *x_cur_stmt_list;
+
+ /* In C++, Nonzero if we should treat statements as full
+ expressions. In particular, this variable is non-zero if at the
+ end of a statement we should destroy any temporaries created
+ during that statement. Similarly, if, at the end of a block, we
+ should destroy any local variables in this block. Normally, this
+ variable is nonzero, since those are the normal semantics of
+ C++.
+
+ This flag has no effect in C. */
+ int stmts_are_full_exprs_p;
+};
+
+// forked from gcc/c-family-common.h stmt_tree_s
+
+typedef struct stmt_tree_s *stmt_tree;
+
+// forked from gcc/c-family-common.h c_language_function
+
+/* Global state pertinent to the current function. Some C dialects
+ extend this structure with additional fields. */
+
+struct GTY (()) c_language_function
+{
+ /* While we are parsing the function, this contains information
+ about the statement-tree that we are building. */
+ struct stmt_tree_s x_stmt_tree;
+
+ /* Vector of locally defined typedefs, for
+ -Wunused-local-typedefs. */
+ vec<tree, va_gc> *local_typedefs;
+};
+
+// forked from gcc/cp/cp-tree.h omp_declare_target_attr
+
+struct GTY (()) omp_declare_target_attr
+{
+ bool attr_syntax;
+};
+
+// forked from gcc/cp/name-lookup.h cxx_binding
+
+/* Datatype that represents binding established by a declaration between
+ a name and a C++ entity. */
+struct GTY (()) cxx_binding
+{
+ /* Link to chain together various bindings for this name. */
+ cxx_binding *previous;
+ /* The non-type entity this name is bound to. */
+ tree value;
+ /* The type entity this name is bound to. */
+ tree type;
+
+ bool value_is_inherited : 1;
+ bool is_local : 1;
+ bool type_is_hidden : 1;
+};
+
+// forked from gcc/cp/name-lookup.h cxx_saved_binding
+
+/* Datatype used to temporarily save C++ bindings (for implicit
+ instantiations purposes and like). Implemented in decl.cc. */
+struct GTY (()) cxx_saved_binding
+{
+ /* The name of the current binding. */
+ tree identifier;
+ /* The binding we're saving. */
+ cxx_binding *binding;
+ tree real_type_value;
+};
+
+// forked from gcc/cp/cp-tree.h saved_scope
+
+/* Global state. */
+
+struct GTY (()) saved_scope
+{
+ vec<cxx_saved_binding, va_gc> *old_bindings;
+ tree old_namespace;
+ vec<tree, va_gc> *decl_ns_list;
+ tree class_name;
+ tree class_type;
+ tree access_specifier;
+ tree function_decl;
+ vec<tree, va_gc> *lang_base;
+ tree lang_name;
+ tree template_parms;
+ tree x_saved_tree;
+
+ /* Only used for uses of this in trailing return type. */
+ tree x_current_class_ptr;
+ tree x_current_class_ref;
+
+ int x_processing_template_decl;
+ int x_processing_specialization;
+ int x_processing_constraint;
+ int suppress_location_wrappers;
+ BOOL_BITFIELD x_processing_explicit_instantiation : 1;
+ BOOL_BITFIELD need_pop_function_context : 1;
+
+ /* Nonzero if we are parsing the discarded statement of a constexpr
+ if-statement. */
+ BOOL_BITFIELD discarded_stmt : 1;
+ /* Nonzero if we are parsing or instantiating the compound-statement
+ of consteval if statement. Also set while processing an immediate
+ invocation. */
+ BOOL_BITFIELD consteval_if_p : 1;
+
+ int unevaluated_operand;
+ int inhibit_evaluation_warnings;
+ int noexcept_operand;
+ int ref_temp_count;
+
+ struct stmt_tree_s x_stmt_tree;
+
+ hash_map<tree, tree> *GTY ((skip)) x_local_specializations;
+ vec<omp_declare_target_attr, va_gc> *omp_declare_target_attribute;
+
+ struct saved_scope *prev;
+};
+
+extern GTY (()) struct saved_scope *scope_chain;
+
+// forked from gcc/cp/cp-tree.h named_label_hash
+
+struct named_label_entry; /* Defined in decl.cc. */
+
+struct named_label_hash : ggc_remove<named_label_entry *>
+{
+ typedef named_label_entry *value_type;
+ typedef tree compare_type; /* An identifier. */
+
+ inline static hashval_t hash (value_type);
+ inline static bool equal (const value_type, compare_type);
+
+ static const bool empty_zero_p = true;
+ inline static void mark_empty (value_type &p) { p = NULL; }
+ inline static bool is_empty (value_type p) { return !p; }
+
+ /* Nothing is deletable. Everything is insertable. */
+ inline static bool is_deleted (value_type) { return false; }
+ inline static void mark_deleted (value_type) { gcc_unreachable (); }
+};
+
+// forked from gcc/cp/cp-tree.h
+
+/* Global state pertinent to the current function. */
+
+struct GTY (()) language_function
+{
+ struct c_language_function base;
+
+ tree x_cdtor_label;
+ tree x_current_class_ptr;
+ tree x_current_class_ref;
+ tree x_eh_spec_block;
+ tree x_in_charge_parm;
+ tree x_vtt_parm;
+ tree x_return_value;
+
+ BOOL_BITFIELD returns_value : 1;
+ BOOL_BITFIELD returns_null : 1;
+ BOOL_BITFIELD returns_abnormally : 1;
+ BOOL_BITFIELD infinite_loop : 1;
+ BOOL_BITFIELD x_in_function_try_handler : 1;
+ BOOL_BITFIELD x_in_base_initializer : 1;
+
+ /* True if this function can throw an exception. */
+ BOOL_BITFIELD can_throw : 1;
+
+ BOOL_BITFIELD invalid_constexpr : 1;
+ BOOL_BITFIELD throwing_cleanup : 1;
+
+ hash_table<named_label_hash> *x_named_labels;
+
+ /* Tracking possibly infinite loops. This is a vec<tree> only because
+ vec<bool> doesn't work with gtype. */
+ vec<tree, va_gc> *infinite_loops;
+};
+
+// forked from gcc/c-family/c-common.h ref_operator
+
+/* The various name of operator that appears in error messages. */
+enum ref_operator
+{
+ /* NULL */
+ RO_NULL,
+ /* array indexing */
+ RO_ARRAY_INDEXING,
+ /* unary * */
+ RO_UNARY_STAR,
+ /* -> */
+ RO_ARROW,
+ /* implicit conversion */
+ RO_IMPLICIT_CONVERSION,
+ /* ->* */
+ RO_ARROW_STAR
+};
+
// forked from gcc/cp/cp-tree.h lang_decl_min
/* DECL_LANG_SPECIFIC for the above codes. */
@@ -1530,24 +1879,6 @@ struct c_fileinfo
short interface_unknown;
};
-// 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
@@ -2194,6 +2525,23 @@ extern bool reject_gcc_builtin (const_tree, location_t = UNKNOWN_LOCATION);
extern tree resolve_nondeduced_context (tree, tsubst_flags_t);
+extern void cxx_incomplete_type_diagnostic (location_t, const_tree, const_tree,
+ diagnostic_t);
+
+extern void cxx_incomplete_type_error (location_t, const_tree, const_tree);
+
+extern bool invalid_nonstatic_memfn_p (location_t, tree, tsubst_flags_t);
+
+extern bool really_overloaded_fn (tree) ATTRIBUTE_PURE;
+
+extern tree resolve_nondeduced_context_or_error (tree, tsubst_flags_t);
+
+extern tree instantiate_non_dependent_or_null (tree);
+
+extern void cxx_incomplete_type_inform (const_tree);
+
+extern tree strip_top_quals (tree);
+
// forked from gcc/cp/cp-tree.h
enum
@@ -2362,6 +2710,20 @@ null_node_p (const_tree expr)
return expr == null_node;
}
+inline void
+cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
+ diagnostic_t diag_kind)
+{
+ cxx_incomplete_type_diagnostic (rs_expr_loc_or_input_loc (value), value, type,
+ diag_kind);
+}
+
+inline void
+cxx_incomplete_type_error (const_tree value, const_tree type)
+{
+ cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+}
+
} // namespace Rust
#endif // RUST_TREE