[llvm-commits] CVS: llvm/tools/llvm-upgrade/UpgradeParser.y

Reid Spencer reid at x10sys.com
Thu Feb 8 00:10:42 PST 2007



Changes in directory llvm/tools/llvm-upgrade:

UpgradeParser.y updated: 1.59 -> 1.60
---
Log message:

For PR1187: http://llvm.org/PR1187 :
Some changes to get the smbd.ll test case working:
1. Move the logic for CSRETCC->sret attribute out of the ResolveDefinitions
   code and into getExistingValue. This resolves it much earlier and works
   in function scope as well.
2. Fix handling of CSRETCC->sret for the store instruction.
3. Rewrite the code for handling renaming to factor in linkage types.
4. Rename a structure filed for a PATypeInfo* so it doesn't get confused 
   with a field for a Type*.


---
Diffs of the changes:  (+277 -253)

 UpgradeParser.y |  530 +++++++++++++++++++++++++++++---------------------------
 1 files changed, 277 insertions(+), 253 deletions(-)


Index: llvm/tools/llvm-upgrade/UpgradeParser.y
diff -u llvm/tools/llvm-upgrade/UpgradeParser.y:1.59 llvm/tools/llvm-upgrade/UpgradeParser.y:1.60
--- llvm/tools/llvm-upgrade/UpgradeParser.y:1.59	Wed Feb  7 18:21:06 2007
+++ llvm/tools/llvm-upgrade/UpgradeParser.y	Thu Feb  8 02:09:36 2007
@@ -171,7 +171,6 @@
   std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs;
   std::vector<BasicBlock*> NumberedBlocks;
   RenameMapType RenameMap;
-  unsigned LastCC;
   unsigned NextBBNum;
 
   inline PerFunctionInfo() {
@@ -268,6 +267,55 @@
   return Typ;
  }
 
+/// This function determines if two function types differ only in their use of
+/// the sret parameter attribute in the first argument. If they are identical 
+/// in all other respects, it returns true. Otherwise, it returns false.
+bool FuncTysDifferOnlyBySRet(const FunctionType *F1, 
+                                   const FunctionType *F2) {
+  if (F1->getReturnType() != F2->getReturnType() ||
+      F1->getNumParams() != F2->getNumParams() ||
+      F1->getParamAttrs(0) != F2->getParamAttrs(0))
+    return false;
+  unsigned SRetMask = ~unsigned(FunctionType::StructRetAttribute);
+  for (unsigned i = 0; i < F1->getNumParams(); ++i) {
+    if (F1->getParamType(i) != F2->getParamType(i) ||
+        unsigned(F1->getParamAttrs(i+1)) & SRetMask !=
+        unsigned(F2->getParamAttrs(i+1)) & SRetMask)
+      return false;
+  }
+  return true;
+}
+
+// The upgrade of csretcc to sret param attribute may have caused a function 
+// to not be found because the param attribute changed the type of the called 
+// function. This helper function, used in getExistingValue, detects that
+// situation and returns V if it occurs and 0 otherwise. 
+static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) {
+  // Handle degenerate cases
+  if (!V)
+    return 0;
+  if (V->getType() == Ty)
+    return V;
+
+  Value* Result = 0;
+  const PointerType *PF1 = dyn_cast<PointerType>(Ty);
+  const PointerType *PF2 = dyn_cast<PointerType>(V->getType());
+  if (PF1 && PF2) {
+    const FunctionType *FT1 =
+      dyn_cast<FunctionType>(PF1->getElementType());
+    const FunctionType *FT2 =
+      dyn_cast<FunctionType>(PF2->getElementType());
+    if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2))
+      if (FT2->paramHasAttr(1, FunctionType::StructRetAttribute))
+        Result = V;
+      else if (Constant *C = dyn_cast<Constant>(V))
+        Result = ConstantExpr::getBitCast(C, PF1);
+      else
+        Result = new BitCastInst(V, PF1, "upgrd.cast", CurBB);
+  }
+  return Result;
+}
+
 // getExistingValue - Look up the value specified by the provided type and
 // the provided ValID.  If the value exists and has already been defined, return
 // it.  Otherwise return null.
@@ -314,8 +362,7 @@
         LookupName = Name;
       ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable();
       V = SymTab.lookup(LookupName);
-      if (V && V->getType() != Ty)
-        V = 0;
+      V = handleSRetFuncTypeMerge(V, Ty);
     }
     if (!V) {
       RenameMapType::const_iterator I = CurModule.RenameMap.find(Key);
@@ -325,8 +372,7 @@
       else
         LookupName = Name;
       V = CurModule.CurrentModule->getValueSymbolTable().lookup(LookupName);
-      if (V && V->getType() != Ty)
-        V = 0;
+      V = handleSRetFuncTypeMerge(V, Ty);
     }
     if (!V) 
       return 0;
@@ -509,25 +555,6 @@
 // and back patchs after we are done.
 //
 
-/// This function determines if two function types differ only in their use of
-/// the sret parameter attribute in the first argument. If they are identical 
-/// in all other respects, it returns true. Otherwise, it returns false.
-bool FuncTysDifferOnlyBySRet(const FunctionType *F1, 
-                                   const FunctionType *F2) {
-  if (F1->getReturnType() != F2->getReturnType() ||
-      F1->getNumParams() != F2->getNumParams() ||
-      F1->getParamAttrs(0) != F2->getParamAttrs(0))
-    return false;
-  unsigned SRetMask = ~unsigned(FunctionType::StructRetAttribute);
-  for (unsigned i = 0; i < F1->getNumParams(); ++i) {
-    if (F1->getParamType(i) != F2->getParamType(i) ||
-        unsigned(F1->getParamAttrs(i+1)) & SRetMask !=
-        unsigned(F2->getParamAttrs(i+1)) & SRetMask)
-      return false;
-  }
-  return true;
-}
-
 // ResolveDefinitions - If we could not resolve some defs at parsing
 // time (forward branches, phi functions for loops, etc...) resolve the
 // defs now...
