如何获得LLVM中的原始源和行号?

时间:2019-01-15 05:22:02

标签: llvm

我从LLVM源树的Hello.cpp修改了以下代码。该代码当前可打印功能,指令和操作数。

我还想打印源文件名和函数,指令和访问的变量的行号。有人可以告诉我怎么做吗?

$ cat Hello.cpp
/* vim: set noexpandtab tabstop=2: */
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "hello"

STATISTIC(HelloCounter, "Counts number of functions greeted");

namespace {
  // Hello - The first implementation, without getAnalysisUsage.
  struct Hello : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    Hello() : FunctionPass(ID) {}

    bool runOnFunction(Function &F) override {
      ++HelloCounter;
      errs() << "Hello: ";
      errs().write_escaped(F.getName()) << '\n';

      for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
        errs() << "I:" << *I << "\n";
        for (Use &U : I->operands()) {
          Value *v = U.get();
          errs() << "v:" << *v << "\n";
        }
      }
      return false;
    }
  };
}

char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass");

$ ./main.sh ;./opt.sh 
Hello: main
I:  %1 = alloca i32, align 4
v:i32 1
I:  store i32 0, i32* %1, align 4
v:i32 0
v:  %1 = alloca i32, align 4
I:  call void (...) bitcast (void ()* @f to void (...)*)()
v:void (...)* bitcast (void ()* @f to void (...)*)
I:  ret i32 0
v:i32 0
Hello: f
I:  %1 = load i32, i32* @U, align 4
v:@U = common dso_local global i32 0, align 4
I:  %2 = add nsw i32 %1, 1
v:  %1 = load i32, i32* @U, align 4
v:i32 1
I:  store i32 %2, i32* @U, align 4
v:  %2 = add nsw i32 %1, 1
v:@U = common dso_local global i32 0, align 4
I:  ret void


==> main.sh <==
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

compile=(
    c++
    -I"$HOME"/opt/llvm/include
    -std=c++11 -Wall -pedantic
    -g -fPIC
    -fno-rtti
    -o Hello.cpp.o -c Hello.cpp
)
"${compile[@]}"
link=(
    c++
    -Wl,-flat_namespace -Wl,-undefined -Wl,suppress
    -o x.so
    Hello.cpp.o
)
"${link[@]}"

==> opt.sh <==
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

cmd=(
    ~/opt/llvm/bin/opt
    -load x.so
    -hello
)
"${cmd[@]}" < hello.bc > /dev/null

==> hello.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>

int U;

void f();

int main() {
  f();
  return 0;
}

==> f.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>

extern int U;

void f() {
    ++U;
}

1 个答案:

答案 0 :(得分:0)

您需要将值转换为Instruction,然后可以通过DebugLoc类访问调试信息:

Value *v = U.get();
Instruction *instruction = dyn_cast<Instruction>(v);
const llvm::DebugLoc &debugInfo = instruction->getDebugLoc();

std::string directory = debugInfo->getDirectory();
std::string filePath = debugInfo->getFilename();
int line = debugInfo->getLine();
int column = debugInfo->getColumn();

UPD::确保包含必需的头文件:

#include <llvm/IR/DebugLoc.h>
#include <llvm/IR/DebugInfoMetadata.h>