diff options
Diffstat (limited to 'gcc/rust/ast/rust-item.h')
| -rw-r--r-- | gcc/rust/ast/rust-item.h | 644 |
1 files changed, 172 insertions, 472 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 2ae7c44..3e3735c 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -51,21 +51,12 @@ class TypePath; // A type generic parameter (as opposed to a lifetime generic parameter) class TypeParam : public GenericParam { - // bool has_outer_attribute; - // std::unique_ptr<Attribute> outer_attr; AST::AttrVec outer_attrs; - Identifier type_representation; - - // bool has_type_param_bounds; - // TypeParamBounds type_param_bounds; - std::vector<std::unique_ptr<TypeParamBound>> - type_param_bounds; // inlined form - - // bool has_type; + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; std::unique_ptr<Type> type; - location_t locus; + bool was_impl_trait; public: Identifier get_type_representation () const { return type_representation; } @@ -85,18 +76,19 @@ public: std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds = std::vector<std::unique_ptr<TypeParamBound>> (), std::unique_ptr<Type> type = nullptr, - AST::AttrVec outer_attrs = {}) + AST::AttrVec outer_attrs = {}, bool was_impl_trait = false) : GenericParam (Analysis::Mappings::get ().get_next_node_id ()), outer_attrs (std::move (outer_attrs)), type_representation (std::move (type_representation)), type_param_bounds (std::move (type_param_bounds)), - type (std::move (type)), locus (locus) + type (std::move (type)), locus (locus), was_impl_trait (was_impl_trait) {} // Copy constructor uses clone TypeParam (TypeParam const &other) : GenericParam (other.node_id), outer_attrs (other.outer_attrs), - type_representation (other.type_representation), locus (other.locus) + type_representation (other.type_representation), locus (other.locus), + was_impl_trait (other.was_impl_trait) { // guard to prevent null pointer dereference if (other.type != nullptr) @@ -114,6 +106,7 @@ public: outer_attrs = other.outer_attrs; locus = other.locus; node_id = other.node_id; + was_impl_trait = other.was_impl_trait; // guard to prevent null pointer dereference if (other.type != nullptr) @@ -153,17 +146,19 @@ public: return type; } - // TODO: mutable getter seems kinda dodgy std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds () { return type_param_bounds; } + const std::vector<std::unique_ptr<TypeParamBound>> & get_type_param_bounds () const { return type_param_bounds; } + bool from_impl_trait () const { return was_impl_trait; } + protected: // Clone function implementation as virtual method TypeParam *clone_generic_param_impl () const override @@ -434,13 +429,14 @@ class SelfParam : public Param bool has_ref; bool is_mut; // bool has_lifetime; // only possible if also ref - Lifetime lifetime; + tl::optional<Lifetime> lifetime; // bool has_type; // only possible if not ref std::unique_ptr<Type> type; // Unrestricted constructor used for error state - SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type) + SelfParam (tl::optional<Lifetime> lifetime, bool has_ref, bool is_mut, + Type *type) : Param ({}, UNDEF_LOCATION), has_ref (has_ref), is_mut (is_mut), lifetime (std::move (lifetime)), type (type) {} @@ -453,7 +449,7 @@ public: bool has_type () const { return type != nullptr; } // Returns whether the self-param has a valid lifetime. - bool has_lifetime () const { return !lifetime.is_error (); } + bool has_lifetime () const { return lifetime.has_value (); } // Returns whether the self-param is in an error state. bool is_error () const @@ -472,11 +468,11 @@ public: // Type-based self parameter (not ref, no lifetime) SelfParam (std::unique_ptr<Type> type, bool is_mut, location_t locus) : Param ({}, locus), has_ref (false), is_mut (is_mut), - lifetime (Lifetime::error ()), type (std::move (type)) + lifetime (tl::nullopt), type (std::move (type)) {} // Lifetime-based self parameter (is ref, no type) - SelfParam (Lifetime lifetime, bool is_mut, location_t locus) + SelfParam (tl::optional<Lifetime> lifetime, bool is_mut, location_t locus) : Param ({}, locus), has_ref (true), is_mut (is_mut), lifetime (std::move (lifetime)) {} @@ -522,8 +518,8 @@ public: bool get_has_ref () const { return has_ref; }; bool get_is_mut () const { return is_mut; } - Lifetime get_lifetime () const { return lifetime; } - Lifetime &get_lifetime () { return lifetime; } + Lifetime get_lifetime () const { return lifetime.value (); } + Lifetime &get_lifetime () { return lifetime.value (); } NodeId get_node_id () const { return node_id; } @@ -635,6 +631,12 @@ public: return *param_name; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (param_name != nullptr); + return param_name; + } + const Pattern &get_pattern () const { rust_assert (param_name != nullptr); @@ -718,6 +720,12 @@ public: return *param_name; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (param_name != nullptr); + return param_name; + } + bool has_name () const { return param_name != nullptr; } // TODO: is this better? Or is a "vis_block" better? @@ -758,8 +766,6 @@ public: Identifier get_name () const { return module_name; } - AST::Kind get_ast_kind () const override { return AST::Kind::MODULE; } - private: Identifier module_name; location_t locus; @@ -899,6 +905,8 @@ public: void mark_for_strip () override { module_name = {""}; } bool is_marked_for_strip () const override { return module_name.empty (); } + Item::Kind get_item_kind () const override { return Item::Kind::Module; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -960,6 +968,8 @@ public: return referenced_crate.empty (); } + Item::Kind get_item_kind () const override { return Item::Kind::ExternCrate; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -1301,6 +1311,11 @@ public: void mark_for_strip () override { use_tree = nullptr; } bool is_marked_for_strip () const override { return use_tree == nullptr; } + Item::Kind get_item_kind () const override + { + return Item::Kind::UseDeclaration; + } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -1323,7 +1338,7 @@ class Function : public VisItem, public AssociatedItem, public ExternalItem WhereClause where_clause; tl::optional<std::unique_ptr<BlockExpr>> function_body; location_t locus; - bool is_default; + bool has_default; bool is_external_function; public: @@ -1348,6 +1363,8 @@ public: bool has_body () const { return function_body.has_value (); } + bool is_default () const { return has_default; } + // Mega-constructor with all possible fields Function (Identifier function_name, FunctionQualifiers qualifiers, std::vector<std::unique_ptr<GenericParam>> generic_params, @@ -1355,7 +1372,7 @@ public: std::unique_ptr<Type> return_type, WhereClause where_clause, tl::optional<std::unique_ptr<BlockExpr>> function_body, Visibility vis, std::vector<Attribute> outer_attrs, - location_t locus, bool is_default = false, + location_t locus, bool has_default = false, bool is_external_function = false) : VisItem (std::move (vis), std::move (outer_attrs)), ExternalItem (Stmt::node_id), qualifiers (std::move (qualifiers)), @@ -1365,7 +1382,7 @@ public: return_type (std::move (return_type)), where_clause (std::move (where_clause)), function_body (std::move (function_body)), locus (locus), - is_default (is_default), is_external_function (is_external_function) + has_default (has_default), is_external_function (is_external_function) {} // TODO: add constructor with less fields @@ -1459,6 +1476,8 @@ public: // ExternalItem::node_id is same as Stmt::node_id NodeId get_node_id () const override { return Stmt::node_id; } + Item::Kind get_item_kind () const override { return Item::Kind::Function; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -1560,6 +1579,9 @@ public: location_t get_locus () const override final { return locus; } + // needed to override AssociatedItem::get_node_id + NodeId get_node_id () const override final { return VisItem::get_node_id (); } + void accept_vis (ASTVisitor &vis) override; // Invalid if existing type is null, so base stripping on that. @@ -1588,8 +1610,16 @@ public: return *existing_type; } + std::unique_ptr<Type> &get_type_aliased_ptr () + { + rust_assert (existing_type != nullptr); + return existing_type; + } + Identifier get_new_type_name () const { return new_type_name; } + Item::Kind get_item_kind () const override { return Item::Kind::TypeAlias; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -1649,6 +1679,8 @@ public: Identifier get_identifier () const { return struct_name; } + Item::Kind get_item_kind () const override { return Item::Kind::Struct; } + protected: Struct (Identifier struct_name, std::vector<std::unique_ptr<GenericParam>> generic_params, @@ -1994,6 +2026,41 @@ class EnumItem : public VisItem location_t locus; public: + enum class Kind + { + Identifier, + Tuple, + Struct, + + // FIXME: In the future, we'll need to remove this possibility as well as + // remove the EnumItemDiscriminant class. The feature for arbitrary + // discriminants on all kinds of variants has been stabilized, and a + // "discriminant" is no longer an enum item variant - it's simply an + // optional part of all variants. + // + // Per the reference: + // + // EnumItem : + // OuterAttribute* Visibility? + // IDENTIFIER ( EnumItemTuple | EnumItemStruct )? EnumItemDiscriminant? + // + // EnumItemTuple : + // ( TupleFields? ) + // + // EnumItemStruct : + // { StructFields? } + // + // EnumItemDiscriminant : + // = Expression + // + // So we instead need to remove the class, and add an optional expression to + // the base EnumItem class + // + // gccrs#3340 + + Discriminant, + }; + virtual ~EnumItem () {} EnumItem (Identifier variant_name, Visibility vis, @@ -2002,6 +2069,8 @@ public: variant_name (std::move (variant_name)), locus (locus) {} + virtual Kind get_enum_item_kind () const { return Kind::Identifier; } + // Unique pointer custom clone function std::unique_ptr<EnumItem> clone_enum_item () const { @@ -2021,6 +2090,8 @@ public: void mark_for_strip () override { variant_name = {""}; } bool is_marked_for_strip () const override { return variant_name.empty (); } + Item::Kind get_item_kind () const override { return Item::Kind::EnumItem; } + protected: EnumItem *clone_item_impl () const override { return new EnumItem (*this); } }; @@ -2043,6 +2114,11 @@ public: tuple_fields (std::move (tuple_fields)) {} + EnumItem::Kind get_enum_item_kind () const override + { + return EnumItem::Kind::Tuple; + } + std::string as_string () const override; void accept_vis (ASTVisitor &vis) override; @@ -2080,6 +2156,11 @@ public: struct_fields (std::move (struct_fields)) {} + EnumItem::Kind get_enum_item_kind () const override + { + return EnumItem::Kind::Struct; + } + std::string as_string () const override; void accept_vis (ASTVisitor &vis) override; @@ -2133,6 +2214,11 @@ public: EnumItemDiscriminant (EnumItemDiscriminant &&other) = default; EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default; + EnumItem::Kind get_enum_item_kind () const override + { + return EnumItem::Kind::Discriminant; + } + std::string as_string () const override; void accept_vis (ASTVisitor &vis) override; @@ -2269,6 +2355,8 @@ public: // TODO: is this better? Or is a "vis_block" better? WhereClause &get_where_clause () { return where_clause; } + Item::Kind get_item_kind () const override { return Item::Kind::Enum; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -2368,6 +2456,8 @@ public: Identifier get_identifier () const { return union_name; } + Item::Kind get_item_kind () const override { return Item::Kind::Union; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -2381,7 +2471,7 @@ class ConstantItem : public VisItem, public AssociatedItem // either has an identifier or "_" - maybe handle in identifier? // bool identifier_is_underscore; // if no identifier declared, identifier will be "_" - std::string identifier; + Identifier identifier; std::unique_ptr<Type> type; std::unique_ptr<Expr> const_expr; @@ -2391,7 +2481,7 @@ class ConstantItem : public VisItem, public AssociatedItem public: std::string as_string () const override; - ConstantItem (std::string ident, Visibility vis, std::unique_ptr<Type> type, + ConstantItem (Identifier ident, Visibility vis, std::unique_ptr<Type> type, std::unique_ptr<Expr> const_expr, std::vector<Attribute> outer_attrs, location_t locus) : VisItem (std::move (vis), std::move (outer_attrs)), @@ -2399,7 +2489,7 @@ public: const_expr (std::move (const_expr)), locus (locus) {} - ConstantItem (std::string ident, Visibility vis, std::unique_ptr<Type> type, + ConstantItem (Identifier ident, Visibility vis, std::unique_ptr<Type> type, std::vector<Attribute> outer_attrs, location_t locus) : VisItem (std::move (vis), std::move (outer_attrs)), identifier (std::move (ident)), type (std::move (type)), @@ -2442,13 +2532,16 @@ public: /* Returns whether constant item is an "unnamed" (wildcard underscore used * as identifier) constant. */ - bool is_unnamed () const { return identifier == "_"; } + bool is_unnamed () const { return identifier.as_string () == "_"; } location_t get_locus () const override final { return locus; } + // needed to override AssociatedItem::get_node_id + NodeId get_node_id () const override final { return VisItem::get_node_id (); } + void accept_vis (ASTVisitor &vis) override; - // Invalid if type or expression are null, so base stripping on that. + // Invalid if type and expression are null, so base stripping on that. void mark_for_strip () override { type = nullptr; @@ -2459,7 +2552,7 @@ public: return type == nullptr && const_expr == nullptr; } - bool has_expr () { return const_expr != nullptr; } + bool has_expr () const { return const_expr != nullptr; } // TODO: is this better? Or is a "vis_block" better? Expr &get_expr () @@ -2487,7 +2580,12 @@ public: return type; } - std::string get_identifier () const { return identifier; } + const Identifier &get_identifier () const { return identifier; } + + Item::Kind get_item_kind () const override + { + return Item::Kind::ConstantItem; + } protected: /* Use covariance to implement clone function as returning this object @@ -2610,6 +2708,8 @@ public: Identifier get_identifier () const { return name; } + Item::Kind get_item_kind () const override { return Item::Kind::StaticItem; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -2619,123 +2719,6 @@ protected: } }; -// Constant item within traits -class TraitItemConst : public TraitItem -{ - std::vector<Attribute> outer_attrs; - Identifier name; - std::unique_ptr<Type> type; - - // bool has_expression; - std::unique_ptr<Expr> expr; - -public: - // Whether the constant item has an associated expression. - bool has_expression () const { return expr != nullptr; } - - TraitItemConst (Identifier name, std::unique_ptr<Type> type, - std::unique_ptr<Expr> expr, - std::vector<Attribute> outer_attrs, location_t locus) - : TraitItem (locus), outer_attrs (std::move (outer_attrs)), - name (std::move (name)), type (std::move (type)), expr (std::move (expr)) - {} - - // Copy constructor with clones - TraitItemConst (TraitItemConst const &other) - : TraitItem (other.locus), outer_attrs (other.outer_attrs), - name (other.name) - { - node_id = other.node_id; - - // guard to prevent null dereference - if (other.expr != nullptr) - expr = other.expr->clone_expr (); - - // guard to prevent null dereference (only for error state) - if (other.type != nullptr) - type = other.type->clone_type (); - } - - // Overloaded assignment operator to clone - TraitItemConst &operator= (TraitItemConst const &other) - { - TraitItem::operator= (other); - outer_attrs = other.outer_attrs; - name = other.name; - locus = other.locus; - node_id = other.node_id; - - // guard to prevent null dereference - if (other.expr != nullptr) - expr = other.expr->clone_expr (); - else - expr = nullptr; - - // guard to prevent null dereference (only for error state) - if (other.type != nullptr) - type = other.type->clone_type (); - else - type = nullptr; - - return *this; - } - - // move constructors - TraitItemConst (TraitItemConst &&other) = default; - TraitItemConst &operator= (TraitItemConst &&other) = default; - - std::string as_string () const override; - - location_t get_locus () const override { return locus; } - - void accept_vis (ASTVisitor &vis) override; - - // Invalid if type is null, so base stripping on that. - void mark_for_strip () override { type = nullptr; } - bool is_marked_for_strip () const override { return type == nullptr; } - - // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - - bool has_expr () const { return expr != nullptr; } - - // TODO: is this better? Or is a "vis_block" better? - Expr &get_expr () - { - rust_assert (has_expr ()); - return *expr; - } - - std::unique_ptr<Expr> &get_expr_ptr () - { - rust_assert (has_expr ()); - return expr; - } - - // TODO: is this better? Or is a "vis_block" better? - Type &get_type () - { - rust_assert (type != nullptr); - return *type; - } - - std::unique_ptr<Type> &get_type_ptr () - { - rust_assert (type != nullptr); - return type; - } - - Identifier get_identifier () const { return name; } - -protected: - // Clone function implementation as (not pure) virtual method - TraitItemConst *clone_associated_item_impl () const override - { - return new TraitItemConst (*this); - } -}; - // Type items within traits class TraitItemType : public TraitItem { @@ -2743,21 +2726,28 @@ class TraitItemType : public TraitItem Identifier name; + // Generic parameters for GATs (Generic Associated Types) + std::vector<std::unique_ptr<GenericParam>> generic_params; + // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; // inlined form public: + bool has_generics () const { return !generic_params.empty (); } + // Returns whether trait item type has type param bounds. bool has_type_param_bounds () const { return !type_param_bounds.empty (); } TraitItemType (Identifier name, + std::vector<std::unique_ptr<GenericParam>> generic_params, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, 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)) + name (std::move (name)), generic_params (std::move (generic_params)), + type_param_bounds (std::move (type_param_bounds)) {} // Copy constructor with vector clone @@ -2766,6 +2756,9 @@ public: name (other.name) { node_id = other.node_id; + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) type_param_bounds.push_back (e->clone_type_param_bound ()); @@ -2780,6 +2773,9 @@ public: locus = other.locus; node_id = other.node_id; + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) type_param_bounds.push_back (e->clone_type_param_bound ()); @@ -2803,7 +2799,15 @@ public: std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - // TODO: mutable getter seems kinda dodgy + std::vector<std::unique_ptr<GenericParam>> &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const + { + return generic_params; + } + std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds () { return type_param_bounds; @@ -2831,6 +2835,7 @@ class Trait : public VisItem bool has_auto; Identifier name; std::vector<std::unique_ptr<GenericParam>> generic_params; + TypeParam self_param; std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; WhereClause where_clause; std::vector<Attribute> inner_attrs; @@ -2870,7 +2875,7 @@ public: std::vector<Attribute> inner_attrs, location_t locus) : VisItem (std::move (vis), std::move (outer_attrs)), has_unsafe (is_unsafe), has_auto (is_auto), name (std::move (name)), - generic_params (std::move (generic_params)), + generic_params (std::move (generic_params)), self_param ({"Self"}, locus), type_param_bounds (std::move (type_param_bounds)), where_clause (std::move (where_clause)), inner_attrs (std::move (inner_attrs)), @@ -2880,8 +2885,9 @@ public: // Copy constructor with vector clone Trait (Trait const &other) : VisItem (other), has_unsafe (other.has_unsafe), has_auto (other.has_auto), - name (other.name), where_clause (other.where_clause), - inner_attrs (other.inner_attrs), locus (other.locus) + name (other.name), self_param (other.self_param), + where_clause (other.where_clause), inner_attrs (other.inner_attrs), + locus (other.locus) { generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) @@ -2901,6 +2907,7 @@ public: { VisItem::operator= (other); name = other.name; + self_param = other.self_param; has_unsafe = other.has_unsafe; has_auto = other.has_auto; where_clause = other.where_clause; @@ -2968,19 +2975,9 @@ public: WhereClause &get_where_clause () { return where_clause; } - void insert_implict_self (std::unique_ptr<AST::GenericParam> &¶m) - { - std::vector<std::unique_ptr<GenericParam>> new_list; - new_list.reserve (generic_params.size () + 1); - - new_list.push_back (std::move (param)); - for (auto &p : generic_params) - { - new_list.push_back (std::move (p)); - } + AST::TypeParam &get_implicit_self () { return self_param; } - generic_params = std::move (new_list); - } + Item::Kind get_item_kind () const override { return Item::Kind::Trait; } protected: /* Use covariance to implement clone function as returning this object @@ -3054,6 +3051,8 @@ public: return trait_type; } + Item::Kind get_item_kind () const override { return Item::Kind::Impl; } + protected: // Mega-constructor Impl (std::vector<std::unique_ptr<GenericParam>> generic_params, @@ -3202,8 +3201,8 @@ public: : Impl (std::move (generic_params), std::move (trait_type), std::move (where_clause), std::move (vis), std::move (inner_attrs), std::move (outer_attrs), locus), - has_unsafe (is_unsafe), has_exclam (has_exclam), - trait_path (std::move (trait_path)), impl_items (std::move (impl_items)) + has_unsafe (is_unsafe), has_exclam (has_exclam), trait_path (trait_path), + impl_items (std::move (impl_items)) {} // Copy constructor with vector clone @@ -3251,11 +3250,7 @@ public: } // TODO: is this better? Or is a "vis_block" better? - TypePath &get_trait_path () - { - // TODO: assert that trait path is not empty? - return trait_path; - } + TypePath &get_trait_path () { return trait_path; } protected: /* Use covariance to implement clone function as returning this object @@ -3528,303 +3523,6 @@ protected: } }; -// A named function parameter used in external functions -class NamedFunctionParam -{ - // bool has_name; // otherwise is _ - std::string name; - - std::unique_ptr<Type> param_type; - - // seemingly new since writing this node - std::vector<Attribute> outer_attrs; - - NodeId node_id; - location_t locus; - bool variadic; - -public: - /* Returns whether the named function parameter has a name (i.e. name is not - * '_'). */ - bool has_name () const { return name != "_" && name != ""; } - - bool has_outer_attrs () const { return !outer_attrs.empty (); } - - // Returns whether the named function parameter is in an error state. - bool is_error () const - { - // also if identifier is "" but that is probably more costly to compute - return param_type == nullptr && !variadic; - } - - bool is_variadic () const { return variadic; } - - std::string get_name () const { return name; } - - location_t get_locus () { return locus; } - - // Creates an error state named function parameter. - static NamedFunctionParam create_error () - { - return NamedFunctionParam ("", nullptr, {}, UNDEF_LOCATION); - } - - NamedFunctionParam (std::string name, std::unique_ptr<Type> param_type, - std::vector<Attribute> outer_attrs, location_t locus) - : name (std::move (name)), param_type (std::move (param_type)), - outer_attrs (std::move (outer_attrs)), - node_id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus), - variadic (false) - {} - - NamedFunctionParam (std::string name, std::vector<Attribute> outer_attrs, - location_t locus) - : name (std::move (name)), param_type (nullptr), - outer_attrs (std::move (outer_attrs)), - node_id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus), - variadic (true) - {} - - NamedFunctionParam (std::vector<Attribute> outer_attrs, location_t locus) - : name (""), param_type (nullptr), outer_attrs (std::move (outer_attrs)), - node_id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus), - variadic (true) - {} - - // Copy constructor - NamedFunctionParam (NamedFunctionParam const &other) - : name (other.name), outer_attrs (other.outer_attrs), - variadic (other.variadic) - { - node_id = other.node_id; - // guard to prevent null dereference (only required if error state) - if (other.param_type != nullptr) - param_type = other.param_type->clone_type (); - else - param_type = nullptr; - } - - ~NamedFunctionParam () = default; - - // Overloaded assignment operator to clone - NamedFunctionParam &operator= (NamedFunctionParam const &other) - { - node_id = other.node_id; - name = other.name; - // has_name = other.has_name; - outer_attrs = other.outer_attrs; - - // guard to prevent null dereference (only required if error state) - if (other.param_type != nullptr) - param_type = other.param_type->clone_type (); - else - param_type = nullptr; - - return *this; - } - - // move constructors - NamedFunctionParam (NamedFunctionParam &&other) = default; - NamedFunctionParam &operator= (NamedFunctionParam &&other) = default; - - std::string as_string () const; - - // Based on idea that nane should never be empty. - void mark_for_strip () { param_type = nullptr; }; - bool is_marked_for_strip () const { return is_error (); }; - - // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - - // TODO: is this better? Or is a "vis_block" better? - Type &get_type () - { - rust_assert (param_type != nullptr); - return *param_type; - } - - std::unique_ptr<Type> &get_type_ptr () - { - rust_assert (param_type != nullptr); - return param_type; - } - - NodeId get_node_id () const { return node_id; } -}; - -// A function item used in an extern block -class ExternalFunctionItem : public ExternalItem -{ - // bool has_outer_attrs; - std::vector<Attribute> outer_attrs; - - // bool has_visibility; - Visibility visibility; - - Identifier item_name; - location_t locus; - - // bool has_generics; - // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined - - // bool has_return_type; - // FunctionReturnType return_type; - std::unique_ptr<Type> return_type; // inlined - - // bool has_where_clause; - WhereClause where_clause; - - std::vector<NamedFunctionParam> function_params; - -public: - // Returns whether item has generic parameters. - bool has_generics () const { return !generic_params.empty (); } - - // Returns whether item has a return type (otherwise void). - bool has_return_type () const { return return_type != nullptr; } - - // Returns whether item has a where clause. - bool has_where_clause () const { return !where_clause.is_empty (); } - - // Returns whether item has outer attributes. - bool has_outer_attrs () const { return !outer_attrs.empty (); } - - // Returns whether item has non-default visibility. - bool has_visibility () const { return !visibility.is_error (); } - - // Returns whether item has variadic parameters. - bool is_variadic () const - { - return function_params.size () != 0 - && function_params.back ().is_variadic (); - } - - location_t get_locus () const { return locus; } - - Visibility &get_visibility () { return visibility; } - const Visibility &get_visibility () const { return visibility; } - - ExternalFunctionItem ( - Identifier item_name, - std::vector<std::unique_ptr<GenericParam>> generic_params, - std::unique_ptr<Type> return_type, WhereClause where_clause, - std::vector<NamedFunctionParam> function_params, Visibility vis, - std::vector<Attribute> outer_attrs, location_t locus) - : ExternalItem (), outer_attrs (std::move (outer_attrs)), - visibility (std::move (vis)), item_name (std::move (item_name)), - locus (locus), generic_params (std::move (generic_params)), - return_type (std::move (return_type)), - where_clause (std::move (where_clause)), - function_params (std::move (function_params)) - { - // TODO: assert that if has variadic outer attrs, then has_variadics is - // true? - } - - // Copy constructor with clone - ExternalFunctionItem (ExternalFunctionItem const &other) - : ExternalItem (other.get_node_id ()), outer_attrs (other.outer_attrs), - visibility (other.visibility), item_name (other.item_name), - locus (other.locus), where_clause (other.where_clause), - function_params (other.function_params) - { - node_id = other.node_id; - // guard to prevent null pointer dereference - if (other.return_type != nullptr) - return_type = other.return_type->clone_type (); - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - } - - // Overloaded assignment operator with clone - ExternalFunctionItem &operator= (ExternalFunctionItem const &other) - { - outer_attrs = other.outer_attrs; - visibility = other.visibility; - item_name = other.item_name; - locus = other.locus; - where_clause = other.where_clause; - function_params = other.function_params; - node_id = other.node_id; - - // guard to prevent null pointer dereference - if (other.return_type != nullptr) - return_type = other.return_type->clone_type (); - else - return_type = nullptr; - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - return *this; - } - - // move constructors - ExternalFunctionItem (ExternalFunctionItem &&other) = default; - ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default; - - std::string as_string () const override; - - void accept_vis (ASTVisitor &vis) override; - - // Based on idea that nane should never be empty. - void mark_for_strip () override { item_name = {""}; }; - bool is_marked_for_strip () const override { return item_name.empty (); }; - - // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - - std::vector<NamedFunctionParam> &get_function_params () - { - return function_params; - } - const std::vector<NamedFunctionParam> &get_function_params () const - { - return function_params; - } - - std::vector<std::unique_ptr<GenericParam>> &get_generic_params () - { - return generic_params; - } - const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const - { - return generic_params; - } - - // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { return where_clause; } - - // TODO: is this better? Or is a "vis_block" better? - Type &get_return_type () - { - rust_assert (has_return_type ()); - return *return_type; - } - - std::unique_ptr<Type> &get_return_type_ptr () - { - rust_assert (has_return_type ()); - return return_type; - } - - Identifier get_identifier () const { return item_name; }; - -protected: - /* Use covariance to implement clone function as returning this object - * rather than base */ - ExternalFunctionItem *clone_external_item_impl () const override - { - return new ExternalFunctionItem (*this); - } -}; - // An extern block AST node class ExternBlock : public VisItem { @@ -3917,6 +3615,8 @@ public: const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } + Item::Kind get_item_kind () const override { return Item::Kind::ExternBlock; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ |
