diff options
Diffstat (limited to 'gcc/rust/ast')
-rw-r--r-- | gcc/rust/ast/rust-ast-collector.cc | 45 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-collector.h | 1 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-visitor.cc | 30 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-visitor.h | 4 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.cc | 6 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 19 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 93 | ||||
-rw-r--r-- | gcc/rust/ast/rust-path.cc | 2 | ||||
-rw-r--r-- | gcc/rust/ast/rust-path.h | 28 |
9 files changed, 199 insertions, 29 deletions
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 8ee6375..c850e96 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -491,7 +491,7 @@ TokenCollector::visit (ConstGenericParam ¶m) if (param.has_default_value ()) { push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); - visit (param.get_default_value ()); + visit (param.get_default_value_unchecked ()); } } @@ -639,8 +639,6 @@ TokenCollector::visit (GenericArg &arg) push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (path))); } break; - case GenericArg::Kind::Error: - rust_unreachable (); } } @@ -1522,6 +1520,47 @@ void TokenCollector::visit (InlineAsm &expr) {} +void +TokenCollector::visit (LlvmInlineAsm &expr) +{ + push (Rust::Token::make_identifier (expr.get_locus (), "llvm_asm")); + push (Rust::Token::make (EXCLAM, expr.get_locus ())); + push (Rust::Token::make (LEFT_PAREN, expr.get_locus ())); + for (auto &template_str : expr.get_templates ()) + push (Rust::Token::make_string (template_str.get_locus (), + std::move (template_str.symbol))); + + push (Rust::Token::make (COLON, expr.get_locus ())); + for (auto output : expr.get_outputs ()) + { + push (Rust::Token::make_string (expr.get_locus (), + std::move (output.constraint))); + visit (output.expr); + push (Rust::Token::make (COMMA, expr.get_locus ())); + } + + push (Rust::Token::make (COLON, expr.get_locus ())); + for (auto input : expr.get_inputs ()) + { + push (Rust::Token::make_string (expr.get_locus (), + std::move (input.constraint))); + visit (input.expr); + push (Rust::Token::make (COMMA, expr.get_locus ())); + } + + push (Rust::Token::make (COLON, expr.get_locus ())); + for (auto &clobber : expr.get_clobbers ()) + { + push (Rust::Token::make_string (expr.get_locus (), + std::move (clobber.symbol))); + push (Rust::Token::make (COMMA, expr.get_locus ())); + } + push (Rust::Token::make (COLON, expr.get_locus ())); + // Dump options + + push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ())); +} + // rust-item.h void diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h index b014c23..f45e3cc 100644 --- a/gcc/rust/ast/rust-ast-collector.h +++ b/gcc/rust/ast/rust-ast-collector.h @@ -303,6 +303,7 @@ public: void visit (AwaitExpr &expr); void visit (AsyncBlockExpr &expr); void visit (InlineAsm &expr); + void visit (LlvmInlineAsm &expr); // rust-item.h void visit (TypeParam ¶m); void visit (LifetimeWhereClauseItem &item); diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index 9d524c3..b6833f6 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -82,7 +82,7 @@ DefaultASTVisitor::visit (AST::ConstGenericParam &const_param) if (const_param.has_type ()) visit (const_param.get_type ()); if (const_param.has_default_value ()) - visit (const_param.get_default_value ()); + visit (const_param.get_default_value_unchecked ()); } void @@ -108,7 +108,8 @@ DefaultASTVisitor::visit (GenericArgsBinding &binding) void DefaultASTVisitor::visit (AST::TypePathSegmentGeneric &segment) { - visit (segment.get_generic_args ()); + if (segment.has_generic_args ()) + visit (segment.get_generic_args ()); } void @@ -581,8 +582,8 @@ DefaultASTVisitor::visit (AST::WhileLetLoopExpr &expr) visit_outer_attrs (expr); for (auto &pattern : expr.get_patterns ()) visit (pattern); - visit (expr.get_scrutinee_expr ()); visit (expr.get_loop_label ()); + visit (expr.get_scrutinee_expr ()); visit (expr.get_loop_block ()); } @@ -714,6 +715,16 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr) } void +DefaultASTVisitor::visit (AST::LlvmInlineAsm &expr) +{ + for (auto &output : expr.get_outputs ()) + visit (output.expr); + + for (auto &input : expr.get_inputs ()) + visit (input.expr); +} + +void DefaultASTVisitor::visit (AST::TypeParam ¶m) { visit_outer_attrs (param); @@ -817,10 +828,18 @@ DefaultASTVisitor::visit (AST::UseTreeRebind &use_tree) void DefaultASTVisitor::visit (AST::UseDeclaration &use_decl) { + visit (use_decl.get_visibility ()); visit (use_decl.get_tree ()); } void +DefaultASTVisitor::visit_function_params (AST::Function &function) +{ + for (auto ¶m : function.get_function_params ()) + visit (param); +} + +void DefaultASTVisitor::visit (AST::Function &function) { visit_outer_attrs (function); @@ -828,8 +847,9 @@ DefaultASTVisitor::visit (AST::Function &function) visit (function.get_qualifiers ()); for (auto &generic : function.get_generic_params ()) visit (generic); - for (auto ¶m : function.get_function_params ()) - visit (param); + + visit_function_params (function); + if (function.has_return_type ()) visit (function.get_return_type ()); if (function.has_where_clause ()) diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index 51661df..b1fc504 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -131,6 +131,7 @@ public: virtual void visit (AwaitExpr &expr) = 0; virtual void visit (AsyncBlockExpr &expr) = 0; virtual void visit (InlineAsm &expr) = 0; + virtual void visit (LlvmInlineAsm &expr) = 0; // rust-item.h virtual void visit (TypeParam ¶m) = 0; @@ -241,6 +242,8 @@ public: class DefaultASTVisitor : public ASTVisitor { public: + virtual void visit_function_params (AST::Function &function); + virtual void visit (AST::Crate &crate); virtual void visit (AST::Token &tok) override; @@ -314,6 +317,7 @@ public: virtual void visit (AST::AwaitExpr &expr) override; virtual void visit (AST::AsyncBlockExpr &expr) override; virtual void visit (InlineAsm &expr) override; + virtual void visit (LlvmInlineAsm &expr) override; virtual void visit (AST::TypeParam ¶m) override; virtual void visit (AST::LifetimeWhereClauseItem &item) override; diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 06e0e7b..4e82be4 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -4651,6 +4651,12 @@ InlineAsm::accept_vis (ASTVisitor &vis) } void +LlvmInlineAsm::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void TypeParam::accept_vis (ASTVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 91611ec..aa6ad50 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -57,6 +57,11 @@ public: bool empty () const { return ident.empty (); } + bool operator== (const Identifier &other) const + { + return ident == other.ident; + } + private: std::string ident; location_t loc; @@ -1264,6 +1269,7 @@ public: Await, AsyncBlock, InlineAsm, + LlvmInlineAsm, Identifier, FormatArgs, MacroInvocation, @@ -2096,6 +2102,19 @@ template <> struct less<Rust::Identifier> return lhs.as_string () < rhs.as_string (); } }; + +template <> struct hash<Rust::Identifier> +{ + std::size_t operator() (const Rust::Identifier &k) const + { + using std::hash; + using std::size_t; + using std::string; + + return hash<string> () (k.as_string ()) ^ (hash<int> () (k.get_locus ())); + } +}; + } // namespace std #endif diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 69538df..fdb6360 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -4885,6 +4885,27 @@ struct InlineAsmRegOrRegClass location_t locus; }; +struct LlvmOperand +{ + std::string constraint; + std::unique_ptr<Expr> expr; + + LlvmOperand (std::string constraint, std::unique_ptr<Expr> &&expr) + : constraint (constraint), expr (std::move (expr)) + {} + + LlvmOperand (const LlvmOperand &other) + : constraint (other.constraint), expr (other.expr->clone_expr ()) + {} + LlvmOperand &operator= (const LlvmOperand &other) + { + constraint = other.constraint; + expr = other.expr->clone_expr (); + + return *this; + } +}; + class InlineAsmOperand { public: @@ -5258,6 +5279,7 @@ struct TupleTemplateStr location_t loc; std::string symbol; + location_t get_locus () { return loc; } TupleTemplateStr (location_t loc, const std::string &symbol) : loc (loc), symbol (symbol) {} @@ -5330,6 +5352,77 @@ public: Expr::Kind get_expr_kind () const override { return Expr::Kind::InlineAsm; } }; +class LlvmInlineAsm : public ExprWithoutBlock +{ + // llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile"); + // Asm, Outputs, Inputs, Clobbers, Options, + +public: + enum class Dialect + { + Att, + Intel, + }; + +private: + location_t locus; + std::vector<Attribute> outer_attrs; + std::vector<LlvmOperand> inputs; + std::vector<LlvmOperand> outputs; + std::vector<TupleTemplateStr> templates; + std::vector<TupleClobber> clobbers; + bool volatility; + bool align_stack; + Dialect dialect; + +public: + LlvmInlineAsm (location_t locus) : locus (locus) {} + + Dialect get_dialect () { return dialect; } + + location_t get_locus () const override { return locus; } + + void mark_for_strip () override {} + + bool is_marked_for_strip () const override { return false; } + + std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } + + void accept_vis (ASTVisitor &vis) override; + + std::string as_string () const override { return "InlineAsm AST Node"; } + + void set_outer_attrs (std::vector<Attribute> v) override { outer_attrs = v; } + + LlvmInlineAsm *clone_expr_without_block_impl () const override + { + return new LlvmInlineAsm (*this); + } + + std::vector<TupleTemplateStr> &get_templates () { return templates; } + + Expr::Kind get_expr_kind () const override + { + return Expr::Kind::LlvmInlineAsm; + } + + void set_align_stack (bool align_stack) { this->align_stack = align_stack; } + bool is_stack_aligned () { return align_stack; } + + void set_volatile (bool volatility) { this->volatility = volatility; } + bool is_volatile () { return volatility; } + + void set_dialect (Dialect dialect) { this->dialect = dialect; } + + void set_inputs (std::vector<LlvmOperand> operands) { inputs = operands; } + void set_outputs (std::vector<LlvmOperand> operands) { outputs = operands; } + + std::vector<LlvmOperand> &get_inputs () { return inputs; } + std::vector<LlvmOperand> &get_outputs () { return outputs; } + + std::vector<TupleClobber> &get_clobbers () { return clobbers; } +}; + } // namespace AST } // namespace Rust diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc index 69627be8..8e43ddf 100644 --- a/gcc/rust/ast/rust-path.cc +++ b/gcc/rust/ast/rust-path.cc @@ -119,7 +119,7 @@ ConstGenericParam::as_string () const str += "const " + name.as_string () + ": " + type->as_string (); if (has_default_value ()) - str += " = " + get_default_value ().as_string (); + str += " = " + get_default_value_unchecked ().as_string (); return str; } diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 805be8e..a4ba93b 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -167,17 +167,11 @@ public: */ enum class Kind { - Error, Const, // A const value Type, // A type argument (not discernable during parsing) Either, // Either a type or a const value, cleared up during resolving }; - static GenericArg create_error () - { - return GenericArg (nullptr, nullptr, {""}, Kind::Error, UNDEF_LOCATION); - } - static GenericArg create_const (std::unique_ptr<Expr> expression) { auto locus = expression->get_locus (); @@ -222,8 +216,6 @@ public: GenericArg (GenericArg &&other) = default; GenericArg &operator= (GenericArg &&other) = default; - bool is_error () const { return kind == Kind::Error; } - Kind get_kind () const { return kind; } location_t get_locus () const { return locus; } @@ -239,8 +231,6 @@ public: break; case Kind::Either: break; - case Kind::Error: - rust_unreachable (); } } @@ -283,8 +273,6 @@ public: { switch (get_kind ()) { - case Kind::Error: - rust_unreachable (); case Kind::Either: return "Ambiguous: " + path.as_string (); case Kind::Const: @@ -355,15 +343,15 @@ class ConstGenericParam : public GenericParam /** * Default value for the const generic parameter */ - GenericArg default_value; + tl::optional<GenericArg> default_value; AST::AttrVec outer_attrs; location_t locus; public: ConstGenericParam (Identifier name, std::unique_ptr<AST::Type> type, - GenericArg default_value, AST::AttrVec outer_attrs, - location_t locus) + tl::optional<GenericArg> default_value, + AST::AttrVec outer_attrs, location_t locus) : name (name), type (std::move (type)), default_value (std::move (default_value)), outer_attrs (outer_attrs), locus (locus) @@ -376,7 +364,7 @@ public: {} bool has_type () const { return type != nullptr; } - bool has_default_value () const { return !default_value.is_error (); } + bool has_default_value () const { return default_value.has_value (); } const Identifier &get_name () const { return name; } @@ -389,18 +377,18 @@ public: return *type; } - GenericArg &get_default_value () + GenericArg &get_default_value_unchecked () { rust_assert (has_default_value ()); - return default_value; + return default_value.value (); } - const GenericArg &get_default_value () const + const GenericArg &get_default_value_unchecked () const { rust_assert (has_default_value ()); - return default_value; + return default_value.value (); } std::string as_string () const override; |