diff --git a/bindings/go/llvm/IRBindings.h b/bindings/go/llvm/IRBindings.h index f4f490391d4..25a00b13804 100644 --- a/bindings/go/llvm/IRBindings.h +++ b/bindings/go/llvm/IRBindings.h @@ -26,7 +26,6 @@ extern "C" { #endif -typedef struct LLVMOpaqueMetadata *LLVMMetadataRef; struct LLVMDebugLocMetadata{ unsigned Line; unsigned Col; @@ -59,16 +58,6 @@ void LLVMSetSubprogram(LLVMValueRef Fn, LLVMMetadataRef SP); #ifdef __cplusplus } -namespace llvm { - -DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef) - -inline Metadata **unwrap(LLVMMetadataRef *Vals) { - return reinterpret_cast(Vals); -} - -} - #endif #endif diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 7f5c05d21e6..0a1d8faf99b 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -2130,6 +2130,16 @@ LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, */ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count); +/** + * Obtain a Metadata as a Value. + */ +LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD); + +/** + * Obtain a Value as a Metadata. + */ +LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val); + /** * Obtain the underlying string from a MDString value. * diff --git a/include/llvm-c/Types.h b/include/llvm-c/Types.h index 3d472a6bf47..13fb36ec86e 100644 --- a/include/llvm-c/Types.h +++ b/include/llvm-c/Types.h @@ -82,6 +82,13 @@ typedef struct LLVMOpaqueValue *LLVMValueRef; */ typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef; +/** + * Represents an LLVM Metadata. + * + * This models llvm::Metadata. + */ +typedef struct LLVMOpaqueMetadata *LLVMMetadataRef; + /** * Represents an LLVM basic block builder. * diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index fd79355bff1..8f24a6a1d69 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -30,6 +30,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/ErrorHandling.h" #include #include @@ -133,6 +134,14 @@ public: /// @} }; +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef) + +// Specialized opaque metadata conversions. +inline Metadata **unwrap(LLVMMetadataRef *MDs) { + return reinterpret_cast(MDs); +} + #define HANDLE_METADATA(CLASS) class CLASS; #include "llvm/IR/Metadata.def" diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index b5ed30b85c8..bc7cf0b91c0 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -863,6 +863,19 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) { return LLVMMDNodeInContext(LLVMGetGlobalContext(), Vals, Count); } +LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) { + return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD))); +} + +LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val) { + auto *V = unwrap(Val); + if (auto *C = dyn_cast(V)) + return wrap(ConstantAsMetadata::get(C)); + if (auto *MAV = dyn_cast(V)) + return wrap(MAV->getMetadata()); + return wrap(ValueAsMetadata::get(V)); +} + const char *LLVMGetMDString(LLVMValueRef V, unsigned *Length) { if (const auto *MD = dyn_cast(unwrap(V))) if (const MDString *S = dyn_cast(MD->getMetadata())) {