#pragma once #include "3rdparty/easylogging++.h" #include "common.h" #include "llir_type.h" #include #include #include #include #include #include namespace antlrSysY { class Value { public: std::string name; TypePtr_t type; Value(const std::string &name, TypePtr_t type) : name(name), type(type) {} virtual ~Value() = default; template static bool isValueType(std::shared_ptr ptr) { if (ptr.get()) { // auto &r = *ptr.get(); // return typeid(r) == typeid(TT); return dynamic_cast(ptr.get()) != nullptr; } LOG(WARNING) << "Comparing with nullptr"; assert(0); return false; } // it is caller's duty to check before use `asType` template static std::shared_ptr asValueType(std::shared_ptr ptr) { return std::dynamic_pointer_cast(ptr); } virtual std::string to_string() { return name + ": " + type->to_string(); } virtual std::string to_IR_string() { panic("No applicable for IR gen"); } }; class User : public Value { public: }; class BasicBlock; class Instruction; class FParam : public Value { public: int ir_seqno = -1; FParam(const std::string &name, TypePtr_t type) : Value(name, type) {} virtual std::string to_string() override { return type->to_string() + " @" + name + " %" + std::to_string(ir_seqno); } virtual std::string to_IR_string() override { return type->to_IR_string() + " %" + std::to_string(ir_seqno); } }; typedef std::list>::iterator BasicBlockListNode_t; class Function : public Value { public: std::vector> fparam_list; std::list> bb_list; // we use empty basic_block to represent lib function Function(const std::string &name, TypePtr_t ret_type) : Value(name, std::make_shared(ret_type)) {} std::shared_ptr get_type() { return std::dynamic_pointer_cast(type); } bool is_libfunc() { return bb_list.size() == 0; } virtual std::string to_string() override { std::string params_str; for (auto fparam : fparam_list) { params_str += fparam->to_string() + ","; } return name + "(" + params_str + ") -> " + type->to_string(); } }; class BasicBlock : public Value { public: int ir_seqno = -1; std::vector> inst_list; std::shared_ptr parent; BasicBlockListNode_t itr; std::vector> successors; std::vector> predecessors; BasicBlock(const std::string &name, std::shared_ptr parent) : Value(name, TypeHelper::TYPE_LABEL) { this->parent = parent; } }; typedef std::shared_ptr ValuePtr_t; typedef std::shared_ptr BasicBlockPtr_t; typedef std::shared_ptr FunctionPtr_t; class Constant : public Value { public: Constant(const std::string &name, TypePtr_t type) : Value(name, type) {} }; class ConstantInt : public Constant { public: int value; ConstantInt(const std::string &name, int value) : Constant(name, TypeHelper::TYPE_I32), value(value) {} static std::shared_ptr make_shared(int value) { return std::make_shared("", value); } virtual std::string to_string() override { std::string str = type->to_string() + " " + std::to_string(value); return str; } virtual std::string to_IR_string() override { return type->to_IR_string() + " " + std::to_string(value); } }; class ConstantArr : public Constant { public: std::vector value_list; ConstantArr(const std::string &name, const std::vector &value_list, std::shared_ptr type) : Constant(name, type), value_list(value_list) {} int real_size() const { return std::dynamic_pointer_cast(type)->element_count; } static std::shared_ptr make_shared( const std::string &name, const std::vector &value_list, std::shared_ptr type ) { return std::make_shared(name, value_list, type); } virtual std::string to_string() override { std::string str = "{"; for (auto elem : value_list) { if (elem) str += elem->to_string() + ", "; else str += "{...}, "; } if (real_size() > value_list.size()) { str += std::to_string(real_size() - value_list.size()) + " zeros"; } str += "}"; return str; } }; typedef std::shared_ptr ConstantPtr_t; // emmm, actually it is more of a Instruction type class GlobalVar : public Value { public: ConstantPtr_t init_value; bool is_const; GlobalVar(const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const) : Value(name, PointerType::make_shared(type)), init_value(init_value), is_const(is_const) {} static std::shared_ptr make_shared( const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const ) { return std::make_shared(name, type, init_value, is_const); } virtual std::string to_IR_string() override { std::string str = type->to_IR_string() + " @" + name; return str; } }; std::shared_ptr gen_arr_hierarchy( const std::shared_ptr array_type, const std::vector &const_array, int base, int length ); } // namespace antlrSysY