aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-item.h36
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc84
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. */