https://gcc.gnu.org/g:889dec2e6a444301b8fdf825fd65e2220052ef88
commit 889dec2e6a444301b8fdf825fd65e2220052ef88 Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Date: Thu Nov 2 17:10:33 2023 +0100 Add visibility to trait item The compiler shall parse visibility modifiers on trait items and reject those at a later stage (ast validation). gcc/rust/ChangeLog: * ast/rust-item.h (struct Visibility): Move Visibility from here... * ast/rust-ast.h (struct Visibility): ...to here. * parse/rust-parse-impl.h (Parser::parse_trait_item): Parse visibility before giving it back to the item parsing function. (Parser::parse_trait_type): Add visibility modifier. * parse/rust-parse.h (RUST_PARSE_H): Change function prototype. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Diff: --- gcc/rust/ast/rust-ast.h | 248 ++++++++++++++++++++------------------- gcc/rust/ast/rust-item.h | 5 +- gcc/rust/parse/rust-parse-impl.h | 10 +- gcc/rust/parse/rust-parse.h | 3 +- 4 files changed, 140 insertions(+), 126 deletions(-) diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index cd0577ce3f5f..7f4be0a07f27 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -490,6 +490,126 @@ operator!= (const SimplePath &lhs, const std::string &rhs) // forward decl for Attribute class AttrInput; +// Visibility of item - if the item has it, then it is some form of public +struct Visibility +{ +public: + enum VisType + { + PRIV, + PUB, + PUB_CRATE, + PUB_SELF, + PUB_SUPER, + PUB_IN_PATH + }; + +private: + VisType vis_type; + // Only assigned if vis_type is IN_PATH + SimplePath in_path; + location_t locus; + + // should this store location info? + +public: + // Creates a Visibility - TODO make constructor protected or private? + Visibility (VisType vis_type, SimplePath in_path, location_t locus) + : vis_type (vis_type), in_path (std::move (in_path)), locus (locus) + {} + + VisType get_vis_type () const { return vis_type; } + + // Returns whether visibility is in an error state. + bool is_error () const + { + return vis_type == PUB_IN_PATH && in_path.is_empty (); + } + + // Returns whether a visibility has a path + bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; } + + // Returns whether visibility is public or not. + bool is_public () const { return vis_type != PRIV && !is_error (); } + + location_t get_locus () const { return locus; } + + // empty? + // Creates an error visibility. + static Visibility create_error () + { + return Visibility (PUB_IN_PATH, SimplePath::create_empty (), + UNDEF_LOCATION); + } + + // Unique pointer custom clone function + /*std::unique_ptr<Visibility> clone_visibility() const { + return std::unique_ptr<Visibility>(clone_visibility_impl()); + }*/ + + /* TODO: think of a way to only allow valid Visibility states - polymorphism + * is one idea but may be too resource-intensive. */ + + // Creates a public visibility with no further features/arguments. + // empty? + static Visibility create_public (location_t pub_vis_location) + { + return Visibility (PUB, SimplePath::create_empty (), pub_vis_location); + } + + // Creates a public visibility with crate-relative paths + static Visibility create_crate (location_t crate_tok_location, + location_t crate_vis_location) + { + return Visibility (PUB_CRATE, + SimplePath::from_str ("crate", crate_tok_location), + crate_vis_location); + } + + // Creates a public visibility with self-relative paths + static Visibility create_self (location_t self_tok_location, + location_t self_vis_location) + { + return Visibility (PUB_SELF, + SimplePath::from_str ("self", self_tok_location), + self_vis_location); + } + + // Creates a public visibility with parent module-relative paths + static Visibility create_super (location_t super_tok_location, + location_t super_vis_location) + { + return Visibility (PUB_SUPER, + SimplePath::from_str ("super", super_tok_location), + super_vis_location); + } + + // Creates a private visibility + static Visibility create_private () + { + return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION); + } + + // Creates a public visibility with a given path or whatever. + static Visibility create_in_path (SimplePath in_path, + location_t in_path_vis_location) + { + return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location); + } + + std::string as_string () const; + const SimplePath &get_path () const { return in_path; } + SimplePath &get_path () { return in_path; } + +protected: + // Clone function implementation - not currently virtual but may be if + // polymorphism used + /*virtual*/ Visibility *clone_visibility_impl () const + { + return new Visibility (*this); + } +}; + // aka Attr // Attribute AST representation struct Attribute @@ -1042,125 +1162,6 @@ protected: Item *clone_stmt_impl () const final override { return clone_item_impl (); } }; -// Visibility of item - if the item has it, then it is some form of public -struct Visibility -{ -public: - enum VisType - { - PRIV, - PUB, - PUB_CRATE, - PUB_SELF, - PUB_SUPER, - PUB_IN_PATH - }; - -private: - VisType vis_type; - // Only assigned if vis_type is IN_PATH - SimplePath in_path; - location_t locus; - - // should this store location info? - -public: - // Creates a Visibility - TODO make constructor protected or private? - Visibility (VisType vis_type, SimplePath in_path, location_t locus) - : vis_type (vis_type), in_path (std::move (in_path)), locus (locus) - {} - - VisType get_vis_type () const { return vis_type; } - - // Returns whether visibility is in an error state. - bool is_error () const - { - return vis_type == PUB_IN_PATH && in_path.is_empty (); - } - - // Returns whether a visibility has a path - bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; } - - // Returns whether visibility is public or not. - bool is_public () const { return vis_type != PRIV && !is_error (); } - - location_t get_locus () const { return locus; } - - // empty? - // Creates an error visibility. - static Visibility create_error () - { - return Visibility (PUB_IN_PATH, SimplePath::create_empty (), - UNDEF_LOCATION); - } - - // Unique pointer custom clone function - /*std::unique_ptr<Visibility> clone_visibility() const { - return std::unique_ptr<Visibility>(clone_visibility_impl()); - }*/ - - /* TODO: think of a way to only allow valid Visibility states - polymorphism - * is one idea but may be too resource-intensive. */ - - // Creates a public visibility with no further features/arguments. - // empty? - static Visibility create_public (location_t pub_vis_location) - { - return Visibility (PUB, SimplePath::create_empty (), pub_vis_location); - } - - // Creates a public visibility with crate-relative paths - static Visibility create_crate (location_t crate_tok_location, - location_t crate_vis_location) - { - return Visibility (PUB_CRATE, - SimplePath::from_str ("crate", crate_tok_location), - crate_vis_location); - } - - // Creates a public visibility with self-relative paths - static Visibility create_self (location_t self_tok_location, - location_t self_vis_location) - { - return Visibility (PUB_SELF, - SimplePath::from_str ("self", self_tok_location), - self_vis_location); - } - - // Creates a public visibility with parent module-relative paths - static Visibility create_super (location_t super_tok_location, - location_t super_vis_location) - { - return Visibility (PUB_SUPER, - SimplePath::from_str ("super", super_tok_location), - super_vis_location); - } - - // Creates a private visibility - static Visibility create_private () - { - return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION); - } - - // Creates a public visibility with a given path or whatever. - static Visibility create_in_path (SimplePath in_path, - location_t in_path_vis_location) - { - return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location); - } - - std::string as_string () const; - const SimplePath &get_path () const { return in_path; } - SimplePath &get_path () { return in_path; } - -protected: - // Clone function implementation - not currently virtual but may be if - // polymorphism used - /*virtual*/ Visibility *clone_visibility_impl () const - { - return new Visibility (*this); - } -}; // Item that supports visibility - abstract base class class VisItem : public Item { @@ -1649,13 +1650,20 @@ class TraitItem : virtual public AssociatedItem { protected: TraitItem (location_t locus) - : node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus) + : node_id (Analysis::Mappings::get ()->get_next_node_id ()), + vis (Visibility::create_private ()), locus (locus) + {} + + TraitItem (Visibility vis, location_t locus) + : node_id (Analysis::Mappings::get ()->get_next_node_id ()), vis (vis), + locus (locus) {} // Clone function implementation as pure virtual method virtual TraitItem *clone_associated_item_impl () const override = 0; NodeId node_id; + Visibility vis; location_t locus; public: diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 81bb17ea0d6e..6c6104ef591d 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -3048,8 +3048,9 @@ public: TraitItemType (Identifier name, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, - std::vector<Attribute> outer_attrs, location_t locus) - : TraitItem (locus), outer_attrs (std::move (outer_attrs)), + std::vector<Attribute> outer_attrs, Visibility vis, + location_t locus) + : TraitItem (vis, locus), outer_attrs (std::move (outer_attrs)), name (std::move (name)), type_param_bounds (std::move (type_param_bounds)) {} diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 3cfbc67c5e33..17a4f7e5acca 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -22,6 +22,7 @@ /* DO NOT INCLUDE ANYWHERE - this is automatically included with rust-parse.h * This is also the reason why there are no include guards. */ +#include "rust-item.h" #include "rust-token.h" #define INCLUDE_ALGORITHM #include "rust-diagnostics.h" @@ -5012,12 +5013,14 @@ Parser<ManagedTokenSource>::parse_trait_item () // parse outer attributes (if they exist) AST::AttrVec outer_attrs = parse_outer_attributes (); + AST::Visibility vis = parse_visibility (); + // lookahead to determine what type of trait item to parse const_TokenPtr tok = lexer.peek_token (); switch (tok->get_id ()) { case TYPE: - return parse_trait_type (std::move (outer_attrs)); + return parse_trait_type (std::move (outer_attrs), vis); case CONST: // disambiguate with function qualifier if (lexer.peek_token (1)->get_id () == IDENTIFIER) @@ -5176,7 +5179,8 @@ Parser<ManagedTokenSource>::parse_trait_item () // Parse a typedef trait item. template <typename ManagedTokenSource> std::unique_ptr<AST::TraitItemType> -Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs) +Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs, + AST::Visibility vis) { location_t locus = lexer.peek_token ()->get_locus (); skip_token (TYPE); @@ -5208,7 +5212,7 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs) return std::unique_ptr<AST::TraitItemType> ( new AST::TraitItemType (std::move (ident), std::move (bounds), - std::move (outer_attrs), locus)); + std::move (outer_attrs), vis, locus)); } // Parses a constant trait item. diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 9e924e0015ce..08e6ce000f4d 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see #ifndef RUST_PARSE_H #define RUST_PARSE_H +#include "rust-item.h" #include "rust-lex.h" #include "rust-ast-full.h" #include "rust-diagnostics.h" @@ -331,7 +332,7 @@ private: std::unique_ptr<AST::Trait> parse_trait (AST::Visibility vis, AST::AttrVec outer_attrs); std::unique_ptr<AST::TraitItemType> - parse_trait_type (AST::AttrVec outer_attrs); + parse_trait_type (AST::AttrVec outer_attrs, AST::Visibility); std::unique_ptr<AST::TraitItemConst> parse_trait_const (AST::AttrVec outer_attrs); std::unique_ptr<AST::Param> parse_self_param ();