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

Reid Spencer reid at x10sys.com
Mon Jan 1 21:44:48 PST 2007



Changes in directory llvm/tools/llvm-upgrade:

ParserInternals.h updated: 1.10 -> 1.11
UpgradeLexer.l updated: 1.11 -> 1.12
UpgradeParser.y updated: 1.28 -> 1.29
---
Log message:

For PR1070: http://llvm.org/PR1070 :
Revise the upgrade parser to keep track of types more faithfully and use
this information to resolve name conflicts resulting from collapsed type
planes. The type planes have collapsed because the integer types are now
signless so that uint and int became i32. Where two planes existed for uint
and int, only i32 exists. Any variable names depending on the type planes
to pmake the identifier unique would cause a conflict. This patch resolves
that conflict for many but not all cases.

Situations involving the integer types and pointers to them are handled
by this patch.  However, there are corner cases that are not handled 
well, such as:

%t1 = type { uint, int }
%t2 = type { int, uint }

void %myfunc(%t1* one, %t2* two) {
  %var = load %t1* one
  %var = load %t2* two
}

In the scenario above, %t1 and %t2 are really the same type: { i32, i32 }
Consequently attempting to name %var twice will yield a redefinition error
when assembled.  

While this patch is sufficien to allow the llvm/test suite to pass, More 
work needs to be to complete the handling of these corner cases.



---
Diffs of the changes:  (+563 -313)

 ParserInternals.h |  173 +++++++++++--
 UpgradeLexer.l    |    4 
 UpgradeParser.y   |  699 ++++++++++++++++++++++++++++++++----------------------
 3 files changed, 563 insertions(+), 313 deletions(-)


Index: llvm/tools/llvm-upgrade/ParserInternals.h
diff -u llvm/tools/llvm-upgrade/ParserInternals.h:1.10 llvm/tools/llvm-upgrade/ParserInternals.h:1.11
--- llvm/tools/llvm-upgrade/ParserInternals.h:1.10	Sun Dec 31 00:02:26 2006
+++ llvm/tools/llvm-upgrade/ParserInternals.h	Mon Jan  1 23:44:33 2007
@@ -15,9 +15,11 @@
 #ifndef PARSER_INTERNALS_H
 #define PARSER_INTERNALS_H
 
+#include <llvm/ADT/StringExtras.h>
 #include <string>
 #include <istream>
 #include <vector>
+#include <cassert>
 
 // Global variables exported from the lexer...
 
@@ -26,11 +28,15 @@
 extern int Upgradelineno;
 extern std::istream* LexInput;
 
+struct TypeInfo;
+typedef std::vector<TypeInfo*> TypeList;
 
 void UpgradeAssembly(
   const std::string & infile, std::istream& in, std::ostream &out, bool debug,
   bool addAttrs);
 
+TypeInfo* ResolveType(TypeInfo*& Ty);
+
 // Globals exported by the parser...
 extern char* Upgradetext;
 extern int   Upgradeleng;
@@ -47,6 +53,17 @@
   OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, NumericTy
 };
 
+/// 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;
+  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
@@ -55,20 +72,89 @@
 /// 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 {
-  std::string* newTy;
-  Types oldTy;
-  Types elemTy;
+  TypeInfo() 
+    : newTy(0), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0),
+      nelems(0) {
+  }
+
+  TypeInfo(const char * newType, Types oldType)
+    : newTy(0), oldTy(oldType), elemTy(0), resultTy(0), elements(0), nelems(0) {
+    newTy = new std::string(newType);
+  }
+
+  TypeInfo(std::string *newType, Types oldType, TypeInfo* eTy = 0, 
+           TypeInfo *rTy = 0) 
+    : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(rTy), elements(0),
+      nelems(0) { 
+  }
+
+  TypeInfo(std::string *newType, Types oldType, TypeInfo *eTy, uint64_t elems)
+    : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(0), elements(0), 
+      nelems(elems) {
+  }
+
+  TypeInfo(std::string *newType, Types oldType, TypeList* TL)
+    : newTy(newType), oldTy(oldType), elemTy(0), resultTy(0), elements(TL),
+      nelems(0) {
+  }
+
+  TypeInfo(std::string *newType, TypeInfo* resTy, TypeList* TL) 
+    : newTy(newType), oldTy(FunctionTy), elemTy(0), resultTy(resTy), 
+    elements(TL), nelems(0) {
+  }
+
+  TypeInfo(const TypeInfo& that)
+    : newTy(0), oldTy(that.oldTy), elemTy(0), resultTy(0), elements(0), 
+      nelems(0) {
+    *this = that;
+  }
+
+  TypeInfo& operator=(const TypeInfo& that) {
+    oldTy = that.oldTy;
+    nelems = that.nelems;
+    if (that.newTy)
+      newTy = new std::string(*that.newTy);
+    if (that.elemTy)
+      elemTy = that.elemTy->clone();
+    if (that.resultTy)
+      resultTy = that.resultTy->clone();
+    if (that.elements) {
+      elements = new std::vector<TypeInfo*>(that.elements->size());
+      *elements = *that.elements;
+    }
+    return *this;
+  }
 
-  void destroy() const { delete newTy; }
+  ~TypeInfo() { 
+    delete newTy; delete elemTy; delete resultTy; delete elements;
+  }
 
-  TypeInfo clone() const { 
-    TypeInfo result = *this; 
-    result.newTy = new std::string(*newTy);
-    return result;
+  TypeInfo* clone() const { 
+    return new TypeInfo(*this);
   }
 
-  Types getElementType() const { return elemTy; }
+  Types getElementTy() const { 
+    if (elemTy) {
+      return elemTy->oldTy;
+    }
+    return UnresolvedTy;
+  }
+
+  const std::string& getNewTy() const { return *newTy; }
+  void setOldTy(Types Ty) { oldTy = Ty; }
+
+  TypeInfo* getResultType() const { return resultTy; }
+  TypeInfo* getElementType() const { return elemTy; }
 
+  TypeInfo* getPointerType() const {
+    std::string* ty = new std::string(*newTy + "*");
+    return new TypeInfo(ty, PointerTy, this->clone(), (TypeInfo*)0);
+  }
+
+  bool isUnresolved() const { return oldTy == UnresolvedTy; }
+  bool isNumeric() const { return oldTy == NumericTy; }
+  bool isVoid() const { return oldTy == VoidTy; }
+  bool isBool() const { return oldTy == BoolTy; }
   bool isSigned() const {
     return oldTy == SByteTy || oldTy == ShortTy || 
            oldTy == IntTy || oldTy == LongTy;
@@ -79,9 +165,6 @@
            oldTy == UIntTy || oldTy == ULongTy;
   }
 
-  bool isBool() const {
-    return oldTy == BoolTy;
-  }
 
   bool isSignless() const { return !isSigned() && !isUnsigned(); }
   bool isInteger() const { return isSigned() || isUnsigned(); }
@@ -89,8 +172,14 @@
   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;
@@ -98,6 +187,7 @@
 
   unsigned getBitWidth() const {
     switch (oldTy) {
+      default:
       case LabelTy:
       case VoidTy : return 0;
       case BoolTy : return 1;
@@ -106,32 +196,61 @@
       case IntTy: case UIntTy: case FloatTy: return 32;
       case LongTy: case ULongTy: case DoubleTy : return 64;
       case PointerTy: return SizeOfPointer; // global var
-      default:
-        return 128; /// Struct/Packed/Array --> doesn't matter
-      
+      case PackedTy: 
+      case ArrayTy: 
+        return nelems * elemTy->getBitWidth();
+      case StructTy:
+      case PackedStructTy: {
+        uint64_t size = 0;
+        for (unsigned i = 0; i < elements->size(); i++) {
+          ResolveType((*elements)[i]);
+          size += (*elements)[i]->getBitWidth();
+        }
+        return size;
+      }
     }
   }
-};
 
