创建LLVM IR的方法 [英] Method to create LLVM IR

查看:2980
本文介绍了创建LLVM IR的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建clang工具,我想从clang AST生成LLVM IR。我知道 -emit-llvm 选项,我可以用来获取* .ll文件,但有办法生成IR内部代码?我可以调用的一些方法需要clang AST或AST上下文并返回 llvm :: Module ?我找不到任何显示此示例。

I am creating clang tool and I want to generate LLVM IR from clang AST. I am aware of -emit-llvm option that I can use to get *.ll file, but is there way to generate IR inside code? Some method that I can call that takes clang AST or AST context and returns llvm::Module? I cannot find any example that shows this.

已编辑:
所以我试图使用CodeGenAction为此,让它工作。我结束了未解决的外部符号错误。我缺少某些东西?

Edited: So I tried using CodeGenAction for this, but I can't get it to work. I end up with unresolved external symbol error. Am I missing something?

#include <clang/CodeGen/CodeGenAction.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Basic/DiagnosticOptions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <llvm/ADT/IntrusiveRefCntPtr.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>

using namespace std;

clang::CodeGenAction * getAction(void)
{
    // Path to the C file
    string inputPath = "test.c";

    // Arguments to pass to the clang frontend
    vector<const char *> args;
    args.push_back(inputPath.c_str());

    // The compiler invocation needs a DiagnosticsEngine so it can report problems
    clang::DiagnosticOptions opt = clang::DiagnosticOptions();
    clang::TextDiagnosticPrinter *DiagClient = new clang::TextDiagnosticPrinter(llvm::errs(), &opt);
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
    clang::DiagnosticsEngine Diags(DiagID, &opt, DiagClient);

    // Create the compiler invocation
    clang::CompilerInvocation* CI(new clang::CompilerInvocation());
    clang::CompilerInvocation::CreateFromArgs(*CI, &args[0], &args[0] + args.size(), Diags);

    // Create the compiler instance
    clang::CompilerInstance Clang;
    Clang.setInvocation(CI);

    // Get ready to report problems
    Clang.createDiagnostics(&Diags.getDiagnosticOptions());
    if (!Clang.hasDiagnostics())
        return NULL;

    // Create an action and make the compiler instance carry it out
    clang::CodeGenAction *Act = new clang::EmitLLVMOnlyAction(&llvm::getGlobalContext());
    if (!Clang.ExecuteAction(*Act))
        return NULL;

    return Act;
}

int main(void)
{
    clang::CodeGenAction* Act = getAction();

    // Grab the module built by the EmitLLVMOnlyAction
    std::unique_ptr<llvm::Module> module = Act->takeModule();

    // Print all functions in the module
    for (llvm::Module::FunctionListType::iterator i = module->getFunctionList().begin(); i != module->getFunctionList().end(); ++i)
        printf("%s\n", i->getName().str().c_str());

    return 0;
}

链接过程中出现错误:

LNK1120: 2 unresolved externals 

LNK2001: unresolved external symbol "public: __thiscall clang::EmitLLVMOnlyAction::EmitLLVMOnlyAction(class llvm::LLVMContext *)" (??0EmitLLVMOnlyAction@clang@@QAE@PAVLLVMContext@llvm@@@Z)

LNK2001: unresolved external symbol "public: class std::unique_ptr<class llvm::Module,struct std::default_delete<class llvm::Module> > __thiscall clang::CodeGenAction::takeModule(void)" (?takeModule@CodeGenAction@clang@@QAE?AV?$unique_ptr@VModule@llvm@@U?$default_delete@VModule@llvm@@@std@@@std@@XZ)


推荐答案

在clang中,代码生成发生在 CodeGenModule 类中。在那里你可以通过 llvm :: Module& getModule()const CodeGenModule 在模块级处理代码生成,而 CodeGenFunction 为特定函数执行此操作。在那里你可以找到AST的每个节点的 Emit * 函数。

In clang the code generation happens in the CodeGenModule class. There you can get the current module through llvm::Module & getModule () const. CodeGenModule handles code generation on module level while CodeGenFunction does this for a particular function. There you find Emit* functions for each node of the AST.

这篇关于创建LLVM IR的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