void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes);
/**
+ * Sets a metadata attachment, erasing the existing metadata attachment if
+ * it already exists for the given kind.
+ *
+ * @see llvm::GlobalObject::setMetadata()
+ */
+void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind,
+ LLVMMetadataRef MD);
+
+/**
+ * Erases a metadata attachment of the given kind if it exists.
+ *
+ * @see llvm::GlobalObject::eraseMetadata()
+ */
+void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind);
+
+/**
+ * Removes all metadata attachments from this value.
+ *
+ * @see llvm::GlobalObject::clearMetadata()
+ */
+void LLVMGlobalClearMetadata(LLVMValueRef Global);
+
+/**
+ * Retrieves an array of metadata entries representing the metadata attached to
+ * this value. The caller is responsible for freeing this array by calling
+ * \c LLVMDisposeValueMetadataEntries.
+ *
+ * @see llvm::GlobalObject::getAllMetadata()
+ */
+LLVMValueMetadataEntry *LLVMGlobalCopyAllMetadata(LLVMValueRef Value,
+ size_t *NumEntries);
+
+/**
+ * Destroys value metadata entries.
+ */
+void LLVMDisposeValueMetadataEntries(LLVMValueMetadataEntry *Entries);
+
+/**
+ * Returns the kind of a value metadata entry at a specific index.
+ */
+unsigned LLVMValueMetadataEntriesGetKind(LLVMValueMetadataEntry *Entries,
+ unsigned Index);
+
+/**
+ * Returns the underlying metadata node of a value metadata entry at a
+ * specific index.
+ */
+LLVMMetadataRef
+LLVMValueMetadataEntriesGetMetadata(LLVMValueMetadataEntry *Entries,
+ unsigned Index);
+
+/**
* @}
*/
void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node);
/**
+ * Returns the metadata associated with an instruction value, but filters out
+ * all the debug locations.
+ *
+ * @see llvm::Instruction::getAllMetadataOtherThanDebugLoc()
+ */
+LLVMValueMetadataEntry *
+LLVMInstructionGetAllMetadataOtherThanDebugLoc(LLVMValueRef Instr,
+ size_t *NumEntries);
+
+/**
* Obtain the basic block to which an instruction belongs.
*
* @see llvm::Instruction::getParent()
typedef struct LLVMOpaqueNamedMDNode *LLVMNamedMDNodeRef;
/**
+ * Represents an entry in a Global Object's metadata attachments.
+ *
+ * This models std::pair<unsigned, MDNode *>
+ */
+typedef struct LLVMOpaqueValueMetadataEntry LLVMValueMetadataEntry;
+
+/**
* Represents an LLVM basic block builder.
*
* This models llvm::IRBuilder.
unwrap<Instruction>(Inst)->setMetadata(KindID, N);
}
+LLVMValueMetadataEntry *
+LLVMInstructionGetAllMetadataOtherThanDebugLoc(LLVMValueRef Value,
+ size_t *NumEntries) {
+ return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) {
+ unwrap<Instruction>(Value)->getAllMetadata(Entries);
+ });
+}
+
/*--.. Conversion functions ................................................--*/
#define LLVM_DEFINE_VALUE_CAST(name) \
"only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment");
}
+struct LLVMOpaqueValueMetadataEntry {
+ unsigned Kind;
+ LLVMMetadataRef Metadata;
+};
+
+using MetadataEntries = SmallVectorImpl<std::pair<unsigned, MDNode *>>;
+static LLVMValueMetadataEntry *
+llvm_getMetadata(size_t *NumEntries,
+ llvm::function_ref<void(MetadataEntries &)> AccessMD) {
+ SmallVector<std::pair<unsigned, MDNode *>, 8> MVEs;
+ AccessMD(MVEs);
+
+ LLVMOpaqueValueMetadataEntry *Result =
+ static_cast<LLVMOpaqueValueMetadataEntry *>(
+ safe_malloc(MVEs.size() * sizeof(LLVMOpaqueValueMetadataEntry)));
+ for (unsigned i = 0; i < MVEs.size(); ++i) {
+ const auto &ModuleFlag = MVEs[i];
+ Result[i].Kind = ModuleFlag.first;
+ Result[i].Metadata = wrap(ModuleFlag.second);
+ }
+ *NumEntries = MVEs.size();
+ return Result;
+}
+
+LLVMValueMetadataEntry *LLVMGlobalCopyAllMetadata(LLVMValueRef Value,
+ size_t *NumEntries) {
+ return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) {
+ if (Instruction *Instr = dyn_cast<Instruction>(unwrap(Value))) {
+ Instr->getAllMetadata(Entries);
+ } else {
+ unwrap<GlobalObject>(Value)->getAllMetadata(Entries);
+ }
+ });
+}
+
+unsigned LLVMValueMetadataEntriesGetKind(LLVMValueMetadataEntry *Entries,
+ unsigned Index) {
+ LLVMOpaqueValueMetadataEntry MVE =
+ static_cast<LLVMOpaqueValueMetadataEntry>(Entries[Index]);
+ return MVE.Kind;
+}
+
+LLVMMetadataRef
+LLVMValueMetadataEntriesGetMetadata(LLVMValueMetadataEntry *Entries,
+ unsigned Index) {
+ LLVMOpaqueValueMetadataEntry MVE =
+ static_cast<LLVMOpaqueValueMetadataEntry>(Entries[Index]);
+ return MVE.Metadata;
+}
+
+void LLVMDisposeValueMetadataEntries(LLVMValueMetadataEntry *Entries) {
+ free(Entries);
+}
+
+void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind,
+ LLVMMetadataRef MD) {
+ unwrap<GlobalObject>(Global)->setMetadata(Kind, unwrapDI<MDNode>(MD));
+}
+
+void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind) {
+ unwrap<GlobalObject>(Global)->eraseMetadata(Kind);
+}
+
+void LLVMGlobalClearMetadata(LLVMValueRef Global) {
+ unwrap<GlobalObject>(Global)->clearMetadata();
+}
+
/*--.. Operations on global variables ......................................--*/
LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) {
ret void
}
-!llvm.module.flags = !{!0}
-!named = !{!1, !2, !3}
-
-!0 = !{i32 2, !"Debug Info Version", i32 3}
-!1 = distinct !{}
-!2 = distinct !{}
-!3 = !{!4}
-!4 = distinct !{}
+define void @with_debuginfo() !dbg !4 {
+ ret void, !dbg !7
+}
+
+!llvm.dbg.cu = !{!0, !2}
+!llvm.module.flags = !{!3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "echo.ll", directory: "/llvm/test/Bindings/llvm-c/echo.ll")
+!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = distinct !DISubprogram(name: "with_debuginfo", linkageName: "_with_debuginfo", scope: null, file: !1, line: 42, type: !5, isLocal: false, isDefinition: true, scopeLine: 1519, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, retainedNodes: !6)
+!5 = !DISubroutineType(types: !6)
+!6 = !{}
+!7 = !DILocation(line: 42, scope: !8, inlinedAt: !11)
+!8 = distinct !DILexicalBlock(scope: !9, file: !1, line: 42, column: 12)
+!9 = distinct !DISubprogram(name: "fake_inlined_block", linkageName: "_fake_inlined_block", scope: null, file: !1, line: 82, type: !5, isLocal: false, isDefinition: true, scopeLine: 82, flags: DIFlagPrototyped, isOptimized: true, unit: !2, templateParams: !6, retainedNodes: !6)
+!10 = distinct !DILocation(line: 84, scope: !8, inlinedAt: !11)
+!11 = !DILocation(line: 42, scope: !4)
//===----------------------------------------------------------------------===//
#include "llvm-c-test.h"
+#include "llvm-c/DebugInfo.h"
#include "llvm-c/Target.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ErrorHandling.h"
exit(-1);
}
+ auto Ctx = LLVMGetModuleContext(M);
+ size_t NumMetadataEntries;
+ auto *AllMetadata =
+ LLVMInstructionGetAllMetadataOtherThanDebugLoc(Src,
+ &NumMetadataEntries);
+ for (unsigned i = 0; i < NumMetadataEntries; ++i) {
+ unsigned Kind = LLVMValueMetadataEntriesGetKind(AllMetadata, i);
+ LLVMMetadataRef MD = LLVMValueMetadataEntriesGetMetadata(AllMetadata, i);
+ LLVMSetMetadata(Dst, Kind, LLVMMetadataAsValue(Ctx, MD));
+ }
+ LLVMDisposeValueMetadataEntries(AllMetadata);
+ LLVMSetInstDebugLocation(Builder, Dst);
+
check_value_kind(Dst, LLVMInstructionValueKind);
return VMap[Src] = Dst;
}
if (auto I = LLVMGetInitializer(Cur))
LLVMSetInitializer(G, clone_constant(I, M));
+ size_t NumMetadataEntries;
+ auto *AllMetadata = LLVMGlobalCopyAllMetadata(Cur, &NumMetadataEntries);
+ for (unsigned i = 0; i < NumMetadataEntries; ++i) {
+ unsigned Kind = LLVMValueMetadataEntriesGetKind(AllMetadata, i);
+ LLVMMetadataRef MD = LLVMValueMetadataEntriesGetMetadata(AllMetadata, i);
+ LLVMGlobalSetMetadata(G, Kind, MD);
+ }
+ LLVMDisposeValueMetadataEntries(AllMetadata);
+
LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur));
LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur));
LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur));
LLVMSetPersonalityFn(Fun, P);
}
+ size_t NumMetadataEntries;
+ auto *AllMetadata = LLVMGlobalCopyAllMetadata(Cur, &NumMetadataEntries);
+ for (unsigned i = 0; i < NumMetadataEntries; ++i) {
+ unsigned Kind = LLVMValueMetadataEntriesGetKind(AllMetadata, i);
+ LLVMMetadataRef MD = LLVMValueMetadataEntriesGetMetadata(AllMetadata, i);
+ LLVMGlobalSetMetadata(Fun, Kind, MD);
+ }
+ LLVMDisposeValueMetadataEntries(AllMetadata);
+
FunCloner FC(Cur, Fun);
FC.CloneBBs(Cur);