Make structs and arrays first-class types, and add assembly
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y.cvs
index 90fe540b8df3c74460115a3a6b87a5328309d792..66e656915ec076d7279d307fc6612909c461a208 100644 (file)
@@ -475,7 +475,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
   if (TriggerError) return 0;
 
   if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
-    GenerateError("Invalid use of a composite type");
+    GenerateError("Invalid use of a non-first-class type");
     return 0;
   }
 
@@ -1093,6 +1093,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 %token <OtherOpVal> PHI_TOK SELECT VAARG
 %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
 %token <OtherOpVal> GETRESULT
+%token <OtherOpVal> EXTRACTVALUE INSERTVALUE
 
 // Function Attributes
 %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
@@ -1966,6 +1967,48 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
       GEN_ERROR("Invalid shufflevector operands");
     $$ = ConstantExpr::getShuffleVector($3, $5, $7);
     CHECK_FOR_ERROR
+  }
+  | EXTRACTVALUE '(' ConstVal IndexList ')' {
+    if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
+      GEN_ERROR("ExtractValue requires an aggregate operand");
+
+    const Type *IdxTy =
+      ExtractValueInst::getIndexedType($3->getType(), $4->begin(), $4->end());
+    if (!IdxTy)
+      GEN_ERROR("Index list invalid for constant extractvalue");
+
+    SmallVector<Constant*, 8> IdxVec;
+    for (unsigned i = 0, e = $4->size(); i != e; ++i)
+      if (Constant *C = dyn_cast<Constant>((*$4)[i]))
+        IdxVec.push_back(C);
+      else
+        GEN_ERROR("Indices to constant extractvalue must be constants");
+
+    delete $4;
+
+    $$ = ConstantExpr::getExtractValue($3, &IdxVec[0], IdxVec.size());
+    CHECK_FOR_ERROR
+  }
+  | INSERTVALUE '(' ConstVal ',' ConstVal IndexList ')' {
+    if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
+      GEN_ERROR("InsertValue requires an aggregate operand");
+
+    const Type *IdxTy =
+      ExtractValueInst::getIndexedType($3->getType(), $6->begin(), $6->end());
+    if (IdxTy != $5->getType())
+      GEN_ERROR("Index list invalid for constant insertvalue");
+
+    SmallVector<Constant*, 8> IdxVec;
+    for (unsigned i = 0, e = $6->size(); i != e; ++i)
+      if (Constant *C = dyn_cast<Constant>((*$6)[i]))
+        IdxVec.push_back(C);
+      else
+        GEN_ERROR("Indices to constant insertvalue must be constants");
+
+    delete $6;
+
+    $$ = ConstantExpr::getInsertValue($3, $5, &IdxVec[0], IdxVec.size());
+    CHECK_FOR_ERROR
   };
 
 
@@ -2852,7 +2895,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     CHECK_FOR_ERROR
     Value* val2 = getVal(*$2, $5);
     CHECK_FOR_ERROR
-    $$ = BinaryOperator::create($1, val1, val2);
+    $$ = BinaryOperator::Create($1, val1, val2);
     if ($$ == 0)
       GEN_ERROR("binary operator returned null");
     delete $2;
@@ -2869,7 +2912,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$2, $5);
     CHECK_FOR_ERROR
-    $$ = BinaryOperator::create($1, tmpVal1, tmpVal2);
+    $$ = BinaryOperator::Create($1, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("binary operator returned null");
     delete $2;
@@ -2883,7 +2926,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$3, $6);
     CHECK_FOR_ERROR
-    $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("icmp operator returned null");
     delete $3;
@@ -2897,7 +2940,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$3, $6);
     CHECK_FOR_ERROR
-    $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("fcmp operator returned null");
     delete $3;
@@ -2911,7 +2954,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$3, $6);
     CHECK_FOR_ERROR
-    $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("icmp operator returned null");
     delete $3;
@@ -2925,7 +2968,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$3, $6);
     CHECK_FOR_ERROR
-    $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("fcmp operator returned null");
     delete $3;
@@ -2939,7 +2982,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
       GEN_ERROR("invalid cast opcode for cast from '" +
                 Val->getType()->getDescription() + "' to '" +
                 DestTy->getDescription() + "'"); 
-    $$ = CastInst::create($1, Val, DestTy);
+    $$ = CastInst::Create($1, Val, DestTy);
     delete $4;
   }
   | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
@@ -3165,7 +3208,7 @@ MemoryInst : MALLOC Types OptCAlign {
     $$ = new StoreInst($3, tmpVal, $1, $7);
     delete $5;
   }
-| GETRESULT Types ValueRef ',' EUINT64VAL  {
+  | GETRESULT Types ValueRef ',' EUINT64VAL  {
   Value *TmpVal = getVal($2->get(), $3);
   if (!GetResultInst::isValidOperands(TmpVal, $5))
       GEN_ERROR("Invalid getresult operands");
@@ -3187,6 +3230,38 @@ MemoryInst : MALLOC Types OptCAlign {
     $$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
     delete $2; 
     delete $4;
+  }
+  | EXTRACTVALUE Types ValueRef IndexList {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+      GEN_ERROR("extractvalue insn requires an aggregate operand");
+
+    if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end()))
+      GEN_ERROR("Invalid extractvalue indices for type '" +
+                     (*$2)->getDescription()+ "'");
+    Value* tmpVal = getVal(*$2, $3);
+    CHECK_FOR_ERROR
+    $$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end());
+    delete $2; 
+    delete $4;
+  }
+  | INSERTVALUE Types ValueRef ',' Types ValueRef IndexList {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+      GEN_ERROR("extractvalue insn requires an aggregate operand");
+
+    if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get())
+      GEN_ERROR("Invalid insertvalue indices for type '" +
+                     (*$2)->getDescription()+ "'");
+    Value* aggVal = getVal(*$2, $3);
+    Value* tmpVal = getVal(*$5, $6);
+    CHECK_FOR_ERROR
+    $$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end());
+    delete $2; 
+    delete $5;
+    delete $7;
   };