控制流if,break,while,continue实现,条件跳转,无条件跳转实现,函数参数,函数类型系统完善

LuoHello 3 weeks ago
parent affccfb27c
commit bc4400c1c7

@ -95,7 +95,8 @@ class Context {
class Type {
public:
enum class Kind { Void, Int32, Float, PtrInt32, PtrFloat, Label, Array, Function };
enum class Kind { Void, Int32, Float, PtrInt32, PtrFloat, Label, Array, Function,
Int1, PtrInt1};
virtual ~Type() = default;
@ -110,7 +111,10 @@ class Type {
static const std::shared_ptr<Type>& GetLabelType();
static std::shared_ptr<ArrayType> GetArrayType(std::shared_ptr<Type> elem, std::vector<int> dims);
static std::shared_ptr<FunctionType> GetFunctionType(std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params);
static const std::shared_ptr<Type>& GetInt1Type();
static const std::shared_ptr<Type>& GetPtrInt1Type();
// 类型判断
Kind GetKind() const { return kind_; }
bool IsVoid() const { return kind_ == Kind::Void; }
@ -121,6 +125,8 @@ class Type {
bool IsLabel() const { return kind_ == Kind::Label; }
bool IsArray() const { return kind_ == Kind::Array; }
bool IsFunction() const { return kind_ == Kind::Function; }
bool IsInt1() const { return kind_ == Kind::Int1; }
bool IsPtrInt1() const { return kind_ == Kind::PtrInt1; }
// 类型属性
virtual size_t Size() const; // 字节大小
@ -221,7 +227,9 @@ class Argument : public Value {
};
// 后续还需要扩展更多指令类型。add call instruction 只是最小占位,后续可以继续补 sub/mul/div/rem、br/condbr、phi、gep 等指令。
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret, Call };
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret, Call,
Br, CondBr, Icmp, ZExt, Trunc };
// ZExt 和 Trunc 是零扩展和截断指令,SysY 的 int (i32) vs LLVM IR 的比较结果 (i1)。
// User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。
// 当前实现中只有 Instruction 继承自 User。
@ -231,7 +239,16 @@ class User : public Value {
size_t GetNumOperands() const;
Value* GetOperand(size_t index) const;
void SetOperand(size_t index, Value* value);
// 添加模板方法,支持派生类自动转换
template<typename T>
void SetOperand(size_t index, T* value) {
SetOperand(index, static_cast<Value*>(value));
}
template<typename T>
void AddOperand(T* value) {
AddOperand(static_cast<Value*>(value));
}
protected:
// 统一的 operand 入口。
void AddOperand(Value* value);
@ -292,6 +309,199 @@ class StoreInst : public Instruction {
Value* GetPtr() const;
};
// 在 IR.h 中修改 BranchInst 类定义
class BranchInst : public Instruction {
public:
// 无条件跳转构造函数
BranchInst(std::shared_ptr<Type> void_ty, BasicBlock* target)
: Instruction(Opcode::Br, void_ty, ""),
is_conditional_(false),
cond_(nullptr),
target_(target),
true_target_(nullptr),
false_target_(nullptr) {}
// 条件跳转构造函数
BranchInst(std::shared_ptr<Type> void_ty, Value* cond,
BasicBlock* true_target, BasicBlock* false_target)
: Instruction(Opcode::CondBr, void_ty, ""),
is_conditional_(true),
cond_(cond),
target_(nullptr),
true_target_(true_target),
false_target_(false_target) {
// 添加操作数以便维护 def-use 关系
AddOperand(cond);
// 注意BasicBlock 也是 Value也需要添加到操作数中
// 但 BasicBlock 继承自 Value所以可以添加
AddOperand(true_target);
AddOperand(false_target);
}
// 判断是否为条件跳转
bool IsConditional() const { return is_conditional_; }
// 获取无条件跳转的目标(仅适用于无条件跳转)
BasicBlock* GetTarget() const {
if (is_conditional_) {
throw std::runtime_error("GetTarget called on conditional branch");
}
return target_;
}
// 获取条件值(仅适用于条件跳转)
Value* GetCondition() const {
if (!is_conditional_) {
throw std::runtime_error("GetCondition called on unconditional branch");
}
return cond_;
}
// 获取真分支目标(仅适用于条件跳转)
BasicBlock* GetTrueTarget() const {
if (!is_conditional_) {
throw std::runtime_error("GetTrueTarget called on unconditional branch");
}
return true_target_;
}
// 获取假分支目标(仅适用于条件跳转)
BasicBlock* GetFalseTarget() const {
if (!is_conditional_) {
throw std::runtime_error("GetFalseTarget called on unconditional branch");
}
return false_target_;
}
// 设置无条件跳转目标
void SetTarget(BasicBlock* target) {
if (is_conditional_) {
throw std::runtime_error("SetTarget called on conditional branch");
}
target_ = target;
}
// 设置条件跳转的分支目标
void SetTrueTarget(BasicBlock* target) {
if (!is_conditional_) {
throw std::runtime_error("SetTrueTarget called on unconditional branch");
}
true_target_ = target;
// 更新操作数
SetOperand(1, target);
}
void SetFalseTarget(BasicBlock* target) {
if (!is_conditional_) {
throw std::runtime_error("SetFalseTarget called on unconditional branch");
}
false_target_ = target;
// 更新操作数
SetOperand(2, target);
}
void SetCondition(Value* cond) {
if (!is_conditional_) {
throw std::runtime_error("SetCondition called on unconditional branch");
}
cond_ = cond;
// 更新操作数
SetOperand(0, cond);
}
private:
bool is_conditional_;
Value* cond_; // 条件值(条件跳转使用)
BasicBlock* target_; // 无条件跳转目标
BasicBlock* true_target_; // 真分支目标(条件跳转使用)
BasicBlock* false_target_; // 假分支目标(条件跳转使用)
};
// 创建整数比较指令
class IcmpInst : public Instruction {
public:
enum class Predicate {
EQ, // equal
NE, // not equal
LT, // less than
LE, // less than or equal
GT, // greater than
GE // greater than or equal
};
IcmpInst(Predicate pred, Value* lhs, Value* rhs, std::shared_ptr<Type> i1_ty, std::string name)
: Instruction(Opcode::Icmp, i1_ty, name), pred_(pred) {
AddOperand(lhs);
AddOperand(rhs);
}
Predicate GetPredicate() const { return pred_; }
Value* GetLhs() const { return GetOperand(0); }
Value* GetRhs() const { return GetOperand(1); }
private:
Predicate pred_;
};
// ZExtInst - 零扩展指令
class ZExtInst : public Instruction {
public:
ZExtInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::ZExt, target_ty, name) {
AddOperand(value);
}
// 获取被扩展的值
Value* GetValue() const {
return GetOperand(0);
}
// 获取源类型
std::shared_ptr<Type> GetSourceType() const {
return GetValue()->GetType();
}
// 获取目标类型
std::shared_ptr<Type> GetTargetType() const {
return GetType();
}
// 设置被扩展的值
void SetValue(Value* value) {
SetOperand(0, value);
}
};
// TruncInst - 截断指令
class TruncInst : public Instruction {
public:
TruncInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::Trunc, target_ty, name) {
AddOperand(value);
}
// 获取被截断的值
Value* GetValue() const {
return GetOperand(0);
}
// 获取源类型
std::shared_ptr<Type> GetSourceType() const {
return GetValue()->GetType();
}
// 获取目标类型
std::shared_ptr<Type> GetTargetType() const {
return GetType();
}
// 设置被截断的值
void SetValue(Value* value) {
SetOperand(0, value);
}
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
class BasicBlock : public Value {
@ -367,11 +577,15 @@ class Module {
// 创建函数时传入完整的 FunctionType。
Function* CreateFunction(const std::string& name,
std::shared_ptr<FunctionType> func_type);
GlobalValue* CreateGlobal(const std::string& name,
std::shared_ptr<Type> ty);
const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
const std::vector<std::unique_ptr<GlobalValue>>& GetGlobals() const;
private:
Context context_;
std::vector<std::unique_ptr<Function>> functions_;
std::vector<std::unique_ptr<GlobalValue>> globals_;
};
class IRBuilder {
@ -393,6 +607,33 @@ class IRBuilder {
CallInst* CreateCall(Function* callee, const std::vector<Value*>& args,
const std::string& name);
// 创建无条件跳转
BranchInst* CreateBr(BasicBlock* target);
// 创建条件跳转
BranchInst* CreateCondBr(Value* cond, BasicBlock* true_target,
BasicBlock* false_target);
// 创建整数比较指令
IcmpInst* CreateICmpEQ(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpNE(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpLT(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpLE(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpGT(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpGE(Value* lhs, Value* rhs, const std::string& name);
// 创建类型转换指令
ZExtInst* CreateZExt(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
TruncInst* CreateTrunc(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
// 便捷方法
ZExtInst* CreateZExtI1ToI32(Value* value, const std::string& name = "zext");
TruncInst* CreateTruncI32ToI1(Value* value, const std::string& name = "trunc");
private:
Context& ctx_;
BasicBlock* insert_block_;

@ -41,6 +41,7 @@ class IRGenImpl final : public SysYBaseVisitor {
// 表达式
// 基本表达式(变量、常量、括号表达式)直接翻译为 IR 中的值;函数调用和一元运算需要特殊处理。
std::any visitExp(SysYParser::ExpContext* ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
// 一元表达式包括函数调用和一元运算,需要特殊处理
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override;

File diff suppressed because it is too large Load Diff

@ -35,7 +35,7 @@ total=0
passed=0
failed=0
echo "开始测试 SysY 解析..."
echo "开始测试 ir out 解析..."
echo "输出将保存到 $RESULT_FILE"
echo "------------------------"
@ -59,10 +59,10 @@ for file in "${TEST_FILES[@]}"; do
echo "========== $file ==========" >> "$RESULT_FILE"
if [ $VERBOSE -eq 1 ]; then
"$COMPILER" --emit-parse-tree "$file" 2>&1 | tee -a "$RESULT_FILE"
"$COMPILER" --emit-ir "$file" 2>&1 | tee -a "$RESULT_FILE"
result=${PIPESTATUS[0]}
else
"$COMPILER" --emit-parse-tree "$file" >> "$RESULT_FILE" 2>&1
"$COMPILER" --emit-ir "$file" >> "$RESULT_FILE" 2>&1
result=$?
fi

@ -0,0 +1,121 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPILER="$ROOT_DIR/build/bin/compiler"
TMP_DIR="$ROOT_DIR/build/test_compiler"
TEST_DIRS=("$ROOT_DIR/test/test_case/functional" "$ROOT_DIR/test/test_case/performance")
if [[ ! -x "$COMPILER" ]]; then
echo "未找到编译器: $COMPILER"
echo "请先构建编译器,例如: mkdir -p build && cd build && cmake .. && make -j"
exit 1
fi
mkdir -p "$TMP_DIR"
ir_total=0
ir_pass=0
result_total=0
result_pass=0
ir_failures=()
result_failures=()
function normalize_file() {
sed 's/\r$//' "$1"
}
for test_dir in "${TEST_DIRS[@]}"; do
if [[ ! -d "$test_dir" ]]; then
echo "跳过不存在的测试目录: $test_dir"
continue
fi
shopt -s nullglob
for input in "$test_dir"/*.sy; do
ir_total=$((ir_total+1))
base=$(basename "$input")
stem=${base%.sy}
out_dir="$TMP_DIR/$(basename "$test_dir")"
mkdir -p "$out_dir"
ll_file="$out_dir/$stem.ll"
stdout_file="$out_dir/$stem.stdout"
expected_file="$test_dir/$stem.out"
stdin_file="$test_dir/$stem.in"
echo "[TEST] $input"
compiler_status=0
compiler_output=
compiler_output=$("$COMPILER" --emit-ir "$input" 2>&1) || compiler_status=$?
printf '%s\n' "$compiler_output" | sed '/^\[DEBUG/d' > "$ll_file"
if [[ $compiler_status -ne 0 ]]; then
echo " [IR] 编译失败: 返回码 $compiler_status"
ir_failures+=("$input: compiler failed ($compiler_status)")
continue
fi
if ! grep -qE '^define ' "$ll_file"; then
echo " [IR] 失败: 未生成有效函数定义"
ir_failures+=("$input: invalid IR output")
continue
fi
ir_pass=$((ir_pass+1))
echo " [IR] 生成成功"
if [[ -f "$expected_file" ]]; then
result_total=$((result_total+1))
expected=$(normalize_file "$expected_file")
run_status=0
if [[ -f "$stdin_file" ]]; then
lli "$ll_file" < "$stdin_file" > "$stdout_file" 2>&1 || run_status=$?
else
lli "$ll_file" > "$stdout_file" 2>&1 || run_status=$?
fi
if [[ ! -s "$stdout_file" && "$expected" =~ ^-?[0-9]+$ ]]; then
if [[ "$run_status" -eq "$expected" ]]; then
result_pass=$((result_pass+1))
echo " [RUN] 返回码匹配"
else
echo " [RUN] 返回码不匹配: got $run_status"
result_failures+=("$input: exit code mismatch (got $run_status)")
fi
else
if diff -u <(printf '%s\n' "$expected") <(normalize_file "$stdout_file") > "$out_dir/$stem.diff"; then
result_pass=$((result_pass+1))
echo " [RUN] 输出匹配"
else
echo " [RUN] 输出不匹配"
result_failures+=("$input: output mismatch")
fi
fi
else
echo " [RUN] 未找到预期输出 $expected_file,跳过结果验证"
fi
done
shopt -u nullglob
done
cat <<EOF
测试完成。
IR 生成: $ir_pass / $ir_total
结果匹配: $result_pass / $result_total
EOF
if [[ ${#ir_failures[@]} -gt 0 ]]; then
echo "\nIR 失败列表:"
for item in "${ir_failures[@]}"; do
echo " $item"
done
fi
if [[ ${#result_failures[@]} -gt 0 ]]; then
echo "\n结果失败列表:"
for item in "${result_failures[@]}"; do
echo " $item"
done
fi

@ -17,7 +17,7 @@ ConstantInt* Context::GetConstInt(int v) {
std::string Context::NextTemp() {
std::ostringstream oss;
oss << "%" << ++temp_index_;
oss << "%t" << ++temp_index_;
return oss.str();
}

@ -117,4 +117,214 @@ CallInst* IRBuilder::CreateCall(Function* callee,
return insert_block_->Append<CallInst>(ret_ty, callee, args, name);
}
BranchInst* IRBuilder::CreateBr(BasicBlock* target) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!target) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateBr 缺少 target"));
}
return insert_block_->Append<BranchInst>(Type::GetVoidType(), target);
}
BranchInst* IRBuilder::CreateCondBr(Value* cond, BasicBlock* true_target,
BasicBlock* false_target) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!cond) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateCondBr 缺少 cond"));
}
if (!true_target) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateCondBr 缺少 true_target"));
}
if (!false_target) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateCondBr 缺少 false_target"));
}
return insert_block_->Append<BranchInst>(Type::GetVoidType(), cond, true_target, false_target);
}
// 创建整数相等比较
IcmpInst* IRBuilder::CreateICmpEQ(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpEQ 缺少操作数"));
}
// 检查类型必须一致
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::EQ, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数不等比较
IcmpInst* IRBuilder::CreateICmpNE(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpNE 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::NE, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数小于比较
IcmpInst* IRBuilder::CreateICmpLT(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpLT 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::LT, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数小于等于比较
IcmpInst* IRBuilder::CreateICmpLE(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpLE 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::LE, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数大于比较
IcmpInst* IRBuilder::CreateICmpGT(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpGT 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::GT, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数大于等于比较
IcmpInst* IRBuilder::CreateICmpGE(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpGE 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::GE, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建零扩展指令
ZExtInst* IRBuilder::CreateZExt(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!value) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateZExt 缺少 value"));
}
if (!target_ty) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateZExt 缺少 target_ty"));
}
auto src_ty = value->GetType();
// 类型检查:源类型应该是较小的整数类型
if (!src_ty->IsInt1() && !src_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "ZExt 源类型必须是整数类型"));
}
// 目标类型应该是较大的整数类型
if (!target_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "ZExt 目标类型必须是整数类型"));
}
return insert_block_->Append<ZExtInst>(value, target_ty, name);
}
// 创建截断指令
TruncInst* IRBuilder::CreateTrunc(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!value) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateTrunc 缺少 value"));
}
if (!target_ty) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateTrunc 缺少 target_ty"));
}
auto src_ty = value->GetType();
// 类型检查:源类型应该是较大的整数类型
if (!src_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "Trunc 源类型必须是整数类型"));
}
// 目标类型应该是较小的整数类型
if (!target_ty->IsInt1() && !target_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "Trunc 目标类型必须是整数类型"));
}
return insert_block_->Append<TruncInst>(value, target_ty, name);
}
// 便捷方法i1 转 i32
ZExtInst* IRBuilder::CreateZExtI1ToI32(Value* value, const std::string& name) {
return CreateZExt(value, Type::GetInt32Type(), name);
}
// 便捷方法i32 转 i1
TruncInst* IRBuilder::CreateTruncI32ToI1(Value* value, const std::string& name) {
return CreateTrunc(value, Type::GetInt1Type(), name);
}
} // namespace ir

@ -22,6 +22,8 @@ static const char* TypeToString(const Type& ty) {
case Type::Kind::Label: return "label";
case Type::Kind::Array: return "array";
case Type::Kind::Function: return "function";
case Type::Kind::Int1: return "i1";
case Type::Kind::PtrInt1: return "i1*";
default: return "unknown";
}
throw std::runtime_error(FormatError("ir", "未知类型"));
@ -45,6 +47,12 @@ static const char* OpcodeToString(Opcode op) {
return "ret";
case Opcode::Call:
return "call";
case Opcode::Br:
return "br";
case Opcode::CondBr:
return "condbr";
case Opcode::Icmp:
return "icmp";
}
return "?";
}
@ -53,10 +61,34 @@ static std::string ValueToString(const Value* v) {
if (auto* ci = dynamic_cast<const ConstantInt*>(v)) {
return std::to_string(ci->GetValue());
}
return v ? v->GetName() : "<null>";
if (!v) {
return "<null>";
}
const auto& name = v->GetName();
if (name.empty()) {
return "<unnamed>";
}
if (name[0] == '%' || name[0] == '@') {
return name;
}
if (dynamic_cast<const GlobalValue*>(v)) {
return "@" + name;
}
return "%" + name;
}
void IRPrinter::Print(const Module& module, std::ostream& os) {
for (const auto& global : module.GetGlobals()) {
if (!global) continue;
os << "@" << global->GetName() << " = global ";
if (global->GetType()->IsPtrInt32()) {
os << "i32 0\n";
} else if (global->GetType()->IsPtrFloat()) {
os << "float 0.0\n";
} else {
os << TypeToString(*global->GetType()) << " zeroinitializer\n";
}
}
for (const auto& func : module.GetFunctions()) {
auto* func_ty = static_cast<const FunctionType*>(func->GetType().get());
os << "define " << TypeToString(*func_ty->GetReturnType()) << " @" << func->GetName() << "(";
@ -64,7 +96,7 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
for (const auto& arg : func->GetArguments()) {
if (!first) os << ", ";
first = false;
os << TypeToString(*arg->GetType()) << " " << arg->GetName();
os << TypeToString(*arg->GetType()) << " %" << arg->GetName();
}
os << ") {\n";
for (const auto& bb : func->GetBlocks()) {
@ -135,6 +167,57 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
os << ")\n";
break;
}
// 在 IRPrinter.cpp 的 switch 语句中添加
case Opcode::Br:
case Opcode::CondBr: {
auto* br = static_cast<const BranchInst*>(inst);
if (!br->IsConditional()) {
os << " br label %" << br->GetTarget()->GetName() << "\n";
} else {
os << " br i1 " << ValueToString(br->GetCondition())
<< ", label %" << br->GetTrueTarget()->GetName()
<< ", label %" << br->GetFalseTarget()->GetName() << "\n";
}
break;
}
case Opcode::Icmp: {
auto* icmp = static_cast<const IcmpInst*>(inst);
os << " " << icmp->GetName() << " = icmp ";
switch (icmp->GetPredicate()) {
case IcmpInst::Predicate::EQ: os << "eq"; break;
case IcmpInst::Predicate::NE: os << "ne"; break;
case IcmpInst::Predicate::LT: os << "slt"; break;
case IcmpInst::Predicate::LE: os << "sle"; break;
case IcmpInst::Predicate::GT: os << "sgt"; break;
case IcmpInst::Predicate::GE: os << "sge"; break;
}
os << " " << TypeToString(*icmp->GetLhs()->GetType())
<< " " << ValueToString(icmp->GetLhs())
<< ", " << ValueToString(icmp->GetRhs()) << "\n";
break;
}
case Opcode::ZExt: {
auto* zext = static_cast<const ZExtInst*>(inst);
os << " " << zext->GetName() << " = zext "
<< TypeToString(*zext->GetSourceType()) << " "
<< ValueToString(zext->GetValue()) << " to "
<< TypeToString(*zext->GetTargetType()) << "\n";
break;
}
case Opcode::Trunc: {
auto* trunc = static_cast<const TruncInst*>(inst);
os << " " << trunc->GetName() << " = trunc "
<< TypeToString(*trunc->GetSourceType()) << " "
<< ValueToString(trunc->GetValue()) << " to "
<< TypeToString(*trunc->GetTargetType()) << "\n";
break;
}
default:
os << "NOT_IMPLEMENTED: " << OpcodeToString(inst->GetOpcode()) << "\n";
}
}
}

@ -52,7 +52,10 @@ Instruction::Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name)
Opcode Instruction::GetOpcode() const { return opcode_; }
bool Instruction::IsTerminator() const { return opcode_ == Opcode::Ret; }
bool Instruction::IsTerminator() const {
return opcode_ == Opcode::Ret || opcode_ == Opcode::Br ||
opcode_ == Opcode::CondBr;
}
BasicBlock* Instruction::GetParent() const { return parent_; }

@ -18,4 +18,14 @@ const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
return functions_;
}
GlobalValue* Module::CreateGlobal(const std::string& name,
std::shared_ptr<Type> ty) {
globals_.push_back(std::make_unique<GlobalValue>(ty, name));
return globals_.back().get();
}
const std::vector<std::unique_ptr<GlobalValue>>& Module::GetGlobals() const {
return globals_;
}
} // namespace ir

@ -62,6 +62,17 @@ const std::shared_ptr<Type>& Type::GetLabelType() {
return type;
}
// Int1 类型表示布尔值,通常用于比较指令的结果
const std::shared_ptr<Type>& Type::GetInt1Type() {
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::Int1));
return type;
}
// PtrInt1 类型表示指向 Int1 的指针,主要用于条件跳转等场景
const std::shared_ptr<Type>& Type::GetPtrInt1Type() {
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::PtrInt1));
return type;
}
// ---------- 数组类型缓存 ----------
// 使用自定义键类型保证唯一性:元素类型指针 + 维度向量
struct ArrayKey {

@ -76,7 +76,7 @@ void Value::ReplaceAllUsesWith(Value* new_value) {
ConstantValue::ConstantValue(std::shared_ptr<Type> ty, std::string name)
: Value(std::move(ty), std::move(name)) {}
// 建一个 Argument 对象,用给定的类型和名称初始化它,并继承 Value 的所有属性和方法。
Argument::Argument(std::shared_ptr<Type> ty, std::string name)
: Value(std::move(ty), std::move(name)) {}

@ -65,7 +65,7 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
// 全局变量(简化):用全局占位符记录为 i32*Default 不直接插入指令
// 全局变量:在数据段分配
// TODO:真正的全局变量应该存储值本身,而不是指针,这里为了简化实现先使用指针占位,后续可以改为直接存储值
auto* global = new ir::GlobalValue(ir::Type::GetPtrInt32Type(), varName);
auto* global = module_.CreateGlobal(varName, ir::Type::GetPtrInt32Type());
global_map_[varName] = global;
// 对全局初始化暂不支持默认为0
return {};
@ -75,19 +75,15 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[ctx] = slot;
ir::Value* init = nullptr;
// 使用 initVal() 而不是 initValue()
if (auto* initVal = ctx->initVal()) {
ir::Value* init = nullptr;
if (initVal->exp()) {
init = EvalExpr(*initVal->exp());
builder_.CreateStore(init, slot);
} else {
// 数组初始化暂不支持
init = builder_.CreateConstInt(0);
// 数组初始化暂不支持,局部数组也不做默认初始化
}
} else {
init = builder_.CreateConstInt(0);
}
builder_.CreateStore(init, slot);
return {};
}

@ -22,6 +22,7 @@
// - ...
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
std::cout << "[DEBUG IRGEN] EvalExpr: " << expr.getText() << std::endl;
return std::any_cast<ir::Value*>(expr.accept(this));
}
@ -29,8 +30,17 @@ ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
return std::any_cast<ir::Value*>(cond.accept(this));
}
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少表达式"));
}
std::cout << "[DEBUG IRGEN] visitExp: " << ctx->getText() << std::endl;
return ctx->addExp()->accept(this);
}
// 基本表达式:数字、变量、括号表达式
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitPrimaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
}
@ -71,12 +81,15 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
}
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitUnaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少一元表达式"));
}
if (ctx->primaryExp()) {
return ctx->primaryExp()->accept(this);
auto result = ctx->primaryExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitUnaryExp primary result: " << (ctx->primaryExp() ? ctx->primaryExp()->getText() : "<null>") << std::endl;
return result;
}
if (ctx->Ident() && ctx->L_PAREN()) {
@ -104,14 +117,17 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
}
if (ctx->unaryOp() && ctx->unaryExp()) {
auto* operand = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
auto operand_any = ctx->unaryExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitUnaryExp operand_any.type=" << operand_any.type().name() << " text=" << ctx->unaryExp()->getText() << std::endl;
auto* operand = std::any_cast<ir::Value*>(operand_any);
if (ctx->unaryOp()->AddOp()) {
return operand;
}
if (ctx->unaryOp()->SubOp()) {
auto* zero = builder_.CreateConstInt(0);
return builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
module_.GetContext().NextTemp());
return static_cast<ir::Value*>(
builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
module_.GetContext().NextTemp()));
}
if (ctx->unaryOp()->NotOp()) {
// 逻辑非暂不支持,先默认 0/1 取反
@ -129,6 +145,7 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
// 2. 再通过 storage_map_ 找到该声明对应的栈槽位;
// 3. 最后生成 load把内存中的值读出来。
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
std::cout << "[DEBUG IRGEN] visitLVal: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
@ -172,6 +189,7 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
// 加法表达式
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
@ -185,10 +203,14 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
// 如果有左子节点AddExp递归处理
if (ctx->addExp()) {
result = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
auto left_any = ctx->addExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitAddExp left_any.type=" << left_any.type().name() << " text=" << ctx->addExp()->getText() << std::endl;
result = std::any_cast<ir::Value*>(left_any);
} else {
// 否则是 MulExp
result = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
auto right_any = ctx->mulExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitAddExp right_any.type=" << right_any.type().name() << " text=" << ctx->mulExp()->getText() << std::endl;
result = std::any_cast<ir::Value*>(right_any);
}
// 如果有运算符和右操作数
@ -209,55 +231,108 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
// 在 IRGenExp.cpp 中添加
// 简化版 visitMulExp
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitMulExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 暂时只返回 unaryExp 的值
if (ctx->unaryExp()) {
return ctx->unaryExp()->accept(this);
// 检查 unaryExp返回指针可能为 nullptr
auto* unaryExp = ctx->unaryExp();
std::cout << "[DEBUG] unaryExp is " << (unaryExp ? "not null" : "null") << std::endl;
if (unaryExp) {
std::cout << "[DEBUG] calling unaryExp->accept(this)" << std::endl;
auto result = unaryExp->accept(this);
std::cout << "[DEBUG] returned from unaryExp" << std::endl;
return result;
}
// 如果有 mulExp 子节点,递归处理
if (ctx->mulExp()) {
return ctx->mulExp()->accept(this);
// 检查 mulExp
auto* mulExp = ctx->mulExp();
std::cout << "[DEBUG] mulExp is " << (mulExp ? "not null" : "null") << std::endl;
if (mulExp) {
std::cout << "[DEBUG] calling mulExp->accept(this)" << std::endl;
auto result = mulExp->accept(this);
std::cout << "[DEBUG] returned from mulExp" << std::endl;
return result;
}
std::cout << "[DEBUG] no unaryExp or mulExp found!" << std::endl;
throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现"));
}
// 关系表达式(暂未完整实现
// 关系表达式(支持 <, >, <=, >=
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
}
// 简化:返回 addExp 的值
if (ctx->relExp() && ctx->addExp()) {
auto left_any = ctx->relExp()->accept(this);
auto right_any = ctx->addExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(right_any);
if (ctx->LOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp()));
}
if (ctx->GOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp()));
}
if (ctx->LeOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp()));
}
if (ctx->GeOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpGE(lhs, rhs, module_.GetContext().NextTemp()));
}
throw std::runtime_error(FormatError("irgen", "未知关系运算符"));
}
if (ctx->addExp()) {
return ctx->addExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现"));
}
// 相等表达式(暂未完整实现)
// 相等表达式(支持 ==, !=
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
}
// 简化:返回 relExp 的值
if (ctx->eqExp() && ctx->relExp()) {
auto left_any = ctx->eqExp()->accept(this);
auto right_any = ctx->relExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(right_any);
if (ctx->EqOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp()));
}
if (ctx->NeOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpNE(lhs, rhs, module_.GetContext().NextTemp()));
}
throw std::runtime_error(FormatError("irgen", "未知相等运算符"));
}
if (ctx->relExp()) {
return ctx->relExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
}
// 条件表达式
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
}

@ -30,6 +30,7 @@ IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
// 修正:没有 mainFuncDef通过函数名找到 main
std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
std::cout << "[DEBUG IRGEN] visitCompUnit" << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少编译单元"));
}
@ -52,6 +53,7 @@ std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
}
std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
std::cout << "[DEBUG IRGEN] visitFuncDef: " << (ctx && ctx->Ident() ? ctx->Ident()->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
}
@ -154,36 +156,51 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
}
std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) {
std::cout << "[DEBUG IRGEN] visitBlock: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
}
BlockFlow flow = BlockFlow::Continue;
for (auto* item : ctx->blockItem()) {
if (item) {
if (VisitBlockItemResult(*item) == BlockFlow::Terminated) {
break;
}
if (!item) continue;
flow = VisitBlockItemResult(*item);
if (flow == BlockFlow::Terminated) {
break;
}
auto* cur = builder_.GetInsertBlock();
std::cout << "[DEBUG] current insert block: "
<< (cur ? cur->GetName() : "<null>") << std::endl;
if (cur && cur->HasTerminator()) {
break;
}
}
return {};
return flow;
}
// 类型安全的包装器
IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult(
SysYParser::BlockItemContext& item) {
return std::any_cast<BlockFlow>(item.accept(this));
auto result = item.accept(this);// 调用 visitBlockItem返回 std::any 包装的 BlockFlow
return std::any_cast<BlockFlow>(result); // 解包为 BlockFlow
}
// 用于遍历块内项,返回是否继续访问后续项(如遇到 return/break/continue 则终止访问)
std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) {
std::cout << "[DEBUG IRGEN] visitBlockItem: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少块内项"));
}
// 块内项可以是语句或声明,优先处理语句(如 return/break/continue 可能终止块内执行)
if (ctx->stmt()) {
return ctx->stmt()->accept(this);
return ctx->stmt()->accept(this); // 语句访问返回 BlockFlow指示是否继续访问后续项
}
// 处理声明(如变量定义),继续访问后续项
if (ctx->decl()) {
ctx->decl()->accept(this);
return BlockFlow::Continue;
return BlockFlow::Continue; // 声明不会终止块内执行,继续访问后续项
}
throw std::runtime_error(FormatError("irgen", "暂不支持的块内项"));
}

@ -16,6 +16,7 @@
// - 空语句、块语句嵌套分发之外的更多语句形态
std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] visitStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句"));
}
@ -30,6 +31,24 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
return HandleAssignStmt(ctx);
}
// if 语句
if (ctx->If()) {
return HandleIfStmt(ctx);
}
// while 语句
if (ctx->While()) {
return HandleWhileStmt(ctx);
}
// break 语句
if (ctx->Break()) {
return HandleBreakStmt(ctx);
}
// continue 语句
if (ctx->Continue()) {
return HandleContinueStmt(ctx);
}
// 块语句
if (ctx->block()) {
return ctx->block()->accept(this);
@ -44,12 +63,14 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}
IRGenImpl::BlockFlow IRGenImpl::HandleReturnStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleReturnStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少 return 语句"));
}
ir::Value* retValue = nullptr;
if (ctx->exp()) {
std::cout << "[DEBUG IRGEN] HandleReturnStmt eval exp: " << ctx->exp()->getText() << std::endl;
retValue = EvalExpr(*ctx->exp());
}
// 如果没有表达式返回0对于int main
@ -63,26 +84,187 @@ IRGenImpl::BlockFlow IRGenImpl::HandleReturnStmt(SysYParser::StmtContext* ctx) {
// if语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleIfStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现if语句
throw std::runtime_error(FormatError("irgen", "if语句暂未实现"));
std::cout << "[DEBUG IRGEN] HandleIfStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
auto* cond = ctx->cond();
auto* thenStmt = ctx->stmt(0);
auto* elseStmt = ctx->stmt(1);
// 创建基本块
auto* thenBlock = func_->CreateBlock("then");
auto* elseBlock = (ctx->Else() && elseStmt) ? func_->CreateBlock("else") : nullptr;
auto* mergeBlock = func_->CreateBlock("merge");
std::cout << "[DEBUG IF] thenBlock: " << thenBlock->GetName() << std::endl;
if (elseBlock) std::cout << "[DEBUG IF] elseBlock: " << elseBlock->GetName() << std::endl;
std::cout << "[DEBUG IF] mergeBlock: " << mergeBlock->GetName() << std::endl;
std::cout << "[DEBUG IF] current insert block before cond: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
// 生成条件
auto* condValue = EvalCond(*cond);
// 创建条件跳转
if (elseBlock) {
std::cout << "[DEBUG IF] Creating condbr: " << condValue->GetName()
<< " -> " << thenBlock->GetName() << ", " << elseBlock->GetName() << std::endl;
builder_.CreateCondBr(condValue, thenBlock, elseBlock);
} else {
std::cout << "[DEBUG IF] Creating condbr: " << condValue->GetName()
<< " -> " << thenBlock->GetName() << ", " << mergeBlock->GetName() << std::endl;
builder_.CreateCondBr(condValue, thenBlock, mergeBlock);
}
// 生成 then 分支
std::cout << "[DEBUG IF] Generating then branch in block: " << thenBlock->GetName() << std::endl;
builder_.SetInsertPoint(thenBlock);
auto thenResult = thenStmt->accept(this);
bool thenTerminated = (std::any_cast<BlockFlow>(thenResult) == BlockFlow::Terminated);
std::cout << "[DEBUG IF] then branch terminated: " << thenTerminated << std::endl;
if (!thenTerminated) {
std::cout << "[DEBUG IF] Adding br to merge block from then" << std::endl;
builder_.CreateBr(mergeBlock);
}
std::cout << "[DEBUG IF] then block has terminator: " << thenBlock->HasTerminator() << std::endl;
// 生成 else 分支
bool elseTerminated = false;
if (elseBlock) {
std::cout << "[DEBUG IF] Generating else branch in block: " << elseBlock->GetName() << std::endl;
builder_.SetInsertPoint(elseBlock);
auto elseResult = elseStmt->accept(this);
elseTerminated = (std::any_cast<BlockFlow>(elseResult) == BlockFlow::Terminated);
std::cout << "[DEBUG IF] else branch terminated: " << elseTerminated << std::endl;
if (!elseTerminated) {
std::cout << "[DEBUG IF] Adding br to merge block from else" << std::endl;
builder_.CreateBr(mergeBlock);
}
std::cout << "[DEBUG IF] else block has terminator: " << elseBlock->HasTerminator() << std::endl;
}
// 决定后续插入点
std::cout << "[DEBUG IF] thenTerminated=" << thenTerminated
<< ", elseTerminated=" << elseTerminated << std::endl;
if (elseBlock) {
if (thenTerminated && elseTerminated) {
auto* afterIfBlock = func_->CreateBlock("after.if");
std::cout << "[DEBUG IF] Both branches terminated, creating new block: "
<< afterIfBlock->GetName() << std::endl;
builder_.SetInsertPoint(afterIfBlock);
} else {
std::cout << "[DEBUG IF] Setting insert point to merge block: "
<< mergeBlock->GetName() << std::endl;
builder_.SetInsertPoint(mergeBlock);
}
} else {
std::cout << "[DEBUG IF] No else, setting insert point to merge block: "
<< mergeBlock->GetName() << std::endl;
builder_.SetInsertPoint(mergeBlock);
}
std::cout << "[DEBUG IF] Final insert block: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
return BlockFlow::Continue;
}
// while语句待实现
// while语句待实现IRGenImpl::BlockFlow IRGenImpl::HandleWhileStmt(SysYParser::StmtContext* ctx) {
IRGenImpl::BlockFlow IRGenImpl::HandleWhileStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现while语句
throw std::runtime_error(FormatError("irgen", "while语句暂未实现"));
std::cout << "[DEBUG IRGEN] HandleWhileStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->cond() || !ctx->stmt(0)) {
throw std::runtime_error(FormatError("irgen", "非法 while 语句"));
}
std::cout << "[DEBUG WHILE] Current insert block before while: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
auto* condBlock = func_->CreateBlock("while.cond");
auto* bodyBlock = func_->CreateBlock("while.body");
auto* exitBlock = func_->CreateBlock("while.exit");
std::cout << "[DEBUG WHILE] condBlock: " << condBlock->GetName() << std::endl;
std::cout << "[DEBUG WHILE] bodyBlock: " << bodyBlock->GetName() << std::endl;
std::cout << "[DEBUG WHILE] exitBlock: " << exitBlock->GetName() << std::endl;
std::cout << "[DEBUG WHILE] Adding br to condBlock from current block" << std::endl;
builder_.CreateBr(condBlock);
loopStack_.push_back({condBlock, bodyBlock, exitBlock});
std::cout << "[DEBUG WHILE] loopStack size: " << loopStack_.size() << std::endl;
// 条件块
std::cout << "[DEBUG WHILE] Generating condition in block: " << condBlock->GetName() << std::endl;
builder_.SetInsertPoint(condBlock);
auto* condValue = EvalCond(*ctx->cond());
builder_.CreateCondBr(condValue, bodyBlock, exitBlock);
std::cout << "[DEBUG WHILE] condBlock has terminator: " << condBlock->HasTerminator() << std::endl;
// 循环体
std::cout << "[DEBUG WHILE] Generating body in block: " << bodyBlock->GetName() << std::endl;
builder_.SetInsertPoint(bodyBlock);
auto bodyResult = ctx->stmt(0)->accept(this);
bool bodyTerminated = (std::any_cast<BlockFlow>(bodyResult) == BlockFlow::Terminated);
std::cout << "[DEBUG WHILE] body terminated: " << bodyTerminated << std::endl;
if (!bodyTerminated) {
std::cout << "[DEBUG WHILE] Adding br to condBlock from body" << std::endl;
builder_.CreateBr(condBlock);
}
std::cout << "[DEBUG WHILE] bodyBlock has terminator: " << bodyBlock->HasTerminator() << std::endl;
loopStack_.pop_back();
std::cout << "[DEBUG WHILE] loopStack size after pop: " << loopStack_.size() << std::endl;
// 设置插入点为 exitBlock
std::cout << "[DEBUG WHILE] Setting insert point to exitBlock: " << exitBlock->GetName() << std::endl;
builder_.SetInsertPoint(exitBlock);
std::cout << "[DEBUG WHILE] exitBlock has terminator before return: "
<< exitBlock->HasTerminator() << std::endl;
return BlockFlow::Continue;
}
// break语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleBreakStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现break
throw std::runtime_error(FormatError("irgen", "break语句暂未实现"));
std::cout << "[DEBUG IRGEN] HandleBreakStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (loopStack_.empty()) {
throw std::runtime_error(FormatError("irgen", "break 语句不在循环中"));
}
std::cout << "[DEBUG BREAK] Current insert block before break: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
std::cout << "[DEBUG BREAK] Breaking to exitBlock: "
<< loopStack_.back().exitBlock->GetName() << std::endl;
// 跳转到循环退出块
builder_.CreateBr(loopStack_.back().exitBlock);
// break 本身就是终止当前路径,后续 unreachable 代码不需要继续生成。
return BlockFlow::Terminated;
}
// continue语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleContinueStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现continue
throw std::runtime_error(FormatError("irgen", "continue语句暂未实现"));
std::cout << "[DEBUG IRGEN] HandleContinueStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (loopStack_.empty()) {
throw std::runtime_error(FormatError("irgen", "continue 语句不在循环中"));
}
std::cout << "[DEBUG CONTINUE] Current insert block before continue: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
std::cout << "[DEBUG CONTINUE] Continuing to condBlock: "
<< loopStack_.back().condBlock->GetName() << std::endl;
// 跳转到循环条件块
builder_.CreateBr(loopStack_.back().condBlock);
// continue 本身就是终止当前路径,后续 unreachable 代码不需要继续生成。
return BlockFlow::Terminated;
}
// 赋值语句(待实现)

Loading…
Cancel
Save