Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ *值未生成到LLVM代码中_C++_Compiler Construction_Llvm - Fatal编程技术网

C++ *值未生成到LLVM代码中

C++ *值未生成到LLVM代码中,c++,compiler-construction,llvm,C++,Compiler Construction,Llvm,我试图编写一些编译器并使用LLVM生成中间代码。不幸的是,LLVM文档不是很好,甚至有些混乱 目前我已经实现了lexer、语法和AST。我也在网上找到了一些例子。我当前的AST的工作原理如下:它有抽象基类树*,其他树从中继承(例如,一个用于变量定义,一个用于语句列表,一个用于二进制表达式等) 我试图实现变量定义,因此对于输入 class Test{ int main() { int x; } } 我希望LLVM输出为: ; ModuleID = "Test"

我试图编写一些编译器并使用LLVM生成中间代码。不幸的是,LLVM文档不是很好,甚至有些混乱

目前我已经实现了lexer、语法和AST。我也在网上找到了一些例子。我当前的AST的工作原理如下:它有抽象基类树*,其他树从中继承(例如,一个用于变量定义,一个用于语句列表,一个用于二进制表达式等)

我试图实现变量定义,因此对于输入

class Test{
   int main() 
   {
     int x;
   } 
}
我希望LLVM输出为:

; ModuleID = "Test"

define i32 @main() {
entry:
   %x = alloca i32
   return i32 0
}
但是,现在我可以将%x=alloca i32部分添加到创建主函数的部分,但是实际输出缺少%x=alloca i32。我得到的结果如下:

; ModuleID = "Test"

define i32 @main() {
entry:
   return i32 0
}
变量声明的Codegen()如下所示(目前的符号表只是一个列表,我正在努力使事情尽可能简单):

我生成@main的部分如下所示: 注意:我已经注释掉了print_int函数(这是我稍后用来打印东西的函数,但现在我不需要它)。如果我取消对print_int函数的注释,该函数将不会通过验证器(TheFunction)->投诉模块被破坏,参数与签名不匹配

Function *gen_main_def(llvm::Value *RetVal, Function *print_int) {
  if (RetVal == 0) {
    throw runtime_error("something went horribly wrong\n");
  }
  // create the top-level definition for main
  FunctionType *FT = FunctionType::get(IntegerType::get(getGlobalContext(), 32), false);
  Function *TheFunction = Function::Create(FT, Function::ExternalLinkage, "main", TheModule);
  if (TheFunction == 0) {
    throw runtime_error("empty function block"); 
  }
  // Create a new basic block which contains a sequence of LLVM instructions
  BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
  // All subsequent calls to IRBuilder will place instructions in this location
  Builder.SetInsertPoint(BB);

  /*
  Function *CalleeF = TheModule->getFunction(print_int->getName());
  if (CalleeF == 0) {
    throw runtime_error("could not find the function print_int\n");
  }*/
  // print the value of the expression and we are done
 // Value *CallF = Builder.CreateCall(CalleeF, RetVal, "calltmp");



 // Finish off the function.
 // return 0 from main, which is EXIT_SUCCESS
  Builder.CreateRet(ConstantInt::get(getGlobalContext(), APInt(32, 0)));
  return TheFunction;
}
如果有人知道为什么我的Alloca对象没有被生成,请帮助我-任何提示将不胜感激

多谢各位

编辑:

根据语法调用Codegen:

start: program

program: extern_list decafclass
{ 


    ProgramAST *prog = new ProgramAST((decafStmtList *)$1, (ClassAST *)$2); 
    if (printAST) {
        cout << getString(prog) << endl;
    }
     Value *RetVal = prog->Codegen();
     delete $1; // get rid of abstract syntax tree
     delete $2; // get rid of abstract syntax tree

     // we create an implicit print_int function call to print
     // out the value of the expression.

     Function *print_int = gen_print_int_def();
     Function *TheFunction = gen_main_def(RetVal, print_int);
     verifyFunction(*TheFunction);
}
开始:程序
程序:extern_list decafclass
{ 
ProgramAST*prog=新的ProgramAST((decafStmtList*)$1,(ClassAST*)$2);
if(printAST){

这里有两件奇怪的事:

  • 你要做的就是调用Builder.CreateRet…我不知道main中怎么会有任何代码,除非你调用了创建相应指令的东西。特别是,你似乎从来没有调用CodeGen部分

  • 将大小0传递给CreateAlloc。我认为单个变量的大小应该为1


  • 另外,确保在生成代码后不调用任何LLVM优化过程。这些过程将优化值(它从未使用过,因此是死代码).

    感谢您的快速响应,这里有一些进一步的澄清:1.这正是我所想的-LLVM中应该有一些函数为alloca创建指令,但我找不到任何函数。因此,我假设CreateAlloca会这样做。您知道创建指令的函数吗n在main中?Codegen是从语法中调用的。2.我仍然不理解CreateAlloca的第二个参数的含义,文档指定CreateAlloca(Type*Ty,Value*ArraySize=0,const Twine&Name=“”)[inline]另外,在函数*gen\u main\u def(){…}中,我可以放置RetVal->dump()它将打印%x=alloca i32,因此它会生成正确的输出。之后,由于我未知的原因,它丢失了。我还认为主块中应该有一个函数来存储%x=alloca i32,但我在llvm上找不到任何相关函数。org@user1039063我对这个类似问题的回答还是导师以下链接可能会有所帮助:
    start: program
    
    program: extern_list decafclass
    { 
    
    
        ProgramAST *prog = new ProgramAST((decafStmtList *)$1, (ClassAST *)$2); 
        if (printAST) {
            cout << getString(prog) << endl;
        }
         Value *RetVal = prog->Codegen();
         delete $1; // get rid of abstract syntax tree
         delete $2; // get rid of abstract syntax tree
    
         // we create an implicit print_int function call to print
         // out the value of the expression.
    
         Function *print_int = gen_print_int_def();
         Function *TheFunction = gen_main_def(RetVal, print_int);
         verifyFunction(*TheFunction);
    }