Keep track of named mdnodes in a Module using an ilist.
authorDevang Patel <dpatel@apple.com>
Wed, 29 Jul 2009 17:16:17 +0000 (17:16 +0000)
committerDevang Patel <dpatel@apple.com>
Wed, 29 Jul 2009 17:16:17 +0000 (17:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77476 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Metadata.h
include/llvm/Module.h
include/llvm/ValueSymbolTable.h
lib/VMCore/Metadata.cpp
lib/VMCore/Module.cpp
lib/VMCore/Value.cpp

index f341475afb50b00063fecdc2a02f7a8ef6724c60..54af723b92f8e27daa541cbf406344a1e872dbb1 100644 (file)
 
 #include "llvm/Value.h"
 #include "llvm/Type.h"
+#include "llvm/OperandTraits.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ilist_node.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ValueHandle.h"
 
@@ -173,7 +175,11 @@ public:
 //===----------------------------------------------------------------------===//
 /// NamedMDNode - a tuple of other metadata. 
 /// NamedMDNode is always named. All NamedMDNode element has a type of metadata.
-class NamedMDNode : public MetadataBase {
+template<typename ValueSubClass, typename ItemParentClass>
+  class SymbolTableListTraits;
+
+class NamedMDNode : public MetadataBase, public ilist_node<NamedMDNode> {
+  friend class SymbolTableListTraits<NamedMDNode, Module>;
   NamedMDNode(const NamedMDNode &);      // DO NOT IMPLEMENT
 
   friend class LLVMContextImpl;
@@ -201,6 +207,7 @@ public:
   /// getParent - Get the module that holds this named metadata collection.
   inline Module *getParent() { return Parent; }
   inline const Module *getParent() const { return Parent; }
+  void setParent(Module *M) { Parent = M; }
 
   Value *getElement(unsigned i) const {
     return Node[i];
index 913f8746ead54c6e51b87b0fc5331eff49b052f8..0f8722dc9d37ef210219824bd1518b26181b5b40 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/Function.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/GlobalAlias.h"
+#include "llvm/Metadata.h"
 #include "llvm/Support/DataTypes.h"
 #include <vector>
 
@@ -56,6 +57,21 @@ template<> struct ilist_traits<GlobalAlias>
   static GlobalAlias *createSentinel();
   static void destroySentinel(GlobalAlias *GA) { delete GA; }
 };
+template<> struct ilist_traits<NamedMDNode>
+  : public SymbolTableListTraits<NamedMDNode, Module> {
+  // createSentinel is used to get hold of a node that marks the end of
+  // the list...
+  NamedMDNode *createSentinel() const {
+    return static_cast<NamedMDNode*>(&Sentinel);
+  }
+  static void destroySentinel(NamedMDNode*) {}
+
+  NamedMDNode *provideInitialHead() const { return createSentinel(); }
+  NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); }
+  static void noteHead(NamedMDNode*, NamedMDNode*) {}
+private:
+  mutable ilist_node<NamedMDNode> Sentinel;
+};
 
 /// A Module instance is used to store all the information related to an
 /// LLVM module. Modules are the top level container of all other LLVM
@@ -78,25 +94,31 @@ public:
   typedef iplist<Function> FunctionListType;
   /// The type for the list of aliases.
   typedef iplist<GlobalAlias> AliasListType;
+  /// The type for the list of named metadata.
+  typedef iplist<NamedMDNode> NamedMDListType;
 
   /// The type for the list of dependent libraries.
   typedef std::vector<std::string> LibraryListType;
 
   /// The Global Variable iterator.
-  typedef GlobalListType::iterator                     global_iterator;
+  typedef GlobalListType::iterator                      global_iterator;
   /// The Global Variable constant iterator.
-  typedef GlobalListType::const_iterator         const_global_iterator;
+  typedef GlobalListType::const_iterator          const_global_iterator;
 
   /// The Function iterators.
-  typedef FunctionListType::iterator                          iterator;
+  typedef FunctionListType::iterator                           iterator;
   /// The Function constant iterator
-  typedef FunctionListType::const_iterator              const_iterator;
+  typedef FunctionListType::const_iterator               const_iterator;
 
   /// The Global Alias iterators.
-  typedef AliasListType::iterator                       alias_iterator;
+  typedef AliasListType::iterator                        alias_iterator;
   /// The Global Alias constant iterator
-  typedef AliasListType::const_iterator           const_alias_iterator;
+  typedef AliasListType::const_iterator            const_alias_iterator;
 
+  /// The named metadata iterators.
+  typedef NamedMDListType::iterator             named_metadata_iterator;
+  /// The named metadata constant interators.
+  typedef NamedMDListType::const_iterator const_named_metadata_iterator;
   /// The Library list iterator.
   typedef LibraryListType::const_iterator lib_iterator;
 
@@ -116,6 +138,7 @@ private:
   FunctionListType FunctionList; ///< The Functions in the module
   AliasListType AliasList;       ///< The Aliases in the module
   LibraryListType LibraryList;   ///< The Libraries needed by the module
+  NamedMDListType NamedMDList;   ///< The named metadata in the module
   std::string GlobalScopeAsm;    ///< Inline Asm at global scope.
   ValueSymbolTable *ValSymTab;   ///< Symbol table for values
   TypeSymbolTable *TypeSymTab;   ///< Symbol table for types
@@ -276,6 +299,15 @@ public:
   /// with the specified name is not found.
   GlobalAlias *getNamedAlias(const StringRef &Name) const;
 
+/// @}
+/// @name Named Metadata Accessors
+/// @{
+public:
+  /// getNamedMetadata - Return the first named MDNode in the module with the
+  /// specified name. This method returns null if a MDNode with the specified
+  /// name is not found.
+  NamedMDNode *getNamedMetadata(const StringRef &Name) const;
+
 /// @}
 /// @name Type Accessors
 /// @{
@@ -318,6 +350,13 @@ public:
   static iplist<GlobalAlias> Module::*getSublistAccess(GlobalAlias*) {
     return &Module::AliasList;
   }
+  /// Get the Module's list of named metadata (constant).
+  const NamedMDListType  &getNamedMDList() const      { return NamedMDList; }
+  /// Get the Module's list of named metadata.
+  NamedMDListType  &getNamedMDList()                  { return NamedMDList; }
+  static iplist<NamedMDNode> Module::*getSublistAccess(NamedMDNode *) {
+    return &Module::NamedMDList;
+  }
   /// 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.
@@ -393,6 +432,31 @@ public:
   /// Determine if the list of aliases is empty.
   bool                 alias_empty() const      { return AliasList.empty(); }
 
+
+/// @}
+/// @name Named Metadata Iteration
+/// @{
+public:
+  /// Get an iterator to the first named metadata.
+  named_metadata_iterator       named_metadata_begin()            
+                                                { return NamedMDList.begin(); }
+  /// Get a constant iterator to the first named metadata.
+  const_named_metadata_iterator named_metadata_begin() const      
+                                                { return NamedMDList.begin(); }
+  /// Get an iterator to the last named metadata.
+  named_metadata_iterator       named_metadata_end  ()            
+                                                { return NamedMDList.end();   }
+  /// Get a constant iterator to the last named metadata.
+  const_named_metadata_iterator named_metadata_end  () const      
+                                                { return NamedMDList.end();   }
+  /// Determine how many NamedMDNodes are in the Module's list of named metadata.
+  size_t                        named_metadata_size () const      
+                                                { return NamedMDList.size();  }
+  /// Determine if the list of named metadata is empty.
+  bool                          named_metadata_empty() const      
+                                                { return NamedMDList.empty(); }
+
+
 /// @}
 /// @name Utility functions for printing and dumping Module objects
 /// @{
index c9dc82bac9a4dec6a37ce67dfc7ef0e22db935cb..4f8ebe800172a1b30a879753eef10f36170b8d79 100644 (file)
@@ -23,6 +23,7 @@ namespace llvm {
         class SymbolTableListTraits;
   class BasicBlock;
   class Function;
+  class NamedMDNode;
   class Module;
   class StringRef;
   
@@ -38,6 +39,7 @@ class ValueSymbolTable {
   friend class SymbolTableListTraits<Function, Module>;
   friend class SymbolTableListTraits<GlobalVariable, Module>;
   friend class SymbolTableListTraits<GlobalAlias, Module>;
+  friend class SymbolTableListTraits<NamedMDNode, Module>;
 /// @name Types
 /// @{
 public:
index 73f89caa388ef20021bbcfd264a1362d2301b925..2f6c153a9d7667adcd06ee647825f5421fe2533f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "llvm/Metadata.h"
 #include "llvm/Module.h"
+#include "SymbolTableListTraitsImpl.h"
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -36,9 +37,11 @@ NamedMDNode::NamedMDNode(const char *N, unsigned NameLength,
                          MetadataBase*const* MDs, unsigned NumMDs,
                          Module *M)
   : MetadataBase(Type::MetadataTy, Value::NamedMDNodeVal),
-    Parent(M), Name(N, NameLength) {
+    Name(N, NameLength) {
+  setName(N);
   for (unsigned i = 0; i != NumMDs; ++i)
     Node.push_back(WeakMetadataVH(MDs[i]));
 
-  // FIXME : Add into the parent module.
+  if (M)
+    M->getNamedMDList().push_back(this);
 }
index 35db8d25b5bf598cfa933f5de267d1ad784054c8..c9d599eb953e24a39157c6576602bcca38c7a745 100644 (file)
@@ -67,6 +67,7 @@ Module::~Module() {
   FunctionList.clear();
   AliasList.clear();
   LibraryList.clear();
+  NamedMDList.clear();
   delete ValSymTab;
   delete TypeSymTab;
 }
@@ -288,6 +289,13 @@ GlobalAlias *Module::getNamedAlias(const StringRef &Name) const {
   return dyn_cast_or_null<GlobalAlias>(getNamedValue(Name));
 }
 
+/// getNamedMetadata - Return the first named MDNode in the module with the
+/// specified name. This method returns null if a MDNode with the specified
+/// name is not found.
+NamedMDNode *Module::getNamedMetadata(const StringRef &Name) const {
+  return dyn_cast_or_null<NamedMDNode>(getNamedValue(Name));
+}
+
 //===----------------------------------------------------------------------===//
 // Methods for easy access to the types in the module.
 //
index af13973e8309b808aa76028977479695ea0fd34e..2cdd55217cc4133c1af6495513b7c0073e4db3aa 100644 (file)
@@ -142,6 +142,10 @@ static bool getSymTab(Value *V, ValueSymbolTable *&ST) {
   } else if (Argument *A = dyn_cast<Argument>(V)) {
     if (Function *P = A->getParent()) 
       ST = &P->getValueSymbolTable();
+  } else if (NamedMDNode *N = dyn_cast<NamedMDNode>(V)) {
+    if (Module *P = N->getParent()) {
+      ST = &P->getValueSymbolTable();
+    }
   } else if (isa<MDString>(V))
     return true;
   else {