refactor: LLVM目标初始化解耦 — 抽取 target.h/c
- 新增 src/codegen/target.h/c: target_init/get_default_triple/create_machine/emit_obj - main.c 移除 inline LLVM Target API 调用,改调 target_* 接口 - codegen.c 专注 AST→IR,不再混入目标平台初始化 基于 Codex 分析报告 4.1 节架构改进建议。
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
#include "target.h"
|
||||
#include <llvm-c/Target.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void target_init(void) {
|
||||
LLVMInitializeX86TargetInfo();
|
||||
LLVMInitializeX86Target();
|
||||
LLVMInitializeX86TargetMC();
|
||||
LLVMInitializeX86AsmPrinter();
|
||||
LLVMInitializeX86AsmParser();
|
||||
}
|
||||
|
||||
char* target_get_default_triple(void) {
|
||||
return LLVMGetDefaultTargetTriple();
|
||||
}
|
||||
|
||||
LLVMTargetMachineRef target_create_machine(const char* triple) {
|
||||
LLVMTargetRef target;
|
||||
char* error = NULL;
|
||||
if (LLVMGetTargetFromTriple(triple, &target, &error)) {
|
||||
fprintf(stderr, "目标平台错误: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return LLVMCreateTargetMachine(
|
||||
target, triple, "generic", "",
|
||||
LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault);
|
||||
}
|
||||
|
||||
int target_emit_obj(LLVMTargetMachineRef tm, LLVMModuleRef module,
|
||||
const char* filename, char** error_msg) {
|
||||
return LLVMTargetMachineEmitToFile(tm, module, (char*)filename,
|
||||
LLVMObjectFile, error_msg);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef TARGET_H
|
||||
#define TARGET_H
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/TargetMachine.h>
|
||||
|
||||
// 初始化 X86 目标平台(LLVMInitializeAllTarget* 的替代,LLVM-C.lib 不导出 All 系列)
|
||||
void target_init(void);
|
||||
|
||||
// 获取默认目标三元组
|
||||
char* target_get_default_triple(void);
|
||||
|
||||
// 从三元组获取目标机
|
||||
LLVMTargetMachineRef target_create_machine(const char* triple);
|
||||
|
||||
// 将模块写入目标文件
|
||||
// 返回 0 成功,非 0 失败(*error_msg 包含错误信息)
|
||||
int target_emit_obj(LLVMTargetMachineRef tm, LLVMModuleRef module,
|
||||
const char* filename, char** error_msg);
|
||||
|
||||
#endif
|
||||
+7
-25
@@ -3,12 +3,11 @@
|
||||
#include "parser.h"
|
||||
#include "sema.h"
|
||||
#include "codegen.h"
|
||||
#include "target.h"
|
||||
#include "error.h"
|
||||
#include "arena.h"
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/TargetMachine.h>
|
||||
#include <llvm-c/Target.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -111,35 +110,18 @@ int main(int argc, char** argv) {
|
||||
printf("IR 已输出到: %s\n", ir_path);
|
||||
LLVMDisposeMessage(ir);
|
||||
} else {
|
||||
// 初始化 X86 目标(LLVM-C.lib 中没有 InitializeAll 系列符号)
|
||||
LLVMInitializeX86TargetInfo();
|
||||
LLVMInitializeX86Target();
|
||||
LLVMInitializeX86TargetMC();
|
||||
LLVMInitializeX86AsmPrinter();
|
||||
LLVMInitializeX86AsmParser();
|
||||
// LLVM 目标平台初始化和目标代码生成
|
||||
target_init();
|
||||
|
||||
char* triple = LLVMGetDefaultTargetTriple();
|
||||
LLVMTargetRef target;
|
||||
char* target_error = NULL;
|
||||
if (LLVMGetTargetFromTriple(triple, &target, &target_error)) {
|
||||
fprintf(stderr, "目标平台错误: %s\n", target_error);
|
||||
LLVMDisposeMessage(target_error); LLVMDisposeMessage(triple);
|
||||
free(source); arena_destroy(&arena); LLVMDisposeModule(module);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLVMTargetMachineRef tm = LLVMCreateTargetMachine(
|
||||
target, triple, "generic", "",
|
||||
LLVMCodeGenLevelDefault, LLVMRelocDefault,
|
||||
LLVMCodeModelDefault);
|
||||
char* triple = target_get_default_triple();
|
||||
LLVMTargetMachineRef tm = target_create_machine(triple);
|
||||
LLVMDisposeMessage(triple);
|
||||
if (!tm) { free(source); arena_destroy(&arena); LLVMDisposeModule(module); return 1; }
|
||||
|
||||
// 输出目标文件
|
||||
char obj_path[512];
|
||||
snprintf(obj_path, sizeof(obj_path), "%s.o", input);
|
||||
char* obj_error = NULL;
|
||||
if (LLVMTargetMachineEmitToFile(tm, module, obj_path,
|
||||
LLVMObjectFile, &obj_error)) {
|
||||
if (target_emit_obj(tm, module, obj_path, &obj_error)) {
|
||||
fprintf(stderr, "目标代码生成错误: %s\n", obj_error);
|
||||
LLVMDisposeMessage(obj_error);
|
||||
free(source); arena_destroy(&arena);
|
||||
|
||||
Reference in New Issue
Block a user