@@ -535,9 +562,11 @@
 static void 
 ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers,
                    std::map<const Type*,ValueList> *FutureLateResolvers) {
+
   // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
   for (std::map<const Type*,ValueList>::iterator LRI = LateResolvers.begin(),
          E = LateResolvers.end(); LRI != E; ++LRI) {
+    const Type* Ty = LRI->first;
     ValueList &List = LRI->second;
     while (!List.empty()) {
       Value *V = List.back();
@@ -549,7 +578,7 @@
 
       ValID &DID = PHI->second.first;
 
-      Value *TheRealValue = getExistingValue(LRI->first, DID);
+      Value *TheRealValue = getExistingValue(Ty, DID);
       if (TheRealValue) {
         V->replaceAllUsesWith(TheRealValue);
         delete V;
@@ -560,26 +589,10 @@
         InsertValue(V, *FutureLateResolvers);
       } else {
         if (DID.Type == ValID::NameVal) {
-          // The upgrade of csretcc to sret param attribute may have caused a
-          // function to not be found because the param attribute changed the 
-          // type of the called function. Detect this situation and insert a 
-          // cast as necessary.
-          bool fixed = false;
-          if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
-            if (const FunctionType *FTy =
-              dyn_cast<FunctionType>(PTy->getElementType()))
-              if (Function *OtherF =
-                CurModule.CurrentModule->getFunction(DID.getName()))
-                if (FuncTysDifferOnlyBySRet(FTy,OtherF->getFunctionType())) {
-                  V->replaceAllUsesWith(ConstantExpr::getBitCast(OtherF, PTy));
-                  fixed = true;
-                }
-          if (!fixed) {
-            error("Reference to an invalid definition: '" +DID.getName()+
-                  "' of type '" + V->getType()->getDescription() + "'",
-                  PHI->second.second);
+          error("Reference to an invalid definition: '" + DID.getName() +
+                "' of type '" + V->getType()->getDescription() + "'",
+                PHI->second.second);
             return;
-          }
         } else {
           error("Reference to an invalid definition: #" +
                 itostr(DID.Num) + " of type '" + 
@@ -1488,7 +1501,7 @@
 %type <BoolVal>       OptVolatile                 // 'volatile' or not
 %type <BoolVal>       OptTailCall                 // TAIL CALL or plain CALL.
 %type <BoolVal>       OptSideEffect               // 'sideeffect' or not.
-%type <Linkage>       OptLinkage
+%type <Linkage>       OptLinkage FnDeclareLinkage
 %type <Endianness>    BigOrLittle
 
 // ValueRef - Unresolved reference to a definition or BB
@@ -1666,13 +1679,13 @@
   ;
 
 OptCallingConv 
-  : /*empty*/          { CurFun.LastCC = $$ = OldCallingConv::C; } 
-  | CCC_TOK            { CurFun.LastCC = $$ = OldCallingConv::C; } 
-  | CSRETCC_TOK        { CurFun.LastCC = $$ = OldCallingConv::CSRet; } 
-  | FASTCC_TOK         { CurFun.LastCC = $$ = OldCallingConv::Fast; } 
-  | COLDCC_TOK         { CurFun.LastCC = $$ = OldCallingConv::Cold; } 
-  | X86_STDCALLCC_TOK  { CurFun.LastCC = $$ = OldCallingConv::X86_StdCall; } 
-  | X86_FASTCALLCC_TOK { CurFun.LastCC = $$ = OldCallingConv::X86_FastCall; } 
+  : /*empty*/          { $$ = OldCallingConv::C; } 
+  | CCC_TOK            { $$ = OldCallingConv::C; } 
+  | CSRETCC_TOK        { $$ = OldCallingConv::CSRet; } 
+  | FASTCC_TOK         { $$ = OldCallingConv::Fast; } 
+  | COLDCC_TOK         { $$ = OldCallingConv::Cold; } 
+  | X86_STDCALLCC_TOK  { $$ = OldCallingConv::X86_StdCall; } 
+  | X86_FASTCALLCC_TOK { $$ = OldCallingConv::X86_FastCall; } 
   | CC_TOK EUINT64VAL  {
     if ((unsigned)$2 != $2)
       error("Calling conv too large");
@@ -1745,7 +1758,7 @@
 TypesV    
   : Types
   | VOID { 
-    $$.T = new PATypeHolder($1.T); 
+    $$.PAT = new PATypeHolder($1.T); 
     $$.S = Signless;
   }
   ;
@@ -1753,7 +1766,7 @@
 UpRTypesV 
   : UpRTypes 
   | VOID { 
-    $$.T = new PATypeHolder($1.T); 
+    $$.PAT = new PATypeHolder($1.T); 
     $$.S = Signless;
   }
   ;
@@ -1761,7 +1774,7 @@
 Types
   : UpRTypes {
     if (!UpRefs.empty())
-      error("Invalid upreference in type: " + (*$1.T)->getDescription());
+      error("Invalid upreference in type: " + (*$1.PAT)->getDescription());
     $$ = $1;
   }
   ;
@@ -1774,16 +1787,16 @@
 // Derived types are added later...
 UpRTypes 
   : PrimType { 
-    $$.T = new PATypeHolder($1.T);
+    $$.PAT = new PATypeHolder($1.T);
     $$.S = $1.S;
   }
   | OPAQUE {
-    $$.T = new PATypeHolder(OpaqueType::get());
+    $$.PAT = new PATypeHolder(OpaqueType::get());
     $$.S = Signless;
   }
   | SymbolicValueRef {            // Named types are also simple types...
     const Type* tmp = getType($1);
-    $$.T = new PATypeHolder(tmp);
+    $$.PAT = new PATypeHolder(tmp);
     $$.S = Signless; // FIXME: what if its signed?
   }
   | '\\' EUINT64VAL {                   // Type UpReference
@@ -1791,7 +1804,7 @@
       error("Value out of range");
     OpaqueType *OT = OpaqueType::get();        // Use temporary placeholder
     UpRefs.push_back(UpRefRecord((unsigned)$2, OT));  // Add to vector...
-    $$.T = new PATypeHolder(OT);
+    $$.PAT = new PATypeHolder(OT);
     $$.S = Signless;
     UR_OUT("New Upreference!\n");
   }
@@ -1799,75 +1812,72 @@
     std::vector<const Type*> Params;
     for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(),
            E = $3->end(); I != E; ++I) {
-      Params.push_back(I->T->get());
+      Params.push_back(I->PAT->get());
     }
     FunctionType::ParamAttrsList ParamAttrs;
-    if (CurFun.LastCC == OldCallingConv::CSRet) {
-      ParamAttrs.push_back(FunctionType::NoAttributeSet);
-      ParamAttrs.push_back(FunctionType::StructRetAttribute);
-    }
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    $$.T = new PATypeHolder(
-      HandleUpRefs(FunctionType::get($1.T->get(),Params,isVarArg, ParamAttrs)));
+    $$.PAT = new PATypeHolder(
+      HandleUpRefs(FunctionType::get($1.PAT->get(), Params, isVarArg, 
+                   ParamAttrs)));
     $$.S = $1.S;
-    delete $1.T;    // Delete the return type handle
+    delete $1.PAT;    // Delete the return type handle
     delete $3;      // Delete the argument list
   }
   | '[' EUINT64VAL 'x' UpRTypes ']' {          // Sized array type?
-    $$.T = new PATypeHolder(HandleUpRefs(ArrayType::get($4.T->get(), 
+    $$.PAT = new PATypeHolder(HandleUpRefs(ArrayType::get($4.PAT->get(), 
                                                         (unsigned)$2)));
     $$.S = $4.S;
-    delete $4.T;
+    delete $4.PAT;
   }
   | '<' EUINT64VAL 'x' UpRTypes '>' {          // Packed array type?
-     const llvm::Type* ElemTy = $4.T->get();
+     const llvm::Type* ElemTy = $4.PAT->get();
      if ((unsigned)$2 != $2)
         error("Unsigned result not equal to signed result");
      if (!(ElemTy->isInteger() || ElemTy->isFloatingPoint()))
         error("Elements of a PackedType must be integer or floating point");
      if (!isPowerOf2_32($2))
        error("PackedType length should be a power of 2");
-     $$.T = new PATypeHolder(HandleUpRefs(PackedType::get(ElemTy, 
+     $$.PAT = new PATypeHolder(HandleUpRefs(PackedType::get(ElemTy, 
                                           (unsigned)$2)));
      $$.S = $4.S;
-     delete $4.T;
+     delete $4.PAT;
   }
   | '{' TypeListI '}' {                        // Structure type?
     std::vector<const Type*> Elements;
     for (std::list<llvm::PATypeInfo>::iterator I = $2->begin(),
            E = $2->end(); I != E; ++I)
-      Elements.push_back(I->T->get());
-    $$.T = new PATypeHolder(HandleUpRefs(StructType::get(Elements)));
+      Elements.push_back(I->PAT->get());
+    $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements)));
     $$.S = Signless;
     delete $2;
   }
   | '{' '}' {                                  // Empty structure type?
-    $$.T = new PATypeHolder(StructType::get(std::vector<const Type*>()));
+    $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>()));
     $$.S = Signless;
   }
   | '<' '{' TypeListI '}' '>' {                // Packed Structure type?
     std::vector<const Type*> Elements;
     for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(),
            E = $3->end(); I != E; ++I) {
-      Elements.push_back(I->T->get());
-      delete I->T;
+      Elements.push_back(I->PAT->get());
+      delete I->PAT;
     }
-    $$.T = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true)));
+    $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true)));
     $$.S = Signless;
     delete $3;
   }
   | '<' '{' '}' '>' {                          // Empty packed structure type?
-    $$.T = new PATypeHolder(StructType::get(std::vector<const Type*>(),true));
+    $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>(),true));
     $$.S = Signless;
   }
   | UpRTypes '*' {                             // Pointer type?
-    if ($1.T->get() == Type::LabelTy)
+    if ($1.PAT->get() == Type::LabelTy)
       error("Cannot form a pointer to a basic block");
-    $$.T = new PATypeHolder(HandleUpRefs(PointerType::get($1.T->get())));
+    $$.PAT = new PATypeHolder(HandleUpRefs(PointerType::get($1.PAT->get())));
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   ;
 
@@ -1889,14 +1899,14 @@
   : TypeListI
   | TypeListI ',' DOTDOTDOT {
     PATypeInfo VoidTI;
-    VoidTI.T = new PATypeHolder(Type::VoidTy);
+    VoidTI.PAT = new PATypeHolder(Type::VoidTy);
     VoidTI.S = Signless;
     ($$=$1)->push_back(VoidTI);
   }
   | DOTDOTDOT {
     $$ = new std::list<PATypeInfo>();
     PATypeInfo VoidTI;
-    VoidTI.T = new PATypeHolder(Type::VoidTy);
+    VoidTI.PAT = new PATypeHolder(Type::VoidTy);
     VoidTI.S = Signless;
     $$->push_back(VoidTI);
   }
@@ -1913,10 +1923,10 @@
 //
 ConstVal
   : Types '[' ConstVector ']' { // Nonempty unsized arr
-    const ArrayType *ATy = dyn_cast<ArrayType>($1.T->get());
+    const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
     if (ATy == 0)
       error("Cannot make array constant with type: '" + 
-            $1.T->get()->getDescription() + "'");
+            $1.PAT->get()->getDescription() + "'");
     const Type *ETy = ATy->getElementType();
     int NumElements = ATy->getNumElements();
 
@@ -1939,27 +1949,27 @@
     }
     $$.C = ConstantArray::get(ATy, Elems);
     $$.S = $1.S;
