aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/ast')
-rw-r--r--gcc/rust/ast/rust-ast-builder-type.cc164
-rw-r--r--gcc/rust/ast/rust-ast-builder-type.h57
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc201
-rw-r--r--gcc/rust/ast/rust-ast-builder.h17
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc14
-rw-r--r--gcc/rust/ast/rust-ast-collector.h2
-rw-r--r--gcc/rust/ast/rust-ast-full-decls.h4
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc52
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h6
-rw-r--r--gcc/rust/ast/rust-ast.cc4
-rw-r--r--gcc/rust/ast/rust-ast.h27
-rw-r--r--gcc/rust/ast/rust-expr.h196
-rw-r--r--gcc/rust/ast/rust-item.h2
-rw-r--r--gcc/rust/ast/rust-path.cc28
-rw-r--r--gcc/rust/ast/rust-path.h274
-rw-r--r--gcc/rust/ast/rust-pattern.h2
-rw-r--r--gcc/rust/ast/rust-type.h10
17 files changed, 942 insertions, 118 deletions
diff --git a/gcc/rust/ast/rust-ast-builder-type.cc b/gcc/rust/ast/rust-ast-builder-type.cc
new file mode 100644
index 0000000..e76d0de
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-builder-type.cc
@@ -0,0 +1,164 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-builder-type.h"
+#include "rust-ast-builder.h"
+#include "rust-ast-full.h"
+#include "rust-common.h"
+#include "rust-make-unique.h"
+
+namespace Rust {
+namespace AST {
+
+ASTTypeBuilder::ASTTypeBuilder () : translated (nullptr) {}
+
+Type *
+ASTTypeBuilder::build (Type &type)
+{
+ ASTTypeBuilder builder;
+ type.accept_vis (builder);
+ rust_assert (builder.translated != nullptr);
+ return builder.translated;
+}
+
+void
+ASTTypeBuilder::visit (BareFunctionType &fntype)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (TupleType &tuple)
+{
+ std::vector<std::unique_ptr<Type> > elems;
+ for (auto &elem : tuple.get_elems ())
+ {
+ Type *t = ASTTypeBuilder::build (*elem.get ());
+ std::unique_ptr<Type> ty (t);
+ elems.push_back (std::move (ty));
+ }
+ translated = new TupleType (std::move (elems), tuple.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (TypePath &path)
+{
+ std::vector<std::unique_ptr<TypePathSegment> > segments;
+ for (auto &seg : path.get_segments ())
+ {
+ switch (seg->get_type ())
+ {
+ case TypePathSegment::REG: {
+ const TypePathSegment &segment
+ = (const TypePathSegment &) (*seg.get ());
+ TypePathSegment *s
+ = new TypePathSegment (segment.get_ident_segment (),
+ segment.get_separating_scope_resolution (),
+ segment.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::GENERIC: {
+ TypePathSegmentGeneric &generic
+ = (TypePathSegmentGeneric &) (*seg.get ());
+
+ GenericArgs args
+ = Builder::new_generic_args (generic.get_generic_args ());
+ TypePathSegmentGeneric *s
+ = new TypePathSegmentGeneric (generic.get_ident_segment (), false,
+ std::move (args),
+ generic.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::FUNCTION: {
+ rust_unreachable ();
+ // TODO
+ // const TypePathSegmentFunction &fn
+ // = (const TypePathSegmentFunction &) (*seg.get ());
+ }
+ break;
+ }
+ }
+
+ translated = new TypePath (std::move (segments), path.get_locus (),
+ path.has_opening_scope_resolution_op ());
+}
+
+void
+ASTTypeBuilder::visit (QualifiedPathInType &path)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (ArrayType &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (ReferenceType &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (RawPointerType &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (SliceType &type)
+{
+ Type *t = ASTTypeBuilder::build (type.get_elem_type ());
+ std::unique_ptr<Type> ty (t);
+ translated = new SliceType (std::move (ty), type.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (InferredType &type)
+{
+ translated = new InferredType (type.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (NeverType &type)
+{
+ translated = new NeverType (type.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (TraitObjectTypeOneBound &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (TraitObjectType &type)
+{
+ /* TODO */
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-builder-type.h b/gcc/rust/ast/rust-ast-builder-type.h
new file mode 100644
index 0000000..b67ae3b
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-builder-type.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_AST_BUILDER_TYPE
+#define RUST_AST_BUILDER_TYPE
+
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+namespace AST {
+
+class ASTTypeBuilder : public DefaultASTVisitor
+{
+protected:
+ using DefaultASTVisitor::visit;
+
+public:
+ static Type *build (Type &type);
+
+ void visit (BareFunctionType &fntype) override;
+ void visit (TupleType &tuple) override;
+ void visit (TypePath &path) override;
+ void visit (QualifiedPathInType &path) override;
+ void visit (ArrayType &type) override;
+ void visit (ReferenceType &type) override;
+ void visit (RawPointerType &type) override;
+ void visit (SliceType &type) override;
+ void visit (InferredType &type) override;
+ void visit (NeverType &type) override;
+ void visit (TraitObjectTypeOneBound &type) override;
+ void visit (TraitObjectType &type) override;
+
+private:
+ ASTTypeBuilder ();
+
+ Type *translated;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // RUST_AST_BUILDER_TYPE
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 4679aa7..529c686 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -17,8 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ast-builder.h"
-#include "rust-ast-full-decls.h"
-#include "rust-ast-full.h"
+#include "rust-ast-builder-type.h"
#include "rust-common.h"
#include "rust-expr.h"
#include "rust-token.h"
@@ -83,6 +82,13 @@ Builder::type_path_segment (std::string seg) const
new TypePathSegment (seg, false, loc));
}
+std::unique_ptr<TypePathSegment>
+Builder::generic_type_path_segment (std::string seg, GenericArgs args) const
+{
+ return std::unique_ptr<TypePathSegment> (
+ new TypePathSegmentGeneric (PathIdentSegment (seg, loc), false, args, loc));
+}
+
std::unique_ptr<Type>
Builder::single_type_path (std::string type) const
{
@@ -92,6 +98,15 @@ Builder::single_type_path (std::string type) const
return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
}
+std::unique_ptr<Type>
+Builder::single_generic_type_path (std::string type, GenericArgs args) const
+{
+ auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
+ segments.emplace_back (generic_type_path_segment (type, args));
+
+ return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
+}
+
PathInExpression
Builder::path_in_expression (std::vector<std::string> &&segments) const
{
@@ -174,5 +189,187 @@ Builder::wildcard () const
return std::unique_ptr<Pattern> (new WildcardPattern (loc));
}
+std::unique_ptr<Type>
+Builder::new_type (Type &type)
+{
+ Type *t = ASTTypeBuilder::build (type);
+ return std::unique_ptr<Type> (t);
+}
+
+std::unique_ptr<GenericParam>
+Builder::new_lifetime_param (LifetimeParam &param)
+{
+ Lifetime l = new_lifetime (param.get_lifetime ());
+ std::vector<Lifetime> lifetime_bounds;
+ for (auto b : param.get_lifetime_bounds ())
+ {
+ Lifetime bl = new_lifetime (b);
+ lifetime_bounds.push_back (bl);
+ }
+
+ auto p = new LifetimeParam (l, std::move (lifetime_bounds),
+ param.get_outer_attrs (), param.get_locus ());
+ return std::unique_ptr<GenericParam> (p);
+}
+
+std::unique_ptr<GenericParam>
+Builder::new_type_param (TypeParam &param)
+{
+ location_t locus = param.get_locus ();
+ AST::AttrVec outer_attrs = param.get_outer_attrs ();
+ Identifier type_representation = param.get_type_representation ();
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
+ std::unique_ptr<Type> type = nullptr;
+
+ if (param.has_type ())
+ type = new_type (param.get_type ());
+
+ for (const auto &b : param.get_type_param_bounds ())
+ {
+ switch (b->get_bound_type ())
+ {
+ case TypeParamBound::TypeParamBoundType::TRAIT: {
+ const TraitBound &tb = (const TraitBound &) *b.get ();
+ const TypePath &path = tb.get_type_path ();
+
+ std::vector<LifetimeParam> for_lifetimes;
+ for (const auto &lifetime : tb.get_for_lifetimes ())
+ {
+ std::vector<Lifetime> lifetime_bounds;
+ for (const auto &b : lifetime.get_lifetime_bounds ())
+ {
+ Lifetime bl = new_lifetime (b);
+ lifetime_bounds.push_back (std::move (bl));
+ }
+
+ Lifetime nl = new_lifetime (lifetime.get_lifetime ());
+ LifetimeParam p (std::move (nl), std::move (lifetime_bounds),
+ {}, lifetime.get_locus ());
+ for_lifetimes.push_back (std::move (p));
+ }
+
+ std::vector<std::unique_ptr<TypePathSegment>> segments;
+ for (auto &seg : path.get_segments ())
+ {
+ switch (seg->get_type ())
+ {
+ case TypePathSegment::REG: {
+ const TypePathSegment &segment
+ = (const TypePathSegment &) (*seg.get ());
+ TypePathSegment *s = new TypePathSegment (
+ segment.get_ident_segment (),
+ segment.get_separating_scope_resolution (),
+ segment.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::GENERIC: {
+ TypePathSegmentGeneric &generic
+ = (TypePathSegmentGeneric &) (*seg.get ());
+
+ GenericArgs args
+ = new_generic_args (generic.get_generic_args ());
+ TypePathSegmentGeneric *s = new TypePathSegmentGeneric (
+ generic.get_ident_segment (), false, std::move (args),
+ generic.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::FUNCTION: {
+ rust_unreachable ();
+ // TODO
+ // const TypePathSegmentFunction &fn
+ // = (const TypePathSegmentFunction &) (*seg.get ());
+ }
+ break;
+ }
+ }
+
+ TypePath p (std::move (segments), path.get_locus (),
+ path.has_opening_scope_resolution_op ());
+
+ TraitBound *b = new TraitBound (std::move (p), tb.get_locus (),
+ tb.is_in_parens (),
+ tb.has_opening_question_mark (),
+ std::move (for_lifetimes));
+ std::unique_ptr<TypeParamBound> bound (b);
+ type_param_bounds.push_back (std::move (bound));
+ }
+ break;
+
+ case TypeParamBound::TypeParamBoundType::LIFETIME: {
+ const Lifetime &l = (const Lifetime &) *b.get ();
+
+ auto bl = new Lifetime (l.get_lifetime_type (),
+ l.get_lifetime_name (), l.get_locus ());
+ std::unique_ptr<TypeParamBound> bound (bl);
+ type_param_bounds.push_back (std::move (bound));
+ }
+ break;
+ }
+ }
+
+ auto type_param
+ = new TypeParam (type_representation, locus, std::move (type_param_bounds),
+ std::move (type), std::move (outer_attrs));
+
+ return std::unique_ptr<GenericParam> (type_param);
+}
+
+Lifetime
+Builder::new_lifetime (const Lifetime &lifetime)
+{
+ return Lifetime (lifetime.get_lifetime_type (), lifetime.get_lifetime_name (),
+ lifetime.get_locus ());
+}
+
+GenericArgs
+Builder::new_generic_args (GenericArgs &args)
+{
+ std::vector<Lifetime> lifetime_args;
+ std::vector<GenericArg> generic_args;
+ std::vector<GenericArgsBinding> binding_args;
+ location_t locus = args.get_locus ();
+
+ for (const auto &lifetime : args.get_lifetime_args ())
+ {
+ Lifetime l = new_lifetime (lifetime);
+ lifetime_args.push_back (std::move (l));
+ }
+
+ for (auto &binding : args.get_binding_args ())
+ {
+ Type &t = *binding.get_type_ptr ().get ();
+ std::unique_ptr<Type> ty = new_type (t);
+ GenericArgsBinding b (binding.get_identifier (), std::move (ty),
+ binding.get_locus ());
+ binding_args.push_back (std::move (b));
+ }
+
+ for (auto &arg : args.get_generic_args ())
+ {
+ switch (arg.get_kind ())
+ {
+ case GenericArg::Kind::Type: {
+ std::unique_ptr<Type> ty = new_type (arg.get_type ());
+ GenericArg arg = GenericArg::create_type (std::move (ty));
+ }
+ break;
+
+ default:
+ // FIXME
+ rust_unreachable ();
+ break;
+ }
+ }
+
+ return GenericArgs (std::move (lifetime_args), std::move (generic_args),
+ std::move (binding_args), locus);
+}
+
} // namespace AST
} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index aed71e7..bad79d0 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -82,10 +82,16 @@ public:
/* And similarly for type path segments */
std::unique_ptr<TypePathSegment> type_path_segment (std::string seg) const;
+ std::unique_ptr<TypePathSegment>
+ generic_type_path_segment (std::string seg, GenericArgs args) const;
+
/* Create a Type from a single string - the most basic kind of type in our AST
*/
std::unique_ptr<Type> single_type_path (std::string type) const;
+ std::unique_ptr<Type> single_generic_type_path (std::string type,
+ GenericArgs args) const;
+
/**
* Create a path in expression from multiple segments (`Clone::clone`). You
* do not need to separate the segments using `::`, you can simply provide a
@@ -116,6 +122,17 @@ public:
/* Create a wildcard pattern (`_`) */
std::unique_ptr<Pattern> wildcard () const;
+ static std::unique_ptr<Type> new_type (Type &type);
+
+ static std::unique_ptr<GenericParam>
+ new_lifetime_param (LifetimeParam &param);
+
+ static std::unique_ptr<GenericParam> new_type_param (TypeParam &param);
+
+ static Lifetime new_lifetime (const Lifetime &lifetime);
+
+ static GenericArgs new_generic_args (GenericArgs &args);
+
private:
/**
* Location of the generated AST nodes
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index 6980fef..2022668 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -21,6 +21,7 @@
#include "rust-expr.h"
#include "rust-item.h"
#include "rust-keyword-values.h"
+#include "rust-system.h"
#include "rust-token.h"
namespace Rust {
@@ -561,6 +562,19 @@ TokenCollector::visit (PathInExpression &path)
}
void
+TokenCollector::visit (RegularPath &path)
+{
+ // FIXME: We probably want to have a proper implementation here, and call this
+ // function from things like the PathInExpression visitor
+}
+
+void
+TokenCollector::visit (LangItemPath &path)
+{
+ // TODO: Implement proper token collection for lang item paths
+}
+
+void
TokenCollector::visit (TypePathSegment &segment)
{
// Syntax:
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index b2dc41b..32a5bd3 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -234,6 +234,8 @@ public:
void visit (PathExprSegment &segment);
void visit (PathIdentSegment &segment);
void visit (PathInExpression &path);
+ void visit (RegularPath &path);
+ void visit (LangItemPath &path);
void visit (TypePathSegment &segment);
void visit (TypePathSegmentGeneric &segment);
void visit (TypePathSegmentFunction &segment);
diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h
index d2ba876..80d217e 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -61,7 +61,7 @@ class PathIdentSegment;
struct GenericArgsBinding;
struct GenericArgs;
class PathExprSegment;
-class PathPattern;
+class Path;
class PathInExpression;
class TypePathSegment;
class TypePathSegmentGeneric;
@@ -148,7 +148,7 @@ class AsyncBlockExpr;
enum class InlineAsmOption;
struct AnonConst;
struct InlineAsmRegOrRegClass;
-struct InlineAsmOperand;
+class InlineAsmOperand;
struct InlineAsmPlaceHolder;
struct InlineAsmTemplatePiece;
struct TupleClobber;
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 866357b..8f53e52 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -86,6 +86,17 @@ DefaultASTVisitor::visit (AST::ConstGenericParam &const_param)
}
void
+DefaultASTVisitor::visit (AST::RegularPath &path)
+{
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+DefaultASTVisitor::visit (AST::LangItemPath &path)
+{}
+
+void
DefaultASTVisitor::visit (AST::PathInExpression &path)
{
visit_outer_attrs (path);
@@ -664,7 +675,46 @@ DefaultASTVisitor::visit (AST::AsyncBlockExpr &expr)
void
DefaultASTVisitor::visit (AST::InlineAsm &expr)
-{}
+{
+ visit_outer_attrs (expr);
+ using RegisterType = AST::InlineAsmOperand::RegisterType;
+ for (auto &operand : expr.get_operands ())
+ {
+ switch (operand.get_register_type ())
+ {
+ case RegisterType::In: {
+ visit (operand.get_in ().expr);
+ break;
+ }
+ case RegisterType::Out: {
+ visit (operand.get_out ().expr);
+ break;
+ }
+ case RegisterType::InOut: {
+ visit (operand.get_in_out ().expr);
+ break;
+ }
+ case RegisterType::SplitInOut: {
+ auto split = operand.get_split_in_out ();
+ visit (split.in_expr);
+ visit (split.out_expr);
+ break;
+ }
+ case RegisterType::Const: {
+ visit (operand.get_const ().anon_const.expr);
+ break;
+ }
+ case RegisterType::Sym: {
+ visit (operand.get_sym ().expr);
+ break;
+ }
+ case RegisterType::Label: {
+ visit (operand.get_label ().expr);
+ break;
+ }
+ }
+ }
+}
void
DefaultASTVisitor::visit (AST::TypeParam &param)
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 2f56d89..50b9301 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -24,6 +24,7 @@
#include "rust-ast-full-decls.h"
#include "rust-ast.h"
#include "rust-item.h"
+#include "rust-path.h"
#include "rust-system.h"
namespace Rust {
@@ -58,6 +59,8 @@ public:
// virtual void visit(TraitImplItem& trait_impl_item) = 0;
// rust-path.h
+ virtual void visit (RegularPath &path) = 0;
+ virtual void visit (LangItemPath &path) = 0;
virtual void visit (PathInExpression &path) = 0;
virtual void visit (TypePathSegment &segment) = 0;
virtual void visit (TypePathSegmentGeneric &segment) = 0;
@@ -241,7 +244,6 @@ class DefaultASTVisitor : public ASTVisitor
public:
virtual void visit (AST::Crate &crate);
-protected:
virtual void visit (AST::Token &tok) override;
virtual void visit (AST::DelimTokenTree &delim_tok_tree) override;
virtual void visit (AST::AttrInputMetaItemContainer &input) override;
@@ -249,6 +251,8 @@ protected:
virtual void visit (AST::Lifetime &lifetime) override;
virtual void visit (AST::LifetimeParam &lifetime_param) override;
virtual void visit (AST::ConstGenericParam &const_param) override;
+ virtual void visit (AST::RegularPath &path) override;
+ virtual void visit (AST::LangItemPath &path) override;
virtual void visit (AST::PathInExpression &path) override;
virtual void visit (AST::TypePathSegment &segment) override;
virtual void visit (AST::TypePathSegmentGeneric &segment) override;
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index bf7d31d..1d52352 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -311,7 +311,8 @@ Attribute::get_traits_to_derive ()
// Copy constructor must deep copy attr_input as unique pointer
Attribute::Attribute (Attribute const &other)
- : path (other.path), locus (other.locus)
+ : path (other.path), locus (other.locus),
+ inner_attribute (other.inner_attribute)
{
// guard to protect from null pointer dereference
if (other.attr_input != nullptr)
@@ -324,6 +325,7 @@ Attribute::operator= (Attribute const &other)
{
path = other.path;
locus = other.locus;
+ inner_attribute = other.inner_attribute;
// guard to protect from null pointer dereference
if (other.attr_input != nullptr)
attr_input = other.attr_input->clone_attr_input ();
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 4f40eff..42ad011 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1477,6 +1477,12 @@ protected:
class TypeParamBound : public Visitable
{
public:
+ enum TypeParamBoundType
+ {
+ TRAIT,
+ LIFETIME
+ };
+
virtual ~TypeParamBound () {}
// Unique pointer custom clone function
@@ -1491,6 +1497,8 @@ public:
virtual location_t get_locus () const = 0;
+ virtual TypeParamBoundType get_bound_type () const = 0;
+
protected:
// Clone function implementation as pure virtual method
virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
@@ -1546,12 +1554,17 @@ public:
void accept_vis (ASTVisitor &vis) override;
- LifetimeType get_lifetime_type () { return lifetime_type; }
+ LifetimeType get_lifetime_type () const { return lifetime_type; }
location_t get_locus () const override final { return locus; }
std::string get_lifetime_name () const { return lifetime_name; }
+ TypeParamBoundType get_bound_type () const override
+ {
+ return TypeParamBound::TypeParamBoundType::LIFETIME;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1587,7 +1600,7 @@ public:
virtual Kind get_kind () const = 0;
- NodeId get_node_id () { return node_id; }
+ NodeId get_node_id () const { return node_id; }
protected:
GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
@@ -1619,6 +1632,11 @@ public:
std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
+ const std::vector<Lifetime> &get_lifetime_bounds () const
+ {
+ return lifetime_bounds;
+ }
+
// Returns whether the lifetime param has an outer attribute.
bool has_outer_attribute () const { return !outer_attrs.empty (); }
@@ -2048,11 +2066,6 @@ public:
}
};
-// Base path expression AST node - abstract
-class PathExpr : public ExprWithoutBlock
-{
-};
-
} // namespace AST
} // namespace Rust
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 9477bf0..438d3d3 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4768,9 +4768,10 @@ struct InlineAsmRegOrRegClass
location_t locus;
};
-struct InlineAsmOperand
+class InlineAsmOperand
{
- enum RegisterType
+public:
+ enum class RegisterType
{
In,
Out,
@@ -4781,8 +4782,24 @@ struct InlineAsmOperand
Label,
};
- struct In
+ class Register
+ {
+ public:
+ Register () {}
+ virtual ~Register () = default;
+
+ std::unique_ptr<Register> clone () const
+ {
+ return std::unique_ptr<Register> (clone_impl ());
+ }
+
+ protected:
+ virtual Register *clone_impl () const = 0;
+ };
+
+ class In : public Register
{
+ public:
tl::optional<InlineAsmRegOrRegClass> reg;
std::unique_ptr<Expr> expr;
@@ -4807,10 +4824,14 @@ struct InlineAsmOperand
return *this;
}
+
+ private:
+ In *clone_impl () const { return new In (*this); }
};
- struct Out
+ class Out : public Register
{
+ public:
tl::optional<InlineAsmRegOrRegClass> reg;
bool late;
std::unique_ptr<Expr> expr; // can be null
@@ -4836,10 +4857,14 @@ struct InlineAsmOperand
expr = other.expr->clone_expr ();
return *this;
}
+
+ private:
+ Out *clone_impl () const { return new Out (*this); }
};
- struct InOut
+ class InOut : public Register
{
+ public:
tl::optional<InlineAsmRegOrRegClass> reg;
bool late;
std::unique_ptr<Expr> expr; // this can't be null
@@ -4866,10 +4891,14 @@ struct InlineAsmOperand
return *this;
}
+
+ private:
+ InOut *clone_impl () const { return new InOut (*this); }
};
- struct SplitInOut
+ class SplitInOut : public Register
{
+ public:
tl::optional<InlineAsmRegOrRegClass> reg;
bool late;
std::unique_ptr<Expr> in_expr;
@@ -4901,15 +4930,23 @@ struct InlineAsmOperand
return *this;
}
+
+ private:
+ SplitInOut *clone_impl () const { return new SplitInOut (*this); }
};
- struct Const
+ class Const : public Register
{
+ public:
AnonConst anon_const;
+
+ private:
+ Const *clone_impl () const { return new Const (*this); }
};
- struct Sym
+ class Sym : public Register
{
+ public:
std::unique_ptr<Expr> expr;
Sym (std::unique_ptr<Expr> expr) : expr (std::move (expr))
@@ -4926,10 +4963,14 @@ struct InlineAsmOperand
expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
return *this;
}
+
+ private:
+ Sym *clone_impl () const { return new Sym (*this); }
};
- struct Label
+ class Label : public Register
{
+ public:
std::string label_name;
std::unique_ptr<Expr> expr;
@@ -4950,76 +4991,127 @@ struct InlineAsmOperand
expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
return *this;
}
- };
- RegisterType register_type;
-
- tl::optional<struct In> in;
- tl::optional<struct Out> out;
- tl::optional<struct InOut> in_out;
- tl::optional<struct SplitInOut> split_in_out;
- tl::optional<struct Const> cnst;
- tl::optional<struct Sym> sym;
- tl::optional<struct Label> label;
+ private:
+ Label *clone_impl () const { return new Label (*this); }
+ };
- InlineAsmOperand () {}
InlineAsmOperand (const InlineAsmOperand &other)
- : in (other.in), out (other.out), in_out (other.in_out),
- split_in_out (other.split_in_out), cnst (other.cnst), sym (other.sym)
+ : register_type (other.register_type), locus (other.locus),
+ reg (other.reg->clone ())
{}
- void set_in (const tl::optional<struct In> &reg)
- {
- this->register_type = In;
+ InlineAsmOperand (const In &reg, location_t locus)
+ : register_type (RegisterType::In), locus (locus), reg (new In (reg))
+ {}
+ InlineAsmOperand (const Out &reg, location_t locus)
+ : register_type (RegisterType::Out), locus (locus), reg (new Out (reg))
+ {}
+ InlineAsmOperand (const InOut &reg, location_t locus)
+ : register_type (RegisterType::InOut), locus (locus), reg (new InOut (reg))
+ {}
+ InlineAsmOperand (const SplitInOut &reg, location_t locus)
+ : register_type (RegisterType::SplitInOut), locus (locus),
+ reg (new SplitInOut (reg))
+ {}
+ InlineAsmOperand (const Const &reg, location_t locus)
+ : register_type (RegisterType::Const), locus (locus), reg (new Const (reg))
+ {}
+ InlineAsmOperand (const Sym &reg, location_t locus)
+ : register_type (RegisterType::Sym), locus (locus), reg (new Sym (reg))
+ {}
+ InlineAsmOperand (const Label &reg, location_t locus)
+ : register_type (RegisterType::Label), locus (locus), reg (new Label (reg))
+ {}
- if (reg.has_value ())
- this->in = reg.value ();
- }
+ location_t get_locus () const { return locus; }
+ RegisterType get_register_type () const { return register_type; }
- void set_out (const tl::optional<struct Out> &reg)
+ // Potentially fail immediately if you don't use get_register_type() to
+ // inspect the RegisterType first before calling the following functions Check
+ // first
+ In &get_in ()
+ {
+ rust_assert (register_type == RegisterType::In);
+ return static_cast<In &> (*reg);
+ }
+ const In &get_in () const
{
- this->register_type = Out;
+ rust_assert (register_type == RegisterType::In);
+ return static_cast<const In &> (*reg);
+ }
- if (reg.has_value ())
- this->out = reg.value ();
+ Out &get_out ()
+ {
+ rust_assert (register_type == RegisterType::Out);
+ return static_cast<Out &> (*reg);
+ }
+ const Out &get_out () const
+ {
+ rust_assert (register_type == RegisterType::Out);
+ return static_cast<const Out &> (*reg);
}
- void set_in_out (const tl::optional<struct InOut> &reg)
+ InOut &get_in_out ()
+ {
+ rust_assert (register_type == RegisterType::InOut);
+ return static_cast<InOut &> (*reg);
+ }
+ const InOut &get_in_out () const
{
- this->register_type = InOut;
- if (reg.has_value ())
- this->in_out = reg.value ();
+ rust_assert (register_type == RegisterType::InOut);
+ return static_cast<const InOut &> (*reg);
}
- void set_split_in_out (const tl::optional<struct SplitInOut> &reg)
+ SplitInOut &get_split_in_out ()
{
- this->register_type = SplitInOut;
- if (reg.has_value ())
- this->split_in_out = reg.value ();
+ rust_assert (register_type == RegisterType::SplitInOut);
+ return static_cast<SplitInOut &> (*reg);
+ }
+ const SplitInOut &get_split_in_out () const
+ {
+ rust_assert (register_type == RegisterType::SplitInOut);
+ return static_cast<const SplitInOut &> (*reg);
}
- void set_cnst (const tl::optional<struct Const> &reg)
+ Const &get_const ()
+ {
+ rust_assert (register_type == RegisterType::Const);
+ return static_cast<Const &> (*reg);
+ }
+ const Const &get_const () const
{
- this->register_type = Const;
- if (reg.has_value ())
- this->cnst = reg.value ();
+ rust_assert (register_type == RegisterType::Const);
+ return static_cast<Const &> (*reg);
}
- void set_sym (const tl::optional<struct Sym> &reg)
+ Sym &get_sym ()
+ {
+ rust_assert (register_type == RegisterType::Sym);
+ return static_cast<Sym &> (*reg);
+ }
+ const Sym &get_sym () const
{
- this->register_type = Sym;
- if (reg.has_value ())
- this->sym = reg.value ();
+ rust_assert (register_type == RegisterType::Sym);
+ return static_cast<const Sym &> (*reg);
}
- void set_label (const tl::optional<struct Label> &reg)
+ Label &get_label ()
{
- this->register_type = Label;
- if (reg.has_value ())
- this->label = reg.value ();
+ rust_assert (register_type == RegisterType::Label);
+ return static_cast<Label &> (*reg);
}
+ const Label &get_label () const
+ {
+ rust_assert (register_type == RegisterType::Label);
+ return static_cast<const Label &> (*reg);
+ }
+
+private:
+ RegisterType register_type;
location_t locus;
+ std::unique_ptr<Register> reg;
};
struct InlineAsmPlaceHolder
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index bd9113f..2ae7c44 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1213,7 +1213,7 @@ public:
std::string as_string () const override;
- NewBindType get_new_bind_type () { return bind_type; }
+ NewBindType get_new_bind_type () const { return bind_type; }
void accept_vis (ASTVisitor &vis) override;
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 3aaf263..06c98cd 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#include "rust-path.h"
#include "rust-system.h"
#include "rust-ast-full.h"
#include "rust-diagnostics.h"
@@ -135,7 +136,7 @@ PathExprSegment::as_string () const
}
std::string
-PathPattern::as_string () const
+RegularPath::as_string () const
{
std::string str;
@@ -148,8 +149,15 @@ PathPattern::as_string () const
return str;
}
+std::string
+LangItemPath::as_string () const
+{
+ // FIXME: Handle #[lang] paths
+ rust_unreachable ();
+}
+
SimplePath
-PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
+RegularPath::convert_to_simple_path (bool with_opening_scope_resolution) const
{
if (!has_segments ())
return SimplePath::create_empty ();
@@ -184,6 +192,18 @@ PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
}
void
+RegularPath::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+LangItemPath::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
PathInExpression::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
@@ -197,7 +217,7 @@ PathInExpression::as_string () const
if (has_opening_scope_resolution)
str = "::";
- return str + PathPattern::as_string ();
+ return str + path->as_string ();
}
std::string
@@ -297,7 +317,7 @@ TypePathFunction::as_string () const
std::string
QualifiedPathInExpression::as_string () const
{
- return path_type.as_string () + "::" + PathPattern::as_string ();
+ return path_type.as_string () + "::" + path->as_string ();
}
std::string
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index b20f31c..98fde5a 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -22,6 +22,9 @@
* for virtually all AST-related functionality. */
#include "rust-ast.h"
+#include "rust-hir-map.h"
+#include "rust-mapping-common.h"
+#include "rust-system.h"
#include "system.h"
namespace Rust {
@@ -476,15 +479,23 @@ public:
std::string as_string () const;
- // TODO: is this better? Or is a "vis_pattern" better?
std::vector<GenericArg> &get_generic_args () { return generic_args; }
- // TODO: is this better? Or is a "vis_pattern" better?
std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
+ const std::vector<GenericArgsBinding> &get_binding_args () const
+ {
+ return binding_args;
+ }
+
std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; };
- location_t get_locus () { return locus; }
+ const std::vector<Lifetime> &get_lifetime_args () const
+ {
+ return lifetime_args;
+ };
+
+ location_t get_locus () const { return locus; }
};
/* A segment of a path in expression, including an identifier aspect and maybe
@@ -565,51 +576,114 @@ public:
// AST node representing a pattern that involves a "path" - abstract base
// class
-class PathPattern : public Pattern
+class Path : public Pattern
{
- std::vector<PathExprSegment> segments;
+public:
+ enum class Kind
+ {
+ LangItem,
+ Regular,
+ };
+
+ virtual Kind get_path_kind () const = 0;
+
+ Pattern::Kind get_pattern_kind () override final
+ {
+ return Pattern::Kind::Path;
+ }
+
+ location_t get_locus () const override final { return locus; }
+ NodeId get_node_id () const override final { return node_id; }
+
+ std::unique_ptr<Path> clone_path ()
+ {
+ return std::unique_ptr<Path> (clone_path_impl ());
+ }
+
+ Pattern *clone_pattern_impl () const override final
+ {
+ return clone_path_impl ();
+ }
protected:
- PathPattern (std::vector<PathExprSegment> segments)
- : segments (std::move (segments))
+ location_t locus;
+ NodeId node_id;
+
+ Path (location_t locus, NodeId node_id) : locus (locus), node_id (node_id) {}
+
+ virtual Path *clone_path_impl () const = 0;
+};
+
+class RegularPath : public Path
+{
+ std::vector<PathExprSegment> segments;
+
+public:
+ explicit RegularPath (std::vector<PathExprSegment> &&segments,
+ location_t locus, NodeId node_id)
+ : Path (locus, node_id), segments (std::move (segments))
{}
+ std::string as_string () const override;
+
// Returns whether path has segments.
bool has_segments () const { return !segments.empty (); }
+ std::vector<PathExprSegment> &get_segments () { return segments; }
+
+ const std::vector<PathExprSegment> &get_segments () const { return segments; }
+
+ /* Returns whether the path is a single segment (excluding qualified path
+ * initial as segment). */
+ bool is_single_segment () const { return segments.size () == 1; }
+
/* Converts path segments to their equivalent SimplePath segments if
* possible, and creates a SimplePath from them. */
SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const;
- // Removes all segments of the path.
- void remove_all_segments ()
+ Path::Kind get_path_kind () const override { return Path::Kind::Regular; }
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ Path *clone_path_impl () const override
{
- segments.clear ();
- segments.shrink_to_fit ();
+ return new RegularPath (std::vector<PathExprSegment> (segments), locus,
+ node_id);
}
+};
-public:
- /* Returns whether the path is a single segment (excluding qualified path
- * initial as segment). */
- bool is_single_segment () const { return segments.size () == 1; }
+class LangItemPath : public Path
+{
+ NodeId lang_item;
+ // TODO: Add LangItemKind or w/ever here as well
- std::string as_string () const override;
+ // TODO: This constructor is wrong
+ explicit LangItemPath (NodeId lang_item, location_t locus)
+ : Path (locus, lang_item), lang_item (lang_item)
+ {}
- // TODO: this seems kinda dodgy
- std::vector<PathExprSegment> &get_segments () { return segments; }
- const std::vector<PathExprSegment> &get_segments () const { return segments; }
+ Path::Kind get_path_kind () const override { return Path::Kind::LangItem; }
- Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
+ void accept_vis (ASTVisitor &vis) override;
+
+ Path *clone_path_impl () const override
+ {
+ return new LangItemPath (lang_item, locus);
+ }
+
+ std::string as_string () const override;
};
/* AST node representing a path-in-expression pattern (path that allows
* generic arguments) */
-class PathInExpression : public PathPattern, public PathExpr
+class PathInExpression : public Pattern, public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
bool has_opening_scope_resolution;
location_t locus;
NodeId _node_id;
+ std::unique_ptr<Path> path;
+ bool marked_for_strip;
public:
std::string as_string () const override;
@@ -618,12 +692,34 @@ public:
PathInExpression (std::vector<PathExprSegment> path_segments,
std::vector<Attribute> outer_attrs, location_t locus,
bool has_opening_scope_resolution = false)
- : PathPattern (std::move (path_segments)),
- outer_attrs (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 ())
+ locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ path (Rust::make_unique<RegularPath> (std::move (path_segments), locus,
+ _node_id)),
+ marked_for_strip (false)
{}
+ PathInExpression (const PathInExpression &other)
+ : outer_attrs (other.outer_attrs),
+ has_opening_scope_resolution (other.has_opening_scope_resolution),
+ locus (other.locus), _node_id (other._node_id),
+ path (other.path->clone_path ()),
+ marked_for_strip (other.marked_for_strip)
+ {}
+
+ PathInExpression &operator= (const PathInExpression &other)
+ {
+ outer_attrs = other.outer_attrs;
+ has_opening_scope_resolution = other.has_opening_scope_resolution;
+ locus = other.locus;
+ _node_id = other._node_id;
+ path = other.path->clone_path ();
+ marked_for_strip = other.marked_for_strip;
+
+ return *this;
+ }
+
// Creates an error state path in expression.
static PathInExpression create_error ()
{
@@ -631,28 +727,34 @@ public:
}
// Returns whether path in expression is in an error state.
- bool is_error () const { return !has_segments (); }
+ bool is_error () const
+ {
+ // FIXME: Cleanup
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return !static_cast<RegularPath &> (*path).has_segments ();
+
+ return false;
+ }
/* Converts PathInExpression to SimplePath if possible (i.e. no generic
* arguments). Otherwise returns an empty SimplePath. */
SimplePath as_simple_path () const
{
- /* delegate to parent class as can't access segments. however,
- * QualifiedPathInExpression conversion to simple path wouldn't make
- * sense, so the method in the parent class should be protected, not
- * public. Have to pass in opening scope resolution as parent class has no
- * access to it.
- */
- return convert_to_simple_path (has_opening_scope_resolution);
+ // FIXME: Cleanup
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).convert_to_simple_path (
+ has_opening_scope_resolution);
+ else
+ // FIXME: lang item to simple path?
+ rust_unreachable ();
}
location_t get_locus () const override final { return 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 (); }
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
bool opening_scope_resolution () const
{
@@ -671,13 +773,61 @@ public:
NodeId get_pattern_node_id () const { return get_node_id (); }
- PathExprSegment &get_final_segment () { return get_segments ().back (); }
+ PathExprSegment &get_final_segment ()
+ {
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ().back ();
+
+ // lang item segment?
+ rust_unreachable ();
+ }
+
const PathExprSegment &get_final_segment () const
{
- return get_segments ().back ();
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ().back ();
+
+ // lang item segment?
+ rust_unreachable ();
+ }
+
+ const std::vector<PathExprSegment> &get_segments () const
+ {
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ();
+
+ rust_unreachable ();
+ }
+
+ std::vector<PathExprSegment> &get_segments ()
+ {
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ();
+
+ rust_unreachable ();
+ }
+
+ bool is_single_segment () const
+ {
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ().size () == 1;
+
+ return false;
}
+ Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
+
protected:
+ PathInExpression (std::vector<Attribute> &&outer_attrs,
+ bool has_opening_scope_resolution, location_t locus,
+ NodeId node_id, std::unique_ptr<Path> &&path,
+ bool marked_for_strip)
+ : outer_attrs (std::move (outer_attrs)),
+ has_opening_scope_resolution (has_opening_scope_resolution),
+ locus (locus), _node_id (node_id), path (std::move (path)),
+ marked_for_strip (marked_for_strip)
+ {}
+
/* Use covariance to implement clone function as returning this object
* rather than base */
PathInExpression *clone_pattern_impl () const final override
@@ -1226,12 +1376,12 @@ public:
/* AST node representing a qualified path-in-expression pattern (path that
* allows specifying trait functions) */
-class QualifiedPathInExpression : public PathPattern, public PathExpr
+class QualifiedPathInExpression : public Pattern, public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
QualifiedPathType path_type;
- location_t locus;
- NodeId _node_id;
+
+ std::unique_ptr<Path> path;
public:
std::string as_string () const override;
@@ -1240,10 +1390,16 @@ public:
std::vector<PathExprSegment> path_segments,
std::vector<Attribute> outer_attrs,
location_t locus)
- : PathPattern (std::move (path_segments)),
- outer_attrs (std::move (outer_attrs)),
- path_type (std::move (qual_path_type)), locus (locus),
- _node_id (Analysis::Mappings::get ().get_next_node_id ())
+ : outer_attrs (std::move (outer_attrs)),
+ path_type (std::move (qual_path_type)),
+ path (Rust::make_unique<RegularPath> (
+ std::move (path_segments), locus,
+ Analysis::Mappings::get ().get_next_node_id ()))
+ {}
+
+ QualifiedPathInExpression (const QualifiedPathInExpression &other)
+ : outer_attrs (other.outer_attrs), path_type (other.path_type),
+ path (other.path->clone_path ())
{}
/* TODO: maybe make a shortcut constructor that has QualifiedPathType
@@ -1259,7 +1415,9 @@ public:
{}, UNDEF_LOCATION);
}
- location_t get_locus () const override final { return locus; }
+ Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
+
+ location_t get_locus () const override final { return path->get_locus (); }
void accept_vis (ASTVisitor &vis) override;
@@ -1285,7 +1443,31 @@ public:
outer_attrs = std::move (new_attrs);
}
- NodeId get_node_id () const override { return _node_id; }
+ NodeId get_node_id () const override { return path->get_node_id (); }
+
+ const std::vector<PathExprSegment> &get_segments () const
+ {
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ();
+
+ rust_unreachable ();
+ }
+
+ std::vector<PathExprSegment> &get_segments ()
+ {
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ();
+
+ rust_unreachable ();
+ }
+
+ bool is_single_segment () const
+ {
+ if (path->get_path_kind () == Path::Kind::Regular)
+ return static_cast<RegularPath &> (*path).get_segments ().size () == 1;
+
+ return false;
+ }
protected:
/* Use covariance to implement clone function as returning this object
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 383a5ee..69dbd98 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -1657,7 +1657,7 @@ protected:
};
// Moved definition to rust-path.h
-class PathPattern;
+class Path;
// Forward decls for paths (defined in rust-path.h)
class PathInExpression;
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index cf830f6..20e0232 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -48,6 +48,11 @@ public:
std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+ const std::vector<LifetimeParam> &get_for_lifetimes () const
+ {
+ return for_lifetimes;
+ }
+
TraitBound (TypePath type_path, location_t locus, bool in_parens = false,
bool opening_question_mark = false,
std::vector<LifetimeParam> for_lifetimes
@@ -81,6 +86,11 @@ public:
bool is_in_parens () const { return in_parens; }
bool has_opening_question_mark () const { return opening_question_mark; }
+ TypeParamBoundType get_bound_type () const override
+ {
+ return TypeParamBound::TypeParamBoundType::TRAIT;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */