编写代码(LLVM的第一个项目)

下面这个完整代码
它相对较短,因为它建立在LLVM 流程的基础设施上
后者替我们完成大部分工作
编写代码(LLVM的第一个项目)_第1张图片

我们从程序使用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 
#include 
#include 
#include 
#include 
#include 
#include 
#include
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的第一个项目)_第2张图片

// 引入相关LLVM头文件
#include 
#include 
#include 
#include 
#include 
#include 

using namespace llvm;

// LLVM上下文全局变量
static ManagedStatic<LLVMContext> GlobalContext;

// 命令行位置参数全局变量, 这个参数的含义是需要处理的LLVM IR字节码的文件名
static cl::opt<std::string> InputFilename(cl::Positional, cl::desc(".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中的每一个Function
    for (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";
        }
    }
}

编写代码(LLVM的第一个项目)_第3张图片
这里我测试了之前我写的文章中那个sum函数https://blog.csdn.net/m0_72827793/article/details/135894096

你可能感兴趣的:(LLVM,学习)