从 C++ 创建 LLVM 字节码类

发布于 2024-11-16 14:10:42 字数 513 浏览 6 评论 0原文

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

// lib.c
int f() {
    return 123;
}

这对于像But 的部分库的编写方式

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

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

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

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

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

I'm writing a compiler for a special purpose language in LLVM. I want to add bindings for a library that is already written in C++. My idea is to compile the library to LLVM bytecode (using clang -emit-llvm -S abc.c) and link it during compilation. This works well for code like

// lib.c
int f() {
    return 123;
}

But parts of the library are written like

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

Which results in empty bytecode files. I know that I can fix this by separating the implementation:

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

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

But that would be a lot of tedious work. Is there any way to create useful bytecode from my library sources as they are? Or any other way to make the library available in my compiler?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

゛时过境迁 2024-11-23 14:10:42

您可以查看 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

You could see whether clang honours external linkage for explicit template instantiations. This might apply to non-templates, but otherwise you could 'force it' to work for templates.

Simple synopsis:

lib1.h

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

add a file lib1_instantiate.cpp

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

This should instantiate the named templates with external linkage.

If you're stuck with a non-template class, and the trick above doesn't work for that, you might wrap it like so:

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>;

If you're out of luck you'll have to 'use' the inline members for them to get external linkage. A common trick is to use the address of these members (you won't need to implement delegating stuff):

instantiate.cpp:

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

However

  1. the conversion to (void*) invokes undefined behaviour (you can't compile that with -pedantic -Werror on gcc)
  2. for overloads you'll have to specify ugly casts to disambiguate them

HTH

想你只要分分秒秒 2024-11-23 14:10:42

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

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

// and so on

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

An alternative which works if one only wants to use a few library functions: Create a wrapper for everything that you use.

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

// and so on

This way you don't have to modify your library, but it's definitely some extra typing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文