-/// 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;
-  TypeInfo type;
-  bool constant;
-  bool isConstant() const { return constant; }
-  void destroy() { delete val; type.destroy(); }
+  TypeInfo* getIndexedType(const ValueInfo&  VI) {
+    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;
+  }
+
+private:
+  std::string* newTy;
+  Types oldTy;
+  TypeInfo *elemTy;
+  TypeInfo *resultTy;
+  TypeList *elements;
+  uint64_t nelems;
 };
 
 /// This type is used to keep track of the signedness of constants.
 struct ConstInfo {
   std::string *cnst;
-  TypeInfo type;
-  void destroy() { delete cnst; type.destroy(); }
+  TypeInfo *type;
+  void destroy() { delete cnst; delete type; }
 };
 
 typedef std::vector<ValueInfo> ValueList;
 
+inline void ValueInfo::destroy() { delete val; delete type; }
 
 #endif


Index: llvm/tools/llvm-upgrade/UpgradeLexer.l
diff -u llvm/tools/llvm-upgrade/UpgradeLexer.l:1.11 llvm/tools/llvm-upgrade/UpgradeLexer.l:1.12
--- llvm/tools/llvm-upgrade/UpgradeLexer.l:1.11	Sat Dec 30 23:45:57 2006
+++ llvm/tools/llvm-upgrade/UpgradeLexer.l	Mon Jan  1 23:44:33 2007
@@ -48,9 +48,7 @@
   return sym
 
 #define RET_TY(sym,OldTY,NewTY,sign) \
-  Upgradelval.Type.newTy = new std::string(NewTY); \
-  Upgradelval.Type.oldTy = OldTY; \
-  Upgradelval.Type.elemTy = VoidTy; \
+  Upgradelval.Type = new TypeInfo(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.28 llvm/tools/llvm-upgrade/UpgradeParser.y:1.29
--- llvm/tools/llvm-upgrade/UpgradeParser.y:1.28	Sun Dec 31 19:20:16 2006
+++ llvm/tools/llvm-upgrade/UpgradeParser.y	Mon Jan  1 23:44:33 2007
@@ -13,12 +13,10 @@
 
 %{
 #include "ParserInternals.h"
-#include <llvm/ADT/StringExtras.h>
 #include <algorithm>
 #include <map>
 #include <utility>
 #include <iostream>
-#include <cassert>
 
 #define YYERROR_VERBOSE 1
 #define YYINCLUDED_STDLIB_H
@@ -78,71 +76,72 @@
   }
 }
 
