diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-item.h | 36 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 84 |
2 files changed, 97 insertions, 23 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index a56d1b5..a4ff3eb 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -1585,9 +1585,12 @@ public: // Copy constructor StructField (StructField const &other) : outer_attrs (other.outer_attrs), visibility (other.visibility), - field_name (other.field_name), - field_type (other.field_type->clone_type ()) - {} + field_name (other.field_name) + { + // guard to prevent null dereference + if (other.field_type != nullptr) + field_type = other.field_type->clone_type (); + } ~StructField () = default; @@ -1595,10 +1598,15 @@ public: StructField &operator= (StructField const &other) { field_name = other.field_name; - field_type = other.field_type->clone_type (); visibility = other.visibility; outer_attrs = other.outer_attrs; + // guard to prevent null dereference + if (other.field_type != nullptr) + field_type = other.field_type->clone_type (); + else + field_type = nullptr; + return *this; } @@ -1620,6 +1628,10 @@ public: } std::string as_string () const; + + // 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; } }; // Rust struct declaration with true struct type AST node @@ -2074,6 +2086,10 @@ public: void mark_for_strip () override { union_name = ""; } bool is_marked_for_strip () const override { return union_name.empty (); } + // TODO: this mutable getter seems really dodgy. Think up better way. + std::vector<StructField> &get_variants () { return variants; } + const std::vector<StructField> &get_variants () const { return variants; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -2420,6 +2436,12 @@ public: std::vector<FunctionParam> &get_function_params () { return decl.get_function_params (); } const std::vector<FunctionParam> &get_function_params () const { return decl.get_function_params (); } + // TODO: is this better? Or is a "vis_block" better? + std::unique_ptr<BlockExpr> &get_definition () { + rust_assert (has_definition()); + return block_expr; + } + protected: // Clone function implementation as (not pure) virtual method TraitItemFunc *clone_trait_item_impl () const override @@ -2602,6 +2624,12 @@ public: std::vector<FunctionParam> &get_function_params () { return decl.get_function_params (); } const std::vector<FunctionParam> &get_function_params () const { return decl.get_function_params (); } + // TODO: is this better? Or is a "vis_block" better? + std::unique_ptr<BlockExpr> &get_definition () { + rust_assert (has_definition()); + return block_expr; + } + protected: // Clone function implementation as (not pure) virtual method TraitItemMethod *clone_trait_item_impl () const override diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index c7524dc..ad97e2cd 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -12,6 +12,28 @@ namespace Rust { public: AttrVisitor(MacroExpander& expander) : expander(expander) {} + void expand_struct_fields(std::vector<AST::StructField>& fields) { + for (int i = 0; i < fields.size(); ) { + auto& field_attrs = fields[i].get_outer_attrs (); + expander.expand_cfg_attrs(field_attrs); + if (expander.fails_cfg (field_attrs)) + fields.erase (fields.begin() + i); + else + i++; + } + } + + void expand_function_params(std::vector<AST::FunctionParam>& params) { + for (int i = 0; i < params.size(); ) { + auto& param_attrs = params[i].get_outer_attrs (); + expander.expand_cfg_attrs(param_attrs); + if (expander.fails_cfg (param_attrs)) + params.erase (params.begin() + i); + else + i++; + } + } + void visit(AST::Token& tok) override {} void visit(AST::DelimTokenTree& delim_tok_tree) override {} void visit(AST::AttrInputMetaItemContainer& input) override {} @@ -122,10 +144,37 @@ namespace Rust { void visit(AST::EnumItemStruct& item) override {} void visit(AST::EnumItemDiscriminant& item) override {} void visit(AST::Enum& enum_item) override {} - void visit(AST::Union& union_item) override {} - void visit(AST::ConstantItem& const_item) override {} - void visit(AST::StaticItem& static_item) override { + void visit(AST::Union& union_item) override { + // initial test based on outer attrs + expander.expand_cfg_attrs(union_item.get_outer_attrs()); + if (expander.fails_cfg(union_item.get_outer_attrs())) { + union_item.mark_for_strip(); + return; + } + /* strip union fields if required - this is presumably + * allowed by spec */ + expand_struct_fields(union_item.get_variants()); + } + void visit(AST::ConstantItem& const_item) override { + // initial test based on outer attrs + expander.expand_cfg_attrs(const_item.get_outer_attrs()); + if (expander.fails_cfg(const_item.get_outer_attrs())) { + const_item.mark_for_strip(); + return; + } + /* TODO: is there any way to invalidate the expr? Are attributes + * even allowed on it? */ + } + void visit(AST::StaticItem& static_item) override { + // initial test based on outer attrs + expander.expand_cfg_attrs(static_item.get_outer_attrs()); + if (expander.fails_cfg(static_item.get_outer_attrs())) { + static_item.mark_for_strip(); + return; + } + /* TODO: is there any way to invalidate the expr? Are attributes + * even allowed on it? */ } void visit(AST::TraitItemFunc& item) override { // initial test based on outer attrs @@ -137,14 +186,11 @@ namespace Rust { /* strip function parameters if required - this is specifically * allowed by spec */ - auto& params = item.get_function_params(); - for (int i = 0; i < params.size(); ) { - auto& param_attrs = params[i].get_outer_attrs (); - expander.expand_cfg_attrs(param_attrs); - if (expander.fails_cfg (param_attrs)) - params.erase (params.begin() + i); - else - i++; + expand_function_params(item.get_function_params()); + + if (item.has_definition()) { + item.get_definition()->accept_vis(*this); + // TODO: can block as a whole be invalidated here? Assuming no } } void visit(AST::TraitItemMethod& item) override { @@ -161,14 +207,11 @@ namespace Rust { /* strip function parameters if required - this is specifically * allowed by spec */ - auto& params = item.get_function_params(); - for (int i = 0; i < params.size(); ) { - auto& param_attrs = params[i].get_outer_attrs (); - expander.expand_cfg_attrs(param_attrs); - if (expander.fails_cfg (param_attrs)) - params.erase (params.begin() + i); - else - i++; + expand_function_params(item.get_function_params()); + + if (item.has_definition()) { + item.get_definition()->accept_vis(*this); + // TODO: can block as a whole be invalidated here? Assuming no } } void visit(AST::TraitItemConst& item) override { @@ -303,6 +346,9 @@ namespace Rust { else i++; } + /* NOTE: these are extern function params, which may have different + * rules and restrictions to "normal" function params. So expansion + * handled separately. */ /* TODO: assuming that variadic nature cannot be stripped. If this * is not true, then have code here to do so. */ |