Parse LLVM IR

Hello,

I am a newbie to LLVM and right now I am on the hook to parse some IR code and do some instrumentations. However, my problem is that no matter how I tweak my parsing code, it simply cannot print out anything.

So here is my C code:

int your_fun(int arg2) {
    int x = arg2;
    return x+2;
}

And here is my parsing code:

#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/Support/SourceMgr.h>
#include <iostream>
#include <llvm/Support/raw_ostream.h>

using namespace llvm;
int main()
{
  LLVMContext context;
  SMDiagnostic error;
  Module *m = parseIRFile("t.ll", error, context).get();
  if(!m)
  {
    return 0;
  }
  std::cout << error.getMessage().str() << std::endl;
  std::cout << sizeof(m->getFunctionList()) << std::endl;
  auto iter1 = m->getFunctionList().begin();
  std::cout << " Function: " << (*iter1).getName().str() << std::endl;

  for (auto iter1 = m->getFunctionList().begin();
       iter1 != m->getFunctionList().end(); iter1++) {
        Function &f = *iter1;
        std::cout << " Function: " << std::endl;
        std::cout << " Function: " << f.getName().str() << std::endl;
        for (auto iter2 = f.getBasicBlockList().begin();
         iter2 != f.getBasicBlockList().end(); iter2++) {
             BasicBlock &bb = *iter2;
             std::cout << "  BasicBlock: " << bb.getName().str() << std::endl;
             for (auto iter3 = bb.begin(); iter3 != bb.end(); iter3++) {
               Instruction &inst = *iter3;
               std::cout << "   Instruction " << &inst << " : " << inst.getOpcodeName();

            unsigned int  i = 0;
            unsigned int opnt_cnt = inst.getNumOperands();
               for(; i < opnt_cnt; ++i)
               {
                 Value *opnd = inst.getOperand(i);
                 std::string o;
                 if (opnd->hasName()) {
                   o = opnd->getName();
                   std::cout << " " << o << "," ;
                 } else {
                   std::cout << " ptr" << opnd << ",";
                 }
               }
               std:: cout << std::endl;
             }
           }
  }
  return 1;

}

And this is my output:

Any suggestions on this? I am sorry for the trouble this has caused, but the inconsistent APIs cause me a bunch of confusions…

Best,
Irene

At a first glance your usage looks correct.
Though, it seems like you are misusing the sizeof: I assume you want to see the number of functions in the module, while sizeof returns size of the iterator itself.
Then, it seems there are no functions in the module, therefore you are dereferencing an iterator that points to invalid location, then your program terminates.

One reason the module can be empty:

    Module *m = parseIRFile("t.ll", error, context).get();

In this line, parseIRFile returns std::unique_ptr<Module>, but the result is not stored anywhere, the instance of unique_ptr deallocated right after the call to .get() at the end of the line.
When you use the Module *m later on it already points to a deallocated memory.

I hope it helps.

Cheers,
Alex.

Thank you Alex. Yes, it works as expected…

Regards,
Irene