[llvm-commits] CVS: llvm/tools/llvm-upgrade/UpgradeInternals.h UpgradeLexer.l UpgradeParser.y ParserInternals.h

Reid Spencer reid at x10sys.com
Fri Jan 5 09:19:13 PST 2007



Changes in directory llvm/tools/llvm-upgrade:

UpgradeInternals.h added (r1.1)
UpgradeLexer.l updated: 1.12 -> 1.13
UpgradeParser.y updated: 1.32 -> 1.33
ParserInternals.h (r1.12) removed
---
Log message:

Major update of llvm-upgrade:
1. Completely revise the type system so that types are handled as const
   objects and not created multiple times, cloned, or otherwise copied.
   This gets around memory issues, saves memory, and also emulates LLVM's
   no-two-types-of-the-same-shape-created semantics.
2. Adjust the handling of global names. Basically, we cannot rename them
   for a variety of reasons: linking, forward references, etc. 
3. Detect global names that have name conflicts as the result of collapsed
   type planes or redefinitions that llvm-as no longer accepts. These will
   produce warnings on stderr and one of the globals will be renamed.
4. Rename ParserInternals.h as UpgradeInternals.h so it doesn't conflict
   in the debugger with ParserInternals.h from lib/AsmParser.
5. Move the guts of the TypeInfo class into the grammar so we aren't 
   implementing large functions in a header file. This also helps with
   debugging a bit.


---
Diffs of the changes:  (+683 -120)

 UpgradeInternals.h |  210 ++++++++++++++++++
 UpgradeLexer.l     |    4 
 UpgradeParser.y    |  589 ++++++++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 683 insertions(+), 120 deletions(-)


Index: llvm/tools/llvm-upgrade/UpgradeInternals.h
diff -c /dev/null llvm/tools/llvm-upgrade/UpgradeInternals.h:1.1
*** /dev/null	Fri Jan  5 11:19:08 2007
--- llvm/tools/llvm-upgrade/UpgradeInternals.h	Fri Jan  5 11:18:58 2007
***************
*** 0 ****
--- 1,210 ----
+ //===-- UpgradeInternals.h - Internal parser definitionsr -------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Reid Spencer and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ //  This header file defines the variables that are shared between the lexer,
+ //  the parser, and the main program.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef UPGRADE_INTERNALS_H
+ #define UPGRADE_INTERNALS_H
+ 
+ #include <llvm/ADT/StringExtras.h>
+ #include <string>
+ #include <istream>
+ #include <vector>
+ #include <set>
+ #include <cassert>
+ 
+ // Global variables exported from the lexer...
+ 
+ extern std::string CurFileName;
+ extern std::string Textin;
+ extern int Upgradelineno;
+ extern std::istream* LexInput;
+ 
+ struct TypeInfo;
+ typedef std::vector<const TypeInfo*> TypeList;
+ 
+ void UpgradeAssembly(
+   const std::string & infile, std::istream& in, std::ostream &out, bool debug,
+   bool addAttrs);
+ 
+ // Globals exported by the parser...
+ extern char* Upgradetext;
+ extern int   Upgradeleng;
+ extern unsigned SizeOfPointer;
+ 
+ int yyerror(const char *ErrorMsg) ;
+ 
+ /// This enum is used to keep track of the original (1.9) type used to form
+ /// a type. These are needed for type upgrades and to determine how to upgrade
+ /// signed instructions with signless operands.
+ enum Types {
+   BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy,
+   FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, PackedStructTy, 
+   OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, UpRefTy
+ };
+ 
+ /// This type is used to keep track of the signedness of values. Instead
+ /// of creating llvm::Value directly, the parser will create ValueInfo which
+ /// associates a Value* with a Signedness indication.
+ struct ValueInfo {
+   std::string* val;
+   const TypeInfo* type;
+   bool constant;
+   bool isConstant() const { return constant; }
+   inline void destroy();
+ };
+ 
+ /// This type is used to keep track of the signedness of the obsolete
+ /// integer types. Instead of creating an llvm::Type directly, the Lexer will
+ /// create instances of TypeInfo which retains the signedness indication so
+ /// it can be used by the parser for upgrade decisions.
+ /// For example if "uint" is encountered then the "first" field will be set 
+ /// to "int32" and the "second" field will be set to "isUnsigned".  If the 
+ /// type is not obsolete then "second" will be set to "isSignless".
+ struct TypeInfo {
+ 
+   static const TypeInfo* get(const std::string &newType, Types oldType);
+   static const TypeInfo* get(const std::string& newType, Types oldType, 
+                              const TypeInfo* eTy, const TypeInfo* rTy);
+ 
+   static const TypeInfo* get(const std::string& newType, Types oldType, 
+                        const TypeInfo *eTy, uint64_t elems);
+ 
+   static const TypeInfo* get(const std::string& newType, Types oldType, 
+                        TypeList* TL);
+ 
+   static const TypeInfo* get(const std::string& newType, const TypeInfo* resTy, 
+                        TypeList* TL);
+ 
+   const TypeInfo* resolve() const;
+   bool operator<(const TypeInfo& that) const;
+ 
+   bool sameNewTyAs(const TypeInfo* that) const {
+     return this->newTy == that->newTy;
+   }
+ 
+   bool sameOldTyAs(const TypeInfo* that) const;
+ 
+   Types getElementTy() const {
+     if (elemTy) {
+       return elemTy->oldTy;
+     }
+     return UnresolvedTy;
+   }
+ 
+   unsigned getUpRefNum() const {
+     assert(oldTy == UpRefTy && "Can't getUpRefNum on non upreference");
+     return atoi(&((getNewTy().c_str())[1])); // skip the slash
+   }
+ 
+   const std::string& getNewTy() const { return newTy; }
+   const TypeInfo* getResultType() const { return resultTy; }
+   const TypeInfo* getElementType() const { return elemTy; }
+ 
+   const TypeInfo* getPointerType() const {
+     return get(newTy + "*", PointerTy, this, (TypeInfo*)0);
+   }
+ 
+   bool isUnresolved() const { return oldTy == UnresolvedTy; }
+   bool isUpReference() const { return oldTy == UpRefTy; }
+   bool isVoid() const { return oldTy == VoidTy; }
+   bool isBool() const { return oldTy == BoolTy; }
+   bool isSigned() const {
+     return oldTy == SByteTy || oldTy == ShortTy || 
+            oldTy == IntTy || oldTy == LongTy;
+   }
+ 
+   bool isUnsigned() const {
+     return oldTy == UByteTy || oldTy == UShortTy || 
+            oldTy == UIntTy || oldTy == ULongTy;
+   }
+   bool isSignless() const { return !isSigned() && !isUnsigned(); }
+   bool isInteger() const { return isSigned() || isUnsigned(); }
+   bool isIntegral() const { return oldTy == BoolTy || isInteger(); }
+   bool isFloatingPoint() const { return oldTy == DoubleTy || oldTy == FloatTy; }
+   bool isPacked() const { return oldTy == PackedTy; }
+   bool isPointer() const { return oldTy == PointerTy; }
+   bool isStruct() const { return oldTy == StructTy || oldTy == PackedStructTy; }
+   bool isArray() const { return oldTy == ArrayTy; }
+   bool isOther() const { 
+     return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); }
+   bool isFunction() const { return oldTy == FunctionTy; }
+   bool isComposite() const {
+     return isStruct() || isPointer() || isArray() || isPacked();
+   }
+ 
+   bool isAttributeCandidate() const {
+     return isIntegral() && getBitWidth() < 32;
+   }
+ 
+   bool isUnresolvedDeep() const;
+ 
+   unsigned getBitWidth() const;
+ 
+   const TypeInfo* getIndexedType(const ValueInfo&  VI) const;
+ 
+   unsigned getNumStructElements() const { 
+     return (elements ? elements->size() : 0);
+   }
+ 
+   const TypeInfo* getElement(unsigned idx) const {
+     if (elements)
+       if (idx < elements->size())
+         return (*elements)[idx];
+     return 0;
+   }
+ 
+ 
+ private:
+   TypeInfo() 
+     : newTy(), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0),
+       nelems(0) {
+   }
+ 
+   TypeInfo(const TypeInfo& that); // do not implement
+   TypeInfo& operator=(const TypeInfo& that); // do not implement
+ 
+   ~TypeInfo() { delete elements; }
+ 
+   struct ltfunctor
+   {
+     bool operator()(const TypeInfo* X, const TypeInfo* Y) const {
+       assert(X && "Can't compare null pointer");
+       assert(Y && "Can't compare null pointer");
+       return *X < *Y;
+     }
+   };
+ 
+   typedef std::set<const TypeInfo*, ltfunctor> TypeRegMap;
+   static const TypeInfo* add_new_type(TypeInfo* existing);
+ 
+   std::string newTy;
+   Types oldTy;
+   TypeInfo *elemTy;
+   TypeInfo *resultTy;
+   TypeList *elements;
+   uint64_t nelems;
+   static TypeRegMap registry;
+ };
+ 
+ /// This type is used to keep track of the signedness of constants.
+ struct ConstInfo {
+   std::string *cnst;
+   const TypeInfo *type;
+   void destroy() { delete cnst; }
+ };
+ 
+ typedef std::vector<ValueInfo> ValueList;
+ 
+ inline void ValueInfo::destroy() { delete val; }
+ 
+ #endif


