// Use ifunc_size() to get the number of functions in IFuncList.
// Use ifuncs() to get the range of all IFuncs.
+ /// Detach \p MDNode from the list but don't delete it.
+ void removeNamedMDNode(NamedMDNode *MDNode) { NamedMDList.remove(MDNode); }
+ /// Remove \p MDNode from the list and delete it.
+ void eraseNamedMDNode(NamedMDNode *MDNode) { NamedMDList.erase(MDNode); }
+ /// Insert \p MDNode at the end of the alias list and take ownership.
+ void insertNamedMDNode(NamedMDNode *MDNode) {
+ NamedMDList.push_back(MDNode);
+ }
+ // Use named_metadata_size() to get the size of the named meatadata list.
+ // Use named_metadata() to get the range of all named metadata.
+
private: // Please use functions like insertAlias(), removeAlias() etc.
/// Get the Module's list of aliases (constant).
const AliasListType &getAliasList() const { return AliasList; }
}
friend class llvm::SymbolTableListTraits<llvm::GlobalIFunc>;
-public:
/// Get the Module's list of named metadata (constant).
const NamedMDListType &getNamedMDList() const { return NamedMDList; }
/// Get the Module's list of named metadata.
return &Module::NamedMDList;
}
+public:
/// Get the symbol table of global variable and function identifiers
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
/// Get the Module's symbol table of global variable and function identifiers.
// Create a new llvm.dbg.cu, which is equivalent to the one
// -gline-tables-only would have created.
- for (auto &NMD : M.getNamedMDList()) {
+ for (auto &NMD : M.named_metadata()) {
SmallVector<MDNode *, 8> Ops;
for (MDNode *Op : NMD.operands())
Ops.push_back(remap(Op));
if (!NMD) {
NMD = new NamedMDNode(Name);
NMD->setParent(this);
- NamedMDList.push_back(NMD);
+ insertNamedMDNode(NMD);
}
return NMD;
}
/// delete it.
void Module::eraseNamedMetadata(NamedMDNode *NMD) {
NamedMDSymTab.erase(NMD->getName());
- NamedMDList.erase(NMD->getIterator());
+ eraseNamedMDNode(NMD);
}
bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) {
EXPECT_EQ(M->ifunc_size(), 1u);
}
+TEST(ModuleTest, NamedMDList) {
+ // This tests all Module's functions that interact with Module::NamedMDList.
+ LLVMContext C;
+ SMDiagnostic Err;
+ LLVMContext Context;
+ auto M = std::make_unique<Module>("M", C);
+ NamedMDNode *MDN1 = M->getOrInsertNamedMetadata("MDN1");
+ EXPECT_EQ(M->named_metadata_size(), 1u);
+ NamedMDNode *MDN2 = M->getOrInsertNamedMetadata("MDN2");
+ EXPECT_EQ(M->named_metadata_size(), 2u);
+ auto *NewMDN = M->getOrInsertNamedMetadata("NewMDN");
+ EXPECT_EQ(M->named_metadata_size(), 3u);
+
+ M->removeNamedMDNode(NewMDN);
+ EXPECT_EQ(M->named_metadata_size(), 2u);
+
+ M->insertNamedMDNode(NewMDN);
+ EXPECT_EQ(&*std::prev(M->named_metadata().end()), NewMDN);
+
+ M->removeNamedMDNode(NewMDN);
+ M->insertNamedMDNode(NewMDN);
+ EXPECT_EQ(M->named_metadata_size(), 3u);
+ EXPECT_EQ(&*std::prev(M->named_metadata().end()), NewMDN);
+
+ auto Range = M->named_metadata();
+ EXPECT_EQ(&*Range.begin(), MDN1);
+ EXPECT_EQ(&*std::next(Range.begin(), 1), MDN2);
+ EXPECT_EQ(&*std::next(Range.begin(), 2), NewMDN);
+ EXPECT_EQ(std::next(Range.begin(), 3), Range.end());
+
+ M->eraseNamedMDNode(NewMDN);
+ EXPECT_EQ(M->named_metadata_size(), 2u);
+}
+
} // end namespace