diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 1390 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 549 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 446 | ||||
-rw-r--r-- | gcc/rust/ast/rust-item.h | 12 | ||||
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 116 | ||||
-rw-r--r-- | gcc/rust/ast/rust-path.h | 61 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 639 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.h | 20 | ||||
-rw-r--r-- | gcc/rust/lex/rust-token.h | 14 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 228 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 2 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 17 |
12 files changed, 1570 insertions, 1924 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index ef21360..2c196a0 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -109,38 +109,78 @@ frag_spec_to_str (MacroFragSpec frag_spec) } } -std::string -Crate::as_string () const +enum AttrMode { - fprintf (stderr, "beginning crate recursive as-string\n"); + OUTER, + INNER +}; - std::string str ("Crate: "); - // add utf8bom and shebang - if (has_utf8bom) - { - str += "\n has utf8bom"; - } - if (has_shebang) +std::string +get_mode_dump_desc (AttrMode mode) +{ + switch (mode) { - str += "\n has shebang"; + case OUTER: + return "outer attributes"; + case INNER: + return "inner attributes"; + default: + gcc_unreachable (); + return ""; } +} - // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) +// Adds lines below adding attributes +std::string +append_attributes (std::vector<Attribute> attrs, AttrMode mode) +{ + indent_spaces (enter); + + std::string str + = "\n" + indent_spaces (stay) + get_mode_dump_desc (mode) + ": "; + // str += "\n" + indent_spaces (stay) + "inner attributes: "; + if (attrs.empty ()) { str += "none"; } else { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - { - str += "\n " + attr.as_string (); - } + /* note that this does not print them with outer or "inner attribute" + * syntax - just prints the body */ + for (const auto &attr : attrs) + str += "\n" + indent_spaces (stay) + attr.as_string (); } + indent_spaces (out); + + return str; +} + +// Removes the beginning and end quotes of a quoted string. +std::string +unquote_string (std::string input) +{ + rust_assert (input.front () == '"'); + rust_assert (input.back () == '"'); + return input.substr (1, input.length () - 2); +} + +std::string +Crate::as_string () const +{ + fprintf (stderr, "beginning crate recursive as-string\n"); + + std::string str ("Crate: "); + // add utf8bom and shebang + if (has_utf8bom) + str += "\n has utf8bom"; + + if (has_shebang) + str += "\n has shebang"; + + // inner attributes + str += append_attributes (inner_attrs, INNER); + // items str += "\n items: "; if (items.empty ()) @@ -156,7 +196,7 @@ Crate::as_string () const { fprintf (stderr, "something really terrible has gone wrong - " "null pointer item in crate."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + item->as_string (); @@ -236,7 +276,7 @@ DelimTokenTree::as_string () const stderr, "something really terrible has gone wrong - null pointer " "token tree in delim token tree."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += tree->as_string (); @@ -250,13 +290,17 @@ DelimTokenTree::as_string () const std::string Token::as_string () const { - /* FIXME: only works when not identifier or literal or whatever, i.e. when - * doesn't store string value */ - // return get_token_description(token_id); + if (tok_ref->has_str ()) + { + std::string str = tok_ref->get_str (); - // maybe fixed - stores everything as string though, so storage-inefficient - std::string quote = is_string_lit () ? "\"" : ""; - return quote + str + quote; + std::string quote = is_string_lit () ? "\"" : ""; + return quote + str + quote; + } + else + { + return tok_ref->get_token_description (); + } } std::string @@ -270,9 +314,7 @@ SimplePath::as_string () const { std::string path; if (has_opening_scope_resolution) - { - path = "::"; - } + path = "::"; // crappy hack because doing proper for loop would be more code bool first_time = true; @@ -336,30 +378,11 @@ VisItem::as_string () const } if (has_visibility ()) - { - str = visibility.as_string () + " "; - } + str += visibility.as_string () + " "; return str; } -// Creates a string that reflects the outer attributes stored. -/*std::string -Item::as_string () const -{ - std::string str; - - if (!outer_attrs.empty ()) - { - for (const auto &attr : outer_attrs) - { - str += attr.as_string () + "\n"; - } - } - - return str; -}*/ - std::string Module::as_string () const { @@ -375,20 +398,7 @@ ModuleBodied::as_string () const std::string str = Module::as_string (); // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - { - str += "\n " + attr.as_string (); - } - } + str += append_attributes (inner_attrs, INNER); // items str += "\n items: "; @@ -405,7 +415,7 @@ ModuleBodied::as_string () const { fprintf (stderr, "something really terrible has gone wrong - " "null pointer item in crate."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + item->as_string (); @@ -433,9 +443,7 @@ StaticItem::as_string () const str += indent_spaces (stay) + "static"; if (has_mut) - { - str += " mut"; - } + str += " mut"; str += " " + name; @@ -444,7 +452,7 @@ StaticItem::as_string () const { fprintf (stderr, "something really terrible has gone wrong - null " "pointer type in static item."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n" + indent_spaces (stay) + "Type: " + type->as_string (); @@ -453,7 +461,7 @@ StaticItem::as_string () const { fprintf (stderr, "something really terrible has gone wrong - null " "pointer expr in static item."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n" + indent_spaces (stay) + "Expression: " + expr->as_string (); @@ -468,9 +476,7 @@ ExternCrate::as_string () const str += "extern crate " + referenced_crate; if (has_as_clause ()) - { - str += " as " + as_clause_name; - } + str += " as " + as_clause_name; return str; } @@ -499,7 +505,7 @@ TupleStruct::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in enum."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -515,20 +521,14 @@ TupleStruct::as_string () const else { for (const auto &field : fields) - { - str += "\n " + field.as_string (); - } + str += "\n " + field.as_string (); } str += "\n Where clause: "; if (has_where_clause ()) - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); else - { - str += "none"; - } + str += "none"; return str; } @@ -545,7 +545,7 @@ ConstantItem::as_string () const { fprintf (stderr, "something really terrible has gone wrong - null " "pointer type in const item."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n Type: " + type->as_string (); @@ -554,7 +554,7 @@ ConstantItem::as_string () const { fprintf (stderr, "something really terrible has gone wrong - null " "pointer expr in const item."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n Expression: " + const_expr->as_string (); @@ -585,7 +585,7 @@ InherentImpl::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in inherent impl."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -596,29 +596,12 @@ InherentImpl::as_string () const str += "\n Where clause: "; if (has_where_clause ()) - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); else - { - str += "none"; - } + str += "none"; // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - { - str += "\n " + attr.as_string (); - } - } + str += append_attributes (inner_attrs, INNER); // inherent impl items str += "\n Inherent impl items: "; @@ -629,9 +612,7 @@ InherentImpl::as_string () const else { for (const auto &item : impl_items) - { - str += "\n " + item->as_string (); - } + str += "\n " + item->as_string (); } return str; @@ -663,7 +644,7 @@ Method::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in method."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -725,7 +706,7 @@ StructStruct::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in enum."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -734,13 +715,9 @@ StructStruct::as_string () const str += "\n Where clause: "; if (has_where_clause ()) - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); else - { - str += "none"; - } + str += "none"; // struct fields str += "\n Struct fields: "; @@ -755,9 +732,7 @@ StructStruct::as_string () const else { for (const auto &field : fields) - { - str += "\n " + field.as_string (); - } + str += "\n " + field.as_string (); } return str; @@ -775,7 +750,7 @@ UseDeclaration::as_string () const stderr, "something really terrible has gone wrong - null pointer use tree in " "use declaration."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "use " + use_tree->as_string (); @@ -835,7 +810,7 @@ UseTreeList::as_string () const fprintf (stderr, "something really terrible has gone wrong - null pointer " "tree in use tree list."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } for (; i != e; i++) @@ -900,7 +875,7 @@ Enum::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in enum."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -909,13 +884,9 @@ Enum::as_string () const str += "\n Where clause: "; if (has_where_clause ()) - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); else - { - str += "none"; - } + str += "none"; // items str += "\n Items: "; @@ -934,7 +905,7 @@ Enum::as_string () const stderr, "something really terrible has gone wrong - null pointer " "enum item in enum."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + item->as_string (); @@ -950,9 +921,7 @@ Trait::as_string () const std::string str = VisItem::as_string (); if (has_unsafe) - { - str += "unsafe "; - } + str += "unsafe "; str += "trait " + name; @@ -973,7 +942,7 @@ Trait::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in trait."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -996,7 +965,7 @@ Trait::as_string () const stderr, "something really terrible has gone wrong - null pointer " "type param bound in trait."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + bound->as_string (); @@ -1005,13 +974,9 @@ Trait::as_string () const str += "\n Where clause: "; if (!has_where_clause ()) - { - str += "none"; - } + str += "none"; else - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); str += "\n Trait items: "; if (!has_trait_items ()) @@ -1029,7 +994,7 @@ Trait::as_string () const stderr, "something really terrible has gone wrong - null pointer " "trait item in trait."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + item->as_string (); @@ -1063,7 +1028,7 @@ Union::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in union."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -1072,13 +1037,9 @@ Union::as_string () const str += "\n Where clause: "; if (has_where_clause ()) - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); else - { - str += "none"; - } + str += "none"; // struct fields str += "\n Struct fields (variants): "; @@ -1089,9 +1050,7 @@ Union::as_string () const else { for (const auto &field : variants) - { - str += "\n " + field.as_string (); - } + str += "\n " + field.as_string (); } return str; @@ -1114,7 +1073,7 @@ Function::as_string () const stderr, "something really terrible has gone wrong - null pointer return " "type in function."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += return_type->as_string () + " "; @@ -1139,7 +1098,7 @@ Function::as_string () const fprintf (stderr, "something really terrible has gone wrong - null pointer " "generic param in function item."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } for (; i != e; i++) @@ -1181,7 +1140,7 @@ Function::as_string () const stderr, "something really terrible has gone wrong - null pointer function " "body in function."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += function_body->as_string () + "\n"; @@ -1212,22 +1171,12 @@ BlockExpr::as_string () const { std::string istr = indent_spaces (enter); std::string str = istr + "BlockExpr:\n" + istr; + // get outer attributes - str += "{\n" + indent_spaces (stay) + Expr::as_string (); + str += append_attributes (outer_attrs, OUTER); // inner attributes - str += "\n" + indent_spaces (stay) + "inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - str += "\n" + indent_spaces (stay) + attr.as_string (); - } + str += append_attributes (inner_attrs, INNER); // statements str += "\n" + indent_spaces (stay) + "statements: "; @@ -1246,7 +1195,7 @@ BlockExpr::as_string () const stderr, "something really terrible has gone wrong - null pointer " "stmt in block expr."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n" + indent_spaces (stay) + stmt->as_string (); @@ -1260,7 +1209,7 @@ BlockExpr::as_string () const else str += "\n" + expr->as_string (); - str += "\n" + indent_spaces (out) + "}"; + str += "\n" + indent_spaces (out); return str; } @@ -1303,18 +1252,7 @@ TraitImpl::as_string () const str += where_clause.as_string (); // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); - } + str += append_attributes (inner_attrs, INNER); str += "\n trait impl items: "; if (!has_impl_items ()) @@ -1358,13 +1296,9 @@ TypeAlias::as_string () const str += "\n Where clause: "; if (!has_where_clause ()) - { - str += "none"; - } + str += "none"; else - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); str += "\n Type: " + existing_type->as_string (); @@ -1374,46 +1308,11 @@ TypeAlias::as_string () const std::string MacroInvocationSemi::as_string () const { - std::string str; - - // get outer attrs - if (!outer_attrs.empty ()) - { - for (const auto &attr : outer_attrs) - str += attr.as_string () + "\n"; - } - - str += "\n" + path.as_string () + "!"; + std::string str = "MacroInvocationSemi: "; - std::string tok_trees; - if (token_trees.empty ()) - { - tok_trees = "none"; - } - else - { - auto i = token_trees.begin (); - auto e = token_trees.end (); + str += append_attributes (outer_attrs, OUTER); - // DEBUG: null pointer check - if (i == e) - { - fprintf (stderr, - "something really terrible has gone wrong - null pointer " - "token tree in macro invocation semi."); - return "nullptr_POINTER_MARK"; - } - - std::string s; - for (; i != e; i++) - { - s += (*i)->as_string (); - if (e != i + 1) - s += ", "; - } - - tok_trees += get_string_in_delims (s, delim_type); - } + str += "\n" + invoc_data.as_string (); return str; } @@ -1425,23 +1324,9 @@ ExternBlock::as_string () const str += "extern "; if (has_abi ()) - { - str += "\"" + abi + "\" "; - } + str += "\"" + abi + "\" "; - // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); - } + str += append_attributes (inner_attrs, INNER); str += "\n external items: "; if (!has_extern_items ()) @@ -1477,11 +1362,7 @@ MacroRulesDefinition::as_string () const std::string str; // get outer attrs - if (!outer_attrs.empty ()) - { - for (const auto &attr : outer_attrs) - str += attr.as_string () + "\n"; - } + str += append_attributes (outer_attrs, OUTER); str += "macro_rules!"; @@ -1520,8 +1401,19 @@ MacroRulesDefinition::as_string () const std::string MacroInvocation::as_string () const { - return "MacroInvocation: " + path.as_string () + "!" - + token_tree.as_string (); + std::string str = "MacroInvocation: "; + + str += append_attributes (outer_attrs, OUTER); + + str += "\n " + invoc_data.as_string (); + + return str; +} + +std::string +MacroInvocData::as_string () const +{ + return path.as_string () + "!" + token_tree.as_string (); } std::string @@ -1569,7 +1461,11 @@ ClosureParam::as_string () const std::string ClosureExpr::as_string () const { - std::string str ("ClosureExpr:\n Has move: "); + std::string str = "ClosureExpr:"; + + str += append_attributes (outer_attrs, OUTER); + + str += "\n Has move: "; if (has_move) str += "true"; else @@ -1636,6 +1532,9 @@ QualifiedPathInExpression::as_string () const std::string BorrowExpr::as_string () const { + /* TODO: find way to incorporate outer attrs - may have to represent in + * different style (i.e. something more like BorrowExpr: \n outer attrs) */ + std::string str ("&"); if (double_borrow) @@ -1652,6 +1551,9 @@ BorrowExpr::as_string () const std::string ReturnExpr::as_string () const { + /* TODO: find way to incorporate outer attrs - may have to represent in + * different style (i.e. something more like BorrowExpr: \n outer attrs) */ + std::string str ("return "); if (has_returned_expr ()) @@ -1665,19 +1567,11 @@ GroupedExpr::as_string () const { std::string str ("Grouped expr:"); + // outer attrs + str += append_attributes (outer_attrs, OUTER); + // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); - } + str += append_attributes (inner_attrs, INNER); str += "\n Expr in parens: " + expr_in_parens->as_string (); @@ -1693,6 +1587,7 @@ RangeToExpr::as_string () const std::string ContinueExpr::as_string () const { + // TODO: rewrite format to allow outer attributes std::string str ("continue "); if (has_label ()) @@ -1704,6 +1599,7 @@ ContinueExpr::as_string () const std::string NegationExpr::as_string () const { + // TODO: rewrite formula to allow outer attributes std::string str; switch (negation_type) @@ -1738,6 +1634,7 @@ RangeFullExpr::as_string () const std::string ArrayIndexExpr::as_string () const { + // TODO: rewrite formula to allow outer attributes return array_expr->as_string () + "[" + index_expr->as_string () + "]"; } @@ -1768,7 +1665,8 @@ AsyncBlockExpr::as_string () const std::string str = "AsyncBlockExpr: "; // get outer attributes - str += "\n " + Expr::as_string (); + // str += "\n " + Expr::as_string (); + str += append_attributes (outer_attrs, OUTER); str += "\n Has move: "; str += has_move ? "true" : "false"; @@ -1779,6 +1677,7 @@ AsyncBlockExpr::as_string () const std::string ComparisonExpr::as_string () const { + // TODO: rewrite to better reflect non-literal expressions std::string str (main_or_left_expr->as_string ()); switch (expr_type) @@ -1813,12 +1712,14 @@ ComparisonExpr::as_string () const std::string MethodCallExpr::as_string () const { - std::string str ("MethodCallExpr: \n Object (receiver) expr: "); + std::string str = "MethodCallExpr: "; + str += append_attributes (outer_attrs, OUTER); + + str += "\n Object (receiver) expr: \n"; str += receiver->as_string (); str += "\n Method path segment: \n"; - str += method_name.as_string (); str += "\n Call params:"; @@ -1843,24 +1744,28 @@ MethodCallExpr::as_string () const std::string TupleIndexExpr::as_string () const { + // TODO: rewrite dump to better reflect non-literal exprs return tuple_expr->as_string () + "." + std::to_string (tuple_index); } std::string DereferenceExpr::as_string () const { + // TODO: rewrite dump to better reflect non-literal exprs return "*" + main_or_left_expr->as_string (); } std::string FieldAccessExpr::as_string () const { + // TODO: rewrite dump to better reflect non-literal exprs return receiver->as_string () + "." + field; } std::string LazyBooleanExpr::as_string () const { + // TODO: rewrite dump to better reflect non-literal exprs std::string str (main_or_left_expr->as_string ()); switch (expr_type) @@ -1883,26 +1788,28 @@ LazyBooleanExpr::as_string () const std::string RangeFromToExpr::as_string () const { + // TODO: rewrite dump to better reflect non-literal exprs return from->as_string () + ".." + to->as_string (); } std::string RangeToInclExpr::as_string () const { + // TODO: rewrite dump to better reflect non-literal exprs return "..=" + to->as_string (); } std::string UnsafeBlockExpr::as_string () const { - std::string istr = indent_spaces (enter); - std::string str = istr + "UnsafeBlockExpr:"; - str += istr + "{"; + std::string str = "UnsafeBlockExpr:" + indent_spaces (enter); // get outer attributes - str += "\n" + indent_spaces (stay) + Expr::as_string (); + str += append_attributes (outer_attrs, OUTER); - return str + "\n" + indent_spaces (out) + "}\n" + expr->as_string (); + str += indent_spaces (stay) + expr->as_string () + "\n" + indent_spaces (out); + + return str; } std::string @@ -1918,7 +1825,9 @@ ClosureExprInner::as_string () const std::string IfExpr::as_string () const { - std::string str ("IfExpr: "); + std::string str = "IfExpr: "; + + str += append_attributes (outer_attrs, OUTER); str += "\n Condition expr: " + condition->as_string (); @@ -1960,7 +1869,9 @@ IfExprConseqIfLet::as_string () const std::string IfLetExpr::as_string () const { - std::string str ("IfLetExpr: "); + std::string str = "IfLetExpr: "; + + str += append_attributes (outer_attrs, OUTER); str += "\n Condition match arm patterns: "; if (match_arm_patterns.empty ()) @@ -2013,12 +1924,14 @@ IfLetExprConseqIfLet::as_string () const std::string RangeFromToInclExpr::as_string () const { + // TODO: rewrite to allow dumps with non-literal exprs return from->as_string () + "..=" + to->as_string (); } std::string ErrorPropagationExpr::as_string () const { + // TODO: rewrite to allow dumps with non-literal exprs return main_or_left_expr->as_string () + "?"; } @@ -2145,8 +2058,11 @@ ArithmeticOrLogicalExpr::as_string () const std::string CallExpr::as_string () const { - std::string str ("CallExpr: \n Function expr: "); + std::string str = "CallExpr: "; + + str += append_attributes (outer_attrs, OUTER); + str += "\n Function expr: "; str += function->as_string (); str += "\n Call params:"; @@ -2171,7 +2087,9 @@ CallExpr::as_string () const std::string WhileLoopExpr::as_string () const { - std::string str ("WhileLoopExpr: "); + std::string str = "WhileLoopExpr: "; + + str += append_attributes (outer_attrs, OUTER); str += "\n Label: "; if (!has_loop_label ()) @@ -2189,7 +2107,9 @@ WhileLoopExpr::as_string () const std::string WhileLetLoopExpr::as_string () const { - std::string str ("WhileLetLoopExpr: "); + std::string str = "WhileLetLoopExpr: "; + + str += append_attributes (outer_attrs, OUTER); str += "\n Label: "; if (!has_loop_label ()) @@ -2218,7 +2138,9 @@ WhileLetLoopExpr::as_string () const std::string LoopExpr::as_string () const { - std::string str ("LoopExpr: (infinite loop)"); + std::string str = "LoopExpr: (infinite loop)"; + + str += append_attributes (outer_attrs, OUTER); str += "\n Label: "; if (!has_loop_label ()) @@ -2234,21 +2156,12 @@ LoopExpr::as_string () const std::string ArrayExpr::as_string () const { - std::string str ("ArrayExpr:"); + std::string str = "ArrayExpr:"; + + str += append_attributes (outer_attrs, OUTER); // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); - } + str += append_attributes (inner_attrs, INNER); str += "\n Array elems: "; if (!has_array_elems ()) @@ -2262,12 +2175,14 @@ ArrayExpr::as_string () const std::string AwaitExpr::as_string () const { + // TODO: rewrite dump to allow non-literal exprs return awaited_expr->as_string () + ".await"; } std::string BreakExpr::as_string () const { + // TODO: rewrite dump to allow outer attrs, non-literal exprs std::string str ("break "); if (has_label ()) @@ -2289,18 +2204,7 @@ std::string MatchArm::as_string () const { // outer attributes - std::string str = "Outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); - } + std::string str = append_attributes (outer_attrs, OUTER); str += "\nPatterns: "; if (match_arm_patterns.empty ()) @@ -2333,48 +2237,17 @@ MatchCase::as_string () const return str; } -/*std::string -MatchCaseBlockExpr::as_string () const -{ - std::string str = MatchCase::as_string (); - - str += "\n Block expr: " + block_expr->as_string (); - - return str; -} - -std::string -MatchCaseExpr::as_string () const -{ - std::string str = MatchCase::as_string (); - - str += "\n Expr: " + expr->as_string (); - - return str; -}*/ - std::string MatchExpr::as_string () const { std::string str ("MatchExpr:"); + str += append_attributes (outer_attrs, OUTER); + str += "\n Scrutinee expr: " + branch_value->as_string (); // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - { - str += "\n " + attr.as_string (); - } - } + str += append_attributes (inner_attrs, INNER); // match arms str += "\n Match arms: "; @@ -2396,21 +2269,10 @@ TupleExpr::as_string () const { std::string str ("TupleExpr:"); + str += append_attributes (outer_attrs, OUTER); + // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - { - str += "\n " + attr.as_string (); - } - } + str += append_attributes (inner_attrs, INNER); str += "\n Tuple elements: "; if (tuple_elems.empty ()) @@ -2420,9 +2282,7 @@ TupleExpr::as_string () const else { for (const auto &elem : tuple_elems) - { - str += "\n " + elem->as_string (); - } + str += "\n " + elem->as_string (); } return str; @@ -2436,13 +2296,9 @@ ExprStmtWithoutBlock::as_string () const str += indent_spaces (stay); if (expr == nullptr) - { - str += "none (this shouldn't happen and is probably an error)"; - } + str += "none (this shouldn't happen and is probably an error)"; else - { - str += expr->as_string (); - } + str += expr->as_string (); indent_spaces (out); return str; @@ -2451,6 +2307,7 @@ ExprStmtWithoutBlock::as_string () const std::string FunctionParam::as_string () const { + // TODO: rewrite dump to allow non-literal types return param_name->as_string () + " : " + type->as_string (); } @@ -2475,17 +2332,13 @@ FunctionQualifiers::as_string () const } if (has_unsafe) - { - str += "unsafe "; - } + str += "unsafe "; if (has_extern) { str += "extern"; if (extern_abi != "") - { - str += " \"" + extern_abi + "\""; - } + str += " \"" + extern_abi + "\""; } return str; @@ -2498,13 +2351,9 @@ TraitBound::as_string () const str += "\n Has opening question mark: "; if (opening_question_mark) - { - str += "true"; - } + str += "true"; else - { - str += "false"; - } + str += "false"; str += "\n For lifetimes: "; if (!has_for_lifetimes ()) @@ -2514,9 +2363,7 @@ TraitBound::as_string () const else { for (const auto &lifetime : for_lifetimes) - { - str += "\n " + lifetime.as_string (); - } + str += "\n " + lifetime.as_string (); } str += "\n Type path: " + type_path.as_string (); @@ -2555,9 +2402,7 @@ MacroMatcher::as_string () const else { for (const auto &match : matches) - { - str += "\n " + match->as_string (); - } + str += "\n " + match->as_string (); } return str; @@ -2570,13 +2415,9 @@ LifetimeParam::as_string () const str += "\n Outer attribute: "; if (!has_outer_attribute ()) - { - str += "none"; - } + str += "none"; else - { - str += outer_attr.as_string (); - } + str += outer_attr.as_string (); str += "\n Lifetime: " + lifetime.as_string (); @@ -2588,9 +2429,7 @@ LifetimeParam::as_string () const else { for (const auto &bound : lifetime_bounds) - { - str += "\n " + bound.as_string (); - } + str += "\n " + bound.as_string (); } return str; @@ -2605,12 +2444,12 @@ MacroMatchFragment::as_string () const std::string QualifiedPathInType::as_string () const { + /* TODO: this may need adjusting if segments (e.g. with functions) can't be + * literalised */ std::string str = path_type.as_string (); for (const auto &segment : segments) - { - str += "::" + segment->as_string (); - } + str += "::" + segment->as_string (); return str; } @@ -2628,20 +2467,14 @@ MacroMatchRepetition::as_string () const else { for (const auto &match : matches) - { - str += "\n " + match->as_string (); - } + str += "\n " + match->as_string (); } str += "\n Sep: "; if (!has_sep ()) - { - str += "none"; - } + str += "none"; else - { - str += sep->as_string (); - } + str += sep->as_string (); str += "\n Op: "; switch (op) @@ -2669,9 +2502,7 @@ std::string Lifetime::as_string () const { if (is_error ()) - { - return "error lifetime"; - } + return "error lifetime"; switch (lifetime_type) { @@ -2689,17 +2520,15 @@ Lifetime::as_string () const std::string TypePath::as_string () const { + /* TODO: this may need to be rewritten if a segment (e.g. function) can't be + * literalised */ std::string str; if (has_opening_scope_resolution) - { - str = "::"; - } + str = "::"; for (const auto &segment : segments) - { - str += segment->as_string () + "::"; - } + str += segment->as_string () + "::"; // kinda hack - remove last 2 '::' characters str.erase (str.length () - 2); @@ -2714,13 +2543,9 @@ TypeParam::as_string () const str += "\n Outer attribute: "; if (!has_outer_attribute ()) - { - str += "none"; - } + str += "none"; else - { - str += outer_attr.as_string (); - } + str += outer_attr.as_string (); str += "\n Identifier: " + type_representation; @@ -2732,20 +2557,14 @@ TypeParam::as_string () const else { for (const auto &bound : type_param_bounds) - { - str += "\n " + bound->as_string (); - } + str += "\n " + bound->as_string (); } str += "\n Type: "; if (!has_type ()) - { - str += "none"; - } + str += "none"; else - { - str += type->as_string (); - } + str += type->as_string (); return str; } @@ -2754,9 +2573,7 @@ SimplePath PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const { if (!has_segments ()) - { - return SimplePath::create_empty (); - } + return SimplePath::create_empty (); // create vector of reserved size (to minimise reallocations) std::vector<SimplePathSegment> simple_segments; @@ -2767,9 +2584,7 @@ PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const // return empty path if doesn't meet simple path segment requirements if (segment.is_error () || segment.has_generic_args () || segment.as_string () == "Self") - { - return SimplePath::create_empty (); - } + return SimplePath::create_empty (); // create segment and add to vector std::string segment_str = segment.as_string (); @@ -2780,13 +2595,10 @@ PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const // kind of a HACK to get locus depending on opening scope resolution Location locus = Linemap::unknown_location (); if (with_opening_scope_resolution) - { - locus = simple_segments[0].get_locus () - 2; // minus 2 chars for :: - } + locus = simple_segments[0].get_locus () - 2; // minus 2 chars for :: else - { - locus = simple_segments[0].get_locus (); - } + locus = simple_segments[0].get_locus (); + // FIXME: this hack probably doesn't actually work return SimplePath (std::move (simple_segments), with_opening_scope_resolution, locus); @@ -2796,9 +2608,7 @@ SimplePath TypePath::as_simple_path () const { if (segments.empty ()) - { - return SimplePath::create_empty (); - } + return SimplePath::create_empty (); // create vector of reserved size (to minimise reallocations) std::vector<SimplePathSegment> simple_segments; @@ -2809,9 +2619,7 @@ TypePath::as_simple_path () const // return empty path if doesn't meet simple path segment requirements if (segment == nullptr || segment->is_error () || !segment->is_ident_only () || segment->as_string () == "Self") - { - return SimplePath::create_empty (); - } + return SimplePath::create_empty (); // create segment and add to vector std::string segment_str = segment->as_string (); @@ -2826,11 +2634,10 @@ TypePath::as_simple_path () const std::string PathExprSegment::as_string () const { + // TODO: rewrite dump to work with non-literalisable types std::string ident_str = segment_name.as_string (); if (has_generic_args ()) - { - ident_str += "::<" + generic_args.as_string () + ">"; - } + ident_str += "::<" + generic_args.as_string () + ">"; return ident_str; } @@ -2888,23 +2695,22 @@ GenericArgs::as_string () const std::string GenericArgsBinding::as_string () const { + // TODO: rewrite to work with non-literalisable types return identifier + " = " + type->as_string (); } std::string ForLoopExpr::as_string () const { - std::string str ("ForLoopExpr: "); + std::string str = "ForLoopExpr: "; + + str += append_attributes (outer_attrs, OUTER); str += "\n Label: "; if (!has_loop_label ()) - { - str += "none"; - } + str += "none"; else - { - str += loop_label.as_string (); - } + str += loop_label.as_string (); str += "\n Pattern: " + pattern->as_string (); @@ -2918,14 +2724,11 @@ ForLoopExpr::as_string () const std::string RangePattern::as_string () const { + // TODO: maybe rewrite to work with non-linearisable bounds if (has_ellipsis_syntax) - { - return lower->as_string () + "..." + upper->as_string (); - } + return lower->as_string () + "..." + upper->as_string (); else - { - return lower->as_string () + "..=" + upper->as_string (); - } + return lower->as_string () + "..=" + upper->as_string (); } std::string @@ -2934,9 +2737,7 @@ RangePatternBoundLiteral::as_string () const std::string str; if (has_minus) - { - str += "-"; - } + str += "-"; str += literal.as_string (); @@ -2949,9 +2750,7 @@ SlicePattern::as_string () const std::string str ("SlicePattern: "); for (const auto &pattern : items) - { - str += "\n " + pattern->as_string (); - } + str += "\n " + pattern->as_string (); return str; } @@ -2962,9 +2761,7 @@ TuplePatternItemsMultiple::as_string () const std::string str; for (const auto &pattern : patterns) - { - str += "\n " + pattern->as_string (); - } + str += "\n " + pattern->as_string (); return str; } @@ -2982,9 +2779,7 @@ TuplePatternItemsRanged::as_string () const else { for (const auto &lower : lower_patterns) - { - str += "\n " + lower->as_string (); - } + str += "\n " + lower->as_string (); } str += "\n Upper patterns: "; @@ -2995,9 +2790,7 @@ TuplePatternItemsRanged::as_string () const else { for (const auto &upper : upper_patterns) - { - str += "\n " + upper->as_string (); - } + str += "\n " + upper->as_string (); } return str; @@ -3013,20 +2806,7 @@ std::string StructPatternField::as_string () const { // outer attributes - std::string str ("Outer attributes: "); - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + std::string str = append_attributes (outer_attrs, OUTER); return str; } @@ -3039,14 +2819,10 @@ StructPatternFieldIdent::as_string () const str += "\n"; if (has_ref) - { - str += "ref "; - } + str += "ref "; if (has_mut) - { - str += "mut "; - } + str += "mut "; str += ident; @@ -3056,6 +2832,7 @@ StructPatternFieldIdent::as_string () const std::string StructPatternFieldTuplePat::as_string () const { + // TODO: maybe rewrite to work with non-linearisable patterns std::string str = StructPatternField::as_string (); str += "\n"; @@ -3068,6 +2845,7 @@ StructPatternFieldTuplePat::as_string () const std::string StructPatternFieldIdentPat::as_string () const { + // TODO: maybe rewrite to work with non-linearisable patterns std::string str = StructPatternField::as_string (); str += "\n"; @@ -3089,20 +2867,14 @@ StructPatternElements::as_string () const else { for (const auto &field : fields) - { - str += "\n " + field->as_string (); - } + str += "\n " + field->as_string (); } str += "\n Etc: "; if (has_struct_pattern_etc) - { - str += "true"; - } + str += "true"; else - { - str += "false"; - } + str += "false"; return str; } @@ -3116,13 +2888,9 @@ StructPattern::as_string () const str += "\n Struct pattern elems: "; if (!has_struct_pattern_elems ()) - { - str += "none"; - } + str += "none"; else - { - str += elems.as_string (); - } + str += elems.as_string (); return str; } @@ -3133,9 +2901,7 @@ LiteralPattern::as_string () const std::string str; if (has_minus) - { - str += "-"; - } + str += "-"; return str + lit.as_string (); } @@ -3143,17 +2909,14 @@ LiteralPattern::as_string () const std::string ReferencePattern::as_string () const { + // TODO: maybe rewrite to work with non-linearisable patterns std::string str ("&"); if (has_two_amps) - { - str += "&"; - } + str += "&"; if (is_mut) - { - str += "mut "; - } + str += "mut "; str += pattern->as_string (); @@ -3163,24 +2926,19 @@ ReferencePattern::as_string () const std::string IdentifierPattern::as_string () const { + // TODO: maybe rewrite to work with non-linearisable patterns std::string str; if (is_ref) - { - str += "ref "; - } + str += "ref "; if (is_mut) - { - str += "mut "; - } + str += "mut "; str += variable_ident; if (has_pattern_to_bind ()) - { - str += " @ " + to_bind->as_string (); - } + str += " @ " + to_bind->as_string (); return str; } @@ -3191,9 +2949,7 @@ TupleStructItemsNoRange::as_string () const std::string str; for (const auto &pattern : patterns) - { - str += "\n " + pattern->as_string (); - } + str += "\n " + pattern->as_string (); return str; } @@ -3210,9 +2966,7 @@ TupleStructItemsRange::as_string () const else { for (const auto &lower : lower_patterns) - { - str += "\n " + lower->as_string (); - } + str += "\n " + lower->as_string (); } str += "\n Upper patterns: "; @@ -3223,9 +2977,7 @@ TupleStructItemsRange::as_string () const else { for (const auto &upper : upper_patterns) - { - str += "\n " + upper->as_string (); - } + str += "\n " + upper->as_string (); } return str; @@ -3246,58 +2998,16 @@ TupleStructPattern::as_string () const std::string LetStmt::as_string () const { - // outer attributes - std::string str = "Outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - indent_spaces (enter); - for (const auto &attr : outer_attrs) - { - str += "\n" + indent_spaces (stay) + attr.as_string (); - } - indent_spaces (out); - } + // TODO: rewrite to work with non-linearisable types and exprs + std::string str = append_attributes (outer_attrs, OUTER); str += "\n" + indent_spaces (stay) + "let " + variables_pattern->as_string (); if (has_type ()) - { - str += " : " + type->as_string (); - } + str += " : " + type->as_string (); if (has_init_expr ()) - { - str += " = " + init_expr->as_string (); - } - - return str; -} - -// Used to get outer attributes for expressions. -std::string -Expr::as_string () const -{ - // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + str += " = " + init_expr->as_string (); return str; } @@ -3306,10 +3016,7 @@ Expr::as_string () const TraitBound * TypePath::to_trait_bound (bool in_parens) const { - // create clone FIXME is this required? or is copy constructor automatically - // called? - TypePath copy (*this); - return new TraitBound (std::move (copy), copy.get_locus (), in_parens); + return new TraitBound (TypePath (*this), get_locus (), in_parens); } std::string @@ -3321,6 +3028,7 @@ InferredType::as_string () const std::string TypeCastExpr::as_string () const { + // TODO: rewrite to work with non-linearisable exprs and types return main_or_left_expr->as_string () + " as " + type_to_convert_to->as_string (); } @@ -3337,9 +3045,7 @@ ImplTraitType::as_string () const else { for (const auto &bound : type_param_bounds) - { - str += "\n " + bound->as_string (); - } + str += "\n " + bound->as_string (); } return str; @@ -3348,17 +3054,14 @@ ImplTraitType::as_string () const std::string ReferenceType::as_string () const { + // TODO: rewrite to work with non-linearisable types std::string str ("&"); if (has_lifetime ()) - { - str += lifetime.as_string () + " "; - } + str += lifetime.as_string () + " "; if (has_mut) - { - str += "mut "; - } + str += "mut "; str += type->as_string (); @@ -3368,6 +3071,7 @@ ReferenceType::as_string () const std::string RawPointerType::as_string () const { + // TODO: rewrite to work with non-linearisable types std::string str ("*"); switch (pointer_type) @@ -3393,13 +3097,9 @@ TraitObjectType::as_string () const std::string str ("TraitObjectType: \n Has dyn dispatch: "); if (has_dyn) - { - str += "true"; - } + str += "true"; else - { - str += "false"; - } + str += "false"; str += "\n TypeParamBounds: "; if (type_param_bounds.empty ()) @@ -3409,9 +3109,7 @@ TraitObjectType::as_string () const else { for (const auto &bound : type_param_bounds) - { - str += "\n " + bound->as_string (); - } + str += "\n " + bound->as_string (); } return str; @@ -3429,9 +3127,7 @@ BareFunctionType::as_string () const else { for (const auto &for_lifetime : for_lifetimes) - { - str += "\n " + for_lifetime.as_string (); - } + str += "\n " + for_lifetime.as_string (); } str += "\n Qualifiers: " + function_qualifiers.as_string (); @@ -3444,30 +3140,20 @@ BareFunctionType::as_string () const else { for (const auto ¶m : params) - { - str += "\n " + param.as_string (); - } + str += "\n " + param.as_string (); } str += "\n Is variadic: "; if (is_variadic) - { - str += "true"; - } + str += "true"; else - { - str += "false"; - } + str += "false"; str += "\n Return type: "; if (!has_return_type ()) - { - str += "none (void)"; - } + str += "none (void)"; else - { - str += return_type->as_string (); - } + str += return_type->as_string (); return str; } @@ -3483,6 +3169,7 @@ ImplTraitTypeOneBound::as_string () const std::string TypePathSegmentGeneric::as_string () const { + // TODO: rewrite to work with non-linearisable types return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">"; } @@ -3492,13 +3179,9 @@ TraitObjectTypeOneBound::as_string () const std::string str ("TraitObjectTypeOneBound: \n Has dyn dispatch: "); if (has_dyn) - { - str += "true"; - } + str += "true"; else - { - str += "false"; - } + str += "false"; str += "\n TraitBound: " + trait_bound.as_string (); @@ -3508,6 +3191,7 @@ TraitObjectTypeOneBound::as_string () const std::string TypePathFunction::as_string () const { + // TODO: rewrite to work with non-linearisable types std::string str ("("); if (has_inputs ()) @@ -3526,9 +3210,7 @@ TypePathFunction::as_string () const str += ")"; if (has_return_type ()) - { - str += " -> " + return_type->as_string (); - } + str += " -> " + return_type->as_string (); return str; } @@ -3536,24 +3218,28 @@ TypePathFunction::as_string () const std::string TypePathSegmentFunction::as_string () const { + // TODO: rewrite to work with non-linearisable types return TypePathSegment::as_string () + function_path.as_string (); } std::string ArrayType::as_string () const { + // TODO: rewrite to work with non-linearisable types and exprs return "[" + elem_type->as_string () + "; " + size->as_string () + "]"; } std::string SliceType::as_string () const { + // TODO: rewrite to work with non-linearisable types return "[" + elem_type->as_string () + "]"; } std::string TupleType::as_string () const { + // TODO: rewrite to work with non-linearisable types std::string str ("("); if (!is_unit_type ()) @@ -3577,7 +3263,7 @@ TupleType::as_string () const std::string StructExpr::as_string () const { - std::string str = ExprWithoutBlock::as_string (); + std::string str = append_attributes (outer_attrs, OUTER); indent_spaces (enter); str += "\n" + indent_spaces (stay) + "StructExpr:"; indent_spaces (enter); @@ -3604,9 +3290,7 @@ StructExprTuple::as_string () const // debug - null pointer check if (*i == nullptr) - { - return "ERROR_MARK_STRING - nullptr struct expr tuple field"; - } + return "ERROR_MARK_STRING - nullptr struct expr tuple field"; str += '('; for (; i != e; i++) @@ -3621,18 +3305,7 @@ StructExprTuple::as_string () const indent_spaces (enter); indent_spaces (enter); // inner attributes - str += "\n" + indent_spaces (stay) + "inner attributes:"; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - str += "\n" + indent_spaces (stay) + attr.as_string (); - } + str += append_attributes (inner_attrs, INNER); indent_spaces (out); indent_spaces (out); @@ -3642,23 +3315,13 @@ StructExprTuple::as_string () const std::string StructExprStruct::as_string () const { + // TODO: doesn't this require data from StructExpr? std::string str ("StructExprStruct (or subclass): "); str += "\n Path: " + get_struct_name ().as_string (); // inner attributes - str += "\n inner attributes: "; - if (inner_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "inner attribute" syntax - - * just the body */ - for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); - } + str += append_attributes (inner_attrs, INNER); return str; } @@ -3682,12 +3345,14 @@ StructExprFieldWithVal::as_string () const std::string StructExprFieldIdentifierValue::as_string () const { + // TODO: rewrite to work with non-linearisable exprs return field_name + " : " + StructExprFieldWithVal::as_string (); } std::string StructExprFieldIndexValue::as_string () const { + // TODO: rewrite to work with non-linearisable exprs return std::to_string (index) + " : " + StructExprFieldWithVal::as_string (); } @@ -3719,7 +3384,7 @@ StructExprStructFields::as_string () const std::string EnumExprStruct::as_string () const { - std::string str ("StructExprStruct (or subclass): "); + std::string str ("EnumExprStruct (or subclass): "); str += "\n Path: " + get_enum_variant_path ().as_string (); @@ -3747,12 +3412,14 @@ EnumExprFieldWithVal::as_string () const std::string EnumExprFieldIdentifierValue::as_string () const { + // TODO: rewrite to work with non-linearisable exprs return field_name + " : " + EnumExprFieldWithVal::as_string (); } std::string EnumExprFieldIndexValue::as_string () const { + // TODO: rewrite to work with non-linearisable exprs return std::to_string (index) + " : " + EnumExprFieldWithVal::as_string (); } @@ -3760,18 +3427,7 @@ std::string EnumItem::as_string () const { // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); - } + std::string str = append_attributes (outer_attrs, OUTER); str += "\n" + variant_name; @@ -3809,26 +3465,13 @@ EnumItemTuple::as_string () const std::string TupleField::as_string () const { + // TODO: rewrite to work with non-linearisable exprs + // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + std::string str = append_attributes (outer_attrs, OUTER); if (has_visibility ()) - { - str += "\n" + visibility.as_string (); - } + str += "\n" + visibility.as_string (); str += " " + field_type->as_string (); @@ -3866,26 +3509,12 @@ EnumItemStruct::as_string () const std::string StructField::as_string () const { + // TODO: rewrite to work with non-linearisable exprs // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + std::string str = append_attributes (outer_attrs, OUTER); if (has_visibility ()) - { - str += "\n" + visibility.as_string (); - } + str += "\n" + visibility.as_string (); str += " " + field_name + " : " + field_type->as_string (); @@ -3895,6 +3524,7 @@ StructField::as_string () const std::string EnumItemDiscriminant::as_string () const { + // TODO: rewrite to work with non-linearisable exprs std::string str = EnumItem::as_string (); // add equal and expression @@ -3903,47 +3533,11 @@ EnumItemDiscriminant::as_string () const return str; } -#if 0 -std::string -ExternalItem::as_string () const -{ - // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); - } - - // start visibility on new line and with a space - str += "\n" + visibility.as_string () + " "; - - return str; -} -#endif - std::string ExternalStaticItem::as_string () const { // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); - } + std::string str = append_attributes (outer_attrs, OUTER); // start visibility on new line and with a space str += "\n" + visibility.as_string () + " "; @@ -3966,18 +3560,7 @@ std::string ExternalFunctionItem::as_string () const { // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); - } + std::string str = append_attributes (outer_attrs, OUTER); // start visibility on new line and with a space str += "\n" + visibility.as_string () + " "; @@ -4004,7 +3587,7 @@ ExternalFunctionItem::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in external function item."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -4054,17 +3637,7 @@ ExternalFunctionItem::as_string () const std::string NamedFunctionParam::as_string () const { - std::string str = "outer attributes: "; - - if (!has_outer_attrs ()) - { - str += "none"; - } - else - { - for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); - } + std::string str = append_attributes (outer_attrs, OUTER); str += "\n" + name; @@ -4073,50 +3646,18 @@ NamedFunctionParam::as_string () const return str; } -/*std::string TraitItem::as_string() const { - // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty()) { - str += "none"; - } else { - // note that this does not print them with "outer attribute" syntax - -just the body for (const auto& attr : outer_attrs) { str += "\n " + -attr.as_string(); - } - } - - return str; -}*/ - std::string TraitItemFunc::as_string () const { - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + std::string str = append_attributes (outer_attrs, OUTER); str += "\n" + decl.as_string (); str += "\n Definition (block expr): "; if (has_definition ()) - { - str += block_expr->as_string (); - } + str += block_expr->as_string (); else - { - str += "none"; - } + str += "none"; return str; } @@ -4143,7 +3684,7 @@ TraitFunctionDecl::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in trait function decl."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -4154,9 +3695,7 @@ TraitFunctionDecl::as_string () const if (has_params ()) { for (const auto ¶m : function_params) - { - str += "\n " + param.as_string (); - } + str += "\n " + param.as_string (); } else { @@ -4165,23 +3704,15 @@ TraitFunctionDecl::as_string () const str += "\n Return type: "; if (has_return_type ()) - { - str += return_type->as_string (); - } + str += return_type->as_string (); else - { - str += "none (void)"; - } + str += "none (void)"; str += "\n Where clause: "; if (has_where_clause ()) - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); else - { - str += "none"; - } + str += "none"; return str; } @@ -4189,32 +3720,15 @@ TraitFunctionDecl::as_string () const std::string TraitItemMethod::as_string () const { - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + std::string str = append_attributes (outer_attrs, OUTER); str += "\n" + decl.as_string (); str += "\n Definition (block expr): "; if (has_definition ()) - { - str += block_expr->as_string (); - } + str += block_expr->as_string (); else - { - str += "none"; - } + str += "none"; return str; } @@ -4241,7 +3755,7 @@ TraitMethodDecl::as_string () const stderr, "something really terrible has gone wrong - null pointer " "generic param in trait function decl."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + param->as_string (); @@ -4254,9 +3768,7 @@ TraitMethodDecl::as_string () const if (has_params ()) { for (const auto ¶m : function_params) - { - str += "\n " + param.as_string (); - } + str += "\n " + param.as_string (); } else { @@ -4265,23 +3777,15 @@ TraitMethodDecl::as_string () const str += "\n Return type: "; if (has_return_type ()) - { - str += return_type->as_string (); - } + str += return_type->as_string (); else - { - str += "none (void)"; - } + str += "none (void)"; str += "\n Where clause: "; if (has_where_clause ()) - { - str += where_clause.as_string (); - } + str += where_clause.as_string (); else - { - str += "none"; - } + str += "none"; return str; } @@ -4289,27 +3793,13 @@ TraitMethodDecl::as_string () const std::string TraitItemConst::as_string () const { - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + // TODO: rewrite to work with non-linearisable exprs + std::string str = append_attributes (outer_attrs, OUTER); str += "\nconst " + name + " : " + type->as_string (); if (has_expression ()) - { - str += " = " + expr->as_string (); - } + str += " = " + expr->as_string (); return str; } @@ -4317,20 +3807,7 @@ TraitItemConst::as_string () const std::string TraitItemType::as_string () const { - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } + std::string str = append_attributes (outer_attrs, OUTER); str += "\ntype " + name; @@ -4350,7 +3827,7 @@ TraitItemType::as_string () const stderr, "something really terrible has gone wrong - null pointer " "type param bound in trait item type."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + bound->as_string (); @@ -4363,6 +3840,7 @@ TraitItemType::as_string () const std::string SelfParam::as_string () const { + // TODO: rewrite to allow non-linearisable types if (is_error ()) { return "error"; @@ -4375,9 +3853,7 @@ SelfParam::as_string () const std::string str; if (is_mut) - { - str += "mut "; - } + str += "mut "; str += "self : "; @@ -4391,9 +3867,7 @@ SelfParam::as_string () const std::string str = "&" + lifetime.as_string () + " "; if (is_mut) - { - str += "mut "; - } + str += "mut "; str += "self"; @@ -4405,9 +3879,7 @@ SelfParam::as_string () const std::string str = "&"; if (is_mut) - { - str += " mut "; - } + str += " mut "; str += "self"; @@ -4419,9 +3891,7 @@ SelfParam::as_string () const std::string str; if (is_mut) - { - str += "mut "; - } + str += "mut "; str += "self"; @@ -4433,6 +3903,7 @@ SelfParam::as_string () const std::string ArrayElemsCopied::as_string () const { + // TODO: rewrite to allow non-linearisable exprs return elem_to_copy->as_string () + "; " + num_copies->as_string (); } @@ -4446,9 +3917,7 @@ LifetimeWhereClauseItem::as_string () const str += "\nLifetime bounds: "; for (const auto &bound : lifetime_bounds) - { - str += "\n " + bound.as_string (); - } + str += "\n " + bound.as_string (); return str; } @@ -4465,9 +3934,7 @@ TypeBoundWhereClauseItem::as_string () const else { for (const auto &for_lifetime : for_lifetimes) - { - str += "\n " + for_lifetime.as_string (); - } + str += "\n " + for_lifetime.as_string (); } str += "\nType: " + bound_type->as_string (); @@ -4478,9 +3945,7 @@ TypeBoundWhereClauseItem::as_string () const { // debug null pointer check if (bound == nullptr) - { - return "nullptr_POINTER_MARK - type param bounds"; - } + return "NULL_POINTER_MARK - type param bounds"; str += "\n " + bound->as_string (); } @@ -4501,7 +3966,7 @@ ArrayElemsValues::as_string () const fprintf (stderr, "something really terrible has gone wrong - null pointer " "expr in array elems values."); - return "nullptr_POINTER_MARK"; + return "NULL_POINTER_MARK"; } str += "\n " + expr->as_string (); @@ -4513,6 +3978,7 @@ ArrayElemsValues::as_string () const std::string MaybeNamedParam::as_string () const { + // TODO: rewrite to allow using non-linearisable types in dump std::string str; switch (param_kind) @@ -4621,8 +4087,8 @@ ModuleBodied::add_crate_name (std::vector<std::string> &names) const void Attribute::parse_attr_to_meta_item () { - // only parse if has attribute input - if (!has_attr_input ()) + // only parse if has attribute input and not already parsed + if (!has_attr_input () || is_parsed_to_meta_item ()) return; std::unique_ptr<AttrInput> converted_input ( @@ -4632,7 +4098,7 @@ Attribute::parse_attr_to_meta_item () attr_input = std::move (converted_input); } -AttrInput * +AttrInputMetaItemContainer * DelimTokenTree::parse_to_meta_item () const { // must have token trees @@ -4709,8 +4175,11 @@ MacroParser::parse_meta_item_inner () skip_token (2); + // remove the quotes from the string value + std::string raw_value = unquote_string (std::move (value)); + return std::unique_ptr<MetaNameValueStr> ( - new MetaNameValueStr (std::move (ident), std::move (value))); + new MetaNameValueStr (std::move (ident), std::move (raw_value))); } else { @@ -4831,7 +4300,7 @@ MacroParser::parse_path_meta_item () "failed to parse literal in attribute"); return nullptr; } - LiteralExpr expr (std::move (lit), locus); + LiteralExpr expr (std::move (lit), {}, locus); // stream_pos++; /* shouldn't be required anymore due to parsing literal actually * skipping the token */ @@ -4886,9 +4355,8 @@ MacroParser::parse_meta_item_seq () meta_items.push_back (std::move (inner)); if (peek_token ()->get_id () != COMMA) - { - break; - } + break; + skip_token (); } @@ -4911,9 +4379,10 @@ DelimTokenTree::to_token_stream () const std::vector<std::unique_ptr<Token> > tokens; // simulate presence of delimiters + const_TokenPtr left_paren + = Rust::Token::make (LEFT_PAREN, Linemap::unknown_location ()); tokens.push_back ( - std::unique_ptr<Token> (new Token (LEFT_PAREN, Linemap::unknown_location (), - "", CORETYPE_UNKNOWN))); + std::unique_ptr<Token> (new Token (std::move (left_paren)))); for (const auto &tree : token_trees) { @@ -4923,9 +4392,10 @@ DelimTokenTree::to_token_stream () const std::make_move_iterator (stream.end ())); } - tokens.push_back (std::unique_ptr<Token> ( - new Token (RIGHT_PAREN, Linemap::unknown_location (), "", - CORETYPE_UNKNOWN))); + const_TokenPtr right_paren + = Rust::Token::make (RIGHT_PAREN, Linemap::unknown_location ()); + tokens.push_back ( + std::unique_ptr<Token> (new Token (std::move (right_paren)))); tokens.shrink_to_fit (); @@ -5049,7 +4519,7 @@ std::unique_ptr<MetaItemLitExpr> MacroParser::parse_meta_item_lit () { Location locus = peek_token ()->get_locus (); - LiteralExpr lit_expr (parse_literal (), locus); + LiteralExpr lit_expr (parse_literal (), {}, locus); return std::unique_ptr<MetaItemLitExpr> ( new MetaItemLitExpr (std::move (lit_expr))); } @@ -5063,6 +4533,12 @@ AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const if (items.empty ()) return false; + // DEBUG + fprintf (stderr, + "asked to check cfg of attrinputmetaitemcontainer - delegating to " + "first item. container: '%s'\n", + as_string ().c_str ()); + return items[0]->check_cfg_predicate (session); /*for (const auto &inner_item : items) @@ -5075,8 +4551,7 @@ AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const } bool -MetaItemLitExpr::check_cfg_predicate ( - const Session &session ATTRIBUTE_UNUSED) const +MetaItemLitExpr::check_cfg_predicate (const Session &) const { /* as far as I can tell, a literal expr can never be a valid cfg body, so * false */ @@ -5183,10 +4658,7 @@ bool MetaListPaths::check_path_exists_in_cfg (const Session &session, const SimplePath &path) const { - auto it = session.options.target_data.features.find (path.as_string ()); - if (it != session.options.target_data.features.end ()) - return true; - return false; + return session.options.target_data.has_key (path.as_string ()); } bool @@ -5240,10 +4712,7 @@ MetaItemSeq::check_cfg_predicate (const Session &session) const bool MetaWord::check_cfg_predicate (const Session &session) const { - auto it = session.options.target_data.features.find (ident); - if (it != session.options.target_data.features.end ()) - return true; - return false; + return session.options.target_data.has_key (ident); } bool @@ -5253,15 +4722,20 @@ MetaItemPath::check_cfg_predicate (const Session &session) const * relating to SimplePath being identifier. Currently, it would return true * if path as identifier existed, and if the path in string form existed * (though this shouldn't occur). */ - auto it = session.options.target_data.features.find (path.as_string ()); - if (it != session.options.target_data.features.end ()) - return true; - return false; + return session.options.target_data.has_key (path.as_string ()); } bool MetaNameValueStr::check_cfg_predicate (const Session &session) const { + // DEBUG + fprintf (stderr, + "checked key-value pair for cfg: '%s', '%s' - is%s in target data\n", + ident.c_str (), str.c_str (), + session.options.target_data.has_key_value_pair (ident, str) + ? "" + : " not"); + return session.options.target_data.has_key_value_pair (ident, str); } @@ -5287,7 +4761,7 @@ Attribute MetaNameValueStr::to_attribute () const { LiteralExpr lit_expr (str, Literal::LitType::STRING, - PrimitiveCoreType::CORETYPE_UNKNOWN, Location ()); + PrimitiveCoreType::CORETYPE_UNKNOWN, {}, Location ()); return Attribute (SimplePath::from_str (ident), std::unique_ptr<AttrInputLiteral> ( new AttrInputLiteral (std::move (lit_expr)))); @@ -5375,8 +4849,8 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const Attribute attr = (*it)->to_attribute (); if (attr.is_empty ()) { - // TODO should this be an error that causes us to chuck out - // everything? + /* TODO should this be an error that causes us to chuck out + * everything? */ continue; } attrs.push_back (std::move (attr)); @@ -5387,34 +4861,48 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const } bool -Attribute::check_cfg_predicate (const Session &session) +Attribute::check_cfg_predicate (const Session &session) const { /* assume that cfg predicate actually can exist, i.e. attribute has cfg or * cfg_attr path */ if (!has_attr_input () || (path.as_string () != "cfg" && path.as_string () != "cfg_attr")) - return false; + { + // DEBUG message + fprintf (stderr, + "tried to check cfg predicate on attr that either has no input " + "or invalid path. attr: '%s'\n", + as_string ().c_str ()); - // TODO: maybe replace with storing a "has been parsed" variable? - parse_attr_to_meta_item (); - // can't be const because of this anyway + return false; + } + + // assume that it has already been parsed + if (!is_parsed_to_meta_item ()) + return false; return attr_input->check_cfg_predicate (session); } std::vector<Attribute> -Attribute::separate_cfg_attrs () +Attribute::separate_cfg_attrs () const { if (!has_attr_input () || path.as_string () != "cfg_attr") return {}; - // TODO: maybe replace with storing a "has been parsed" variable? - parse_attr_to_meta_item (); - // can't be const because of this anyway + // assume that it has already been parsed + if (!is_parsed_to_meta_item ()) + return {}; return attr_input->separate_cfg_attrs (); } +bool +Attribute::is_parsed_to_meta_item () const +{ + return has_attr_input () && attr_input->is_meta_item (); +} + /* Visitor implementations - these are short but inlining can't happen anyway * due to virtual functions and I didn't want to make the ast header includes * any longer than they already are. */ @@ -5875,18 +5363,6 @@ IfLetExprConseqIfLet::accept_vis (ASTVisitor &vis) vis.visit (*this); } -/*void -MatchCaseBlockExpr::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -MatchCaseExpr::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -}*/ - void MatchExpr::accept_vis (ASTVisitor &vis) { diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index b61c8c3..b34525e 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -129,6 +129,7 @@ class Token : public TokenTree, public MacroMatch { // A token is a kind of token tree (except delimiter tokens) // A token is a kind of MacroMatch (except $ and delimiter tokens) +#if 0 // TODO: improve member variables - current ones are the same as lexer token // Token kind. TokenId token_id; @@ -138,6 +139,13 @@ class Token : public TokenTree, public MacroMatch std::string str; // Token type hint (if any). PrimitiveCoreType type_hint; +#endif + + const_TokenPtr tok_ref; + + /* new idea: wrapper around const_TokenPtr used for heterogeneuous storage in + * token trees. rather than convert back and forth when parsing macros, just + * wrap it. */ public: // Unique pointer custom clone function @@ -146,6 +154,7 @@ public: return std::unique_ptr<Token> (clone_token_impl ()); } +#if 0 /* constructor from general text - avoid using if lexer const_TokenPtr is * available */ Token (TokenId token_id, Location locus, std::string str, @@ -153,8 +162,11 @@ public: : token_id (token_id), locus (locus), str (std::move (str)), type_hint (type_hint) {} +#endif + // not doable with new implementation - will have to make a const_TokenPtr // Constructor from lexer const_TokenPtr +#if 0 /* TODO: find workaround for std::string being nullptr - probably have to * introduce new method in lexer Token, or maybe make conversion method * there */ @@ -188,10 +200,12 @@ public: lexer_token_ptr->get_token_description ()); } } +#endif + Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {} bool is_string_lit () const { - switch (token_id) + switch (get_id ()) { case STRING_LITERAL: case BYTE_STRING_LITERAL: @@ -208,11 +222,14 @@ public: // Return copy of itself but in token stream form. std::vector<std::unique_ptr<Token> > to_token_stream () const override; - TokenId get_id () const { return token_id; } + TokenId get_id () const { return tok_ref->get_id (); } - Location get_locus () const { return locus; } + Location get_locus () const { return tok_ref->get_locus (); } - PrimitiveCoreType get_type_hint () const { return type_hint; } + PrimitiveCoreType get_type_hint () const { return tok_ref->get_type_hint (); } + + // Get a new token pointer copy. + const_TokenPtr get_tok_ptr () const { return tok_ref; } protected: // No virtual for now as not polymorphic but can be in future @@ -220,11 +237,14 @@ protected: /* Use covariance to implement clone function as returning this object rather * than base */ - Token *clone_token_tree_impl () const override { return clone_token_impl (); } + Token *clone_token_tree_impl () const final override + { + return clone_token_impl (); + } /* Use covariance to implement clone function as returning this object rather * than base */ - Token *clone_macro_match_impl () const override + Token *clone_macro_match_impl () const final override { return clone_token_impl (); } @@ -372,6 +392,13 @@ public: } }; +// path-to-string inverse comparison operator +inline bool +operator!= (const SimplePath &lhs, const std::string &rhs) +{ + return !(lhs == rhs); +} + // forward decl for Attribute class AttrInput; @@ -402,27 +429,9 @@ public: // default destructor ~Attribute () = default; - // Copy constructor must deep copy attr_input as unique pointer - /*Attribute (Attribute const &other) : path (other.path), locus (other.locus) - { - // guard to protect from null pointer dereference - if (other.attr_input != nullptr) - attr_input = other.attr_input->clone_attr_input (); - }*/ // no point in being defined inline as requires virtual call anyway Attribute (const Attribute &other); - // overload assignment operator to use custom clone method - /*Attribute &operator= (Attribute const &other) - { - path = other.path; - locus = other.locus; - // guard to protect from null pointer dereference - if (other.attr_input != nullptr) - attr_input = other.attr_input->clone_attr_input (); - - return *this; - }*/ // no point in being defined inline as requires virtual call anyway Attribute &operator= (const Attribute &other); @@ -499,7 +508,7 @@ public: std::string as_string () const; - // TODO: does this require visitor pattern as not polymorphic? + // no visitor pattern as not currently polymorphic const SimplePath &get_path () const { return path; } SimplePath &get_path () { return path; } @@ -508,10 +517,15 @@ public: void parse_attr_to_meta_item (); /* Determines whether cfg predicate is true and item with attribute should not - * be stripped. */ - bool check_cfg_predicate (const Session &session); + * be stripped. Attribute body must already be parsed to meta item. */ + bool check_cfg_predicate (const Session &session) const; - std::vector<Attribute> separate_cfg_attrs (); + // Returns whether body has been parsed to meta item form or not. + bool is_parsed_to_meta_item () const; + + /* Returns any attributes generated from cfg_attr attributes. Attribute body + * must already be parsed to meta item. */ + std::vector<Attribute> separate_cfg_attrs () const; protected: // not virtual as currently no subclasses of Attribute, but could be in future @@ -544,99 +558,14 @@ public: virtual std::vector<Attribute> separate_cfg_attrs () const { return {}; } + // Returns whether attr input has been parsed to meta item syntax. + virtual bool is_meta_item () const = 0; + protected: // pure virtual clone implementation virtual AttrInput *clone_attr_input_impl () const = 0; }; -// A token tree with delimiters -class DelimTokenTree : public TokenTree, public AttrInput -{ - DelimType delim_type; - std::vector<std::unique_ptr<TokenTree> > token_trees; - Location locus; - -protected: - DelimTokenTree *clone_delim_tok_tree_impl () const - { - return new DelimTokenTree (*this); - } - - /* Use covariance to implement clone function as returning a DelimTokenTree - * object */ - DelimTokenTree *clone_attr_input_impl () const override - { - return clone_delim_tok_tree_impl (); - } - - /* Use covariance to implement clone function as returning a DelimTokenTree - * object */ - DelimTokenTree *clone_token_tree_impl () const override - { - return clone_delim_tok_tree_impl (); - } - -public: - DelimTokenTree (DelimType delim_type, - std::vector<std::unique_ptr<TokenTree> > token_trees - = std::vector<std::unique_ptr<TokenTree> > (), - Location locus = Location ()) - : delim_type (delim_type), token_trees (std::move (token_trees)), - locus (locus) - {} - - // Copy constructor with vector clone - DelimTokenTree (DelimTokenTree const &other) - : delim_type (other.delim_type), locus (other.locus) - { - token_trees.reserve (other.token_trees.size ()); - for (const auto &e : other.token_trees) - token_trees.push_back (e->clone_token_tree ()); - } - - // overloaded assignment operator with vector clone - DelimTokenTree &operator= (DelimTokenTree const &other) - { - delim_type = other.delim_type; - locus = other.locus; - - token_trees.reserve (other.token_trees.size ()); - for (const auto &e : other.token_trees) - token_trees.push_back (e->clone_token_tree ()); - - return *this; - } - - // move constructors - DelimTokenTree (DelimTokenTree &&other) = default; - DelimTokenTree &operator= (DelimTokenTree &&other) = default; - - static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); } - - std::string as_string () const override; - - void accept_vis (ASTVisitor &vis) override; - - bool check_cfg_predicate (const Session &) const override - { - // this should never be called - should be converted first - return false; - } - - AttrInput *parse_to_meta_item () const override; - - std::vector<std::unique_ptr<Token> > to_token_stream () const override; - - std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const - { - return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ()); - } -}; - -/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to - * be defined */ -class AttrInputLiteral; - // Forward decl - defined in rust-macro.h class MetaNameValueStr; @@ -689,7 +618,26 @@ public: : items (std::move (items)) {} - // no destructor definition required + // copy constructor with vector clone + AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other) + { + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_meta_item_inner ()); + } + + // copy assignment operator with vector clone + AttrInputMetaItemContainer & + operator= (const AttrInputMetaItemContainer &other) + { + AttrInput::operator= (other); + + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_meta_item_inner ()); + + return *this; + } // default move constructors AttrInputMetaItemContainer (AttrInputMetaItemContainer &&other) = default; @@ -712,9 +660,18 @@ public: std::vector<Attribute> separate_cfg_attrs () const override; + bool is_meta_item () const override { return true; } + + // TODO: this mutable getter seems dodgy + std::vector<std::unique_ptr<MetaItemInner> > &get_items () { return items; } + const std::vector<std::unique_ptr<MetaItemInner> > &get_items () const + { + return items; + } + protected: // Use covariance to implement clone function as returning this type - AttrInputMetaItemContainer *clone_attr_input_impl () const override + AttrInputMetaItemContainer *clone_attr_input_impl () const final override { return clone_attr_input_meta_item_container_impl (); } @@ -723,29 +680,99 @@ protected: { return new AttrInputMetaItemContainer (*this); } +}; - // copy constructor with vector clone - AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other) +// A token tree with delimiters +class DelimTokenTree : public TokenTree, public AttrInput +{ + DelimType delim_type; + std::vector<std::unique_ptr<TokenTree> > token_trees; + Location locus; + +protected: + DelimTokenTree *clone_delim_tok_tree_impl () const { - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_meta_item_inner ()); + return new DelimTokenTree (*this); } - // copy assignment operator with vector clone - AttrInputMetaItemContainer & - operator= (const AttrInputMetaItemContainer &other) + /* Use covariance to implement clone function as returning a DelimTokenTree + * object */ + DelimTokenTree *clone_attr_input_impl () const final override { - AttrInput::operator= (other); + return clone_delim_tok_tree_impl (); + } - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_meta_item_inner ()); + /* Use covariance to implement clone function as returning a DelimTokenTree + * object */ + DelimTokenTree *clone_token_tree_impl () const final override + { + return clone_delim_tok_tree_impl (); + } + +public: + DelimTokenTree (DelimType delim_type, + std::vector<std::unique_ptr<TokenTree> > token_trees + = std::vector<std::unique_ptr<TokenTree> > (), + Location locus = Location ()) + : delim_type (delim_type), token_trees (std::move (token_trees)), + locus (locus) + {} + + // Copy constructor with vector clone + DelimTokenTree (DelimTokenTree const &other) + : delim_type (other.delim_type), locus (other.locus) + { + token_trees.reserve (other.token_trees.size ()); + for (const auto &e : other.token_trees) + token_trees.push_back (e->clone_token_tree ()); + } + + // overloaded assignment operator with vector clone + DelimTokenTree &operator= (DelimTokenTree const &other) + { + delim_type = other.delim_type; + locus = other.locus; + + token_trees.reserve (other.token_trees.size ()); + for (const auto &e : other.token_trees) + token_trees.push_back (e->clone_token_tree ()); return *this; } + + // move constructors + DelimTokenTree (DelimTokenTree &&other) = default; + DelimTokenTree &operator= (DelimTokenTree &&other) = default; + + static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); } + + std::string as_string () const override; + + void accept_vis (ASTVisitor &vis) override; + + bool check_cfg_predicate (const Session &) const override + { + // this should never be called - should be converted first + rust_assert (false); + return false; + } + + AttrInputMetaItemContainer *parse_to_meta_item () const override; + + std::vector<std::unique_ptr<Token> > to_token_stream () const override; + + std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const + { + return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ()); + } + + bool is_meta_item () const override { return false; } }; +/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to + * be defined */ +class AttrInputLiteral; + // abstract base meta item class class MetaItem : public MetaItemInner { @@ -816,8 +843,6 @@ public: return std::unique_ptr<Item> (clone_item_impl ()); } - std::string as_string () const = 0; - /* Adds crate names to the vector passed by reference, if it can * (polymorphism). TODO: remove, unused. */ virtual void @@ -840,14 +865,7 @@ class ExprWithoutBlock; // Base expression AST node - abstract class Expr { - // TODO: move outer attribute data to derived classes? - std::vector<Attribute> outer_attrs; - public: - // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - // Unique pointer custom clone function std::unique_ptr<Expr> clone_expr () const { @@ -863,8 +881,7 @@ public: * overrided in subclasses of ExprWithoutBlock */ virtual ExprWithoutBlock *as_expr_without_block () const { return nullptr; } - // TODO: make pure virtual if move out outer attributes to derived classes - virtual std::string as_string () const; + virtual std::string as_string () const = 0; virtual ~Expr () {} @@ -886,20 +903,14 @@ public: protected: // Constructor - Expr (std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) - : outer_attrs (std::move (outer_attribs)), - node_id (Analysis::Mappings::get ()->get_next_node_id ()) - {} + Expr () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {} // Clone function implementation as pure virtual method virtual Expr *clone_expr_impl () const = 0; // TODO: think of less hacky way to implement this kind of thing // Sets outer attributes. - void set_outer_attrs (std::vector<Attribute> outer_attrs_to_set) - { - outer_attrs = std::move (outer_attrs_to_set); - } + virtual void set_outer_attrs (std::vector<Attribute>) = 0; NodeId node_id; }; @@ -908,12 +919,6 @@ protected: class ExprWithoutBlock : public Expr { protected: - // Constructor - ExprWithoutBlock (std::vector<Attribute> outer_attribs - = std::vector<Attribute> ()) - : Expr (std::move (outer_attribs)) - {} - // pure virtual clone implementation virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0; @@ -936,7 +941,7 @@ public: /* downcasting hack from expr to use pratt parsing with * parse_expr_without_block */ - ExprWithoutBlock *as_expr_without_block () const override + ExprWithoutBlock *as_expr_without_block () const final override { return clone_expr_without_block_impl (); } @@ -948,21 +953,21 @@ public: */ class IdentifierExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; Identifier ident; Location locus; public: - IdentifierExpr (Identifier ident, Location locus = Location (), - std::vector<Attribute> outer_attrs - = std::vector<Attribute> ()) - : ExprWithoutBlock (std::move (outer_attrs)), ident (std::move (ident)), + IdentifierExpr (Identifier ident, std::vector<Attribute> outer_attrs, + Location locus) + : outer_attrs (std::move (outer_attrs)), ident (std::move (ident)), locus (locus) {} std::string as_string () const override { return ident; } Location get_locus () const { return locus; } - Location get_locus_slow () const override { return locus; } + Location get_locus_slow () const final override { return get_locus (); } Identifier get_ident () const { return ident; } @@ -978,9 +983,17 @@ public: void mark_for_strip () override { ident = {}; } bool is_marked_for_strip () const override { return ident.empty (); } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override + { + outer_attrs = std::move (new_attrs); + } + protected: // Clone method implementation - IdentifierExpr *clone_expr_without_block_impl () const override + IdentifierExpr *clone_expr_without_block_impl () const final override { return clone_identifier_expr_impl (); } @@ -1205,15 +1218,8 @@ protected: class LifetimeParam : public GenericParam { Lifetime lifetime; - - // bool has_lifetime_bounds; - // LifetimeBounds lifetime_bounds; - std::vector<Lifetime> lifetime_bounds; // inlined LifetimeBounds - - // bool has_outer_attribute; - // std::unique_ptr<Attribute> outer_attr; + std::vector<Lifetime> lifetime_bounds; Attribute outer_attr; - Location locus; public: @@ -1226,45 +1232,21 @@ public: // Creates an error state lifetime param. static LifetimeParam create_error () { - return LifetimeParam (Lifetime::error ()); + return LifetimeParam (Lifetime::error (), {}, Attribute::create_empty (), Location ()); } // Returns whether the lifetime param is in an error state. bool is_error () const { return lifetime.is_error (); } // Constructor - LifetimeParam (Lifetime lifetime, Location locus = Location (), - std::vector<Lifetime> lifetime_bounds - = std::vector<Lifetime> (), - Attribute outer_attr = Attribute::create_empty ()) + LifetimeParam (Lifetime lifetime, + std::vector<Lifetime> lifetime_bounds, + Attribute outer_attr, Location locus) : lifetime (std::move (lifetime)), lifetime_bounds (std::move (lifetime_bounds)), outer_attr (std::move (outer_attr)), locus (locus) {} - // TODO: remove copy and assignment operator definitions - not required - - // Copy constructor with clone - LifetimeParam (LifetimeParam const &other) - : lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds), - outer_attr (other.outer_attr), locus (other.locus) - {} - - // Overloaded assignment operator to clone attribute - LifetimeParam &operator= (LifetimeParam const &other) - { - lifetime = other.lifetime; - lifetime_bounds = other.lifetime_bounds; - outer_attr = other.outer_attr; - locus = other.locus; - - return *this; - } - - // move constructors - LifetimeParam (LifetimeParam &&other) = default; - LifetimeParam &operator= (LifetimeParam &&other) = default; - std::string as_string () const override; void accept_vis (ASTVisitor &vis) override; @@ -1278,28 +1260,13 @@ protected: } }; -// A macro item AST node - potentially abstract base class +// A macro item AST node - abstract base class class MacroItem : public Item -{ - /*public: - std::string as_string() const;*/ - // std::vector<Attribute> outer_attrs; - -protected: - /*MacroItem (std::vector<Attribute> outer_attribs) - : outer_attrs (std::move (outer_attribs)) - {}*/ -}; +{}; // Item used in trait declarations - abstract base class class TraitItem { - // bool has_outer_attrs; - // TODO: remove and rely on virtual functions and VisItem-derived attributes? - // std::vector<Attribute> outer_attrs; - - // NOTE: all children should have outer attributes - protected: // Clone function implementation as pure virtual method virtual TraitItem *clone_trait_item_impl () const = 0; @@ -1395,65 +1362,105 @@ protected: virtual ExternalItem *clone_external_item_impl () const = 0; }; -/* A macro invocation item (or statement) AST node (i.e. semi-coloned macro - * invocation) */ -class MacroInvocationSemi : public MacroItem, - public TraitItem, - public InherentImplItem, - public TraitImplItem, - public ExternalItem +/* Data structure to store the data used in macro invocations and macro + * invocations with semicolons. */ +struct MacroInvocData { - std::vector<Attribute> outer_attrs; +private: SimplePath path; - // all delim types except curly must have invocation end with a semicolon - DelimType delim_type; - std::vector<std::unique_ptr<TokenTree> > token_trees; - Location locus; + DelimTokenTree token_tree; + + // One way of parsing the macro. Probably not applicable for all macros. + std::vector<std::unique_ptr<MetaItemInner> > parsed_items; + bool parsed_to_meta_item = false; public: - std::string as_string () const override; + std::string as_string () const; - MacroInvocationSemi (SimplePath macro_path, DelimType delim_type, - std::vector<std::unique_ptr<TokenTree> > token_trees, - std::vector<Attribute> outer_attribs, Location locus) - : outer_attrs (std::move (outer_attribs)), path (std::move (macro_path)), - delim_type (delim_type), token_trees (std::move (token_trees)), - locus (locus) + MacroInvocData (SimplePath path, DelimTokenTree token_tree) + : path (std::move (path)), token_tree (std::move (token_tree)) {} // Copy constructor with vector clone - MacroInvocationSemi (MacroInvocationSemi const &other) - : MacroItem (other), TraitItem (other), InherentImplItem (other), - TraitImplItem (other), outer_attrs (other.outer_attrs), path (other.path), - delim_type (other.delim_type), locus (other.locus) + MacroInvocData (const MacroInvocData &other) + : path (other.path), token_tree (other.token_tree), + parsed_to_meta_item (other.parsed_to_meta_item) { - token_trees.reserve (other.token_trees.size ()); - for (const auto &e : other.token_trees) - token_trees.push_back (e->clone_token_tree ()); + parsed_items.reserve (other.parsed_items.size ()); + for (const auto &e : other.parsed_items) + parsed_items.push_back (e->clone_meta_item_inner ()); } - // Overloaded assignment operator to vector clone - MacroInvocationSemi &operator= (MacroInvocationSemi const &other) + // Copy assignment operator with vector clone + MacroInvocData &operator= (const MacroInvocData &other) { - MacroItem::operator= (other); - TraitItem::operator= (other); - InherentImplItem::operator= (other); - TraitImplItem::operator= (other); - outer_attrs = other.outer_attrs; path = other.path; - delim_type = other.delim_type; - locus = other.locus; + token_tree = other.token_tree; + parsed_to_meta_item = other.parsed_to_meta_item; - token_trees.reserve (other.token_trees.size ()); - for (const auto &e : other.token_trees) - token_trees.push_back (e->clone_token_tree ()); + parsed_items.reserve (other.parsed_items.size ()); + for (const auto &e : other.parsed_items) + parsed_items.push_back (e->clone_meta_item_inner ()); return *this; } // Move constructors - MacroInvocationSemi (MacroInvocationSemi &&other) = default; - MacroInvocationSemi &operator= (MacroInvocationSemi &&other) = default; + MacroInvocData (MacroInvocData &&other) = default; + MacroInvocData &operator= (MacroInvocData &&other) = default; + + // Invalid if path is empty, so base stripping on that. + void mark_for_strip () { path = SimplePath::create_empty (); } + bool is_marked_for_strip () const { return path.is_empty (); } + + // Returns whether the macro has been parsed already. + bool is_parsed () const { return parsed_to_meta_item; } + // TODO: update on other ways of parsing it + + // TODO: this mutable getter seems kinda dodgy + DelimTokenTree &get_delim_tok_tree () { return token_tree; } + const DelimTokenTree &get_delim_tok_tree () const { return token_tree; } + + // TODO: this mutable getter seems kinda dodgy + SimplePath &get_path () { return path; } + const SimplePath &get_path () const { return path; } + + void + set_meta_item_output (std::vector<std::unique_ptr<MetaItemInner> > new_items) + { + parsed_items = std::move (new_items); + } + // TODO: mutable getter seems kinda dodgy + std::vector<std::unique_ptr<MetaItemInner> > &get_meta_items () + { + return parsed_items; + } + const std::vector<std::unique_ptr<MetaItemInner> > &get_meta_items () const + { + return parsed_items; + } +}; + +/* A macro invocation item (or statement) AST node (i.e. semi-coloned macro + * invocation) */ +class MacroInvocationSemi : public MacroItem, + public TraitItem, + public InherentImplItem, + public TraitImplItem, + public ExternalItem +{ + std::vector<Attribute> outer_attrs; + MacroInvocData invoc_data; + Location locus; + +public: + std::string as_string () const override; + + MacroInvocationSemi (MacroInvocData invoc_data, + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), + invoc_data (std::move (invoc_data)), locus (locus) + {} void accept_vis (ASTVisitor &vis) override; @@ -1464,9 +1471,11 @@ public: clone_macro_invocation_semi_impl ()); } - // Invalid if path is empty, so base stripping on that. - void mark_for_strip () override { path = SimplePath::create_empty (); } - bool is_marked_for_strip () const override { return path.is_empty (); } + void mark_for_strip () override { invoc_data.mark_for_strip (); } + bool is_marked_for_strip () const override + { + return invoc_data.is_marked_for_strip (); + } // TODO: this mutable getter seems really dodgy. Think up better way. const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } @@ -1484,35 +1493,35 @@ protected: /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocationSemi *clone_item_impl () const override + MacroInvocationSemi *clone_item_impl () const final override { return clone_macro_invocation_semi_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocationSemi *clone_inherent_impl_item_impl () const override + MacroInvocationSemi *clone_inherent_impl_item_impl () const final override { return clone_macro_invocation_semi_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocationSemi *clone_trait_impl_item_impl () const override + MacroInvocationSemi *clone_trait_impl_item_impl () const final override { return clone_macro_invocation_semi_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocationSemi *clone_trait_item_impl () const override + MacroInvocationSemi *clone_trait_item_impl () const final override { return clone_macro_invocation_semi_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocationSemi *clone_external_item_impl () const override + MacroInvocationSemi *clone_external_item_impl () const final override { return clone_macro_invocation_semi_impl (); } @@ -1593,20 +1602,6 @@ public: // Base path expression AST node - abstract class PathExpr : public ExprWithoutBlock { -protected: - PathExpr (std::vector<Attribute> outer_attribs) - : ExprWithoutBlock (std::move (outer_attribs)) - {} - -public: - // TODO: think of a better and less hacky way to allow this - - /* Replaces the outer attributes of this path expression with the given outer - * attributes. */ - void replace_outer_attrs (std::vector<Attribute> outer_attrs) - { - set_outer_attrs (std::move (outer_attrs)); - } }; } // namespace AST } // namespace Rust diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 52e3abc..5366fac 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -13,12 +13,7 @@ namespace AST { // AST node for an expression with an accompanying block - abstract class ExprWithBlock : public Expr { - // TODO: should this mean that a BlockExpr should be a member variable? protected: - ExprWithBlock (std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) - : Expr (std::move (outer_attrs)) - {} - // pure virtual clone implementation virtual ExprWithBlock *clone_expr_with_block_impl () const = 0; @@ -41,6 +36,7 @@ public: // Literals? Or literal base? class LiteralExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; Literal literal; Location locus; @@ -50,15 +46,15 @@ public: Literal::LitType get_lit_type () const { return literal.get_lit_type (); } LiteralExpr (std::string value_as_string, Literal::LitType type, - PrimitiveCoreType type_hint, Location locus, - std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) - : ExprWithoutBlock (std::move (outer_attrs)), + PrimitiveCoreType type_hint, + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), literal (std::move (value_as_string), type, type_hint), locus (locus) {} - LiteralExpr (Literal literal, Location locus, - std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) - : ExprWithoutBlock (std::move (outer_attrs)), literal (std::move (literal)), + LiteralExpr (Literal literal, + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), literal (std::move (literal)), locus (locus) {} @@ -69,7 +65,7 @@ public: } Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } Literal get_literal () const { return literal; } @@ -79,10 +75,15 @@ public: void mark_for_strip () override { literal = Literal::create_error (); } bool is_marked_for_strip () const override { return literal.is_error (); } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ - LiteralExpr *clone_expr_without_block_impl () const override + LiteralExpr *clone_expr_without_block_impl () const final override { return clone_literal_expr_impl (); } @@ -121,6 +122,8 @@ public: * cfg */ bool check_cfg_predicate (const Session &) const override { return false; } + bool is_meta_item () const override { return false; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -194,20 +197,21 @@ public: Location locus; protected: - /* Variable must be protected to allow derived classes to use it as a first - * class citizen */ + /* Variables must be protected to allow derived classes to use them as first + * class citizens */ + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> main_or_left_expr; // Constructor (only for initialisation of expr purposes) OperatorExpr (std::unique_ptr<Expr> main_or_left_expr, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), locus (locus), + : locus (locus), outer_attrs (std::move (outer_attribs)), main_or_left_expr (std::move (main_or_left_expr)) {} // Copy constructor (only for initialisation of expr purposes) OperatorExpr (OperatorExpr const &other) - : ExprWithoutBlock (other), locus (other.locus) + : locus (other.locus), outer_attrs (other.outer_attrs) { // guard to prevent null dereference (only required if error state) if (other.main_or_left_expr != nullptr) @@ -219,7 +223,7 @@ protected: { ExprWithoutBlock::operator= (other); locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.main_or_left_expr != nullptr) @@ -236,7 +240,7 @@ protected: public: Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } // Invalid if expr is null, so base stripping on that. void mark_for_strip () override { main_or_left_expr = nullptr; } @@ -244,6 +248,11 @@ public: { return main_or_left_expr == nullptr; } + + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } }; /* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be @@ -857,9 +866,9 @@ protected: // Expression in parentheses (i.e. like literally just any 3 + (2 * 6)) class GroupedExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::vector<Attribute> inner_attrs; std::unique_ptr<Expr> expr_in_parens; - Location locus; public: @@ -868,17 +877,22 @@ public: const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + GroupedExpr (std::unique_ptr<Expr> parenthesised_expr, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), inner_attrs (std::move (inner_attribs)), expr_in_parens (std::move (parenthesised_expr)), locus (locus) {} // Copy constructor includes clone for expr_in_parens GroupedExpr (GroupedExpr const &other) - : ExprWithoutBlock (other), inner_attrs (other.inner_attrs), + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), inner_attrs (other.inner_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) @@ -892,7 +906,7 @@ public: ExprWithoutBlock::operator= (other); inner_attrs = other.inner_attrs; locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.expr_in_parens != nullptr) @@ -908,7 +922,7 @@ public: GroupedExpr &operator= (GroupedExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1089,9 +1103,9 @@ protected: // Array definition-ish expression class ArrayExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::vector<Attribute> inner_attrs; std::unique_ptr<ArrayElems> internal_elements; - Location locus; // TODO: find another way to store this to save memory? @@ -1103,6 +1117,11 @@ public: const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + // Returns whether array expr has array elems or if it is just empty. bool has_array_elems () const { return internal_elements != nullptr; } @@ -1110,14 +1129,14 @@ public: ArrayExpr (std::unique_ptr<ArrayElems> array_elems, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), inner_attrs (std::move (inner_attribs)), internal_elements (std::move (array_elems)), locus (locus) {} // Copy constructor requires cloning ArrayElems for polymorphism to hold ArrayExpr (ArrayExpr const &other) - : ExprWithoutBlock (other), inner_attrs (other.inner_attrs), + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), inner_attrs (other.inner_attrs), locus (other.locus), marked_for_strip (other.marked_for_strip) { if (other.has_array_elems ()) @@ -1131,7 +1150,7 @@ public: inner_attrs = other.inner_attrs; locus = other.locus; marked_for_strip = other.marked_for_strip; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; if (other.has_array_elems ()) internal_elements = other.internal_elements->clone_array_elems (); @@ -1146,7 +1165,7 @@ public: ArrayExpr &operator= (ArrayExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1177,9 +1196,9 @@ protected: * implementation */ class ArrayIndexExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> array_expr; std::unique_ptr<Expr> index_expr; - Location locus; public: @@ -1188,14 +1207,14 @@ public: ArrayIndexExpr (std::unique_ptr<Expr> array_expr, std::unique_ptr<Expr> array_index_expr, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), array_expr (std::move (array_expr)), index_expr (std::move (array_index_expr)), locus (locus) {} // Copy constructor requires special cloning due to unique_ptr ArrayIndexExpr (ArrayIndexExpr const &other) - : ExprWithoutBlock (other), locus (other.locus) + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.array_expr != nullptr) @@ -1208,7 +1227,7 @@ public: ArrayIndexExpr &operator= (ArrayIndexExpr const &other) { ExprWithoutBlock::operator= (other); - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; locus = other.locus; // guard to prevent null dereference (only required if error state) @@ -1229,7 +1248,7 @@ public: ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1258,6 +1277,11 @@ public: return index_expr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1270,11 +1294,9 @@ protected: // AST representation of a tuple class TupleExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::vector<Attribute> inner_attrs; - std::vector<std::unique_ptr<Expr> > tuple_elems; - // replaces (inlined version of) TupleElements - Location locus; // TODO: find another way to store this to save memory? @@ -1286,17 +1308,22 @@ public: const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + TupleExpr (std::vector<std::unique_ptr<Expr> > tuple_elements, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), inner_attrs (std::move (inner_attribs)), tuple_elems (std::move (tuple_elements)), locus (locus) {} // copy constructor with vector clone TupleExpr (TupleExpr const &other) - : ExprWithoutBlock (other), inner_attrs (other.inner_attrs), + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), inner_attrs (other.inner_attrs), locus (other.locus), marked_for_strip (other.marked_for_strip) { tuple_elems.reserve (other.tuple_elems.size ()); @@ -1308,6 +1335,7 @@ public: TupleExpr &operator= (TupleExpr const &other) { ExprWithoutBlock::operator= (other); + outer_attrs = other.outer_attrs; inner_attrs = other.inner_attrs; locus = other.locus; marked_for_strip = other.marked_for_strip; @@ -1327,7 +1355,7 @@ public: * comma, i.e. (0,) rather than (0) */ Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1360,6 +1388,7 @@ protected: // AST representation of a tuple indexing expression class TupleIndexExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> tuple_expr; // TupleIndex is a decimal int literal with no underscores or suffix TupleIndex tuple_index; @@ -1375,13 +1404,13 @@ public: TupleIndexExpr (std::unique_ptr<Expr> tuple_expr, TupleIndex index, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus) {} // Copy constructor requires a clone for tuple_expr TupleIndexExpr (TupleIndexExpr const &other) - : ExprWithoutBlock (other), tuple_index (other.tuple_index), + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), tuple_index (other.tuple_index), locus (other.locus) { // guard to prevent null dereference (only required if error state) @@ -1395,7 +1424,7 @@ public: ExprWithoutBlock::operator= (other); tuple_index = other.tuple_index; locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.tuple_expr != nullptr) @@ -1411,7 +1440,7 @@ public: TupleIndexExpr &operator= (TupleIndexExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1426,6 +1455,11 @@ public: return tuple_expr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1438,13 +1472,14 @@ protected: // Base struct/tuple/union value creator AST node (abstract) class StructExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; PathInExpression struct_name; protected: // Protected constructor to allow initialising struct_name StructExpr (PathInExpression struct_path, std::vector<Attribute> outer_attribs) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), struct_name (std::move (struct_path)) {} @@ -1460,6 +1495,11 @@ public: struct_name = PathInExpression::create_error (); } bool is_marked_for_strip () const override { return struct_name.is_error (); } + + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } }; // Actual AST node of the struct creator (with no fields). Not abstract! @@ -1484,7 +1524,7 @@ public: {} Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1885,7 +1925,7 @@ public: StructExprTuple &operator= (StructExprTuple &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1922,7 +1962,7 @@ public: {} Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1939,13 +1979,14 @@ protected: // Base AST node representing creation of an enum variant instance - abstract class EnumVariantExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; PathInExpression enum_variant_path; protected: // Protected constructor for initialising enum_variant_path EnumVariantExpr (PathInExpression path_to_enum_variant, std::vector<Attribute> outer_attribs) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), enum_variant_path (std::move (path_to_enum_variant)) {} @@ -1965,6 +2006,11 @@ public: { return enum_variant_path.is_error (); } + + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } }; /* Base AST node for a single enum expression field (in enum instance creation) @@ -2162,7 +2208,7 @@ public: EnumExprStruct &operator= (EnumExprStruct &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -2186,7 +2232,6 @@ protected: class EnumExprTuple : public EnumVariantExpr { std::vector<std::unique_ptr<Expr> > values; - Location locus; public: @@ -2227,7 +2272,7 @@ public: EnumExprTuple &operator= (EnumExprTuple &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -2266,7 +2311,7 @@ public: {} Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -2285,10 +2330,9 @@ class Function; // Function call expression AST node class CallExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> function; - // inlined form of CallParams std::vector<std::unique_ptr<Expr> > params; - Location locus; public: @@ -2299,14 +2343,14 @@ public: CallExpr (std::unique_ptr<Expr> function_expr, std::vector<std::unique_ptr<Expr> > function_params, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), function (std::move (function_expr)), params (std::move (function_params)), locus (locus) {} // copy constructor requires clone CallExpr (CallExpr const &other) - : ExprWithoutBlock (other), locus (other.locus) + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.function != nullptr) @@ -2322,7 +2366,7 @@ public: { ExprWithoutBlock::operator= (other); locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.function != nullptr) @@ -2345,7 +2389,7 @@ public: bool has_params () const { return !params.empty (); } Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -2376,6 +2420,11 @@ public: return function; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2388,11 +2437,10 @@ protected: // Method call expression AST node class MethodCallExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> receiver; PathExprSegment method_name; - // inlined form of CallParams std::vector<std::unique_ptr<Expr> > params; - Location locus; public: @@ -2402,7 +2450,7 @@ public: PathExprSegment method_path, std::vector<std::unique_ptr<Expr> > method_params, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), receiver (std::move (call_receiver)), method_name (std::move (method_path)), params (std::move (method_params)), locus (locus) @@ -2410,7 +2458,7 @@ public: // copy constructor required due to cloning MethodCallExpr (MethodCallExpr const &other) - : ExprWithoutBlock (other), method_name (other.method_name), + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), method_name (other.method_name), locus (other.locus) { // guard to prevent null dereference (only required if error state) @@ -2428,7 +2476,7 @@ public: ExprWithoutBlock::operator= (other); method_name = other.method_name; locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.receiver != nullptr) @@ -2448,7 +2496,7 @@ public: MethodCallExpr &operator= (MethodCallExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -2482,6 +2530,11 @@ public: const PathExprSegment &get_method_name () const { return method_name; } PathExprSegment &get_method_name () { return method_name; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2495,9 +2548,9 @@ protected: // Struct or union field access expression AST node class FieldAccessExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> receiver; Identifier field; - Location locus; public: @@ -2506,14 +2559,14 @@ public: FieldAccessExpr (std::unique_ptr<Expr> field_access_receiver, Identifier field_name, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), receiver (std::move (field_access_receiver)), field (std::move (field_name)), locus (locus) {} // Copy constructor required due to unique_ptr cloning FieldAccessExpr (FieldAccessExpr const &other) - : ExprWithoutBlock (other), field (other.field), locus (other.locus) + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), field (other.field), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.receiver != nullptr) @@ -2526,7 +2579,7 @@ public: ExprWithoutBlock::operator= (other); field = other.field; locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.receiver != nullptr) @@ -2542,7 +2595,7 @@ public: FieldAccessExpr &operator= (FieldAccessExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -2559,6 +2612,11 @@ public: Identifier get_field_name () const { return field; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2657,17 +2715,15 @@ public: // Base closure definition expression AST node - abstract class ClosureExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; bool has_move; std::vector<ClosureParam> params; // may be empty - /* also note a double pipe "||" can be used for empty params - does not need a - * space */ - Location locus; protected: ClosureExpr (std::vector<ClosureParam> closure_params, bool has_move, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithoutBlock (std::move (outer_attribs)), has_move (has_move), + : outer_attrs (std::move (outer_attribs)), has_move (has_move), params (std::move (closure_params)), locus (locus) {} @@ -2675,11 +2731,16 @@ public: std::string as_string () const override; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } // TODO: this mutable getter seems really dodgy. Think up better way. const std::vector<ClosureParam> &get_params () const { return params; } std::vector<ClosureParam> &get_params () { return params; } + + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } }; // Represents a non-type-specified closure expression AST node @@ -2758,13 +2819,10 @@ protected: // A block AST node class BlockExpr : public ExprWithBlock { + std::vector<Attribute> outer_attrs; std::vector<Attribute> inner_attrs; - - // bool has_statements; std::vector<std::unique_ptr<Stmt> > statements; - // bool has_expr; - std::unique_ptr<ExprWithoutBlock> expr; // inlined from Statements - + std::unique_ptr<ExprWithoutBlock> expr; Location locus; bool marked_for_strip = false; @@ -2781,7 +2839,7 @@ public: std::unique_ptr<ExprWithoutBlock> block_expr, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), inner_attrs (std::move (inner_attribs)), statements (std::move (block_statements)), expr (std::move (block_expr)), locus (locus) @@ -2789,7 +2847,7 @@ public: // Copy constructor with clone BlockExpr (BlockExpr const &other) - : ExprWithBlock (other), inner_attrs (other.inner_attrs), + : ExprWithBlock (other), outer_attrs (other.outer_attrs), inner_attrs (other.inner_attrs), locus (other.locus), marked_for_strip (other.marked_for_strip) { // guard to protect from null pointer dereference @@ -2808,7 +2866,7 @@ public: inner_attrs = other.inner_attrs; locus = other.locus; marked_for_strip = other.marked_for_strip; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to protect from null pointer dereference if (other.expr != nullptr) @@ -2873,10 +2931,15 @@ public: // Removes the tail expression from the block. void strip_tail_expr () { expr = nullptr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ - BlockExpr *clone_expr_with_block_impl () const override + BlockExpr *clone_expr_with_block_impl () const final override { return clone_block_expr_impl (); } @@ -2982,7 +3045,7 @@ protected: // AST node representing continue expression within loops class ContinueExpr : public ExprWithoutBlock { - // bool has_label; + std::vector<Attribute> outer_attrs; Lifetime label; Location locus; @@ -2996,15 +3059,14 @@ public: bool has_label () const { return !label.is_error (); } // Constructor for a ContinueExpr with a label. - ContinueExpr (Location locus, Lifetime label = Lifetime::error (), - std::vector<Attribute> outer_attribs - = std::vector<Attribute> ()) - : ExprWithoutBlock (std::move (outer_attribs)), label (std::move (label)), + ContinueExpr (Lifetime label, + std::vector<Attribute> outer_attribs, Location locus) + : outer_attrs (std::move (outer_attribs)), label (std::move (label)), locus (locus) {} Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -3012,6 +3074,11 @@ public: void mark_for_strip () override { marked_for_strip = true; } bool is_marked_for_strip () const override { return marked_for_strip; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3025,12 +3092,9 @@ protected: // AST node representing break expression within loops class BreakExpr : public ExprWithoutBlock { - // bool has_label; + std::vector<Attribute> outer_attrs; Lifetime label; - - // bool has_break_expr; std::unique_ptr<Expr> break_expr; - Location locus; // TODO: find another way to store this to save memory? @@ -3047,17 +3111,17 @@ public: bool has_break_expr () const { return break_expr != nullptr; } // Constructor for a break expression - BreakExpr (Location locus, Lifetime break_label = Lifetime::error (), - std::unique_ptr<Expr> expr_in_break = nullptr, - std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) - : ExprWithoutBlock (std::move (outer_attribs)), + BreakExpr (Lifetime break_label, + std::unique_ptr<Expr> expr_in_break, + std::vector<Attribute> outer_attribs, Location locus) + : outer_attrs (std::move (outer_attribs)), label (std::move (break_label)), break_expr (std::move (expr_in_break)), locus (locus) {} // Copy constructor defined to use clone for unique pointer BreakExpr (BreakExpr const &other) - : ExprWithoutBlock (other), label (other.label), locus (other.locus), + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), label (other.label), locus (other.locus), marked_for_strip (other.marked_for_strip) { // guard to protect from null pointer dereference @@ -3072,7 +3136,7 @@ public: label = other.label; locus = other.locus; marked_for_strip = other.marked_for_strip; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to protect from null pointer dereference if (other.break_expr != nullptr) @@ -3088,7 +3152,7 @@ public: BreakExpr &operator= (BreakExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -3099,10 +3163,15 @@ public: // TODO: is this better? Or is a "vis_block" better? std::unique_ptr<Expr> &get_break_expr () { - rust_assert (break_expr != nullptr); + rust_assert (has_break_expr ()); return break_expr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + Lifetime &get_label () { return label; } protected: @@ -3121,13 +3190,14 @@ class RangeExpr : public ExprWithoutBlock protected: // outer attributes not allowed before range expressions - RangeExpr (Location locus) - : ExprWithoutBlock (std::vector<Attribute> ()), locus (locus) - {} + RangeExpr (Location locus) : locus (locus) {} public: Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } + + // should never be called - error if called + void set_outer_attrs (std::vector<Attribute> new_attrs) override { rust_assert (false); } }; // Range from (inclusive) and to (exclusive) expression AST node object @@ -3515,8 +3585,8 @@ protected: // Return expression AST node representation class ReturnExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> return_expr; - Location locus; // TODO: find another way to store this to save memory? @@ -3530,15 +3600,15 @@ public: bool has_returned_expr () const { return return_expr != nullptr; } // Constructor for ReturnExpr. - ReturnExpr (Location locus, std::unique_ptr<Expr> returned_expr = nullptr, - std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) - : ExprWithoutBlock (std::move (outer_attribs)), + ReturnExpr (std::unique_ptr<Expr> returned_expr, + std::vector<Attribute> outer_attribs, Location locus) + : outer_attrs (std::move (outer_attribs)), return_expr (std::move (returned_expr)), locus (locus) {} // Copy constructor with clone ReturnExpr (ReturnExpr const &other) - : ExprWithoutBlock (other), locus (other.locus), + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), locus (other.locus), marked_for_strip (other.marked_for_strip) { // guard to protect from null pointer dereference @@ -3552,7 +3622,7 @@ public: ExprWithoutBlock::operator= (other); locus = other.locus; marked_for_strip = other.marked_for_strip; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to protect from null pointer dereference if (other.return_expr != nullptr) @@ -3568,7 +3638,7 @@ public: ReturnExpr &operator= (ReturnExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -3583,6 +3653,11 @@ public: return return_expr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3598,6 +3673,7 @@ class MacroInvocation; // An unsafe block AST node class UnsafeBlockExpr : public ExprWithBlock { + std::vector<Attribute> outer_attrs; // Or just have it extend BlockExpr std::unique_ptr<BlockExpr> expr; Location locus; @@ -3607,13 +3683,13 @@ public: UnsafeBlockExpr (std::unique_ptr<BlockExpr> block_expr, std::vector<Attribute> outer_attribs, Location locus) - : ExprWithBlock (std::move (outer_attribs)), expr (std::move (block_expr)), + : outer_attrs (std::move (outer_attribs)), expr (std::move (block_expr)), locus (locus) {} // Copy constructor with clone UnsafeBlockExpr (UnsafeBlockExpr const &other) - : ExprWithBlock (other), locus (other.locus) + : ExprWithBlock (other), outer_attrs (other.outer_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) @@ -3625,7 +3701,7 @@ public: { ExprWithBlock::operator= (other); locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) @@ -3641,7 +3717,7 @@ public: UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -3656,6 +3732,11 @@ public: return expr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3700,9 +3781,8 @@ class BaseLoopExpr : public ExprWithBlock { protected: // protected to allow subclasses better use of them - // bool has_loop_label; + std::vector<Attribute> outer_attrs; LoopLabel loop_label; - std::unique_ptr<BlockExpr> loop_block; private: @@ -3714,14 +3794,14 @@ protected: LoopLabel loop_label = LoopLabel::error (), std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) - : ExprWithBlock (std::move (outer_attribs)), + : outer_attrs (std::move (outer_attribs)), loop_label (std::move (loop_label)), loop_block (std::move (loop_block)), locus (locus) {} // Copy constructor for BaseLoopExpr with clone BaseLoopExpr (BaseLoopExpr const &other) - : ExprWithBlock (other), loop_label (other.loop_label), locus (other.locus) + : ExprWithBlock (other), outer_attrs (other.outer_attrs), loop_label (other.loop_label), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.loop_block != nullptr) @@ -3734,7 +3814,7 @@ protected: ExprWithBlock::operator= (other); loop_label = other.loop_label; locus = other.locus; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; // guard to prevent null dereference (only required if error state) if (other.loop_block != nullptr) @@ -3755,7 +3835,7 @@ public: LoopLabel &get_loop_label () { return loop_label; } Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } // Invalid if loop block is null, so base stripping on that. void mark_for_strip () override { loop_block = nullptr; } @@ -3767,6 +3847,11 @@ public: rust_assert (loop_block != nullptr); return loop_block; } + + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } }; // 'Loop' expression (i.e. the infinite loop) AST node @@ -4010,24 +4095,23 @@ class IfLetExpr; // Base if expression with no "else" or "if let" AST node class IfExpr : public ExprWithBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> condition; std::unique_ptr<BlockExpr> if_block; - Location locus; public: std::string as_string () const override; IfExpr (std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> if_block, - Location locus) - : ExprWithBlock (std::vector<Attribute> ()), - condition (std::move (condition)), if_block (std::move (if_block)), + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), condition (std::move (condition)), if_block (std::move (if_block)), locus (locus) {} // outer attributes are never allowed on IfExprs // Copy constructor with clone - IfExpr (IfExpr const &other) : ExprWithBlock (other), locus (other.locus) + IfExpr (IfExpr const &other) : ExprWithBlock (other), outer_attrs (other.outer_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.condition != nullptr) @@ -4040,6 +4124,7 @@ public: IfExpr &operator= (IfExpr const &other) { ExprWithBlock::operator= (other); + outer_attrs = other.outer_attrs; locus = other.locus; // guard to prevent null dereference (only required if error state) @@ -4070,7 +4155,7 @@ public: * better approach? or does it not parse correctly and have downsides? */ Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -4102,6 +4187,12 @@ public: return if_block == nullptr && condition == nullptr; } + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + + // TODO: this mutable getter seems really dodgy. Think up better way. + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + protected: // Base clone function but still concrete as concrete base class virtual IfExpr *clone_if_expr_impl () const { return new IfExpr (*this); } @@ -4124,8 +4215,8 @@ public: IfExprConseqElse (std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<BlockExpr> else_block, Location locus) - : IfExpr (std::move (condition), std::move (if_block), locus), + std::unique_ptr<BlockExpr> else_block, std::vector<Attribute> outer_attrs, Location locus) + : IfExpr (std::move (condition), std::move (if_block), std::move (outer_attrs), locus), else_block (std::move (else_block)) {} // again, outer attributes not allowed @@ -4180,8 +4271,8 @@ public: IfExprConseqIf (std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<IfExpr> conseq_if_expr, Location locus) - : IfExpr (std::move (condition), std::move (if_block), locus), + std::unique_ptr<IfExpr> conseq_if_expr, std::vector<Attribute> outer_attrs, Location locus) + : IfExpr (std::move (condition), std::move (if_block), std::move (outer_attrs), locus), conseq_if_expr (std::move (conseq_if_expr)) {} // outer attributes not allowed @@ -4232,7 +4323,7 @@ protected: // Basic "if let" expression AST node with no else class IfLetExpr : public ExprWithBlock { - // MatchArmPatterns patterns; + std::vector<Attribute> outer_attrs; std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined std::unique_ptr<Expr> value; std::unique_ptr<BlockExpr> if_block; @@ -4242,17 +4333,16 @@ public: std::string as_string () const override; IfLetExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, - std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, + std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, std::vector<Attribute> outer_attrs, Location locus) - : ExprWithBlock (std::vector<Attribute> ()), - match_arm_patterns (std::move (match_arm_patterns)), + : match_arm_patterns (std::move (match_arm_patterns)), value (std::move (value)), if_block (std::move (if_block)), locus (locus) {} // outer attributes not allowed on if let exprs either // copy constructor with clone IfLetExpr (IfLetExpr const &other) - : ExprWithBlock (other), locus (other.locus) + : ExprWithBlock (other), outer_attrs (other.outer_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.value != nullptr) @@ -4269,6 +4359,7 @@ public: IfLetExpr &operator= (IfLetExpr const &other) { ExprWithBlock::operator= (other); + outer_attrs = other.outer_attrs; locus = other.locus; // guard to prevent null dereference (only required if error state) @@ -4299,7 +4390,7 @@ public: } Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -4338,6 +4429,12 @@ public: return match_arm_patterns; } + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + + // TODO: this mutable getter seems really dodgy. Think up better way. + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + protected: /* Use covariance to implement clone function as returning this object rather * than base (or rather this or any derived object) */ @@ -4363,9 +4460,9 @@ public: IfExprConseqIfLet (std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<IfLetExpr> conseq_if_let_expr, + std::unique_ptr<IfLetExpr> conseq_if_let_expr, std::vector<Attribute> outer_attrs, Location locus) - : IfExpr (std::move (condition), std::move (if_block), locus), + : IfExpr (std::move (condition), std::move (if_block), std::move (outer_attrs), locus), if_let_expr (std::move (conseq_if_let_expr)) {} // outer attributes not allowed @@ -4420,9 +4517,9 @@ public: IfLetExprConseqElse ( std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<BlockExpr> else_block, Location locus) + std::unique_ptr<BlockExpr> else_block, std::vector<Attribute> outer_attrs, Location locus) : IfLetExpr (std::move (match_arm_patterns), std::move (value), - std::move (if_block), locus), + std::move (if_block), std::move (outer_attrs), locus), else_block (std::move (else_block)) {} // outer attributes not allowed @@ -4479,9 +4576,9 @@ public: IfLetExprConseqIf (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<IfExpr> if_expr, Location locus) + std::unique_ptr<IfExpr> if_expr, std::vector<Attribute> outer_attrs, Location locus) : IfLetExpr (std::move (match_arm_patterns), std::move (value), - std::move (if_block), locus), + std::move (if_block), std::move (outer_attrs), locus), if_expr (std::move (if_expr)) {} // again, outer attributes not allowed @@ -4537,9 +4634,9 @@ public: IfLetExprConseqIfLet ( std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<IfLetExpr> if_let_expr, Location locus) + std::unique_ptr<IfLetExpr> if_let_expr, std::vector<Attribute> outer_attrs, Location locus) : IfLetExpr (std::move (match_arm_patterns), std::move (value), - std::move (if_block), locus), + std::move (if_block), std::move (outer_attrs), locus), if_let_expr (std::move (if_let_expr)) {} // outer attributes not allowed @@ -4849,15 +4946,10 @@ protected: // Match expression AST node class MatchExpr : public ExprWithBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> branch_value; std::vector<Attribute> inner_attrs; - - // bool has_match_arms; - // MatchArms match_arms; - // std::vector<std::unique_ptr<MatchCase> > match_arms; // inlined from - // MatchArms std::vector<MatchCase> match_arms; - Location locus; public: @@ -4867,11 +4959,10 @@ public: bool has_match_arms () const { return !match_arms.empty (); } MatchExpr (std::unique_ptr<Expr> branch_value, - // std::vector<std::unique_ptr<MatchCase> > match_arms, std::vector<MatchCase> match_arms, std::vector<Attribute> inner_attrs, std::vector<Attribute> outer_attrs, Location locus) - : ExprWithBlock (std::move (outer_attrs)), + : outer_attrs (std::move (outer_attrs)), branch_value (std::move (branch_value)), inner_attrs (std::move (inner_attrs)), match_arms (std::move (match_arms)), locus (locus) @@ -4879,16 +4970,12 @@ public: // Copy constructor requires clone due to unique_ptr MatchExpr (MatchExpr const &other) - : ExprWithBlock (other), inner_attrs (other.inner_attrs), + : ExprWithBlock (other), outer_attrs (other.outer_attrs), inner_attrs (other.inner_attrs), match_arms (other.match_arms), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.branch_value != nullptr) branch_value = other.branch_value->clone_expr (); - - /*match_arms.reserve (other.match_arms.size ()); - for (const auto &e : other.match_arms) - match_arms.push_back (e->clone_match_case ());*/ } // Overloaded assignment operator to clone due to unique_ptr @@ -4897,7 +4984,7 @@ public: ExprWithBlock::operator= (other); inner_attrs = other.inner_attrs; match_arms = other.match_arms; - // outer_attrs = other.outer_attrs; + outer_attrs = other.outer_attrs; locus = other.locus; // guard to prevent null dereference (only required if error state) @@ -4906,10 +4993,6 @@ public: else branch_value = nullptr; - /*match_arms.reserve (other.match_arms.size ()); - for (const auto &e : other.match_arms) - match_arms.push_back (e->clone_match_case ());*/ - return *this; } @@ -4918,7 +5001,7 @@ public: MatchExpr &operator= (MatchExpr &&other) = default; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -4930,6 +5013,11 @@ public: const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + // TODO: is this better? Or is a "vis_block" better? std::unique_ptr<Expr> &get_scrutinee_expr () { @@ -4952,6 +5040,7 @@ protected: // Await expression AST node (pseudo-member variable access) class AwaitExpr : public ExprWithoutBlock { + std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> awaited_expr; Location locus; @@ -4959,13 +5048,13 @@ public: // TODO: ensure outer attributes are actually allowed AwaitExpr (std::unique_ptr<Expr> awaited_expr, std::vector<Attribute> outer_attrs, Location locus) - : ExprWithoutBlock (std::move (outer_attrs)), + : outer_attrs (std::move (outer_attrs)), awaited_expr (std::move (awaited_expr)), locus (locus) {} // copy constructor with clone AwaitExpr (AwaitExpr const &other) - : ExprWithoutBlock (other), locus (other.locus) + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.awaited_expr != nullptr) @@ -4976,6 +5065,7 @@ public: AwaitExpr &operator= (AwaitExpr const &other) { ExprWithoutBlock::operator= (other); + outer_attrs = other.outer_attrs; locus = other.locus; // guard to prevent null dereference (only required if error state) @@ -4994,7 +5084,7 @@ public: std::string as_string () const override; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -5009,6 +5099,11 @@ public: return awaited_expr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -5022,6 +5117,7 @@ protected: class AsyncBlockExpr : public ExprWithBlock { // TODO: should this extend BlockExpr rather than be a composite of it? + std::vector<Attribute> outer_attrs; bool has_move; std::unique_ptr<BlockExpr> block_expr; Location locus; @@ -5029,13 +5125,13 @@ class AsyncBlockExpr : public ExprWithBlock public: AsyncBlockExpr (std::unique_ptr<BlockExpr> block_expr, bool has_move, std::vector<Attribute> outer_attrs, Location locus) - : ExprWithBlock (std::move (outer_attrs)), has_move (has_move), + : outer_attrs (std::move (outer_attrs)), has_move (has_move), block_expr (std::move (block_expr)), locus (locus) {} // copy constructor with clone AsyncBlockExpr (AsyncBlockExpr const &other) - : ExprWithBlock (other), has_move (other.has_move), locus (other.locus) + : ExprWithBlock (other), outer_attrs (other.outer_attrs), has_move (other.has_move), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.block_expr != nullptr) @@ -5046,6 +5142,7 @@ public: AsyncBlockExpr &operator= (AsyncBlockExpr const &other) { ExprWithBlock::operator= (other); + outer_attrs = other.outer_attrs; has_move = other.has_move; locus = other.locus; @@ -5065,7 +5162,7 @@ public: std::string as_string () const override; Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -5080,6 +5177,11 @@ public: return block_expr; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 352fabc..a6f5398 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -149,7 +149,7 @@ public: } protected: - // Clone function implementation as (not pure) virtual method + // Clone function implementation as virtual method TypeParam *clone_generic_param_impl () const override { return new TypeParam (*this); @@ -891,17 +891,19 @@ public: protected: /* Use covariance to implement clone function as returning this object * rather than base */ - Method *clone_inherent_impl_item_impl () const override + Method *clone_inherent_impl_item_impl () const final override { - return new Method (*this); + return clone_method_impl (); } /* Use covariance to implement clone function as returning this object * rather than base */ - Method *clone_trait_impl_item_impl () const override + Method *clone_trait_impl_item_impl () const final override { - return new Method (*this); + return clone_method_impl (); } + + /*virtual*/ Method *clone_method_impl () const { return new Method (*this); } }; // Item that supports visibility - abstract base class diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 98051cec..51220e4 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -316,6 +316,12 @@ class MacroRulesDefinition : public MacroItem Location locus; + /* NOTE: in rustc, macro definitions are considered (and parsed as) a type + * of macro, whereas here they are considered part of the language itself. + * I am not aware of the implications of this decision. The rustc spec does + * mention that using the same parser for macro definitions and invocations + * is "extremely self-referential and non-intuitive". */ + public: std::string as_string () const override; @@ -354,49 +360,62 @@ class MacroInvocation : public TypeNoBounds, public Pattern, public ExprWithoutBlock { - SimplePath path; - DelimTokenTree token_tree; + std::vector<Attribute> outer_attrs; + MacroInvocData invoc_data; Location locus; public: std::string as_string () const override; - MacroInvocation (SimplePath path, DelimTokenTree token_tree, + MacroInvocation (MacroInvocData invoc_data, std::vector<Attribute> outer_attrs, Location locus) - : ExprWithoutBlock (std::move (outer_attrs)), path (std::move (path)), - token_tree (std::move (token_tree)), locus (locus) + : outer_attrs (std::move (outer_attrs)), + invoc_data (std::move (invoc_data)), locus (locus) {} Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; // Invalid if path is empty, so base stripping on that. - void mark_for_strip () override { path = SimplePath::create_empty (); } - bool is_marked_for_strip () const override { return path.is_empty (); } + void mark_for_strip () override { invoc_data.mark_for_strip (); } + bool is_marked_for_strip () const override + { + return invoc_data.is_marked_for_strip (); + } - const SimplePath &get_path () const { return path; } - SimplePath &get_path () { return path; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override + { + outer_attrs = std::move (new_attrs); + } protected: /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocation *clone_pattern_impl () const override + MacroInvocation *clone_pattern_impl () const final override { - return new MacroInvocation (*this); + return clone_macro_invocation_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocation *clone_expr_without_block_impl () const override + MacroInvocation *clone_expr_without_block_impl () const final override { - return new MacroInvocation (*this); + return clone_macro_invocation_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - MacroInvocation *clone_type_no_bounds_impl () const override + MacroInvocation *clone_type_no_bounds_impl () const final override + { + return clone_macro_invocation_impl (); + } + + /*virtual*/ MacroInvocation *clone_macro_invocation_impl () const { return new MacroInvocation (*this); } @@ -514,6 +533,7 @@ protected: class MetaNameValueStr : public MetaItem { Identifier ident; + // NOTE: str stored without quotes std::string str; public: @@ -521,7 +541,10 @@ public: : ident (std::move (ident)), str (std::move (str)) {} - std::string as_string () const override { return ident + " = " + str; } + std::string as_string () const override + { + return ident + " = \"" + str + "\""; + } void accept_vis (ASTVisitor &vis) override; @@ -602,17 +625,70 @@ protected: } }; +/* Should be a tagged union to save space but implemented as struct due to + * technical difficulties. TODO: fix + * Basically, a single AST node used inside an AST fragment. */ +struct SingleASTNode +{ + std::unique_ptr<Expr> expr; + std::unique_ptr<Stmt> stmt; + std::unique_ptr<Item> item; + std::unique_ptr<Type> type; + std::unique_ptr<Pattern> pattern; + std::unique_ptr<TraitItem> trait_item; + std::unique_ptr<InherentImplItem> inherent_impl_item; + std::unique_ptr<TraitImplItem> trait_impl_item; + std::unique_ptr<ExternalItem> external_item; + + SingleASTNode (std::unique_ptr<Expr> expr) : expr (std::move (expr)) {} + SingleASTNode (std::unique_ptr<Stmt> stmt) : stmt (std::move (stmt)) {} + SingleASTNode (std::unique_ptr<Item> item) : item (std::move (item)) {} + SingleASTNode (std::unique_ptr<Type> type) : type (std::move (type)) {} + SingleASTNode (std::unique_ptr<Pattern> pattern) + : pattern (std::move (pattern)) + {} + SingleASTNode (std::unique_ptr<TraitItem> trait_item) + : trait_item (std::move (trait_item)) + {} + SingleASTNode (std::unique_ptr<InherentImplItem> inherent_impl_item) + : inherent_impl_item (std::move (inherent_impl_item)) + {} + SingleASTNode (std::unique_ptr<TraitImplItem> trait_impl_item) + : trait_impl_item (std::move (trait_impl_item)) + {} + SingleASTNode (std::unique_ptr<ExternalItem> external_item) + : external_item (std::move (external_item)) + {} +}; + +/* Basically, a "fragment" that can be incorporated into the AST, created as + * a result of macro expansion. Really annoying to work with due to the fact + * that macros can really expand to anything. As such, horrible representation + * at the moment. */ +struct ASTFragment +{ +private: + /* basic idea: essentially, a vector of tagged unions of different AST node + * types. Now, this could actually be stored without a tagged union if the + * different AST node types had a unified parent, but that would create + * issues with the diamond problem or significant performance penalties. So + * a tagged union had to be used instead. A vector is used to represent the + * ability for a macro to expand to two statements, for instance. */ + + std::vector<SingleASTNode> nodes; + +public: + ASTFragment (std::vector<SingleASTNode> nodes) : nodes (std::move (nodes)) {} +}; + // Object that parses macros from a token stream. /* TODO: would "AttributeParser" be a better name? MetaItems are only for * attributes, I believe */ struct MacroParser { private: + // TODO: might as well rewrite to use lexer tokens std::vector<std::unique_ptr<Token> > token_stream; - /* probably have to make this mutable (mutable int stream_pos) otherwise const - * has to be removed up to DelimTokenTree or further ok since this changing - * would have an effect on the results of the methods run (i.e. not logically - * const), the parsing methods shouldn't be const */ int stream_pos; public: diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index d1be6f3..b30dffc 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -311,9 +311,9 @@ public: * arguments) */ class PathInExpression : public PathPattern, public PathExpr { + std::vector<Attribute> outer_attrs; bool has_opening_scope_resolution; Location locus; - NodeId _node_id; public: @@ -321,12 +321,10 @@ public: // Constructor PathInExpression (std::vector<PathExprSegment> path_segments, - Location locus = Location (), - bool has_opening_scope_resolution = false, - std::vector<Attribute> outer_attrs - = std::vector<Attribute> ()) + std::vector<Attribute> outer_attrs, Location locus, + bool has_opening_scope_resolution = false) : PathPattern (std::move (path_segments)), - PathExpr (std::move (outer_attrs)), + outer_attrs (std::move (outer_attrs)), has_opening_scope_resolution (has_opening_scope_resolution), locus (locus), _node_id (Analysis::Mappings::get ()->get_next_node_id ()) {} @@ -334,7 +332,7 @@ public: // Creates an error state path in expression. static PathInExpression create_error () { - return PathInExpression (std::vector<PathExprSegment> ()); + return PathInExpression ({}, {}, Location ()); } // Returns whether path in expression is in an error state. @@ -353,28 +351,39 @@ public: } Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; // Invalid if path is empty (error state), so base stripping on that. void mark_for_strip () override { remove_all_segments (); } bool is_marked_for_strip () const override { return is_error (); } - bool opening_scope_resolution () { return has_opening_scope_resolution; } + + bool opening_scope_resolution () const { return has_opening_scope_resolution; } NodeId get_node_id () const override { return _node_id; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ - PathInExpression *clone_pattern_impl () const override + PathInExpression *clone_pattern_impl () const final override { - return new PathInExpression (*this); + return clone_path_in_expression_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - PathInExpression *clone_expr_without_block_impl () const override + PathInExpression *clone_expr_without_block_impl () const final override + { + return clone_path_in_expression_impl (); + } + + /*virtual*/ PathInExpression *clone_path_in_expression_impl () const { return new PathInExpression (*this); } @@ -830,6 +839,7 @@ public: * allows specifying trait functions) */ class QualifiedPathInExpression : public PathPattern, public PathExpr { + std::vector<Attribute> outer_attrs; QualifiedPathType path_type; Location locus; @@ -838,11 +848,10 @@ public: QualifiedPathInExpression (QualifiedPathType qual_path_type, std::vector<PathExprSegment> path_segments, - Location locus = Location (), - std::vector<Attribute> outer_attrs - = std::vector<Attribute> ()) + std::vector<Attribute> outer_attrs, + Location locus) : PathPattern (std::move (path_segments)), - PathExpr (std::move (outer_attrs)), + outer_attrs (std::move (outer_attrs)), path_type (std::move (qual_path_type)), locus (locus) {} @@ -856,11 +865,11 @@ public: static QualifiedPathInExpression create_error () { return QualifiedPathInExpression (QualifiedPathType::create_error (), - std::vector<PathExprSegment> ()); + {}, {}, Location ()); } Location get_locus () const { return locus; } - Location get_locus_slow () const override { return get_locus (); } + Location get_locus_slow () const final override { return get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -878,17 +887,27 @@ public: return path_type; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override { outer_attrs = std::move (new_attrs); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ - QualifiedPathInExpression *clone_pattern_impl () const override + QualifiedPathInExpression *clone_pattern_impl () const final override { - return new QualifiedPathInExpression (*this); + return clone_qual_path_in_expression_impl (); } /* Use covariance to implement clone function as returning this object rather * than base */ - QualifiedPathInExpression *clone_expr_without_block_impl () const override + QualifiedPathInExpression *clone_expr_without_block_impl () const final override + { + return clone_qual_path_in_expression_impl (); + } + + /*virtual*/ QualifiedPathInExpression *clone_qual_path_in_expression_impl () const { return new QualifiedPathInExpression (*this); } diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 1647909..b2a0bb5 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -18,7 +18,6 @@ #include "rust-macro-expand.h" #include "rust-ast-full.h" -// is full really required? #include "rust-ast-visitor.h" #include "rust-diagnostics.h" @@ -34,15 +33,15 @@ public: void expand_struct_fields (std::vector<AST::StructField> &fields) { - for (int i = 0; i < fields.size ();) + for (auto it = fields.begin (); it != fields.end ();) { - auto &field = fields[i]; + auto &field = *it; auto &field_attrs = field.get_outer_attrs (); expander.expand_cfg_attrs (field_attrs); - if (expander.fails_cfg (field_attrs)) + if (expander.fails_cfg_with_expand (field_attrs)) { - fields.erase (fields.begin () + i); + it = fields.erase (it); continue; } @@ -54,21 +53,21 @@ public: "cannot strip type in this position"); // if nothing else happens, increment - i++; + ++it; } } void expand_tuple_fields (std::vector<AST::TupleField> &fields) { - for (int i = 0; i < fields.size ();) + for (auto it = fields.begin (); it != fields.end ();) { - auto &field = fields[i]; + auto &field = *it; auto &field_attrs = field.get_outer_attrs (); expander.expand_cfg_attrs (field_attrs); - if (expander.fails_cfg (field_attrs)) + if (expander.fails_cfg_with_expand (field_attrs)) { - fields.erase (fields.begin () + i); + it = fields.erase (it); continue; } @@ -80,21 +79,21 @@ public: "cannot strip type in this position"); // if nothing else happens, increment - i++; + ++it; } } void expand_function_params (std::vector<AST::FunctionParam> ¶ms) { - for (int i = 0; i < params.size ();) + for (auto it = params.begin (); it != params.end ();) { - auto ¶m = params[i]; + auto ¶m = *it; auto ¶m_attrs = param.get_outer_attrs (); expander.expand_cfg_attrs (param_attrs); - if (expander.fails_cfg (param_attrs)) + if (expander.fails_cfg_with_expand (param_attrs)) { - params.erase (params.begin () + i); + it = params.erase (it); continue; } @@ -112,7 +111,7 @@ public: "cannot strip type in this position"); // increment - i++; + ++it; } } @@ -160,15 +159,15 @@ public: void expand_closure_params (std::vector<AST::ClosureParam> ¶ms) { - for (int i = 0; i < params.size ();) + for (auto it = params.begin (); it != params.end ();) { - auto ¶m = params[i]; + auto ¶m = *it; auto ¶m_attrs = param.get_outer_attrs (); expander.expand_cfg_attrs (param_attrs); - if (expander.fails_cfg (param_attrs)) + if (expander.fails_cfg_with_expand (param_attrs)) { - params.erase (params.begin () + i); + it = params.erase (it); continue; } @@ -188,7 +187,7 @@ public: } // increment if found nothing else so far - i++; + ++it; } } @@ -202,8 +201,8 @@ public: rust_error_at (type->get_locus_slow (), "cannot strip type in this position"); } - // TODO: maybe check for invariants being violated - e.g. both type and - // lifetime? + /* TODO: maybe check for invariants being violated - e.g. both type and + * lifetime? */ } void expand_where_clause (AST::WhereClause &where_clause) @@ -264,6 +263,22 @@ public: expand_where_clause (decl.get_where_clause ()); } + template <typename T> void expand_pointer_allow_strip (T &values) + { + for (auto it = values.begin (); it != values.end ();) + { + auto &value = *it; + + // mark for stripping if required + value->accept_vis (*this); + + if (value->is_marked_for_strip ()) + it = values.erase (it); + else + ++it; + } + } + void visit (AST::Token &) override { // shouldn't require? @@ -280,7 +295,7 @@ public: { // strip test based on outer attrs expander.expand_cfg_attrs (ident_expr.get_outer_attrs ()); - if (expander.fails_cfg (ident_expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (ident_expr.get_outer_attrs ())) { ident_expr.mark_for_strip (); return; @@ -298,7 +313,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ()); - if (expander.fails_cfg (macro_invoc.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ())) { macro_invoc.mark_for_strip (); return; @@ -315,7 +330,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (path.get_outer_attrs ()); - if (expander.fails_cfg (path.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (path.get_outer_attrs ())) { path.mark_for_strip (); return; @@ -371,7 +386,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (path.get_outer_attrs ()); - if (expander.fails_cfg (path.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (path.get_outer_attrs ())) { path.mark_for_strip (); return; @@ -398,7 +413,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -420,7 +435,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -440,7 +455,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -460,7 +475,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -480,7 +495,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -638,7 +653,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -647,7 +662,7 @@ public: /* 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 ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -667,19 +682,7 @@ public: { /* apparently outer attributes are allowed in "elements of array * expressions" according to spec */ - auto &values = elems.get_values (); - 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++; - } + expand_pointer_allow_strip (elems.get_values ()); } void visit (AST::ArrayElemsCopied &elems) override { @@ -707,7 +710,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -716,7 +719,7 @@ public: /* strip test based on inner attrs - spec says there are separate * inner attributes, not just outer attributes of inner exprs */ expander.expand_cfg_attrs (expr.get_inner_attrs ()); - if (expander.fails_cfg (expr.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -734,7 +737,7 @@ public: * having expansion code anyway. TODO */ // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -764,7 +767,7 @@ public: // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -773,7 +776,7 @@ public: /* 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 ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -781,25 +784,13 @@ public: /* 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++; - } + expand_pointer_allow_strip (expr.get_tuple_elems ()); } 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 ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -819,7 +810,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -828,7 +819,7 @@ public: /* 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 ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -871,7 +862,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -880,7 +871,7 @@ public: /* 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 ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -919,7 +910,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -928,7 +919,7 @@ public: /* 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 ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -955,7 +946,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -964,7 +955,7 @@ public: /* 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 ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -979,25 +970,13 @@ public: /* 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++; - } + expand_pointer_allow_strip (expr.get_elems ()); } 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 ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1040,7 +1019,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1069,7 +1048,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1086,19 +1065,7 @@ public: /* spec says outer attributes are specifically allowed for elements * of tuple-style enum 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++; - } + expand_pointer_allow_strip (expr.get_elems ()); } void visit (AST::EnumExprFieldless &expr) override { @@ -1115,7 +1082,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1133,25 +1100,13 @@ public: /* spec says outer attributes are specifically allowed for elements * of call expressions, so full stripping possible */ - auto ¶ms = expr.get_params (); - for (int i = 0; i < params.size ();) - { - auto ¶m = params[i]; - - // mark for stripping if required - param->accept_vis (*this); - - if (param->is_marked_for_strip ()) - params.erase (params.begin () + i); - else - i++; - } + expand_pointer_allow_strip (expr.get_params ()); } void visit (AST::MethodCallExpr &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 ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1173,25 +1128,13 @@ public: /* spec says outer attributes are specifically allowed for elements * of method call expressions, so full stripping possible */ - auto ¶ms = expr.get_params (); - for (int i = 0; i < params.size ();) - { - auto ¶m = params[i]; - - // mark for stripping if required - param->accept_vis (*this); - - if (param->is_marked_for_strip ()) - params.erase (params.begin () + i); - else - i++; - } + expand_pointer_allow_strip (expr.get_params ()); } void visit (AST::FieldAccessExpr &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 ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1211,7 +1154,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1233,7 +1176,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1242,26 +1185,14 @@ public: /* strip test based on inner attrs - spec says there are inner * attributes, not just outer attributes of inner stmts */ expander.expand_cfg_attrs (expr.get_inner_attrs ()); - if (expander.fails_cfg (expr.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; } // strip all statements - auto &stmts = expr.get_statements (); - for (int i = 0; i < stmts.size ();) - { - auto &stmt = stmts[i]; - - // mark for stripping if required - stmt->accept_vis (*this); - - if (stmt->is_marked_for_strip ()) - stmts.erase (stmts.begin () + i); - else - i++; - } + expand_pointer_allow_strip (expr.get_statements ()); // strip tail expression if exists - can actually fully remove it if (expr.has_tail_expr ()) @@ -1278,7 +1209,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1307,7 +1238,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1317,7 +1248,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1440,7 +1371,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1470,7 +1401,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1488,7 +1419,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1506,7 +1437,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1532,7 +1463,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1566,13 +1497,13 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; } - // TODO: strip sub-patterns of pattern + // strip sub-patterns of pattern auto &pattern = expr.get_pattern (); pattern->accept_vis (*this); if (pattern->is_marked_for_strip ()) @@ -1597,9 +1528,12 @@ public: } void visit (AST::IfExpr &expr) override { + // rust playground test shows that IfExpr does support outer attrs, at least + // when used as statement + // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1625,7 +1559,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1659,7 +1593,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1693,7 +1627,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1728,7 +1662,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1762,7 +1696,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1804,7 +1738,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1846,7 +1780,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1889,7 +1823,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1897,7 +1831,7 @@ public: // inner attr strip test expander.expand_cfg_attrs (expr.get_inner_attrs ()); - if (expander.fails_cfg (expr.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_inner_attrs ())) { expr.mark_for_strip (); return; @@ -1913,17 +1847,17 @@ public: // strip match cases auto &match_cases = expr.get_match_cases (); - for (int i = 0; i < match_cases.size ();) + for (auto it = match_cases.begin (); it != match_cases.end ();) { - auto &match_case = match_cases[i]; + auto &match_case = *it; // strip match case based on outer attributes in match arm auto &match_arm = match_case.get_arm (); expander.expand_cfg_attrs (match_arm.get_outer_attrs ()); - if (expander.fails_cfg (match_arm.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (match_arm.get_outer_attrs ())) { // strip match case - match_cases.erase (match_cases.begin () + i); + it = match_cases.erase (it); continue; } @@ -1958,14 +1892,14 @@ public: "attributes not allowed"); // increment to next case if haven't continued - i++; + ++it; } } void visit (AST::AwaitExpr &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 ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -1984,7 +1918,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (expr.get_outer_attrs ()); - if (expander.fails_cfg (expr.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (expr.get_outer_attrs ())) { expr.mark_for_strip (); return; @@ -2041,7 +1975,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (method.get_outer_attrs ()); - if (expander.fails_cfg (method.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (method.get_outer_attrs ())) { method.mark_for_strip (); return; @@ -2086,7 +2020,7 @@ public: { // strip test based on outer attrs expander.expand_cfg_attrs (module.get_outer_attrs ()); - if (expander.fails_cfg (module.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (module.get_outer_attrs ())) { module.mark_for_strip (); return; @@ -2094,32 +2028,20 @@ public: // strip test based on inner attrs expander.expand_cfg_attrs (module.get_inner_attrs ()); - if (expander.fails_cfg (module.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (module.get_inner_attrs ())) { module.mark_for_strip (); return; } // strip items if required - auto &items = module.get_items (); - for (int i = 0; i < items.size ();) - { - auto &item = items[i]; - - // mark for stripping if required - item->accept_vis (*this); - - if (item->is_marked_for_strip ()) - items.erase (items.begin () + i); - else - i++; - } + expand_pointer_allow_strip (module.get_items ()); } void visit (AST::ModuleNoBody &module) override { // strip test based on outer attrs expander.expand_cfg_attrs (module.get_outer_attrs ()); - if (expander.fails_cfg (module.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (module.get_outer_attrs ())) { module.mark_for_strip (); return; @@ -2129,7 +2051,7 @@ public: { // strip test based on outer attrs expander.expand_cfg_attrs (crate.get_outer_attrs ()); - if (expander.fails_cfg (crate.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (crate.get_outer_attrs ())) { crate.mark_for_strip (); return; @@ -2151,7 +2073,7 @@ public: { // strip test based on outer attrs expander.expand_cfg_attrs (use_decl.get_outer_attrs ()); - if (expander.fails_cfg (use_decl.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (use_decl.get_outer_attrs ())) { use_decl.mark_for_strip (); return; @@ -2161,7 +2083,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (function.get_outer_attrs ()); - if (expander.fails_cfg (function.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (function.get_outer_attrs ())) { function.mark_for_strip (); return; @@ -2201,7 +2123,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (type_alias.get_outer_attrs ()); - if (expander.fails_cfg (type_alias.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (type_alias.get_outer_attrs ())) { type_alias.mark_for_strip (); return; @@ -2224,7 +2146,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (struct_item.get_outer_attrs ()); - if (expander.fails_cfg (struct_item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (struct_item.get_outer_attrs ())) { struct_item.mark_for_strip (); return; @@ -2245,7 +2167,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (tuple_struct.get_outer_attrs ()); - if (expander.fails_cfg (tuple_struct.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (tuple_struct.get_outer_attrs ())) { tuple_struct.mark_for_strip (); return; @@ -2266,7 +2188,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2276,7 +2198,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2290,7 +2212,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2304,7 +2226,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2324,7 +2246,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (enum_item.get_outer_attrs ()); - if (expander.fails_cfg (enum_item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (enum_item.get_outer_attrs ())) { enum_item.mark_for_strip (); return; @@ -2339,25 +2261,13 @@ public: /* strip enum fields if required - this is presumably * allowed by spec */ - auto &variants = enum_item.get_variants (); - for (int i = 0; i < variants.size ();) - { - auto &variant = variants[i]; - - // mark for stripping if required - variant->accept_vis (*this); - - if (variant->is_marked_for_strip ()) - variants.erase (variants.begin () + i); - else - i++; - } + expand_pointer_allow_strip (enum_item.get_variants ()); } 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 ())) + if (expander.fails_cfg_with_expand (union_item.get_outer_attrs ())) { union_item.mark_for_strip (); return; @@ -2378,7 +2288,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (const_item.get_outer_attrs ()); - if (expander.fails_cfg (const_item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (const_item.get_outer_attrs ())) { const_item.mark_for_strip (); return; @@ -2405,7 +2315,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (static_item.get_outer_attrs ()); - if (expander.fails_cfg (static_item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (static_item.get_outer_attrs ())) { static_item.mark_for_strip (); return; @@ -2432,7 +2342,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2457,7 +2367,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2482,7 +2392,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2512,7 +2422,7 @@ public: { // initial test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2529,7 +2439,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (trait.get_outer_attrs ()); - if (expander.fails_cfg (trait.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (trait.get_outer_attrs ())) { trait.mark_for_strip (); return; @@ -2537,7 +2447,7 @@ public: // strip test based on inner attrs expander.expand_cfg_attrs (trait.get_inner_attrs ()); - if (expander.fails_cfg (trait.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (trait.get_inner_attrs ())) { trait.mark_for_strip (); return; @@ -2558,25 +2468,13 @@ public: expand_where_clause (trait.get_where_clause ()); // strip trait items if required - auto &trait_items = trait.get_trait_items (); - for (int i = 0; i < trait_items.size ();) - { - auto &item = trait_items[i]; - - // mark for stripping if required - item->accept_vis (*this); - - if (item->is_marked_for_strip ()) - trait_items.erase (trait_items.begin () + i); - else - i++; - } + expand_pointer_allow_strip (trait.get_trait_items ()); } void visit (AST::InherentImpl &impl) override { // initial strip test based on outer attrs expander.expand_cfg_attrs (impl.get_outer_attrs ()); - if (expander.fails_cfg (impl.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (impl.get_outer_attrs ())) { impl.mark_for_strip (); return; @@ -2584,7 +2482,7 @@ public: // strip test based on inner attrs expander.expand_cfg_attrs (impl.get_inner_attrs ()); - if (expander.fails_cfg (impl.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (impl.get_inner_attrs ())) { impl.mark_for_strip (); return; @@ -2604,25 +2502,13 @@ public: expand_where_clause (impl.get_where_clause ()); // strip inherent impl items if required - auto &impl_items = impl.get_impl_items (); - for (int i = 0; i < impl_items.size ();) - { - auto &item = impl_items[i]; - - // mark for stripping if required - item->accept_vis (*this); - - if (item->is_marked_for_strip ()) - impl_items.erase (impl_items.begin () + i); - else - i++; - } + expand_pointer_allow_strip (impl.get_impl_items ()); } void visit (AST::TraitImpl &impl) override { // initial strip test based on outer attrs expander.expand_cfg_attrs (impl.get_outer_attrs ()); - if (expander.fails_cfg (impl.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (impl.get_outer_attrs ())) { impl.mark_for_strip (); return; @@ -2630,7 +2516,7 @@ public: // strip test based on inner attrs expander.expand_cfg_attrs (impl.get_inner_attrs ()); - if (expander.fails_cfg (impl.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (impl.get_inner_attrs ())) { impl.mark_for_strip (); return; @@ -2656,25 +2542,13 @@ public: expand_where_clause (impl.get_where_clause ()); // strip trait impl items if required - auto &impl_items = impl.get_impl_items (); - for (int i = 0; i < impl_items.size ();) - { - auto &item = impl_items[i]; - - // mark for stripping if required - item->accept_vis (*this); - - if (item->is_marked_for_strip ()) - impl_items.erase (impl_items.begin () + i); - else - i++; - } + expand_pointer_allow_strip (impl.get_impl_items ()); } void visit (AST::ExternalStaticItem &item) override { // strip test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2690,7 +2564,7 @@ public: { // strip test based on outer attrs expander.expand_cfg_attrs (item.get_outer_attrs ()); - if (expander.fails_cfg (item.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (item.get_outer_attrs ())) { item.mark_for_strip (); return; @@ -2703,15 +2577,15 @@ public: /* strip function parameters if required - this is specifically * allowed by spec */ auto ¶ms = item.get_function_params (); - for (int i = 0; i < params.size ();) + for (auto it = params.begin (); it != params.end ();) { - auto ¶m = params[i]; + auto ¶m = *it; auto ¶m_attrs = param.get_outer_attrs (); expander.expand_cfg_attrs (param_attrs); - if (expander.fails_cfg (param_attrs)) + if (expander.fails_cfg_with_expand (param_attrs)) { - params.erase (params.begin () + i); + it = params.erase (it); continue; } @@ -2722,7 +2596,7 @@ public: "cannot strip type in this position"); // increment if nothing else happens - i++; + ++it; } /* NOTE: these are extern function params, which may have different * rules and restrictions to "normal" function params. So expansion @@ -2747,7 +2621,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (block.get_outer_attrs ()); - if (expander.fails_cfg (block.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (block.get_outer_attrs ())) { block.mark_for_strip (); return; @@ -2755,26 +2629,14 @@ public: // strip test based on inner attrs expander.expand_cfg_attrs (block.get_inner_attrs ()); - if (expander.fails_cfg (block.get_inner_attrs ())) + if (expander.fails_cfg_with_expand (block.get_inner_attrs ())) { block.mark_for_strip (); return; } // strip external items if required - auto &extern_items = block.get_extern_items (); - for (int i = 0; i < extern_items.size ();) - { - auto &item = extern_items[i]; - - // mark for stripping if required - item->accept_vis (*this); - - if (item->is_marked_for_strip ()) - extern_items.erase (extern_items.begin () + i); - else - i++; - } + expand_pointer_allow_strip (block.get_extern_items ()); } // I don't think it would be possible to strip macros without expansion @@ -2785,7 +2647,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (rules_def.get_outer_attrs ()); - if (expander.fails_cfg (rules_def.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (rules_def.get_outer_attrs ())) { rules_def.mark_for_strip (); return; @@ -2797,7 +2659,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ()); - if (expander.fails_cfg (macro_invoc.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ())) { macro_invoc.mark_for_strip (); return; @@ -2872,7 +2734,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (field.get_outer_attrs ()); - if (expander.fails_cfg (field.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (field.get_outer_attrs ())) { field.mark_for_strip (); return; @@ -2889,7 +2751,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (field.get_outer_attrs ()); - if (expander.fails_cfg (field.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (field.get_outer_attrs ())) { field.mark_for_strip (); return; @@ -2906,7 +2768,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (field.get_outer_attrs ()); - if (expander.fails_cfg (field.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (field.get_outer_attrs ())) { field.mark_for_strip (); return; @@ -2920,32 +2782,21 @@ public: if (path.is_marked_for_strip ()) rust_error_at (path.get_locus (), "cannot strip path in this position"); - // TODO: apparently struct pattern fields can have outer attrs. so can they - // be stripped? + /* TODO: apparently struct pattern fields can have outer attrs. so can they + * be stripped? */ if (!pattern.has_struct_pattern_elems ()) return; auto &elems = pattern.get_struct_pattern_elems (); // assuming you can strip struct pattern fields - auto &fields = elems.get_struct_pattern_fields (); - for (int i = 0; i < fields.size ();) - { - auto &field = fields[i]; - - field->accept_vis (*this); - - if (field->is_marked_for_strip ()) - fields.erase (fields.begin () + i); - else - i++; - } + expand_pointer_allow_strip (elems.get_struct_pattern_fields ()); // assuming you can strip the ".." part if (elems.has_etc ()) { expander.expand_cfg_attrs (elems.get_etc_outer_attrs ()); - if (expander.fails_cfg (elems.get_etc_outer_attrs ())) + if (expander.fails_cfg_with_expand (elems.get_etc_outer_attrs ())) elems.strip_etc (); } } @@ -3068,7 +2919,7 @@ public: { // initial strip test based on outer attrs expander.expand_cfg_attrs (stmt.get_outer_attrs ()); - if (expander.fails_cfg (stmt.get_outer_attrs ())) + if (expander.fails_cfg_with_expand (stmt.get_outer_attrs ())) { stmt.mark_for_strip (); return; @@ -3250,15 +3101,15 @@ public: // presumably function params can be stripped auto ¶ms = type.get_function_params (); - for (int i = 0; i < params.size ();) + for (auto it = params.begin (); it != params.end ();) { - auto ¶m = params[i]; + auto ¶m = *it; auto ¶m_attrs = param.get_outer_attrs (); expander.expand_cfg_attrs (param_attrs); - if (expander.fails_cfg (param_attrs)) + if (expander.fails_cfg_with_expand (param_attrs)) { - params.erase (params.begin () + i); + it = params.erase (it); continue; } @@ -3269,7 +3120,7 @@ public: "cannot strip type in this position"); // increment if nothing else happens - i++; + ++it; } /* TODO: assuming that variadic nature cannot be stripped. If this @@ -3289,6 +3140,94 @@ public: }; void +MacroExpander::parse_macro_to_meta_item (AST::MacroInvocData &invoc) +{ + // only parse if not already parsed + if (invoc.is_parsed ()) + return; + + std::unique_ptr<AST::AttrInputMetaItemContainer> converted_input ( + invoc.get_delim_tok_tree ().parse_to_meta_item ()); + + if (converted_input == nullptr) + { + fprintf (stderr, "DEBUG: failed to parse macro to meta item\n"); + // TODO: do something now? is this an actual error? + } + else + { + std::vector<std::unique_ptr<AST::MetaItemInner> > meta_items ( + std::move (converted_input->get_items ())); + invoc.set_meta_item_output (std::move (meta_items)); + } +} + +AST::Literal +MacroExpander::expand_cfg_macro (AST::MacroInvocData &invoc) +{ + // only allow on cfg macros + if (invoc.get_path () != "cfg") + return AST::Literal::create_error (); + + parse_macro_to_meta_item (invoc); + + /* TODO: assuming that cfg! macros can only have one meta item inner, like cfg + * attributes */ + if (invoc.get_meta_items ().size () != 1) + return AST::Literal::create_error (); + + bool result = invoc.get_meta_items ()[0]->check_cfg_predicate (session); + if (result) + return AST::Literal ("true", AST::Literal::BOOL, CORETYPE_BOOL); + else + return AST::Literal ("false", AST::Literal::BOOL, CORETYPE_BOOL); +} + +AST::ASTFragment +MacroExpander::expand_decl_macro (AST::MacroInvocData &invoc, + AST::MacroRulesDefinition &rules_def) +{ + // ensure that both invocation and rules are in a valid state + rust_assert (!invoc.is_marked_for_strip ()); + rust_assert (!rules_def.is_marked_for_strip ()); + rust_assert (rules_def.get_macro_rules ().size () > 0); + + /* probably something here about parsing invoc and rules def token trees to + * token stream. if not, how would parser handle the captures of exprs and + * stuff? on the other hand, token trees may be kind of useful in rules def as + * creating a point where recursion can occur (like having + * "compare_macro_match" and then it calling itself when it finds delimiters) + */ + + /* find matching rule to invoc token tree, based on macro rule's matcher. if + * none exist, error. + * - specifically, check each matcher in order. if one fails to match, move + * onto next. */ + /* TODO: does doing this require parsing expressions and whatever in the + * invoc? if so, might as well save the results if referenced using $ or + * whatever. If not, do another pass saving them. Except this is probably + * useless as different rules could have different starting points for exprs + * or whatever. Decision trees could avoid this, but they have their own + * issues. */ + /* TODO: will need to modify the parser so that it can essentially "catch" + * errors - maybe "try_parse_expr" or whatever methods. */ + // this technically creates a back-tracking parser - this will be the + // implementation style + + /* then, after results are saved, generate the macro output from the + * transcriber token tree. if i understand this correctly, the macro + * invocation gets replaced by the transcriber tokens, except with + * substitutions made (e.g. for $i variables) */ + + /* TODO: it is probably better to modify AST::Token to store a pointer to a + * Lexer::Token (rather than being converted) - i.e. not so much have + * AST::Token as a Token but rather a TokenContainer (as it is another type of + * TokenTree). This will prevent re-conversion of Tokens between each type + * all the time, while still allowing the heterogenous storage of token trees. + */ +} + +void MacroExpander::expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc) { /* if current expansion depth > recursion limit, create an error (maybe fatal @@ -3309,7 +3248,7 @@ MacroExpander::expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc) - derive or legacy derive - "token-based" vs "AST-based" - else is unreachable - derive container macro - unreachable*/ - + #if 0 // macro_rules macro test code auto rule_def = find_rules_def(invoc->get_path()); @@ -3331,11 +3270,11 @@ MacroExpander::expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc) } /* Determines whether any cfg predicate is false and hence item with attributes - * should be stripped. */ + * should be stripped. Note that attributes must be expanded before calling. */ bool -MacroExpander::fails_cfg (std::vector<AST::Attribute> &attrs) +MacroExpander::fails_cfg (const std::vector<AST::Attribute> &attrs) const { - for (auto &attr : attrs) + for (const auto &attr : attrs) { if (attr.get_path () == "cfg" && !attr.check_cfg_predicate (session)) return true; @@ -3343,15 +3282,62 @@ MacroExpander::fails_cfg (std::vector<AST::Attribute> &attrs) return false; } +/* Determines whether any cfg predicate is false and hence item with attributes + * should be stripped. Will expand attributes as well. */ +bool +MacroExpander::fails_cfg_with_expand (std::vector<AST::Attribute> &attrs) const +{ + // TODO: maybe have something that strips cfg attributes that evaluate true? + for (auto &attr : attrs) + { + if (attr.get_path () == "cfg") + { + if (!attr.is_parsed_to_meta_item ()) + attr.parse_attr_to_meta_item (); + + // DEBUG + if (!attr.is_parsed_to_meta_item ()) + fprintf (stderr, "failed to parse attr to meta item, right before " + "cfg predicate check\n"); + else + fprintf (stderr, "attr has been successfully parsed to meta item, " + "right before cfg predicate check\n"); + + if (!attr.check_cfg_predicate (session)) + { + // DEBUG + fprintf ( + stderr, + "cfg predicate failed for attribute: \033[0;31m'%s'\033[0m\n", + attr.as_string ().c_str ()); + + return true; + } + else + { + // DEBUG + fprintf (stderr, + "cfg predicate succeeded for attribute: " + "\033[0;31m'%s'\033[0m\n", + attr.as_string ().c_str ()); + } + } + } + return false; +} + // Expands cfg_attr attributes. void MacroExpander::expand_cfg_attrs (std::vector<AST::Attribute> &attrs) { - for (int i = 0; i < attrs.size ();) + for (std::size_t i = 0; i < attrs.size ();) { auto &attr = attrs[i]; if (attr.get_path () == "cfg_attr") { + if (!attr.is_parsed_to_meta_item ()) + attr.parse_attr_to_meta_item (); + if (attr.check_cfg_predicate (session)) { // split off cfg_attr @@ -3394,7 +3380,7 @@ MacroExpander::expand_crate () // expand crate cfg_attr attributes expand_cfg_attrs (crate.inner_attrs); - if (fails_cfg (crate.inner_attrs)) + if (fails_cfg_with_expand (crate.inner_attrs)) { // basically, delete whole crate crate.strip_crate (); @@ -3405,18 +3391,19 @@ MacroExpander::expand_crate () // expand attributes recursively and strip items if required AttrVisitor attr_visitor (*this); auto &items = crate.items; - for (int i = 0; i < items.size ();) + for (auto it = items.begin (); it != items.end ();) { - auto &item = items[i]; + auto &item = *it; // mark for stripping if required item->accept_vis (attr_visitor); if (item->is_marked_for_strip ()) - items.erase (items.begin () + i); + it = items.erase (it); else - i++; + ++it; } + // TODO: should recursive attribute and macro expansion be done in the same // transversal? Or in separate ones like currently? diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index 1102565..2e9b88b 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -20,6 +20,7 @@ #define RUST_MACRO_EXPAND_H #include "rust-ast.h" +#include "rust-macro.h" // Provides objects and method prototypes for macro expansion @@ -34,9 +35,9 @@ struct ExpansionCfg { // features? unsigned int recursion_limit = 50; // TODO: determine default recursion limit - // trace macros? - // should test? - // more default stuff? + // trace macros? + // should test? + // more default stuff? }; // Object used to store shared data (between functions) for macro expansion. @@ -59,11 +60,18 @@ struct MacroExpander // should this be public or private? void expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc); + // Expands a single declarative macro. + AST::ASTFragment expand_decl_macro (AST::MacroInvocData &invoc, + AST::MacroRulesDefinition &rules_def); + void expand_cfg_attrs (std::vector<AST::Attribute> &attrs); - bool fails_cfg (std::vector<AST::Attribute> &attr); + bool fails_cfg (const std::vector<AST::Attribute> &attr) const; + bool fails_cfg_with_expand (std::vector<AST::Attribute> &attrs) const; - /* TODO: make it extend ASTVisitor so that individual items can be accessed - * properly? */ + // Expand the data of a cfg! macro. + void parse_macro_to_meta_item (AST::MacroInvocData &invoc); + // Get the literal representation of a cfg! macro. + AST::Literal expand_cfg_macro (AST::MacroInvocData &invoc); private: AST::Crate &crate; diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h index fab736a..6070244 100644 --- a/gcc/rust/lex/rust-token.h +++ b/gcc/rust/lex/rust-token.h @@ -318,13 +318,6 @@ public: } // Makes and returns a new TokenPtr of type INT_LITERAL. - /*static TokenPtr make_int (Location locus, const std::string &str) - { - //return TokenPtr (new Token (INT_LITERAL, locus, str)); - return std::make_shared<Token>(INT_LITERAL, locus, str); - }*/ - - // Makes and returns a new TokenPtr of type INT_LITERAL. static TokenPtr make_int (Location locus, const std::string &str, PrimitiveCoreType type_hint = CORETYPE_UNKNOWN) { @@ -333,13 +326,6 @@ public: } // Makes and returns a new TokenPtr of type FLOAT_LITERAL. - /*static TokenPtr make_float (Location locus, const std::string &str) - { - return TokenPtr (new Token (FLOAT_LITERAL, locus, str)); - return std::make_shared<Token>(FLOAT_LITERAL, locus, str); - }*/ - - // Makes and returns a new TokenPtr of type FLOAT_LITERAL. static TokenPtr make_float (Location locus, const std::string &str, PrimitiveCoreType type_hint = CORETYPE_UNKNOWN) { diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index fcb3d18..437a7b5 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -792,7 +792,7 @@ Parser<ManagedTokenSource>::parse_attr_input () // create actual LiteralExpr AST::LiteralExpr lit_expr (t->get_str (), lit_type, t->get_type_hint (), - t->get_locus ()); + {}, t->get_locus ()); std::unique_ptr<AST::AttrInputLiteral> attr_input_lit ( new AST::AttrInputLiteral (std::move (lit_expr))); @@ -974,8 +974,7 @@ Parser<ManagedTokenSource>::parse_token_tree () default: // parse token itself as TokenTree lexer.skip_token (); - // TODO: fix that token constructor, possibly with c++11 features - return std::unique_ptr<AST::Token> (new AST::Token (t)); + return std::unique_ptr<AST::Token> (new AST::Token (std::move (t))); } } @@ -1531,6 +1530,7 @@ Parser<ManagedTokenSource>::parse_macro_invocation_semi ( t->get_token_description ()); return nullptr; } + Location tok_tree_locus = t->get_locus (); lexer.skip_token (); // parse actual token trees @@ -1556,6 +1556,10 @@ Parser<ManagedTokenSource>::parse_macro_invocation_semi ( t = lexer.peek_token (); } + AST::DelimTokenTree delim_tok_tree (delim_type, std::move (token_trees), + tok_tree_locus); + AST::MacroInvocData invoc_data (std::move (path), std::move (delim_tok_tree)); + // parse end delimiters t = lexer.peek_token (); if (token_id_matches_delims (t->get_id (), delim_type)) @@ -1570,8 +1574,7 @@ Parser<ManagedTokenSource>::parse_macro_invocation_semi ( { // as this is the end, allow recovery (probably) - may change return std::unique_ptr<AST::MacroInvocationSemi> ( - new AST::MacroInvocationSemi (std::move (path), delim_type, - std::move (token_trees), + new AST::MacroInvocationSemi (std::move (invoc_data), std::move (outer_attrs), macro_locus)); } @@ -1584,8 +1587,7 @@ Parser<ManagedTokenSource>::parse_macro_invocation_semi ( lexer.peek_token ()->get_token_description ()); return std::unique_ptr<AST::MacroInvocationSemi> ( - new AST::MacroInvocationSemi (std::move (path), delim_type, - std::move (token_trees), + new AST::MacroInvocationSemi (std::move (invoc_data), std::move (outer_attrs), macro_locus)); } else @@ -1633,8 +1635,8 @@ Parser<ManagedTokenSource>::parse_macro_invocation ( Location macro_locus = macro_path.get_locus (); return std::unique_ptr<AST::MacroInvocation> ( - new AST::MacroInvocation (std::move (macro_path), - std::move (delim_tok_tree), + new AST::MacroInvocation (AST::MacroInvocData (std::move (macro_path), + std::move (delim_tok_tree)), std::move (outer_attrs), macro_locus)); } @@ -1804,7 +1806,7 @@ Parser<ManagedTokenSource>::parse_macro_match () default: // just the token lexer.skip_token (); - return std::unique_ptr<AST::Token> (new AST::Token (t)); + return std::unique_ptr<AST::Token> (new AST::Token (std::move (t))); } } @@ -1912,7 +1914,7 @@ Parser<ManagedTokenSource>::parse_macro_match_repetition () break; default: // separator does exist - separator = std::unique_ptr<AST::Token> (new AST::Token (t)); + separator = std::unique_ptr<AST::Token> (new AST::Token (std::move (t))); lexer.skip_token (); break; } @@ -2664,9 +2666,9 @@ Parser<ManagedTokenSource>::parse_generic_params () } std::unique_ptr<AST::LifetimeParam> param ( - new AST::LifetimeParam (std::move (lifetime), locus, + new AST::LifetimeParam (std::move (lifetime), std::move (lifetime_bounds), - std::move (outer_attr))); + std::move (outer_attr), locus)); generic_params.push_back (std::move (param)); if (lexer.peek_token ()->get_id () != COMMA) @@ -2840,9 +2842,9 @@ Parser<ManagedTokenSource>::parse_generic_params (EndTokenPred is_end_token) } std::unique_ptr<AST::LifetimeParam> param ( - new AST::LifetimeParam (std::move (lifetime), locus, + new AST::LifetimeParam (std::move (lifetime), std::move (lifetime_bounds), - std::move (outer_attr))); + std::move (outer_attr), locus)); generic_params.push_back (std::move (param)); if (lexer.peek_token ()->get_id () != COMMA) @@ -3165,9 +3167,9 @@ Parser<ManagedTokenSource>::parse_lifetime_param () // TODO: have end token passed in? } - return AST::LifetimeParam (std::move (lifetime), lifetime_tok->get_locus (), + return AST::LifetimeParam (std::move (lifetime), std::move (lifetime_bounds), - std::move (outer_attr)); + std::move (outer_attr), lifetime_tok->get_locus ()); } // Parses type generic parameters. Will also consume any trailing comma. @@ -3692,13 +3694,11 @@ Parser<ManagedTokenSource>::parse_trait_bound () lexer.skip_token (); } - // parse for lifetimes, if it exists (although empty for lifetimes is ok to - // handle this) + /* parse for lifetimes, if it exists (although empty for lifetimes is ok to + * handle this) */ std::vector<AST::LifetimeParam> for_lifetimes; if (lexer.peek_token ()->get_id () == FOR) - { for_lifetimes = parse_for_lifetimes (); - } // handle TypePath AST::TypePath type_path = parse_type_path (); @@ -6359,9 +6359,8 @@ Parser<ManagedTokenSource>::parse_path_in_expression () segments.shrink_to_fit (); - return AST::PathInExpression (std::move (segments), locus, - has_opening_scope_resolution, - std::vector<AST::Attribute> ()); + return AST::PathInExpression (std::move (segments), {}, locus, + has_opening_scope_resolution); } /* Parses a single path in expression path segment (including generic @@ -6474,8 +6473,7 @@ Parser<ManagedTokenSource>::parse_qualified_path_in_expression ( // FIXME: outer attr parsing return AST::QualifiedPathInExpression (std::move (qual_path_type), - std::move (segments), locus, - std::vector<AST::Attribute> ()); + std::move (segments), {}, locus); } // Parses the type syntactical construction at the start of a qualified path. @@ -7375,8 +7373,8 @@ Parser<ManagedTokenSource>::parse_literal_expr ( // create literal based on stuff in switch return std::unique_ptr<AST::LiteralExpr> ( new AST::LiteralExpr (std::move (literal_value), std::move (type), - t->get_type_hint (), t->get_locus (), - std::move (outer_attrs))); + t->get_type_hint (), std::move (outer_attrs), + t->get_locus ())); } // Parses a return expression (including any expression to return). @@ -7406,8 +7404,8 @@ Parser<ManagedTokenSource>::parse_return_expr ( = parse_expr (std::vector<AST::Attribute> (), restrictions); return std::unique_ptr<AST::ReturnExpr> ( - new AST::ReturnExpr (locus, std::move (returned_expr), - std::move (outer_attrs))); + new AST::ReturnExpr (std::move (returned_expr), std::move (outer_attrs), + locus)); } /* Parses a break expression (including any label to break to AND any return @@ -7445,8 +7443,8 @@ Parser<ManagedTokenSource>::parse_break_expr ( = parse_expr (std::vector<AST::Attribute> (), restrictions); return std::unique_ptr<AST::BreakExpr> ( - new AST::BreakExpr (locus, std::move (label), std::move (return_expr), - std::move (outer_attrs))); + new AST::BreakExpr (std::move (label), std::move (return_expr), + std::move (outer_attrs), locus)); } // Parses a continue expression (including any label to continue from). @@ -7477,7 +7475,7 @@ Parser<ManagedTokenSource>::parse_continue_expr ( } return std::unique_ptr<AST::ContinueExpr> ( - new AST::ContinueExpr (locus, std::move (label), std::move (outer_attrs))); + new AST::ContinueExpr (std::move (label), std::move (outer_attrs), locus)); } // Parses a loop label used in loop expressions. @@ -7511,7 +7509,7 @@ Parser<ManagedTokenSource>::parse_loop_label () template <typename ManagedTokenSource> std::unique_ptr<AST::IfExpr> Parser<ManagedTokenSource>::parse_if_expr ( - std::vector<AST::Attribute> outer_attrs ATTRIBUTE_UNUSED, bool pratt_parse) + std::vector<AST::Attribute> outer_attrs, bool pratt_parse) { // TODO: make having outer attributes an error? Location locus = Linemap::unknown_location (); @@ -7543,8 +7541,7 @@ Parser<ManagedTokenSource>::parse_if_expr ( * parsed */ ParseRestrictions no_struct_expr; no_struct_expr.can_be_struct_expr = false; - std::unique_ptr<AST::Expr> condition - = parse_expr (std::vector<AST::Attribute> (), no_struct_expr); + std::unique_ptr<AST::Expr> condition = parse_expr ({}, no_struct_expr); if (condition == nullptr) { rust_error_at (lexer.peek_token ()->get_locus (), @@ -7569,7 +7566,8 @@ Parser<ManagedTokenSource>::parse_if_expr ( { // single selection - end of if expression return std::unique_ptr<AST::IfExpr> ( - new AST::IfExpr (std::move (condition), std::move (if_body), locus)); + new AST::IfExpr (std::move (condition), std::move (if_body), + std::move (outer_attrs), locus)); } else { @@ -7598,7 +7596,8 @@ Parser<ManagedTokenSource>::parse_if_expr ( return std::unique_ptr<AST::IfExprConseqElse> ( new AST::IfExprConseqElse (std::move (condition), std::move (if_body), - std::move (else_body), locus)); + std::move (else_body), + std::move (outer_attrs), locus)); } case IF: { // multiple selection - else if or else if let @@ -7620,7 +7619,8 @@ Parser<ManagedTokenSource>::parse_if_expr ( return std::unique_ptr<AST::IfExprConseqIfLet> ( new AST::IfExprConseqIfLet (std::move (condition), std::move (if_body), - std::move (if_let_expr), locus)); + std::move (if_let_expr), + std::move (outer_attrs), locus)); } else { @@ -7638,7 +7638,8 @@ Parser<ManagedTokenSource>::parse_if_expr ( return std::unique_ptr<AST::IfExprConseqIf> ( new AST::IfExprConseqIf (std::move (condition), std::move (if_body), - std::move (if_expr), locus)); + std::move (if_expr), + std::move (outer_attrs), locus)); } } default: @@ -7658,7 +7659,7 @@ Parser<ManagedTokenSource>::parse_if_expr ( template <typename ManagedTokenSource> std::unique_ptr<AST::IfLetExpr> Parser<ManagedTokenSource>::parse_if_let_expr ( - std::vector<AST::Attribute> outer_attrs ATTRIBUTE_UNUSED, bool pratt_parse) + std::vector<AST::Attribute> outer_attrs, bool pratt_parse) { // TODO: make having outer attributes an error? Location locus = Linemap::unknown_location (); @@ -7708,8 +7709,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr ( // parse expression (required) - HACK to prevent struct expr being parsed ParseRestrictions no_struct_expr; no_struct_expr.can_be_struct_expr = false; - std::unique_ptr<AST::Expr> scrutinee_expr - = parse_expr (std::vector<AST::Attribute> (), no_struct_expr); + std::unique_ptr<AST::Expr> scrutinee_expr = parse_expr ({}, no_struct_expr); if (scrutinee_expr == nullptr) { rust_error_at ( @@ -7739,7 +7739,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr ( return std::unique_ptr<AST::IfLetExpr> ( new AST::IfLetExpr (std::move (match_arm_patterns), std::move (scrutinee_expr), std::move (if_let_body), - locus)); + std::move (outer_attrs), locus)); } else { @@ -7769,7 +7769,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr ( new AST::IfLetExprConseqElse (std::move (match_arm_patterns), std::move (scrutinee_expr), std::move (if_let_body), - std::move (else_body), locus)); + std::move (else_body), + std::move (outer_attrs), locus)); } case IF: { // multiple selection - else if or else if let @@ -7791,7 +7792,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr ( return std::unique_ptr<AST::IfLetExprConseqIfLet> ( new AST::IfLetExprConseqIfLet ( std::move (match_arm_patterns), std::move (scrutinee_expr), - std::move (if_let_body), std::move (if_let_expr), locus)); + std::move (if_let_body), std::move (if_let_expr), + std::move (outer_attrs), locus)); } else { @@ -7810,7 +7812,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr ( new AST::IfLetExprConseqIf (std::move (match_arm_patterns), std::move (scrutinee_expr), std::move (if_let_body), - std::move (if_expr), locus)); + std::move (if_expr), + std::move (outer_attrs), locus)); } } default: @@ -8887,10 +8890,10 @@ Parser<ManagedTokenSource>::parse_type () AST::DelimTokenTree tok_tree = parse_delim_token_tree (); return std::unique_ptr<AST::MacroInvocation> ( - new AST::MacroInvocation (std::move (macro_path), - std::move (tok_tree), - std::vector<AST::Attribute> (), - locus)); + new AST::MacroInvocation ( + AST::MacroInvocData (std::move (macro_path), + std::move (tok_tree)), + {}, locus)); } case PLUS: { // type param bounds @@ -9690,10 +9693,10 @@ Parser<ManagedTokenSource>::parse_type_no_bounds () AST::DelimTokenTree tok_tree = parse_delim_token_tree (); return std::unique_ptr<AST::MacroInvocation> ( - new AST::MacroInvocation (std::move (macro_path), - std::move (tok_tree), - std::vector<AST::Attribute> (), - locus)); + new AST::MacroInvocation ( + AST::MacroInvocData (std::move (macro_path), + std::move (tok_tree)), + {}, locus)); } case PLUS: { // type param bounds - not allowed, here for error message @@ -11465,25 +11468,25 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr ( * fixed up via HACKs in semantic analysis (by checking whether it * is the last elem in the vector). */ + AST::DelimTokenTree delim_tok_tree (type, std::move (token_trees), + tok_tree_loc); + AST::MacroInvocData invoc_data (std::move (macro_path), + std::move (delim_tok_tree)); + if (lexer.peek_token ()->get_id () == SEMICOLON) { lexer.skip_token (); std::unique_ptr<AST::MacroInvocationSemi> stmt ( - new AST::MacroInvocationSemi (std::move (macro_path), type, - std::move (token_trees), + new AST::MacroInvocationSemi (std::move (invoc_data), std::move (outer_attrs), stmt_or_expr_loc)); return ExprOrStmt (std::move (stmt)); } // otherwise, create macro invocation - AST::DelimTokenTree delim_tok_tree (type, std::move (token_trees), - tok_tree_loc); - std::unique_ptr<AST::MacroInvocation> expr ( - new AST::MacroInvocation (std::move (macro_path), - std::move (delim_tok_tree), + new AST::MacroInvocation (std::move (invoc_data), std::move (outer_attrs), stmt_or_expr_loc)); return ExprOrStmt (std::move (expr)); @@ -11491,14 +11494,12 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr ( else { // tokens don't match opening delimiters, so produce error - rust_error_at (t2->get_locus (), - "unexpected token %qs - expecting closing " - "delimiter %qs (for a " - "macro invocation)", - t2->get_token_description (), - (type == AST::PARENS - ? ")" - : (type == AST::SQUARE ? "]" : "}"))); + rust_error_at ( + t2->get_locus (), + "unexpected token %qs - expecting closing delimiter %qs (for a " + "macro invocation)", + t2->get_token_description (), + (type == AST::PARENS ? ")" : (type == AST::SQUARE ? "]" : "}"))); return ExprOrStmt::create_error (); } } @@ -11535,7 +11536,7 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr ( // lexer.skip_token(); // HACK: add outer attrs to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); expr = std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -11586,7 +11587,7 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr ( // lexer.skip_token(); // HACK: replace outer attributes in path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); std::unique_ptr<AST::PathInExpression> expr ( new AST::PathInExpression (std::move (path))); @@ -11765,25 +11766,25 @@ Parser<ManagedTokenSource>::parse_macro_invocation_maybe_semi ( * HACKs in semantic analysis (by checking whether it is the last elem in * the vector). */ + AST::DelimTokenTree delim_tok_tree (type, std::move (token_trees), + tok_tree_loc); + AST::MacroInvocData invoc_data (std::move (macro_path), + std::move (delim_tok_tree)); + if (lexer.peek_token ()->get_id () == SEMICOLON) { lexer.skip_token (); std::unique_ptr<AST::MacroInvocationSemi> stmt ( - new AST::MacroInvocationSemi (std::move (macro_path), type, - std::move (token_trees), + new AST::MacroInvocationSemi (std::move (invoc_data), std::move (outer_attrs), macro_locus)); return ExprOrStmt (std::move (stmt)); } // otherwise, create macro invocation - AST::DelimTokenTree delim_tok_tree (type, std::move (token_trees), - tok_tree_loc); - std::unique_ptr<AST::MacroInvocation> expr ( - new AST::MacroInvocation (std::move (macro_path), - std::move (delim_tok_tree), + new AST::MacroInvocation (std::move (invoc_data), std::move (outer_attrs), macro_locus)); return ExprOrStmt (std::move (expr)); } @@ -12095,11 +12096,11 @@ Parser<ManagedTokenSource>::null_denotation ( /* HACK: may have to become permanent, but this is my * current identifier expression */ return std::unique_ptr<AST::IdentifierExpr> ( - new AST::IdentifierExpr (tok->get_str (), + new AST::IdentifierExpr (tok->get_str (), {}, tok->get_locus ())); } // HACK: add outer attrs to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -12117,11 +12118,11 @@ Parser<ManagedTokenSource>::null_denotation ( /* HACK: may have to become permanent, but this is my * current identifier expression */ return std::unique_ptr<AST::IdentifierExpr> ( - new AST::IdentifierExpr (tok->get_str (), + new AST::IdentifierExpr (tok->get_str (), {}, tok->get_locus ())); } // HACK: add outer attrs to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -12135,10 +12136,11 @@ Parser<ManagedTokenSource>::null_denotation ( /* HACK: may have to become permanent, but this is my current * identifier expression */ return std::unique_ptr<AST::IdentifierExpr> ( - new AST::IdentifierExpr (tok->get_str (), tok->get_locus ())); + new AST::IdentifierExpr (tok->get_str (), {}, + tok->get_locus ())); } // HACK: add outer attrs to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -12153,33 +12155,35 @@ Parser<ManagedTokenSource>::null_denotation ( // HACK: add outer attrs to path AST::QualifiedPathInExpression path = parse_qualified_path_in_expression (true); - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::QualifiedPathInExpression> ( new AST::QualifiedPathInExpression (std::move (path))); } + // FIXME: for literal exprs, should outer attrs be passed in or just + // ignored? case INT_LITERAL: // we should check the range, but ignore for now // encode as int? return std::unique_ptr<AST::LiteralExpr> ( new AST::LiteralExpr (tok->get_str (), AST::Literal::INT, - tok->get_type_hint (), tok->get_locus ())); + tok->get_type_hint (), {}, tok->get_locus ())); case FLOAT_LITERAL: // encode as float? return std::unique_ptr<AST::LiteralExpr> ( new AST::LiteralExpr (tok->get_str (), AST::Literal::FLOAT, - tok->get_type_hint (), tok->get_locus ())); + tok->get_type_hint (), {}, tok->get_locus ())); case STRING_LITERAL: return std::unique_ptr<AST::LiteralExpr> ( new AST::LiteralExpr (tok->get_str (), AST::Literal::STRING, - tok->get_type_hint (), tok->get_locus ())); + tok->get_type_hint (), {}, tok->get_locus ())); case TRUE_LITERAL: return std::unique_ptr<AST::LiteralExpr> ( new AST::LiteralExpr ("true", AST::Literal::BOOL, tok->get_type_hint (), - tok->get_locus ())); + {}, tok->get_locus ())); case FALSE_LITERAL: return std::unique_ptr<AST::LiteralExpr> ( new AST::LiteralExpr ("false", AST::Literal::BOOL, - tok->get_type_hint (), tok->get_locus ())); + tok->get_type_hint (), {}, tok->get_locus ())); case LEFT_PAREN: { // have to parse whole expression if inside brackets /* recursively invoke parse_expression with lowest priority possible as * it it were a top-level expression. */ @@ -12218,8 +12222,7 @@ Parser<ManagedTokenSource>::null_denotation ( ParseRestrictions entered_from_unary; entered_from_unary.entered_from_unary = true; std::unique_ptr<AST::Expr> expr - = parse_expr (LBP_UNARY_MINUS, std::vector<AST::Attribute> (), - entered_from_unary); + = parse_expr (LBP_UNARY_MINUS, {}, entered_from_unary); if (expr == nullptr) return nullptr; @@ -12243,8 +12246,7 @@ Parser<ManagedTokenSource>::null_denotation ( ParseRestrictions entered_from_unary; entered_from_unary.entered_from_unary = true; std::unique_ptr<AST::Expr> expr - = parse_expr (LBP_UNARY_EXCLAM, std::vector<AST::Attribute> (), - entered_from_unary); + = parse_expr (LBP_UNARY_EXCLAM, {}, entered_from_unary); if (expr == nullptr) return nullptr; @@ -12270,8 +12272,7 @@ Parser<ManagedTokenSource>::null_denotation ( entered_from_unary.entered_from_unary = true; entered_from_unary.can_be_struct_expr = false; std::unique_ptr<AST::Expr> expr - = parse_expr (LBP_UNARY_ASTERISK, std::vector<AST::Attribute> (), - entered_from_unary); + = parse_expr (LBP_UNARY_ASTERISK, {}, entered_from_unary); // FIXME: allow outer attributes on expression return std::unique_ptr<AST::DereferenceExpr> ( new AST::DereferenceExpr (std::move (expr), std::move (outer_attrs), @@ -12291,15 +12292,12 @@ Parser<ManagedTokenSource>::null_denotation ( if (lexer.peek_token ()->get_id () == MUT) { lexer.skip_token (); - expr - = parse_expr (LBP_UNARY_AMP_MUT, std::vector<AST::Attribute> (), - entered_from_unary); + expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary); is_mut_borrow = true; } else { - expr = parse_expr (LBP_UNARY_AMP, std::vector<AST::Attribute> (), - entered_from_unary); + expr = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary); } // FIXME: allow outer attributes on expression @@ -12318,15 +12316,12 @@ Parser<ManagedTokenSource>::null_denotation ( if (lexer.peek_token ()->get_id () == MUT) { lexer.skip_token (); - expr - = parse_expr (LBP_UNARY_AMP_MUT, std::vector<AST::Attribute> (), - entered_from_unary); + expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary); is_mut_borrow = true; } else { - expr = parse_expr (LBP_UNARY_AMP, std::vector<AST::Attribute> (), - entered_from_unary); + expr = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary); } // FIXME: allow outer attributes on expression @@ -12364,7 +12359,7 @@ Parser<ManagedTokenSource>::null_denotation ( if (tok->get_id () == SELF && path.is_single_segment ()) { // HACK: add outer attrs to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -12394,7 +12389,7 @@ Parser<ManagedTokenSource>::null_denotation ( { // assume path is returned // HACK: add outer attributes to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -12407,7 +12402,7 @@ Parser<ManagedTokenSource>::null_denotation ( { // assume path is returned // HACK: add outer attributes to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -12416,7 +12411,7 @@ Parser<ManagedTokenSource>::null_denotation ( default: // assume path is returned // HACK: add outer attributes to path - path.replace_outer_attrs (std::move (outer_attrs)); + path.set_outer_attrs (std::move (outer_attrs)); return std::unique_ptr<AST::PathInExpression> ( new AST::PathInExpression (std::move (path))); } @@ -14011,7 +14006,8 @@ Parser<ManagedTokenSource>::parse_macro_invocation_partial ( Location macro_locus = converted_path.get_locus (); return std::unique_ptr<AST::MacroInvocation> ( - new AST::MacroInvocation (std::move (converted_path), std::move (tok_tree), + new AST::MacroInvocation (AST::MacroInvocData (std::move (converted_path), + std::move (tok_tree)), std::move (outer_attrs), macro_locus)); } @@ -14178,9 +14174,8 @@ Parser<ManagedTokenSource>::parse_struct_expr_tuple_partial ( exprs.push_back (std::move (expr)); if (lexer.peek_token ()->get_id () != COMMA) - { - break; - } + break; + lexer.skip_token (); t = lexer.peek_token (); @@ -14306,7 +14301,8 @@ Parser<ManagedTokenSource>::parse_path_in_expression_pratt (const_TokenPtr tok) "current token (just about to return path to null denotation): '%s'\n", lexer.peek_token ()->get_token_description ()); - return AST::PathInExpression (std::move (segments), tok->get_locus (), false); + return AST::PathInExpression (std::move (segments), {}, tok->get_locus (), + false); } // Parses a closure expression with pratt parsing (from null denotation). diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index 213d141..4f7382a 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -360,7 +360,7 @@ ResolveStructExprField::visit (AST::StructExprFieldIndexValue &field) void ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field) { - AST::IdentifierExpr expr (field.get_field_name (), field.get_locus ()); + AST::IdentifierExpr expr (field.get_field_name (), {}, field.get_locus ()); expr.set_node_id (field.get_node_id ()); ResolveExpr::go (&expr, field.get_node_id ()); diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 6960556..b8742fb 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -366,8 +366,11 @@ Session::enable_dump (std::string arg) { if (arg.empty ()) { - rust_error_at (Location (), "dump option was not given a name. choose " - "%<lex%>, %<parse%>, or %<target_options%>"); + rust_error_at ( + Location (), + "dump option was not given a name. choose %<lex%>, %<parse%>, " + "%<register_plugins%>, %<injection%>, %<expansion%>, %<resolution%>," + " %<target_options%>, %<hir%>, or %<all%>"); return false; } @@ -401,11 +404,6 @@ Session::enable_dump (std::string arg) } else if (arg == "target_options") { - // special case - dump all target options, and then quit compilation - // nope, option handling called before init, so have to make this an - // actual compile option - // options.target_data.dump_target_options(); - // return false; options.enable_dump_option (CompileOptions::TARGET_OPTION_DUMP); } else if (arg == "hir") @@ -416,8 +414,9 @@ Session::enable_dump (std::string arg) { rust_error_at ( Location (), - "dump option %qs was unrecognised. choose %<lex%>, %<parse%>, or " - "%<target_options%>", + "dump option %qs was unrecognised. choose %<lex%>, %<parse%>, " + "%<register_plugins%>, %<injection%>, %<expansion%>, %<resolution%>," + " %<target_options%>, or %<hir%>", arg.c_str ()); return false; } |