diff options
-rw-r--r-- | gcc/rust/ast/rust-path.h | 21 | ||||
-rw-r--r-- | gcc/rust/backend/rust-tree.cc | 88 | ||||
-rw-r--r-- | gcc/rust/backend/rust-tree.h | 211 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-path.h | 22 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-type.h | 140 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir.h | 12 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 4 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-privacy-reporter.cc | 12 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-privacy-reporter.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/privacy5.rs | 3 |
10 files changed, 382 insertions, 134 deletions
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 03758d0..6e2b020 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -156,19 +156,20 @@ public: static ConstGenericArg create_error () { - return ConstGenericArg (nullptr, "", Kind::Error); + return ConstGenericArg (nullptr, "", Kind::Error, Location ()); } - ConstGenericArg (std::unique_ptr<Expr> expression) - : expression (std::move (expression)), path (""), kind (Kind::Clear) + ConstGenericArg (std::unique_ptr<Expr> expression, Location locus) + : expression (std::move (expression)), path (""), kind (Kind::Clear), + locus (locus) {} - ConstGenericArg (Identifier path) - : expression (nullptr), path (path), kind (Kind::Ambiguous) + ConstGenericArg (Identifier path, Location locus) + : expression (nullptr), path (path), kind (Kind::Ambiguous), locus (locus) {} ConstGenericArg (const ConstGenericArg &other) - : path (other.path), kind (other.kind) + : path (other.path), kind (other.kind), locus (other.locus) { if (other.expression) expression = other.expression->clone_expr (); @@ -178,6 +179,7 @@ public: { kind = other.kind; path = other.path; + locus = other.locus; if (other.expression) expression = other.expression->clone_expr (); @@ -208,8 +210,9 @@ public: private: ConstGenericArg (std::unique_ptr<AST::Expr> expression, Identifier path, - Kind kind) - : expression (std::move (expression)), path (std::move (path)), kind (kind) + Kind kind, Location locus) + : expression (std::move (expression)), path (std::move (path)), kind (kind), + locus (locus) {} /** @@ -228,6 +231,8 @@ private: /* Which kind of const generic application are we dealing with */ Kind kind; + + Location locus; }; // Generic arguments allowed in each path expression segment - inline? diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc index a2a8a22..a71b584 100644 --- a/gcc/rust/backend/rust-tree.cc +++ b/gcc/rust/backend/rust-tree.cc @@ -760,4 +760,92 @@ out: #undef WALK_SUBTREE } +// forked from gcc/cp/tree.cc cp_expr_location + +/* Like EXPR_LOCATION, but also handle some tcc_exceptional that have + locations. */ + +location_t +cp_expr_location (const_tree t_) +{ + tree t = CONST_CAST_TREE (t_); + if (t == NULL_TREE) + return UNKNOWN_LOCATION; + + return EXPR_LOCATION (t); +} + +// forked from gcc/cp/class.cc + +/* Returns true if TYPE contains no actual data, just various + possible combinations of empty classes. If IGNORE_VPTR is true, + a vptr doesn't prevent the class from being considered empty. Typically + we want to ignore the vptr on assignment, and not on initialization. */ + +bool +is_really_empty_class (tree type, bool ignore_vptr) +{ + if (CLASS_TYPE_P (type)) + { + tree field; + tree binfo; + tree base_binfo; + int i; + + /* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid + out, but we'd like to be able to check this before then. */ + if (COMPLETE_TYPE_P (type) && is_empty_class (type)) + return true; + + if (!ignore_vptr && TYPE_CONTAINS_VPTR_P (type)) + return false; + + for (binfo = TYPE_BINFO (type), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) + if (!is_really_empty_class (BINFO_TYPE (base_binfo), ignore_vptr)) + return false; + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && !DECL_ARTIFICIAL (field) + /* An unnamed bit-field is not a data member. */ + && !DECL_UNNAMED_BIT_FIELD (field) + && !is_really_empty_class (TREE_TYPE (field), ignore_vptr)) + return false; + return true; + } + else if (TREE_CODE (type) == ARRAY_TYPE) + return (integer_zerop (array_type_nelts_top (type)) + || is_really_empty_class (TREE_TYPE (type), ignore_vptr)); + return false; +} + +// forked from gcc/cp/class.cc is_empty_class + +/* Returns 1 if TYPE contains only padding bytes. */ + +int +is_empty_class (tree type) +{ + if (type == error_mark_node) + return 0; + + if (!CLASS_TYPE_P (type)) + return 0; + + return CLASSTYPE_EMPTY_P (type); +} + +// forked from gcc/cp/tree.cc array_type_nelts_top + +/* Return, as an INTEGER_CST node, the number of elements for TYPE + (which is an ARRAY_TYPE). This counts only elements of the top + array. */ + +tree +array_type_nelts_top (tree type) +{ + return fold_build2_loc (input_location, PLUS_EXPR, sizetype, + array_type_nelts (type), size_one_node); +} + } // namespace Rust diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h index f164a10..b564090 100644 --- a/gcc/rust/backend/rust-tree.h +++ b/gcc/rust/backend/rust-tree.h @@ -111,8 +111,186 @@ has been duly initialized in its constructor. */ #define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE)) +/* Nonzero if T is a class type. Zero for template type parameters, + typename types, and so forth. */ +#define CLASS_TYPE_P(T) \ + (RECORD_OR_UNION_CODE_P (TREE_CODE (T)) && TYPE_LANG_FLAG_5 (T)) + +/* [class.virtual] + + A class that declares or inherits a virtual function is called a + polymorphic class. */ +#define TYPE_POLYMORPHIC_P(NODE) (TREE_LANG_FLAG_2 (NODE)) + +/* Nonzero if this class has a virtual function table pointer. */ +#define TYPE_CONTAINS_VPTR_P(NODE) \ + (TYPE_POLYMORPHIC_P (NODE) || CLASSTYPE_VBASECLASSES (NODE)) + +/* A vector of BINFOs for the direct and indirect virtual base classes + that this type uses in a post-order depth-first left-to-right + order. (In other words, these bases appear in the order that they + should be initialized.) */ +#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases) + +/* A vector of BINFOs for the direct and indirect virtual base classes + that this type uses in a post-order depth-first left-to-right + order. (In other words, these bases appear in the order that they + should be initialized.) */ +#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases) + +/* We used to have a variant type for lang_type. Keep the name of the + checking accessor for the sole survivor. */ +#define LANG_TYPE_CLASS_CHECK(NODE) (TYPE_LANG_SPECIFIC (NODE)) + +/* Keep these checks in ascending code order. */ +#define RECORD_OR_UNION_CODE_P(T) ((T) == RECORD_TYPE || (T) == UNION_TYPE) +#define OVERLOAD_TYPE_P(T) (CLASS_TYPE_P (T) || TREE_CODE (T) == ENUMERAL_TYPE) + +/* Nonzero if this class is "empty" in the sense of the C++ ABI. */ +#define CLASSTYPE_EMPTY_P(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->empty_p) + +// Below macros are copied from gcc/c-family/c-common.h + +/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */ +#define DECL_C_BIT_FIELD(NODE) (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1) +#define SET_DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1) +#define CLEAR_DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0) + +/* True if the decl was an unnamed bitfield. */ +#define DECL_UNNAMED_BIT_FIELD(NODE) \ + (DECL_C_BIT_FIELD (NODE) && !DECL_NAME (NODE)) + +// Above macros are copied from gcc/c-family/c-common.h + +// forked from gcc/cp/cp-tree.h treee_pair_s + +struct GTY (()) tree_pair_s +{ + tree purpose; + tree value; +}; + +// forked from gcc/cp/cp-tree.h tree_pair_p + +typedef tree_pair_s *tree_pair_p; + +// forked from gcc/cp/cp-tree.h lang_type + +/* This structure provides additional information above and beyond + what is provide in the ordinary tree_type. In the past, we used it + for the types of class types, template parameters types, typename + types, and so forth. However, there can be many (tens to hundreds + of thousands) of template parameter types in a compilation, and + there's no need for this additional information in that case. + Therefore, we now use this data structure only for class types. + + In the past, it was thought that there would be relatively few + class types. However, in the presence of heavy use of templates, + many (i.e., thousands) of classes can easily be generated. + Therefore, we should endeavor to keep the size of this structure to + a minimum. */ +struct GTY (()) lang_type +{ + unsigned char align; + + unsigned has_type_conversion : 1; + unsigned has_copy_ctor : 1; + unsigned has_default_ctor : 1; + unsigned const_needs_init : 1; + unsigned ref_needs_init : 1; + unsigned has_const_copy_assign : 1; + unsigned use_template : 2; + + unsigned has_mutable : 1; + unsigned com_interface : 1; + unsigned non_pod_class : 1; + unsigned nearly_empty_p : 1; + unsigned user_align : 1; + unsigned has_copy_assign : 1; + unsigned has_new : 1; + unsigned has_array_new : 1; + + unsigned gets_delete : 2; + unsigned interface_only : 1; + unsigned interface_unknown : 1; + unsigned contains_empty_class_p : 1; + unsigned anon_aggr : 1; + unsigned non_zero_init : 1; + unsigned empty_p : 1; + /* 32 bits allocated. */ + + unsigned vec_new_uses_cookie : 1; + unsigned declared_class : 1; + unsigned diamond_shaped : 1; + unsigned repeated_base : 1; + unsigned being_defined : 1; + unsigned debug_requested : 1; + unsigned fields_readonly : 1; + unsigned ptrmemfunc_flag : 1; + + unsigned lazy_default_ctor : 1; + unsigned lazy_copy_ctor : 1; + unsigned lazy_copy_assign : 1; + unsigned lazy_destructor : 1; + unsigned has_const_copy_ctor : 1; + unsigned has_complex_copy_ctor : 1; + unsigned has_complex_copy_assign : 1; + unsigned non_aggregate : 1; + + unsigned has_complex_dflt : 1; + unsigned has_list_ctor : 1; + unsigned non_std_layout : 1; + unsigned is_literal : 1; + unsigned lazy_move_ctor : 1; + unsigned lazy_move_assign : 1; + unsigned has_complex_move_ctor : 1; + unsigned has_complex_move_assign : 1; + + unsigned has_constexpr_ctor : 1; + unsigned unique_obj_representations : 1; + unsigned unique_obj_representations_set : 1; + bool erroneous : 1; + bool non_pod_aggregate : 1; + + /* When adding a flag here, consider whether or not it ought to + apply to a template instance if it applies to the template. If + so, make sure to copy it in instantiate_class_template! */ + + /* There are some bits left to fill out a 32-bit word. Keep track + of this by updating the size of this bitfield whenever you add or + remove a flag. */ + unsigned dummy : 3; + + tree primary_base; + vec<tree_pair_s, va_gc> *vcall_indices; + tree vtables; + tree typeinfo_var; + vec<tree, va_gc> *vbases; + tree as_base; + vec<tree, va_gc> *pure_virtuals; + tree friend_classes; + vec<tree, va_gc> *GTY ((reorder ("resort_type_member_vec"))) members; + tree key_method; + tree decl_list; + tree befriending_classes; + /* In a RECORD_TYPE, information specific to Objective-C++, such + as a list of adopted protocols or a pointer to a corresponding + @interface. See objc/objc-act.h for details. */ + tree objc_info; + /* FIXME reuse another field? */ + tree lambda_expr; +}; + namespace Rust { +// forked from gcc/cp/cp-tree.h tsubst_flags_t + +/* This type is used for parameters and variables which hold + combinations of the flags in enum tsubst_flags. */ +typedef int tsubst_flags_t; + // forked from gcc/cp/cvt.cc convert_to_void // // When an expression is used in a void context, its value is discarded and @@ -220,6 +398,20 @@ get_fndecl_from_callee (tree fn); extern tree pointer_offset_expression (tree base_tree, tree index_tree, location_t locus); +/* A tree node, together with a location, so that we can track locations + (and ranges) during parsing. + + The location is redundant for node kinds that have locations, + but not all node kinds do (e.g. constants, and references to + params, locals, etc), so we stash a copy here. */ + +extern location_t cp_expr_location (const_tree); + +extern int +is_empty_class (tree type); + +extern tree array_type_nelts_top (tree); + extern tree rs_walk_subtrees (tree *, int *, walk_tree_fn, void *, hash_set<tree> *); #define rs_walk_tree(tp, func, data, pset) \ @@ -227,6 +419,25 @@ rs_walk_subtrees (tree *, int *, walk_tree_fn, void *, hash_set<tree> *); #define rs_walk_tree_without_duplicates(tp, func, data) \ walk_tree_without_duplicates_1 (tp, func, data, rs_walk_subtrees) +// forked from gcc/cp/cp-tree.h cp_expr_loc_or_loc + +inline location_t +cp_expr_loc_or_loc (const_tree t, location_t or_loc) +{ + location_t loc = cp_expr_location (t); + if (loc == UNKNOWN_LOCATION) + loc = or_loc; + return loc; +} + +// forked from gcc/cp/cp-tree.h cp_expr_loc_or_input_loc + +inline location_t +cp_expr_loc_or_input_loc (const_tree t) +{ + return cp_expr_loc_or_loc (t, input_location); +} + } // namespace Rust #endif // RUST_TREE diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index a5006f5..64c6ddc 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -657,7 +657,6 @@ class TypePath : public TypeNoBounds public: bool has_opening_scope_resolution; std::vector<std::unique_ptr<TypePathSegment> > segments; - Location locus; protected: /* Use covariance to implement clone function as returning this object rather @@ -694,16 +693,15 @@ public: TypePath (Analysis::NodeMapping mappings, std::vector<std::unique_ptr<TypePathSegment> > segments, Location locus, bool has_opening_scope_resolution = false) - : TypeNoBounds (mappings), + : TypeNoBounds (mappings, locus), has_opening_scope_resolution (has_opening_scope_resolution), - segments (std::move (segments)), locus (locus) + segments (std::move (segments)) {} // Copy constructor with vector clone TypePath (TypePath const &other) - : TypeNoBounds (other.mappings), - has_opening_scope_resolution (other.has_opening_scope_resolution), - locus (other.locus) + : TypeNoBounds (other.mappings, other.locus), + has_opening_scope_resolution (other.has_opening_scope_resolution) { segments.reserve (other.segments.size ()); for (const auto &e : other.segments) @@ -737,8 +735,6 @@ public: // Creates a trait bound with a clone of this type path as its only element. TraitBound *to_trait_bound (bool in_parens) const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; @@ -899,7 +895,6 @@ class QualifiedPathInType : public TypeNoBounds QualifiedPathType path_type; std::unique_ptr<TypePathSegment> associated_segment; std::vector<std::unique_ptr<TypePathSegment> > segments; - Location locus; protected: /* Use covariance to implement clone function as returning this object rather @@ -922,9 +917,9 @@ public: std::unique_ptr<TypePathSegment> associated_segment, std::vector<std::unique_ptr<TypePathSegment> > path_segments, Location locus = Location ()) - : TypeNoBounds (mappings), path_type (std::move (qual_path_type)), + : TypeNoBounds (mappings, locus), path_type (std::move (qual_path_type)), associated_segment (std::move (associated_segment)), - segments (std::move (path_segments)), locus (locus) + segments (std::move (path_segments)) {} /* TODO: maybe make a shortcut constructor that has QualifiedPathType elements @@ -932,8 +927,7 @@ public: // Copy constructor with vector clone QualifiedPathInType (QualifiedPathInType const &other) - : TypeNoBounds (other.mappings), path_type (other.path_type), - locus (other.locus) + : TypeNoBounds (other.mappings, other.locus), path_type (other.path_type) { segments.reserve (other.segments.size ()); for (const auto &e : other.segments) @@ -977,8 +971,6 @@ public: { return segments; } - - Location get_locus () { return locus; } }; class SimplePathSegment diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h index c4817ad..0d2e743 100644 --- a/gcc/rust/hir/tree/rust-hir-type.h +++ b/gcc/rust/hir/tree/rust-hir-type.h @@ -87,9 +87,7 @@ class ImplTraitType : public Type { // TypeParamBounds type_param_bounds; // inlined form - std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds; - - Location locus; + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; protected: /* Use covariance to implement clone function as returning this object rather @@ -100,17 +98,15 @@ protected: } public: - ImplTraitType ( - Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds, - Location locus) - : Type (mappings), type_param_bounds (std::move (type_param_bounds)), - locus (locus) + ImplTraitType (Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + Location locus) + : Type (mappings, locus), type_param_bounds (std::move (type_param_bounds)) {} // copy constructor with vector clone ImplTraitType (ImplTraitType const &other) - : Type (other.mappings), locus (other.locus) + : Type (other.mappings, other.locus) { type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) @@ -136,8 +132,6 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; }; @@ -146,8 +140,7 @@ public: class TraitObjectType : public Type { bool has_dyn; - std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds; - Location locus; + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; protected: /* Use covariance to implement clone function as returning this object rather @@ -160,15 +153,15 @@ protected: public: TraitObjectType ( Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, Location locus, bool is_dyn_dispatch) - : Type (mappings), has_dyn (is_dyn_dispatch), - type_param_bounds (std::move (type_param_bounds)), locus (locus) + : Type (mappings, locus), has_dyn (is_dyn_dispatch), + type_param_bounds (std::move (type_param_bounds)) {} // copy constructor with vector clone TraitObjectType (TraitObjectType const &other) - : Type (other.mappings), has_dyn (other.has_dyn), locus (other.locus) + : Type (other.mappings, other.locus), has_dyn (other.has_dyn) { type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) @@ -194,17 +187,15 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; - std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () + std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds () { return type_param_bounds; } - const std::vector<std::unique_ptr<TypeParamBound> > & + const std::vector<std::unique_ptr<TypeParamBound>> & get_type_param_bounds () const { return type_param_bounds; @@ -215,7 +206,6 @@ public: class ParenthesisedType : public TypeNoBounds { std::unique_ptr<Type> type_in_parens; - Location locus; protected: /* Use covariance to implement clone function as returning this object rather @@ -236,15 +226,15 @@ public: // Constructor uses Type pointer for polymorphism ParenthesisedType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type_inside_parens, Location locus) - : TypeNoBounds (mappings), type_in_parens (std::move (type_inside_parens)), - locus (locus) + : TypeNoBounds (mappings, locus), + type_in_parens (std::move (type_inside_parens)) {} /* Copy constructor uses custom deep copy method for type to preserve * polymorphism */ ParenthesisedType (ParenthesisedType const &other) - : TypeNoBounds (other.mappings), - type_in_parens (other.type_in_parens->clone_type ()), locus (other.locus) + : TypeNoBounds (other.mappings, other.locus), + type_in_parens (other.type_in_parens->clone_type ()) {} // overload assignment operator to use custom clone method @@ -274,8 +264,6 @@ public: return type_in_parens->to_trait_bound (true); } - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; }; @@ -285,8 +273,6 @@ class ImplTraitTypeOneBound : public TypeNoBounds { TraitBound trait_bound; - Location locus; - protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -305,14 +291,11 @@ protected: public: ImplTraitTypeOneBound (Analysis::NodeMapping mappings, TraitBound trait_bound, Location locus) - : TypeNoBounds (mappings), trait_bound (std::move (trait_bound)), - locus (locus) + : TypeNoBounds (mappings, locus), trait_bound (std::move (trait_bound)) {} std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; }; @@ -323,21 +306,20 @@ class TypePath; // definition moved to "rust-path.h" * specific order */ class TupleType : public TypeNoBounds { - std::vector<std::unique_ptr<Type> > elems; - Location locus; + std::vector<std::unique_ptr<Type>> elems; public: // Returns whether the tuple type is the unit type, i.e. has no elements. bool is_unit_type () const { return elems.empty (); } TupleType (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Type> > elems, Location locus) - : TypeNoBounds (mappings), elems (std::move (elems)), locus (locus) + std::vector<std::unique_ptr<Type>> elems, Location locus) + : TypeNoBounds (mappings, locus), elems (std::move (elems)) {} // copy constructor with vector clone TupleType (TupleType const &other) - : TypeNoBounds (other.mappings), locus (other.locus) + : TypeNoBounds (other.mappings, other.locus) { mappings = other.mappings; elems.reserve (other.elems.size ()); @@ -363,16 +345,11 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; - std::vector<std::unique_ptr<Type> > &get_elems () { return elems; } - const std::vector<std::unique_ptr<Type> > &get_elems () const - { - return elems; - } + std::vector<std::unique_ptr<Type>> &get_elems () { return elems; } + const std::vector<std::unique_ptr<Type>> &get_elems () const { return elems; } protected: /* Use covariance to implement clone function as returning this object rather @@ -392,8 +369,6 @@ protected: * Represented as "!". */ class NeverType : public TypeNoBounds { - Location locus; - protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -408,13 +383,11 @@ protected: public: NeverType (Analysis::NodeMapping mappings, Location locus) - : TypeNoBounds (mappings), locus (locus) + : TypeNoBounds (mappings, locus) {} std::string as_string () const override { return "! (never type)"; } - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; }; @@ -425,19 +398,18 @@ class RawPointerType : public TypeNoBounds private: Mutability mut; std::unique_ptr<Type> type; - Location locus; public: // Constructor requires pointer for polymorphism reasons RawPointerType (Analysis::NodeMapping mappings, Mutability mut, std::unique_ptr<Type> type, Location locus) - : TypeNoBounds (mappings), mut (mut), type (std::move (type)), locus (locus) + : TypeNoBounds (mappings, locus), mut (mut), type (std::move (type)) {} // Copy constructor calls custom polymorphic clone function RawPointerType (RawPointerType const &other) - : TypeNoBounds (other.mappings), mut (other.mut), - type (other.type->clone_type ()), locus (other.locus) + : TypeNoBounds (other.mappings, other.locus), mut (other.mut), + type (other.type->clone_type ()) {} // overload assignment operator to use custom clone method @@ -456,8 +428,6 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; @@ -495,7 +465,6 @@ class ReferenceType : public TypeNoBounds Mutability mut; std::unique_ptr<Type> type; - Location locus; public: // Returns whether the reference is mutable or immutable. @@ -508,14 +477,14 @@ public: ReferenceType (Analysis::NodeMapping mappings, Mutability mut, std::unique_ptr<Type> type_no_bounds, Location locus, Lifetime lifetime) - : TypeNoBounds (mappings), lifetime (std::move (lifetime)), mut (mut), - type (std::move (type_no_bounds)), locus (locus) + : TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)), + mut (mut), type (std::move (type_no_bounds)) {} // Copy constructor with custom clone method ReferenceType (ReferenceType const &other) - : TypeNoBounds (other.mappings), lifetime (other.lifetime), mut (other.mut), - type (other.type->clone_type ()), locus (other.locus) + : TypeNoBounds (other.mappings, other.locus), lifetime (other.lifetime), + mut (other.mut), type (other.type->clone_type ()) {} // Operator overload assignment operator to custom clone the unique pointer @@ -536,8 +505,6 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; @@ -568,20 +535,20 @@ class ArrayType : public TypeNoBounds { std::unique_ptr<Type> elem_type; std::unique_ptr<Expr> size; - Location locus; public: // Constructor requires pointers for polymorphism ArrayType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, std::unique_ptr<Expr> array_size, Location locus) - : TypeNoBounds (mappings), elem_type (std::move (type)), - size (std::move (array_size)), locus (locus) + : TypeNoBounds (mappings, locus), elem_type (std::move (type)), + size (std::move (array_size)) {} // Copy constructor requires deep copies of both unique pointers ArrayType (ArrayType const &other) - : TypeNoBounds (other.mappings), elem_type (other.elem_type->clone_type ()), - size (other.size->clone_expr ()), locus (other.locus) + : TypeNoBounds (other.mappings, other.locus), + elem_type (other.elem_type->clone_type ()), + size (other.size->clone_expr ()) {} // Overload assignment operator to deep copy pointers @@ -600,8 +567,6 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; @@ -609,8 +574,6 @@ public: Expr *get_size_expr () { return size.get (); } - Location &get_locus () { return locus; } - protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -629,19 +592,18 @@ protected: class SliceType : public TypeNoBounds { std::unique_ptr<Type> elem_type; - Location locus; public: // Constructor requires pointer for polymorphism SliceType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, Location locus) - : TypeNoBounds (mappings), elem_type (std::move (type)), locus (locus) + : TypeNoBounds (mappings, locus), elem_type (std::move (type)) {} // Copy constructor requires deep copy of Type smart pointer SliceType (SliceType const &other) - : TypeNoBounds (other.mappings), elem_type (other.elem_type->clone_type ()), - locus (other.locus) + : TypeNoBounds (other.mappings, other.locus), + elem_type (other.elem_type->clone_type ()) {} // Overload assignment operator to deep copy @@ -660,8 +622,6 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; @@ -684,8 +644,6 @@ protected: * pattern) */ class InferredType : public TypeNoBounds { - Location locus; - // e.g. Vec<_> = whatever protected: /* Use covariance to implement clone function as returning this object rather @@ -704,13 +662,11 @@ protected: public: InferredType (Analysis::NodeMapping mappings, Location locus) - : TypeNoBounds (mappings), locus (locus) + : TypeNoBounds (mappings, locus) {} std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; }; @@ -804,8 +760,6 @@ class BareFunctionType : public TypeNoBounds std::unique_ptr<Type> return_type; // inlined version - Location locus; - public: // Whether a return type is defined with the function. bool has_return_type () const { return return_type != nullptr; } @@ -818,18 +772,20 @@ public: FunctionQualifiers qualifiers, std::vector<MaybeNamedParam> named_params, bool is_variadic, std::unique_ptr<Type> type, Location locus) - : TypeNoBounds (mappings), for_lifetimes (std::move (lifetime_params)), + : TypeNoBounds (mappings, locus), + for_lifetimes (std::move (lifetime_params)), function_qualifiers (std::move (qualifiers)), params (std::move (named_params)), is_variadic (is_variadic), - return_type (std::move (type)), locus (locus) + return_type (std::move (type)) {} // Copy constructor with clone BareFunctionType (BareFunctionType const &other) - : TypeNoBounds (other.mappings), for_lifetimes (other.for_lifetimes), + : TypeNoBounds (other.mappings, other.locus), + for_lifetimes (other.for_lifetimes), function_qualifiers (other.function_qualifiers), params (other.params), is_variadic (other.is_variadic), - return_type (other.return_type->clone_type ()), locus (other.locus) + return_type (other.return_type->clone_type ()) {} // Overload assignment operator to deep copy @@ -852,8 +808,6 @@ public: std::string as_string () const override; - Location get_locus () const { return locus; } - void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index 2267a1f..8f94354 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -478,16 +478,18 @@ public: virtual void accept_vis (HIRTypeVisitor &vis) = 0; virtual Analysis::NodeMapping get_mappings () const { return mappings; } + virtual Location get_locus () const { return locus; } protected: - Type (Analysis::NodeMapping mappings) : mappings (mappings) {} + Type (Analysis::NodeMapping mappings, Location locus) + : mappings (mappings), locus (locus) + {} // Clone function implementation as pure virtual method virtual Type *clone_type_impl () const = 0; Analysis::NodeMapping mappings; - - // FIXME: How do we get the location here for each type? + Location locus; }; // A type without parentheses? - abstract @@ -501,7 +503,9 @@ public: } protected: - TypeNoBounds (Analysis::NodeMapping mappings) : Type (mappings) {} + TypeNoBounds (Analysis::NodeMapping mappings, Location locus) + : Type (mappings, locus) + {} // Clone function implementation as pure virtual method virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0; diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index c2efd53..708140a 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -6181,7 +6181,7 @@ Parser<ManagedTokenSource>::parse_const_generic_expression () // special variant here // FIXME: We need locus here as well - return AST::ConstGenericArg (tok->get_str ()); + return AST::ConstGenericArg (tok->get_str (), tok->get_locus ()); case LEFT_CURLY: expr = parse_block_expr (); break; @@ -6201,7 +6201,7 @@ Parser<ManagedTokenSource>::parse_const_generic_expression () if (!expr) return AST::ConstGenericArg::create_error (); - return AST::ConstGenericArg (std::move (expr)); + return AST::ConstGenericArg (std::move (expr), tok->get_locus ()); } // Parses the generic arguments in each path segment. diff --git a/gcc/rust/privacy/rust-privacy-reporter.cc b/gcc/rust/privacy/rust-privacy-reporter.cc index f2752b6..77f477b 100644 --- a/gcc/rust/privacy/rust-privacy-reporter.cc +++ b/gcc/rust/privacy/rust-privacy-reporter.cc @@ -188,8 +188,7 @@ PrivacyReporter::check_base_type_privacy (Analysis::NodeMapping &node_mappings, } void -PrivacyReporter::check_type_privacy (const HIR::Type *type, - const Location &locus) +PrivacyReporter::check_type_privacy (const HIR::Type *type) { rust_assert (type); @@ -198,7 +197,7 @@ PrivacyReporter::check_type_privacy (const HIR::Type *type, ty_ctx.lookup_type (type->get_mappings ().get_hirid (), &lookup)); auto node_mappings = type->get_mappings (); - return check_base_type_privacy (node_mappings, lookup, locus); + return check_base_type_privacy (node_mappings, lookup, type->get_locus ()); } void @@ -634,9 +633,7 @@ void PrivacyReporter::visit (HIR::Function &function) { for (auto ¶m : function.get_function_params ()) - check_type_privacy (param.get_type (), param.get_locus ()); - - // FIXME: It would be better if it was specifically the type's locus (#1256) + check_type_privacy (param.get_type ()); function.get_definition ()->accept_vis (*this); } @@ -737,8 +734,7 @@ PrivacyReporter::visit (HIR::LetStmt &stmt) { auto type = stmt.get_type (); if (type) - check_type_privacy (type, stmt.get_locus ()); - // FIXME: #1256 + check_type_privacy (type); auto init_expr = stmt.get_init_expr (); if (init_expr) diff --git a/gcc/rust/privacy/rust-privacy-reporter.h b/gcc/rust/privacy/rust-privacy-reporter.h index 234bea7..a04e318 100644 --- a/gcc/rust/privacy/rust-privacy-reporter.h +++ b/gcc/rust/privacy/rust-privacy-reporter.h @@ -74,9 +74,8 @@ types * * @param type Reference to an explicit type used in a statement, expression * or parameter - * @param locus Location of said type */ - void check_type_privacy (const HIR::Type *type, const Location &locus); + void check_type_privacy (const HIR::Type *type); virtual void visit (HIR::StructExprFieldIdentifier &field); virtual void visit (HIR::StructExprFieldIdentifierValue &field); diff --git a/gcc/testsuite/rust/compile/privacy5.rs b/gcc/testsuite/rust/compile/privacy5.rs index ad552c7..0e0e496 100644 --- a/gcc/testsuite/rust/compile/privacy5.rs +++ b/gcc/testsuite/rust/compile/privacy5.rs @@ -12,7 +12,6 @@ mod orange { let _: green::Foo; // { dg-error "definition is private in this context" } - fn any(a0: green::Foo, a1: green::Bar) {} - // { dg-error "definition is private in this context" "" { target *-*-* } .-1 } + fn any(a0: green::Foo, a1: green::Bar) {} // { dg-error "20:definition is private in this context" } } } |