Line data Source code
1 :
2 : #include "rust-ast-fragment.h"
3 : #include "rust-macro-builtins.h"
4 : #include "rust-macro-builtins-helpers.h"
5 : #include "expected.h"
6 : #include "rust-macro-invoc-lexer.h"
7 : #include "rust/ast/rust-expr.h"
8 : #include "system.h"
9 : namespace Rust {
10 :
11 : enum InlineAsmParseError
12 : {
13 : // Enum for InlineAsmParseError
14 :
15 : // Currently with two error, COMMITTED AND NONCOMMITTED (to a token),
16 : // which directs the parser to either bubbles the error up, or keep on going
17 : // (vertical or horizontal)
18 :
19 : // COMMITTED can be use as a way for parser to bubble up
20 : // after it has exhausted its search space despite it not having committed to
21 : // any token
22 :
23 : COMMITTED,
24 : NONCOMMITED,
25 : };
26 : class InlineAsmContext
27 : {
28 : public:
29 : bool allow_templates;
30 : bool is_explicit;
31 : bool consumed_comma_without_formatted_string;
32 : AST::InlineAsm &inline_asm;
33 : Parser<MacroInvocLexer> &parser;
34 : int last_token_id;
35 :
36 39 : InlineAsmContext (AST::InlineAsm &inline_asm, Parser<MacroInvocLexer> &parser,
37 : int last_token_id)
38 39 : : allow_templates (true), is_explicit (false),
39 39 : consumed_comma_without_formatted_string (false), inline_asm (inline_asm),
40 39 : parser (parser), last_token_id (last_token_id)
41 : {}
42 :
43 718 : InlineAsmContext (const InlineAsmContext &inline_asm_ctx)
44 718 : : allow_templates (inline_asm_ctx.allow_templates),
45 718 : is_explicit (inline_asm_ctx.is_explicit),
46 718 : consumed_comma_without_formatted_string (false),
47 718 : inline_asm (inline_asm_ctx.inline_asm), parser (inline_asm_ctx.parser),
48 689 : last_token_id (inline_asm_ctx.last_token_id)
49 : {}
50 : // explicit InlineAsmContext (InlineAsmContext&& inline_asm_ctx)
51 : // : allow_templates (inline_asm_ctx.allow_templates), is_explicit
52 : // (inline_asm_ctx.is_explicit),
53 : // consumed_comma_without_formatted_string (false), inline_asm
54 : // (inline_asm_ctx.inline_asm), parser (inline_asm_ctx.parser),
55 : // last_token_id (inline_asm_ctx.last_token_id)
56 : // {}
57 :
58 : // InlineAsmContext(tl::expected<InlineAsmContext, InlineAsmParseError>
59 : // &expected)
60 : // : allow_templates(expected->allow_templates),
61 : // is_explicit(expected->is_explicit),
62 : // consumed_comma_without_formatted_string(expected->consumed_comma_without_formatted_string),
63 : // inline_asm(expected->inline_asm), parser(expected->parser),
64 : // last_token_id(expected->last_token_id)
65 : // {
66 :
67 : // }
68 32 : InlineAsmContext &operator= (const InlineAsmContext &inline_asm_ctx)
69 : {
70 32 : allow_templates = inline_asm_ctx.allow_templates;
71 32 : is_explicit = inline_asm_ctx.is_explicit;
72 32 : consumed_comma_without_formatted_string = false;
73 32 : last_token_id = inline_asm_ctx.last_token_id;
74 32 : return *this;
75 : }
76 :
77 154 : bool is_global_asm () { return inline_asm.is_global_asm; }
78 :
79 : bool allows_templates () { return allow_templates; }
80 :
81 : void set_allow_templates (bool allow_templates)
82 : {
83 : this->allow_templates = allow_templates;
84 : }
85 : };
86 : WARN_UNUSED_RESULT
87 : tl::expected<InlineAsmContext, InlineAsmParseError>
88 : expand_inline_asm_strings (InlineAsmContext inline_asm_ctx);
89 :
90 : // Expected calls
91 : WARN_UNUSED_RESULT
92 : tl::expected<InlineAsmContext, InlineAsmParseError>
93 : validate (InlineAsmContext inline_asm_ctx);
94 :
95 : WARN_UNUSED_RESULT
96 : tl::expected<InlineAsmContext, InlineAsmParseError>
97 : parse_asm_arg (InlineAsmContext inline_asm_ctx);
98 :
99 : WARN_UNUSED_RESULT
100 : tl::expected<InlineAsmContext, InlineAsmParseError>
101 : parse_format_strings (InlineAsmContext inline_asm_ctx);
102 :
103 : WARN_UNUSED_RESULT
104 : tl::expected<InlineAsmContext, InlineAsmParseError>
105 : parse_clobber_abi (InlineAsmContext inline_asm_ctx);
106 :
107 : // From rustc
108 : WARN_UNUSED_RESULT
109 : tl::expected<InlineAsmContext, InlineAsmParseError>
110 : parse_reg_operand (InlineAsmContext inline_asm_ctx);
111 :
112 : WARN_UNUSED_RESULT
113 : tl::expected<InlineAsmContext, InlineAsmParseError>
114 : parse_reg_operand_in (InlineAsmContext inline_asm_ctx);
115 :
116 : WARN_UNUSED_RESULT
117 : tl::expected<InlineAsmContext, InlineAsmParseError>
118 : parse_reg_operand_out (InlineAsmContext inline_asm_ctx);
119 :
120 : WARN_UNUSED_RESULT
121 : tl::expected<InlineAsmContext, InlineAsmParseError>
122 : parse_reg_operand_lateout (InlineAsmContext inline_asm_ctx);
123 :
124 : WARN_UNUSED_RESULT
125 : tl::expected<InlineAsmContext, InlineAsmParseError>
126 : parse_reg_operand_inout (InlineAsmContext inline_asm_ctx);
127 :
128 : WARN_UNUSED_RESULT
129 : tl::expected<InlineAsmContext, InlineAsmParseError>
130 : parse_reg_operand_inlateout (InlineAsmContext inline_asm_ctx);
131 :
132 : WARN_UNUSED_RESULT
133 : tl::expected<InlineAsmContext, InlineAsmParseError>
134 : parse_reg_operand_const (InlineAsmContext inline_asm_ctx);
135 :
136 : WARN_UNUSED_RESULT
137 : tl::expected<InlineAsmContext, InlineAsmParseError>
138 : parse_reg_operand_sym (InlineAsmContext inline_asm_ctx);
139 :
140 : WARN_UNUSED_RESULT
141 : tl::expected<InlineAsmContext, InlineAsmParseError>
142 : parse_reg_operand_unexpected (InlineAsmContext inline_asm_ctx);
143 :
144 : WARN_UNUSED_RESULT
145 : tl::optional<AST::Fragment> parse_asm (location_t invoc_locus,
146 : AST::MacroInvocData &invoc,
147 : AST::InvocKind semicolon,
148 : AST::AsmKind is_global_asm);
149 :
150 : WARN_UNUSED_RESULT
151 : bool check_identifier (Parser<MacroInvocLexer> &parser, std::string ident);
152 :
153 : void check_and_set (InlineAsmContext &inline_asm_ctx,
154 : AST::InlineAsm::Option option);
155 :
156 : // From rustc
157 : WARN_UNUSED_RESULT
158 : tl::expected<InlineAsmContext, InlineAsmParseError>
159 : parse_options (InlineAsmContext &inline_asm_ctx);
160 :
161 : // From rustc
162 : WARN_UNUSED_RESULT
163 : tl::optional<AST::InlineAsmRegOrRegClass>
164 : parse_reg (InlineAsmContext &inline_asm_ctx);
165 :
166 : WARN_UNUSED_RESULT
167 : tl::optional<std::string>
168 : parse_format_string (InlineAsmContext &inline_asm_ctx);
169 :
170 : WARN_UNUSED_RESULT
171 : tl::optional<std::string> parse_label (Parser<MacroInvocLexer> &parser,
172 : TokenId last_token_id,
173 : InlineAsmContext &inline_asm_ctx);
174 :
175 : // LLVM ASM bits
176 :
177 : class LlvmAsmContext
178 : {
179 : public:
180 : AST::LlvmInlineAsm &llvm_asm;
181 : Parser<MacroInvocLexer> &parser;
182 : int last_token_id;
183 :
184 : public:
185 2 : LlvmAsmContext (AST::LlvmInlineAsm &llvm_asm, Parser<MacroInvocLexer> &parser,
186 : int last_token_id)
187 2 : : llvm_asm (llvm_asm), parser (parser), last_token_id (last_token_id)
188 : {}
189 : };
190 :
191 : void parse_llvm_outputs (LlvmAsmContext &ctx);
192 :
193 : void parse_llvm_inputs (LlvmAsmContext &ctx);
194 :
195 : void parse_llvm_clobbers (LlvmAsmContext &ctx);
196 :
197 : void parse_llvm_options (LlvmAsmContext &ctx);
198 :
199 : WARN_UNUSED_RESULT tl::optional<AST::Fragment>
200 : parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
201 : AST::InvocKind semicolon, AST::AsmKind is_global_asm);
202 :
203 : } // namespace Rust
|