提问人:mantissa 提问时间:11/14/2023 最后编辑:mantissa 更新时间:11/14/2023 访问量:30
从 AST 内存错误生成 LLVM 代码
LLVM code generation from AST memory error
问:
我有这个 AST 结构,它填充了 Bison 生成的 parser.c。 首先,我尝试编译的虚拟代码:
start
int a;
a = 5;
end
AST:
struct ASTNode {
NodeType type;
LLVMValueRef llvmValue;
union {
int intValue;
double doubleValue;
bool boolValue;
char *identifier;
struct BinaryOpNode binaryOp;
struct AssignmentNode assignment;
struct VariableDeclarationNode variableDeclaration;
} data;
};
我像这样设置 llvm:
void setupLLVM() {
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
GlobalContext = LLVMContextCreate();
GlobalModule = LLVMModuleCreateWithNameInContext("test_module", GlobalContext);
GlobalBuilder = LLVMCreateBuilderInContext(GlobalContext); }
这是ast.c,它包含实际代码:
ASTNode* createVariableDeclarationNode(char *type, char *identifier) {
ASTNode* node = malloc(sizeof(ASTNode));
node->type = AST_VARIABLE_DECLARATION;
node->data.variableDeclaration.type = _strdup(type);
node->data.variableDeclaration.identifier = _strdup(identifier);
LLVMTypeRef varType = 0;
if (strcmp(type, "int") == 0) {
varType = LLVMInt32TypeInContext(GlobalContext);
}
else if (strcmp(type, "double") == 0) {
varType = LLVMDoubleTypeInContext(GlobalContext);
}
else if (strcmp(type, "bool") == 0) {
varType = LLVMInt1TypeInContext(GlobalContext);
}
LLVMValueRef var = LLVMAddGlobal(GlobalModule, varType, identifier);
LLVMSetInitializer(var, LLVMConstInt(varType, 0, 0));
node->llvmValue = var;
printNode(node);
return node;
}
以及生成 const int 节点的代码:
ASTNode* createIntNode(int value) {
ASTNode* node = malloc(sizeof(ASTNode));
node->type = AST_INTEGER;
node->data.intValue = value;
node->llvmValue = LLVMConstInt(LLVMInt32TypeInContext(GlobalContext), value, 0);
printNode(node);
return node;
}
现在,当我想做作业 a = 5 时,我会这样做:
ASTNode* createAssignmentNode(char *identifier, ASTNode *expression) {
ASTNode* node = malloc(sizeof(ASTNode));
node->type = AST_ASSIGNMENT;
node->data.assignment.identifier = _strdup(identifier);
node->data.assignment.expression = expression;
LLVMValueRef var = LLVMGetNamedGlobal(GlobalModule, identifier);
if (!var || !expression->llvmValue) {
printf("assigment error\n");
}
// CRASH
node->llvmValue = LLVMBuildStore(GlobalBuilder, expression->llvmValue, var);
printNode(node);
return node;
}
但是在 node->llvmValue = LLVMBuildStore(GlobalBuilder, expression->llvmValue, var); 我在0x0000000000000050地址中读取了错误: 调用堆栈:
本地变量:
请帮我找到错误的原因。
答:
1赞
mantissa
11/14/2023
#1
好的,我想通了。我的设置LLVM是错误的。现在是
void setupLLVM() {
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
GlobalContext = LLVMContextCreate();
GlobalModule = LLVMModuleCreateWithNameInContext("test_module", GlobalContext);
GlobalBuilder = LLVMCreateBuilderInContext(GlobalContext);
LLVMTypeRef mainFuncType = LLVMFunctionType(LLVMVoidTypeInContext(GlobalContext), NULL, 0, 0);
LLVMValueRef mainFunc = LLVMAddFunction(GlobalModule, "main", mainFuncType);
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(GlobalContext, mainFunc, "entry");
LLVMPositionBuilderAtEnd(GlobalBuilder, entry);
}
我需要为自己创建模块。(EP)。
上一个:在编译器构造中实现类型系统
下一个:在 CFG 中查找第一个非终端
评论
NULL
LLVMBuildStore()
LLVMBuildStore(GlobalBuilder, expression->llvmValue, var);
NULL
if (!var || !expression->llvmValue) { printf("assigment error\n"); }
NULL
LLVMBuildStore()