aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/expand/rust-macro-expand.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/expand/rust-macro-expand.cc')
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc200
1 files changed, 188 insertions, 12 deletions
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 164b5a5..65918db 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -345,20 +345,196 @@ namespace Rust {
expr.get_array_expr()->accept_vis(*this);
expr.get_index_expr()->accept_vis(*this);
}
- void visit(AST::TupleExpr& expr) override {}
- void visit(AST::TupleIndexExpr& expr) override {}
- void visit(AST::StructExprStruct& expr) override {}
- void visit(AST::StructExprFieldIdentifier& field) override {}
- void visit(AST::StructExprFieldIdentifierValue& field) override {}
- void visit(AST::StructExprFieldIndexValue& field) override {}
- void visit(AST::StructExprStructFields& expr) override {}
- void visit(AST::StructExprStructBase& expr) override {}
- void visit(AST::StructExprTuple& expr) override {}
- void visit(AST::StructExprUnit& expr) override {}
- void visit(AST::EnumExprFieldIdentifier& field) override {}
+ void visit(AST::TupleExpr& expr) override {
+ /* according to spec, outer attributes are allowed on "elements of
+ * tuple expressions" */
+
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* strip test based on inner attrs - spec says these are inner
+ * attributes, not outer attributes of inner expr */
+ expander.expand_cfg_attrs(expr.get_inner_attrs());
+ if (expander.fails_cfg(expr.get_inner_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* apparently outer attributes are allowed in "elements of tuple
+ * expressions" according to spec */
+ auto& values = expr.get_tuple_elems();
+ for (int i = 0; i < values.size();) {
+ auto& value = values[i];
+
+ // mark for stripping if required
+ value->accept_vis(*this);
+
+ if (value->is_marked_for_strip())
+ values.erase(values.begin() + i);
+ else
+ i++;
+ }
+ }
+ void visit(AST::TupleIndexExpr& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* wouldn't strip this directly (as outer attrs should be
+ * associated with this level), but any sub-expressions would be
+ * stripped. Thus, no need to erase when strip check called. */
+ expr.get_tuple_expr()->accept_vis(*this);
+ }
+ void visit(AST::StructExprStruct& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* strip test based on inner attrs - spec says these are inner
+ * attributes, not outer attributes of inner expr */
+ expander.expand_cfg_attrs(expr.get_inner_attrs());
+ if (expander.fails_cfg(expr.get_inner_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+ }
+ void visit(AST::StructExprFieldIdentifier& field) override {
+ // as no attrs (at moment, at least), no stripping possible
+ }
+ void visit(AST::StructExprFieldIdentifierValue& field) override {
+ /* as no attrs possible (at moment, at least), only sub-expression
+ * stripping is possible */
+ field.get_value()->accept_vis(*this);
+ }
+ void visit(AST::StructExprFieldIndexValue& field) override {
+ /* as no attrs possible (at moment, at least), only sub-expression
+ * stripping is possible */
+ field.get_value()->accept_vis(*this);
+ }
+ void visit(AST::StructExprStructFields& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* strip test based on inner attrs - spec says these are inner
+ * attributes, not outer attributes of inner expr */
+ expander.expand_cfg_attrs(expr.get_inner_attrs());
+ if (expander.fails_cfg(expr.get_inner_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* spec does not specify whether expressions are allowed to be
+ * stripped at top level of struct fields, but I wouldn't think
+ * that they would be, so operating under the assumption that only
+ * sub-expressions can be stripped. */
+ for (auto& field : expr.get_fields()) {
+ field->accept_vis(*this);
+ // shouldn't strip in this
+ }
+
+ /* struct base presumably can't be stripped, as the '..' is before
+ * the expression. as such, can only strip sub-expressions. */
+ if (expr.has_struct_base())
+ expr.get_struct_base().get_base_struct()->accept_vis(*this);
+ }
+ void visit(AST::StructExprStructBase& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* strip test based on inner attrs - spec says these are inner
+ * attributes, not outer attributes of inner expr */
+ expander.expand_cfg_attrs(expr.get_inner_attrs());
+ if (expander.fails_cfg(expr.get_inner_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* struct base presumably can't be stripped, as the '..' is before
+ * the expression. as such, can only strip sub-expressions. */
+ rust_assert(!expr.get_struct_base().is_invalid());
+ expr.get_struct_base().get_base_struct()->accept_vis(*this);
+ }
+ void visit(AST::StructExprTuple& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* strip test based on inner attrs - spec says these are inner
+ * attributes, not outer attributes of inner expr */
+ expander.expand_cfg_attrs(expr.get_inner_attrs());
+ if (expander.fails_cfg(expr.get_inner_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* spec says outer attributes are specifically allowed for elements
+ * of tuple-style struct expressions, so full stripping possible */
+ auto& values = expr.get_elems();
+ for (int i = 0; i < values.size();) {
+ auto& value = values[i];
+
+ // mark for stripping if required
+ value->accept_vis(*this);
+
+ if (value->is_marked_for_strip())
+ values.erase(values.begin() + i);
+ else
+ i++;
+ }
+ }
+ void visit(AST::StructExprUnit& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+ }
+ void visit(AST::EnumExprFieldIdentifier& field) override {
+
+ }
void visit(AST::EnumExprFieldIdentifierValue& field) override {}
void visit(AST::EnumExprFieldIndexValue& field) override {}
- void visit(AST::EnumExprStruct& expr) override {}
+ void visit(AST::EnumExprStruct& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ // supposedly spec doesn't allow inner attributes in enum exprs
+
+ /* spec does not specify whether expressions are allowed to be
+ * stripped at top level of expression fields, but I wouldn't think
+ * that they would be, so operating under the assumption that only
+ * sub-expressions can be stripped. */
+ for (auto& field : expr.get_fields()) {
+ field->accept_vis(*this);
+ // shouldn't strip in this
+ }
+ }
void visit(AST::EnumExprTuple& expr) override {}
void visit(AST::EnumExprFieldless& expr) override {}
void visit(AST::CallExpr& expr) override {}