blob: 3196a5ae184ca3a4222949606e8db4e6e9d1e8b3 [file] [log] [blame]
#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::InlineAsm::Option 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);
// LLVM ASM bits
class LlvmAsmContext
{
public:
AST::LlvmInlineAsm &llvm_asm;
Parser<MacroInvocLexer> &parser;
int last_token_id;
public:
LlvmAsmContext (AST::LlvmInlineAsm &llvm_asm, Parser<MacroInvocLexer> &parser,
int last_token_id)
: llvm_asm (llvm_asm), parser (parser), last_token_id (last_token_id)
{}
};
void parse_llvm_outputs (LlvmAsmContext &ctx);
void parse_llvm_inputs (LlvmAsmContext &ctx);
void parse_llvm_clobbers (LlvmAsmContext &ctx);
void parse_llvm_options (LlvmAsmContext &ctx);
WARN_UNUSED_RESULT tl::optional<AST::Fragment>
parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
AST::InvocKind semicolon, AST::AsmKind is_global_asm);
} // namespace Rust