接続数

COUNTER248862FROM 2012/5/16

MISRA-C diary(C言語日誌)

MISRA-C >> 記事詳細

2017/10/12new

きつねさんでもわかるLLVM コンパイルエラー

Tweet ThisSend to Facebook | by kaizen

make

mkdir -p ./obj

clang++ -g ./src/dcc.cpp -I./inc `llvm-config --cxxflags --ldflags --libs -std=c++04` -c -o ./obj/dcc.o

usage: llvm-config <OPTION>... [<COMPONENT>...]


Get various configuration information needed to compile programs which use

LLVM.  Typically called from 'configure' scripts.  Examples:

  llvm-config --cxxflags

  llvm-config --ldflags

  llvm-config --libs engine bcreader scalaropts


Options:

  --version         Print LLVM version.

  --prefix          Print the installation prefix.

  --src-root        Print the source root LLVM was built from.

  --obj-root        Print the object root used to build LLVM.

  --bindir          Directory containing LLVM executables.

  --includedir      Directory containing LLVM headers.

  --libdir          Directory containing LLVM libraries.

  --cmakedir        Directory containing LLVM cmake modules.

  --cppflags        C preprocessor flags for files that include LLVM headers.

  --cflags          C compiler flags for files that include LLVM headers.

  --cxxflags        C++ compiler flags for files that include LLVM headers.

  --ldflags         Print Linker flags.

  --system-libs     System Libraries needed to link against LLVM components.

  --libs            Libraries needed to link against LLVM components.

  --libnames        Bare library names for in-tree builds.

  --libfiles        Fully qualified library filenames for makefile depends.

  --components      List of all possible components.

  --targets-built   List of all targets currently built.

  --host-target     Target triple used to configure LLVM.

  --build-mode      Print build mode of LLVM tree (e.g. Debug or Release).

  --assertion-mode  Print assertion mode of LLVM tree (ON or OFF).

  --build-system    Print the build system used to build LLVM (always cmake).

  --has-rtti        Print whether or not LLVM was built with rtti (YES or NO).

  --has-global-isel Print whether or not LLVM was built with global-isel support (ON or OFF).

  --shared-mode     Print how the provided components can be collectively linked (`shared` or `static`).

  --link-shared     Link the components as shared libraries.

  --link-static     Link the component libraries statically.

  --ignore-libllvm  Ignore libLLVM and link component libraries instead.

Typical components:

  all               All LLVM libraries (default).

  engine            Either a native JIT or a bitcode interpreter.

clang: warning: -Wl,-search_paths_first: 'linker' input unused [-Wunused-command-line-argument]

clang: warning: -Wl,-headerpad_max_install_names: 'linker' input unused [-Wunused-command-line-argument]

clang: warning: argument unused during compilation: '-L/usr/local/lib' [-Wunused-command-line-argument]

In file included from ./src/dcc.cpp:13:

