From: 0xn4utilus <[email protected]>
gcc/rust/ChangeLog:
* ast/rust-ast-collector.cc (TokenCollector::visit): Implement for
InlineAsm.
* ast/rust-ast-full-decls.h (enum class): Move InlineAsmOption enum
inside InlineAsm.
* ast/rust-expr.h (enum class): Likewise.
(class InlineAsm): Likewise.
* expand/rust-macro-builtins-asm.cc (check_and_set): Likewise.
(parse_options): Likewise.
* expand/rust-macro-builtins-asm.h (check_and_set): Likewise.
* hir/tree/rust-hir-expr.cc (InlineAsm::InlineAsm): Likewise.
* hir/tree/rust-hir-expr.h: Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Likewise.
---
gcc/rust/ast/rust-ast-collector.cc | 83 ++++++++++++++++++-
gcc/rust/ast/rust-ast-full-decls.h | 1 -
gcc/rust/ast/rust-expr.h | 59 +++++++++----
gcc/rust/expand/rust-macro-builtins-asm.cc | 35 +++-----
gcc/rust/expand/rust-macro-builtins-asm.h | 2 +-
gcc/rust/hir/tree/rust-hir-expr.cc | 2 +-
gcc/rust/hir/tree/rust-hir-expr.h | 6 +-
.../typecheck/rust-hir-type-check-expr.cc | 2 +-
8 files changed, 143 insertions(+), 47 deletions(-)
diff --git a/gcc/rust/ast/rust-ast-collector.cc
b/gcc/rust/ast/rust-ast-collector.cc
index c850e965cf4..538c6a411d1 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1518,7 +1518,88 @@ TokenCollector::visit (AsyncBlockExpr &expr)
void
TokenCollector::visit (InlineAsm &expr)
-{}
+{
+ push (Rust::Token::make_identifier (expr.get_locus (), "asm"));
+ push (Rust::Token::make (EXCLAM, expr.get_locus ()));
+ push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
+
+ for (auto &template_str : expr.get_template_strs ())
+ push (Rust::Token::make_string (template_str.get_locus (),
+ std::move (template_str.symbol)));
+
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+
+ for (auto &operand : expr.get_operands ())
+ {
+ using RegisterType = AST::InlineAsmOperand::RegisterType;
+ 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;
+ }
+ }
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+
+ for (auto &clobber : expr.get_clobber_abi ())
+ {
+ 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 ()));
+
+ for (auto it = expr.named_args.begin (); it != expr.named_args.end (); ++it)
+ {
+ auto &arg = *it;
+ push (
+ Rust::Token::make_identifier (expr.get_locus (), arg.first.c_str ()));
+ push (Rust::Token::make (EQUAL, expr.get_locus ()));
+ push (Rust::Token::make_identifier (expr.get_locus (),
+ std::to_string (arg.second)));
+
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+
+ for (auto &option : expr.get_options ())
+ {
+ push (Rust::Token::make_identifier (
+ expr.get_locus (), InlineAsm::option_to_string (option).c_str ()));
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+
+ push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
+}
void
TokenCollector::visit (LlvmInlineAsm &expr)
diff --git a/gcc/rust/ast/rust-ast-full-decls.h
b/gcc/rust/ast/rust-ast-full-decls.h
index 9359248aabd..1d5853d0deb 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -145,7 +145,6 @@ struct MatchCase;
class MatchExpr;
class AwaitExpr;
class AsyncBlockExpr;
-enum class InlineAsmOption;
struct AnonConst;
struct InlineAsmRegOrRegClass;
class InlineAsmOperand;
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index fdb6360eb3b..9ecca225103 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4822,20 +4822,6 @@ protected:
}
};
-// Inline-assembly specific options
-enum class InlineAsmOption
-{
- PURE = 1 << 0,
- NOMEM = 1 << 1,
- READONLY = 1 << 2,
- PRESERVES_FLAGS = 1 << 3,
- NORETURN = 1 << 4,
- NOSTACK = 1 << 5,
- ATT_SYNTAX = 1 << 6,
- RAW = 1 << 7,
- MAY_UNWIND = 1 << 8,
-};
-
struct AnonConst
{
NodeId id;
@@ -5288,6 +5274,20 @@ struct TupleTemplateStr
// Inline Assembly Node
class InlineAsm : public ExprWithoutBlock
{
+public:
+ enum class Option
+ {
+ PURE = 1 << 0,
+ NOMEM = 1 << 1,
+ READONLY = 1 << 2,
+ PRESERVES_FLAGS = 1 << 3,
+ NORETURN = 1 << 4,
+ NOSTACK = 1 << 5,
+ ATT_SYNTAX = 1 << 6,
+ RAW = 1 << 7,
+ MAY_UNWIND = 1 << 8,
+ };
+
private:
location_t locus;
// TODO: Not sure how outer_attrs plays with InlineAsm, I put it here in
order
@@ -5311,7 +5311,7 @@ public:
std::map<std::string, int> named_args;
std::set<int> reg_args;
std::vector<TupleClobber> clobber_abi;
- std::set<InlineAsmOption> options;
+ std::set<InlineAsm::Option> options;
std::vector<location_t> line_spans;
@@ -5342,7 +5342,7 @@ public:
std::vector<TupleClobber> get_clobber_abi () { return clobber_abi; }
- std::set<InlineAsmOption> get_options () { return options; }
+ std::set<InlineAsm::Option> get_options () { return options; }
InlineAsm *clone_expr_without_block_impl () const override
{
@@ -5350,6 +5350,33 @@ public:
}
Expr::Kind get_expr_kind () const override { return Expr::Kind::InlineAsm; }
+
+ static std::string option_to_string (Option option)
+ {
+ switch (option)
+ {
+ case Option::PURE:
+ return "pure";
+ case Option::NOMEM:
+ return "nomem";
+ case Option::READONLY:
+ return "readonly";
+ case Option::PRESERVES_FLAGS:
+ return "preserves_flags";
+ case Option::NORETURN:
+ return "noreturn";
+ case Option::NOSTACK:
+ return "nostack";
+ case Option::ATT_SYNTAX:
+ return "att_syntax";
+ case Option::RAW:
+ return "raw";
+ case Option::MAY_UNWIND:
+ return "may_unwind";
+ default:
+ rust_unreachable ();
+ }
+ }
};
class LlvmInlineAsm : public ExprWithoutBlock
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index e255729885b..ca3c22e7f8b 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -25,18 +25,6 @@
#include "rust-parse.h"
namespace Rust {
-std::map<AST::InlineAsmOption, std::string> InlineAsmOptionMap{
- {AST::InlineAsmOption::PURE, "pure"},
- {AST::InlineAsmOption::NOMEM, "nomem"},
- {AST::InlineAsmOption::READONLY, "readonly"},
- {AST::InlineAsmOption::PRESERVES_FLAGS, "preserves_flags"},
- {AST::InlineAsmOption::NORETURN, "noreturn"},
- {AST::InlineAsmOption::NOSTACK, "nostack"},
- {AST::InlineAsmOption::MAY_UNWIND, "may_unwind"},
- {AST::InlineAsmOption::ATT_SYNTAX, "att_syntax"},
- {AST::InlineAsmOption::RAW, "raw"},
-};
-
std::set<std::string> potentially_nonpromoted_keywords
= {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};
@@ -500,7 +488,7 @@ parse_reg_operand_unexpected (InlineAsmContext
inline_asm_ctx)
}
void
-check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsmOption option)
+check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsm::Option option)
{
auto &parser = inline_asm_ctx.parser;
auto &inline_asm = inline_asm_ctx.inline_asm;
@@ -509,7 +497,7 @@ check_and_set (InlineAsmContext &inline_asm_ctx,
AST::InlineAsmOption option)
// TODO: report an error of duplication
rust_error_at (parser.peek_current_token ()->get_locus (),
"the %qs option was already provided",
- InlineAsmOptionMap[option].c_str ());
+ AST::InlineAsm::option_to_string (option).c_str ());
return;
}
else
@@ -536,39 +524,40 @@ parse_options (InlineAsmContext &inline_asm_ctx)
{
if (!is_global_asm && check_identifier (parser, "pure"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::PURE);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::PURE);
}
else if (!is_global_asm && check_identifier (parser, "nomem"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::NOMEM);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::NOMEM);
}
else if (!is_global_asm && check_identifier (parser, "readonly"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::READONLY);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::READONLY);
}
else if (!is_global_asm && check_identifier (parser, "preserves_flags"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::PRESERVES_FLAGS);
+ check_and_set (inline_asm_ctx,
+ AST::InlineAsm::Option::PRESERVES_FLAGS);
}
else if (!is_global_asm && check_identifier (parser, "noreturn"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::NORETURN);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::NORETURN);
}
else if (!is_global_asm && check_identifier (parser, "nostack"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::NOSTACK);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::NOSTACK);
}
else if (!is_global_asm && check_identifier (parser, "may_unwind"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::MAY_UNWIND);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::MAY_UNWIND);
}
else if (check_identifier (parser, "att_syntax"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::ATT_SYNTAX);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::ATT_SYNTAX);
}
else if (check_identifier (parser, "raw"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::RAW);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::RAW);
}
else
{
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h
b/gcc/rust/expand/rust-macro-builtins-asm.h
index bd64a7f4dd6..2bdaed5e08f 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -151,7 +151,7 @@ bool
check_identifier (Parser<MacroInvocLexer> &parser, std::string ident);
void
-check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsmOption option);
+check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsm::Option
option);
// From rustc
WARN_UNUSED_RESULT
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc
b/gcc/rust/hir/tree/rust-hir-expr.cc
index 266c79c2fe8..5df9253aae2 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.cc
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -1476,7 +1476,7 @@ InlineAsm::InlineAsm (location_t locus, bool
is_global_asm,
std::vector<AST::TupleTemplateStr> template_strs,
std::vector<HIR::InlineAsmOperand> operands,
std::vector<AST::TupleClobber> clobber_abi,
- std::set<AST::InlineAsmOption> options,
+ std::set<AST::InlineAsm::Option> options,
Analysis::NodeMapping mappings,
AST::AttrVec outer_attribs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h
b/gcc/rust/hir/tree/rust-hir-expr.h
index 375f47402f0..6fbe1e48e1b 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -3059,7 +3059,7 @@ public:
std::vector<AST::TupleTemplateStr> template_strs;
std::vector<HIR::InlineAsmOperand> operands;
std::vector<AST::TupleClobber> clobber_abi;
- std::set<AST::InlineAsmOption> options;
+ std::set<AST::InlineAsm::Option> options;
std::vector<location_t> line_spans;
@@ -3094,7 +3094,7 @@ public:
std::vector<AST::TupleClobber> get_clobber_abi () { return clobber_abi; }
- std::set<AST::InlineAsmOption> get_options () { return options; }
+ std::set<AST::InlineAsm::Option> get_options () { return options; }
bool is_simple_asm ()
{
@@ -3113,7 +3113,7 @@ public:
std::vector<AST::TupleTemplateStr> template_strs,
std::vector<HIR::InlineAsmOperand> operands,
std::vector<AST::TupleClobber> clobber_abi,
- std::set<AST::InlineAsmOption> options,
+ std::set<AST::InlineAsm::Option> options,
Analysis::NodeMapping mappings,
AST::AttrVec outer_attribs = AST::AttrVec ());
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index cbf529a77eb..7283d01d5a3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -837,7 +837,7 @@ TypeCheckExpr::visit (HIR::InlineAsm &expr)
// NOTE: Hoise out if we have noreturn as an option
// to return a never type
// TODO : new keyword for memory seems sooooo shaky
- if (expr.options.count (AST::InlineAsmOption::NORETURN) == 1)
+ if (expr.options.count (AST::InlineAsm::Option::NORETURN) == 1)
infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
else
infered = TyTy::TupleType::get_unit_type ();
--
2.49.0