Add a new method
authorChris Lattner <sabre@nondot.org>
Sun, 5 Dec 2004 06:43:27 +0000 (06:43 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 5 Dec 2004 06:43:27 +0000 (06:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18531 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Function.h
lib/VMCore/Function.cpp

index e67ef01a56b3bde3fe290f6de6a1c8510413789d..a540ee3f7438df48f0b312b38aa45ab102466f56 100644 (file)
@@ -106,6 +106,13 @@ public:
   unsigned getIntrinsicID() const;
   bool isIntrinsic() const { return getIntrinsicID() != 0; }
 
+  /// renameLocalSymbols - This method goes through the Function's symbol table
+  /// and renames any symbols that conflict with symbols at global scope.  This
+  /// is required before printing out to a textual form, to ensure that there is
+  /// no ambiguity when parsing.
+  void renameLocalSymbols();
+
+
   /// deleteBody - This method deletes the body of the function, and converts
   /// the linkage to external.
   ///
index 46cb4c23d43651ac57f0dc2921679d2abb0d5ce2..a35a55b4bb41cf35df5d49c2ff6c8b3e6c2c7c31 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/IntrinsicInst.h"
 #include "llvm/Support/LeakDetector.h"
 #include "SymbolTableListTraitsImpl.h"
+#include "llvm/ADT/StringExtras.h"
 using namespace llvm;
 
 BasicBlock *ilist_traits<BasicBlock>::createNode() {
@@ -153,6 +154,46 @@ void Function::eraseFromParent() {
   getParent()->getFunctionList().erase(this);
 }
 
+
+/// renameLocalSymbols - This method goes through the Function's symbol table
+/// and renames any symbols that conflict with symbols at global scope.  This is
+/// required before printing out to a textual form, to ensure that there is no
+/// ambiguity when parsing.
+void Function::renameLocalSymbols() {
+  SymbolTable &LST = getSymbolTable();                 // Local Symtab
+  SymbolTable &GST = getParent()->getSymbolTable();    // Global Symtab
+
+  for (SymbolTable::plane_iterator LPI = LST.plane_begin(), E = LST.plane_end();
+       LPI != E; ++LPI)
+    // All global symbols are of pointer type, ignore any non-pointer planes.
+    if (isa<PointerType>(LPI->first)) {
+      // Only check if the global plane has any symbols of this type.
+      SymbolTable::plane_iterator GPI = GST.find(LPI->first);
+      if (GPI != GST.plane_end()) {
+        SymbolTable::ValueMap &LVM       = LPI->second;
+        const SymbolTable::ValueMap &GVM = GPI->second;
+
+        // Loop over all local symbols, renaming those that are in the global
+        // symbol table already.
+        for (SymbolTable::value_iterator VI = LVM.begin(), E = LVM.end();
+             VI != E;) {
+          Value *V                = VI->second;
+          const std::string &Name = VI->first;
+          ++VI;
+          if (GVM.count(Name)) {
+            static unsigned UniqueNum = 0;
+            // Find a name that does not conflict!
+            while (GVM.count(Name + "_" + utostr(++UniqueNum)) ||
+                   LVM.count(Name + "_" + utostr(UniqueNum)))
+              /* scan for UniqueNum that works */;
+            V->setName(Name + "_" + utostr(UniqueNum));
+          }
+        }
+      }
+    }
+}
+
+
 // dropAllReferences() - This function causes all the subinstructions to "let
 // go" of all references that they are maintaining.  This allows one to
 // 'delete' a whole class at a time, even though there may be circular