-static void ResolveType(TypeInfo& Ty) {
-  if (Ty.oldTy == UnresolvedTy) {
-    TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
+TypeInfo* ResolveType(TypeInfo*& Ty) {
+  if (Ty->isUnresolved()) {
+    TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
     if (I != NamedTypes.end()) {
-      Ty.oldTy = I->second.oldTy;
-      Ty.elemTy = I->second.elemTy;
+      Ty = I->second.clone();
+      return Ty;
     } else {
-      std::string msg("Can't resolve type: ");
-      msg += *Ty.newTy;
+      std::string msg("Cannot resolve type: ");
+      msg += Ty->getNewTy();
       yyerror(msg.c_str());
     }
-  } else if (Ty.oldTy == NumericTy) {
-    unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
+  } else if (Ty->isNumeric()) {
+    unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // Skip the '\\'
     if (ref < EnumeratedTypes.size()) {
-      Ty.oldTy = EnumeratedTypes[ref].oldTy;
-      Ty.elemTy = EnumeratedTypes[ref].elemTy;
+      Ty = EnumeratedTypes[ref].clone();
+      return Ty;
     } else {
       std::string msg("Can't resolve type: ");
-      msg += *Ty.newTy;
+      msg += Ty->getNewTy();
       yyerror(msg.c_str());
     }
   }
   // otherwise its already resolved.
+  return Ty;
 }
 
 static const char* getCastOpcode(
-  std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy) 
+  std::string& Source, const TypeInfo* SrcTy, const TypeInfo* DstTy) 
 {
-  unsigned SrcBits = SrcTy.getBitWidth();
-  unsigned DstBits = DstTy.getBitWidth();
+  unsigned SrcBits = SrcTy->getBitWidth();
+  unsigned DstBits = DstTy->getBitWidth();
   const char* opcode = "bitcast";
   // Run through the possibilities ...
-  if (DstTy.isIntegral()) {                        // Casting to integral
-    if (SrcTy.isIntegral()) {                      // Casting from integral
+  if (DstTy->isIntegral()) {                        // Casting to integral
+    if (SrcTy->isIntegral()) {                      // Casting from integral
       if (DstBits < SrcBits)
         opcode = "trunc";
       else if (DstBits > SrcBits) {                // its an extension
-        if (SrcTy.isSigned())
+        if (SrcTy->isSigned())
           opcode ="sext";                          // signed -> SEXT
         else
           opcode = "zext";                         // unsigned -> ZEXT
       } else {
         opcode = "bitcast";                        // Same size, No-op cast
       }
-    } else if (SrcTy.isFloatingPoint()) {          // Casting from floating pt
-      if (DstTy.isSigned()) 
+    } else if (SrcTy->isFloatingPoint()) {          // Casting from floating pt
+      if (DstTy->isSigned()) 
         opcode = "fptosi";                         // FP -> sint
       else
         opcode = "fptoui";                         // FP -> uint 
-    } else if (SrcTy.isPacked()) {
-      assert(DstBits == SrcTy.getBitWidth() &&
+    } else if (SrcTy->isPacked()) {
+      assert(DstBits == SrcTy->getBitWidth() &&
                "Casting packed to integer of different width");
         opcode = "bitcast";                        // same size, no-op cast
     } else {
-      assert(SrcTy.isPointer() &&
+      assert(SrcTy->isPointer() &&
              "Casting from a value that is not first-class type");
       opcode = "ptrtoint";                         // ptr -> int
     }
-  } else if (DstTy.isFloatingPoint()) {           // Casting to floating pt
-    if (SrcTy.isIntegral()) {                     // Casting from integral
-      if (SrcTy.isSigned())
+  } else if (DstTy->isFloatingPoint()) {           // Casting to floating pt
+    if (SrcTy->isIntegral()) {                     // Casting from integral
+      if (SrcTy->isSigned())
         opcode = "sitofp";                         // sint -> FP
       else
         opcode = "uitofp";                         // uint -> FP
-    } else if (SrcTy.isFloatingPoint()) {         // Casting from floating pt
+    } else if (SrcTy->isFloatingPoint()) {         // Casting from floating pt
       if (DstBits < SrcBits) {
         opcode = "fptrunc";                        // FP -> smaller FP
       } else if (DstBits > SrcBits) {
@@ -150,27 +149,27 @@
       } else  {
         opcode ="bitcast";                         // same size, no-op cast
       }
-    } else if (SrcTy.isPacked()) {
-      assert(DstBits == SrcTy.getBitWidth() &&
+    } else if (SrcTy->isPacked()) {
+      assert(DstBits == SrcTy->getBitWidth() &&
              "Casting packed to floating point of different width");
         opcode = "bitcast";                        // same size, no-op cast
     } else {
       assert(0 && "Casting pointer or non-first class to float");
     }
-  } else if (DstTy.isPacked()) {
-    if (SrcTy.isPacked()) {
-      assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
+  } else if (DstTy->isPacked()) {
+    if (SrcTy->isPacked()) {
+      assert(DstTy->getBitWidth() == SrcTy->getBitWidth() &&
              "Casting packed to packed of different widths");
       opcode = "bitcast";                          // packed -> packed
-    } else if (DstTy.getBitWidth() == SrcBits) {
+    } else if (DstTy->getBitWidth() == SrcBits) {
       opcode = "bitcast";                          // float/int -> packed
     } else {
       assert(!"Illegal cast to packed (wrong type or size)");
     }
-  } else if (DstTy.isPointer()) {
-    if (SrcTy.isPointer()) {
+  } else if (DstTy->isPointer()) {
+    if (SrcTy->isPointer()) {
       opcode = "bitcast";                          // ptr -> ptr
-    } else if (SrcTy.isIntegral()) {
+    } else if (SrcTy->isIntegral()) {
       opcode = "inttoptr";                         // int -> ptr
     } else {
       assert(!"Casting invalid type to pointer");
@@ -181,12 +180,12 @@
   return opcode;
 }
 
-static std::string getCastUpgrade(
-  const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
+static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy,
+                                  TypeInfo* DstTy, bool isConst)
 {
   std::string Result;
   std::string Source = Src;
-  if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
+  if (SrcTy->isFloatingPoint() && DstTy->isPointer()) {
     // fp -> ptr cast is no longer supported but we must upgrade this
     // by doing a double cast: fp -> int -> ptr
     if (isConst)
@@ -197,16 +196,16 @@
       Source = "i64 %cast_upgrade" + llvm::utostr(unique);
     }
     // Update the SrcTy for the getCastOpcode call below
-    SrcTy.destroy();
-    SrcTy.newTy = new std::string("i64");
-    SrcTy.oldTy = ULongTy;
-  } else if (DstTy.oldTy == BoolTy && SrcTy.oldTy != BoolTy) {
-    // cast ptr %x to  bool was previously defined as setne ptr %x, null
-    // The ptrtoint semantic is to truncate, not compare so we must retain
-    // the original intent by replace the cast with a setne
-    const char* comparator = SrcTy.isPointer() ? ", null" : 
-      (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
-    const char* compareOp = SrcTy.isFloatingPoint() ? "fcmp one " : "icmp ne ";
+    delete SrcTy;
+    SrcTy = new TypeInfo("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
+    // the original intent by replacing the cast with a setne
+    const char* comparator = SrcTy->isPointer() ? ", null" : 
+      (SrcTy->isFloatingPoint() ? ", 0.0" : 
+       (SrcTy->isBool() ? ", false" : ", 0"));
+    const char* compareOp = SrcTy->isFloatingPoint() ? "fcmp one " : "icmp ne ";
     if (isConst) { 
       Result = "(" + Source + comparator + ")";
       Result = compareOp + Result;
@@ -218,33 +217,32 @@
   ResolveType(DstTy);
   std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
   if (isConst)
-    Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
+    Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")";
   else
-    Result += Opcode + " " + Source + " to " + *DstTy.newTy;
+    Result += Opcode + " " + Source + " to " + DstTy->getNewTy();
   return Result;
 }
 
-const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) {
+const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) {
   const char* op = opcode.c_str();
-  TypeInfo Ty = TI;
-  ResolveType(Ty);
-  if (Ty.isPacked())
-    Ty.oldTy = Ty.getElementType();
+  const TypeInfo* Ty = ResolveType(TI);
+  if (Ty->isPacked())
+    Ty = Ty->getElementType();
   if (opcode == "div")
-    if (Ty.isFloatingPoint())
+    if (Ty->isFloatingPoint())
       op = "fdiv";
-    else if (Ty.isUnsigned())
+    else if (Ty->isUnsigned())
       op = "udiv";
-    else if (Ty.isSigned())
+    else if (Ty->isSigned())
       op = "sdiv";
     else
       yyerror("Invalid type for div instruction");
   else if (opcode == "rem")
-    if (Ty.isFloatingPoint())
+    if (Ty->isFloatingPoint())
       op = "frem";
-    else if (Ty.isUnsigned())
+    else if (Ty->isUnsigned())
       op = "urem";
-    else if (Ty.isSigned())
+    else if (Ty->isSigned())
       op = "srem";
     else
       yyerror("Invalid type for rem instruction");
@@ -252,7 +250,7 @@
 }
 
 std::string 
-getCompareOp(const std::string& setcc, const TypeInfo& TI) {
+getCompareOp(const std::string& setcc, const TypeInfo* TI) {
   assert(setcc.length() == 5);
   char cc1 = setcc[3];
   char cc2 = setcc[4];
@@ -261,20 +259,20 @@
   std::string result("xcmp xxx");
   result[6] = cc1;
   result[7] = cc2;
-  if (TI.isFloatingPoint()) {
+  if (TI->isFloatingPoint()) {
     result[0] = 'f';
     result[5] = 'o';
     if (cc1 == 'n')
       result[5] = 'u'; // NE maps to unordered
     else
       result[5] = 'o'; // everything else maps to ordered
-  } else if (TI.isIntegral() || TI.isPointer()) {
+  } else if (TI->isIntegral() || TI->isPointer()) {
     result[0] = 'i';
     if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
       result.erase(5,1);
-    else if (TI.isSigned())
+    else if (TI->isSigned())
       result[5] = 's';
-    else if (TI.isUnsigned() || TI.isPointer() || TI.isBool())
+    else if (TI->isUnsigned() || TI->isPointer() || TI->isBool())
       result[5] = 'u';
     else
       yyerror("Invalid integral type for setcc");
@@ -282,16 +280,87 @@
   return result;
 }
 
+static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) {
+  ResolveType(PFTy);
+  if (PFTy->isPointer()) {
+    TypeInfo* ElemTy = PFTy->getElementType();
+    ResolveType(ElemTy);
+    if (ElemTy->isFunction())
+      return ElemTy->getResultType()->clone();
+  } else if (PFTy->isFunction()) {
+    return PFTy->getResultType()->clone();
+  }
+  return PFTy->clone();
+}
+
+static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) {
+  ResolveType(PTy);
+  assert(PTy->isPointer() && "GEP Operand is not a pointer?");
+  TypeInfo* Result = PTy->getElementType(); // just skip first index
+  ResolveType(Result);
+  for (unsigned i = 1; i < idxs->size(); ++i) {
+    if (Result->isComposite()) {
+      Result = Result->getIndexedType((*idxs)[i]);
+      ResolveType(Result);
+    } else
+      yyerror("Invalid type for index");
+  }
+  return Result->getPointerType();
+}
+
+static std::string makeUniqueName(const std::string *Name, bool isSigned) {
+  const char *suffix = ".u";
+  if (isSigned)
+    suffix = ".s";
+  if ((*Name)[Name->size()-1] == '"') {
+    std::string Result(*Name);
+    Result.insert(Name->size()-1, suffix);
+    return Result;
+  }
+  return *Name + suffix;
+}
+
+// This function handles appending .u or .s to integer value names that
+// 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) {
+  // 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);
+
+  // Default the result to the current name
+  std::string Result = *Name; 
+
+  if (Ty->isInteger()) {
+    // If its an integer type, make the name unique
+    Result = makeUniqueName(Name, Ty->isSigned());
+  } else if (Ty->isPointer()) {
+    while (Ty->isPointer()) 
+      Ty = Ty->getElementType();
+    if (Ty->isInteger())
+      Result = makeUniqueName(Name, Ty->isSigned());
+  }
+  return Result;
+}
+
 %}
 
 // %file-prefix="UpgradeParser"
 
 %union {
   std::string*    String;
-  TypeInfo        Type;
+  TypeInfo*       Type;
   ValueInfo       Value;
   ConstInfo       Const;
   ValueList*      ValList;
+  TypeList*       TypeVec;
 }
 
 %token <Type>   VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
@@ -322,19 +391,20 @@
 
 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign 
 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
-%type <String> ArgTypeListI ConstExpr DefinitionList
+%type <String> ConstExpr DefinitionList
 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
-%type <String> Function FunctionProto BasicBlock TypeListI
-%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
-%type <String> OptTailCall InstVal OptVolatile Unwind
-%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
+%type <String> Function FunctionProto BasicBlock 
+%type <String> InstructionList BBTerminatorInst JumpTable Inst
+%type <String> OptTailCall OptVolatile Unwind
+%type <String> SymbolicValueRef OptSideEffect GlobalType
 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
 %type <String> Name ConstValueRef ConstVector External
 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
 %type <String> IPredicates FPredicates
 
 %type <ValList> ValueRefList ValueRefListE IndexList
+%type <TypeVec> TypeListI ArgTypeListI
 
 %type <Type> IntType SIntType UIntType FPType TypesV Types 
 %type <Type> PrimType UpRTypesV UpRTypes
@@ -342,7 +412,7 @@
 %type <String> IntVal EInt64Val 
 %type <Const>  ConstVal
 
-%type <Value> ValueRef ResolvedVal 
+%type <Value> ValueRef ResolvedVal InstVal PHIList MemoryInst
 
 %start Module
 
@@ -456,68 +526,79 @@
 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
 UpRTypes 
   : OPAQUE { 
-    $$.newTy = $1; 
-    $$.oldTy = OpaqueTy; 
+    $$ = new TypeInfo($1, OpaqueTy);
   } 
   | SymbolicValueRef { 
-    $$.newTy = $1;
-    $$.oldTy = UnresolvedTy;
+    $$ = new TypeInfo($1, UnresolvedTy);
   }
   | PrimType { 
     $$ = $1; 
   }
   | '\\' EUINT64VAL {                   // Type UpReference
     $2->insert(0, "\\");
-    $$.newTy = $2;
-    $$.oldTy = NumericTy;
+    $$ = new TypeInfo($2, NumericTy);
   }
   | UpRTypesV '(' ArgTypeListI ')' {           // Function derived type?
-    *$1.newTy += "( " + *$3 + " )";
-    delete $3;
-    $$.newTy = $1.newTy;
-    $$.oldTy = FunctionTy;
+    std::string newTy( $1->getNewTy() + "(");
+    for (unsigned i = 0; i < $3->size(); ++i) {
+      if (i != 0)
+        newTy +=  ", ";
+      if ((*$3)[i]->isVoid())
+        newTy += "...";
+      else
+        newTy += (*$3)[i]->getNewTy();
+    }
+    newTy += ")";
+    $$ = new TypeInfo(new std::string(newTy), $1, $3);
+    EnumeratedTypes.push_back(*$$);
   }
   | '[' EUINT64VAL 'x' UpRTypes ']' {          // Sized array type?
     $2->insert(0,"[ ");
-    *$2 += " x " + *$4.newTy + " ]";
-    delete $4.newTy;
-    $$.newTy = $2;
-    $$.oldTy = ArrayTy;
-    $$.elemTy = $4.oldTy;
+    *$2 += " x " + $4->getNewTy() + " ]";
+    uint64_t elems = atoi($2->c_str());
+    $$ = new TypeInfo($2, ArrayTy, $4, elems);
+    EnumeratedTypes.push_back(*$$);
   }
   | '<' EUINT64VAL 'x' UpRTypes '>' {          // Packed array type?
     $2->insert(0,"< ");
-    *$2 += " x " + *$4.newTy + " >";
-    delete $4.newTy;
-    $$.newTy = $2;
-    $$.oldTy = PackedTy;
-    $$.elemTy = $4.oldTy;
+    *$2 += " x " + $4->getNewTy() + " >";
+    uint64_t elems = atoi($2->c_str());
+    $$ = new TypeInfo($2, PackedTy, $4, elems);
+    EnumeratedTypes.push_back(*$$);
   }
   | '{' TypeListI '}' {                        // Structure type?
-    $2->insert(0, "{ ");
-    *$2 += " }";
-    $$.newTy = $2;
-    $$.oldTy = StructTy;
+    std::string newTy("{");
+    for (unsigned i = 0; i < $2->size(); ++i) {
+      if (i != 0)
+        newTy +=  ", ";
+      newTy += (*$2)[i]->getNewTy();
+    }
+    newTy += "}";
+    $$ = new TypeInfo(new std::string(newTy), StructTy, $2);
+    EnumeratedTypes.push_back(*$$);
   }
   | '{' '}' {                                  // Empty structure type?
-    $$.newTy = new std::string("{}");
-    $$.oldTy = StructTy;
+    $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList());
+    EnumeratedTypes.push_back(*$$);
   }
   | '<' '{' TypeListI '}' '>' {                // Packed Structure type?
-    $3->insert(0, "<{ ");
-    *$3 += " }>";
-    $$.newTy = $3;
-    $$.oldTy = StructTy;
+    std::string newTy("<{");
+    for (unsigned i = 0; i < $3->size(); ++i) {
+      if (i != 0)
+        newTy +=  ", ";
+      newTy += (*$3)[i]->getNewTy();
+    }
+    newTy += "}>";
+    $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3);
+    EnumeratedTypes.push_back(*$$);
   }
   | '<' '{' '}' '>' {                          // Empty packed structure type?
-    $$.newTy = new std::string("<{}>");
-    $$.oldTy = StructTy;
+    $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList());
+    EnumeratedTypes.push_back(*$$);
   }
   | UpRTypes '*' {                             // Pointer type?
-    *$1.newTy += '*';
-    $$.elemTy = $1.oldTy;
-    $1.oldTy = PointerTy;
-    $$ = $1;
+    $$ = $1->getPointerType();
+    EnumeratedTypes.push_back(*$$);
   };
 
 // TypeList - Used for struct declarations and as a basis for function type 
@@ -525,27 +606,29 @@
 //
 TypeListI 
   : UpRTypes {
-    $$ = $1.newTy;
+    $$ = new TypeList();
+    $$->push_back($1);
   }
   | TypeListI ',' UpRTypes {
-    *$1 += ", " + *$3.newTy;
-    delete $3.newTy;
     $$ = $1;
+    $$->push_back($3);
   };
 
 // ArgTypeList - List of types for a function type declaration...
 ArgTypeListI 
   : TypeListI 
   | TypeListI ',' DOTDOTDOT {
-    *$1 += ", ...";
-    delete $3;
     $$ = $1;
+    $$->push_back(new TypeInfo("void",VoidTy));
+    delete $3;
   }
   | DOTDOTDOT {
-    $$ = $1;
+    $$ = new TypeList();
+    $$->push_back(new TypeInfo("void",VoidTy));
+    delete $1;
   }
   | /*empty*/ {
-    $$ = new std::string();
+    $$ = new TypeList();
   };
 
 // ConstVal - The various declarations that go into the constant pool.  This
@@ -556,95 +639,96 @@
 //
 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " [ " + *$3 + " ]";
     delete $3;
   }
   | Types '[' ']' {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += "[ ]";
   }
   | Types 'c' STRINGCONSTANT {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " c" + *$3;
     delete $3;
   }
   | Types '<' ConstVector '>' { // Nonempty unsized arr
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " < " + *$3 + " >";
     delete $3;
   }
   | Types '{' ConstVector '}' {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " { " + *$3 + " }";
     delete $3;
   }
   | Types '{' '}' {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " {}";
   }
   | Types NULL_TOK {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst +=  " " + *$2;
     delete $2;
   }
   | Types UNDEF {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   }
   | Types SymbolicValueRef {
+    std::string Name = getUniqueName($2,$1);
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
-    *$$.cnst += " " + *$2;
+    $$.cnst = new std::string($1->getNewTy());
+    *$$.cnst += " " + Name;
     delete $2;
   }
   | Types ConstExpr {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   }
   | Types ZEROINITIALIZER {
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   }
   | SIntType EInt64Val {      // integral constants
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   }
   | UIntType EUINT64VAL {            // integral constants
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   }
   | BOOL TRUETOK {                      // Boolean constants
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   }
   | BOOL FALSETOK {                     // Boolean constants
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   }
   | FPType FPVAL {                   // Float & Double constants
     $$.type = $1;
-    $$.cnst = new std::string(*$1.newTy);
+    $$.cnst = new std::string($1->getNewTy());
     *$$.cnst += " " + *$2;
     delete $2;
   };
@@ -652,17 +736,16 @@
 
 ConstExpr: CastOps '(' ConstVal TO Types ')' {
     std::string source = *$3.cnst;
-    TypeInfo DstTy = $5;
-    ResolveType(DstTy);
+    TypeInfo* DstTy = ResolveType($5);
     if (*$1 == "cast") {
       // Call getCastUpgrade to upgrade the old cast
-      $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
+      $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true));
     } else {
       // Nothing to upgrade, just create the cast constant expr
       $$ = new std::string(*$1);
-      *$$ += "( " + source + " to " + *$5.newTy + ")";
+      *$$ += "( " + source + " to " + $5->getNewTy() + ")";
     }
-    delete $1; $3.destroy(); delete $4; $5.destroy();
+    delete $1; $3.destroy(); delete $4; delete $5;
   }
   | GETELEMENTPTR '(' ConstVal IndexList ')' {
     *$1 += "(" + *$3.cnst;
@@ -711,7 +794,7 @@
   | ShiftOps '(' ConstVal ',' ConstVal ')' {
     const char* shiftop = $1->c_str();
     if (*$1 == "shr")
-      shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
+      shiftop = ($3.type->isUnsigned()) ? "lshr" : "ashr";
     $$ = new std::string(shiftop);
     *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
     delete $1; $3.destroy(); $5.destroy();
@@ -783,15 +866,13 @@
 
 // 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].newTy = new std::string(*$4.newTy);
-      NamedTypes[*$2].oldTy = $4.oldTy;
-      NamedTypes[*$2].elemTy = $4.elemTy;
+      NamedTypes[*$2] = *$4;
       *O << *$2 << " = ";
     }
-    *O << "type " << *$4.newTy << '\n';
-    delete $2; delete $3; $4.destroy();
+    *O << "type " << $4->getNewTy() << '\n';
+    delete $2; delete $3;
     $$ = 0;
   }
   | ConstPool FunctionProto {       // Function prototypes can be in const pool
@@ -806,38 +887,42 @@
   }
   | ConstPool OptAssign OptLinkage GlobalType ConstVal  GlobalVarAttributes {
     if (!$2->empty()) {
-      *O << *$2 << " = ";
-      Globals[*$2] = $5.type.clone();
+      std::string Name = getUniqueName($2,$5.type);
+      *O << Name << " = ";
+      Globals[Name] = *$5.type;
     }
     *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
-    delete $2; delete $3; delete $4; $5.destroy(); delete $6; 
+    delete $2; delete $3; delete $4; delete $6; 
     $$ = 0;
   }
   | ConstPool OptAssign External GlobalType Types  GlobalVarAttributes {
     if (!$2->empty()) {
-      *O << *$2 << " = ";
-      Globals[*$2] = $5.clone();
+      std::string Name = getUniqueName($2,$5);
+      *O << Name << " = ";
+      Globals[Name] = *$5;
     }
-    *O <<  *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
-    delete $2; delete $3; delete $4; $5.destroy(); delete $6;
+    *O <<  *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
+    delete $2; delete $3; delete $4; delete $6;
     $$ = 0;
   }
   | ConstPool OptAssign DLLIMPORT GlobalType Types  GlobalVarAttributes {
     if (!$2->empty()) {
-      *O << *$2 << " = ";
-      Globals[*$2] = $5.clone();
+      std::string Name = getUniqueName($2,$5);
+      *O << Name << " = ";
+      Globals[Name] = *$5;
     }
-    *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
-    delete $2; delete $3; delete $4; $5.destroy(); delete $6;
+    *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
+    delete $2; delete $3; delete $4; delete $6;
     $$ = 0;
   }
   | ConstPool OptAssign EXTERN_WEAK GlobalType Types  GlobalVarAttributes {
     if (!$2->empty()) {
-      *O << *$2 << " = ";
-      Globals[*$2] = $5.clone();
+      std::string Name = getUniqueName($2,$5);
+      *O << Name << " = ";
+      Globals[Name] = *$5;
     }
-    *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
-    delete $2; delete $3; delete $4; $5.destroy(); delete $6;
+    *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
+    delete $2; delete $3; delete $4; delete $6;
     $$ = 0;
   }
   | ConstPool TARGET TargetDefinition { 
@@ -909,9 +994,11 @@
 OptName : Name | /*empty*/ { $$ = new std::string(); };
 
 ArgVal : Types OptName {
-  $$ = $1.newTy;
-  if (!$2->empty())
-    *$$ += " " + *$2;
+  $$ = new std::string($1->getNewTy());
+  if (!$2->empty()) {
+    std::string Name = getUniqueName($2, $1);
+    *$$ += " " + Name;
+  }
   delete $2;
 };
 
@@ -941,14 +1028,13 @@
     if (!$1->empty()) {
       *$1 += " ";
     }
-    *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
+    *$1 += $2->getNewTy() + " " + *$3 + "(" + *$5 + ")";
     if (!$7->empty()) {
       *$1 += " " + *$7;
     }
     if (!$8->empty()) {
       *$1 += " " + *$8;
     }
-    $2.destroy();
     delete $3;
     delete $5;
     delete $7;
@@ -978,6 +1064,7 @@
   if ($2)
     *O << *$2;
   *O << *$3 << "\n\n";
+  delete $1; delete $2; delete $3;
   $$ = 0;
 };
 
@@ -1029,14 +1116,12 @@
   : SymbolicValueRef {
     $$.val = $1;
     $$.constant = false;
-    $$.type.newTy = 0;
-    $$.type.oldTy = UnresolvedTy;
+    $$.type = new TypeInfo();
   }
   | ConstValueRef {
     $$.val = $1;
     $$.constant = true;
-    $$.type.newTy = 0;
-    $$.type.oldTy = UnresolvedTy;
+    $$.type = new TypeInfo();
   }
   ;
 
@@ -1044,9 +1129,12 @@
 // 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 {
+    std::string Name = getUniqueName($2.val, $1);
     $$ = $2;
+    delete $$.val;
+    delete $$.type;
+    $$.val = new std::string($1->getNewTy() + " " + Name);
     $$.type = $1;
-    $$.val->insert(0, *$1.newTy + " ");
   };
 
 BasicBlockList : BasicBlockList BasicBlock {
@@ -1086,42 +1174,48 @@
     $$ = 0;
   }
   | RET VOID {                                       // Return with no result...
-    *O << "    " << *$1 << ' ' << *$2.newTy << '\n';
-    delete $1; $2.destroy();
+    *O << "    " << *$1 << ' ' << $2->getNewTy() << '\n';
+    delete $1; delete $2;
     $$ = 0;
   }
   | BR LABEL ValueRef {                         // Unconditional Branch...
-    *O << "    " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << '\n';
-    delete $1; $2.destroy(); $3.destroy();
+    *O << "    " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n';
+    delete $1; delete $2; $3.destroy();
     $$ = 0;
   }                                                  // Conditional Branch...
   | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {  
-    *O << "    " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", " 
-       << *$5.newTy << ' ' << *$6.val << ", " << *$8.newTy << ' ' 
+    std::string Name = getUniqueName($3.val, $2);
+    *O << "    " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", " 
+       << $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' ' 
        << *$9.val << '\n';
-    delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy(); 
-    $8.destroy(); $9.destroy();
+    delete $1; delete $2; $3.destroy(); delete $5; $6.destroy(); 
+    delete $8; $9.destroy();
     $$ = 0;
   }
   | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
-    *O << "    " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", " 
-       << *$5.newTy << ' ' << *$6.val << " [" << *$8 << " ]\n";
-    delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy(); 
+    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 $8;
     $$ = 0;
   }
   | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
-    *O << "    " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", " 
-       << *$5.newTy << ' ' << *$6.val << "[]\n";
-    delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
+    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();
     $$ = 0;
   }
   | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
     TO LABEL ValueRef Unwind LABEL ValueRef {
+    TypeInfo* ResTy = getFunctionReturnType($4);
     *O << "    ";
-    if (!$1->empty())
-      *O << *$1 << " = ";
-    *O << *$2 << ' ' << *$3 << ' ' << *$4.newTy << ' ' << *$5.val << " (";
+    if (!$1->empty()) {
+      std::string Name = getUniqueName($1, ResTy);
+      *O << Name << " = ";
+    }
+    *O << *$2 << ' ' << *$3 << ' ' << $4->getNewTy() << ' ' << *$5.val << " (";
     for (unsigned i = 0; i < $7->size(); ++i) {
       ValueInfo& VI = (*$7)[i];
       *O << *VI.val;
@@ -1129,10 +1223,10 @@
         *O << ", ";
       VI.destroy();
     }
-    *O << ") " << *$9 << ' ' << *$10.newTy << ' ' << *$11.val << ' ' 
-       << *$12 << ' ' << *$13.newTy << ' ' << *$14.val << '\n';
-    delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7; 
-    delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy(); 
+    *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(); 
     $$ = 0;
   }
@@ -1148,14 +1242,15 @@
   };
 
 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
-    *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
-    $2.destroy(); delete $3; $5.destroy(); $6.destroy();
+    *$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " + 
+           *$6.val;
+    delete $2; delete $3; delete $5; $6.destroy();
     $$ = $1;
   }
   | IntType ConstValueRef ',' LABEL ValueRef {
-    $2->insert(0, *$1.newTy + " " );
-    *$2 += ", " + *$4.newTy + " " + *$5.val;
-    $1.destroy(); $4.destroy(); $5.destroy();
+    $2->insert(0, $1->getNewTy() + " " );
+    *$2 += ", " + $4->getNewTy() + " " + *$5.val;
+    delete $1; delete $4; $5.destroy();
     $$ = $2;
   };
 
@@ -1167,38 +1262,41 @@
         $1->insert(0, "; "); // don't actually delete it, just comment it out
         delete deleteUselessCastName;
       } else {
-        *$1 += " = ";
+        // Get a unique name for the name of this value, based on its type.
+        *$1 = getUniqueName($1, $2.type) + " = ";
       }
     }
