forked from OSchip/llvm-project
[LLVM-C] Add Bindings For Named Metadata
Summary: Add a new type for named metadata nodes. Use this to implement iterators and accessors for NamedMDNodes and extend the echo test to use them to copy module-level debug information. Reviewers: whitequark, deadalnix, aprantl, dexonsmith Reviewed By: whitequark Subscribers: Wallbraker, JDevlieghere, llvm-commits, harlanhaskins Differential Revision: https://reviews.llvm.org/D47179 llvm-svn: 341085
This commit is contained in:
parent
8d39ed895f
commit
0a35b7668b
|
@ -842,6 +842,63 @@ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M);
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -89,6 +89,13 @@ typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
|
|||
*/
|
||||
typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
|
||||
|
||||
/**
|
||||
* Represents an LLVM Named Metadata Node.
|
||||
*
|
||||
* This models llvm::NamedMDNode.
|
||||
*/
|
||||
typedef struct LLVMOpaqueNamedMDNode *LLVMNamedMDNodeRef;
|
||||
|
||||
/**
|
||||
* Represents an LLVM basic block builder.
|
||||
*
|
||||
|
|
|
@ -1316,10 +1316,11 @@ public:
|
|||
//===----------------------------------------------------------------------===//
|
||||
/// 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;
|
||||
|
@ -1420,6 +1421,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_ISA_CONVERSION_FUNCTIONS(NamedMDNode, LLVMNamedMDNodeRef)
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_IR_METADATA_H
|
||||
|
|
|
@ -1065,6 +1065,54 @@ unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) {
|
|||
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())) {
|
||||
|
|
|
@ -166,6 +166,11 @@ exit:
|
|||
ret void
|
||||
}
|
||||
|
||||
!llvm.module.flags = !{!1}
|
||||
!llvm.module.flags = !{!0}
|
||||
!named = !{!1, !2, !3}
|
||||
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!0 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!1 = distinct !{}
|
||||
!2 = distinct !{}
|
||||
!3 = !{!4}
|
||||
!4 = distinct !{}
|
||||
|
|
|
@ -916,7 +916,7 @@ AliasDecl:
|
|||
if (!Begin) {
|
||||
if (End != nullptr)
|
||||
report_fatal_error("Range has an end but no beginning");
|
||||
return;
|
||||
goto NamedMDDecl;
|
||||
}
|
||||
|
||||
Cur = Begin;
|
||||
|
@ -943,6 +943,38 @@ AliasDecl:
|
|||
|
||||
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) {
|
||||
|
@ -1041,7 +1073,7 @@ AliasClone:
|
|||
if (!Begin) {
|
||||
if (End != nullptr)
|
||||
report_fatal_error("Range has an end but no beginning");
|
||||
return;
|
||||
goto NamedMDClone;
|
||||
}
|
||||
|
||||
Cur = Begin;
|
||||
|
@ -1073,6 +1105,47 @@ AliasClone:
|
|||
|
||||
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) {
|
||||
|
@ -1089,18 +1162,6 @@ 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)))
|
||||
|
@ -1115,7 +1176,6 @@ int llvm_echo(void) {
|
|||
char *Str = LLVMPrintModuleToString(M);
|
||||
fputs(Str, stdout);
|
||||
|
||||
LLVMDisposeModuleFlagsMetadata(ModuleFlags);
|
||||
LLVMDisposeMessage(Str);
|
||||
LLVMDisposeModule(Src);
|
||||
LLVMDisposeModule(M);
|
||||
|
|
Loading…
Reference in New Issue