// Copyright (C) 2020-2024 Free Software Foundation, Inc.
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
// You should have received a copy of the GNU General Public License
// along with GCC; see the file COPYING3. If not see
// .
#ifndef RUST_HIR_EXPR_ABSTRACT_H
#define RUST_HIR_EXPR_ABSTRACT_H
#include "rust-ast.h"
#include "rust-hir-visitable.h"
#include "rust-hir-node.h"
namespace Rust {
namespace HIR {
// Base expression HIR node - abstract
class Expr : public Node, virtual public FullVisitable
{
public:
using FullVisitable::accept_vis;
protected:
AST::AttrVec outer_attrs;
Analysis::NodeMapping mappings;
public:
enum BlockType
{
WITH_BLOCK,
WITHOUT_BLOCK,
};
enum ExprType
{
Lit,
Operator,
Grouped,
Array,
ArrayIndex,
Tuple,
TupleIdx,
Struct,
Call,
MethodCall,
FieldAccess,
Closure,
Block,
Continue,
Break,
Range,
Return,
UnsafeBlock,
BaseLoop,
If,
IfLet,
Match,
Await,
AsyncBlock,
Path,
InlineAsm,
};
BaseKind get_hir_kind () override final { return Node::BaseKind::EXPR; }
const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
// Unique pointer custom clone function
std::unique_ptr clone_expr () const
{
return std::unique_ptr (clone_expr_impl ());
}
// TODO: make pure virtual if move out outer attributes to derived classes
virtual std::string as_string () const;
virtual ~Expr () {}
virtual location_t get_locus () const = 0;
const Analysis::NodeMapping &get_mappings () const { return mappings; }
// Clone function implementation as pure virtual method
virtual Expr *clone_expr_impl () const = 0;
virtual BlockType get_block_expr_type () const = 0;
virtual ExprType get_expression_type () const = 0;
virtual void accept_vis (HIRExpressionVisitor &vis) = 0;
protected:
// Constructor
Expr (Analysis::NodeMapping mappings,
AST::AttrVec outer_attribs = AST::AttrVec ());
// TODO: think of less hacky way to implement this kind of thing
// Sets outer attributes.
void set_outer_attrs (AST::AttrVec outer_attrs_to_set)
{
outer_attrs = std::move (outer_attrs_to_set);
}
};
// HIR node for an expression without an accompanying block - abstract
class ExprWithoutBlock : public Expr
{
protected:
// Constructor
ExprWithoutBlock (Analysis::NodeMapping mappings,
AST::AttrVec outer_attribs = AST::AttrVec ());
// pure virtual clone implementation
virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
/* Save having to specify two clone methods in derived classes by making expr
* clone return exprwithoutblock clone. Hopefully won't affect performance too
* much. */
ExprWithoutBlock *clone_expr_impl () const override
{
return clone_expr_without_block_impl ();
}
public:
// Unique pointer custom clone function
std::unique_ptr clone_expr_without_block () const
{
return std::unique_ptr (clone_expr_without_block_impl ());
}
BlockType get_block_expr_type () const final override
{
return BlockType::WITHOUT_BLOCK;
};
};
// Base path expression HIR node - abstract
class PathExpr : public ExprWithoutBlock
{
protected:
PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attribs))
{}
public:
/* Replaces the outer attributes of this path expression with the given outer
* attributes. */
void replace_outer_attrs (AST::AttrVec outer_attrs)
{
set_outer_attrs (std::move (outer_attrs));
}
ExprType get_expression_type () const final override
{
return ExprType::Path;
}
};
} // namespace HIR
} // namespace Rust
#endif