Cleanup of the [SU]ADDO type legalization code. Patch by Duncan!
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y
index 9b4c1aeb1546755058735970b47c4f5ed68743ff..af8e3afee3f6213abce006c314634c24dbac03af 100644 (file)
@@ -140,6 +140,7 @@ static struct PerModuleInfo {
     GlobalValue *Ret = 0;
     if (I != GlobalRefs.end()) {
       Ret = I->second;
+      I->first.second.destroy();
       GlobalRefs.erase(I);
     }
     return Ret;
@@ -307,8 +308,10 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
   }
 
   std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D);
-  if (I != CurModule.LateResolveTypes.end())
+  if (I != CurModule.LateResolveTypes.end()) {
+    D.destroy();
     return I->second;
+  }
 
   Type *Typ = OpaqueType::get();
   CurModule.LateResolveTypes.insert(std::make_pair(D, Typ));
@@ -415,6 +418,7 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
 
     {
       APSInt Tmp = *D.ConstPoolInt;
+      D.destroy();
       Tmp.extOrTrunc(Ty->getPrimitiveSizeInBits());
       return ConstantInt::get(Tmp);
     }
@@ -428,9 +432,16 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
     // Lexer has no type info, so builds all float and double FP constants
     // as double.  Fix this here.  Long double does not need this.
     if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble &&
-        Ty==Type::FloatTy)
-      D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
-    return ConstantFP::get(*D.ConstPoolFP);
+        Ty==Type::FloatTy) {
+      bool ignored;
+      D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+                             &ignored);
+    }
+    {
+      ConstantFP *tmp = ConstantFP::get(*D.ConstPoolFP);
+      D.destroy();
+      return tmp;
+    }
 
   case ValID::ConstNullVal:      // Is it a null value?
     if (!isa<PointerType>(Ty)) {
@@ -705,8 +716,10 @@ static void ResolveTypeTo(std::string *Name, const Type *ToTy) {
     CurModule.LateResolveTypes.find(D);
   if (I != CurModule.LateResolveTypes.end()) {
     ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy);
+    I->first.destroy();
     CurModule.LateResolveTypes.erase(I);
   }
+  D.destroy();
 }
 
 // setValueName - Set the specified value to the name given.  The name may be
@@ -782,9 +795,12 @@ ParseGlobalVariable(std::string *NameStr,
     GV->setConstant(isConstantGlobal);
     GV->setThreadLocal(IsThreadLocal);
     InsertValue(GV, CurModule.Values);
+    ID.destroy();
     return GV;
   }
 
+  ID.destroy();
+
   // If this global has a name
   if (!Name.empty()) {
     // if the global we're parsing has an initializer (is a definition) and
@@ -994,7 +1010,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 
   llvm::GlobalValue::LinkageTypes         Linkage;
   llvm::GlobalValue::VisibilityTypes      Visibility;
-  llvm::Attributes                  ParamAttrs;
+  llvm::Attributes                  Attributes;
   llvm::APInt                       *APIntVal;
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
@@ -1064,7 +1080,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 
 // Built in types...
 %type  <TypeVal> Types ResultTypes
-%type  <PrimType> IntType FPType PrimType           // Classifications
+%type  <PrimType> PrimType           // Classifications
 %token <PrimType> VOID INTTYPE
 %token <PrimType> FLOAT DOUBLE X86_FP80 FP128 PPC_FP128 LABEL
 %token TYPE
@@ -1085,13 +1101,11 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE
 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
 %token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
-%token X86_SSECALLCC_TOK
 %token DATALAYOUT
 %type <UIntVal> OptCallingConv LocalNumber
-%type <ParamAttrs> OptParamAttrs ParamAttr
-%type <ParamAttrs> OptFuncAttrs  FuncAttr
-%type <ParamAttrs> OptFuncNotes FuncNote
-%type <ParamAttrs> FuncNoteList
+%type <Attributes> OptAttributes Attribute
+%type <Attributes> OptFuncAttrs  FuncAttr
+%type <Attributes> OptRetAttrs  RetAttr
 
 // Basic Block Terminating Operators
 %token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
@@ -1123,10 +1137,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 
 // Function Attributes
 %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
-%token READNONE READONLY GC
-
-// Function Notes
-%token FNNOTE INLINE ALWAYS NEVER OPTIMIZEFORSIZE
+%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ
 
 // Visibility Styles
 %token DEFAULT HIDDEN PROTECTED
@@ -1163,11 +1174,6 @@ FPredicates
   | FALSETOK { $$ = FCmpInst::FCMP_FALSE; }
   ;
 
-// These are some types that allow classification if we only want a particular
-// thing... for example, only a signed, unsigned, or integral type.
-IntType :  INTTYPE;
-FPType   : FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80;
-
 LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
 OptLocalName : LocalName | /*empty*/ { $$ = 0; };
 
@@ -1252,7 +1258,6 @@ OptCallingConv : /*empty*/          { $$ = CallingConv::C; } |
                  COLDCC_TOK         { $$ = CallingConv::Cold; } |
                  X86_STDCALLCC_TOK  { $$ = CallingConv::X86_StdCall; } |
                  X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } |
