Skip to content

Commit 0a35b76

Browse files
committed
[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
1 parent 8d39ed8 commit 0a35b76

File tree

6 files changed

+202
-21
lines changed

6 files changed

+202
-21
lines changed

llvm/include/llvm-c/Core.h

+57
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,63 @@ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M);
842842
*/
843843
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
844844

845+
/**
846+
* Obtain an iterator to the first NamedMDNode in a Module.
847+
*
848+
* @see llvm::Module::named_metadata_begin()
849+
*/
850+
LLVMNamedMDNodeRef LLVMGetFirstNamedMetadata(LLVMModuleRef M);
851+
852+
/**
853+
* Obtain an iterator to the last NamedMDNode in a Module.
854+
*
855+
* @see llvm::Module::named_metadata_end()
856+
*/
857+
LLVMNamedMDNodeRef LLVMGetLastNamedMetadata(LLVMModuleRef M);
858+
859+
/**
860+
* Advance a NamedMDNode iterator to the next NamedMDNode.
861+
*
862+
* Returns NULL if the iterator was already at the end and there are no more
863+
* named metadata nodes.
864+
*/
865+
LLVMNamedMDNodeRef LLVMGetNextNamedMetadata(LLVMNamedMDNodeRef NamedMDNode);
866+
867+
/**
868+
* Decrement a NamedMDNode iterator to the previous NamedMDNode.
869+
*
870+
* Returns NULL if the iterator was already at the beginning and there are
871+
* no previous named metadata nodes.
872+
*/
873+
LLVMNamedMDNodeRef LLVMGetPreviousNamedMetadata(LLVMNamedMDNodeRef NamedMDNode);
874+
875+
/**
876+
* Retrieve a NamedMDNode with the given name, returning NULL if no such
877+
* node exists.
878+
*
879+
* @see llvm::Module::getNamedMetadata()
880+
*/
881+
LLVMNamedMDNodeRef LLVMGetNamedMetadata(LLVMModuleRef M,
882+
const char *Name, size_t NameLen);
883+
884+
/**
885+
* Retrieve a NamedMDNode with the given name, creating a new node if no such
886+
* node exists.
887+
*
888+
* @see llvm::Module::getOrInsertNamedMetadata()
889+
*/
890+
LLVMNamedMDNodeRef LLVMGetOrInsertNamedMetadata(LLVMModuleRef M,
891+
const char *Name,
892+
size_t NameLen);
893+
894+
/**
895+
* Retrieve the name of a NamedMDNode.
896+
*
897+
* @see llvm::NamedMDNode::getName()
898+
*/
899+
const char *LLVMGetNamedMetadataName(LLVMNamedMDNodeRef NamedMD,
900+
size_t *NameLen);
901+
845902
/**
846903
* Obtain the number of operands for named metadata in a module.
847904
*

llvm/include/llvm-c/Types.h

+7
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
8989
*/
9090
typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
9191