-    *$1 += *$2;
-    delete $2;
+    *$1 += *$2.val;
+    $2.destroy();
     deleteUselessCastFlag = false;
     $$ = $1; 
   };
 
 PHIList 
   : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
-    $3.val->insert(0, *$1.newTy + "[");
-    *$3.val += "," + *$5.val + "]";
-    $1.destroy(); $5.destroy();
-    $$ = new std::string(*$3.val);
-    $3.destroy();
+    std::string Name = getUniqueName($3.val, $1);
+    Name.insert(0, $1->getNewTy() + "[");
+    Name += "," + *$5.val + "]";
+    $$.val = new std::string(Name);
+    $$.type = $1;
+    $3.destroy(); $5.destroy();
   }
   | PHIList ',' '[' ValueRef ',' ValueRef ']' {
-    *$1 += ", [" + *$4.val + "," + *$6.val + "]";
+    std::string Name = getUniqueName($4.val, $1.type);
+    *$1.val += ", [" + Name + "," + *$6.val + "]";
     $4.destroy(); $6.destroy();
     $$ = $1;
   };
 
 
 ValueRefList 
-  : ResolvedVal { 
+  : ResolvedVal {
     $$ = new ValueList();
     $$->push_back($1);
   }
   | ValueRefList ',' ResolvedVal {
-    $1->push_back($3);
     $$ = $1;
+    $$->push_back($3);
   };
 
 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
@@ -1218,61 +1316,77 @@
 
 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     const char* op = getDivRemOpcode(*$1, $2); 
-    $$ = new std::string(op);
-    *$$ += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
-    delete $1; $2.destroy(); $3.destroy(); $5.destroy();
+    std::string Name1 = getUniqueName($3.val, $2);
+    std::string Name2 = getUniqueName($5.val, $2);
+    $$.val = new std::string(op);
+    *$$.val += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
+    $$.type = $2;
+    delete $1; $3.destroy(); $5.destroy();
   }
   | LogicalOps Types ValueRef ',' ValueRef {
-    *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
-    $2.destroy(); $3.destroy(); $5.destroy();
-    $$ = $1;
+    std::string Name1 = getUniqueName($3.val, $2);
+    std::string Name2 = getUniqueName($5.val, $2);
+    *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
+    $$.val = $1;
+    $$.type = $2;
+    $3.destroy(); $5.destroy();
   }
   | SetCondOps Types ValueRef ',' ValueRef {
+    std::string Name1 = getUniqueName($3.val, $2);
+    std::string Name2 = getUniqueName($5.val, $2);
     *$1 = getCompareOp(*$1, $2);
-    *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
-    $2.destroy(); $3.destroy(); $5.destroy();
-    $$ = $1;
+    *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
+    $$.val = $1;
+    $$.type = new TypeInfo("bool",BoolTy);
+    $3.destroy(); $5.destroy();
   }
   | ICMP IPredicates Types ValueRef ',' ValueRef {
-    *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val;
+    std::string Name1 = getUniqueName($4.val, $3);
+    std::string Name2 = getUniqueName($6.val, $3);
+    *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
+    $$.val = $1;
+    $$.type = new TypeInfo("bool",BoolTy);
     delete $2; $4.destroy(); $6.destroy();
-    $$ = $1;
   }
   | FCMP FPredicates Types ValueRef ',' ValueRef {
-    *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val;
+    std::string Name1 = getUniqueName($4.val, $3);
+    std::string Name2 = getUniqueName($6.val, $3);
+    *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
+    $$.val = $1;
+    $$.type = new TypeInfo("bool",BoolTy);
     delete $2; $4.destroy(); $6.destroy();
-    $$ = $1;
   }
   | NOT ResolvedVal {
-    *$1 += " " + *$2.val;
-    $2.destroy();
-    $$ = $1;
+    $$ = $2;
+    $$.val->insert(0, *$1 + " ");
+    delete $1;
   }
   | ShiftOps ResolvedVal ',' ResolvedVal {
     const char* shiftop = $1->c_str();
     if (*$1 == "shr")
-      shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
-    $$ = new std::string(shiftop);
-    *$$ += " " + *$2.val + ", " + *$4.val;
-    delete $1; $2.destroy(); $4.destroy();
+      shiftop = ($2.type->isUnsigned()) ? "lshr" : "ashr";
+    $$.val = new std::string(shiftop);
+    *$$.val += " " + *$2.val + ", " + *$4.val;
+    $$.type = $2.type;
+    delete $1; delete $2.val; $4.destroy();
   }
   | CastOps ResolvedVal TO Types {
     std::string source = *$2.val;
-    TypeInfo SrcTy = $2.type;
-    TypeInfo DstTy = $4;
-    ResolveType(DstTy);
-    $$ = new std::string();
+    TypeInfo* SrcTy = $2.type;
+    TypeInfo* DstTy = ResolveType($4);
+    $$.val = new std::string();
     if (*$1 == "cast") {
-      *$$ +=  getCastUpgrade(source, SrcTy, DstTy, false);
+      *$$.val +=  getCastUpgrade(source, SrcTy, DstTy, false);
     } else {
-      *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
+      *$$.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() && $4.isInteger() &&
-          $2.type.getBitWidth() == $4.getBitWidth()) {
+      if ($2.type->isInteger() && DstTy->isInteger() &&
+          $2.type->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);
@@ -1282,44 +1396,51 @@
         }
       }
     delete $1; $2.destroy();
