forked from NUDT-compiler/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
4.1 KiB
101 lines
4.1 KiB
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "SysYParser.h"
|
|
#include "ir/IR.h"
|
|
#include "sem/Sema.h"
|
|
|
|
class IRGenImpl {
|
|
public:
|
|
IRGenImpl(ir::Module& module, const SemanticContext& sema);
|
|
|
|
void Gen(SysYParser::CompUnitContext& cu);
|
|
|
|
private:
|
|
struct StorageEntry {
|
|
ir::Value* storage = nullptr;
|
|
std::shared_ptr<ir::Type> declared_type;
|
|
bool is_array_param = false;
|
|
bool is_global = false;
|
|
bool is_const = false;
|
|
};
|
|
|
|
void DeclareBuiltins();
|
|
void GenGlobals(SysYParser::CompUnitContext& cu);
|
|
void GenFunctionDecls(SysYParser::CompUnitContext& cu);
|
|
void GenFunctionBodies(SysYParser::CompUnitContext& cu);
|
|
|
|
void GenFuncDef(SysYParser::FuncDefContext& func);
|
|
void GenBlock(SysYParser::BlockContext& block);
|
|
void GenBlockItem(SysYParser::BlockItemContext& item);
|
|
void GenDecl(SysYParser::DeclContext& decl);
|
|
void GenConstDecl(SysYParser::ConstDeclContext& decl);
|
|
void GenVarDecl(SysYParser::VarDeclContext& decl);
|
|
void GenStmt(SysYParser::StmtContext& stmt);
|
|
|
|
ir::Value* GenExpr(SysYParser::ExpContext& expr);
|
|
ir::Value* GenAddExpr(SysYParser::AddExpContext& add);
|
|
ir::Value* GenMulExpr(SysYParser::MulExpContext& mul);
|
|
ir::Value* GenUnaryExpr(SysYParser::UnaryExpContext& unary);
|
|
ir::Value* GenPrimary(SysYParser::PrimaryContext& primary);
|
|
ir::Value* GenRelExpr(SysYParser::RelExpContext& rel);
|
|
ir::Value* GenEqExpr(SysYParser::EqExpContext& eq);
|
|
|
|
ir::Value* GenLValueAddress(SysYParser::LValContext& lval);
|
|
ir::Value* GenLValueValue(SysYParser::LValContext& lval);
|
|
|
|
void GenCond(SysYParser::CondContext& cond, ir::BasicBlock* true_block,
|
|
ir::BasicBlock* false_block);
|
|
void GenLOrCond(SysYParser::LOrExpContext& expr, ir::BasicBlock* true_block,
|
|
ir::BasicBlock* false_block);
|
|
void GenLAndCond(SysYParser::LAndExpContext& expr, ir::BasicBlock* true_block,
|
|
ir::BasicBlock* false_block);
|
|
|
|
ir::Value* CastValue(ir::Value* value, const std::shared_ptr<ir::Type>& dst_type);
|
|
ir::Value* ToBool(ir::Value* value);
|
|
ir::Value* DecayArrayPointer(ir::Value* array_ptr);
|
|
|
|
void EnterScope();
|
|
void ExitScope();
|
|
void EnsureInsertableBlock();
|
|
void DeclareLocal(const std::string& name, StorageEntry entry);
|
|
StorageEntry* LookupStorage(const std::string& name);
|
|
const StorageEntry* LookupStorage(const std::string& name) const;
|
|
|
|
size_t CountScalars(const std::shared_ptr<ir::Type>& type) const;
|
|
std::vector<int> FlatIndexToIndices(const std::shared_ptr<ir::Type>& type,
|
|
size_t flat_index) const;
|
|
void EmitArrayStore(ir::Value* base_ptr, const std::shared_ptr<ir::Type>& array_type,
|
|
size_t flat_index, ir::Value* value);
|
|
void ZeroInitializeLocalArray(ir::Value* base_ptr,
|
|
const std::shared_ptr<ir::Type>& array_type);
|
|
void EmitLocalArrayInit(ir::Value* base_ptr, const std::shared_ptr<ir::Type>& array_type,
|
|
SysYParser::InitValContext& init);
|
|
void EmitLocalConstArrayInit(ir::Value* base_ptr,
|
|
const std::shared_ptr<ir::Type>& array_type,
|
|
SysYParser::ConstInitValContext& init);
|
|
|
|
ir::ConstantValue* BuildGlobalInitializer(const std::shared_ptr<ir::Type>& type,
|
|
SysYParser::InitValContext* init);
|
|
ir::ConstantValue* BuildGlobalConstInitializer(
|
|
const std::shared_ptr<ir::Type>& type, SysYParser::ConstInitValContext* init);
|
|
|
|
ir::Module& module_;
|
|
const SemanticContext& sema_;
|
|
ir::Function* current_function_ = nullptr;
|
|
std::shared_ptr<ir::Type> current_return_type_;
|
|
ir::IRBuilder builder_;
|
|
std::vector<std::unordered_map<std::string, StorageEntry>> local_scopes_;
|
|
std::unordered_map<std::string, StorageEntry> globals_;
|
|
std::vector<ir::BasicBlock*> break_targets_;
|
|
std::vector<ir::BasicBlock*> continue_targets_;
|
|
std::unordered_map<std::string, ConstantData> global_const_values_;
|
|
};
|
|
|
|
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
|
|
const SemanticContext& sema);
|