C语言 从AST内存错误生成LLVM代码

fnvucqvd  于 2023-11-16  发布在  其他
关注(0)|答案(1)|浏览(92)

我有这个AST结构,它填充了野牛生成的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 node的代码:

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)中;我在0x 000000000050 address:call stack中读取了错误的异常:
x1c 0d1x的数据
本地变量:



请帮我找出错误的原因。

ndh0cuux

ndh0cuux1#

好吧,我发现了。我的setupLLVM错了。现在它

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)。

相关问题