-    delete $3; $4.destroy();
+    delete $3;
   }
   | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
     *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
-    $2.destroy(); $4.destroy(); $6.destroy();
-    $$ = $1;
+    $$.val = $1;
+    $$.type = $4.type;
+    $2.destroy(); delete $4.val; $6.destroy();
   }
   | VAARG ResolvedVal ',' Types {
-    *$1 += " " + *$2.val + ", " + *$4.newTy;
-    $2.destroy(); $4.destroy();
-    $$ = $1;
+    *$1 += " " + *$2.val + ", " + $4->getNewTy();
+    $$.val = $1;
+    $$.type = $4;
+    $2.destroy();
   }
   | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
     *$1 += " " + *$2.val + ", " + *$4.val;
-    $2.destroy(); $4.destroy();
-    $$ = $1;
+    $$.val = $1;
+    ResolveType($2.type);
+    $$.type = $2.type->getElementType()->clone();
+    delete $2.val; $4.destroy();
   }
   | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
     *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
-    $2.destroy(); $4.destroy(); $6.destroy();
-    $$ = $1;
+    $$.val = $1;
+    $$.type = $2.type;
+    delete $2.val; $4.destroy(); $6.destroy();
   }
   | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
     *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
-    $2.destroy(); $4.destroy(); $6.destroy();
-    $$ = $1;
+    $$.val = $1;
+    $$.type = $2.type;
+    delete $2.val; $4.destroy(); $6.destroy();
   }
   | PHI_TOK PHIList {
-    *$1 += " " + *$2;
-    delete $2;
-    $$ = $1;
+    *$1 += " " + *$2.val;
+    $$.val = $1;
+    $$.type = $2.type;
+    delete $2.val;
   }
   | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')'  {
     if (!$2->empty())
       *$1 += " " + *$2;
     if (!$1->empty())
       *$1 += " ";
-    *$1 += *$3.newTy + " " + *$4.val + "(";
+    *$1 += $3->getNewTy() + " " + *$4.val + "(";
     for (unsigned i = 0; i < $6->size(); ++i) {
       ValueInfo& VI = (*$6)[i];
       *$1 += *VI.val;
@@ -1328,8 +1449,9 @@
       VI.destroy();
     }
     *$1 += ")";
-    delete $2; $3.destroy(); $4.destroy(); delete $6;
-    $$ = $1;
+    $$.val = $1;
+    $$.type = getFunctionReturnType($3);
+    delete $2; delete $3; $4.destroy(); delete $6;
   }
   | MemoryInst ;
 