Index: llvm/tools/llvm-upgrade/UpgradeLexer.l
diff -u llvm/tools/llvm-upgrade/UpgradeLexer.l:1.12 llvm/tools/llvm-upgrade/UpgradeLexer.l:1.13
--- llvm/tools/llvm-upgrade/UpgradeLexer.l:1.12	Mon Jan  1 23:44:33 2007
+++ llvm/tools/llvm-upgrade/UpgradeLexer.l	Fri Jan  5 11:18:58 2007
@@ -26,7 +26,7 @@
 
 %{
 
-#include "ParserInternals.h"
+#include "UpgradeInternals.h"
 #include "UpgradeParser.h"
 #include <cctype>
 #include <cstdlib>
@@ -48,7 +48,7 @@
   return sym
 
 #define RET_TY(sym,OldTY,NewTY,sign) \
-  Upgradelval.Type = new TypeInfo(NewTY, OldTY); \
+  Upgradelval.Type = TypeInfo::get(NewTY, OldTY); \
   return sym
 
 #define YY_NEVER_INTERACTIVE 1


Index: llvm/tools/llvm-upgrade/UpgradeParser.y
diff -u llvm/tools/llvm-upgrade/UpgradeParser.y:1.32 llvm/tools/llvm-upgrade/UpgradeParser.y:1.33
--- llvm/tools/llvm-upgrade/UpgradeParser.y:1.32	Thu Jan  4 12:45:51 2007
+++ llvm/tools/llvm-upgrade/UpgradeParser.y	Fri Jan  5 11:18:58 2007
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 %{
-#include "ParserInternals.h"
+#include "UpgradeInternals.h"
 #include <algorithm>
 #include <map>
 #include <utility>
@@ -45,11 +45,15 @@
 static bool deleteUselessCastFlag = false;
 static std::string* deleteUselessCastName = 0;
 
-typedef std::vector<TypeInfo> TypeVector;
+typedef std::vector<const TypeInfo*> TypeVector;
 static TypeVector EnumeratedTypes;
-typedef std::map<std::string,TypeInfo> TypeMap;
+typedef std::map<std::string,const TypeInfo*> TypeMap;
 static TypeMap NamedTypes;
-static TypeMap Globals;
+typedef std::map<const TypeInfo*,std::string> TypePlaneMap;
+typedef std::map<std::string,TypePlaneMap> GlobalsTypeMap;
+static GlobalsTypeMap Globals;
+
+static void warning(const std::string& msg);
 
 void destroy(ValueList* VL) {
   while (!VL->empty()) {
@@ -77,32 +81,261 @@
   }
 }
 
-TypeInfo* ResolveType(TypeInfo*& Ty) {
-  if (Ty->isUnresolved()) {
-    if (Ty->getNewTy()[0] == '%' && isdigit(Ty->getNewTy()[1])) {
-      unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the %
+TypeInfo::TypeRegMap TypeInfo::registry;
+
+const TypeInfo* TypeInfo::get(const std::string &newType, Types oldType) {
+  TypeInfo* Ty = new TypeInfo();
+  Ty->newTy = newType;
+  Ty->oldTy = oldType;
+  return add_new_type(Ty);
+}
+
+const TypeInfo* TypeInfo::get(const std::string& newType, Types oldType, 
+                              const TypeInfo* eTy, const TypeInfo* rTy) {
+  TypeInfo* Ty= new TypeInfo();
+  Ty->newTy = newType;
+  Ty->oldTy = oldType;
+  Ty->elemTy = const_cast<TypeInfo*>(eTy);
+  Ty->resultTy = const_cast<TypeInfo*>(rTy);
+  return add_new_type(Ty);
+}
+
+const TypeInfo* TypeInfo::get(const std::string& newType, Types oldType, 
+                              const TypeInfo *eTy, uint64_t elems) {
+  TypeInfo* Ty = new TypeInfo();
+  Ty->newTy = newType;
+  Ty->oldTy = oldType;
+  Ty->elemTy = const_cast<TypeInfo*>(eTy);
+  Ty->nelems = elems;
+  return  add_new_type(Ty);
+}
+
+const TypeInfo* TypeInfo::get(const std::string& newType, Types oldType, 
+                              TypeList* TL) {
+  TypeInfo* Ty = new TypeInfo();
+  Ty->newTy = newType;
+  Ty->oldTy = oldType;
+  Ty->elements = TL;
+  return add_new_type(Ty);
+}
+
+const TypeInfo* TypeInfo::get(const std::string& newType, const TypeInfo* resTy,
+                              TypeList* TL) {
+  TypeInfo* Ty = new TypeInfo();
+  Ty->newTy = newType;
+  Ty->oldTy = FunctionTy;
+  Ty->resultTy = const_cast<TypeInfo*>(resTy);
+  Ty->elements = TL;
+  return add_new_type(Ty);
+}
+
+const TypeInfo* TypeInfo::resolve() const {
+  if (isUnresolved()) {
+    if (getNewTy()[0] == '%' && isdigit(getNewTy()[1])) {
+      unsigned ref = atoi(&((getNewTy().c_str())[1])); // skip the %
       if (ref < EnumeratedTypes.size()) {
-        Ty = &EnumeratedTypes[ref];
-        return Ty;
+        return EnumeratedTypes[ref];
       } else {
         std::string msg("Can't resolve numbered type: ");
-        msg += Ty->getNewTy();
+        msg += getNewTy();
         yyerror(msg.c_str());
       }
     } else {
-      TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
+      TypeMap::iterator I = NamedTypes.find(getNewTy());
       if (I != NamedTypes.end()) {
-        Ty = &I->second;
-        return Ty;
+        return I->second;
       } else {
         std::string msg("Cannot resolve type: ");
-        msg += Ty->getNewTy();
+        msg += getNewTy();
         yyerror(msg.c_str());
       }
     }
   }
   // otherwise its already resolved.
-  return Ty;
+  return this;
+}
+
+bool TypeInfo::operator<(const TypeInfo& that) const {
+  if (this == &that)
+    return false;
+  if (oldTy != that.oldTy)
+    return oldTy < that.oldTy;
+  switch (oldTy) {
+    case UpRefTy: {
+      unsigned thisUp = this->getUpRefNum();
+      unsigned thatUp = that.getUpRefNum();
+      return thisUp < thatUp;
+    }
+    case PackedTy:
+    case ArrayTy:
+      if (this->nelems != that.nelems)
+        return nelems < that.nelems;
+    case PointerTy: {
+      const TypeInfo* thisTy = this->elemTy;
+      const TypeInfo* thatTy = that.elemTy;
+      return *thisTy < *thatTy;
+    }
+    case FunctionTy: {
+      const TypeInfo* thisTy = this->resultTy;
+      const TypeInfo* thatTy = that.resultTy;
+      if (!thisTy->sameOldTyAs(thatTy))
+        return *thisTy < *thatTy;
+      /* FALL THROUGH */
+    }
+    case StructTy:
+    case PackedStructTy: {
+      if (elements->size() != that.elements->size())
+        return elements->size() < that.elements->size();
+      for (unsigned i = 0; i < elements->size(); i++) {
+        const TypeInfo* thisTy = (*this->elements)[i];
+        const TypeInfo* thatTy = (*that.elements)[i];
+        if (!thisTy->sameOldTyAs(thatTy))
+          return *thisTy < *thatTy;
+      }
+      break;
+    }
+    case UnresolvedTy:
+      return this->newTy < that.newTy;
+    default:
+      break;
+  }
+  return false; 
+}
+
+bool TypeInfo::sameOldTyAs(const TypeInfo* that) const {
+  if (that == 0)
+    return false;
+  if ( this == that ) 
+    return true;
+  if (oldTy != that->oldTy)
+    return false;
+  switch (oldTy) {
+    case PackedTy:
+    case ArrayTy:
+      if (nelems != that->nelems)
+        return false;
+      /* FALL THROUGH */
+    case PointerTy: {
+      const TypeInfo* thisTy = this->elemTy;
+      const TypeInfo* thatTy = that->elemTy;
+      return thisTy->sameOldTyAs(thatTy);
+    }
+    case FunctionTy: {
+      const TypeInfo* thisTy = this->resultTy;
+      const TypeInfo* thatTy = that->resultTy;
+      if (!thisTy->sameOldTyAs(thatTy))
+        return false;
+      /* FALL THROUGH */
+    }
+    case StructTy:
+    case PackedStructTy: {
+      if (elements->size() != that->elements->size())
+        return false;
+      for (unsigned i = 0; i < elements->size(); i++) {
+        const TypeInfo* thisTy = (*this->elements)[i];
+        const TypeInfo* thatTy = (*that->elements)[i];
+        if (!thisTy->sameOldTyAs(thatTy))
+          return false;
+      }
+      return true;
+    }
+    case UnresolvedTy:
+      return this->newTy == that->newTy;
+    default:
+      return true; // for all others oldTy == that->oldTy is sufficient
+  }
+  return true;
+}
+
+bool TypeInfo::isUnresolvedDeep() const {
+  switch (oldTy) {
+    case UnresolvedTy: 
+      return true;
+    case PackedTy:
+    case ArrayTy:
+    case PointerTy:
+      return elemTy->isUnresolvedDeep();
+    case PackedStructTy:
+    case StructTy:
+      for (unsigned i = 0; i < elements->size(); i++)
+        if ((*elements)[i]->isUnresolvedDeep())
+          return true;
+      return false;
+    default:
+      return false;
+  }
+}
+
+unsigned TypeInfo::getBitWidth() const {
+  switch (oldTy) {
+    default:
+    case LabelTy:
+    case VoidTy : return 0;
+    case BoolTy : return 1;
+    case SByteTy: case UByteTy : return 8;
+    case ShortTy: case UShortTy : return 16;
+    case IntTy: case UIntTy: case FloatTy: return 32;
+    case LongTy: case ULongTy: case DoubleTy : return 64;
+    case PointerTy: return SizeOfPointer; // global var
+    case PackedTy: 
+    case ArrayTy: 
+      return nelems * elemTy->getBitWidth();
+    case StructTy:
+    case PackedStructTy: {
+      uint64_t size = 0;
+      for (unsigned i = 0; i < elements->size(); i++) {
+        size += (*elements)[i]->getBitWidth();
+      }
+      return size;
+    }
+  }
+}
+
+const TypeInfo* TypeInfo::getIndexedType(const ValueInfo&  VI) const {
+  if (isStruct()) {
+    if (VI.isConstant() && VI.type->isInteger()) {
+      size_t pos = VI.val->find(' ') + 1;
+      if (pos < VI.val->size()) {
+        uint64_t idx = atoi(VI.val->substr(pos).c_str());
+        return (*elements)[idx];
+      } else {
+        yyerror("Invalid value for constant integer");
+        return 0;
+      }
+    } else {
+      yyerror("Structure requires constant index");
+      return 0;
+    }
+  }
+  if (isArray() || isPacked() || isPointer())
+    return elemTy;
+  yyerror("Invalid type for getIndexedType");
+  return 0;
+}
+
+TypeInfo& TypeInfo::operator=(const TypeInfo& that) {
+  oldTy = that.oldTy;
+  nelems = that.nelems;
+  newTy = that.newTy;
+  elemTy = that.elemTy;
+  resultTy = that.resultTy;
+  if (that.elements) {
+    elements = new TypeList(that.elements->size());
+    *elements = *that.elements;
+  } else {
+    elements = 0;
+  }
+  return *this;
+}
+
+const TypeInfo* TypeInfo::add_new_type(TypeInfo* newTy) {
+  TypeRegMap::iterator I = registry.find(newTy);
+  if (I != registry.end()) {
+    delete newTy;
+    return *I;
+  }
+  registry.insert(newTy);
+  return newTy;
 }
 
 static const char* getCastOpcode(
@@ -183,8 +416,8 @@
   return opcode;
 }
 
-static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy,
-                                  TypeInfo* DstTy, bool isConst)
+static std::string getCastUpgrade(const std::string& Src, const TypeInfo* SrcTy,
+                                  const TypeInfo* DstTy, bool isConst)
 {
   std::string Result;
   std::string Source = Src;
@@ -199,8 +432,7 @@
       Source = "i64 %cast_upgrade" + llvm::utostr(unique);
     }
     // Update the SrcTy for the getCastOpcode call below
-    delete SrcTy;
-    SrcTy = new TypeInfo("i64", ULongTy);
+    SrcTy = TypeInfo::get("i64", ULongTy);
   } else if (DstTy->isBool()) {
     // cast type %x to bool was previously defined as setne type %x, null
     // The cast semantic is now to truncate, not compare so we must retain
@@ -216,8 +448,8 @@
       Result = compareOp + Source + comparator;
     return Result; // skip cast processing below
   }
-  ResolveType(SrcTy);
-  ResolveType(DstTy);
+  SrcTy = SrcTy->resolve();
+  DstTy = DstTy->resolve();
   std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
   if (isConst)
     Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")";
@@ -226,9 +458,9 @@
   return Result;
 }
 
-const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) {
+const char* getDivRemOpcode(const std::string& opcode, const TypeInfo* TI) {
   const char* op = opcode.c_str();
-  const TypeInfo* Ty = ResolveType(TI);
+  const TypeInfo* Ty = TI->resolve();
   if (Ty->isPacked())
     Ty = Ty->getElementType();
   if (opcode == "div")
@@ -283,35 +515,36 @@
   return result;
 }
 
-static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) {
-  ResolveType(PFTy);
+static const TypeInfo* getFunctionReturnType(const TypeInfo* PFTy) {
+  PFTy = PFTy->resolve();
   if (PFTy->isPointer()) {
-    TypeInfo* ElemTy = PFTy->getElementType();
-    ResolveType(ElemTy);
+    const TypeInfo* ElemTy = PFTy->getElementType();
+    ElemTy = ElemTy->resolve();
     if (ElemTy->isFunction())
-      return ElemTy->getResultType()->clone();
+      return ElemTy->getResultType();
   } else if (PFTy->isFunction()) {
-    return PFTy->getResultType()->clone();
+    return PFTy->getResultType();
   }
-  return PFTy->clone();
+  return PFTy;
 }
 
-typedef std::vector<TypeInfo*> UpRefStack;
-static TypeInfo* ResolveUpReference(TypeInfo* Ty, UpRefStack* stack) {
+typedef std::vector<const TypeInfo*> UpRefStack;
+static const TypeInfo* ResolveUpReference(const TypeInfo* Ty, 
+                                          UpRefStack* stack) {
   assert(Ty->isUpReference() && "Can't resolve a non-upreference");
-  unsigned upref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the slash
+  unsigned upref = Ty->getUpRefNum();
   assert(upref < stack->size() && "Invalid up reference");
   return (*stack)[upref - stack->size() - 1];
 }
 
-static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) {
-  TypeInfo* Result = ResolveType(PTy);
+static const TypeInfo* getGEPIndexedType(const TypeInfo* PTy, ValueList* idxs) {
+  const TypeInfo* Result = PTy = PTy->resolve();
   assert(PTy->isPointer() && "GEP Operand is not a pointer?");
   UpRefStack stack;
   for (unsigned i = 0; i < idxs->size(); ++i) {
     if (Result->isComposite()) {
       Result = Result->getIndexedType((*idxs)[i]);
-      ResolveType(Result);
+      Result = Result->resolve();
       stack.push_back(Result);
     } else
       yyerror("Invalid type for index");
@@ -344,25 +577,47 @@
 // were previously unsigned or signed, respectively. This avoids name
 // collisions since the unsigned and signed type planes have collapsed
 // into a single signless type plane.
-static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) {
+static std::string getUniqueName(const std::string *Name, const TypeInfo* Ty,
+                                 bool isGlobal = false) {
+
   // If its not a symbolic name, don't modify it, probably a constant val.
   if ((*Name)[0] != '%' && (*Name)[0] != '"')
     return *Name;
+
   // If its a numeric reference, just leave it alone.
   if (isdigit((*Name)[1]))
     return *Name;
 
   // Resolve the type
-  ResolveType(Ty);
+  Ty = Ty->resolve(); 
+
+  // If its a global name, get its uniquified name, if any
+  GlobalsTypeMap::iterator GI = Globals.find(*Name);
+  if (GI != Globals.end()) {
+    TypePlaneMap::iterator TPI = GI->second.begin();
+    TypePlaneMap::iterator TPE = GI->second.end();
+    for ( ; TPI != TPE ; ++TPI) {
+      if (TPI->first->sameNewTyAs(Ty)) 
+        return TPI->second;
+    }
+  }
+
+  if (isGlobal) {
+    // We didn't find a global name, but if its supposed to be global then all 
+    // we can do is return the name. This is probably a forward reference of a 
+    // global value that hasn't been defined yet. Since we have no definition
+    // we don't know its linkage class. Just assume its an external and the name
+    // shouldn't change.
+    return *Name;
+  }
 
   // Remove as many levels of pointer nesting that we have.
   if (Ty->isPointer()) {
     // Avoid infinite loops in recursive types
-    TypeInfo* Last = 0;
-    while (Ty->isPointer() && Last != Ty) {
+    const TypeInfo* Last = 0;
+    while (Ty->isPointer() && !Ty->sameOldTyAs(Last)) {
       Last = Ty;
-      Ty = Ty->getElementType();
-      ResolveType(Ty);
+      Ty = Ty->getElementType()->resolve();
     }
   }
 
@@ -381,7 +636,7 @@
     // Scan the fields and count the signed and unsigned fields
     int isSigned = 0;
     for (unsigned i = 0; i < Ty->getNumStructElements(); ++i) {
-      TypeInfo* Tmp = Ty->getElement(i);
+      const TypeInfo* Tmp = Ty->getElement(i);
       if (Tmp->isInteger())
         if (Tmp->isSigned())
           isSigned++;
@@ -394,13 +649,99 @@
   return Result;
 }
 
+static unsigned UniqueNameCounter = 0;
+
+std::string getGlobalName(const std::string* Name, const std::string Linkage,
+                          const TypeInfo* Ty, bool isConstant) {
+  // Default to given name
+  std::string Result = *Name; 
+  // Look up the name in the Globals Map
+  GlobalsTypeMap::iterator GI = Globals.find(*Name);
+  // Did we see this global name before?
+  if (GI != Globals.end()) {
+    if (Ty->isUnresolvedDeep()) {
+      // The Gval's type is unresolved. Consequently, we can't disambiguate it
+      // by type. We'll just change its name and emit a warning.
+      warning("Cannot disambiguate global value '" + *Name + 
+              "' because type '" + Ty->getNewTy() + "'is unresolved.\n");
+      Result = *Name + ".unique";
+      UniqueNameCounter++;
+      Result += llvm::utostr(UniqueNameCounter);
+      return Result;
+    } else {
+      TypePlaneMap::iterator TPI = GI->second.find(Ty);
+      if (TPI != GI->second.end()) {
+        // We found an existing name of the same old type. This isn't allowed 
+        // in LLVM 2.0. Consequently, we must alter the name of the global so it
+        // can at least compile. References to the global will yield the first
+        // definition, which is okay. We also must warn about this.
+        Result = *Name + ".unique";
+        UniqueNameCounter++;
+        Result += llvm::utostr(UniqueNameCounter);
+        warning(std::string("Global variable '") + *Name + "' was renamed to '"+
+                Result + "'");
+      } else { 
+        // There isn't an existing definition for this name according to the
+        // old types. Now search the TypePlanMap for types with the same new
+        // name. 
+        TypePlaneMap::iterator TPI = GI->second.begin();
+        TypePlaneMap::iterator TPE = GI->second.end();
+        for ( ; TPI != TPE; ++TPI) {
+          if (TPI->first->sameNewTyAs(Ty)) {
+            // The new types are the same but the old types are different so 
+            // this is a global name collision resulting from type planes 
+            // collapsing. 
+            if (Linkage == "external" || Linkage == "dllimport" || 
+                Linkage == "extern_weak" || Linkage == "") {
+              // The linkage of this gval is external so we can't reliably 
+              // rename it because it could potentially create a linking 
+              // problem.  However, we can't leave the name conflict in the 
+              // output either or it won't assemble with LLVM 2.0.  So, all we 
+              // can do is rename this one to something unique and emit a 
+              // warning about the problem.
+              Result = *Name + ".unique";
+              UniqueNameCounter++;
+              Result += llvm::utostr(UniqueNameCounter);
+              warning("Renaming global value '" + *Name + "' to '" + Result + 
+                      "' may cause linkage errors.");
+              return Result;
+            } else {
+              // Its linkage is internal and its type is known so we can 
+              // disambiguate the name collision successfully based on the type.
+              Result = getUniqueName(Name, Ty);
+              TPI->second = Result;
+              return Result;
+            }
+          }
+        }
+        // We didn't find an entry in the type plane with the same new type and
+        // the old types differ so this is a new type plane for this global 
+        // variable. We just fall through to the logic below which inserts
+        // the global.
+      }
+    }
+  }
+
+  // Its a new global name, if it is external we can't change it
+  if (isConstant || Linkage == "external" || Linkage == "dllimport" || 
+      Linkage == "extern_weak" || Linkage == "") {
+    Globals[Result][Ty] = Result;
+    return Result;
+  }
+
+  // Its a new global name, and it is internal, change the name to make it
+  // unique for its type.
+  // Result = getUniqueName(Name, Ty);
+  Globals[*Name][Ty] = Result;
+  return Result;
+}
 %}
 
 // %file-prefix="UpgradeParser"
 
 %union {
   std::string*    String;
-  TypeInfo*       Type;
+  const TypeInfo* Type;
   ValueInfo       Value;
   ConstInfo       Const;
   ValueList*      ValList;
@@ -570,17 +911,17 @@
 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
 UpRTypes 
   : OPAQUE { 
-    $$ = new TypeInfo($1, OpaqueTy);
+    $$ = TypeInfo::get(*$1, OpaqueTy);
   } 
   | SymbolicValueRef { 
-    $$ = new TypeInfo($1, UnresolvedTy);
+    $$ = TypeInfo::get(*$1, UnresolvedTy);
   }
   | PrimType { 
     $$ = $1; 
   }
   | '\\' EUINT64VAL {                   // Type UpReference
     $2->insert(0, "\\");
-    $$ = new TypeInfo($2, UpRefTy);
+    $$ = TypeInfo::get(*$2, UpRefTy);
   }
   | UpRTypesV '(' ArgTypeListI ')' {           // Function derived type?
     std::string newTy( $1->getNewTy() + "(");
@@ -593,19 +934,19 @@
         newTy += (*$3)[i]->getNewTy();
     }
     newTy += ")";
-    $$ = new TypeInfo(new std::string(newTy), $1, $3);
+    $$ = TypeInfo::get(newTy, $1, $3);
   }
   | '[' EUINT64VAL 'x' UpRTypes ']' {          // Sized array type?
+    uint64_t elems = atoi($2->c_str());
     $2->insert(0,"[ ");
     *$2 += " x " + $4->getNewTy() + " ]";
-    uint64_t elems = atoi($2->c_str());
-    $$ = new TypeInfo($2, ArrayTy, $4, elems);
+    $$ = TypeInfo::get(*$2, ArrayTy, $4, elems);
   }
   | '<' EUINT64VAL 'x' UpRTypes '>' {          // Packed array type?
+    uint64_t elems = atoi($2->c_str());
     $2->insert(0,"< ");
     *$2 += " x " + $4->getNewTy() + " >";
-    uint64_t elems = atoi($2->c_str());
-    $$ = new TypeInfo($2, PackedTy, $4, elems);
+    $$ = TypeInfo::get(*$2, PackedTy, $4, elems);
   }
   | '{' TypeListI '}' {                        // Structure type?
     std::string newTy("{");
@@ -615,10 +956,10 @@
       newTy += (*$2)[i]->getNewTy();
     }
     newTy += "}";
-    $$ = new TypeInfo(new std::string(newTy), StructTy, $2);
+    $$ = TypeInfo::get(newTy, StructTy, $2);
   }
   | '{' '}' {                                  // Empty structure type?
-    $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList());
+    $$ = TypeInfo::get("{}", StructTy, new TypeList());
   }
   | '<' '{' TypeListI '}' '>' {                // Packed Structure type?
     std::string newTy("<{");
@@ -628,10 +969,10 @@
       newTy += (*$3)[i]->getNewTy();
     }
     newTy += "}>";
-    $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3);
+    $$ = TypeInfo::get(newTy, PackedStructTy, $3);
   }
   | '<' '{' '}' '>' {                          // Empty packed structure type?
-    $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList());
+    $$ = TypeInfo::get("<{}>", PackedStructTy, new TypeList());
   }
   | UpRTypes '*' {                             // Pointer type?
     $$ = $1->getPointerType();
@@ -655,12 +996,12 @@
   : TypeListI 
   | TypeListI ',' DOTDOTDOT {
     $$ = $1;
-    $$->push_back(new TypeInfo("void",VoidTy));
+    $$->push_back(TypeInfo::get("void",VoidTy));
     delete $3;
   }
   | DOTDOTDOT {
     $$ = new TypeList();
-    $$->push_back(new TypeInfo("void",VoidTy));
+    $$->push_back(TypeInfo::get("void",VoidTy));
     delete $1;
   }
   | /*empty*/ {
@@ -720,7 +1061,7 @@
     delete $2;
   }
   | Types SymbolicValueRef {
-    std::string Name = getUniqueName($2,$1);
+    std::string Name = getUniqueName($2, $1->resolve(), true);
     $$.type = $1;
     $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + Name;
@@ -772,10 +1113,11 @@
 
 ConstExpr: CastOps '(' ConstVal TO Types ')' {
     std::string source = *$3.cnst;
-    TypeInfo* DstTy = ResolveType($5);
+    const TypeInfo* SrcTy = $3.type->resolve();
+    const TypeInfo* DstTy = $5->resolve(); 
     if (*$1 == "cast") {
       // Call getCastUpgrade to upgrade the old cast
-      $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true));
+      $$ = new std::string(getCastUpgrade(source, SrcTy, DstTy, true));
     } else {
       // Nothing to upgrade, just create the cast constant expr
       $$ = new std::string(*$1);
@@ -902,9 +1244,9 @@
 
 // ConstPool - Constants with optional names assigned to them.
 ConstPool : ConstPool OptAssign TYPE TypesV {
-    EnumeratedTypes.push_back(*$4);
+    EnumeratedTypes.push_back($4);
     if (!$2->empty()) {
-      NamedTypes[*$2] = *$4;
+      NamedTypes[*$2] = $4;
       *O << *$2 << " = ";
     }
     *O << "type " << $4->getNewTy() << '\n';
@@ -923,9 +1265,9 @@
   }
   | ConstPool OptAssign OptLinkage GlobalType ConstVal  GlobalVarAttributes {
     if (!$2->empty()) {
-      std::string Name = getUniqueName($2,$5.type);
+      std::string Name = getGlobalName($2,*$3, $5.type->getPointerType(),
+                                       *$4 == "constant");
       *O << Name << " = ";
-      Globals[Name] = *$5.type;
     }
     *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
     delete $2; delete $3; delete $4; delete $6; 
@@ -933,19 +1275,19 @@
   }
   | ConstPool OptAssign External GlobalType Types  GlobalVarAttributes {
     if (!$2->empty()) {
-      std::string Name = getUniqueName($2,$5);
+      std::string Name = getGlobalName($2,*$3,$5->getPointerType(),
+                                       *$4 == "constant");
       *O << Name << " = ";
-      Globals[Name] = *$5;
     }
     *O <<  *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
     delete $2; delete $3; delete $4; delete $6;
     $$ = 0;
   }
-  | ConstPool OptAssign DLLIMPORT GlobalType Types  GlobalVarAttributes {
+  | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
     if (!$2->empty()) {
-      std::string Name = getUniqueName($2,$5);
+      std::string Name = getGlobalName($2,*$3,$5->getPointerType(),
+                                       *$4 == "constant");
       *O << Name << " = ";
-      Globals[Name] = *$5;
     }
     *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
     delete $2; delete $3; delete $4; delete $6;
@@ -953,9 +1295,9 @@
   }
   | ConstPool OptAssign EXTERN_WEAK GlobalType Types  GlobalVarAttributes {
     if (!$2->empty()) {
-      std::string Name = getUniqueName($2,$5);
+      std::string Name = getGlobalName($2,*$3,$5->getPointerType(),
+                                       *$4 == "constant");
       *O << Name << " = ";
-      Globals[Name] = *$5;
     }
     *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
     delete $2; delete $3; delete $4; delete $6;
@@ -1032,7 +1374,7 @@
 ArgVal : Types OptName {
   $$ = new std::string($1->getNewTy());
   if (!$2->empty()) {
-    std::string Name = getUniqueName($2, $1);
+    std::string Name = getUniqueName($2, $1->resolve());
     *$$ += " " + Name;
   }
   delete $2;
@@ -1152,12 +1494,12 @@
   : SymbolicValueRef {
     $$.val = $1;
     $$.constant = false;
-    $$.type = new TypeInfo();
+    $$.type = 0;
   }
   | ConstValueRef {
     $$.val = $1;
     $$.constant = true;
-    $$.type = new TypeInfo();
+    $$.type = 0;
   }
   ;
 
@@ -1165,11 +1507,10 @@
 // type immediately preceeds the value reference, and allows complex constant
 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
 ResolvedVal : Types ValueRef {
-    ResolveType($1);
+    $1 = $1->resolve();
     std::string Name = getUniqueName($2.val, $1);
     $$ = $2;
     delete $$.val;
-    delete $$.type;
     $$.val = new std::string($1->getNewTy() + " " + Name);
     $$.type = $1;
   };
@@ -1212,12 +1553,12 @@
   }
   | RET VOID {                                       // Return with no result...
     *O << "    " << *$1 << ' ' << $2->getNewTy() << '\n';
-    delete $1; delete $2;
+    delete $1;
     $$ = 0;
   }
   | BR LABEL ValueRef {                         // Unconditional Branch...
     *O << "    " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n';
-    delete $1; delete $2; $3.destroy();
+    delete $1; $3.destroy();
     $$ = 0;
   }                                                  // Conditional Branch...
   | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {  
@@ -1225,15 +1566,14 @@
     *O << "    " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", " 
        << $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' ' 
        << *$9.val << '\n';
-    delete $1; delete $2; $3.destroy(); delete $5; $6.destroy(); 
-    delete $8; $9.destroy();
+    delete $1; $3.destroy(); $6.destroy(); $9.destroy();
     $$ = 0;
   }
   | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
     std::string Name = getUniqueName($3.val, $2);
     *O << "    " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", " 
        << $5->getNewTy() << ' ' << *$6.val << " [" << *$8 << " ]\n";
-    delete $1; delete $2; $3.destroy(); delete $5; $6.destroy(); 
+    delete $1; $3.destroy(); $6.destroy(); 
     delete $8;
     $$ = 0;
   }
@@ -1241,12 +1581,12 @@
     std::string Name = getUniqueName($3.val, $2);
     *O << "    " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", " 
        << $5->getNewTy() << ' ' << *$6.val << "[]\n";
-    delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
+    delete $1; $3.destroy(); $6.destroy();
     $$ = 0;
   }
   | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
     TO LABEL ValueRef Unwind LABEL ValueRef {
-    TypeInfo* ResTy = getFunctionReturnType($4);
+    const TypeInfo* ResTy = getFunctionReturnType($4);
     *O << "    ";
     if (!$1->empty()) {
       std::string Name = getUniqueName($1, ResTy);
@@ -1262,9 +1602,8 @@
     }
     *O << ") " << *$9 << ' ' << $10->getNewTy() << ' ' << *$11.val << ' ' 
        << *$12 << ' ' << $13->getNewTy() << ' ' << *$14.val << '\n';
-    delete $1; delete $2; delete $3; delete $4; $5.destroy(); delete $7; 
-    delete $9; delete $10; $11.destroy(); delete $12; delete $13; 
-    $14.destroy(); 
+    delete $1; delete $2; delete $3; $5.destroy(); delete $7; 
+    delete $9; $11.destroy(); delete $12; $14.destroy(); 
     $$ = 0;
   }
   | Unwind {
@@ -1281,26 +1620,26 @@
 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
     *$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " + 
            *$6.val;
-    delete $2; delete $3; delete $5; $6.destroy();
+    delete $3; $6.destroy();
     $$ = $1;
   }
   | IntType ConstValueRef ',' LABEL ValueRef {
     $2->insert(0, $1->getNewTy() + " " );
     *$2 += ", " + $4->getNewTy() + " " + *$5.val;
-    delete $1; delete $4; $5.destroy();
+    $5.destroy();
     $$ = $2;
   };
 
 Inst 
   : OptAssign InstVal {
     if (!$1->empty()) {
-      if (deleteUselessCastFlag && *deleteUselessCastName == *$1) {
-        *$1 += " = ";
-        $1->insert(0, "; "); // don't actually delete it, just comment it out
+      // Get a unique name for this value, based on its type.
+      std::string Name = getUniqueName($1, $2.type);
+      *$1 = Name + " = ";
+      if (deleteUselessCastFlag && *deleteUselessCastName == Name) {
+        // don't actually delete it, just comment it out
+        $1->insert(0, "; USELSS BITCAST: "); 
         delete deleteUselessCastName;
-      } else {
-        // Get a unique name for the name of this value, based on its type.
-        *$1 = getUniqueName($1, $2.type) + " = ";
       }
     }
     *$1 += *$2.val;
@@ -1374,7 +1713,7 @@
     *$1 = getCompareOp(*$1, $2);
     *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
     $$.val = $1;
-    $$.type = new TypeInfo("bool",BoolTy);
+    $$.type = TypeInfo::get("bool",BoolTy);
     $3.destroy(); $5.destroy();
   }
   | ICMP IPredicates Types ValueRef ',' ValueRef {
@@ -1382,7 +1721,7 @@
     std::string Name2 = getUniqueName($6.val, $3);
     *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
     $$.val = $1;
-    $$.type = new TypeInfo("bool",BoolTy);
+    $$.type = TypeInfo::get("bool",BoolTy);
     delete $2; $4.destroy(); $6.destroy();
   }
   | FCMP FPredicates Types ValueRef ',' ValueRef {
@@ -1390,7 +1729,7 @@
     std::string Name2 = getUniqueName($6.val, $3);
     *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
     $$.val = $1;
-    $$.type = new TypeInfo("bool",BoolTy);
+    $$.type = TypeInfo::get("bool",BoolTy);
     delete $2; $4.destroy(); $6.destroy();
   }
   | NOT ResolvedVal {
@@ -1409,21 +1748,21 @@
   }
   | CastOps ResolvedVal TO Types {
     std::string source = *$2.val;
-    TypeInfo* SrcTy = $2.type;
-    TypeInfo* DstTy = ResolveType($4);
+    const TypeInfo* SrcTy = $2.type->resolve();
+    const TypeInfo* DstTy = $4->resolve();
     $$.val = new std::string();
+    $$.type = DstTy;
     if (*$1 == "cast") {
-      *$$.val +=  getCastUpgrade(source, SrcTy, DstTy, false);
+      *$$.val += getCastUpgrade(source, SrcTy, DstTy, false);
     } else {
       *$$.val += *$1 + " " + source + " to " + DstTy->getNewTy();
     }
-    $$.type = $4;
     // Check to see if this is a useless cast of a value to the same name
     // and the same type. Such casts will probably cause redefinition errors
     // when assembled and perform no code gen action so just remove them.
     if (*$1 == "cast" || *$1 == "bitcast")
-      if ($2.type->isInteger() && DstTy->isInteger() &&
-          $2.type->getBitWidth() == DstTy->getBitWidth()) {
+      if (SrcTy->isInteger() && DstTy->isInteger() &&
+          SrcTy->getBitWidth() == DstTy->getBitWidth()) {
         deleteUselessCastFlag = true; // Flag the "Inst" rule
         deleteUselessCastName = new std::string(*$2.val); // save the name
         size_t pos = deleteUselessCastName->find_first_of("%\"",0);
@@ -1450,7 +1789,7 @@
   | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
     *$1 += " " + *$2.val + ", " + *$4.val;
     $$.val = $1;
-    ResolveType($2.type);
+    $2.type = $2.type->resolve();;
     $$.type = $2.type->getElementType();
     delete $2.val; $4.destroy();
   }
@@ -1488,7 +1827,7 @@
     *$1 += ")";
     $$.val = $1;
     $$.type = getFunctionReturnType($3);
-    delete $2; delete $3; $4.destroy(); delete $6;
+    delete $2; $4.destroy(); delete $6;
   }
   | MemoryInst ;
 
@@ -1510,7 +1849,7 @@
       *$1 += " " + *$3;
     $$.val = $1;
     $$.type = $2->getPointerType();
-    delete $2; delete $3;
+    delete $3;
   }
   | MALLOC Types ',' UINT ValueRef OptCAlign {
     std::string Name = getUniqueName($5.val, $4);
@@ -1519,7 +1858,7 @@
       *$1 += " " + *$6;
     $$.val = $1;
     $$.type = $2->getPointerType();
-    delete $2; delete $4; $5.destroy(); delete $6;
+    $5.destroy(); delete $6;
   }
   | ALLOCA Types OptCAlign {
     *$1 += " " + $2->getNewTy();
@@ -1527,7 +1866,7 @@
       *$1 += " " + *$3;
     $$.val = $1;
     $$.type = $2->getPointerType();
-    delete $2; delete $3;
+    delete $3;
   }
   | ALLOCA Types ',' UINT ValueRef OptCAlign {
     std::string Name = getUniqueName($5.val, $4);
@@ -1536,12 +1875,12 @@
       *$1 += " " + *$6;
     $$.val = $1;
     $$.type = $2->getPointerType();
-    delete $2; delete $4; $5.destroy(); delete $6;
+    $5.destroy(); delete $6;
   }
   | FREE ResolvedVal {
     *$1 += " " + *$2.val;
     $$.val = $1;
-    $$.type = new TypeInfo("void", VoidTy); 
+    $$.type = TypeInfo::get("void", VoidTy); 
     $2.destroy();
   }
   | OptVolatile LOAD Types ValueRef {
@@ -1550,8 +1889,8 @@
       *$1 += " ";
     *$1 += *$2 + " " + $3->getNewTy() + " " + Name;
     $$.val = $1;
-    $$.type = $3->getElementType()->clone();
-    delete $2; delete $3; $4.destroy();
+    $$.type = $3->getElementType();
+    delete $2; $4.destroy();
   }
   | OptVolatile STORE ResolvedVal ',' Types ValueRef {
     std::string Name = getUniqueName($6.val, $5);
@@ -1559,8 +1898,8 @@
       *$1 += " ";
     *$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name;
     $$.val = $1;
-    $$.type = new TypeInfo("void", VoidTy);
-    delete $2; $3.destroy(); delete $5; $6.destroy();
+    $$.type = TypeInfo::get("void", VoidTy);
+    delete $2; $3.destroy(); $6.destroy();
   }
   | GETELEMENTPTR Types ValueRef IndexList {
     std::string Name = getUniqueName($3.val, $2);
@@ -1573,7 +1912,7 @@
         *O << "    %gep_upgrade" << unique << " = zext " << *old 
            << " to i64\n";
         VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
-        VI.type->setOldTy(ULongTy);
+        VI.type = TypeInfo::get("i64",ULongTy);
       }
     }
     *$1 += " " + $2->getNewTy() + " " + Name;
@@ -1592,7 +1931,8 @@
   std::string where 
     = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
                   + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
-  std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
+  std::string errMsg = where + "error: " + std::string(ErrorMsg) + 
+                       " while reading ";
   if (yychar == YYEMPTY || yychar == 0)
     errMsg += "end-of-file.";
   else
@@ -1601,3 +1941,16 @@
   *O << "llvm-upgrade parse failed.\n";
   exit(1);
 }
+
+static void warning(const std::string& ErrorMsg) {
+  std::string where 
+    = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+                  + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+  std::string errMsg = where + "warning: " + std::string(ErrorMsg) + 
+                       " while reading ";
+  if (yychar == YYEMPTY || yychar == 0)
+    errMsg += "end-of-file.";
+  else
+    errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
+  std::cerr << "llvm-upgrade: " << errMsg << '\n';
+}






More information about the llvm-commits mailing list