-    delete $1.T; 
+    delete $1.PAT; 
     delete $3;
   }
   | Types '[' ']' {
-    const ArrayType *ATy = dyn_cast<ArrayType>($1.T->get());
+    const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
     if (ATy == 0)
       error("Cannot make array constant with type: '" + 
-            $1.T->get()->getDescription() + "'");
+            $1.PAT->get()->getDescription() + "'");
     int NumElements = ATy->getNumElements();
     if (NumElements != -1 && NumElements != 0) 
       error("Type mismatch: constant sized array initialized with 0"
             " arguments, but has size of " + itostr(NumElements) +"");
     $$.C = ConstantArray::get(ATy, std::vector<Constant*>());
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | Types 'c' STRINGCONSTANT {
-    const ArrayType *ATy = dyn_cast<ArrayType>($1.T->get());
+    const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
     if (ATy == 0)
       error("Cannot make array constant with type: '" + 
-            $1.T->get()->getDescription() + "'");
+            $1.PAT->get()->getDescription() + "'");
     int NumElements = ATy->getNumElements();
     const Type *ETy = dyn_cast<IntegerType>(ATy->getElementType());
     if (!ETy || cast<IntegerType>(ETy)->getBitWidth() != 8)
@@ -1976,13 +1986,13 @@
     free($3);
     $$.C = ConstantArray::get(ATy, Vals);
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | Types '<' ConstVector '>' { // Nonempty unsized arr
-    const PackedType *PTy = dyn_cast<PackedType>($1.T->get());
+    const PackedType *PTy = dyn_cast<PackedType>($1.PAT->get());
     if (PTy == 0)
       error("Cannot make packed constant with type: '" + 
-            $1.T->get()->getDescription() + "'");
+            $1.PAT->get()->getDescription() + "'");
     const Type *ETy = PTy->getElementType();
     int NumElements = PTy->getNumElements();
     // Verify that we have the correct size...