-                 X86_SSECALLCC_TOK  { $$ = CallingConv::X86_SSECall; } |
                  CC_TOK EUINT64VAL  {
                    if ((unsigned)$2 != $2)
                      GEN_ERROR("Calling conv too large");
@@ -1260,64 +1265,57 @@ OptCallingConv : /*empty*/          { $$ = CallingConv::C; } |
                   CHECK_FOR_ERROR
                  };
 
-ParamAttr     : ZEROEXT { $$ = ParamAttr::ZExt;      }
-              | ZEXT    { $$ = ParamAttr::ZExt;      }
-              | SIGNEXT { $$ = ParamAttr::SExt;      }
-              | SEXT    { $$ = ParamAttr::SExt;      }
-              | INREG   { $$ = ParamAttr::InReg;     }
-              | SRET    { $$ = ParamAttr::StructRet; }
-              | NOALIAS { $$ = ParamAttr::NoAlias;   }
-              | BYVAL   { $$ = ParamAttr::ByVal;     }
-              | NEST    { $$ = ParamAttr::Nest;      }
+Attribute     : ZEROEXT { $$ = Attribute::ZExt;      }
+              | ZEXT    { $$ = Attribute::ZExt;      }
+              | SIGNEXT { $$ = Attribute::SExt;      }
+              | SEXT    { $$ = Attribute::SExt;      }
+              | INREG   { $$ = Attribute::InReg;     }
+              | SRET    { $$ = Attribute::StructRet; }
+              | NOALIAS { $$ = Attribute::NoAlias;   }
+              | BYVAL   { $$ = Attribute::ByVal;     }
+              | NEST    { $$ = Attribute::Nest;      }
               | ALIGN EUINT64VAL { $$ =
-                          ParamAttr::constructAlignmentFromInt($2);    }
+                          Attribute::constructAlignmentFromInt($2);    }
               ;
 