./inc/lexer.hpp:31:57: warning: field 'TokenString' will be initialized after

      field 'Type' [-Wreorder]

  Token(std::string string, TokenType type, int line) : TokenString(st...

                                                        ^

./inc/lexer.hpp:83:20: warning: comparison of integers of different signs:

      'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

  for(int i = 0; i < Tokens.size(); i++){

                 ~ ^ ~~~~~~~~~~~~~

In file included from ./src/dcc.cpp:14:

./inc/AST.hpp:125:9: warning: comparison of integers of different signs: 'int'

      and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i<Args.size()){

       ~^~~~~~~~~~~~

./inc/AST.hpp:203:10: warning: comparison of integers of different signs:

      'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < Params.size()){

       ~ ^ ~~~~~~~~~~~~~

./inc/AST.hpp:227:62: warning: control reaches end of non-void function

      [-Wreturn-type]

  bool addStatement(BaseAST *stmt){StmtLists.push_back(stmt);};

                                                             ^

./inc/AST.hpp:230:10: warning: comparison of integers of different signs:

      'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < VariableDecls.size()){

       ~ ^ ~~~~~~~~~~~~~~~~~~~~

./inc/AST.hpp:239:10: warning: comparison of integers of different signs:

      'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < StmtLists.size()){

       ~ ^ ~~~~~~~~~~~~~~~~

./inc/AST.hpp:283:10: warning: comparison of integers of different signs:

      'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < Prototypes.size()){

       ~ ^ ~~~~~~~~~~~~~~~~~

./inc/AST.hpp:292:10: warning: comparison of integers of different signs:

      'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < Functions.size()){

       ~ ^ ~~~~~~~~~~~~~~~~

./src/dcc.cpp:22:43: error: too few arguments to function call, at least

      argument 'Argv0' must be specified

  llvm::sys::PrintStackTraceOnErrorSignal();

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^

/usr/local/include/llvm/Support/Signals.h:47:3: note: 

      'PrintStackTraceOnErrorSignal' declared here

  void PrintStackTraceOnErrorSignal(StringRef Argv0,

  ^

./src/dcc.cpp:77:13: error: too few arguments to function call, expected 2,

      have 1

  pm.run(mod);

  ~~~~~~    ^

/usr/local/include/llvm/IR/IRPrintingPasses.h:71:3: note: 'run' declared here

  PreservedAnalyses run(Module &M, AnalysisManager<Module> &);

  ^

9 warnings and 2 errors generated.

make: *** [obj/dcc.o] Error 1

---------------------
ひとまず。llvm::ModuleAnalysisManager DummyMAM;// https://llvm.org/doxygen/IRPrintingPasses_8cpp_source.html#l00045 http://pm.run (mod, DummyMAM);で次に進む。#きつねさんでもわかるLLVM#cpp
エラー12個に増えた。
-----

make
./src/parser.cpp:417:11:
note: use '==' to turn this assignment into an equality comparison

  if(stmt = visitExpressionStatement()){

          ^

          ==

./src/parser.cpp:420:16: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]

  else if(stmt = visitJumpStatement()){

          ~~~~~^~~~~~~~~~~~~~~~~~~~~~

./src/parser.cpp:420:16: note: place parentheses around the assignment to silence this warning

  else if(stmt = visitJumpStatement()){

               ^

          (                          )

./src/parser.cpp:420:16: note: use '==' to turn this assignment into an equality comparison

  else if(stmt = visitJumpStatement()){

               ^

               ==

18 warnings generated.

clang++ -g ./src/codegen.cpp -I./inc `llvm-config --cxxflags --ldflags --libs -std=c++04` -c -o ./obj/codegen.o

usage: llvm-config <OPTION>... [<COMPONENT>...]

(中略)

clang: warning: argument unused during compilation: '-L/usr/local/lib' [-Wunused-command-line-argument]

In file included from ./src/codegen.cpp:1:

In file included from ./inc/codegen.hpp:24:

./inc/AST.hpp:125:9: warning: comparison of integers of different signs: 'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i<Args.size()){

       ~^~~~~~~~~~~~

./inc/AST.hpp:203:10: warning: comparison of integers of different signs: 'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < Params.size()){

       ~ ^ ~~~~~~~~~~~~~

./inc/AST.hpp:227:62: warning: control reaches end of non-void function [-Wreturn-type]

  bool addStatement(BaseAST *stmt){StmtLists.push_back(stmt);};

                                                             ^

./inc/AST.hpp:230:10: warning: comparison of integers of different signs: 'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < VariableDecls.size()){

       ~ ^ ~~~~~~~~~~~~~~~~~~~~

./inc/AST.hpp:239:10: warning: comparison of integers of different signs: 'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < StmtLists.size()){

       ~ ^ ~~~~~~~~~~~~~~~~

./inc/AST.hpp:283:10: warning: comparison of integers of different signs: 'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < Prototypes.size()){

       ~ ^ ~~~~~~~~~~~~~~~~~

./inc/AST.hpp:292:10: warning: comparison of integers of different signs: 'int' and 'size_type' (aka 'unsigned long') [-Wsign-compare]

    if(i < Functions.size()){

       ~ ^ ~~~~~~~~~~~~~~~~

./src/codegen.cpp:4:41: error: no member named 'getGlobalContext' in namespace 'llvm'

  Builder = new llvm::IRBuilder<>(llvm::getGlobalContext());

                                  ~~~~~~^

./src/codegen.cpp:23:46: error: no member named 'getGlobalContext' in namespace 'llvm'

    return *(new llvm::Module ("null", llvm::getGlobalContext()));

                                       ~~~~~~^

./src/codegen.cpp:28:39: error: no member named 'getGlobalContext' in namespace 'llvm'

  Mod = new llvm::Module (name, llvm::getGlobalContext());

                                ~~~~~~^

./src/codegen.cpp:66:89: error: no member named 'getGlobalContext' in namespace 'llvm'

  std::vector<llvm::Type*> int_types(proto->getParamNum(), llvm::Type::getInt32Ty(llvm::getGlobalContext()));

                                                                                  ~~~~~~^

./src/codegen.cpp:67:88: error: no member named 'getGlobalContext' in namespace 'llvm'

  llvm::FunctionType *func_type = llvm::FunctionType::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), int_types, false);

                                                                                 ~~~~~~^

./src/codegen.cpp:57:25: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]

    if(func->arg_size() == proto->getParamNum() && func->empty()){

       ~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:85:61: error: no member named 'getGlobalContext' in namespace 'llvm'

  llvm::BasicBlock *bblock = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", func);

                                                      ~~~~~~^

./src/codegen.cpp:118:81: error: no member named 'getGlobalContext' in namespace 'llvm'

  llvm::AllocaInst *alloca = Builder->CreateAlloca(llvm::Type::getInt32Ty(llvm::getGlobalContext()), 0, vdecl->getName());

                                                                          ~~~~~~^

./src/codegen.cpp:120:29: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

    llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                            ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:149:29: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

    llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                            ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:200:27: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

  llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                          ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:250:27: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

  llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                          ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:255:62: error: no member named 'getGlobalContext' in namespace 'llvm'

  return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), value);

                                                       ~~~~~~^

8 warnings and 12 errors generated.

make: *** [obj/codegen.o] Error 1

-----
static llvm::LLVMContext TheContext;
///return *(new llvm::Module ("null", llvm::getGlobalContext()));
return *(new llvm::Module ("null", TheContext));
///  https://stackoverflow.com/questions/41760481/what-should-i-replace-getglobalcontext-with-in-llvm-3-9-1 
----
(前略)

./src/codegen.cpp:130:29: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

    llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                            ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:159:29: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

    llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                            ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:210:27: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

  llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                          ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./src/codegen.cpp:260:27: error: non-const lvalue reference to type 'llvm::ValueSymbolTable' cannot bind to a temporary of type 'llvm::ValueSymbolTable *'

  llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

                          ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

8 warnings and 4 errors generated.

make: *** [obj/codegen.o] Error 1

---dcc.cpp
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include <fcntl.h>
#include "lexer.hpp"
#include "AST.hpp"
#include "APP.hpp"
#include "parser.hpp"
#include "codegen.hpp"
#include "option_parser.hpp"

int main(int argc, char **argv){
  llvm::InitializeNativeTarget();
llvm::sys::PrintStackTraceOnErrorSignal(*argv);///  llvm::sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc, argv);
  llvm::EnableDebugBuffering = true;

  OptionParser opt(argc, argv);
  if(!opt.parseOption()){
    exit(1);
  }

  if(opt.getInputFileName().length() == 0){
    fprintf(stderr, "入力ファイル名が設定されていません\n");
    exit(1);
  }

  Parser *parser = new Parser(opt.getInputFileName());
  if(parser->doParse()){
    fprintf(stderr, "error at parser or lexer\n");
    SAFE_DELETE(parser);
    exit(1);
  }

  TranslationUnitAST &tunit = parser->getAST();
  if(tunit.empty()){
    fprintf(stderr, "TranslationUnit is empty\n");
    SAFE_DELETE(parser);
    exit(1);
  }

  CodeGen *codegen = new CodeGen();
  if(!codegen->doCodeGen(tunit, opt.getInputFileName())){
    fprintf(stderr, "error at codegen\n");
    SAFE_DELETE(parser);
    SAFE_DELETE(codegen);
    exit(1);
  }

  llvm::Module &mod = codegen->getModule();
  if(mod.empty()){
    fprintf(stderr, "Module is empty\n");
    SAFE_DELETE(parser);
    SAFE_DELETE(codegen);
    exit(1);
  }


  int fd = open(opt.getOutputFileName().c_str(), O_WRONLY | O_CREAT, S_IWRITE);
  if(fd == -1){
    fprintf(stderr, "output file error\n");
    SAFE_DELETE(parser);
    SAFE_DELETE(codegen);
    exit(1);
  }

  llvm::raw_fd_ostream raw_stream(fd, true);
llvm::PrintModulePass pm(raw_stream);
llvm::ModuleAnalysisManager DummyMAM;/// https://llvm.org/doxygen/IRPrintingPasses_8cpp_source.html#l00045
pm.run(mod, DummyMAM);///  pm.run(mod);
  raw_stream.close();

  SAFE_DELETE(parser);
  SAFE_DELETE(codegen);

  return 0;
}
----codegen.cpp
#include "codegen.hpp"
static llvm::LLVMContext TheContext;

CodeGen::CodeGen(){
Builder = new llvm::IRBuilder<>(TheContext);
  Mod = NULL;
}

CodeGen::~CodeGen(){
SAFE_DELETE(Builder);
SAFE_DELETE(Mod);
}


bool CodeGen::doCodeGen(TranslationUnitAST &tunit, std::string name){
  return generateTranslationUnit(tunit, name);
}

llvm::Module &CodeGen::getModule(){
  if(Mod){
    return *Mod;
  }
  else{
///return *(new llvm::Module ("null", llvm::getGlobalContext()));
return *(new llvm::Module ("null", TheContext));
///  https://stackoverflow.com/questions/41760481/what-should-i-replace-getglobalcontext-with-in-llvm-3-9-1 static LLVMContext TheContext;
  }
}

bool CodeGen::generateTranslationUnit(TranslationUnitAST &tunit, std::string name){
///  Mod = new llvm::Module (name, llvm::getGlobalContext());
Mod = new llvm::Module (name, TheContext);

  for(int i = 0; ; i++){
    PrototypeAST *proto = tunit.getPrototype(i);
    if(!proto){
      break;
    }
    else if(!generatePrototype(proto, Mod)){
      SAFE_DELETE(Mod);
      return false;
    }
  }

  for(int i = 0; ; i++){
    FunctionAST *func = tunit.getFunction(i);
    if(!func){
      break;
    }
    else if(!generateFunctionDefinition(func, Mod)){
      SAFE_DELETE(Mod);
      return false;
    }
  }
  return true;
}

llvm::Function *CodeGen::generatePrototype(PrototypeAST *proto, llvm::Module *mod){
  llvm::Function *func = mod->getFunction(proto->getName());
  if(func){
    if(func->arg_size() == proto->getParamNum() && func->empty()){
      return func;
    }
    else{
      fprintf(stderr, "error::function %s id redefined", proto->getName().c_str());
      return NULL;
    }
  }

///  std::vector<llvm::Type*> int_types(proto->getParamNum(), llvm::Type::getInt32Ty(llvm::getGlobalContext()));
std::vector<llvm::Type*> int_types(proto->getParamNum(), llvm::Type::getInt32Ty(TheContext));
///  llvm::FunctionType *func_type = llvm::FunctionType::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), int_types, false);
llvm::FunctionType *func_type = llvm::FunctionType::get(llvm::Type::getInt32Ty(TheContext), int_types, false);
  func = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage, proto->getName(), mod);

  llvm::Function::arg_iterator arg_iter = func->arg_begin();
  for(int i = 0; i< proto->getParamNum(); i++){
    arg_iter->setName(proto->getParamName(i).append("_arg"));
    arg_iter++;
  }

  return func;
}


llvm::Function *CodeGen::generateFunctionDefinition(FunctionAST *func_ast, llvm::Module *mod){
  llvm::Function *func = generatePrototype(func_ast->getPrototype(), mod);
  if(!func){
    return NULL;
  }
CurFunc = func;
///llvm::BasicBlock *bblock = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", func);
llvm::BasicBlock *bblock = llvm::BasicBlock::Create(TheContext, "entry", func);
Builder->SetInsertPoint(bblock);
  generateFunctionStatement(func_ast->getBody());

  return func;
}

llvm::Value *CodeGen::generateFunctionStatement(FunctionStmtAST *func_stmt){
  VariableDeclAST *vdecl;
  llvm::Value *v = NULL;
  for(int i = 0; ; i++){
    if(!func_stmt->getVariableDecl(i)){
      break;
    }
    vdecl = llvm::dyn_cast<VariableDeclAST>(func_stmt->getVariableDecl(i));
    v = generateVariableDeclaration(vdecl);
  }

  BaseAST *stmt;
  for(int i = 0; ; i++){
    stmt = func_stmt->getStatement(i);
    if(!stmt){
      break;
    }
    else if(!llvm::isa<NullExprAST>(stmt)){
      v = generateStatement(stmt);
    }
  }

  return v;
}

llvm::Value *CodeGen::generateVariableDeclaration(VariableDeclAST *vdecl){
///llvm::AllocaInst *alloca = Builder->CreateAlloca(llvm::Type::getInt32Ty(llvm::getGlobalContext()), 0, vdecl->getName());
  llvm::AllocaInst *alloca = Builder->CreateAlloca(llvm::Type::getInt32Ty(TheContext), 0, vdecl->getName());
  if(vdecl->getType() == VariableDeclAST::param){
    llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();
    Builder->CreateStore(vs_table.lookup(vdecl->getName().append("_arg")), alloca);
  }
  return alloca;
}

llvm::Value *CodeGen::generateStatement(BaseAST *stmt){
  if(llvm::isa<BinaryExprAST>(stmt)){
    return generateBinaryExprssion(llvm::dyn_cast<BinaryExprAST>(stmt));
  }
  else if(llvm::isa<CallExprAST>(stmt)){
    return generateCallExpression(llvm::dyn_cast<CallExprAST>(stmt));
  }
  else if(llvm::isa<JumpStmtAST>(stmt)){
    return generateJumpStatement(llvm::dyn_cast<JumpStmtAST>(stmt));
  }
  else{
    return NULL;
  }
}

llvm::Value *CodeGen::generateBinaryExprssion(BinaryExprAST *bin_expr){
  BaseAST *lhs = bin_expr->getLHS();
  BaseAST *rhs = bin_expr->getRHS();
  llvm::Value *lhs_v;
  llvm::Value *rhs_v;

  if(bin_expr->getOp() == "="){
    VariableAST *lhs_var = llvm::dyn_cast<VariableAST>(lhs);
    llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();
    lhs_v = vs_table.lookup(lhs_var->getName());
  }
  else{
    if(llvm::isa<BinaryExprAST>(lhs)){
      lhs_v = generateBinaryExprssion(llvm::dyn_cast<BinaryExprAST>(lhs));
    }
    else if(llvm::isa<VariableAST>(lhs)){
      lhs_v = generateVariable(llvm::dyn_cast<VariableAST>(lhs));
    }
    else if(llvm::isa<NumberAST>(lhs)){
      NumberAST *num = llvm::dyn_cast<NumberAST>(lhs);
      lhs_v = generateNumber(num->getNumberValue());
    }
  }

  if(llvm::isa<BinaryExprAST>(rhs)){
    rhs_v = generateBinaryExprssion(llvm::dyn_cast<BinaryExprAST>(rhs));
  }
  else if(llvm::isa<CallExprAST>(rhs)){
    rhs_v = generateCallExpression(llvm::dyn_cast<CallExprAST>(rhs));
  }
  else if(llvm::isa<VariableAST>(rhs)){
    rhs_v = generateVariable(llvm::dyn_cast<VariableAST>(rhs));
  }
  else if(llvm::isa<NumberAST>(rhs)){
    NumberAST *num = llvm::dyn_cast<NumberAST>(rhs);
    rhs_v = generateNumber(num->getNumberValue());
  }

  if(bin_expr->getOp() == "="){
    return Builder->CreateStore(rhs_v, lhs_v);
  }
  else if(bin_expr->getOp() == "+"){
    return Builder->CreateAdd(lhs_v, rhs_v, "add_tmp");
  }
  else if(bin_expr->getOp() == "-"){
    return Builder->CreateSub(lhs_v, rhs_v, "sub_tmp");
  }
  else if(bin_expr->getOp() == "*"){
    return Builder->CreateMul(lhs_v, rhs_v, "mul_tmp");
  }
  else if(bin_expr->getOp() == "/"){
    return Builder->CreateSDiv(lhs_v, rhs_v, "div_tmp");
  }
}

llvm::Value *CodeGen::generateCallExpression(CallExprAST *call_expr){
  std::vector<llvm::Value*> arg_vec;
  BaseAST *arg;
  llvm::Value *arg_v;
  llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();

  for(int i = 0; ; i++){
    if(!(arg = call_expr->getArgs(i))){
      break;
    }

    if(llvm::isa<CallExprAST>(arg)){
      arg_v = generateCallExpression(llvm::dyn_cast<CallExprAST>(arg));
    }
    else if(llvm::isa<BinaryExprAST>(arg)){
      BinaryExprAST *bin_expr = llvm::dyn_cast<BinaryExprAST>(arg);
      arg_v = generateBinaryExprssion(llvm::dyn_cast<BinaryExprAST>(arg));
      if(bin_expr->getOp() == "="){
        VariableAST *var = llvm::dyn_cast<VariableAST>(bin_expr->getLHS());
        arg_v = Builder->CreateLoad(vs_table.lookup(var->getName()), "arg_val");
      }
    }
    else if(llvm::isa<VariableAST>(arg)){
      arg_v = generateVariable(llvm::dyn_cast<VariableAST>(arg));
    }
    else if(llvm::isa<NumberAST>(arg)){
      NumberAST *num = llvm::dyn_cast<NumberAST>(arg);
      arg_v = generateNumber(num->getNumberValue());
    }
    arg_vec.push_back(arg_v);
  }

  return Builder->CreateCall(Mod->getFunction(call_expr->getCallee()), arg_vec, "call_tmp");
}

llvm::Value *CodeGen::generateJumpStatement(JumpStmtAST *jump_stmt){
  BaseAST *expr = jump_stmt->getExpr();
  llvm::Value *ret_v;

  if(llvm::isa<BinaryExprAST>(expr)){
    ret_v = generateBinaryExprssion(llvm::dyn_cast<BinaryExprAST>(expr));
  }
  else if(llvm::isa<VariableAST>(expr)){
    ret_v = generateVariable(llvm::dyn_cast<VariableAST>(expr));
  }
  else if(llvm::isa<NumberAST>(expr)){
    NumberAST *num = llvm::dyn_cast<NumberAST>(expr);
    ret_v = generateNumber(num->getNumberValue());
  }

  Builder->CreateRet(ret_v);
}

llvm::Value *CodeGen::generateVariable(VariableAST *var){
  llvm::ValueSymbolTable &vs_table = CurFunc->getValueSymbolTable();
  return Builder->CreateLoad(vs_table.lookup(var->getName()), "var_tmp");
}

llvm::Value *CodeGen::generateNumber(int value){
///return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), value);
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(TheContext), value);

}


13:24 | 投票する | 投票数(0) | コメント(0)