@@ -2003,14 +2013,14 @@
     }
     $$.C = ConstantPacked::get(PTy, Elems);
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
     delete $3;
   }
   | Types '{' ConstVector '}' {
-    const StructType *STy = dyn_cast<StructType>($1.T->get());
+    const StructType *STy = dyn_cast<StructType>($1.PAT->get());
     if (STy == 0)
       error("Cannot make struct constant with type: '" + 
-            $1.T->get()->getDescription() + "'");
+            $1.PAT->get()->getDescription() + "'");
     if ($3->size() != STy->getNumContainedTypes())
       error("Illegal number of initializers for structure type");
 
@@ -2025,25 +2035,25 @@
     }
     $$.C = ConstantStruct::get(STy, Fields);
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
     delete $3;
   }
   | Types '{' '}' {
-    const StructType *STy = dyn_cast<StructType>($1.T->get());
+    const StructType *STy = dyn_cast<StructType>($1.PAT->get());
     if (STy == 0)
       error("Cannot make struct constant with type: '" + 
-              $1.T->get()->getDescription() + "'");
+              $1.PAT->get()->getDescription() + "'");
     if (STy->getNumContainedTypes() != 0)
       error("Illegal number of initializers for structure type");
     $$.C = ConstantStruct::get(STy, std::vector<Constant*>());
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | Types '<' '{' ConstVector '}' '>' {
-    const StructType *STy = dyn_cast<StructType>($1.T->get());
+    const StructType *STy = dyn_cast<StructType>($1.PAT->get());
     if (STy == 0)
       error("Cannot make packed struct constant with type: '" + 
-            $1.T->get()->getDescription() + "'");
+            $1.PAT->get()->getDescription() + "'");
     if ($4->size() != STy->getNumContainedTypes())
       error("Illegal number of initializers for packed structure type");
 
@@ -2058,39 +2068,39 @@
     }
     $$.C = ConstantStruct::get(STy, Fields);
     $$.S = $1.S;
-    delete $1.T; 
+    delete $1.PAT; 
     delete $4;
   }
   | Types '<' '{' '}' '>' {
-    const StructType *STy = dyn_cast<StructType>($1.T->get());
+    const StructType *STy = dyn_cast<StructType>($1.PAT->get());
     if (STy == 0)
       error("Cannot make packed struct constant with type: '" + 
-              $1.T->get()->getDescription() + "'");
+              $1.PAT->get()->getDescription() + "'");
     if (STy->getNumContainedTypes() != 0)
       error("Illegal number of initializers for packed structure type");
     $$.C = ConstantStruct::get(STy, std::vector<Constant*>());
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | Types NULL_TOK {
-    const PointerType *PTy = dyn_cast<PointerType>($1.T->get());
+    const PointerType *PTy = dyn_cast<PointerType>($1.PAT->get());
     if (PTy == 0)
       error("Cannot make null pointer constant with type: '" + 
-            $1.T->get()->getDescription() + "'");
+            $1.PAT->get()->getDescription() + "'");
     $$.C = ConstantPointerNull::get(PTy);
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | Types UNDEF {
-    $$.C = UndefValue::get($1.T->get());
+    $$.C = UndefValue::get($1.PAT->get());
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | Types SymbolicValueRef {
-    const PointerType *Ty = dyn_cast<PointerType>($1.T->get());
+    const PointerType *Ty = dyn_cast<PointerType>($1.PAT->get());
     if (Ty == 0)
       error("Global const reference must be a pointer type, not" +
-            $1.T->get()->getDescription());
+            $1.PAT->get()->getDescription());
 
     // ConstExprs can exist in the body of a function, thus creating
     // GlobalValues whenever they refer to a variable.  Because we are in
@@ -2142,22 +2152,22 @@
     }
     $$.C = cast<GlobalValue>(V);
     $$.S = $1.S;
-    delete $1.T;            // Free the type handle
+    delete $1.PAT;            // Free the type handle
   }
   | Types ConstExpr {
-    if ($1.T->get() != $2.C->getType())
+    if ($1.PAT->get() != $2.C->getType())
       error("Mismatched types for constant expression");
     $$ = $2;
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | Types ZEROINITIALIZER {
-    const Type *Ty = $1.T->get();
+    const Type *Ty = $1.PAT->get();
     if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || isa<OpaqueType>(Ty))
       error("Cannot create a null initialized value of this type");
     $$.C = Constant::getNullValue(Ty);
     $$.S = $1.S;
-    delete $1.T;
+    delete $1.PAT;
   }
   | SIntType EINT64VAL {      // integral constants
     const Type *Ty = $1.T;
@@ -2192,7 +2202,7 @@
 ConstExpr
   : CastOps '(' ConstVal TO Types ')' {
     const Type* SrcTy = $3.C->getType();
-    const Type* DstTy = $5.T->get();
+    const Type* DstTy = $5.PAT->get();
     Signedness SrcSign = $3.S;
     Signedness DstSign = $5.S;
     if (!SrcTy->isFirstClassType())
@@ -2203,7 +2213,7 @@
             DstTy->getDescription() + "'");
     $$.C = cast<Constant>(getCast($1, $3.C, SrcSign, DstTy, DstSign));
     $$.S = DstSign;
-    delete $5.T;
+    delete $5.PAT;
   }
   | GETELEMENTPTR '(' ConstVal IndexList ')' {
     const Type *Ty = $3.C->getType();
@@ -2385,7 +2395,7 @@
     // If types are not resolved eagerly, then the two types will not be
     // determined to be the same type!
     //
-    const Type* Ty = $4.T->get();
+    const Type* Ty = $4.PAT->get();
     ResolveTypeTo($2, Ty);
 
     if (!setTypeName(Ty, $2) && !$2) {
@@ -2393,7 +2403,7 @@
       // table.
       CurModule.Types.push_back(Ty);
     }
-    delete $4.T;
+    delete $4.PAT;
   }
   | ConstPool FunctionProto {       // Function prototypes can be in const pool
   }
