Programı çalıştırmadan constexpr alın
Bir kitaplığım var (hem kaynak hem de derlenmiş olarak) ve kitaplıktaki bazı türlerin örneğin önemsiz bir şekilde kopyalanabilir olup olmadığını bilmesi gereken bir program (bu kitaplığa bağlı değil) yazıyorum.
Programımın aşağıdakileri file.cpp'ye yazmasını sağlayabilirim:
#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';
}
daha sonra bu kodu derleyip çalıştırın ve çıktıyı ayrıştırın. Bu bilgiyi almanın daha iyi bir yolu var mı? (performans önemlidir). Libclang bunu yapabilir mi?
Yorumlar nedeniyle GÜNCELLE:
XY sorunu ile ilgili olarak: Yapmaya çalıştığım şey, bir C ++ başlık dosyasının yolunu am argümanı olarak alan ve bu başlık dosyası için rust-c ++ bağları oluşturan bir program (rust-bindgen olarak adlandırılır) yazmaktır. Türün önemsiz bir şekilde kopyalanabilir / yeniden yerleştirilebilir olmasına bağlı olarak bağlamaları farklı şekilde oluşturmam gerekiyor.
Bu yüzden bir C ++ başlık dosyasına giden bir yolum var ve bu başlık dosyasında tanımlanan belirli bir türün önemsiz bir şekilde kopyalanabilir olup olmadığını bilmem gerekiyor. Yukarıdaki yaklaşım işe yarıyor, ancak yavaş, çünkü file.cpp'nin derlenmesini içeriyor.
TLDR: Bir argüman olarak iki dizeyi alan ve bir bool döndüren hızlı bir pas işlevi nasıl yazabilirim: İlk dize, bir C ++ başlık dosyasına giden yoldur, ikinci dize, söz konusu başlık dosyasında tanımlanan bir türün adıdır. Türün önemsiz bir şekilde kopyalanabilir olup olmadığını belirten bir bool döndürmelidir.
Yanıtlar
Kodu, en azından IR için derlemeniz gerekecek. Bunun nedeni, bir C ++ sınıfının önemsizliğinin, girdileri platform özniteliklerini, kullanılabilir üstbilgileri, önişlemci tanımlarını, derleyici seçeneklerini vb. İçerebilen rastgele karmaşık bir hesaplamaya bağlı olabilmesidir ve bu nedenle yalnızca bir C ++ derleyicisi tarafından gerçekleştirilebilir.
Eğer clang'ı ikili olarak çağırıyorsanız, IR yayma seçeneği clang -S -emit-llvm, LLVM IR çıktısını ayrıştırmak isteyeceksiniz; örneğin
#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
Eğer libclang kullanmak istiyorsanız, çağırmak gerekir EmitLLVMOnlyAction bir vererek Modülü sonra gelen GlobalVariable tanımlarını çıkarabilir. Bkz: LLVM IR oluşturma yöntemi