【问题标题】:Create LLVM bytecode from C++ classes从 C++ 类创建 LLVM 字节码
【发布时间】:2011-06-23 21:55:38
【问题描述】:

我正在为 LLVM 中的一种特殊用途语言编写编译器。我想为已经用 C++ 编写的库添加绑定。我的想法是将库编译为 LLVM 字节码(使用clang -emit-llvm -S abc.c)并在编译期间链接它。这适用于像

这样的代码
// lib.c
int f() {
    return 123;
}

但是库的某些部分是这样写的

// A.cc
class A {
    public:
        int f() { return 123; }
};

这会导致空字节码文件。我知道我可以通过分离实现来解决这个问题:

// A.cc
class A {
    public:
        int f();
};

int A::f() {
    return 123;
}

但这将是很多乏味的工作。有什么方法可以从我的库源中创建有用的字节码吗?或者任何其他方式使库在我的编译器中可用?

【问题讨论】:

  • 您的第一个示例是源文件,而您的第二个示例是头文件。也许这就是问题所在?您是否尝试过在某个虚拟源文件中包含所有头文件并进行编译?
  • @Space_C0wb0y: 两者没有实际区别,都是处理后编译结果。
  • 你是对的 Space_c0wb0y,如果我编译 .hpp 文件,我会得到一个预处理的头文件(我猜这有点糟糕)。但是,如果我将代码放在一个名为 A.cc 的文件中,那么 clang 会产生所描述的输出。我会修改这个例子。

标签: c++ llvm bytecode clang


【解决方案1】:

您可以查看 clang 是否支持显式模板实例化的外部链接。这可能适用于非模板,但否则您可以“强制它”为模板工作。

简单简介:

lib1.h

template <typename T=int>
struct ATemplate { T f() { return 123; } };

添加文件lib1_instantiate.cpp

#include "lib1.h"
template struct ATemplate<int>;
template struct ATemplate<unsigned int>;
template struct ATemplate<long>; // etc.

这应该通过外部链接实例化命名模板

如果你被一个非模板类卡住了,而上面的技巧对此不起作用,你可以像这样包装它:

instantiate.cpp:

namespace hidden_details
{
    template <class libtype> struct instantiator : public libtype 
    // derives... just do something that requires a complete type (not a forward!)
    { };
}

template struct hidden_details::instantiator<A>;

如果你运气不好,你将不得不“使用”内联成员让他们获得外部链接。一个常见的技巧是使用这些成员的地址(您不需要实现委托):

instantiate.cpp:

static void force_use_A()
{
    void* unused = (void*) &A::f;
}

然而

  1. 转换为 (void*) 会调用未定义的行为(您无法在 gcc 上使用 -pedantic -Werror 进行编译)
  2. 对于重载,您必须指定丑陋的强制转换来消除歧义

HTH

【讨论】:

  • 第一个版本可以正常工作,但是为什么要实例化A 3次呢?
  • 不知道你说的第一个版本是什么意思。另外,我实例化了三个不同的模板实例化;那些是不同的!关键是,我的第一个示例与您的问题中的 struct A 不同;我想演示它是如何使用模板类完成的。 (将通过在我的答案中使用不同的结构名称来消除歧义
  • 第一个版本是指第一个替代方案(带有模板实例化的那个)。您的结构的新名称清除了一切,我认为您所做的是对我的示例的精确翻译。谢谢!
【解决方案2】:

如果只想使用几个库函数,另一种可行的方法是:为您使用的所有内容创建一个包装器。

// wrapper.cc
A* A_create() {
    return new A();
}

// and so on

这样你不必修改你的库,但它肯定是一些额外的输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多