下面这个完整代码
它相对较短,因为它建立在LLVM 流程的基础设施上
后者替我们完成大部分工作
我们从程序使用cl命名空间中的llvm工具(cl代表命令行)来实现我们的命令行接口
需要调用ParseCommandLineOption函数声明cl::类型的全局变量
以显示我们的程序收单个参数,并且该函数是包含位码文件名的string类型
之后我们实例化一个LLVMContext对象,以存放于LLVM编译相关的所有数据
从而使LLVM是线程安全的
MemoryBuffer类位内存块定义的一个只读接口
ParseBitcodeFile函数将使用这个对象来读取我们的输入文件的内容,并解析文件中LLVM IR 的内容
在检查完错误并保证一切正常后,我们遍历该文件中模块的所有函数
LLVM模块的概念类似于翻译单元,其中包含所有编码到位码文件中的内容,也是LLVM层次结构中的最高实体
在它后面的函数
基本都是块
最后是指令
如果只是一个函数声明,则丢弃它,因为我们想要查找函数定义
当我们找到这些函数定义时,将打印它们的名称和它包含的基本块的数量
如果编译此程序,并使用help运行,可以查找已经准备好的LLVM命令执行功能
想要找到转换为LLVM IR 的C或C++文件,然后将其转换并使用程序进行分析:
clang -c -emit-llvm xxx.c -o xxx.bc
helloword mysource.bc
遇到个错误,这里的文件头的路径是有问题的
后面我改了一下
然后还是不行
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/CommandLine.h>
#include <string>
#include<iostream>
suing namesapace llvm;
static cl::opt<std::string>FileName (cl::Positional, c ::desc ("Birtcodefile"),cl::Required);
int main(int argc char**argv)
{cl::ParseCommandLineOptions(argc,argv,"LLVM hello world\n");LLVMContext context;stad::string error;OwningPtr <MemoryBuffer> mb;Memorybuffer: :getFile(FileNmae .mb);Moudle *m=ParseBitcodeFile(mb.get(),context,&error);if(m==0){std:cerr<<"Errorreading bitcode:"<<error<<std::end:return -1;}raw os ostream o(std::cout);for (Module::conset iterator = m->getFunctionList().begin(),e=m->getFunctionList.end();i!=e;++i){if (!i->isDeclaration()){o<<i->getName()<<"has"<<i-size()<<"basic block(s). \n".;}}return 0
}
后面我才发现,需要clang++,并且我之前的那个makefile文件没有启动的
而且这个文件头问题很大,c++和c和混合
所以换个方法
// 引入相关LLVM头文件
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/CommandLine.h>using namespace llvm;// LLVM上下文全局变量
static ManagedStatic<LLVMContext> GlobalContext;// 命令行位置参数全局变量, 这个参数的含义是需要处理的LLVM IR字节码的文件名
static cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<filename>.bc"), cl::Required);int main(int argc, char **argv) {// 诊断实例SMDiagnostic Err;// 格式化命令行参数,cl::ParseCommandLineOptions(argc, argv);// 读取并格式化LLVM IR字节码文件, 返回LLVM Module(Module是LLVM IR的顶级容器)std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, *GlobalContext);// 错误处理if (!M) {Err.print(argv[0], errs());return 1;}// 遍历Module中的每一个Functionfor (Function &F:*M) {// 过滤掉那些以llvm.开头的无关函数if (!F.isIntrinsic()) {// 打印函数返回类型outs() << *(F.getReturnType());// 打印函数名outs() << ' ' << F.getName() << '(';// 遍历函数的每一个参数for (Function::arg_iterator it = F.arg_begin(), ie = F.arg_end(); it != ie; it++) {// 打印参数类型outs() << *(it->getType());if (it != ie - 1) {outs() << ", ";}}outs() << ")\n";}}
}
这里我测试了之前我写的文章中那个sum函数https://blog.csdn.net/m0_72827793/article/details/135894096