2013-07-28 28 views
3

我正在写使用LLVM作为后端的编译器,我已经写前端(解析器等),现在我已经走到一个十字路口。LLVM提取物6-18 *总分结构价值

我有包含单个字段,I8 *值,一个指针到的字符阵列的结构(%原始)。

%Primitive = type { i8* } 

在编译器中,的Primitive实例在栈上传递周围。我试图使用puts函数将此字符数组写入标准输出,但它不像我所期望的那样工作。

declare i32 @puts(i8*) ; Declare the libc function 'puts' 

define void @WritePrimitive(%Primitive) { 
entry: 
    %1 = extractvalue %Primitive %0, 0 ; Extract the character array from the primitive. 
    %2 = call i32 @puts(i8* %1) ; Write it 
    ret void 
} 

当我试图运行的代码(使用一个ExecutionEngine或LLVM解释程序lli),我得到了同样的错误;分段故障。

的错误之处在于传递给puts地址是某种数组中的第一个字符的ASCII字符代码。看起来地址通过了,而不是一个指向8位字符数组的指针,而是一个8位宽的指针,它等于解引用的字符串。

例如,如果我打电话@WritePrimitive与图元,其中6-18 *构件指向字符串"hello"puts被称为与串地址为0x68

任何想法?

感谢

编辑:你说得对,我是我的初始化错误Primitive,我的新的初始化函数:

llvm::Value* PrimitiveHelper::getConstantPrimitive(const std::string& str, llvm::BasicBlock* bb) 
{ 
    ConstantInt* int0 = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0); 
    Constant* strConstant = ConstantDataArray::getString(getGlobalContext(), str, true); 

    GlobalVariable* global = new GlobalVariable(module, 
               strConstant->getType(), 
               true, // Constant 
               GlobalValue::ExternalLinkage, 
               strConstant, 
               "str"); 

    Value* allocated = new AllocaInst(m_primitiveType, "allocated", bb); 

    LoadInst* onStack1 = new LoadInst(allocated, "onStack1", bb); 

    GetElementPtrInst* ptr = GetElementPtrInst::Create(global, std::vector<Value*>(2,int0), "", bb); 

    InsertValueInst* onStack2 = InsertValueInst::Create(onStack1, ptr, std::vector<unsigned>(1, 0), "", bb); 

    return onStack2; 
} 

我错过了,谢谢!

回答

2

没有什么错,你上面贴的代码;我只是自己试了一下,它运行良好。我猜测问题是你没有正确地初始化指针,或者没有正确地将它设置到结构中。

我用完整的代码是:

@str = private unnamed_addr constant [13 x i8] c"hello world\0A\00" 

; Your code 
%Primitive = type { i8* } 

declare i32 @puts(i8*) ; Declare the libc function 'puts' 

define void @WritePrimitive(%Primitive) { 
entry: 
    %1 = extractvalue %Primitive %0, 0 ; Extract the character array from the primitive. 
    %2 = call i32 @puts(i8* %1) ; Write it 
    ret void 
} 

; /Your code 

define void @main() { 
    %allocated = alloca %Primitive 
    %onstack1 = load %Primitive* %allocated 
    %onstack2 = insertvalue %Primitive %onstack1, i8* getelementptr ([13 x i8]* @str, i64 0, i64 0), 0 
    call void @WritePrimitive(%Primitive %onstack2) 
    ret void 
}