@@ -2407,24 +2417,24 @@
     CurGV = 0;
   }
   | ConstPool OptAssign EXTERNAL GlobalType Types {
-    const Type *Ty = $5.T->get();
+    const Type *Ty = $5.PAT->get();
     CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, Ty, 0);
-    delete $5.T;
+    delete $5.PAT;
   } GlobalVarAttributes {
     CurGV = 0;
   }
   | ConstPool OptAssign DLLIMPORT GlobalType Types {
-    const Type *Ty = $5.T->get();
+    const Type *Ty = $5.PAT->get();
     CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0);
-    delete $5.T;
+    delete $5.PAT;
   } GlobalVarAttributes {
     CurGV = 0;
   }
   | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
-    const Type *Ty = $5.T->get();
+    const Type *Ty = $5.PAT->get();
     CurGV = 
       ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0);
-    delete $5.T;
+    delete $5.PAT;
   } GlobalVarAttributes {
     CurGV = 0;
   }
@@ -2508,7 +2518,7 @@
 
 ArgVal 
   : Types OptName {
-    if ($1.T->get() == Type::VoidTy)
+    if ($1.PAT->get() == Type::VoidTy)
       error("void typed arguments are invalid");
     $$ = new std::pair<PATypeInfo, char*>($1, $2);
   }
@@ -2532,14 +2542,14 @@
   | ArgListH ',' DOTDOTDOT {
     $$ = $1;
     PATypeInfo VoidTI;
-    VoidTI.T = new PATypeHolder(Type::VoidTy);
+    VoidTI.PAT = new PATypeHolder(Type::VoidTy);
     VoidTI.S = Signless;
     $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
   }
   | DOTDOTDOT {
     $$ = new std::vector<std::pair<PATypeInfo,char*> >();
     PATypeInfo VoidTI;
-    VoidTI.T = new PATypeHolder(Type::VoidTy);
+    VoidTI.PAT = new PATypeHolder(Type::VoidTy);
     VoidTI.S = Signless;
     $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
   }
@@ -2552,7 +2562,7 @@
     std::string FunctionName($3);
     free($3);  // Free strdup'd memory!
 
-    const Type* RetTy = $2.T->get();
+    const Type* RetTy = $2.PAT->get();
     
     if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
       error("LLVM functions cannot return aggregate types");
@@ -2570,7 +2580,7 @@
     } else if ($5) {   // If there are arguments...
       for (std::vector<std::pair<PATypeInfo,char*> >::iterator 
            I = $5->begin(), E = $5->end(); I != E; ++I) {
-        const Type *Ty = I->first.T->get();
+        const Type *Ty = I->first.PAT->get();
         ParamTyList.push_back(Ty);
       }
     }
@@ -2590,7 +2600,7 @@
     const FunctionType *FT = FunctionType::get(RetTy, ParamTyList, isVarArg,
                                                ParamAttrs);
     const PointerType *PFT = PointerType::get(FT);
-    delete $2.T;
+    delete $2.PAT;
 
     ValID ID;
     if (!FunctionName.empty()) {
@@ -2600,73 +2610,75 @@
     }
 
     Function *Fn = 0;
