LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
/**
+ * Obtain an iterator to the first NamedMDNode in a Module.
+ *
+ * @see llvm::Module::named_metadata_begin()
+ */
+LLVMNamedMDNodeRef LLVMGetFirstNamedMetadata(LLVMModuleRef M);
+
+/**
+ * Obtain an iterator to the last NamedMDNode in a Module.
+ *
+ * @see llvm::Module::named_metadata_end()
+ */
+LLVMNamedMDNodeRef LLVMGetLastNamedMetadata(LLVMModuleRef M);
+
+/**
+ * Advance a NamedMDNode iterator to the next NamedMDNode.
+ *
+ * Returns NULL if the iterator was already at the end and there are no more
+ * named metadata nodes.
+ */
+LLVMNamedMDNodeRef LLVMGetNextNamedMetadata(LLVMNamedMDNodeRef NamedMDNode);
+
+/**
+ * Decrement a NamedMDNode iterator to the previous NamedMDNode.
+ *
+ * Returns NULL if the iterator was already at the beginning and there are
+ * no previous named metadata nodes.
+ */
+LLVMNamedMDNodeRef LLVMGetPreviousNamedMetadata(LLVMNamedMDNodeRef NamedMDNode);
+
+/**
+ * Retrieve a NamedMDNode with the given name, returning NULL if no such
+ * node exists.
+ *
+ * @see llvm::Module::getNamedMetadata()
+ */
+LLVMNamedMDNodeRef LLVMGetNamedMetadata(LLVMModuleRef M,
+ const char *Name, size_t NameLen);
+
+/**
+ * Retrieve a NamedMDNode with the given name, creating a new node if no such
+ * node exists.
+ *
+ * @see llvm::Module::getOrInsertNamedMetadata()
+ */
+LLVMNamedMDNodeRef LLVMGetOrInsertNamedMetadata(LLVMModuleRef M,
+ const char *Name,
+ size_t NameLen);
+
+/**
+ * Retrieve the name of a NamedMDNode.
+ *
+ * @see llvm::NamedMDNode::getName()
+ */
+const char *LLVMGetNamedMetadataName(LLVMNamedMDNodeRef NamedMD,
+ size_t *NameLen);
+
+/**
* Obtain the number of operands for named metadata in a module.
*
* @see llvm::Module::getNamedMetadata()
typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
/**
+ * Represents an LLVM Named Metadata Node.
+ *
+ * This models llvm::NamedMDNode.
+ */
+typedef struct LLVMOpaqueNamedMDNode *LLVMNamedMDNodeRef;
+
+/**
* Represents an LLVM basic block builder.
*
* This models llvm::IRBuilder.
//===----------------------------------------------------------------------===//
/// A tuple of MDNodes.
///
-/// Despite its name, a NamedMDNode isn't itself an MDNode. NamedMDNodes belong
-/// to modules, have names, and contain lists of MDNodes.
+/// Despite its name, a NamedMDNode isn't itself an MDNode.
///
-/// TODO: Inherit from Metadata.
+/// NamedMDNodes are named module-level entities that contain lists of MDNodes.
+///
+/// It is illegal for a NamedMDNode to appear as an operand of an MDNode.
class NamedMDNode : public ilist_node<NamedMDNode> {
friend class LLVMContextImpl;
friend class Module;
}
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_ISA_CONVERSION_FUNCTIONS(NamedMDNode, LLVMNamedMDNodeRef)
+
} // end namespace llvm
#endif // LLVM_IR_METADATA_H
return cast<MDNode>(MD->getMetadata())->getNumOperands();
}
+LLVMNamedMDNodeRef LLVMGetFirstNamedMetadata(LLVMModuleRef M) {
+ Module *Mod = unwrap(M);
+ Module::named_metadata_iterator I = Mod->named_metadata_begin();
+ if (I == Mod->named_metadata_end())
+ return nullptr;
+ return wrap(&*I);
+}
+
+LLVMNamedMDNodeRef LLVMGetLastNamedMetadata(LLVMModuleRef M) {
+ Module *Mod = unwrap(M);
+ Module::named_metadata_iterator I = Mod->named_metadata_end();
+ if (I == Mod->named_metadata_begin())
+ return nullptr;
+ return wrap(&*--I);
+}
+
+LLVMNamedMDNodeRef LLVMGetNextNamedMetadata(LLVMNamedMDNodeRef NMD) {
+ NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
+ Module::named_metadata_iterator I(NamedNode);
+ if (++I == NamedNode->getParent()->named_metadata_end())
+ return nullptr;
+ return wrap(&*I);
+}
+
+LLVMNamedMDNodeRef LLVMGetPreviousNamedMetadata(LLVMNamedMDNodeRef NMD) {
+ NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
+ Module::named_metadata_iterator I(NamedNode);
+ if (I == NamedNode->getParent()->named_metadata_begin())
+ return nullptr;
+ return wrap(&*--I);
+}
+
+LLVMNamedMDNodeRef LLVMGetNamedMetadata(LLVMModuleRef M,
+ const char *Name, size_t NameLen) {
+ return wrap(unwrap(M)->getNamedMetadata(StringRef(Name, NameLen)));
+}
+
+LLVMNamedMDNodeRef LLVMGetOrInsertNamedMetadata(LLVMModuleRef M,
+ const char *Name, size_t NameLen) {
+ return wrap(unwrap(M)->getOrInsertNamedMetadata({Name, NameLen}));
+}
+
+const char *LLVMGetNamedMetadataName(LLVMNamedMDNodeRef NMD, size_t *NameLen) {
+ NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
+ *NameLen = NamedNode->getName().size();
+ return NamedNode->getName().data();
+}
+
void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) {
auto *MD = cast<MetadataAsValue>(unwrap(V));
if (auto *MDV = dyn_cast<ValueAsMetadata>(MD->getMetadata())) {
ret void
}
-!llvm.module.flags = !{!1}
-
-!1 = !{i32 2, !"Debug Info Version", i32 3}
+!llvm.module.flags = !{!0}
+!named = !{!1, !2, !3}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !{}
+!2 = distinct !{}
+!3 = !{!4}
+!4 = distinct !{}
if (!Begin) {
if (End != nullptr)
report_fatal_error("Range has an end but no beginning");
- return;
+ goto NamedMDDecl;
}
Cur = Begin;
Cur = Next;
}
+
+NamedMDDecl:
+ LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
+ LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
+ if (!BeginMD) {
+ if (EndMD != nullptr)
+ report_fatal_error("Range has an end but no beginning");
+ return;
+ }
+
+ LLVMNamedMDNodeRef CurMD = BeginMD;
+ LLVMNamedMDNodeRef NextMD = nullptr;
+ while (true) {
+ size_t NameLen;
+ const char *Name = LLVMGetNamedMetadataName(CurMD, &NameLen);
+ if (LLVMGetNamedMetadata(M, Name, NameLen))
+ report_fatal_error("Named Metadata Node already cloned");
+ LLVMGetOrInsertNamedMetadata(M, Name, NameLen);
+
+ NextMD = LLVMGetNextNamedMetadata(CurMD);
+ if (NextMD == nullptr) {
+ if (CurMD != EndMD)
+ report_fatal_error("");
+ break;
+ }
+
+ LLVMNamedMDNodeRef PrevMD = LLVMGetPreviousNamedMetadata(NextMD);
+ if (PrevMD != CurMD)
+ report_fatal_error("Next.Previous global is not Current");
+
+ CurMD = NextMD;
+ }
}
static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
if (!Begin) {
if (End != nullptr)
report_fatal_error("Range has an end but no beginning");
- return;
+ goto NamedMDClone;
}
Cur = Begin;
Cur = Next;
}
+
+NamedMDClone:
+ LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
+ LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
+ if (!BeginMD) {
+ if (EndMD != nullptr)
+ report_fatal_error("Range has an end but no beginning");
+ return;
+ }
+
+ LLVMNamedMDNodeRef CurMD = BeginMD;
+ LLVMNamedMDNodeRef NextMD = nullptr;
+ while (true) {
+ size_t NameLen;
+ const char *Name = LLVMGetNamedMetadataName(CurMD, &NameLen);
+ LLVMNamedMDNodeRef NamedMD = LLVMGetNamedMetadata(M, Name, NameLen);
+ if (!NamedMD)
+ report_fatal_error("Named MD Node must have been declared already");
+
+ unsigned OperandCount = LLVMGetNamedMetadataNumOperands(Src, Name);
+ LLVMValueRef *OperandBuf = static_cast<LLVMValueRef *>(
+ safe_malloc(OperandCount * sizeof(LLVMValueRef)));
+ LLVMGetNamedMetadataOperands(Src, Name, OperandBuf);
+ for (unsigned i = 0, e = OperandCount; i != e; ++i) {
+ LLVMAddNamedMetadataOperand(M, Name, OperandBuf[i]);
+ }
+ free(OperandBuf);
+
+ NextMD = LLVMGetNextNamedMetadata(CurMD);
+ if (NextMD == nullptr) {
+ if (CurMD != EndMD)
+ report_fatal_error("Last Named MD Node does not match End");
+ break;
+ }
+
+ LLVMNamedMDNodeRef PrevMD = LLVMGetPreviousNamedMetadata(NextMD);
+ if (PrevMD != CurMD)
+ report_fatal_error("Next.Previous Named MD Node is not Current");
+
+ CurMD = NextMD;
+ }
}
int llvm_echo(void) {
LLVMSetSourceFileName(M, SourceFileName, SourceFileLen);
LLVMSetModuleIdentifier(M, ModuleName, ModuleIdentLen);
- size_t SourceFlagsLen;
- LLVMModuleFlagEntry *ModuleFlags =
- LLVMCopyModuleFlagsMetadata(Src, &SourceFlagsLen);
- for (unsigned i = 0; i < SourceFlagsLen; ++i) {
- size_t EntryNameLen;
- const char *EntryName =
- LLVMModuleFlagEntriesGetKey(ModuleFlags, i, &EntryNameLen);
- LLVMAddModuleFlag(M, LLVMModuleFlagEntriesGetFlagBehavior(ModuleFlags, i),
- EntryName, EntryNameLen,
- LLVMModuleFlagEntriesGetMetadata(ModuleFlags, i));
- }
-
LLVMSetTarget(M, LLVMGetTarget(Src));
LLVMSetModuleDataLayout(M, LLVMGetModuleDataLayout(Src));
if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src)))
char *Str = LLVMPrintModuleToString(M);
fputs(Str, stdout);
- LLVMDisposeModuleFlagsMetadata(ModuleFlags);
LLVMDisposeMessage(Str);
LLVMDisposeModule(Src);
LLVMDisposeModule(M);