int main()
{
    llvm::LLVMContext &context = llvm::getGlobalContext();
    llvm::Module *module = new llvm::Module("hello_world", context);
    llvm::IRBuilder<> builder(context);

    // define main() as void
    llvm::FunctionType *funcType = llvm::FunctionType::get(builder.getVoidTy(), false);
    llvm::Function *mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", module);

    llvm::BasicBlock *entry = llvm::BasicBlock::Create(context, "entrypoint", mainFunc);
    builder.SetInsertPoint(entry);

    // define the 'hello world' string constant
    llvm::Value *helloWorld = builder.CreateGlobalStringPtr("Hello world!");

    // define the args to puts()
    std::vector<llvm::Type*> putsArgs;
    putsArgs.push_back(builder.getInt8Ty()->getPointerTo());
    llvm::ArrayRef<llvm::Type*> argsRef(putsArgs);

    llvm::FunctionType *putsType = llvm::FunctionType::get(builder.getInt32Ty(), // return type
                                                           argsRef,              // argument vector
                                                           false);               // no variable number of args

    llvm::Constant *putsFunc = module->getOrInsertFunction("puts", putsType);

    // call puts(hello_world)
    builder.CreateCall(putsFunc, helloWorld);
    builder.CreateRetVoid();

    module->dump();
}
Esempio n. 2
0
    bool CodeGen::wrapTopLevelBlockInMain(BlockAST *ast) {
      // add main to scope
      addScope("main");

      vector<unique_ptr<ASTNode> > * body = ast->body.get();

      // generate void main()
      llvm::FunctionType *voidType = llvm::FunctionType::get(Builder.getVoidTy(), false);
      llvm::Function *mainFunc =
        llvm::Function::Create(voidType, llvm::Function::ExternalLinkage, "main", module.get());

      // basic block for the top level block
      llvm::BasicBlock *MainBlock = llvm::BasicBlock::Create(context, "entry", mainFunc);
      Builder.SetInsertPoint(MainBlock);

      llvm::Value * lastExpr;

      for (auto it = body->begin() ; it != body->end(); ++it) {
        ASTNode * node = it->get();

        if (auto x = dynamic_cast<ValueAST*>(node)) {
          auto code = generateCodeValue(x);
          if (!code) return false;

        } else if (auto x = dynamic_cast<DefAST*>(node)) {
          generateCodeDef(x);
          Builder.SetInsertPoint(MainBlock);

        } else if (auto x = dynamic_cast<NumberExprAST*>(node)) {
          auto code = generateCodeNumber(x);
          if (!code) return false;
          lastExpr = code;

        } else if (auto x = dynamic_cast<BinaryExprAST*>(node)) {
          auto code = generateCodeBinOp(x);
          if (!code) return false;
          lastExpr = code;

        } else if (auto x = dynamic_cast<CallAST*>(node)) {
          auto code = generateCodeCall(x);
          if (!code) return false;
          lastExpr = code;

        } else {
          error = "can't handle ast";
          return false;
        }
      }

      llvm::Value *fmt = Builder.CreateGlobalStringPtr("%lg\n");

      vector<llvm::Type *> putsArgs;
      putsArgs.push_back(Builder.getInt8Ty()->getPointerTo());
      llvm::ArrayRef<llvm::Type*> argsRef(putsArgs);

      llvm::FunctionType *putsType =
        llvm::FunctionType::get(Builder.getInt32Ty(), argsRef, true);
      llvm::Constant *putsFunc = module->getOrInsertFunction("printf", putsType);

      vector<llvm::Value *> CallArgs;
      CallArgs.push_back(fmt);
      CallArgs.push_back(lastExpr);
      Builder.CreateCall(putsFunc, CallArgs);

      Builder.CreateRetVoid();

      string verifyS;
      llvm::raw_string_ostream verifyE(verifyS);
      if (verifyFunction(*mainFunc, &verifyE)) {
        mainFunc->eraseFromParent();
        error = "something wrong with auto-generated main function: " + verifyS;
        return false;
      }

      // remove the main scope
      removeScope();

      return true;
    }