Cleanup of the [SU]ADDO type legalization code. Patch by Duncan!
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y
index 608ed721f717b61a2cb9f0a8484fa9aa3054eb42..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,6 +716,7 @@ 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();
@@ -1068,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
@@ -1125,7 +1137,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 
 // Function Attributes
 %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
-%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE
+%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ
 
 // Visibility Styles
 %token DEFAULT HIDDEN PROTECTED
@@ -1162,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; };
 
@@ -1296,9 +1303,11 @@ FuncAttr      : NORETURN { $$ = Attribute::NoReturn; }
               | SIGNEXT  { $$ = Attribute::SExt;     }
               | READNONE { $$ = Attribute::ReadNone; }
               | READONLY { $$ = Attribute::ReadOnly; }
-              | NOINLINE { $$ = Attribute::NoInline }
-              | ALWAYSINLINE { $$ = Attribute::AlwaysInline }
-              | OPTSIZE { $$ = Attribute::OptimizeForSize }
+              | NOINLINE { $$ = Attribute::NoInline; }
+              | ALWAYSINLINE { $$ = Attribute::AlwaysInline; }
+              | OPTSIZE  { $$ = Attribute::OptimizeForSize; }
+              | SSP      { $$ = Attribute::StackProtect; }
+              | SSPREQ   { $$ = Attribute::StackProtectReq; }
               ;
 
 OptFuncAttrs  : /* empty */ { $$ = Attribute::None; }
@@ -1422,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 {
@@ -1447,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
   }
 
@@ -1868,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
   };
@@ -2805,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);
@@ -2824,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);
@@ -2948,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
@@ -2959,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