在没有 运行 程序的情况下获取 constexpr

Get constexpr without running the program

我有一个库(作为源代码和已编译的),我正在编写一个程序(未链接到该库),它需要知道库中的某些类型是否是,例如是否可平凡复制。

我可以让我的程序将以下内容写入 file.cpp:

#include "mylibrary.hpp"
int main()
{
    std::cout << std::is_trivially_copyable<A>::value << '\n';
    std::cout << std::is_trivially_copyable<B>::value << '\n';
    std::cout << std::is_trivially_copyable<C>::value << '\n';
    std::cout << std::is_trivially_copyable<D>::value << '\n';
}

然后编译并 运行 这段代码并解析输出。有没有更好的方法来获取这些信息? (性能很重要)。 libclang 能做到吗?

由于评论而更新:

关于XY问题: 我想做的是用 rust 编写一个程序(称为 rust-bindgen),它获取 C++ 头文件的路径作为 am 参数,并为该头文件生成 rust-c++ 绑定。 我需要根据类型是否平凡 copyable/relocatable.

来生成不同的绑定

所以我有一个 C++ 头文件的路径,我需要知道在该头文件中定义的给定类型是否可以轻松复制。 上面的方法有效,但是很慢,因为它涉及编译 file.cpp.

TLDR: 我如何编写一个快速的 Rust 函数,它接受两个字符串作为参数和 returns 一个布尔值:第一个字符串是 C++ 头文件的路径,第二个字符串是在所述头文件中定义的类型的名称文件。它应该 return 一个布尔值,说明该类型是否可平凡复制。

您将需要编译代码,至少编译为 IR。这是因为 C++ class 的琐碎性可能取决于任意复杂的计算,其输入可能包括平台属性、可用 headers、预处理器定义、编译器选项等,因此只能由一个 C++ 编译器。

如果您将 clang 作为二进制文件调用,则发出 IR 的选项是 clang -S -emit-llvm,然后您将需要解析 LLVM IR 输出;例如

#include <type_traits>
struct A {};
struct B { B(B const&); };
struct C { ~C(); };
struct D { D(D const&) = default; };
int a = std::is_trivially_copyable<A>::value;
int b = std::is_trivially_copyable<B>::value;
int c = std::is_trivially_copyable<C>::value;
int d = std::is_trivially_copyable<D>::value;

IR 是:

@a = dso_local local_unnamed_addr global i32 1, align 4, !dbg !0
@b = dso_local local_unnamed_addr global i32 0, align 4, !dbg !6
@c = dso_local local_unnamed_addr global i32 0, align 4, !dbg !10
@d = dso_local local_unnamed_addr global i32 1, align 4, !dbg !12
 ^ variable name                             ^ initializer

如果你想使用libclang,你需要调用EmitLLVMOnlyAction giving a Module which you can then extract the GlobalVariable definitions from. See: Method to create LLVM IR