92+
/**
93+
* Represents an LLVM Named Metadata Node.
94+
*
95+
* This models llvm::NamedMDNode.
96+
*/
97+
typedef struct LLVMOpaqueNamedMDNode *LLVMNamedMDNodeRef;
98+
9299
/**
93100
* Represents an LLVM basic block builder.
94101
*

llvm/include/llvm/IR/Metadata.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -1316,10 +1316,11 @@ class DistinctMDOperandPlaceholder : public Metadata {
13161316
//===----------------------------------------------------------------------===//
13171317
/// A tuple of MDNodes.
13181318
///
1319-
/// Despite its name, a NamedMDNode isn't itself an MDNode. NamedMDNodes belong
1320-
/// to modules, have names, and contain lists of MDNodes.
1319+
/// Despite its name, a NamedMDNode isn't itself an MDNode.
13211320
///
1322-
/// TODO: Inherit from Metadata.
1321+
/// NamedMDNodes are named module-level entities that contain lists of MDNodes.
1322+
///
1323+
/// It is illegal for a NamedMDNode to appear as an operand of an MDNode.
13231324
class NamedMDNode : public ilist_node<NamedMDNode> {
13241325
friend class LLVMContextImpl;
13251326
friend class Module;
@@ -1420,6 +1421,9 @@ class NamedMDNode : public ilist_node<NamedMDNode> {
14201421
}
14211422
};
14221423

1424+
// Create wrappers for C Binding types (see CBindingWrapping.h).
1425+
DEFINE_ISA_CONVERSION_FUNCTIONS(NamedMDNode, LLVMNamedMDNodeRef)
1426+
14231427
} // end namespace llvm
14241428

14251429
#endif // LLVM_IR_METADATA_H

llvm/lib/IR/Core.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,54 @@ unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) {
10651065
return cast<MDNode>(MD->getMetadata())->getNumOperands();
10661066
}
10671067

1068+
LLVMNamedMDNodeRef LLVMGetFirstNamedMetadata(LLVMModuleRef M) {
1069+
Module *Mod = unwrap(M);
1070+
Module::named_metadata_iterator I = Mod->named_metadata_begin();
1071+
if (I == Mod->named_metadata_end())
1072+
return nullptr;
1073+
return wrap(&*I);
1074+
}
1075+
1076+
LLVMNamedMDNodeRef LLVMGetLastNamedMetadata(LLVMModuleRef M) {
1077+
Module *Mod = unwrap(M);
1078+
Module::named_metadata_iterator I = Mod->named_metadata_end();
1079+
if (I == Mod->named_metadata_begin())
1080+
return nullptr;
1081+
return wrap(&*--I);
1082+
}
1083+
1084+
LLVMNamedMDNodeRef LLVMGetNextNamedMetadata(LLVMNamedMDNodeRef NMD) {
1085+
NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
1086+
Module::named_metadata_iterator I(NamedNode);
1087+
if (++I == NamedNode->getParent()->named_metadata_end())
1088+
return nullptr;
1089+
return wrap(&*I);
1090+
}
1091+
1092+
LLVMNamedMDNodeRef LLVMGetPreviousNamedMetadata(LLVMNamedMDNodeRef NMD) {
1093+
NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
1094+
Module::named_metadata_iterator I(NamedNode);
1095+
if (I == NamedNode->getParent()->named_metadata_begin())
1096+
return nullptr;
1097+
return wrap(&*--I);
1098+
}
1099+
1100+
LLVMNamedMDNodeRef LLVMGetNamedMetadata(LLVMModuleRef M,
1101+
const char *Name, size_t NameLen) {
1102+
return wrap(unwrap(M)->getNamedMetadata(StringRef(Name, NameLen)));
1103+
}
1104+
1105+
LLVMNamedMDNodeRef LLVMGetOrInsertNamedMetadata(LLVMModuleRef M,
1106+
const char *Name, size_t NameLen) {
1107+
return wrap(unwrap(M)->getOrInsertNamedMetadata({Name, NameLen}));
1108+
}
1109+
1110+
const char *LLVMGetNamedMetadataName(LLVMNamedMDNodeRef NMD, size_t *NameLen) {
1111+
NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
1112+
*NameLen = NamedNode->getName().size();
1113+
return NamedNode->getName().data();
1114+
}
1115+
10681116
void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) {
10691117
auto *MD = cast<MetadataAsValue>(unwrap(V));
10701118
if (auto *MDV = dyn_cast<ValueAsMetadata>(MD->getMetadata())) {

llvm/test/Bindings/llvm-c/echo.ll

+8-3
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ exit:
166166
ret void
167167
}
168168

169-
!llvm.module.flags = !{!1}
170-
171-
!1 = !{i32 2, !"Debug Info Version", i32 3}
169+
!llvm.module.flags = !{!0}
170+
!named = !{!1, !2, !3}
171+
172+
!0 = !{i32 2, !"Debug Info Version", i32 3}
173+
!1 = distinct !{}
174+
!2 = distinct !{}
175+
!3 = !{!4}
176+
!4 = distinct !{}

llvm/tools/llvm-c-test/echo.cpp

+75-15
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
916916
if (!Begin) {
917917
if (End != nullptr)
918918
report_fatal_error("Range has an end but no beginning");
919-
return;
919+
goto NamedMDDecl;
920920
}
921921

922922
Cur = Begin;
@@ -943,6 +943,38 @@ static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
943943

944944
Cur = Next;
945945
}
946+
947+
NamedMDDecl:
948+
LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
949+
LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
950+
if (!BeginMD) {
951+
if (EndMD != nullptr)
952+
report_fatal_error("Range has an end but no beginning");
953+
return;
954+
}
955+
956+
LLVMNamedMDNodeRef CurMD = BeginMD;
957+
LLVMNamedMDNodeRef NextMD = nullptr;
958+
while (true) {
959+
size_t NameLen;
960+
const char *Name = LLVMGetNamedMetadataName(CurMD, &NameLen);
961+
if (LLVMGetNamedMetadata(M, Name, NameLen))
962+
report_fatal_error("Named Metadata Node already cloned");
963+
LLVMGetOrInsertNamedMetadata(M, Name, NameLen);
964+
965+
NextMD = LLVMGetNextNamedMetadata(CurMD);
966+
if (NextMD == nullptr) {
967+
if (CurMD != EndMD)
968+
report_fatal_error("");
969+
break;
970+
}
971+
972+
LLVMNamedMDNodeRef PrevMD = LLVMGetPreviousNamedMetadata(NextMD);
973+
if (PrevMD != CurMD)
974+
report_fatal_error("Next.Previous global is not Current");
975+
976+
CurMD = NextMD;
977+
}
946978
}
947979

948980
static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
@@ -1041,7 +1073,7 @@ static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
10411073
if (!Begin) {
10421074
if (End != nullptr)
10431075
report_fatal_error("Range has an end but no beginning");
1044-
return;
1076+
goto NamedMDClone;
10451077
}
10461078

10471079
Cur = Begin;
@@ -1073,6 +1105,47 @@ static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
10731105

10741106
Cur = Next;
10751107
}
1108+
1109+
NamedMDClone:
1110+
LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
1111+
LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
1112+
if (!BeginMD) {
1113+
if (EndMD != nullptr)
1114+
report_fatal_error("Range has an end but no beginning");
1115+
return;
1116+
}
1117+
1118+
LLVMNamedMDNodeRef CurMD = BeginMD;
1119+
LLVMNamedMDNodeRef NextMD = nullptr;
1120+
while (true) {
1121+
size_t NameLen;
1122+
const char *Name = LLVMGetNamedMetadataName(CurMD, &NameLen);
1123+
LLVMNamedMDNodeRef NamedMD = LLVMGetNamedMetadata(M, Name, NameLen);
1124+
if (!NamedMD)
1125+
report_fatal_error("Named MD Node must have been declared already");
1126+
1127+
unsigned OperandCount = LLVMGetNamedMetadataNumOperands(Src, Name);
1128+
LLVMValueRef *OperandBuf = static_cast<LLVMValueRef *>(
1129+
safe_malloc(OperandCount * sizeof(LLVMValueRef)));
1130+
LLVMGetNamedMetadataOperands(Src, Name, OperandBuf);
1131+
for (unsigned i = 0, e = OperandCount; i != e; ++i) {
1132+
LLVMAddNamedMetadataOperand(M, Name, OperandBuf[i]);
1133+
}
1134+
free(OperandBuf);
1135+
1136+
NextMD = LLVMGetNextNamedMetadata(CurMD);
1137+
if (NextMD == nullptr) {
1138+
if (CurMD != EndMD)
1139+
report_fatal_error("Last Named MD Node does not match End");
1140+
break;
1141+
}
1142+
1143+
LLVMNamedMDNodeRef PrevMD = LLVMGetPreviousNamedMetadata(NextMD);
1144+
if (PrevMD != CurMD)
1145+
report_fatal_error("Next.Previous Named MD Node is not Current");
1146+
1147+
CurMD = NextMD;
1148+
}
10761149
}
10771150

10781151
int llvm_echo(void) {
@@ -1089,18 +1162,6 @@ int llvm_echo(void) {
10891162
LLVMSetSourceFileName(M, SourceFileName, SourceFileLen);
10901163
LLVMSetModuleIdentifier(M, ModuleName, ModuleIdentLen);
10911164

1092-
size_t SourceFlagsLen;
1093-
LLVMModuleFlagEntry *ModuleFlags =
1094-
LLVMCopyModuleFlagsMetadata(Src, &SourceFlagsLen);
1095-
for (unsigned i = 0; i < SourceFlagsLen; ++i) {
1096-
size_t EntryNameLen;
1097-
const char *EntryName =
1098-
LLVMModuleFlagEntriesGetKey(ModuleFlags, i, &EntryNameLen);
1099-
LLVMAddModuleFlag(M, LLVMModuleFlagEntriesGetFlagBehavior(ModuleFlags, i),
1100-
EntryName, EntryNameLen,
1101-
LLVMModuleFlagEntriesGetMetadata(ModuleFlags, i));
1102-
}
1103-
11041165
LLVMSetTarget(M, LLVMGetTarget(Src));
11051166
LLVMSetModuleDataLayout(M, LLVMGetModuleDataLayout(Src));
11061167
if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src)))
@@ -1115,7 +1176,6 @@ int llvm_echo(void) {
11151176
char *Str = LLVMPrintModuleToString(M);
11161177
fputs(Str, stdout);
11171178

1118-
LLVMDisposeModuleFlagsMetadata(ModuleFlags);
11191179
LLVMDisposeMessage(Str);
11201180
LLVMDisposeModule(Src);
11211181
LLVMDisposeModule(M);

0 commit comments

Comments
 (0)