+    Module* M = CurModule.CurrentModule;
+
     // See if this function was forward referenced.  If so, recycle the object.
     if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) {
       // Move the function to the end of the list, from whereever it was 
       // previously inserted.
       Fn = cast<Function>(FWRef);
-      CurModule.CurrentModule->getFunctionList().remove(Fn);
-      CurModule.CurrentModule->getFunctionList().push_back(Fn);
-    } else if (!FunctionName.empty() &&     // Merge with an earlier prototype?
-               (Fn = CurModule.CurrentModule->getFunction(FunctionName))) {
-      if (Fn->getFunctionType() != FT ) {
-        // The existing function doesn't have the same type. Previously this was
-        // permitted because the symbol tables had "type planes" and names were
-        // distinct within a type plane. After PR411 was fixed, this is no
-        // longer the case. To resolve this we must rename this function.
-        // However, renaming it can cause problems if its linkage is external
-        // because it could cause a link failure. We warn about this.
-        std::string NewName = makeNameUnique(FunctionName);
-        warning("Renaming function '" + FunctionName + "' as '" + NewName +
-                "' may cause linkage errors");
-
-        Fn = new Function(FT, GlobalValue::ExternalLinkage, NewName,
-                          CurModule.CurrentModule);
-        InsertValue(Fn, CurModule.Values);
-        RenameMapKey Key = std::make_pair(FunctionName,PFT);
-        CurModule.RenameMap[Key] = NewName;
-      } else if (Fn->hasInternalLinkage()) {
-        // The function we are creating conflicts in name with another function 
-        // that has internal linkage. We'll rename that one quietly to get rid
-        // of the conflict.
-        Fn->setName(makeNameUnique(Fn->getName()));
-        RenameMapKey Key = std::make_pair(FunctionName,PFT);
-        CurModule.RenameMap[Key] = Fn->getName();
-
-        Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
-                          CurModule.CurrentModule);
-
-        InsertValue(Fn, CurModule.Values);
-      } else if (CurFun.Linkage == GlobalValue::InternalLinkage) {
-        // The function we are creating has internal linkage and conflicts with
-        // another function of the same name. We'll just rename this one 
-        // quietly because its internal linkage can't conflict with anything 
-        // else.  
-        std::string NewName = makeNameUnique(FunctionName);
-        Fn = new Function(FT, GlobalValue::ExternalLinkage, NewName,
-                          CurModule.CurrentModule);
-        InsertValue(Fn, CurModule.Values);
-        RenameMapKey Key = std::make_pair(FunctionName,PFT);
-        CurModule.RenameMap[Key] = NewName;
+      M->getFunctionList().remove(Fn);
+      M->getFunctionList().push_back(Fn);
+    } else if (!FunctionName.empty()) {
+      GlobalValue *Conflict = M->getFunction(FunctionName);
+      if (!Conflict)
+        Conflict = M->getNamedGlobal(FunctionName);
+      if (Conflict && PFT == Conflict->getType()) {
+        if (!CurFun.isDeclare && !Conflict->isDeclaration()) {
+          // We have two function definitions that conflict, same type, same
+          // name. This wasn't allowed in 1.9, its not allowed here either
+          error("Redefinition of function '" + FunctionName + "' of type '" +
+                PFT->getDescription() + "'");
+        
+        } else {
+          // If they are not both definitions, then just use the function we
+          // found since the types are the same.
+          Fn = cast<Function>(Conflict);
+
+          // Make sure to strip off any argument names so we can't get 
+          // conflicts.
+          if (Fn->isDeclaration())
+            for (Function::arg_iterator AI = Fn->arg_begin(), 
+                 AE = Fn->arg_end(); AI != AE; ++AI)
+              AI->setName("");
+        }
+      } else if (Conflict) {
+        // We have two globals with the same name and  different types. 
+        // Previously, this was permitted because the symbol table had 
+        // "type planes" and names only needed to be distinct within a 
+        // type plane. After PR411 was fixed, this is no loner the case. 
+        // To resolve this we must rename one of the two. 
+        if (Conflict->hasInternalLinkage()) {
+          // We can safely renamed the Conflict.
+          Conflict->setName(makeNameUnique(Conflict->getName()));
+          RenameMapKey Key = std::make_pair(FunctionName,Conflict->getType());
+          CurModule.RenameMap[Key] = Conflict->getName();
+          Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+          InsertValue(Fn, CurModule.Values);
+        } else if (CurFun.Linkage == GlobalValue::InternalLinkage) {
+          // We can safely rename the function we're defining
+          std::string NewName = makeNameUnique(FunctionName);
+          Fn = new Function(FT, CurFun.Linkage, NewName, M);
+          InsertValue(Fn, CurModule.Values);
+          RenameMapKey Key = std::make_pair(FunctionName,PFT);
+          CurModule.RenameMap[Key] = NewName;
+        } else {
+          // We can't quietly rename either of these things, but we must
+          // rename one of them. Generate a warning about the renaming and
+          // elect to rename the thing we're now defining.
+          std::string NewName = makeNameUnique(FunctionName);
+          warning("Renaming function '" + FunctionName + "' as '" + NewName +
+                  "' may cause linkage errors");
+          Fn = new Function(FT, CurFun.Linkage, NewName, M);
+          InsertValue(Fn, CurModule.Values);
+          RenameMapKey Key = std::make_pair(FunctionName,PFT);
+          CurModule.RenameMap[Key] = NewName;
+        }
       } else {
-        // The types are the same and they are both external linkage. Either 
-        // the existing or the current function needs to be a forward 
-        // declaration. If not, they're attempting to redefine two external 
-        // functions. This wasn't allowed in llvm 1.9 and it isn't allowed now.
-        if (!CurFun.isDeclare && !Fn->isDeclaration())
-          error("Redefinition of function '" + FunctionName + "'");
-      
-        // Make sure to strip off any argument names so we can't get conflicts.
-        if (Fn->isDeclaration())
-          for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end();
-               AI != AE; ++AI)
-            AI->setName("");
-      }
-    } else {  // Not already defined?
-      Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
-                        CurModule.CurrentModule);
-
-      InsertValue(Fn, CurModule.Values);
+        // There's no conflict, just define the function
+        Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+        InsertValue(Fn, CurModule.Values);
+      }
     }
 
     CurFun.FunctionStart(Fn);
@@ -2687,9 +2699,9 @@
     // Add all of the arguments we parsed to the function...
     if ($5) {                     // Is null if empty...
       if (isVarArg) {  // Nuke the last entry
-        assert($5->back().first.T->get() == Type::VoidTy && 
+        assert($5->back().first.PAT->get() == Type::VoidTy && 
                $5->back().second == 0 && "Not a varargs marker");
-        delete $5->back().first.T;
+        delete $5->back().first.PAT;
         $5->pop_back();  // Delete the last entry
       }
       Function::arg_iterator ArgIt = Fn->arg_begin();
@@ -2697,7 +2709,7 @@
       std::vector<std::pair<PATypeInfo,char*> >::iterator I = $5->begin();
       std::vector<std::pair<PATypeInfo,char*> >::iterator E = $5->end();
       for ( ; I != E && ArgIt != ArgEnd; ++I, ++ArgIt) {
-        delete I->first.T;                        // Delete the typeholder...
+        delete I->first.PAT;                      // Delete the typeholder...
         setValueName(ArgIt, I->second);           // Insert arg into symtab...
         InsertValue(ArgIt);
       }
@@ -2730,13 +2742,14 @@
   };
 
 FnDeclareLinkage
-  : /*default*/ 
-  | DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage; } 
-  | EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; }
+  : /*default*/ { $$ = GlobalValue::ExternalLinkage; }
+  | DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } 
+  | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
   ;
   
 FunctionProto 
-  : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
+  : DECLARE { CurFun.isDeclare = true; } 
+     FnDeclareLinkage { CurFun.Linkage = $3; } FunctionHeaderH {
     $$ = CurFun.CurrentFunction;
     CurFun.FunctionDone();
     
@@ -2816,10 +2829,10 @@
 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
 ResolvedVal 
   : Types ValueRef { 
-    const Type *Ty = $1.T->get();
+    const Type *Ty = $1.PAT->get();
     $$.S = $1.S;
     $$.V = getVal(Ty, $2); 
-    delete $1.T;
+    delete $1.PAT;
   }
   ;
 
@@ -2916,7 +2929,7 @@
     const PointerType *PFTy;
     const FunctionType *Ty;
 
-    if (!(PFTy = dyn_cast<PointerType>($3.T->get())) ||
+    if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) ||
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
@@ -2932,7 +2945,7 @@
       }
       bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
       if (isVarArg) ParamTypes.pop_back();
