aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-11-17 10:12:19 +0000
committerGitHub <noreply@github.com>2022-11-17 10:12:19 +0000
commitd8e9850b7f818f56fcf7e945003556db349db536 (patch)
tree5f1b10cfe1f0b19de58b3451f3e5423e57e8c6c5 /gcc
parent27136db8fd7b428870f6c85ae4b328f54c8de4bb (diff)
parent9527e9985890e30c7687c9482b669e3f5338f9fe (diff)
downloadgcc-d8e9850b7f818f56fcf7e945003556db349db536.zip
gcc-d8e9850b7f818f56fcf7e945003556db349db536.tar.gz
gcc-d8e9850b7f818f56fcf7e945003556db349db536.tar.bz2
Merge #1652
1652: AST dump types r=CohenArthur a=jdupak - \[x] GCC development requires copyright assignment or the Developer's Certificate of Origin sign-off, see https://gcc.gnu.org/contribute.html or https://gcc.gnu.org/dco.html - \[x] Read contributing guidlines - \[x] `make check-rust` passes locally - \[x] Run `clang-format` - N\A - Added any relevant test cases to `gcc/testsuite/rust/` --- Add/fix AST dump of types incl. generic parameters. Co-authored-by: Jakub Dupak <dev@jakubdupak.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-dump.cc370
-rw-r--r--gcc/rust/ast/rust-ast-dump.h5
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc2
-rw-r--r--gcc/rust/ast/rust-type.h22
4 files changed, 361 insertions, 38 deletions
diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 8e2a8c6..131e23e 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -17,7 +17,6 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ast-dump.h"
-#include "rust-diagnostics.h"
namespace Rust {
namespace AST {
@@ -250,6 +249,56 @@ Dump::visit (std::vector<LifetimeParam> &for_lifetimes)
}
void
+Dump::visit (FunctionQualifiers &qualifiers)
+{
+ // Syntax:
+ // `const`? `async`? `unsafe`? (`extern` Abi?)?
+ // unsafe? (extern Abi?)?
+
+ switch (qualifiers.get_const_status ())
+ {
+ case NONE:
+ break;
+ case CONST_FN:
+ stream << "const ";
+ break;
+ case ASYNC_FN:
+ stream << "async ";
+ break;
+ }
+
+ if (qualifiers.is_unsafe ())
+ stream << "unsafe ";
+ if (qualifiers.is_extern ())
+ {
+ stream << "extern ";
+ if (qualifiers.has_abi ())
+ stream << "\"" << qualifiers.get_extern_abi () << "\" ";
+ }
+} // namespace AST
+
+void
+Dump::visit (MaybeNamedParam &param)
+{
+ // Syntax:
+ // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
+
+ visit_items_joined_by_separator (param.get_outer_attrs (), " ");
+ switch (param.get_param_kind ())
+ {
+ case MaybeNamedParam::UNNAMED:
+ break;
+ case MaybeNamedParam::IDENTIFIER:
+ stream << " " << param.get_name () << ": ";
+ break;
+ case MaybeNamedParam::WILDCARD:
+ stream << " _: ";
+ break;
+ }
+ visit (param.get_type ());
+}
+
+void
Dump::visit (Token &tok)
{
stream << tok.as_string ();
@@ -322,21 +371,134 @@ Dump::visit (PathInExpression &path)
}
void
-Dump::visit (TypePathSegment &)
-{}
+Dump::visit (TypePathSegment &segment)
+{
+ // Syntax:
+ // PathIdentSegment
+
+ stream << segment.get_ident_segment ().as_string ();
+}
void
-Dump::visit (TypePathSegmentGeneric &)
-{}
+Dump::visit (TypePathSegmentGeneric &segment)
+{
+ // Syntax:
+ // PathIdentSegment `::`? (GenericArgs)?
+ // GenericArgs :
+ // `<` `>`
+ // | `<` ( GenericArg `,` )* GenericArg `,`? `>`
+
+ stream << segment.get_ident_segment ().as_string ();
+
+ if (segment.get_separating_scope_resolution ())
+ stream << "::";
+
+ stream << "<";
+
+ {
+ // Here we join 3 lists (each possibly empty) with a separator.
+
+ auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
+ auto &generic_args = segment.get_generic_args ().get_generic_args ();
+ auto &binding_args = segment.get_generic_args ().get_binding_args ();
+
+ visit_items_joined_by_separator (lifetime_args, ", ");
+ if (!lifetime_args.empty ()
+ && (!generic_args.empty () || !binding_args.empty ()))
+ {
+ // Insert separator if some items have been already emitted and some
+ // more are to be emitted from any of the following collections.
+ stream << ", ";
+ }
+ visit_items_joined_by_separator (generic_args, ", ");
+ if (!generic_args.empty () && !binding_args.empty ())
+ {
+ // Insert separator if some item vas emitted from the previous
+ // collection and more are to be emitted from the last.
+ stream << ", ";
+ }
+ visit_items_joined_by_separator (binding_args, ", ");
+ }
+
+ stream << ">";
+}
void
-Dump::visit (TypePathSegmentFunction &)
-{}
+Dump::visit (GenericArgsBinding &binding)
+{
+ // Syntax:
+ // IDENTIFIER `=` Type
+
+ stream << binding.get_identifier () << " << ";
+ visit (binding.get_type ());
+}
+
+void
+Dump::visit (GenericArg &arg)
+{
+ // `GenericArg` implements `accept_vis` but it is not useful for this case as
+ // it ignores unresolved cases (`Kind::Either`).
+
+ switch (arg.get_kind ())
+ {
+ case GenericArg::Kind::Const:
+ visit (arg.get_expression ());
+ break;
+ case GenericArg::Kind::Type:
+ visit (arg.get_type ());
+ break;
+ case GenericArg::Kind::Either:
+ stream << arg.get_path ();
+ break;
+ case GenericArg::Kind::Error:
+ gcc_unreachable ();
+ }
+} // namespace AST
+
+void
+Dump::visit (TypePathSegmentFunction &segment)
+{
+ // Syntax:
+ // PathIdentSegment `::`? (TypePathFn)?
+
+ stream << segment.get_ident_segment ().as_string ();
+
+ if (segment.get_separating_scope_resolution ())
+ stream << "::";
+
+ if (!segment.is_ident_only ())
+ visit (segment.get_type_path_function ());
+}
+
+void
+Dump::visit (TypePathFunction &type_path_fn)
+{
+ // Syntax:
+ // `(` TypePathFnInputs? `)` (`->` Type)?
+ // TypePathFnInputs :
+ // Type (`,` Type)* `,`?
+
+ stream << '(';
+ if (type_path_fn.has_inputs ())
+ visit_items_joined_by_separator (type_path_fn.get_params (), ", ");
+ stream << ')';
+
+ if (type_path_fn.has_return_type ())
+ {
+ stream << "->";
+ visit (type_path_fn.get_return_type ());
+ }
+}
void
Dump::visit (TypePath &path)
{
- stream << path.as_string ();
+ // Syntax:
+ // `::`? TypePathSegment (`::` TypePathSegment)*
+
+ if (path.has_opening_scope_resolution_op ())
+ stream << "::";
+ visit_items_joined_by_separator (path.get_segments (), "::");
}
void
@@ -686,7 +848,7 @@ Dump::visit (BlockExpr &expr)
stream << "{\n";
indentation.increment ();
- visit_items_as_lines (expr.get_statements (), "; /* stmt */");
+ visit_items_as_lines (expr.get_statements (), ";");
if (expr.has_tail_expr ())
visit_as_line (expr.get_tail_expr (), " /* tail expr */\n");
@@ -842,7 +1004,17 @@ Dump::visit (AsyncBlockExpr &)
void
Dump::visit (TypeParam &param)
{
+ // Syntax:
+ // IDENTIFIER( : TypeParamBounds? )? ( = Type )?
+ // TypeParamBounds :
+ // TypeParamBound ( + TypeParamBound )* +?
+
stream << param.get_type_representation ();
+ if (param.has_type_param_bounds ())
+ {
+ stream << ": ";
+ visit_items_joined_by_separator (param.get_type_param_bounds (), " + ");
+ }
if (param.has_type ())
{
stream << " = ";
@@ -905,8 +1077,12 @@ Dump::visit (Method &method)
visit (method.get_visibility ());
stream << "fn " << method.get_method_name () << '(';
- stream << method.get_self_param ().as_string () << ", ";
- visit_items_joined_by_separator (method.get_function_params (), ", ");
+ stream << method.get_self_param ().as_string ();
+ if (!method.get_function_params ().empty ())
+ {
+ stream << ", ";
+ visit_items_joined_by_separator (method.get_function_params (), ", ");
+ }
stream << ") ";
@@ -1033,7 +1209,6 @@ Dump::visit (TypeAlias &type_alias)
visit (type_alias.get_where_clause ());
stream << " = ";
visit (type_alias.get_type_aliased ());
- stream << ";\n";
}
void
@@ -1172,9 +1347,13 @@ Dump::visit (TraitItemMethod &item)
// emit_visibility (method.get_visibility ());
stream << "fn " << method.get_identifier () << '(';
- stream << method.get_self_param ().as_string () << ", ";
+ stream << method.get_self_param ().as_string ();
- visit_items_joined_by_separator (method.get_function_params (), ", ");
+ if (!method.get_function_params ().empty ())
+ {
+ stream << ", ";
+ visit_items_joined_by_separator (method.get_function_params (), ", ");
+ }
stream << ") ";
@@ -1560,64 +1739,193 @@ Dump::visit (TraitBound &bound)
}
void
-Dump::visit (ImplTraitType &)
-{}
+Dump::visit (ImplTraitType &type)
+{
+ // Syntax:
+ // impl TypeParamBounds
+ // TypeParamBounds :
+ // TypeParamBound ( + TypeParamBound )* +?
+
+ stream << "impl ";
+ visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
+}
void
-Dump::visit (TraitObjectType &)
-{}
+Dump::visit (TraitObjectType &type)
+{
+ // Syntax:
+ // dyn? TypeParamBounds
+ // TypeParamBounds :
+ // TypeParamBound ( + TypeParamBound )* +?
+
+ if (type.is_dyn ())
+ stream << "dyn ";
+ visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
+}
void
-Dump::visit (ParenthesisedType &)
-{}
+Dump::visit (ParenthesisedType &type)
+{
+ // Syntax:
+ // ( Type )
+
+ stream << "(";
+ visit (type.get_type_in_parens ());
+ stream << ")";
+}
void
-Dump::visit (ImplTraitTypeOneBound &)
-{}
+Dump::visit (ImplTraitTypeOneBound &type)
+{
+ // Syntax:
+ // impl TraitBound
+
+ stream << "impl ";
+ visit (type.get_trait_bound ());
+}
void
-Dump::visit (TraitObjectTypeOneBound &)
-{}
+Dump::visit (TraitObjectTypeOneBound &type)
+{
+ // Syntax:
+ // dyn? TraitBound
+
+ if (type.is_dyn ())
+ stream << "dyn ";
+ visit (type.get_trait_bound ());
+}
void
-Dump::visit (TupleType &)
-{}
+Dump::visit (TupleType &type)
+{
+ // Syntax:
+ // ( )
+ // | ( ( Type , )+ Type? )
+
+ stream << '(';
+ visit_items_joined_by_separator (type.get_elems (), ", ");
+ stream << ')';
+}
void
Dump::visit (NeverType &)
-{}
+{
+ // Syntax:
+ // !
+
+ stream << '!';
+}
void
-Dump::visit (RawPointerType &)
-{}
+Dump::visit (RawPointerType &type)
+{
+ // Syntax:
+ // * ( mut | const ) TypeNoBounds
+
+ if (type.get_pointer_type () == RawPointerType::MUT)
+ stream << "*mut ";
+ else /* RawPointerType::CONST */
+ stream << "*const ";
+
+ visit (type.get_type_pointed_to ());
+}
void
Dump::visit (ReferenceType &type)
{
+ // Syntax:
+ // & Lifetime? mut? TypeNoBounds
+
+ stream << '&';
+
+ if (type.has_lifetime ())
+ {
+ visit (type.get_lifetime ());
+ stream << ' ';
+ }
+
+ if (type.get_has_mut ())
+ stream << "mut ";
+
visit (type.get_type_referenced ());
}
void
Dump::visit (ArrayType &type)
{
+ // Syntax:
+ // [ Type ; Expression ]
+
+ stream << '[';
visit (type.get_elem_type ());
+ stream << "; ";
+ visit (type.get_size_expr ());
+ stream << ']';
}
void
Dump::visit (SliceType &type)
{
+ // Syntax:
+ // [ Type ]
+
+ stream << '[';
visit (type.get_elem_type ());
+ stream << ']';
}
void
Dump::visit (InferredType &)
{
+ // Syntax:
+ // _
+
stream << "_";
}
void
-Dump::visit (BareFunctionType &)
-{}
+Dump::visit (BareFunctionType &type)
+{
+ // Syntax:
+ // ForLifetimes? FunctionTypeQualifiers fn
+ // ( FunctionParametersMaybeNamedVariadic? ) BareFunctionReturnType?
+ //
+ // BareFunctionReturnType:
+ // -> TypeNoBounds
+ //
+ // FunctionParametersMaybeNamedVariadic :
+ // MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic
+ //
+ // MaybeNamedFunctionParameters :
+ // MaybeNamedParam ( , MaybeNamedParam )* ,?
+ //
+ // MaybeNamedFunctionParametersVariadic :
+ // ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
+
+ if (type.has_for_lifetimes ())
+ visit (type.get_for_lifetimes ());
+
+ visit (type.get_function_qualifiers ());
+
+ stream << "fn (";
+
+ visit_items_joined_by_separator (type.get_function_params (), ", ");
+
+ if (type.is_variadic ())
+ {
+ stream << ", ";
+ visit_items_joined_by_separator (type.get_variadic_attr (), " ");
+ stream << "...";
+ }
+
+ stream << ')';
+
+ if (type.has_return_type ())
+ {
+ stream << " -> ";
+ visit (type.get_return_type ());
+ }
+}
} // namespace AST
} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 2bd3b31..4bc322c 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -137,6 +137,11 @@ private:
void visit (MacroRule &rule);
void visit (WhereClause &rule);
void visit (std::vector<LifetimeParam> &for_lifetimes);
+ void visit (FunctionQualifiers &qualifiers);
+ void visit (MaybeNamedParam &param);
+ void visit (TypePathFunction &type_path_fn);
+ void visit (GenericArgsBinding &binding);
+ void visit (GenericArg &arg);
// rust-ast.h
void visit (Token &tok);
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index 1e8a93d..c4df730 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -3071,7 +3071,7 @@ BareFunctionType::as_string () const
}
str += "\n Is variadic: ";
- if (is_variadic)
+ if (_is_variadic)
str += "true";
else
str += "false";
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 8fc3d31..4d435cf 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -835,7 +835,7 @@ public:
};
/* A function pointer type - can be created via coercion from function items and
- * non- capturing closures. */
+ * non-capturing closures. */
class BareFunctionType : public TypeNoBounds
{
// bool has_for_lifetimes;
@@ -844,7 +844,7 @@ class BareFunctionType : public TypeNoBounds
FunctionQualifiers function_qualifiers;
std::vector<MaybeNamedParam> params;
- bool is_variadic;
+ bool _is_variadic;
std::vector<Attribute> variadic_attrs;
// bool has_return_type;
@@ -860,6 +860,16 @@ public:
// Whether the function has ForLifetimes.
bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
+ std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+
+ bool is_variadic () const { return _is_variadic; }
+
+ std::vector<Attribute> &get_variadic_attr () { return variadic_attrs; };
+ const std::vector<Attribute> &get_variadic_attr () const
+ {
+ return variadic_attrs;
+ };
+
BareFunctionType (std::vector<LifetimeParam> lifetime_params,
FunctionQualifiers qualifiers,
std::vector<MaybeNamedParam> named_params, bool is_variadic,
@@ -867,7 +877,7 @@ public:
std::unique_ptr<TypeNoBounds> type, Location locus)
: for_lifetimes (std::move (lifetime_params)),
function_qualifiers (std::move (qualifiers)),
- params (std::move (named_params)), is_variadic (is_variadic),
+ params (std::move (named_params)), _is_variadic (is_variadic),
variadic_attrs (std::move (variadic_attrs)),
return_type (std::move (type)), locus (locus)
{
@@ -879,7 +889,7 @@ public:
BareFunctionType (BareFunctionType const &other)
: for_lifetimes (other.for_lifetimes),
function_qualifiers (other.function_qualifiers), params (other.params),
- is_variadic (other.is_variadic), variadic_attrs (other.variadic_attrs),
+ _is_variadic (other._is_variadic), variadic_attrs (other.variadic_attrs),
locus (other.locus)
{
// guard to prevent null dereference
@@ -893,7 +903,7 @@ public:
for_lifetimes = other.for_lifetimes;
function_qualifiers = other.function_qualifiers;
params = other.params;
- is_variadic = other.is_variadic;
+ _is_variadic = other._is_variadic;
variadic_attrs = other.variadic_attrs;
locus = other.locus;
@@ -930,7 +940,7 @@ public:
return return_type;
}
- FunctionQualifiers get_function_qualifiers () { return function_qualifiers; }
+ FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
protected:
/* Use covariance to implement clone function as returning this object rather