[llvm-commits] [bug_122] CVS: llvm/include/llvm/SymbolTable.h

LLVM llvm at cs.uiuc.edu
Wed May 12 11:33:58 PDT 2004


Changes in directory llvm/include/llvm:

SymbolTable.h updated: 1.30 -> 1.30.6.1

---
Log message:

Change SymbolTable to not subclass from std::map but to embed one instead 
and cleanup use of SymbolTable in rest of LLVM. Also, add some new methods
to SymbolTable for small/utility cases and substitute calls to them in 
LLVM.


---
Diffs of the changes:  (+316 -74)

Index: llvm/include/llvm/SymbolTable.h
diff -u llvm/include/llvm/SymbolTable.h:1.30 llvm/include/llvm/SymbolTable.h:1.30.6.1
--- llvm/include/llvm/SymbolTable.h:1.30	Wed Dec 31 01:08:19 2003
+++ llvm/include/llvm/SymbolTable.h	Wed May 12 11:33:43 2004
@@ -7,16 +7,7 @@
 // 
 //===----------------------------------------------------------------------===//
 //
-// This file implements a symbol table that has planes broken up by type.  
-// Identical types may have overlapping symbol names as long as they are 
-// distinct.
-//
-// Note that this implements a chained symbol table.  If a name being 'lookup'd
-// isn't found in the current symbol table, then the parent symbol table is 
-// searched.
-//
-// This chaining behavior does NOT affect iterators though: only the lookup 
-// method.
+// This file implements the main symbol table for LLVM.
 //
 //===----------------------------------------------------------------------===//
 