-      Ty = FunctionType::get($3.T->get(), ParamTypes, isVarArg, ParamAttrs);
+      Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, ParamAttrs);
       PFTy = PointerType::get(Ty);
     }
     Value *V = getVal(PFTy, $4);   // Get the function we're calling...
@@ -2964,7 +2977,7 @@
       $$ = new InvokeInst(V, Normal, Except, Args);
     }
     cast<InvokeInst>($$)->setCallingConv(upgradeCallingConv($2));
-    delete $3.T;
+    delete $3.PAT;
     delete $6;
   }
   | Unwind {
@@ -3031,10 +3044,10 @@
 PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
     $$.P = new std::list<std::pair<Value*, BasicBlock*> >();
     $$.S = $1.S;
-    Value* tmpVal = getVal($1.T->get(), $3);
+    Value* tmpVal = getVal($1.PAT->get(), $3);
     BasicBlock* tmpBB = getBBVal($5);
     $$.P->push_back(std::make_pair(tmpVal, tmpBB));
-    delete $1.T;
+    delete $1.PAT;
   }
   | PHIList ',' '[' ValueRef ',' ValueRef ']' {
     $$ = $1;
@@ -3070,7 +3083,7 @@
 
 InstVal 
   : ArithmeticOps Types ValueRef ',' ValueRef {
-    const Type* Ty = $2.T->get();
+    const Type* Ty = $2.PAT->get();
     if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa<PackedType>(Ty))
       error("Arithmetic operator requires integer, FP, or packed operands");
     if (isa<PackedType>(Ty) && 
@@ -3084,10 +3097,10 @@
     if ($$.I == 0)
       error("binary operator returned null");
     $$.S = $2.S;
-    delete $2.T;
+    delete $2.PAT;
   }
   | LogicalOps Types ValueRef ',' ValueRef {
-    const Type *Ty = $2.T->get();
+    const Type *Ty = $2.PAT->get();
     if (!Ty->isInteger()) {
       if (!isa<PackedType>(Ty) ||
           !cast<PackedType>(Ty)->getElementType()->isInteger())
@@ -3100,10 +3113,10 @@
     if ($$.I == 0)
       error("binary operator returned null");
     $$.S = $2.S;
-    delete $2.T;
+    delete $2.PAT;
   }
   | SetCondOps Types ValueRef ',' ValueRef {
-    const Type* Ty = $2.T->get();
+    const Type* Ty = $2.PAT->get();
     if(isa<PackedType>(Ty))
       error("PackedTypes currently not supported in setcc instructions");
     unsigned short pred;
@@ -3114,10 +3127,10 @@
     if ($$.I == 0)
       error("binary operator returned null");
     $$.S = Unsigned;
-    delete $2.T;
+    delete $2.PAT;
   }
   | ICMP IPredicates Types ValueRef ',' ValueRef {
-    const Type *Ty = $3.T->get();
+    const Type *Ty = $3.PAT->get();
     if (isa<PackedType>(Ty)) 
       error("PackedTypes currently not supported in icmp instructions");
     else if (!Ty->isInteger() && !isa<PointerType>(Ty))
@@ -3126,10 +3139,10 @@
     Value* tmpVal2 = getVal(Ty, $6);
     $$.I = new ICmpInst($2, tmpVal1, tmpVal2);
     $$.S = Unsigned;
-    delete $3.T;
+    delete $3.PAT;
   }
   | FCMP FPredicates Types ValueRef ',' ValueRef {
-    const Type *Ty = $3.T->get();
+    const Type *Ty = $3.PAT->get();
     if (isa<PackedType>(Ty))
       error("PackedTypes currently not supported in fcmp instructions");
     else if (!Ty->isFloatingPoint())
@@ -3138,7 +3151,7 @@
     Value* tmpVal2 = getVal(Ty, $6);
     $$.I = new FCmpInst($2, tmpVal1, tmpVal2);
     $$.S = Unsigned;
-    delete $3.T;
+    delete $3.PAT;
   }
   | NOT ResolvedVal {
     warning("Use of obsolete 'not' instruction: Replacing with 'xor");
@@ -3170,13 +3183,13 @@
     $$.S = $2.S;
   }
   | CastOps ResolvedVal TO Types {
-    const Type *DstTy = $4.T->get();
+    const Type *DstTy = $4.PAT->get();
     if (!DstTy->isFirstClassType())
       error("cast instruction to a non-primitive type: '" +
             DstTy->getDescription() + "'");
     $$.I = cast<Instruction>(getCast($1, $2.V, $2.S, DstTy, $4.S, true));
     $$.S = $4.S;
-    delete $4.T;
+    delete $4.PAT;
   }
   | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
     if (!$2.V->getType()->isInteger() ||
@@ -3188,15 +3201,15 @@
     $$.S = $2.S;
   }
   | VAARG ResolvedVal ',' Types {
-    const Type *Ty = $4.T->get();
+    const Type *Ty = $4.PAT->get();
     NewVarArgs = true;
     $$.I = new VAArgInst($2.V, Ty);
     $$.S = $4.S;
-    delete $4.T;
+    delete $4.PAT;
   }
   | VAARG_old ResolvedVal ',' Types {
     const Type* ArgTy = $2.V->getType();
-    const Type* DstTy = $4.T->get();
+    const Type* DstTy = $4.PAT->get();
     ObsoleteVarArgs = true;
     Function* NF = cast<Function>(CurModule.CurrentModule->
       getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
@@ -3213,11 +3226,11 @@
     CurBB->getInstList().push_back(new StoreInst(bar, foo));
     $$.I = new VAArgInst(foo, DstTy);
     $$.S = $4.S;
-    delete $4.T;
+    delete $4.PAT;
   }
   | VANEXT_old ResolvedVal ',' Types {
     const Type* ArgTy = $2.V->getType();
-    const Type* DstTy = $4.T->get();
+    const Type* DstTy = $4.PAT->get();
     ObsoleteVarArgs = true;
     Function* NF = cast<Function>(CurModule.CurrentModule->
       getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
@@ -3237,7 +3250,7 @@
     CurBB->getInstList().push_back(tmp);
     $$.I = new LoadInst(foo);
     $$.S = $4.S;
-    delete $4.T;
+    delete $4.PAT;
   }
   | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
     if (!ExtractElementInst::isValidOperands($2.V, $4.V))
@@ -3278,7 +3291,7 @@
     // Handle the short call syntax
     const PointerType *PFTy;
     const FunctionType *FTy;
-    if (!(PFTy = dyn_cast<PointerType>($3.T->get())) ||
+    if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) ||
         !(FTy = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
@@ -3296,7 +3309,7 @@
       bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
       if (isVarArg) ParamTypes.pop_back();
 
-      const Type *RetTy = $3.T->get();
+      const Type *RetTy = $3.PAT->get();
       if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
         error("Functions cannot return aggregate types");
 
@@ -3348,7 +3361,7 @@
       $$.I = CI;
       $$.S = $3.S;
     }
-    delete $3.T;
+    delete $3.PAT;
     delete $6;
   }
   | MemoryInst {
@@ -3370,28 +3383,28 @@
 
 MemoryInst 
   : MALLOC Types OptCAlign {
-    const Type *Ty = $2.T->get();
+    const Type *Ty = $2.PAT->get();
     $$.S = $2.S;
     $$.I = new MallocInst(Ty, 0, $3);
-    delete $2.T;
+    delete $2.PAT;
   }
   | MALLOC Types ',' UINT ValueRef OptCAlign {
-    const Type *Ty = $2.T->get();
+    const Type *Ty = $2.PAT->get();
     $$.S = $2.S;
     $$.I = new MallocInst(Ty, getVal($4.T, $5), $6);
-    delete $2.T;
+    delete $2.PAT;
   }
   | ALLOCA Types OptCAlign {
-    const Type *Ty = $2.T->get();
+    const Type *Ty = $2.PAT->get();
     $$.S = $2.S;
     $$.I = new AllocaInst(Ty, 0, $3);
-    delete $2.T;
+    delete $2.PAT;
   }
   | ALLOCA Types ',' UINT ValueRef OptCAlign {
-    const Type *Ty = $2.T->get();
+    const Type *Ty = $2.PAT->get();
     $$.S = $2.S;
     $$.I = new AllocaInst(Ty, getVal($4.T, $5), $6);
-    delete $2.T;
+    delete $2.PAT;
   }
   | FREE ResolvedVal {
     const Type *PTy = $2.V->getType();
@@ -3401,7 +3414,7 @@
     $$.S = Signless;
   }
   | OptVolatile LOAD Types ValueRef {
-    const Type* Ty = $3.T->get();
+    const Type* Ty = $3.PAT->get();
     $$.S = $3.S;
     if (!isa<PointerType>(Ty))
       error("Can't load from nonpointer type: " + Ty->getDescription());
@@ -3410,24 +3423,35 @@
                      Ty->getDescription());
     Value* tmpVal = getVal(Ty, $4);
     $$.I = new LoadInst(tmpVal, "", $1);
-    delete $3.T;
+    delete $3.PAT;
   }
   | OptVolatile STORE ResolvedVal ',' Types ValueRef {
-    const PointerType *PTy = dyn_cast<PointerType>($5.T->get());
+    const PointerType *PTy = dyn_cast<PointerType>($5.PAT->get());
     if (!PTy)
       error("Can't store to a nonpointer type: " + 
-             $5.T->get()->getDescription());
+             $5.PAT->get()->getDescription());
     const Type *ElTy = PTy->getElementType();
-    if (ElTy != $3.V->getType())
-      error("Can't store '" + $3.V->getType()->getDescription() +
-            "' into space of type '" + ElTy->getDescription() + "'");
+    Value *StoreVal = $3.V;
     Value* tmpVal = getVal(PTy, $6);
-    $$.I = new StoreInst($3.V, tmpVal, $1);
+    if (ElTy != $3.V->getType()) {
+      StoreVal = handleSRetFuncTypeMerge($3.V, ElTy);
+      if (!StoreVal)
+        error("Can't store '" + $3.V->getType()->getDescription() +
+              "' into space of type '" + ElTy->getDescription() + "'");
+      else {
+        PTy = PointerType::get(StoreVal->getType());
+        if (Constant *C = dyn_cast<Constant>(tmpVal))
+          tmpVal = ConstantExpr::getBitCast(C, PTy);
+        else
+          tmpVal = new BitCastInst(tmpVal, PTy, "upgrd.cast", CurBB);
+      }
+    }
+    $$.I = new StoreInst(StoreVal, tmpVal, $1);
     $$.S = Signless;
-    delete $5.T;
+    delete $5.PAT;
   }
   | GETELEMENTPTR Types ValueRef IndexList {
-    const Type* Ty = $2.T->get();
+    const Type* Ty = $2.PAT->get();
     if (!isa<PointerType>(Ty))
       error("getelementptr insn requires pointer operand");
 
@@ -3437,7 +3461,7 @@
     Value* tmpVal = getVal(Ty, $3);
     $$.I = new GetElementPtrInst(tmpVal, VIndices);
     $$.S = Signless;
-    delete $2.T;
+    delete $2.PAT;
     delete $4;
   };
 
@@ -3447,7 +3471,7 @@
 int yyerror(const char *ErrorMsg) {
   std::string where 
     = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
-                  + ":" + llvm::utostr((unsigned) Upgradelineno-1) + ": ";
+                  + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
   std::string errMsg = where + "error: " + std::string(ErrorMsg);
   if (yychar != YYEMPTY && yychar != 0)
     errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +
@@ -3460,7 +3484,7 @@
 void warning(const std::string& ErrorMsg) {
   std::string where 
     = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
-                  + ":" + llvm::utostr((unsigned) Upgradelineno-1) + ": ";
+                  + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
   std::string errMsg = where + "warning: " + std::string(ErrorMsg);
   if (yychar != YYEMPTY && yychar != 0)
     errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +






More information about the llvm-commits mailing list