-OptParamAttrs : /* empty */  { $$ = ParamAttr::None; }
-              | OptParamAttrs ParamAttr {
+OptAttributes : /* empty */  { $$ = Attribute::None; }
+              | OptAttributes Attribute {
                 $$ = $1 | $2;
               }
               ;
 
-FuncAttr      : NORETURN { $$ = ParamAttr::NoReturn; }
-              | NOUNWIND { $$ = ParamAttr::NoUnwind; }
-              | INREG    { $$ = ParamAttr::InReg;     }
-              | ZEROEXT  { $$ = ParamAttr::ZExt;     }
-              | SIGNEXT  { $$ = ParamAttr::SExt;     }
-              | READNONE { $$ = ParamAttr::ReadNone; }
-              | READONLY { $$ = ParamAttr::ReadOnly; }
+RetAttr       : INREG    { $$ = Attribute::InReg;     }
+              | ZEROEXT  { $$ = Attribute::ZExt;     }
+              | SIGNEXT  { $$ = Attribute::SExt;     }
               ;
 
-OptFuncAttrs  : /* empty */ { $$ = ParamAttr::None; }
-              | OptFuncAttrs FuncAttr {
-                $$ = $1 | $2;
-              }
+OptRetAttrs  : /* empty */ { $$ = Attribute::None; }
+             | OptRetAttrs RetAttr {
+               $$ = $1 | $2;
+             }
+             ;
+
+
+FuncAttr      : NORETURN { $$ = Attribute::NoReturn; }
+              | NOUNWIND { $$ = Attribute::NoUnwind; }
+              | INREG    { $$ = Attribute::InReg;     }
+              | ZEROEXT  { $$ = Attribute::ZExt;     }
+              | SIGNEXT  { $$ = Attribute::SExt;     }
+              | READNONE { $$ = Attribute::ReadNone; }
+              | READONLY { $$ = Attribute::ReadOnly; }
+              | NOINLINE { $$ = Attribute::NoInline; }
+              | ALWAYSINLINE { $$ = Attribute::AlwaysInline; }
+              | OPTSIZE  { $$ = Attribute::OptimizeForSize; }
+              | SSP      { $$ = Attribute::StackProtect; }
+              | SSPREQ   { $$ = Attribute::StackProtectReq; }
               ;
 
-FuncNoteList  : FuncNote { $$ = $1; }
-              | FuncNoteList ',' FuncNote {
-                unsigned tmp = $1 | $3;
-                if ($3 == FnAttr::NoInline
-                    && ($1 & FnAttr::AlwaysInline))
-                  GEN_ERROR("Function Notes may include only one inline notes!")
-                    if ($3 == FnAttr::AlwaysInline
-                        && ($1 & FnAttr::NoInline))
-                  GEN_ERROR("Function Notes may include only one inline notes!")
-                $$ = tmp;
-                CHECK_FOR_ERROR
+OptFuncAttrs  : /* empty */ { $$ = Attribute::None; }
+              | OptFuncAttrs FuncAttr {
+                $$ = $1 | $2;
               }
               ;
 
-FuncNote      : INLINE '=' NEVER { $$ = FnAttr::NoInline; }
-              | INLINE '=' ALWAYS { $$ = FnAttr::AlwaysInline; }
-              | OPTIMIZEFORSIZE { $$ = FnAttr::OptimizeForSize; }
-              ;
-
-OptFuncNotes  : /* empty */ { $$ = FnAttr::None; }
-              | FNNOTE '(' FuncNoteList  ')' {
-                $$ =  $3;
-              }
-              ;
 
 OptGC         : /* empty */ { $$ = 0; }
               | GC STRINGCONSTANT {
@@ -1433,9 +1431,15 @@ Types
     CHECK_FOR_ERROR
 
     FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg);
-    delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
     $$ = new PATypeHolder(HandleUpRefs(FT));
+
+    // Delete the argument list
+    for (I = $3->begin() ; I != E; ++I ) {
+      delete I->Ty;
+    }
+    delete $3;
+
     CHECK_FOR_ERROR
   }
   | VOID '(' ArgTypeListI ')' OptFuncAttrs {
@@ -1458,8 +1462,14 @@ Types
     CHECK_FOR_ERROR
 
     FunctionType *FT = FunctionType::get($1, Params, isVarArg);
-    delete $3;      // Delete the argument list
     $$ = new PATypeHolder(HandleUpRefs(FT));
+
+    // Delete the argument list
+    for (I = $3->begin() ; I != E; ++I ) {
+      delete I->Ty;
+    }
+    delete $3;
+
     CHECK_FOR_ERROR
   }
 
@@ -1509,11 +1519,11 @@ Types
   ;
 
 ArgType
-  : Types OptParamAttrs {
+  : Types OptAttributes {
     // Allow but ignore attributes on function types; this permits auto-upgrade.
     // FIXME: remove in LLVM 3.0.
     $$.Ty = $1;
-    $$.Attrs = ParamAttr::None;
+    $$.Attrs = Attribute::None;
   }
   ;
 
@@ -1545,14 +1555,14 @@ ArgTypeListI
   : ArgTypeList
   | ArgTypeList ',' DOTDOTDOT {
     $$=$1;
-    TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None;
+    TypeWithAttrs TWA; TWA.Attrs = Attribute::None;
     TWA.Ty = new PATypeHolder(Type::VoidTy);
     $$->push_back(TWA);
     CHECK_FOR_ERROR
   }
   | DOTDOTDOT {
     $$ = new TypeWithAttrsList;
-    TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None;
+    TypeWithAttrs TWA; TWA.Attrs = Attribute::None;
     TWA.Ty = new PATypeHolder(Type::VoidTy);
     $$->push_back(TWA);
     CHECK_FOR_ERROR
@@ -1879,58 +1889,82 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     delete $1;
     CHECK_FOR_ERROR
   }
-  | IntType ESINT64VAL {      // integral constants
-    if (!ConstantInt::isValueValidForType($1, $2))
-      GEN_ERROR("Constant value doesn't fit in type");
-    $$ = ConstantInt::get($1, $2, true);
+  | Types ESINT64VAL {      // integral constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if (!ConstantInt::isValueValidForType(IT, $2))
+        GEN_ERROR("Constant value doesn't fit in type");
+      $$ = ConstantInt::get(IT, $2, true);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
+    }
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | IntType ESAPINTVAL {      // arbitrary precision integer constants
-    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
-    if ($2->getBitWidth() > BitWidth) {
-      GEN_ERROR("Constant value does not fit in type");
+  | Types ESAPINTVAL {      // arbitrary precision integer constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if ($2->getBitWidth() > IT->getBitWidth())
+        GEN_ERROR("Constant value does not fit in type");
+      $2->sextOrTrunc(IT->getBitWidth());
+      $$ = ConstantInt::get(*$2);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
     }
-    $2->sextOrTrunc(BitWidth);
-    $$ = ConstantInt::get(*$2);
+    delete $1;
     delete $2;
     CHECK_FOR_ERROR
   }
-  | IntType EUINT64VAL {      // integral constants
-    if (!ConstantInt::isValueValidForType($1, $2))
-      GEN_ERROR("Constant value doesn't fit in type");
-    $$ = ConstantInt::get($1, $2, false);
+  | Types EUINT64VAL {      // integral constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if (!ConstantInt::isValueValidForType(IT, $2))
+        GEN_ERROR("Constant value doesn't fit in type");
+      $$ = ConstantInt::get(IT, $2, false);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
+    }
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | IntType EUAPINTVAL {      // arbitrary precision integer constants
-    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
-    if ($2->getBitWidth() > BitWidth) {
-      GEN_ERROR("Constant value does not fit in type");
+  | Types EUAPINTVAL {      // arbitrary precision integer constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if ($2->getBitWidth() > IT->getBitWidth())
+        GEN_ERROR("Constant value does not fit in type");
+      $2->zextOrTrunc(IT->getBitWidth());
+      $$ = ConstantInt::get(*$2);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
     }
-    $2->zextOrTrunc(BitWidth);
-    $$ = ConstantInt::get(*$2);
+
     delete $2;
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | INTTYPE TRUETOK {                      // Boolean constants
-    if (cast<IntegerType>($1)->getBitWidth() != 1)
+  | Types TRUETOK {                      // Boolean constants
+    if ($1->get() != Type::Int1Ty)
       GEN_ERROR("Constant true must have type i1");
     $$ = ConstantInt::getTrue();
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | INTTYPE FALSETOK {                     // Boolean constants
-    if (cast<IntegerType>($1)->getBitWidth() != 1)
+  | Types FALSETOK {                     // Boolean constants
+    if ($1->get() != Type::Int1Ty)
       GEN_ERROR("Constant false must have type i1");
     $$ = ConstantInt::getFalse();
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | FPType FPVAL {                   // Floating point constants
-    if (!ConstantFP::isValueValidForType($1, *$2))
+  | Types FPVAL {                   // Floating point constants
+    if (!ConstantFP::isValueValidForType($1->get(), *$2))
       GEN_ERROR("Floating point constant invalid for type");
+      
     // Lexer has no type info, so builds all float and double FP constants
     // as double.  Fix this here.  Long double is done right.
-    if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy)
-      $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
+    if (&$2->getSemantics()==&APFloat::IEEEdouble && $1->get()==Type::FloatTy) {
+      bool ignored;
+      $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+                  &ignored);
+    }
     $$ = ConstantFP::get(*$2);
+    delete $1;
     delete $2;
     CHECK_FOR_ERROR
   };
@@ -2285,7 +2319,7 @@ LibList : LibList ',' STRINGCONSTANT {
 //                       Rules to match Function Headers
 //===----------------------------------------------------------------------===//
 
-ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName {
+ArgListH : ArgListH ',' Types OptAttributes OptLocalName {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
     if (!(*$3)->isFirstClassType())
@@ -2295,7 +2329,7 @@ ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName {
     $1->push_back(E);
     CHECK_FOR_ERROR
   }
-  | Types OptParamAttrs OptLocalName {
+  | Types OptAttributes OptLocalName {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     if (!(*$1)->isFirstClassType())
@@ -2315,7 +2349,7 @@ ArgList : ArgListH {
     struct ArgListEntry E;
     E.Ty = new PATypeHolder(Type::VoidTy);
     E.Name = 0;
-    E.Attrs = ParamAttr::None;
+    E.Attrs = Attribute::None;
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
@@ -2324,7 +2358,7 @@ ArgList : ArgListH {
     struct ArgListEntry E;
     E.Ty = new PATypeHolder(Type::VoidTy);
     E.Name = 0;
-    E.Attrs = ParamAttr::None;
+    E.Attrs = Attribute::None;
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
@@ -2333,45 +2367,64 @@ ArgList : ArgListH {
     CHECK_FOR_ERROR
   };
 
-FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
-                  OptFuncAttrs OptSection OptAlign OptGC OptFuncNotes {
-  std::string FunctionName(*$3);
-  delete $3;  // Free strdup'd memory!
+FunctionHeaderH : OptCallingConv OptRetAttrs ResultTypes GlobalName '(' ArgList ')'
+                  OptFuncAttrs OptSection OptAlign OptGC {
+  std::string FunctionName(*$4);
+  delete $4;  // Free strdup'd memory!
 
   // Check the function result for abstractness if this is a define. We should
   // have no abstract types at this point
-  if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2))
-    GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
+  if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($3))
+    GEN_ERROR("Reference to abstract result: "+ $3->get()->getDescription());
 
-  if (!FunctionType::isValidReturnType(*$2))
+  if (!FunctionType::isValidReturnType(*$3))
     GEN_ERROR("Invalid result type for LLVM function");
 
   std::vector<const Type*> ParamTypeList;
-  SmallVector<FnAttributeWithIndex, 8> Attrs;
-  if ($7 != ParamAttr::None)
-    Attrs.push_back(FnAttributeWithIndex::get(0, $7));
-  if ($5) {   // If there are arguments...
+  SmallVector<AttributeWithIndex, 8> Attrs;
+  //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function 
+  //attributes.
+  Attributes RetAttrs = $2;
+  if ($8 != Attribute::None) {
+    if ($8 & Attribute::ZExt) {
+      RetAttrs = RetAttrs | Attribute::ZExt;
+      $8 = $8 ^ Attribute::ZExt;
+    }
+    if ($8 & Attribute::SExt) {
+      RetAttrs = RetAttrs | Attribute::SExt;
+      $8 = $8 ^ Attribute::SExt;
+    }
+    if ($8 & Attribute::InReg) {
+      RetAttrs = RetAttrs | Attribute::InReg;
+      $8 = $8 ^ Attribute::InReg;
+    }
+  }
+  if (RetAttrs != Attribute::None)
+    Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+  if ($6) {   // If there are arguments...
     unsigned index = 1;
-    for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
+    for (ArgListType::iterator I = $6->begin(); I != $6->end(); ++I, ++index) {
       const Type* Ty = I->Ty->get();
       if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty))
         GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
       ParamTypeList.push_back(Ty);
-      if (Ty != Type::VoidTy && I->Attrs != ParamAttr::None)
-        Attrs.push_back(FnAttributeWithIndex::get(index, I->Attrs));
+      if (Ty != Type::VoidTy && I->Attrs != Attribute::None)
+        Attrs.push_back(AttributeWithIndex::get(index, I->Attrs));
     }
   }
+  if ($8 != Attribute::None)
+    Attrs.push_back(AttributeWithIndex::get(~0, $8));
 
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  PAListPtr PAL;
+  AttrListPtr PAL;
   if (!Attrs.empty())
-    PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+    PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
 
-  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
+  FunctionType *FT = FunctionType::get(*$3, ParamTypeList, isVarArg);
   const PointerType *PFT = PointerType::getUnqual(FT);
-  delete $2;
+  delete $3;
 
   ValID ID;
   if (!FunctionName.empty()) {
@@ -2386,7 +2439,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     // Move the function to the end of the list, from whereever it was
     // previously inserted.
     Fn = cast<Function>(FWRef);
-    assert(Fn->getParamAttrs().isEmpty() &&
+    assert(Fn->getAttributes().isEmpty() &&
            "Forward reference has parameter attributes!");
     CurModule.CurrentModule->getFunctionList().remove(Fn);
     CurModule.CurrentModule->getFunctionList().push_back(Fn);
@@ -2396,7 +2449,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
       // The existing function doesn't have the same type. This is an overload
       // error.
       GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
-    } else if (Fn->getParamAttrs() != PAL) {
+    } else if (Fn->getAttributes() != PAL) {
       // The existing function doesn't have the same parameter attributes.
       // This is an overload error.
       GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
@@ -2416,6 +2469,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     InsertValue(Fn, CurModule.Values);
   }
 
+  ID.destroy();
   CurFun.FunctionStart(Fn);
 
   if (CurFun.isDeclare) {
@@ -2426,33 +2480,30 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     Fn->setVisibility(CurFun.Visibility);
   }
   Fn->setCallingConv($1);
-  Fn->setParamAttrs(PAL);
-  Fn->setAlignment($9);
-  if ($8) {
-    Fn->setSection(*$8);
-    delete $8;
-  }
-  if ($10) {
-    Fn->setGC($10->c_str());
-    delete $10;
+  Fn->setAttributes(PAL);
+  Fn->setAlignment($10);
+  if ($9) {
+    Fn->setSection(*$9);
+    delete $9;
   }
   if ($11) {
-    Fn->setNotes($11);
+    Fn->setGC($11->c_str());
+    delete $11;
   }
 
   // Add all of the arguments we parsed to the function...
-  if ($5) {                     // Is null if empty...
+  if ($6) {                     // Is null if empty...
     if (isVarArg) {  // Nuke the last entry
-      assert($5->back().Ty->get() == Type::VoidTy && $5->back().Name == 0 &&
+      assert($6->back().Ty->get() == Type::VoidTy && $6->back().Name == 0 &&
              "Not a varargs marker!");
-      delete $5->back().Ty;
-      $5->pop_back();  // Delete the last entry
+      delete $6->back().Ty;
+      $6->pop_back();  // Delete the last entry
     }
     Function::arg_iterator ArgIt = Fn->arg_begin();
     Function::arg_iterator ArgEnd = Fn->arg_end();
     unsigned Idx = 1;
-    for (ArgListType::iterator I = $5->begin();
-         I != $5->end() && ArgIt != ArgEnd; ++I, ++ArgIt) {
+    for (ArgListType::iterator I = $6->begin();
+         I != $6->end() && ArgIt != ArgEnd; ++I, ++ArgIt) {
       delete I->Ty;                          // Delete the typeholder...
       setValueName(ArgIt, I->Name);       // Insert arg into symtab...
       CHECK_FOR_ERROR
@@ -2460,7 +2511,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
       Idx++;
     }
 
-    delete $5;                     // We're now done with the argument list
+    delete $6;                     // We're now done with the argument list
   }
   CHECK_FOR_ERROR
 };
@@ -2799,7 +2850,7 @@ BBTerminatorInst :
     CHECK_FOR_ERROR
     $$ = BranchInst::Create(tmpBBA, tmpBBB, tmpVal);
   }
-  | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
+  | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
     Value* tmpVal = getVal($2, $3);
     CHECK_FOR_ERROR
     BasicBlock* tmpBB = getBBVal($6);
@@ -2818,7 +2869,7 @@ BBTerminatorInst :
     delete $8;
     CHECK_FOR_ERROR
   }
-  | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
+  | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' ']' {
     Value* tmpVal = getVal($2, $3);
     CHECK_FOR_ERROR
     BasicBlock* tmpBB = getBBVal($6);
@@ -2827,17 +2878,17 @@ BBTerminatorInst :
     $$ = S;
     CHECK_FOR_ERROR
   }
-  | INVOKE OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs
-    TO LABEL ValueRef UNWIND LABEL ValueRef {
+  | INVOKE OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')' 
+    OptFuncAttrs TO LABEL ValueRef UNWIND LABEL ValueRef {
 
     // Handle the short syntax
     const PointerType *PFTy = 0;
     const FunctionType *Ty = 0;
-    if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
+    if (!(PFTy = dyn_cast<PointerType>($4->get())) ||
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamList::iterator I = $6->begin(), E = $6->end();
+      ParamList::iterator I = $7->begin(), E = $7->end();
       for (; I != E; ++I) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
@@ -2845,29 +2896,46 @@ BBTerminatorInst :
         ParamTypes.push_back(Ty);
       }
 
-      if (!FunctionType::isValidReturnType(*$3))
+      if (!FunctionType::isValidReturnType(*$4))
         GEN_ERROR("Invalid result type for LLVM function");
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false);
+      Ty = FunctionType::get($4->get(), ParamTypes, false);
       PFTy = PointerType::getUnqual(Ty);
     }
 
-    delete $3;
+    delete $4;
 
-    Value *V = getVal(PFTy, $4);   // Get the function we're calling...
+    Value *V = getVal(PFTy, $5);   // Get the function we're calling...
     CHECK_FOR_ERROR
-    BasicBlock *Normal = getBBVal($11);
+    BasicBlock *Normal = getBBVal($12);
     CHECK_FOR_ERROR
-    BasicBlock *Except = getBBVal($14);
+    BasicBlock *Except = getBBVal($15);
     CHECK_FOR_ERROR
 
-    SmallVector<FnAttributeWithIndex, 8> Attrs;
-    if ($8 != ParamAttr::None)
-      Attrs.push_back(FnAttributeWithIndex::get(0, $8));
-
+    SmallVector<AttributeWithIndex, 8> Attrs;
+    //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function 
+    //attributes.
+    Attributes RetAttrs = $3;
+    if ($9 != Attribute::None) {
+      if ($9 & Attribute::ZExt) {
+        RetAttrs = RetAttrs | Attribute::ZExt;
+        $9 = $9 ^ Attribute::ZExt;
+      }
+      if ($9 & Attribute::SExt) {
+        RetAttrs = RetAttrs | Attribute::SExt;
+        $9 = $9 ^ Attribute::SExt;
+      }
+      if ($9 & Attribute::InReg) {
+        RetAttrs = RetAttrs | Attribute::InReg;
+        $9 = $9 ^ Attribute::InReg;
+      }
+    }
+    if (RetAttrs != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+    
     // Check the arguments
     ValueList Args;
-    if ($6->empty()) {                                   // Has no arguments?
+    if ($7->empty()) {                                   // Has no arguments?
       // Make sure no arguments is a good thing!
       if (Ty->getNumParams() != 0)
         GEN_ERROR("No arguments passed to a function that "
@@ -2877,7 +2945,7 @@ BBTerminatorInst :
       // correctly!
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
-      ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      ParamList::iterator ArgI = $7->begin(), ArgE = $7->end();
       unsigned index = 1;
 
       for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
@@ -2885,32 +2953,33 @@ BBTerminatorInst :
           GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
                          (*I)->getDescription() + "'");
         Args.push_back(ArgI->Val);
-        if (ArgI->Attrs != ParamAttr::None)
-          Attrs.push_back(FnAttributeWithIndex::get(index, ArgI->Attrs));
+        if (ArgI->Attrs != Attribute::None)
+          Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
       }
 
       if (Ty->isVarArg()) {
         if (I == E)
           for (; ArgI != ArgE; ++ArgI, ++index) {
             Args.push_back(ArgI->Val); // push the remaining varargs
-            if (ArgI->Attrs != ParamAttr::None)
-              Attrs.push_back(FnAttributeWithIndex::get(index, ArgI->Attrs));
+            if (ArgI->Attrs != Attribute::None)
+              Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
           }
       } else if (I != E || ArgI != ArgE)
         GEN_ERROR("Invalid number of parameters detected");
     }
-
-    PAListPtr PAL;
+    if ($9 != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(~0, $9));
+    AttrListPtr PAL;
     if (!Attrs.empty())
-      PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+      PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
 
     // Create the InvokeInst
     InvokeInst *II = InvokeInst::Create(V, Normal, Except,
                                         Args.begin(), Args.end());
     II->setCallingConv($2);
-    II->setParamAttrs(PAL);
+    II->setAttributes(PAL);
     $$ = II;
-    delete $6;
+    delete $7;
     CHECK_FOR_ERROR
   }
   | UNWIND {
@@ -2924,7 +2993,7 @@ BBTerminatorInst :
 
 
 
-JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
+JumpTable : JumpTable INTTYPE ConstValueRef ',' LABEL ValueRef {
     $$ = $1;
     Constant *V = cast<Constant>(getExistingVal($2, $3));
     CHECK_FOR_ERROR
@@ -2935,7 +3004,7 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
     CHECK_FOR_ERROR
     $$->push_back(std::make_pair(V, tmpBB));
   }
-  | IntType ConstValueRef ',' LABEL ValueRef {
+  | INTTYPE ConstValueRef ',' LABEL ValueRef {
     $$ = new std::vector<std::pair<Constant*, BasicBlock*> >();
     Constant *V = cast<Constant>(getExistingVal($1, $2));
     CHECK_FOR_ERROR
@@ -2991,8 +3060,8 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
   };
 
 
-ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+ParamList : Types OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     // Used for call and invoke instructions
@@ -3002,16 +3071,16 @@ ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
     delete $1;
     CHECK_FOR_ERROR
   }
-  | LABEL OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+  | LABEL OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     // Labels are only valid in ASMs
     $$ = new ParamList();
     ParamListEntry E; E.Attrs = $2 | $4; E.Val = getBBVal($3);
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
-  | ParamList ',' Types OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+  | ParamList ',' Types OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
     $$ = $1;
@@ -3020,8 +3089,8 @@ ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
     delete $3;
     CHECK_FOR_ERROR
   }
-  | ParamList ',' LABEL OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+  | ParamList ',' LABEL OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     $$ = $1;
     ParamListEntry E; E.Attrs = $4 | $6; E.Val = getBBVal($5);
     $$->push_back(E);
@@ -3221,17 +3290,17 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     delete $2;  // Free the list...
     CHECK_FOR_ERROR
   }
-  | OptTailCall OptCallingConv ResultTypes ValueRef '(' ParamList ')'
+  | OptTailCall OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')'
     OptFuncAttrs {
 
     // Handle the short syntax
     const PointerType *PFTy = 0;
     const FunctionType *Ty = 0;
-    if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
+    if (!(PFTy = dyn_cast<PointerType>($4->get())) ||
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamList::iterator I = $6->begin(), E = $6->end();
+      ParamList::iterator I = $7->begin(), E = $7->end();
       for (; I != E; ++I) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
@@ -3239,14 +3308,14 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
         ParamTypes.push_back(Ty);
       }
 
-      if (!FunctionType::isValidReturnType(*$3))
+      if (!FunctionType::isValidReturnType(*$4))
         GEN_ERROR("Invalid result type for LLVM function");
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false);
+      Ty = FunctionType::get($4->get(), ParamTypes, false);
       PFTy = PointerType::getUnqual(Ty);
     }
 
-    Value *V = getVal(PFTy, $4);   // Get the function we're calling...
+    Value *V = getVal(PFTy, $5);   // Get the function we're calling...
     CHECK_FOR_ERROR
 
     // Check for call to invalid intrinsic to avoid crashing later.
@@ -3258,13 +3327,31 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
                   theF->getName() + "'");
     }
 
-    // Set up the ParamAttrs for the function
-    SmallVector<FnAttributeWithIndex, 8> Attrs;
-    if ($8 != ParamAttr::None)
-      Attrs.push_back(FnAttributeWithIndex::get(0, $8));
+    // Set up the Attributes for the function
+    SmallVector<AttributeWithIndex, 8> Attrs;
+    //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function 
+    //attributes.
+    Attributes RetAttrs = $3;
+    if ($9 != Attribute::None) {
+      if ($9 & Attribute::ZExt) {
+        RetAttrs = RetAttrs | Attribute::ZExt;
+        $9 = $9 ^ Attribute::ZExt;
+      }
+      if ($9 & Attribute::SExt) {
+        RetAttrs = RetAttrs | Attribute::SExt;
+        $9 = $9 ^ Attribute::SExt;
+      }
+      if ($9 & Attribute::InReg) {
+        RetAttrs = RetAttrs | Attribute::InReg;
+        $9 = $9 ^ Attribute::InReg;
+      }
+    }
+    if (RetAttrs != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+    
     // Check the arguments
     ValueList Args;
-    if ($6->empty()) {                                   // Has no arguments?
+    if ($7->empty()) {                                   // Has no arguments?
       // Make sure no arguments is a good thing!
       if (Ty->getNumParams() != 0)
         GEN_ERROR("No arguments passed to a function that "
@@ -3274,7 +3361,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
       // correctly.  Also, gather any parameter attributes.
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
-      ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      ParamList::iterator ArgI = $7->begin(), ArgE = $7->end();
       unsigned index = 1;
 
       for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
@@ -3282,33 +3369,35 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
           GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
                          (*I)->getDescription() + "'");
         Args.push_back(ArgI->Val);
-        if (ArgI->Attrs != ParamAttr::None)
-          Attrs.push_back(FnAttributeWithIndex::get(index, ArgI->Attrs));
+        if (ArgI->Attrs != Attribute::None)
+          Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
       }
       if (Ty->isVarArg()) {
         if (I == E)
           for (; ArgI != ArgE; ++ArgI, ++index) {
             Args.push_back(ArgI->Val); // push the remaining varargs
-            if (ArgI->Attrs != ParamAttr::None)
-              Attrs.push_back(FnAttributeWithIndex::get(index, ArgI->Attrs));
+            if (ArgI->Attrs != Attribute::None)
+              Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
           }
       } else if (I != E || ArgI != ArgE)
         GEN_ERROR("Invalid number of parameters detected");
     }
+    if ($9 != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(~0, $9));
 
-    // Finish off the ParamAttrs and check them
-    PAListPtr PAL;
+    // Finish off the Attributes and check them
+    AttrListPtr PAL;
     if (!Attrs.empty())
-      PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+      PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
 
     // Create the call node
     CallInst *CI = CallInst::Create(V, Args.begin(), Args.end());
     CI->setTailCall($1);
     CI->setCallingConv($2);
-    CI->setParamAttrs(PAL);
+    CI->setAttributes(PAL);
     $$ = CI;
-    delete $6;
-    delete $3;
+    delete $7;
+    delete $4;
     CHECK_FOR_ERROR
   }
   | MemoryInst {