aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/expand/rust-macro-builtins-asm.h
blob: 8081dae51409e13a0cb582b0476e2922ac7e09b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

#include "rust-ast-fragment.h"
#include "rust-macro-builtins.h"
#include "rust-macro-builtins-helpers.h"
#include "expected.h"
#include "rust-macro-invoc-lexer.h"
#include "rust/ast/rust-expr.h"
#include "system.h"
namespace Rust {

enum InlineAsmParseError
{
  // Enum for InlineAsmParseError

  // Currently with two error, COMMITTED AND NONCOMMITTED (to a token),
  // which directs the parser to either bubbles the error up, or keep on going
  // (vertical or horizontal)

  // COMMITTED can be use as a way for parser to bubble up
  // after it has exhausted its search space despite it not having committed to
  // any token

  COMMITTED,
  NONCOMMITED,
};
class InlineAsmContext
{
public:
  bool allow_templates;
  bool is_explicit;
  bool consumed_comma_without_formatted_string;
  AST::InlineAsm &inline_asm;
  Parser<MacroInvocLexer> &parser;
  int last_token_id;

  InlineAsmContext (AST::InlineAsm &inline_asm, Parser<MacroInvocLexer> &parser,
		    int last_token_id)
    : allow_templates (true), is_explicit (false),
      consumed_comma_without_formatted_string (false), inline_asm (inline_asm),
      parser (parser), last_token_id (last_token_id)
  {}

  InlineAsmContext (const InlineAsmContext &inline_asm_ctx)
    : allow_templates (inline_asm_ctx.allow_templates),
      is_explicit (inline_asm_ctx.is_explicit),
      consumed_comma_without_formatted_string (false),
      inline_asm (inline_asm_ctx.inline_asm), parser (inline_asm_ctx.parser),
      last_token_id (inline_asm_ctx.last_token_id)
  {}
  // explicit InlineAsmContext (InlineAsmContext&& inline_asm_ctx)
  //   : allow_templates (inline_asm_ctx.allow_templates), is_explicit
  //   (inline_asm_ctx.is_explicit),
  //     consumed_comma_without_formatted_string (false), inline_asm
  //     (inline_asm_ctx.inline_asm), parser (inline_asm_ctx.parser),
  //     last_token_id (inline_asm_ctx.last_token_id)
  // {}

  // InlineAsmContext(tl::expected<InlineAsmContext, InlineAsmParseError>
  // &expected)
  //     : allow_templates(expected->allow_templates),
  //     is_explicit(expected->is_explicit),
  //       consumed_comma_without_formatted_string(expected->consumed_comma_without_formatted_string),
  //       inline_asm(expected->inline_asm), parser(expected->parser),
  //       last_token_id(expected->last_token_id)
  // {

  // }
  InlineAsmContext &operator= (const InlineAsmContext &inline_asm_ctx)
  {
    allow_templates = inline_asm_ctx.allow_templates;
    is_explicit = inline_asm_ctx.is_explicit;
    consumed_comma_without_formatted_string = false;
    last_token_id = inline_asm_ctx.last_token_id;
    return *this;
  }

  bool is_global_asm () { return inline_asm.is_global_asm; }

  bool allows_templates () { return allow_templates; }

  void set_allow_templates (bool allow_templates)
  {
    this->allow_templates = allow_templates;
  }
};
WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
expand_inline_asm_strings (InlineAsmContext inline_asm_ctx);

// Expected calls
WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
validate (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_asm_arg (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_format_strings (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_clobber_abi (InlineAsmContext inline_asm_ctx);

// From rustc
WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_in (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_out (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_lateout (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_inout (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_inlateout (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_const (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_sym (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_unexpected (InlineAsmContext inline_asm_ctx);

WARN_UNUSED_RESULT
tl::optional<AST::Fragment>
parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
	   AST::InvocKind semicolon, AST::AsmKind is_global_asm);

WARN_UNUSED_RESULT
bool
check_identifier (Parser<MacroInvocLexer> &parser, std::string ident);

void
check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsmOption option);

// From rustc
WARN_UNUSED_RESULT
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_options (InlineAsmContext &inline_asm_ctx);

// From rustc
WARN_UNUSED_RESULT
tl::optional<AST::InlineAsmRegOrRegClass>
parse_reg (InlineAsmContext &inline_asm_ctx);

WARN_UNUSED_RESULT
tl::optional<std::string>
parse_format_string (InlineAsmContext &inline_asm_ctx);

WARN_UNUSED_RESULT
tl::optional<std::string>
parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
	     InlineAsmContext &inline_asm_ctx);

} // namespace Rust