@@ -28,112 +19,363 @@
 
 namespace llvm {
 
-class SymbolTable : public AbstractTypeUser,
-		    public std::map<const Type *, 
-                                    std::map<const std::string, Value *> > {
+/// This class provides a symbol table of name/value pairs that is broken
+/// up by type. Each Type* represents a "type plane" in the symbol table.
+/// Identical types may have overlapping symbol names as long as they are
+/// distinct. Note that this implements a chained symbol table. If a name
+/// being looked up (with lookup()) isn't found in the current symbol
+/// table, then the parent symbol table is searched. This chaining behavior
+/// does NOT affect iterators though: only the lookup method.
+///
+/// The SymbolTable provides several utility functions for answering common
+/// questions about its contents as well as an iterator interface for
+/// directly iterating over the contents.
+///
+class SymbolTable : public AbstractTypeUser {
+
+/// @name Types
+/// @{
 public:
-  typedef std::map<const std::string, Value *> VarMap;
-  typedef std::map<const Type *, VarMap> super;
 
-  typedef VarMap::iterator type_iterator;
-  typedef VarMap::const_iterator type_const_iterator;
+  /// @brief A mapping of names to values
+  typedef std::map<const std::string, Value *> ValueMap;
+
+  /// @brief A mapping of types to names to values
+  typedef std::map<const Type *, ValueMap> TypeMap;
+
+  /// @brief An iterator over the TypeMap
+  typedef TypeMap::iterator type_iterator;
+
+  /// @brief A const_iterator over the TypeMap
+  typedef TypeMap::const_iterator type_const_iterator;
+
+  /// @brief A iterator over a ValueMap
+  typedef ValueMap::iterator value_iterator;
+
+  /// @brief A const_iterator over a ValueMap
+  typedef ValueMap::const_iterator value_const_iterator;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
 
   inline SymbolTable() : InternallyInconsistent(false), LastUnique(0) {}
   ~SymbolTable();
 
-  // lookup - Returns null on failure...
+/// @}
+/// @name Accessors
+/// @{
+public:
+
+  /// This method finds the value with the given \p name in the
+  /// type plane \p Ty and returns it.
+  /// @returns null on failure, otherwise the Value associated with
+  /// the \p name in type plane \p Ty.
+  /// @brief Lookup a named, typed value.
   Value *lookup(const Type *Ty, const std::string &name) const;
 
-  // insert - Add named definition to the symbol table...
+  /// @brief Determine if there are types in the symbol table
+  bool hasTypes( void ) const; 
+
+  /// @brief Determine if the symbol table is empty
+  bool isEmpty( void ) const;
+
+  /// The type plane associated with the \p TypeID parameter is
+  /// found and the number of entries in the plane is returned.
+  /// @returns Number of entries in the specified type plane.
+  /// @brief Get the size of a type plane.
+  inline unsigned type_size(const Type *TypeID) const {
+    return map.find(TypeID)->second.size();
+  }
+
+  /// Finds the value \p val in the symbol table and returns its
+  /// name. Only the type plane associated with the type of \p val
+  /// is searched.
+  /// @brief Return the name of a value
+  std::string get_name( const Value* val ) const;
+
+  /// Given a base name, return a string that is either equal to it or 
+  /// derived from it that does not already occur in the symbol table 
+  /// for the specified type.
+  /// @brief Get a name unique to this symbol table
+  std::string getUniqueName(const Type *Ty, 
+    const std::string &BaseName) const;
+
+  /// @brief Debug method, print out symbol table
+  void dump() const;  
+
+/// @}
+/// @name Mutators
+/// @{
+public:
+
+  /// This method adds the provided value \p N to the symbol table. 
+  /// The Value must have both a name and a type which are extracted 
+  /// and used to place the value in the correct type plane under 
+  /// the value's name.
+  /// @brief Add a named value to the symbol table
   inline void insert(Value *N) {
     assert(N->hasName() && "Value must be named to go into symbol table!");
     insertEntry(N->getName(), N->getType(), N);
   }
 
-  void remove(Value *N);
-  Value *type_remove(const type_iterator &It) {
-    return removeEntry(find(It->second->getType()), It);
-  }
-
-  // insert - Insert a constant or type into the symbol table with the specified
-  // name...  There can be a many to one mapping between names and
-  // (constant/type)s.
-  //
+  /// Inserts a constant or type into the symbol table with the specified
+  /// name. There can be a many to one mapping between names and constants
+  /// or types.
+  /// @brief Insert a constant or type.
   inline void insert(const std::string &Name, Value *V) {
     assert((isa<Type>(V) || isa<Constant>(V)) &&
-	   "Can only insert types and constants here!");
+	   "Can only insert types and constants into a symbol table!");
     insertEntry(Name, V->getType(), V);
   }
 
-  /// remove - Remove a constant or type from the symbol table with the
-  /// specified name.
+  /// This method removes a named value from the symbol table. The
+  /// type and name of the Value are extracted from \N and used to
+  /// lookup the Value in the correct type plane. If the Value is
+  /// not in the symbol table, this method silently ignores the
+  /// request.
+  /// @brief Remove a named value from the symbol table.
+  void remove(Value *N);
+
+  /// Remove a constant or type with the specified name from the 
+  /// symbol table.
+  /// @returns the removed Value.
+  /// @breif Remove a constant or type from the symbol table.
   Value *remove(const std::string &Name, Value *V) {
-    iterator TI = find(V->getType());
+      TypeMap::iterator TI = map.find(V->getType());
     return removeEntry(TI, TI->second.find(Name));
   }
 
-  // getUniqueName - Given a base name, return a string that is either equal to
-  // it (or derived from it) that does not already occur in the symbol table for
-  // the specified type.
-  //
-  std::string getUniqueName(const Type *Ty, const std::string &BaseName);
+  /// @brief Strip the symbol table. This leaves the values without names.
+  bool strip( void );
 
-  inline unsigned type_size(const Type *TypeID) const {
-    return find(TypeID)->second.size();
+  /// @brief Empty the symbol table completely
+  void clear( void ) { map.clear(); }
+
+/// @}
+/// @name Iteration
+/// @{
+public:
+
+  inline type_iterator begin() { return map.begin(); }
+
+  inline type_const_iterator begin() const { return map.begin(); }
+
+  inline type_iterator end() { return map.end(); }
+
+  inline type_const_iterator end() const { return map.end(); }
+
+  /// Get an iterator that starts at the beginning of a type plane.
+  /// The iterator will iterate over the name/value pairs in the type plane.
+  /// @note The type plane must already exist before using this.
+  inline value_iterator type_begin(const Type *TypeID) { 
+    return map.find(TypeID)->second.begin(); 
   }
 
-  // Note that type_begin / type_end only work if you know that an element of 
-  // TypeID is already in the symbol table!!!
-  //
-  inline type_iterator type_begin(const Type *TypeID) { 
-    return find(TypeID)->second.begin(); 
+  /// Get a const_iterator that starts at the beginning of a type plane.
+  /// The iterator will iterate over the name/value pairs in the type plane.
+  /// @note The type plane must already exist before using this.
+  inline value_const_iterator type_begin(const Type *TypeID) const {
+    return map.find(TypeID)->second.begin(); 
   }
-  inline type_const_iterator type_begin(const Type *TypeID) const {
-    return find(TypeID)->second.begin(); 
+
+  /// Get an iterator to the end of a type plane. This serves as the marker
+  /// for end of iteration of the type plane.
+  /// @note The type plane must already exist before using this.
+  inline value_iterator type_end(const Type *TypeID) { 
+    return map.find(TypeID)->second.end(); 
   }
 
-  inline type_iterator type_end(const Type *TypeID) { 
-    return find(TypeID)->second.end(); 
+  /// Get a const_iterator to the end of a type plane. This serves as the
+  /// marker for end of iteration of the type plane.
+  /// @note The type plane must already exist before using this.
+  inline value_const_iterator type_end(const Type *TypeID) const { 
+    return map.find(TypeID)->second.end(); 
   }
-  inline type_const_iterator type_end(const Type *TypeID) const { 
-    return find(TypeID)->second.end(); 
+
+  /// This method returns a type_const_iterator for iteration over
+  /// the type planes.
+  /// @brief Find a type plane.
+  type_const_iterator find(const Type* Ty ) const {
+    return map.find( Ty );
   }
 
-  void dump() const;  // Debug method, print out symbol table
+  type_iterator find( const Type* Ty ) { return map.find(Ty); }
 
-private:
-  // InternallyInconsistent - There are times when the symbol table is
-  // internally inconsistent with the rest of the program.  In this one case, a
-  // value exists with a Name, and it's not in the symbol table.  When we call
-  // V->setName(""), it tries to remove itself from the symbol table and dies.
-  // We know this is happening, and so if the flag InternallyInconsistent is
-  // set, removal from the symbol table is a noop.
-  //
-  bool InternallyInconsistent;
+  /// @brief Find a Type Plane
+  const ValueMap* findPlane( const Type* Ty ) const {
+    type_const_iterator I = map.find( Ty );
+    if ( I == map.end() ) return 0;
+    return &I->second;
+  }
 
-  // LastUnique - This value is used to retain the last unique value used
-  // by getUniqueName to generate unique names.
-  unsigned long LastUnique;
-
-  inline super::value_type operator[](const Type *Ty) {
-    assert(0 && "Should not use this operator to access symbol table!");
-    return super::value_type();
+  /// @returns the removed value.
+  /// @brief Remove a specific value given by an iterator
+  Value *type_remove(const value_iterator &It) {
+    return this->removeEntry(map.find(It->second->getType()), It);
   }
 
-  // insertEntry - Insert a value into the symbol table with the specified
-  // name...
-  //
+/// @}
+/// @name Applicators
+/// @{
+public:
+  /// This function calls the functor doIt for each type in the Symbol
+  /// Table. The arguments to the functor are the name and type.
+  /// @brief Apply a functor to the types in the Symbol Table.
+  // template<typename FUNCTOR>
+  // void applyToTypes(FUNCTOR& doIt) const;
+
+  /// This function calls the functor doIt for each type in the Symbol
+  /// Table that has the specified name. If the functor returns true,
+  /// the search stops.
+  //template<typename FUNCTOR>
+  //void findTypeNamed( FUNCTOR& doIt, const std::string& Name) const;
+
+  /// This function calls the functor doIt for each value in the Symbol
+  /// Table. The arguments to the functor are the type, name and value.
+  //template<typename FUNCTOR>
+  //void apply( FUNCTOR& doIt ) const;
+
+  /// This function removes any Types for which the functor \p decide
+  /// returns true.
+  /// @returns the number of types removed
+  //template<typename FUNCTOR>
+  //unsigned removeMatchingTypes( FUNCTOR& decide );
+
+  /// This function replaces the named value of each entry in the
+  /// Type plane with value provided by the replace functor. The functor
+  /// should return the new Value* or null if no replacement should be
+  /// made.
+  /// @returns the number of replacements made.
+  //template<typename FUNCTOR>
+  //unsigned replaceTypes( FUNCTOR& replace );
+
+/// @}
+/// @name Internal Methods
+/// @{
+private:
+  /// Insert a value into the symbol table with the specified name.
   void insertEntry(const std::string &Name, const Type *Ty, Value *V);
 
-  // removeEntry - Remove a value from the symbol table...
-  //
-  Value *removeEntry(iterator Plane, type_iterator Entry);
+  /// Remove a value from the symbol table...
+  Value *removeEntry(TypeMap::iterator Plane, value_iterator Entry);
 
-  // This function is called when one of the types in the type plane are refined
+  /// This function is called when one of the types in the type plane 
+  /// is refined.
   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+
+  /// This function markes a type as being concrete (defined).
   virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+/// @}
+/// @name Internal Data 
+/// @{
+private:
+
+  /// This is the main content of the symbol table. It provides
+  /// separate type planes for named values. That is, each named
+  /// value is organized into a separate dictionary based on 
+  /// Type. This means that the same name can be used for different
+  /// types without conflict.
+  /// @brief The mapping of types to names to values.
+  TypeMap map;
+
+  /// There are times when the symbol table is internally inconsistent with 
+  /// the rest of the program.  In this one case, a value exists with a Name, 
+  /// and it's not in the symbol table.  When we call V->setName(""), it 
+  /// tries to remove itself from the symbol table and dies.  We know this 
+  /// is happening, and so if the flag InternallyInconsistent is set, 
+  /// removal from the symbol table is a noop.
+  /// @brief Indicator of symbol table internal inconsistency.
+  bool InternallyInconsistent;
+
+  /// This value is used to retain the last unique value used
+  /// by getUniqueName to generate unique names.
+  mutable unsigned long LastUnique;
+
+/// @}
+
 };
 
+/*
+template<typename FUNCTOR>
+void SymbolTable::applyToTypes( FUNCTOR& doIt ) const {
+  type_const_iterator TI = map.find(Type::TypeTy);
+  if (TI != map.end()) {
+    value_const_iterator VI = TI->second.begin();
+    for (; VI != TI->second.end(); ++VI) {
+      doIt( Type::TypeTy, VI->first, VI->second );
+    }
+  }
+}
+
+template<typename FUNCTOR>
+void SymbolTable::findTypeNamed( FUNCTOR& decide, 
+  const std::string& Name ) const {
+  type_const_iterator TI = map.begin();
+  type_const_iterator TE = map.end();
+  for ( ; TI != TE; ++TI ) {
+    if (TI->first != Type::TypeTy) {
+      const ValueMap& VM = TI->second;
+      // Does this type plane contain an entry with the specified name?
+      value_const_iterator VI = VM.find(Name);
+      if (VI != VM.end()) {
+	if ( decide( TI->first, VI->first, VI->second ) ) break;
+      }
+    }
+  }
+}
+  
+template<typename FUNCTOR>
+void SymbolTable::apply( FUNCTOR& doIt ) const {
+  for (type_const_iterator TI = map.begin(), TE = map.end(); 
+    TI != TE; ++TI) {
+    for (value_const_iterator VI = TI->second.begin(), 
+	   VE = TI->second.end(); VI != VE; ++VI) {
+      doIt( TI->first, VI->first, VI->second );
+    }
+  }
+}
+
+template<typename FUNCTOR>
+unsigned SymbolTable::removeMatchingTypes( FUNCTOR& decide ) {
+  unsigned result = 0;
+  type_iterator PI = map.find(Type::TypeTy);
+  if (PI != map.end()) {
+    ValueMap& Plane = PI->second;
+    for (value_iterator I=Plane.begin(); I != Plane.end(); ++I) {
+      if ( decide( PI->first, I->first, I->second ) )
+      {
+	Plane.erase( I++ );
+	result++;
+      }
+    }
+  }
+  return result;
+}
+
+template<typename FUNCTOR>
+unsigned SymbolTable::replaceTypes( FUNCTOR& replace ) {
+  unsigned result = 0;
+  type_iterator PI = map.find(Type::TypeTy);
+  if (PI != map.end()) {
+    ValueMap& Plane = PI->second;
+    for (value_iterator I=Plane.begin(), PE=Plane.end(); I != PE; ++I) {
+      Value* v = replace( PI->first, I->first, I->second );
+      if ( v ) {
+	I->second = v;
+	result++;
+	result++;
+      }
+    }
+  }
+  return result;
+}
+*/
+
 } // End llvm namespace
 
 #endif
+
+// vim: sw=2





More information about the llvm-commits mailing list