接続数

COUNTER267932FROM 2012/5/16

MISRA-C diary(C言語日誌)

MISRA-C >> 記事詳細

2017/10/12

link error

Tweet ThisSend to Facebook | by kaizen

make

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>...]


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/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:61: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:209:1: warning: control may reach end of non-void function [-Wreturn-type]

}

^

./src/codegen.cpp:265:1: warning: control reaches end of non-void function [-Wreturn-type]

}

^

./src/codegen.cpp:259:11: warning: variable 'ret_v' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]

  else if(llvm::isa<NumberAST>(expr)){

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

./src/codegen.cpp:264:22: note: uninitialized use occurs here

  Builder->CreateRet(ret_v);

                     ^~~~~

./src/codegen.cpp:259:8: note: remove the 'if' if its condition is always true

  else if(llvm::isa<NumberAST>(expr)){

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

./src/codegen.cpp:251:21: note: initialize the variable 'ret_v' to silence this warning

  llvm::Value *ret_v;

                    ^

                     = nullptr

11 warnings generated.

clang++ -g ./src/option_parser.cpp -I./inc `llvm-config --cxxflags --ldflags --libs -std=c++04` -c -o ./obj/option_parser.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]

mkdir -p ./bin

clang++ -g ./obj/dcc.o ./obj/lexer.o ./obj/AST.o ./obj/parser.o ./obj/codegen.o ./obj/option_parser.o -I./inc `llvm-config --cxxflags --ldflags --libs -std=c++04` -ldl -lz -o ./bin/dcc

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.

Undefined symbols for architecture x86_64:

  "_LLVMInitializeX86Target", referenced from:

      llvm::InitializeNativeTarget() in dcc.o

  "_LLVMInitializeX86TargetInfo", referenced from:

      llvm::InitializeNativeTarget() in dcc.o

  "_LLVMInitializeX86TargetMC", referenced from:

      llvm::InitializeNativeTarget() in dcc.o

  "_LLVMLinkInMCJIT", referenced from:

      (anonymous namespace)::ForceMCJITLinking::ForceMCJITLinking() in dcc.o

      (anonymous namespace)::ForceMCJITLinking::ForceMCJITLinking() in codegen.o

  "llvm::AllocaInst::AllocaInst(llvm::Type*, unsigned int, llvm::Value*, llvm::Twine const&, llvm::Instruction*)", referenced from:

      llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::CreateAlloca(llvm::Type*, llvm::Value*, llvm::Twine const&) in codegen.o

  "llvm::BasicBlock::BasicBlock(llvm::LLVMContext&, llvm::Twine const&, llvm::Function*, llvm::BasicBlock*)", referenced from:

      llvm::BasicBlock::Create(llvm::LLVMContext&, llvm::Twine const&, llvm::Function*, llvm::BasicBlock*) in codegen.o

  "llvm::ReturnInst::ReturnInst(llvm::LLVMContext&, llvm::Value*, llvm::Instruction*)", referenced from:

      llvm::ReturnInst::Create(llvm::LLVMContext&, llvm::Value*, llvm::Instruction*) in codegen.o

  "llvm::ConstantInt::get(llvm::IntegerType*, unsigned long long, bool)", referenced from:

      CodeGen::generateNumber(int) in codegen.o

  "llvm::GCOVOptions::getDefault()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::Instruction::setIsExact(bool)", referenced from:

      llvm::BinaryOperator::CreateExact(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, llvm::Twine const&) in codegen.o

  "llvm::Instruction::setMetadata(unsigned int, llvm::MDNode*)", referenced from:

      llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::AddFPMathAttributes(llvm::Instruction*, llvm::MDNode*, llvm::FastMathFlags) const in codegen.o

  "llvm::Instruction::setFastMathFlags(llvm::FastMathFlags)", referenced from:

      llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::AddFPMathAttributes(llvm::Instruction*, llvm::MDNode*, llvm::FastMathFlags) const in codegen.o

  "llvm::Instruction::setHasNoSignedWrap(bool)", referenced from:

      llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::CreateInsertNUWNSWBinOp(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, llvm::Twine const&, bool, bool) in codegen.o

  "llvm::Instruction::setHasNoUnsignedWrap(bool)", referenced from:

      llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::CreateInsertNUWNSWBinOp(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, llvm::Twine const&, bool, bool) in codegen.o

  "llvm::Instruction::Instruction(llvm::Type*, unsigned int, llvm::Use*, unsigned int, llvm::Instruction*)", referenced from:

      llvm::CallInst::CallInst(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, llvm::Twine const&, llvm::Instruction*) in codegen.o

  "llvm::LLVMContext::LLVMContext()", referenced from:

      ___cxx_global_var_init.1 in codegen.o

  "llvm::LLVMContext::~LLVMContext()", referenced from:

      ___cxx_global_var_init.1 in codegen.o

  "llvm::ConstantExpr::getAdd(llvm::Constant*, llvm::Constant*, bool, bool)", referenced from:

      llvm::ConstantFolder::CreateAdd(llvm::Constant*, llvm::Constant*, bool, bool) const in codegen.o

  "llvm::ConstantExpr::getMul(llvm::Constant*, llvm::Constant*, bool, bool)", referenced from:

      llvm::ConstantFolder::CreateMul(llvm::Constant*, llvm::Constant*, bool, bool) const in codegen.o

  "llvm::ConstantExpr::getSub(llvm::Constant*, llvm::Constant*, bool, bool)", referenced from:

      llvm::ConstantFolder::CreateSub(llvm::Constant*, llvm::Constant*, bool, bool) const in codegen.o

  "llvm::ConstantExpr::getSDiv(llvm::Constant*, llvm::Constant*, bool)", referenced from:

      llvm::ConstantFolder::CreateSDiv(llvm::Constant*, llvm::Constant*, bool) const in codegen.o

  "llvm::FunctionType::get(llvm::Type*, llvm::ArrayRef<llvm::Type*>, bool)", referenced from:

      CodeGen::generatePrototype(PrototypeAST*, llvm::Module*) in codegen.o

  "llvm::PassRegistry::getPassRegistry()", referenced from:

      llvm::IntervalPartition::IntervalPartition() in dcc.o

  "llvm::PMDataManager::~PMDataManager()", referenced from:

      llvm::RGPassManager::~RGPassManager() in dcc.o

  "llvm::RGPassManager::RGPassManager()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createGVNPass(bool)", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::BinaryOperator::Create(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, llvm::Twine const&, llvm::Instruction*)", referenced from:

      llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::CreateInsertNUWNSWBinOp(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, llvm::Twine const&, bool, bool) in codegen.o

      llvm::BinaryOperator::CreateSDiv(llvm::Value*, llvm::Value*, llvm::Twine const&) in codegen.o

      llvm::BinaryOperator::CreateExact(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, llvm::Twine const&) in codegen.o

  "llvm::createLICMPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createLintPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createSCCPPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createSROAPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::raw_fd_ostream::close()", referenced from:

      _main in dcc.o

  "llvm::raw_fd_ostream::raw_fd_ostream(int, bool, bool)", referenced from:

      _main in dcc.o

  "llvm::raw_fd_ostream::~raw_fd_ostream()", referenced from:

      _main in dcc.o

  "llvm::AliasSetTracker::ASTCallbackVH::ASTCallbackVH(llvm::Value*, llvm::AliasSetTracker*)", referenced from:

      llvm::DenseMapBase<llvm::DenseMap<llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*, llvm::AliasSetTracker::ASTCallbackVHDenseMapInfo, llvm::detail::DenseMapPair<llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*> >, llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*, llvm::AliasSetTracker::ASTCallbackVHDenseMapInfo, llvm::detail::DenseMapPair<llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*> >::getEmptyKey() in dcc.o

      llvm::DenseMapBase<llvm::DenseMap<llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*, llvm::AliasSetTracker::ASTCallbackVHDenseMapInfo, llvm::detail::DenseMapPair<llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*> >, llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*, llvm::AliasSetTracker::ASTCallbackVHDenseMapInfo, llvm::detail::DenseMapPair<llvm::AliasSetTracker::ASTCallbackVH, llvm::AliasSet::PointerRec*> >::getTombstoneKey() in dcc.o

  "llvm::AliasSetTracker::add(llvm::Value*, unsigned long long, llvm::AAMDNodes const&)", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::AliasSetTracker::clear()", referenced from:

      llvm::AliasSetTracker::~AliasSetTracker() in dcc.o

  "llvm::AnalysisManager<llvm::Module>::AnalysisManager(bool)", referenced from:

      _main in dcc.o

  "llvm::PrintModulePass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&)", referenced from:

      _main in dcc.o

  "llvm::PrintModulePass::PrintModulePass(llvm::raw_ostream&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:

      _main in dcc.o

  "llvm::ValueHandleBase::RemoveFromUseList()", referenced from:

      llvm::ValueHandleBase::~ValueHandleBase() in dcc.o

  "llvm::ValueHandleBase::AddToExistingUseList(llvm::ValueHandleBase**)", referenced from:

      llvm::ValueHandleBase::ValueHandleBase(llvm::ValueHandleBase::HandleBaseKind, llvm::ValueHandleBase const&) in dcc.o

  "llvm::createLCSSAPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::MetadataTracking::track(void*, llvm::Metadata&, llvm::PointerUnion<llvm::MetadataAsValue*, llvm::Metadata*>)", referenced from:

      llvm::MetadataTracking::track(llvm::Metadata*&) in codegen.o

  "llvm::MetadataTracking::retrack(void*, llvm::Metadata&, void*)", referenced from:

      llvm::MetadataTracking::retrack(llvm::Metadata*&, llvm::Metadata*&) in codegen.o

  "llvm::MetadataTracking::untrack(void*, llvm::Metadata&)", referenced from:

      llvm::MetadataTracking::untrack(llvm::Metadata*&) in codegen.o

  "llvm::createAAEvalPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createIPSCCPPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createNewGVNPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createPAEvalPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::IntervalPartition::ID", referenced from:

      llvm::IntervalPartition::IntervalPartition() in dcc.o

  "llvm::createPostDomTree()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createPruneEHPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createSinkingPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createEarlyCSEPass(bool)", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createGVNHoistPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createLoopSinkPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::raw_string_ostream::~raw_string_ostream()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createDomViewerPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createFloat2IntPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createGlobalDCEPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createInstCountPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

  "llvm::createLoopIdiomPass()", referenced from:

      (anonymous namespace)::ForcePassLinking::ForcePassLinking() in dcc.o

   (中略)

  "vtable for llvm::PrettyStackTraceProgram", referenced from:

      llvm::PrettyStackTraceProgram::PrettyStackTraceProgram(int, char const* const*) in dcc.o

  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

  "vtable for llvm::Pass", referenced from:

      llvm::Pass::Pass(llvm::PassKind, char&) in dcc.o

  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

make: *** [all] Error 1

---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();
llvm::ValueSymbolTable * vs_table = CurFunc->getValueSymbolTable();
///Builder->CreateStore(vs_table.lookup(vdecl->getName().append("_arg")), alloca);
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();
llvm::ValueSymbolTable * vs_table = CurFunc->getValueSymbolTable();
///lhs_v = vs_table.lookup(lhs_var->getName());
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();
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");
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();
llvm::ValueSymbolTable * vs_table = CurFunc->getValueSymbolTable();
///return Builder->CreateLoad(vs_table.lookup(var->getName()), "var_tmp");
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);

}


17:52 | 投票する | 投票数(0) | コメント(0)