aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/analysis/rust-scan.cc2
-rw-r--r--gcc/rust/analysis/rust-type-resolution.cc36
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc50
-rw-r--r--gcc/rust/ast/rust-expr.h93
-rw-r--r--gcc/rust/ast/rust-item.h37
-rw-r--r--gcc/rust/backend/rust-compile.cc34
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc143
-rw-r--r--gcc/rust/parse/rust-parse-impl.h4
8 files changed, 316 insertions, 83 deletions
diff --git a/gcc/rust/analysis/rust-scan.cc b/gcc/rust/analysis/rust-scan.cc
index 402ac32..31c89e4 100644
--- a/gcc/rust/analysis/rust-scan.cc
+++ b/gcc/rust/analysis/rust-scan.cc
@@ -353,7 +353,7 @@ TopLevelScan::visit (AST::UseDeclaration &use_decl)
void
TopLevelScan::visit (AST::Function &function)
{
- functions[function.function_name] = &function;
+ functions[function.get_function_name ()] = &function;
}
void
diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc
index fcf475e..c3a5587 100644
--- a/gcc/rust/analysis/rust-type-resolution.cc
+++ b/gcc/rust/analysis/rust-type-resolution.cc
@@ -471,7 +471,7 @@ TypeResolution::visit (AST::StructExprStructFields &expr)
AST::StructField *declField = NULL;
for (auto &df : decl->get_fields ())
{
- if (identifierBuffer->compare (df.field_name) == 0)
+ if (identifierBuffer->compare (df.get_field_name ()) == 0)
{
declField = &df;
break;
@@ -485,7 +485,7 @@ TypeResolution::visit (AST::StructExprStructFields &expr)
return;
}
- if (!typesAreCompatible (declField->field_type.get (), inferedType,
+ if (!typesAreCompatible (declField->get_field_type ().get (), inferedType,
expr.get_locus_slow ()))
return;
}
@@ -505,7 +505,7 @@ TypeResolution::visit (AST::StructExprStructFields &expr)
return;
}
- if (!typesAreCompatible (declField->field_type.get (), inferedType,
+ if (!typesAreCompatible (declField->get_field_type ().get (), inferedType,
expr.get_locus_slow ()))
return;
}
@@ -561,41 +561,41 @@ void
TypeResolution::visit (AST::CallExpr &expr)
{
// this look up should probably be moved to name resolution
- auto fndecl = lookupFndecl (expr.function.get ());
+ auto fndecl = lookupFndecl (expr.get_function_expr ().get ());
if (fndecl == NULL)
return;
// check num args match
- if (fndecl->function_params.size () != expr.params.size ())
+ if (fndecl->get_function_params ().size () != expr.get_params ().size ())
{
rust_error_at (expr.get_locus_slow (),
"differing number of arguments vs parameters to function");
return;
}
- typeBuffer.push_back (fndecl->return_type.get ());
+ typeBuffer.push_back (fndecl->get_return_type ().get ());
expr.fndeclRef = fndecl;
auto before = typeBuffer.size ();
- for (auto &item : expr.params)
+ for (auto &item : expr.get_params ())
item->accept_vis (*this);
auto numInferedParams = typeBuffer.size () - before;
- if (numInferedParams != expr.params.size ())
+ if (numInferedParams != expr.get_params ().size ())
{
rust_error_at (expr.get_locus (), "Failed to infer all parameters");
return;
}
auto offs = numInferedParams - 1;
- for (auto it = fndecl->function_params.rbegin ();
- it != fndecl->function_params.rend (); ++it)
+ for (auto it = fndecl->get_function_params ().rbegin ();
+ it != fndecl->get_function_params ().rend (); ++it)
{
AST::Type *argument = typeBuffer.back ();
typeBuffer.pop_back ();
if (!typesAreCompatible (it->type.get (), argument,
- expr.params[offs]->get_locus_slow ()))
+ expr.get_params ()[offs]->get_locus_slow ()))
return;
offs--;
}
@@ -762,11 +762,11 @@ TypeResolution::visit (AST::Function &function)
{
// always emit the function with return type in the event of nil return type
// its a marker for a void function
- scope.InsertType (function.function_name, function.return_type.get ());
- scope.InsertFunction (function.function_name, &function);
+ scope.InsertType (function.get_function_name (), function.get_return_type ().get ());
+ scope.InsertFunction (function.get_function_name (), &function);
scope.Push ();
- for (auto &param : function.function_params)
+ for (auto &param : function.get_function_params ())
{
if (!isTypeInScope (param.type.get (), param.get_locus ()))
return;
@@ -787,12 +787,12 @@ TypeResolution::visit (AST::Function &function)
// ensure the return type is resolved
if (function.has_function_return_type ())
{
- if (!isTypeInScope (function.return_type.get (), function.get_locus ()))
+ if (!isTypeInScope (function.get_return_type ().get (), function.get_locus ()))
return;
}
// walk the expression body
- for (auto &stmt : function.function_body->statements)
+ for (auto &stmt : function.get_definition ()->statements)
{
stmt->accept_vis (*this);
}
@@ -813,7 +813,7 @@ TypeResolution::visit (AST::StructStruct &struct_item)
{
for (auto &field : struct_item.get_fields ())
{
- if (!isTypeInScope (field.field_type.get (),
+ if (!isTypeInScope (field.get_field_type ().get (),
Linemap::unknown_location ()))
{
rust_fatal_error (Linemap::unknown_location (),
@@ -822,7 +822,7 @@ TypeResolution::visit (AST::StructStruct &struct_item)
}
}
- scope.InsertStruct (struct_item.struct_name, &struct_item);
+ scope.InsertStruct (struct_item.get_struct_name (), &struct_item);
}
void
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index 8071226..f9dd99c 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -3721,9 +3721,7 @@ StructExprTuple::as_string () const
/* 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 ();
- }
}
indent_spaces (out);
indent_spaces (out);
@@ -3749,9 +3747,7 @@ StructExprStruct::as_string () const
/* 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 ();
- }
}
return str;
@@ -3761,13 +3757,9 @@ std::string
StructBase::as_string () const
{
if (base_struct != nullptr)
- {
return base_struct->as_string ();
- }
else
- {
return "ERROR_MARK_STRING - invalid struct base had as string applied";
- }
}
std::string
@@ -3802,25 +3794,59 @@ StructExprStructFields::as_string () const
else
{
for (const auto &field : fields)
- {
str += "\n " + field->as_string ();
- }
}
str += "\n Struct base: ";
if (!has_struct_base ())
+ str += "none";
+ else
+ str += struct_base.as_string ();
+
+ return str;
+}
+
+std::string
+EnumExprStruct::as_string () const
+{
+ std::string str ("StructExprStruct (or subclass): ");
+
+ str += "\n Path: " + get_enum_variant_path ().as_string ();
+
+ str += "\n Fields: ";
+ if (fields.empty ())
{
str += "none";
}
else
{
- str += struct_base.as_string ();
+ for (const auto &field : fields)
+ str += "\n " + field->as_string ();
}
return str;
}
std::string
+EnumExprFieldWithVal::as_string () const
+{
+ // used to get value string
+ return value->as_string ();
+}
+
+std::string
+EnumExprFieldIdentifierValue::as_string () const
+{
+ return field_name + " : " + EnumExprFieldWithVal::as_string ();
+}
+
+std::string
+EnumExprFieldIndexValue::as_string () const
+{
+ return std::to_string (index) + " : " + EnumExprFieldWithVal::as_string ();
+}
+
+std::string
EnumItem::as_string () const
{
// outer attributes
@@ -3834,9 +3860,7 @@ EnumItem::as_string () const
/* 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 += "\n" + variant_name;
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 1cf8f9c..6f68542 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -1849,6 +1849,8 @@ public:
return std::unique_ptr<EnumExprField> (clone_enum_expr_field_impl ());
}
+ virtual std::string as_string () const = 0;
+
virtual void accept_vis (ASTVisitor &vis) = 0;
protected:
@@ -1870,6 +1872,8 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ std::string as_string () const override { return field_name; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1908,6 +1912,15 @@ protected:
// move constructors
EnumExprFieldWithVal (EnumExprFieldWithVal &&other) = default;
EnumExprFieldWithVal &operator= (EnumExprFieldWithVal &&other) = default;
+
+public:
+ std::string as_string () const override;
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Expr> &get_value () {
+ rust_assert (value != nullptr);
+ return value;
+ }
};
// Identifier and value variant of EnumExprField AST node
@@ -1924,6 +1937,8 @@ public:
field_name (std::move (field_name))
{}
+ std::string as_string () const override;
+
void accept_vis (ASTVisitor &vis) override;
protected:
@@ -1949,6 +1964,8 @@ public:
: EnumExprFieldWithVal (std::move (field_value)), index (field_index)
{}
+ std::string as_string () const override;
+
void accept_vis (ASTVisitor &vis) override;
protected:
@@ -1971,10 +1988,6 @@ class EnumExprStruct : public EnumVariantExpr
public:
std::string as_string () const override;
- /*inline std::vector<std::unique_ptr<EnumExprField>> get_fields() const
- { return fields;
- }*/
-
EnumExprStruct (PathInExpression enum_variant_path,
std::vector<std::unique_ptr<EnumExprField> > variant_fields,
std::vector<Attribute> outer_attribs, Location locus)
@@ -2037,10 +2050,6 @@ class EnumExprTuple : public EnumVariantExpr
public:
std::string as_string () const override;
- /*inline std::vector<std::unique_ptr<Expr>> get_values() const {
- return values;
- }*/
-
EnumExprTuple (PathInExpression enum_variant_path,
std::vector<std::unique_ptr<Expr> > variant_values,
std::vector<Attribute> outer_attribs, Location locus)
@@ -2080,6 +2089,9 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ const std::vector<std::unique_ptr<Expr> > &get_elems () const { return values; }
+ std::vector<std::unique_ptr<Expr> > &get_elems () { return values; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2128,21 +2140,17 @@ class Function;
// Function call expression AST node
class CallExpr : public ExprWithoutBlock
{
-public:
std::unique_ptr<Expr> function;
// inlined form of CallParams
std::vector<std::unique_ptr<Expr> > params;
Location locus;
+public:
Function *fndeclRef;
std::string as_string () const override;
- /*inline std::vector<std::unique_ptr<Expr>> get_params() const {
- return params;
- }*/
-
CallExpr (std::unique_ptr<Expr> function_expr,
std::vector<std::unique_ptr<Expr> > function_params,
std::vector<Attribute> outer_attribs, Location locus)
@@ -2199,6 +2207,16 @@ public:
void mark_for_strip () override { function = nullptr; }
bool is_marked_for_strip () const override { return function == nullptr; }
+ // TODO: this mutable getter seems really dodgy. Think up better way.
+ const std::vector<std::unique_ptr<Expr> > &get_params () const { return params; }
+ std::vector<std::unique_ptr<Expr> > &get_params () { return params; }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Expr> &get_function_expr () {
+ rust_assert (function != nullptr);
+ return function;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2221,10 +2239,6 @@ class MethodCallExpr : public ExprWithoutBlock
public:
std::string as_string () const override;
- /*inline std::vector<std::unique_ptr<Expr>> get_params() const {
- return params;
- }*/
-
MethodCallExpr (std::unique_ptr<Expr> call_receiver,
PathExprSegment method_path,
std::vector<std::unique_ptr<Expr> > method_params,
@@ -2281,6 +2295,18 @@ public:
void mark_for_strip () override { receiver = nullptr; }
bool is_marked_for_strip () const override { return receiver == nullptr; }
+ // TODO: this mutable getter seems really dodgy. Think up better way.
+ const std::vector<std::unique_ptr<Expr> > &get_params () const { return params; }
+ std::vector<std::unique_ptr<Expr> > &get_params () { return params; }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Expr> &get_receiver_expr () {
+ rust_assert (receiver != nullptr);
+ return receiver;
+ }
+
+ PathExprSegment get_method_name () const { return method_name; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2349,6 +2375,14 @@ public:
void mark_for_strip () override { receiver = nullptr; }
bool is_marked_for_strip () const override { return receiver == nullptr; }
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Expr> &get_receiver_expr () {
+ rust_assert (receiver != nullptr);
+ return receiver;
+ }
+
+ Identifier get_field_name () const { return field; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2362,6 +2396,7 @@ protected:
struct ClosureParam
{
private:
+ std::vector<Attribute> outer_attrs;
std::unique_ptr<Pattern> pattern;
// bool has_type_given;
@@ -2373,15 +2408,18 @@ public:
// Returns whether the type of the parameter has been given.
bool has_type_given () const { return type != nullptr; }
+ bool has_outer_attrs () const { return !outer_attrs.empty (); }
+
// Constructor for closure parameter
ClosureParam (std::unique_ptr<Pattern> param_pattern,
- std::unique_ptr<Type> param_type = nullptr)
- : pattern (std::move (param_pattern)), type (std::move (param_type))
+ std::unique_ptr<Type> param_type = nullptr, std::vector<Attribute> outer_attrs = {})
+ : outer_attrs (std::move(outer_attrs)), pattern (std::move (param_pattern)),
+ type (std::move (param_type))
{}
// Copy constructor required due to cloning as a result of unique_ptrs
ClosureParam (ClosureParam const &other)
- : pattern (other.pattern->clone_pattern ())
+ : outer_attrs (other.outer_attrs)
{
// guard to protect from null pointer dereference
if (other.pattern != nullptr)
@@ -2395,6 +2433,8 @@ public:
// Assignment operator must be overloaded to clone as well
ClosureParam &operator= (ClosureParam const &other)
{
+ outer_attrs = other.outer_attrs;
+
// guard to protect from null pointer dereference
if (other.pattern != nullptr)
pattern = other.pattern->clone_pattern ();
@@ -2419,6 +2459,9 @@ public:
static ClosureParam create_error () { return ClosureParam (nullptr); }
std::string as_string () const;
+
+ const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
+ std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
};
// Base closure definition expression AST node - abstract
@@ -2443,6 +2486,10 @@ public:
Location get_locus () const { return locus; }
Location get_locus_slow () const 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; }
};
// Represents a non-type-specified closure expression AST node
@@ -2500,6 +2547,12 @@ public:
void mark_for_strip () override { closure_inner = nullptr; }
bool is_marked_for_strip () const override { return closure_inner == nullptr; }
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Expr> &get_definition_expr () {
+ rust_assert (closure_inner != nullptr);
+ return closure_inner;
+ }
+
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 8a85edad..5891383 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1266,7 +1266,6 @@ class LetStmt;
// Rust function declaration AST node
class Function : public VisItem, public InherentImplItem, public TraitImplItem
{
-public:
FunctionQualifiers qualifiers;
Identifier function_name;
@@ -1288,6 +1287,7 @@ public:
Location locus;
+public:
std::vector<LetStmt *> locals;
std::string as_string () const override;
@@ -1396,6 +1396,22 @@ public:
return function_body;
}
+ FunctionQualifiers get_qualifiers () const { return qualifiers; }
+
+ Identifier get_function_name () const { return function_name; }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ WhereClause &get_where_clause () {
+ rust_assert (has_where_clause ());
+ return where_clause;
+ }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Type> &get_return_type () {
+ rust_assert (return_type != nullptr);
+ return return_type;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1518,7 +1534,7 @@ protected:
// Rust base struct declaration AST node - abstract base class
class Struct : public VisItem
{
-public:
+protected:
// protected to enable access by derived classes - allows better as_string
Identifier struct_name;
@@ -1529,8 +1545,10 @@ public:
// bool has_where_clause;
WhereClause where_clause;
+private:
Location locus;
+public:
// Returns whether struct has generic parameters.
bool has_generics () const { return !generic_params.empty (); }
@@ -1543,6 +1561,8 @@ public:
void mark_for_strip () override { struct_name = ""; }
bool is_marked_for_strip () const override { return struct_name.empty (); }
+ Identifier get_struct_name () const { return struct_name; }
+
protected:
Struct (Identifier struct_name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -1587,7 +1607,7 @@ protected:
// A single field in a struct
struct StructField
{
-public:
+private:
// bool has_outer_attributes;
std::vector<Attribute> outer_attrs;
@@ -1599,6 +1619,7 @@ public:
// should this store location info?
+public:
// Returns whether struct field has any outer attributes.
bool has_outer_attributes () const { return !outer_attrs.empty (); }
@@ -1662,6 +1683,16 @@ public:
// TODO: this mutable getter seems really dodgy. Think up better way.
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
+
+ Identifier get_field_name () const { return field_name; }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Type> &get_field_type () {
+ rust_assert (field_type != nullptr);
+ return field_type;
+ }
+
+ Visibility get_visibility () const { return visibility; }
};
// Rust struct declaration with true struct type AST node
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index ca310ca..12ce47f 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -538,7 +538,7 @@ Compilation::visit (AST::StructExprFieldIdentifierValue &field)
bool found = false;
for (auto &df : decl->get_fields ())
{
- if (field.get_field_name ().compare (df.field_name) == 0)
+ if (field.get_field_name ().compare (df.get_field_name ()) == 0)
{
found = true;
break;
@@ -651,15 +651,15 @@ void
Compilation::visit (AST::CallExpr &expr)
{
Bexpression *fn = NULL;
- VISIT_POP (expr.function->get_locus_slow (), expr.function, fn, exprs);
+ VISIT_POP (expr.get_function_expr ()->get_locus_slow (), expr.get_function_expr (), fn, exprs);
if (fn == NULL)
{
- rust_error_at (expr.function->get_locus_slow (), "failed to resolve");
+ rust_error_at (expr.get_function_expr ()->get_locus_slow (), "failed to resolve");
return;
}
std::vector<Bexpression *> args;
- for (auto &param : expr.params)
+ for (auto &param : expr.get_params ())
{
Bexpression *arg = NULL;
VISIT_POP (param->get_locus_slow (), param, arg, exprs);
@@ -949,7 +949,7 @@ Compilation::visit (AST::Function &function)
std::vector<Backend::Btyped_identifier> parameters;
std::vector<Backend::Btyped_identifier> results;
- for (auto &param : function.function_params)
+ for (auto &param : function.get_function_params ())
{
// translate the type
translatedType = NULL;
@@ -983,7 +983,7 @@ Compilation::visit (AST::Function &function)
if (function.has_function_return_type ())
{
translatedType = NULL;
- function.return_type->accept_vis (*this);
+ function.get_return_type ()->accept_vis (*this);
if (translatedType == NULL)
{
rust_fatal_error (function.get_locus (),
@@ -1000,10 +1000,10 @@ Compilation::visit (AST::Function &function)
Btype *fntype = backend->function_type (receiver, parameters, results, NULL,
function.get_locus ());
Bfunction *fndecl
- = backend->function (fntype, function.function_name, "" /* asm_name */,
+ = backend->function (fntype, function.get_function_name (), "" /* asm_name */,
0 /* flags */, function.get_locus ());
- scope.InsertFunction (function.function_name, fndecl, returnType);
+ scope.InsertFunction (function.get_function_name (), fndecl, returnType);
scope.Push ();
// setup the params
@@ -1039,10 +1039,10 @@ Compilation::visit (AST::Function &function)
Bblock *enclosingScope = NULL;
Location start_location = function.get_locus ();
Location end_location;
- if (function.function_body->statements.size () > 0)
+ if (function.get_definition ()->statements.size () > 0)
{
end_location
- = function.function_body->statements.back ()->get_locus_slow ();
+ = function.get_definition ()->statements.back ()->get_locus_slow ();
}
auto code_block = backend->block (fndecl, enclosingScope, vars,
@@ -1060,10 +1060,10 @@ Compilation::visit (AST::Function &function)
function.get_locus (), &ret_var_stmt);
scope.AddStatement (ret_var_stmt);
}
- scope.PushCurrentFunction (function.function_name, fndecl, returnType,
+ scope.PushCurrentFunction (function.get_function_name (), fndecl, returnType,
retDecl);
- for (auto &stmt : function.function_body->statements)
+ for (auto &stmt : function.get_definition ()->statements)
stmt->accept_vis (*this);
scope.PopBlock ();
@@ -1092,7 +1092,7 @@ Compilation::visit (AST::StructStruct &struct_item)
for (auto &field : struct_item.get_fields ())
{
translatedType = NULL;
- field.field_type->accept_vis (*this);
+ field.get_field_type ()->accept_vis (*this);
if (translatedType == NULL)
{
rust_fatal_error (
@@ -1102,12 +1102,12 @@ Compilation::visit (AST::StructStruct &struct_item)
}
fields.push_back (Backend::Btyped_identifier (
- field.field_name, translatedType,
+ field.get_field_name (), translatedType,
struct_item.get_locus () /* StructField is mi sing locus */));
}
auto compiledStruct
- = backend->placeholder_struct_type (struct_item.struct_name,
+ = backend->placeholder_struct_type (struct_item.get_struct_name (),
struct_item.get_locus ());
bool ok = backend->set_placeholder_struct_type (compiledStruct, fields);
if (!ok)
@@ -1117,8 +1117,8 @@ Compilation::visit (AST::StructStruct &struct_item)
}
type_decls.push_back (compiledStruct);
- scope.InsertType (struct_item.struct_name, compiledStruct);
- scope.InsertStructDecl (struct_item.struct_name, &struct_item);
+ scope.InsertType (struct_item.get_struct_name (), compiledStruct);
+ scope.InsertStructDecl (struct_item.get_struct_name (), &struct_item);
}
void
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 65918db..ed5f365 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -512,10 +512,18 @@ namespace Rust {
}
}
void visit(AST::EnumExprFieldIdentifier& field) override {
-
+ // as no attrs (at moment, at least), no stripping possible
+ }
+ void visit(AST::EnumExprFieldIdentifierValue& field) override {
+ /* as no attrs possible (at moment, at least), only sub-expression
+ * stripping is possible */
+ field.get_value()->accept_vis(*this);
+ }
+ void visit(AST::EnumExprFieldIndexValue& field) override {
+ /* as no attrs possible (at moment, at least), only sub-expression
+ * stripping is possible */
+ field.get_value()->accept_vis(*this);
}
- void visit(AST::EnumExprFieldIdentifierValue& field) override {}
- void visit(AST::EnumExprFieldIndexValue& field) override {}
void visit(AST::EnumExprStruct& expr) override {
// initial strip test based on outer attrs
expander.expand_cfg_attrs(expr.get_outer_attrs());
@@ -535,13 +543,128 @@ namespace Rust {
// shouldn't strip in this
}
}
- void visit(AST::EnumExprTuple& expr) override {}
- void visit(AST::EnumExprFieldless& expr) override {}
- void visit(AST::CallExpr& expr) override {}
- void visit(AST::MethodCallExpr& expr) override {}
- void visit(AST::FieldAccessExpr& expr) override {}
- void visit(AST::ClosureExprInner& expr) override {}
- void visit(AST::BlockExpr& expr) override {}
+ void visit(AST::EnumExprTuple& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ // supposedly spec doesn't allow inner attributes in enum exprs
+
+ /* spec 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++;
+ }
+ }
+ void visit(AST::EnumExprFieldless& expr) override {
+ // can't be stripped as no attrs
+ }
+ void visit(AST::CallExpr& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* should not be outer attrs on "function" expression - outer attrs
+ * should be associated with call expr as a whole. only sub-expr
+ * expansion is possible. */
+ expr.get_function_expr()->accept_vis(*this);
+
+ /* spec says outer attributes are specifically allowed for elements
+ * of call expressions, so full stripping possible */
+ auto& params = expr.get_params();
+ for (int i = 0; i < params.size();) {
+ auto& param = params[i];
+
+ // mark for stripping if required
+ param->accept_vis(*this);
+
+ if (param->is_marked_for_strip())
+ params.erase(params.begin() + i);
+ else
+ i++;
+ }
+ }
+ 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())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* should not be outer attrs on "receiver" expression - outer attrs
+ * should be associated with call expr as a whole. only sub-expr
+ * expansion is possible. */
+ expr.get_receiver_expr()->accept_vis(*this);
+
+ // no outer attrs on paths possible
+
+ /* spec says outer attributes are specifically allowed for elements
+ * of method call expressions, so full stripping possible */
+ auto& params = expr.get_params();
+ for (int i = 0; i < params.size();) {
+ auto& param = params[i];
+
+ // mark for stripping if required
+ param->accept_vis(*this);
+
+ if (param->is_marked_for_strip())
+ params.erase(params.begin() + i);
+ else
+ i++;
+ }
+ }
+ 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())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* should not be outer attrs on "receiver" expression - outer attrs
+ * should be associated with call expr as a whole. only sub-expr
+ * expansion is possible. */
+ expr.get_receiver_expr()->accept_vis(*this);
+ }
+ void visit(AST::ClosureExprInner& expr) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(expr.get_outer_attrs());
+ if (expander.fails_cfg(expr.get_outer_attrs())) {
+ expr.mark_for_strip();
+ return;
+ }
+
+ /* strip closure parameters if required - this is specifically
+ * allowed by spec */
+ auto& params = expr.get_params();
+ for (int i = 0; i < params.size();) {
+ auto& param_attrs = params[i].get_outer_attrs();
+ expander.expand_cfg_attrs(param_attrs);
+ if (expander.fails_cfg(param_attrs))
+ params.erase(params.begin() + i);
+ else
+ i++;
+ }
+ }
+ void visit(AST::BlockExpr& expr) override {
+
+ }
void visit(AST::ClosureExprInnerTyped& expr) override {}
void visit(AST::ContinueExpr& expr) override {}
void visit(AST::BreakExpr& expr) override {}
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 1ad997f..769cf41 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -8512,6 +8512,8 @@ template <typename ManagedTokenSource>
AST::ClosureParam
Parser<ManagedTokenSource>::parse_closure_param ()
{
+ std::vector<AST::Attribute> outer_attrs = parse_outer_attributes ();
+
// parse pattern (which is required)
std::unique_ptr<AST::Pattern> pattern = parse_pattern ();
if (pattern == nullptr)
@@ -8537,7 +8539,7 @@ Parser<ManagedTokenSource>::parse_closure_param ()
}
}
- return AST::ClosureParam (std::move (pattern), std::move (type));
+ return AST::ClosureParam (std::move (pattern), std::move (type), std::move (outer_attrs));
}
// Parses a grouped or tuple expression (disambiguates).