@@ -1346,74 +1468,85 @@
   ;
 
 MemoryInst : MALLOC Types OptCAlign {
-    *$1 += " " + *$2.newTy;
+    *$1 += " " + $2->getNewTy();
     if (!$3->empty())
       *$1 += " " + *$3;
-    $2.destroy(); delete $3;
-    $$ = $1;
+    $$.val = $1;
+    $$.type = $2->getPointerType();
+    delete $2; delete $3;
   }
   | MALLOC Types ',' UINT ValueRef OptCAlign {
-    *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
+    std::string Name = getUniqueName($5.val, $4);
+    *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
     if (!$6->empty())
       *$1 += " " + *$6;
-    $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
-    $$ = $1;
+    $$.val = $1;
+    $$.type = $2->getPointerType();
+    delete $2; delete $4; $5.destroy(); delete $6;
   }
   | ALLOCA Types OptCAlign {
-    *$1 += " " + *$2.newTy;
+    *$1 += " " + $2->getNewTy();
     if (!$3->empty())
       *$1 += " " + *$3;
-    $2.destroy(); delete $3;
-    $$ = $1;
+    $$.val = $1;
+    $$.type = $2->getPointerType();
+    delete $2; delete $3;
   }
   | ALLOCA Types ',' UINT ValueRef OptCAlign {
-    *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
+    std::string Name = getUniqueName($5.val, $4);
+    *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
     if (!$6->empty())
       *$1 += " " + *$6;
-    $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
-    $$ = $1;
+    $$.val = $1;
+    $$.type = $2->getPointerType();
+    delete $2; delete $4; $5.destroy(); delete $6;
   }
   | FREE ResolvedVal {
     *$1 += " " + *$2.val;
+    $$.val = $1;
+    $$.type = new TypeInfo("void", VoidTy); 
     $2.destroy();
-    $$ = $1;
   }
   | OptVolatile LOAD Types ValueRef {
+    std::string Name = getUniqueName($4.val, $3);
     if (!$1->empty())
       *$1 += " ";
-    *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
-    delete $2; $3.destroy(); $4.destroy();
-    $$ = $1;
+    *$1 += *$2 + " " + $3->getNewTy() + " " + Name;
+    $$.val = $1;
+    $$.type = $3->getElementType()->clone();
+    delete $2; delete $3; $4.destroy();
   }
   | OptVolatile STORE ResolvedVal ',' Types ValueRef {
+    std::string Name = getUniqueName($6.val, $5);
     if (!$1->empty())
       *$1 += " ";
-    *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
-    delete $2; $3.destroy(); $5.destroy(); $6.destroy();
-    $$ = $1;
+    *$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name;
+    $$.val = $1;
+    $$.type = new TypeInfo("void", VoidTy);
+    delete $2; $3.destroy(); delete $5; $6.destroy();
   }
   | GETELEMENTPTR Types ValueRef IndexList {
+    std::string Name = getUniqueName($3.val, $2);
     // Upgrade the indices
     for (unsigned i = 0; i < $4->size(); ++i) {
       ValueInfo& VI = (*$4)[i];
-      if (VI.type.isUnsigned() && !VI.isConstant() && 
-          VI.type.getBitWidth() < 64) {
+      if (VI.type->isUnsigned() && !VI.isConstant() && 
+          VI.type->getBitWidth() < 64) {
         std::string* old = VI.val;
         *O << "    %gep_upgrade" << unique << " = zext " << *old 
            << " to i64\n";
         VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
-        VI.type.oldTy = ULongTy;
-        delete old;
+        VI.type->setOldTy(ULongTy);
       }
     }
-    *$1 += " " + *$2.newTy + " " + *$3.val;
+    *$1 += " " + $2->getNewTy() + " " + Name;
     for (unsigned i = 0; i < $4->size(); ++i) {
       ValueInfo& VI = (*$4)[i];
       *$1 += ", " + *VI.val;
-      VI.destroy();
     }
-    $2.destroy(); $3.destroy(); delete $4;
-    $$ = $1;
+    $$.val = $1;
+    $$.type = getGEPIndexedType($2,$4); 
+    $3.destroy(); delete $4;
   };
 
 %%






More information about the llvm-commits mailing list