diff --git a/lib/AsmParser/llvmAsmParser.cpp b/lib/AsmParser/llvmAsmParser.cpp.cvs similarity index 91% rename from lib/AsmParser/llvmAsmParser.cpp rename to lib/AsmParser/llvmAsmParser.cpp.cvs index f7e57fe8788..e9197d153e1 100644 --- a/lib/AsmParser/llvmAsmParser.cpp +++ b/lib/AsmParser/llvmAsmParser.cpp.cvs @@ -1,5 +1,5 @@ -/* A Bison parser, made from /Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y +/* A Bison parser, made from /Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y by GNU Bison version 1.28 */ #define YYBISON 1 /* Identify Bison output. */ @@ -110,7 +110,7 @@ #define VAARG_old 353 #define VANEXT_old 354 -#line 14 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 14 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" #include "ParserInternals.h" #include "llvm/CallingConv.h" @@ -986,7 +986,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { } -#line 890 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 890 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" typedef union { llvm::Module *ModuleVal; llvm::Function *FunctionVal; @@ -2226,7 +2226,7 @@ yyreduce: switch (yyn) { case 2: -#line 1011 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1011 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UIntVal > (uint32_t)INT32_MAX) // Outside of my range! ThrowException("Value too large for type!"); @@ -2234,7 +2234,7 @@ case 2: ; break;} case 4: -#line 1019 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1019 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UInt64Val > (uint64_t)INT64_MAX) // Outside of my range! ThrowException("Value too large for type!"); @@ -2242,55 +2242,55 @@ case 4: ; break;} case 33: -#line 1042 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1042 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = yyvsp[-1].StrVal; ; break;} case 34: -#line 1045 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1045 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = 0; ; break;} case 35: -#line 1049 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1049 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::InternalLinkage; ; break;} case 36: -#line 1050 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1050 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::LinkOnceLinkage; ; break;} case 37: -#line 1051 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1051 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::WeakLinkage; ; break;} case 38: -#line 1052 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1052 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::AppendingLinkage; ; break;} case 39: -#line 1053 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1053 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::ExternalLinkage; ; break;} case 40: -#line 1055 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1055 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::C; ; break;} case 41: -#line 1056 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1056 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::C; ; break;} case 42: -#line 1057 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1057 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::Fast; ; break;} case 43: -#line 1058 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1058 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::Cold; ; break;} case 44: -#line 1059 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1059 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if ((unsigned)yyvsp[0].UInt64Val != yyvsp[0].UInt64Val) ThrowException("Calling conv too large!"); @@ -2298,11 +2298,11 @@ case 44: ; break;} case 45: -#line 1067 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1067 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = 0; ; break;} case 46: -#line 1068 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1068 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = yyvsp[0].UInt64Val; if (yyval.UIntVal != 0 && !isPowerOf2_32(yyval.UIntVal)) @@ -2310,11 +2310,11 @@ case 46: ; break;} case 47: -#line 1073 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1073 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = 0; ; break;} case 48: -#line 1074 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1074 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = yyvsp[0].UInt64Val; if (yyval.UIntVal != 0 && !isPowerOf2_32(yyval.UIntVal)) @@ -2322,7 +2322,7 @@ case 48: ; break;} case 49: -#line 1081 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1081 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { for (unsigned i = 0, e = strlen(yyvsp[0].StrVal); i != e; ++i) if (yyvsp[0].StrVal[i] == '"' || yyvsp[0].StrVal[i] == '\\') @@ -2331,30 +2331,30 @@ case 49: ; break;} case 50: -#line 1088 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1088 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = 0; ; break;} case 51: -#line 1089 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1089 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = yyvsp[0].StrVal; ; break;} case 52: -#line 1094 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1094 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" {; break;} case 53: -#line 1095 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1095 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" {; break;} case 54: -#line 1096 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1096 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV->setSection(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 55: -#line 1100 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1100 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UInt64Val != 0 && !isPowerOf2_32(yyvsp[0].UInt64Val)) ThrowException("Alignment must be a power of two!"); @@ -2362,15 +2362,15 @@ case 55: ; break;} case 57: -#line 1113 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1113 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; break;} case 59: -#line 1114 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1114 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; break;} case 60: -#line 1116 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1116 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) ThrowException("Invalid upreference in type: " + (*yyvsp[0].TypeVal)->getDescription()); @@ -2378,25 +2378,25 @@ case 60: ; break;} case 74: -#line 1127 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1127 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(OpaqueType::get()); ; break;} case 75: -#line 1130 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1130 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; break;} case 76: -#line 1133 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1133 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Named types are also simple types... yyval.TypeVal = new PATypeHolder(getTypeVal(yyvsp[0].ValIDVal)); ; break;} case 77: -#line 1139 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1139 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Type UpReference if (yyvsp[0].UInt64Val > (uint64_t)~0U) ThrowException("Value out of range!"); OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder @@ -2406,7 +2406,7 @@ case 77: ; break;} case 78: -#line 1146 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1146 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Function derived type? std::vector Params; for (std::list::iterator I = yyvsp[-1].TypeList->begin(), @@ -2421,14 +2421,14 @@ case 78: ; break;} case 79: -#line 1158 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1158 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Sized array type? yyval.TypeVal = new PATypeHolder(HandleUpRefs(ArrayType::get(*yyvsp[-1].TypeVal, (unsigned)yyvsp[-3].UInt64Val))); delete yyvsp[-1].TypeVal; ; break;} case 80: -#line 1162 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1162 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Packed array type? const llvm::Type* ElemTy = yyvsp[-1].TypeVal->get(); if ((unsigned)yyvsp[-3].UInt64Val != yyvsp[-3].UInt64Val) @@ -2442,7 +2442,7 @@ case 80: ; break;} case 81: -#line 1173 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1173 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Structure type? std::vector Elements; for (std::list::iterator I = yyvsp[-1].TypeList->begin(), @@ -2454,51 +2454,51 @@ case 81: ; break;} case 82: -#line 1182 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1182 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? yyval.TypeVal = new PATypeHolder(StructType::get(std::vector())); ; break;} case 83: -#line 1185 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1185 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Pointer type? yyval.TypeVal = new PATypeHolder(HandleUpRefs(PointerType::get(*yyvsp[-1].TypeVal))); delete yyvsp[-1].TypeVal; ; break;} case 84: -#line 1193 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1193 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeList = new std::list(); yyval.TypeList->push_back(*yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; ; break;} case 85: -#line 1197 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1197 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList=yyvsp[-2].TypeList)->push_back(*yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; ; break;} case 87: -#line 1203 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1203 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList=yyvsp[-2].TypeList)->push_back(Type::VoidTy); ; break;} case 88: -#line 1206 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1206 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList = new std::list())->push_back(Type::VoidTy); ; break;} case 89: -#line 1209 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1209 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeList = new std::list(); ; break;} case 90: -#line 1219 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1219 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr const ArrayType *ATy = dyn_cast(yyvsp[-3].TypeVal->get()); if (ATy == 0) @@ -2526,7 +2526,7 @@ case 90: ; break;} case 91: -#line 1244 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1244 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const ArrayType *ATy = dyn_cast(yyvsp[-2].TypeVal->get()); if (ATy == 0) @@ -2542,7 +2542,7 @@ case 91: ; break;} case 92: -#line 1257 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1257 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const ArrayType *ATy = dyn_cast(yyvsp[-2].TypeVal->get()); if (ATy == 0) @@ -2574,7 +2574,7 @@ case 92: ; break;} case 93: -#line 1286 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1286 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr const PackedType *PTy = dyn_cast(yyvsp[-3].TypeVal->get()); if (PTy == 0) @@ -2602,7 +2602,7 @@ case 93: ; break;} case 94: -#line 1311 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1311 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast(yyvsp[-3].TypeVal->get()); if (STy == 0) @@ -2625,7 +2625,7 @@ case 94: ; break;} case 95: -#line 1331 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1331 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast(yyvsp[-2].TypeVal->get()); if (STy == 0) @@ -2640,7 +2640,7 @@ case 95: ; break;} case 96: -#line 1343 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1343 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PTy = dyn_cast(yyvsp[-1].TypeVal->get()); if (PTy == 0) @@ -2652,14 +2652,14 @@ case 96: ; break;} case 97: -#line 1352 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1352 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ConstVal = UndefValue::get(yyvsp[-1].TypeVal->get()); delete yyvsp[-1].TypeVal; ; break;} case 98: -#line 1356 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1356 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *Ty = dyn_cast(yyvsp[-1].TypeVal->get()); if (Ty == 0) @@ -2721,7 +2721,7 @@ case 98: ; break;} case 99: -#line 1415 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1415 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-1].TypeVal->get() != yyvsp[0].ConstVal->getType()) ThrowException("Mismatched types for constant expression!"); @@ -2730,7 +2730,7 @@ case 99: ; break;} case 100: -#line 1421 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1421 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const Type *Ty = yyvsp[-1].TypeVal->get(); if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) @@ -2740,7 +2740,7 @@ case 100: ; break;} case 101: -#line 1429 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1429 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantSInt::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].SInt64Val)) ThrowException("Constant value doesn't fit in type!"); @@ -2748,7 +2748,7 @@ case 101: ; break;} case 102: -#line 1434 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1434 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantUInt::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].UInt64Val)) ThrowException("Constant value doesn't fit in type!"); @@ -2756,19 +2756,19 @@ case 102: ; break;} case 103: -#line 1439 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1439 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Boolean constants yyval.ConstVal = ConstantBool::True; ; break;} case 104: -#line 1442 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1442 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Boolean constants yyval.ConstVal = ConstantBool::False; ; break;} case 105: -#line 1445 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1445 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Float & Double constants if (!ConstantFP::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].FPVal)) ThrowException("Floating point constant invalid for type!!"); @@ -2776,7 +2776,7 @@ case 105: ; break;} case 106: -#line 1452 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1452 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!yyvsp[-3].ConstVal->getType()->isFirstClassType()) ThrowException("cast constant expression from a non-primitive type: '" + @@ -2789,7 +2789,7 @@ case 106: ; break;} case 107: -#line 1462 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1462 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-2].ConstVal->getType())) ThrowException("GetElementPtr requires a pointer operand!"); @@ -2823,7 +2823,7 @@ case 107: ; break;} case 108: -#line 1493 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1493 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-5].ConstVal->getType() != Type::BoolTy) ThrowException("Select condition must be of boolean type!"); @@ -2833,7 +2833,7 @@ case 108: ; break;} case 109: -#line 1500 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1500 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("Binary operator types must match!"); @@ -2857,7 +2857,7 @@ case 109: ; break;} case 110: -#line 1521 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1521 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("Logical operator types must match!"); @@ -2870,7 +2870,7 @@ case 110: ; break;} case 111: -#line 1531 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1531 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("setcc operand types must match!"); @@ -2878,7 +2878,7 @@ case 111: ; break;} case 112: -#line 1536 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1536 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-1].ConstVal->getType() != Type::UByteTy) ThrowException("Shift count for shift constant must be unsigned byte!"); @@ -2888,7 +2888,7 @@ case 112: ; break;} case 113: -#line 1543 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1543 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-3].ConstVal->getType())) ThrowException("First operand of extractelement must be " @@ -2899,60 +2899,60 @@ case 113: ; break;} case 114: -#line 1553 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1553 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ConstVector = yyvsp[-2].ConstVector)->push_back(yyvsp[0].ConstVal); ; break;} case 115: -#line 1556 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1556 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ConstVector = new std::vector(); yyval.ConstVector->push_back(yyvsp[0].ConstVal); ; break;} case 116: -#line 1563 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1563 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 117: -#line 1563 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1563 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 118: -#line 1573 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1573 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = ParserResult = yyvsp[0].ModuleVal; CurModule.ModuleDone(); ; break;} case 119: -#line 1580 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1580 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-1].ModuleVal; CurFun.FunctionDone(); ; break;} case 120: -#line 1584 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1584 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-1].ModuleVal; ; break;} case 121: -#line 1587 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1587 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-3].ModuleVal; ; break;} case 122: -#line 1590 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1590 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-1].ModuleVal; ; break;} case 123: -#line 1593 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1593 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = CurModule.CurrentModule; // Emit an error if there are any unresolved types left. @@ -2966,7 +2966,7 @@ case 123: ; break;} case 124: -#line 1606 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1606 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Eagerly resolve types. This is not an optimization, this is a // requirement that is due to the fact that we could have this: @@ -2989,30 +2989,30 @@ case 124: ; break;} case 125: -#line 1626 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1626 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Function prototypes can be in const pool ; break;} case 126: -#line 1628 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1628 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Asm blocks can be in the const pool ; break;} case 127: -#line 1630 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1630 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].ConstVal == 0) ThrowException("Global value initializer is not a constant!"); CurGV = ParseGlobalVariable(yyvsp[-3].StrVal, yyvsp[-2].Linkage, yyvsp[-1].BoolVal, yyvsp[0].ConstVal->getType(), yyvsp[0].ConstVal); ; break;} case 128: -#line 1633 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1633 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ; break;} case 129: -#line 1636 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1636 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV = ParseGlobalVariable(yyvsp[-3].StrVal, GlobalValue::ExternalLinkage, yyvsp[-1].BoolVal, *yyvsp[0].TypeVal, 0); @@ -3020,28 +3020,28 @@ case 129: ; break;} case 130: -#line 1640 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1640 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ; break;} case 131: -#line 1643 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1643 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 132: -#line 1645 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1645 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 133: -#line 1647 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1647 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 134: -#line 1651 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1651 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); char *EndStr = UnEscapeLexed(yyvsp[0].StrVal, true); @@ -3055,21 +3055,21 @@ case 134: ; break;} case 135: -#line 1663 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1663 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Endianness = Module::BigEndian; ; break;} case 136: -#line 1664 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1664 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Endianness = Module::LittleEndian; ; break;} case 137: -#line 1666 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1666 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setEndianness(yyvsp[0].Endianness); ; break;} case 138: -#line 1669 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1669 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UInt64Val == 32) CurModule.CurrentModule->setPointerSize(Module::Pointer32); @@ -3080,37 +3080,37 @@ case 138: ; break;} case 139: -#line 1677 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1677 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setTargetTriple(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 141: -#line 1684 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1684 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 142: -#line 1688 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1688 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 143: -#line 1692 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1692 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 147: -#line 1701 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1701 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = 0; ; break;} case 148: -#line 1703 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1703 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (*yyvsp[-1].TypeVal == Type::VoidTy) ThrowException("void typed arguments are invalid!"); @@ -3118,7 +3118,7 @@ case 148: ; break;} case 149: -#line 1709 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1709 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = yyvsp[-2].ArgList; yyvsp[-2].ArgList->push_back(*yyvsp[0].ArgVal); @@ -3126,7 +3126,7 @@ case 149: ; break;} case 150: -#line 1714 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1714 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = new std::vector >(); yyval.ArgList->push_back(*yyvsp[0].ArgVal); @@ -3134,13 +3134,13 @@ case 150: ; break;} case 151: -#line 1720 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1720 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = yyvsp[0].ArgList; ; break;} case 152: -#line 1723 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1723 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = yyvsp[-2].ArgList; yyval.ArgList->push_back(std::pair >(); yyval.ArgList->push_back(std::make_pair(new PATypeHolder(Type::VoidTy), (char*)0)); ; break;} case 154: -#line 1732 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1732 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = 0; ; break;} case 155: -#line 1737 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1737 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { UnEscapeLexed(yyvsp[-5].StrVal); std::string FunctionName(yyvsp[-5].StrVal); @@ -3248,7 +3248,7 @@ case 155: ; break;} case 158: -#line 1824 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1824 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = CurFun.CurrentFunction; @@ -3258,84 +3258,84 @@ case 158: ; break;} case 161: -#line 1834 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1834 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = yyvsp[-1].FunctionVal; ; break;} case 162: -#line 1838 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1838 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { CurFun.isDeclare = true; ; break;} case 163: -#line 1838 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1838 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = CurFun.CurrentFunction; CurFun.FunctionDone(); ; break;} case 164: -#line 1847 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1847 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 165: -#line 1850 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1850 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 166: -#line 1854 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1854 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // A reference to a direct constant yyval.ValIDVal = ValID::create(yyvsp[0].SInt64Val); ; break;} case 167: -#line 1857 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1857 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(yyvsp[0].UInt64Val); ; break;} case 168: -#line 1860 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1860 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Perhaps it's an FP constant? yyval.ValIDVal = ValID::create(yyvsp[0].FPVal); ; break;} case 169: -#line 1863 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1863 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(ConstantBool::True); ; break;} case 170: -#line 1866 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1866 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(ConstantBool::False); ; break;} case 171: -#line 1869 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1869 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::createNull(); ; break;} case 172: -#line 1872 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1872 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::createUndef(); ; break;} case 173: -#line 1875 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1875 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // A vector zero constant. yyval.ValIDVal = ValID::createZeroInit(); ; break;} case 174: -#line 1878 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1878 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized packed vector const Type *ETy = (*yyvsp[-1].ConstVector)[0]->getType(); int NumElements = yyvsp[-1].ConstVector->size(); @@ -3362,13 +3362,13 @@ case 174: ; break;} case 175: -#line 1902 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1902 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(yyvsp[0].ConstVal); ; break;} case 176: -#line 1905 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1905 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { char *End = UnEscapeLexed(yyvsp[-2].StrVal, true); std::string AsmStr = std::string(yyvsp[-2].StrVal, End); @@ -3380,37 +3380,37 @@ case 176: ; break;} case 177: -#line 1918 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1918 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Is it an integer reference...? yyval.ValIDVal = ValID::create(yyvsp[0].SIntVal); ; break;} case 178: -#line 1921 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1921 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Is it a named reference...? yyval.ValIDVal = ValID::create(yyvsp[0].StrVal); ; break;} case 181: -#line 1932 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1932 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueVal = getVal(*yyvsp[-1].TypeVal, yyvsp[0].ValIDVal); delete yyvsp[-1].TypeVal; ; break;} case 182: -#line 1936 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1936 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = yyvsp[-1].FunctionVal; ; break;} case 183: -#line 1939 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1939 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Do not allow functions with 0 basic blocks yyval.FunctionVal = yyvsp[-1].FunctionVal; ; break;} case 184: -#line 1947 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1947 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { setValueName(yyvsp[0].TermInstVal, yyvsp[-1].StrVal); InsertValue(yyvsp[0].TermInstVal); @@ -3421,14 +3421,14 @@ case 184: ; break;} case 185: -#line 1956 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1956 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyvsp[-1].BasicBlockVal->getInstList().push_back(yyvsp[0].InstVal); yyval.BasicBlockVal = yyvsp[-1].BasicBlockVal; ; break;} case 186: -#line 1960 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1960 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BasicBlockVal = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); @@ -3441,7 +3441,7 @@ case 186: ; break;} case 187: -#line 1970 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1970 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BasicBlockVal = CurBB = getBBVal(ValID::create(yyvsp[0].StrVal), true); @@ -3454,31 +3454,31 @@ case 187: ; break;} case 188: -#line 1981 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1981 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Return with a result... yyval.TermInstVal = new ReturnInst(yyvsp[0].ValueVal); ; break;} case 189: -#line 1984 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1984 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Return with no result... yyval.TermInstVal = new ReturnInst(); ; break;} case 190: -#line 1987 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1987 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Unconditional Branch... yyval.TermInstVal = new BranchInst(getBBVal(yyvsp[0].ValIDVal)); ; break;} case 191: -#line 1990 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1990 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TermInstVal = new BranchInst(getBBVal(yyvsp[-3].ValIDVal), getBBVal(yyvsp[0].ValIDVal), getVal(Type::BoolTy, yyvsp[-6].ValIDVal)); ; break;} case 192: -#line 1993 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1993 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { SwitchInst *S = new SwitchInst(getVal(yyvsp[-7].PrimType, yyvsp[-6].ValIDVal), getBBVal(yyvsp[-3].ValIDVal), yyvsp[-1].JumpTable->size()); yyval.TermInstVal = S; @@ -3495,14 +3495,14 @@ case 192: ; break;} case 193: -#line 2007 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2007 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { SwitchInst *S = new SwitchInst(getVal(yyvsp[-6].PrimType, yyvsp[-5].ValIDVal), getBBVal(yyvsp[-2].ValIDVal), 0); yyval.TermInstVal = S; ; break;} case 194: -#line 2012 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2012 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PFTy; const FunctionType *Ty; @@ -3557,19 +3557,19 @@ case 194: ; break;} case 195: -#line 2064 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2064 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TermInstVal = new UnwindInst(); ; break;} case 196: -#line 2067 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2067 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TermInstVal = new UnreachableInst(); ; break;} case 197: -#line 2073 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2073 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.JumpTable = yyvsp[-5].JumpTable; Constant *V = cast(getValNonImprovising(yyvsp[-4].PrimType, yyvsp[-3].ValIDVal)); @@ -3580,7 +3580,7 @@ case 197: ; break;} case 198: -#line 2081 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2081 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.JumpTable = new std::vector >(); Constant *V = cast(getValNonImprovising(yyvsp[-4].PrimType, yyvsp[-3].ValIDVal)); @@ -3592,7 +3592,7 @@ case 198: ; break;} case 199: -#line 2091 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2091 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Is this definition named?? if so, assign the name... setValueName(yyvsp[0].InstVal, yyvsp[-1].StrVal); @@ -3601,7 +3601,7 @@ case 199: ; break;} case 200: -#line 2098 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2098 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Used for PHI nodes yyval.PHIList = new std::list >(); yyval.PHIList->push_back(std::make_pair(getVal(*yyvsp[-5].TypeVal, yyvsp[-3].ValIDVal), getBBVal(yyvsp[-1].ValIDVal))); @@ -3609,7 +3609,7 @@ case 200: ; break;} case 201: -#line 2103 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2103 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.PHIList = yyvsp[-6].PHIList; yyvsp[-6].PHIList->push_back(std::make_pair(getVal(yyvsp[-6].PHIList->front().first->getType(), yyvsp[-3].ValIDVal), @@ -3617,37 +3617,37 @@ case 201: ; break;} case 202: -#line 2110 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2110 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { // Used for call statements, and memory insts... yyval.ValueList = new std::vector(); yyval.ValueList->push_back(yyvsp[0].ValueVal); ; break;} case 203: -#line 2114 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2114 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = yyvsp[-2].ValueList; yyvsp[-2].ValueList->push_back(yyvsp[0].ValueVal); ; break;} case 205: -#line 2120 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2120 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = 0; ; break;} case 206: -#line 2122 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2122 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 207: -#line 2125 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2125 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 208: -#line 2131 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2131 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!(*yyvsp[-3].TypeVal)->isInteger() && !(*yyvsp[-3].TypeVal)->isFloatingPoint() && !isa((*yyvsp[-3].TypeVal).get())) @@ -3662,7 +3662,7 @@ case 208: ; break;} case 209: -#line 2143 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2143 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!(*yyvsp[-3].TypeVal)->isIntegral()) { if (!isa(yyvsp[-3].TypeVal->get()) || @@ -3676,7 +3676,7 @@ case 209: ; break;} case 210: -#line 2154 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2154 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if(isa((*yyvsp[-3].TypeVal).get())) { ThrowException( @@ -3689,7 +3689,7 @@ case 210: ; break;} case 211: -#line 2164 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2164 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { std::cerr << "WARNING: Use of eliminated 'not' instruction:" << " Replacing with 'xor'.\n"; @@ -3704,7 +3704,7 @@ case 211: ; break;} case 212: -#line 2176 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2176 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].ValueVal->getType() != Type::UByteTy) ThrowException("Shift amount must be ubyte!"); @@ -3714,7 +3714,7 @@ case 212: ; break;} case 213: -#line 2183 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2183 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!yyvsp[0].TypeVal->get()->isFirstClassType()) ThrowException("cast instruction to a non-primitive type: '" + @@ -3724,7 +3724,7 @@ case 213: ; break;} case 214: -#line 2190 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2190 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-4].ValueVal->getType() != Type::BoolTy) ThrowException("select condition must be boolean!"); @@ -3734,7 +3734,7 @@ case 214: ; break;} case 215: -#line 2197 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2197 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { NewVarArgs = true; yyval.InstVal = new VAArgInst(yyvsp[-2].ValueVal, *yyvsp[0].TypeVal); @@ -3742,7 +3742,7 @@ case 215: ; break;} case 216: -#line 2202 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2202 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { ObsoleteVarArgs = true; const Type* ArgTy = yyvsp[-2].ValueVal->getType(); @@ -3764,7 +3764,7 @@ case 216: ; break;} case 217: -#line 2221 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2221 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { ObsoleteVarArgs = true; const Type* ArgTy = yyvsp[-2].ValueVal->getType(); @@ -3789,7 +3789,7 @@ case 217: ; break;} case 218: -#line 2243 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2243 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-2].ValueVal->getType())) ThrowException("First operand of extractelement must be " @@ -3800,7 +3800,7 @@ case 218: ; break;} case 219: -#line 2251 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2251 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-4].ValueVal->getType())) ThrowException("First operand of insertelement must be " @@ -3815,7 +3815,7 @@ case 219: ; break;} case 220: -#line 2263 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2263 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const Type *Ty = yyvsp[0].PHIList->front().first->getType(); if (!Ty->isFirstClassType()) @@ -3832,7 +3832,7 @@ case 220: ; break;} case 221: -#line 2277 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2277 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PFTy; const FunctionType *Ty; @@ -3892,65 +3892,65 @@ case 221: ; break;} case 222: -#line 2334 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2334 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = yyvsp[0].InstVal; ; break;} case 223: -#line 2340 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2340 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = yyvsp[0].ValueList; ; break;} case 224: -#line 2342 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2342 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = new std::vector(); ; break;} case 225: -#line 2346 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2346 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 226: -#line 2349 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2349 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 227: -#line 2355 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2355 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new MallocInst(*yyvsp[-1].TypeVal, 0, yyvsp[0].UIntVal); delete yyvsp[-1].TypeVal; ; break;} case 228: -#line 2359 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2359 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new MallocInst(*yyvsp[-4].TypeVal, getVal(yyvsp[-2].PrimType, yyvsp[-1].ValIDVal), yyvsp[0].UIntVal); delete yyvsp[-4].TypeVal; ; break;} case 229: -#line 2363 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2363 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new AllocaInst(*yyvsp[-1].TypeVal, 0, yyvsp[0].UIntVal); delete yyvsp[-1].TypeVal; ; break;} case 230: -#line 2367 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2367 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new AllocaInst(*yyvsp[-4].TypeVal, getVal(yyvsp[-2].PrimType, yyvsp[-1].ValIDVal), yyvsp[0].UIntVal); delete yyvsp[-4].TypeVal; ; break;} case 231: -#line 2371 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2371 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[0].ValueVal->getType())) ThrowException("Trying to free nonpointer type " + @@ -3959,7 +3959,7 @@ case 231: ; break;} case 232: -#line 2378 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2378 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-1].TypeVal->get())) ThrowException("Can't load from nonpointer type: " + @@ -3972,7 +3972,7 @@ case 232: ; break;} case 233: -#line 2388 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2388 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PT = dyn_cast(yyvsp[-1].TypeVal->get()); if (!PT) @@ -3988,7 +3988,7 @@ case 233: ; break;} case 234: -#line 2401 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2401 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-2].TypeVal->get())) ThrowException("getelementptr insn requires pointer operand!"); @@ -4233,7 +4233,7 @@ yyerrhandle: } return 1; } -#line 2424 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2424 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" int yyerror(const char *ErrorMsg) { std::string where diff --git a/lib/AsmParser/llvmAsmParser.h b/lib/AsmParser/llvmAsmParser.h.cvs similarity index 100% rename from lib/AsmParser/llvmAsmParser.h rename to lib/AsmParser/llvmAsmParser.h.cvs diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs new file mode 100644 index 00000000000..dfdb5f4ac1e --- /dev/null +++ b/lib/AsmParser/llvmAsmParser.y.cvs @@ -0,0 +1,2436 @@ +//===-- llvmAsmParser.y - Parser for llvm assembly files --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the bison parser for LLVM assembly languages files. +// +//===----------------------------------------------------------------------===// + +%{ +#include "ParserInternals.h" +#include "llvm/CallingConv.h" +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/SymbolTable.h" +#include "llvm/Assembly/AutoUpgrade.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/MathExtras.h" +#include +#include +#include +#include + +int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit +int yylex(); // declaration" of xxx warnings. +int yyparse(); + +namespace llvm { + std::string CurFilename; +} +using namespace llvm; + +static Module *ParserResult; + +// DEBUG_UPREFS - Define this symbol if you want to enable debugging output +// relating to upreferences in the input stream. +// +//#define DEBUG_UPREFS 1 +#ifdef DEBUG_UPREFS +#define UR_OUT(X) std::cerr << X +#else +#define UR_OUT(X) +#endif + +#define YYERROR_VERBOSE 1 + +static bool ObsoleteVarArgs; +static bool NewVarArgs; +static BasicBlock *CurBB; +static GlobalVariable *CurGV; + + +// This contains info used when building the body of a function. It is +// destroyed when the function is completed. +// +typedef std::vector ValueList; // Numbered defs +static void +ResolveDefinitions(std::map &LateResolvers, + std::map *FutureLateResolvers = 0); + +static struct PerModuleInfo { + Module *CurrentModule; + std::map Values; // Module level numbered definitions + std::map LateResolveValues; + std::vector Types; + std::map LateResolveTypes; + + /// PlaceHolderInfo - When temporary placeholder objects are created, remember + /// how they were referenced and one which line of the input they came from so + /// that we can resolve them later and print error messages as appropriate. + std::map > PlaceHolderInfo; + + // GlobalRefs - This maintains a mapping between 's and forward + // references to global values. Global values may be referenced before they + // are defined, and if so, the temporary object that they represent is held + // here. This is used for forward references of GlobalValues. + // + typedef std::map, GlobalValue*> GlobalRefsType; + GlobalRefsType GlobalRefs; + + void ModuleDone() { + // If we could not resolve some functions at function compilation time + // (calls to functions before they are defined), resolve them now... Types + // are resolved when the constant pool has been completely parsed. + // + ResolveDefinitions(LateResolveValues); + + // Check to make sure that all global value forward references have been + // resolved! + // + if (!GlobalRefs.empty()) { + std::string UndefinedReferences = "Unresolved global references exist:\n"; + + for (GlobalRefsType::iterator I = GlobalRefs.begin(), E =GlobalRefs.end(); + I != E; ++I) { + UndefinedReferences += " " + I->first.first->getDescription() + " " + + I->first.second.getName() + "\n"; + } + ThrowException(UndefinedReferences); + } + + // Look for intrinsic functions and CallInst that need to be upgraded + for (Module::iterator FI = CurrentModule->begin(),FE = CurrentModule->end(); + FI != FE; ++FI) + UpgradeCallsToIntrinsic(FI); + + Values.clear(); // Clear out function local definitions + Types.clear(); + CurrentModule = 0; + } + + // GetForwardRefForGlobal - Check to see if there is a forward reference + // for this global. If so, remove it from the GlobalRefs map and return it. + // If not, just return null. + GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ValID ID) { + // Check to see if there is a forward reference to this global variable... + // if there is, eliminate it and patch the reference to use the new def'n. + GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PTy, ID)); + GlobalValue *Ret = 0; + if (I != GlobalRefs.end()) { + Ret = I->second; + GlobalRefs.erase(I); + } + return Ret; + } +} CurModule; + +static struct PerFunctionInfo { + Function *CurrentFunction; // Pointer to current function being created + + std::map Values; // Keep track of #'d definitions + std::map LateResolveValues; + bool isDeclare; // Is this function a forward declararation? + + /// BBForwardRefs - When we see forward references to basic blocks, keep + /// track of them here. + std::map > BBForwardRefs; + std::vector NumberedBlocks; + unsigned NextBBNum; + + inline PerFunctionInfo() { + CurrentFunction = 0; + isDeclare = false; + } + + inline void FunctionStart(Function *M) { + CurrentFunction = M; + NextBBNum = 0; + } + + void FunctionDone() { + NumberedBlocks.clear(); + + // Any forward referenced blocks left? + if (!BBForwardRefs.empty()) + ThrowException("Undefined reference to label " + + BBForwardRefs.begin()->first->getName()); + + // Resolve all forward references now. + ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues); + + Values.clear(); // Clear out function local definitions + CurrentFunction = 0; + isDeclare = false; + } +} CurFun; // Info for the current function... + +static bool inFunctionScope() { return CurFun.CurrentFunction != 0; } + + +//===----------------------------------------------------------------------===// +// Code to handle definitions of all the types +//===----------------------------------------------------------------------===// + +static int InsertValue(Value *V, + std::map &ValueTab = CurFun.Values) { + if (V->hasName()) return -1; // Is this a numbered definition? + + // Yes, insert the value into the value table... + ValueList &List = ValueTab[V->getType()]; + List.push_back(V); + return List.size()-1; +} + +static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { + switch (D.Type) { + case ValID::NumberVal: // Is it a numbered definition? + // Module constants occupy the lowest numbered slots... + if ((unsigned)D.Num < CurModule.Types.size()) + return CurModule.Types[(unsigned)D.Num]; + break; + case ValID::NameVal: // Is it a named definition? + if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) { + D.destroy(); // Free old strdup'd memory... + return N; + } + break; + default: + ThrowException("Internal parser error: Invalid symbol type reference!"); + } + + // If we reached here, we referenced either a symbol that we don't know about + // or an id number that hasn't been read yet. We may be referencing something + // forward, so just create an entry to be resolved later and get to it... + // + if (DoNotImprovise) return 0; // Do we just want a null to be returned? + + + if (inFunctionScope()) { + if (D.Type == ValID::NameVal) + ThrowException("Reference to an undefined type: '" + D.getName() + "'"); + else + ThrowException("Reference to an undefined type: #" + itostr(D.Num)); + } + + std::map::iterator I =CurModule.LateResolveTypes.find(D); + if (I != CurModule.LateResolveTypes.end()) + return I->second; + + Type *Typ = OpaqueType::get(); + CurModule.LateResolveTypes.insert(std::make_pair(D, Typ)); + return Typ; + } + +static Value *lookupInSymbolTable(const Type *Ty, const std::string &Name) { + SymbolTable &SymTab = + inFunctionScope() ? CurFun.CurrentFunction->getSymbolTable() : + CurModule.CurrentModule->getSymbolTable(); + return SymTab.lookup(Ty, Name); +} + +// getValNonImprovising - 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. +// +static Value *getValNonImprovising(const Type *Ty, const ValID &D) { + if (isa(Ty)) + ThrowException("Functions are not values and " + "must be referenced as pointers"); + + switch (D.Type) { + case ValID::NumberVal: { // Is it a numbered definition? + unsigned Num = (unsigned)D.Num; + + // Module constants occupy the lowest numbered slots... + std::map::iterator VI = CurModule.Values.find(Ty); + if (VI != CurModule.Values.end()) { + if (Num < VI->second.size()) + return VI->second[Num]; + Num -= VI->second.size(); + } + + // Make sure that our type is within bounds + VI = CurFun.Values.find(Ty); + if (VI == CurFun.Values.end()) return 0; + + // Check that the number is within bounds... + if (VI->second.size() <= Num) return 0; + + return VI->second[Num]; + } + + case ValID::NameVal: { // Is it a named definition? + Value *N = lookupInSymbolTable(Ty, std::string(D.Name)); + if (N == 0) return 0; + + D.destroy(); // Free old strdup'd memory... + return N; + } + + // Check to make sure that "Ty" is an integral type, and that our + // value will fit into the specified type... + case ValID::ConstSIntVal: // Is it a constant pool reference?? + if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64)) + ThrowException("Signed integral constant '" + + itostr(D.ConstPool64) + "' is invalid for type '" + + Ty->getDescription() + "'!"); + return ConstantSInt::get(Ty, D.ConstPool64); + + case ValID::ConstUIntVal: // Is it an unsigned const pool reference? + if (!ConstantUInt::isValueValidForType(Ty, D.UConstPool64)) { + if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64)) { + ThrowException("Integral constant '" + utostr(D.UConstPool64) + + "' is invalid or out of range!"); + } else { // This is really a signed reference. Transmogrify. + return ConstantSInt::get(Ty, D.ConstPool64); + } + } else { + return ConstantUInt::get(Ty, D.UConstPool64); + } + + case ValID::ConstFPVal: // Is it a floating point const pool reference? + if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) + ThrowException("FP constant invalid for type!!"); + return ConstantFP::get(Ty, D.ConstPoolFP); + + case ValID::ConstNullVal: // Is it a null value? + if (!isa(Ty)) + ThrowException("Cannot create a a non pointer null!"); + return ConstantPointerNull::get(cast(Ty)); + + case ValID::ConstUndefVal: // Is it an undef value? + return UndefValue::get(Ty); + + case ValID::ConstZeroVal: // Is it a zero value? + return Constant::getNullValue(Ty); + + case ValID::ConstantVal: // Fully resolved constant? + if (D.ConstantValue->getType() != Ty) + ThrowException("Constant expression type different from required type!"); + return D.ConstantValue; + + case ValID::InlineAsmVal: { // Inline asm expression + const PointerType *PTy = dyn_cast(Ty); + const FunctionType *FTy = + PTy ? dyn_cast(PTy->getElementType()) : 0; + if (!FTy || !InlineAsm::Verify(FTy, D.IAD->Constraints)) + ThrowException("Invalid type for asm constraint string!"); + InlineAsm *IA = InlineAsm::get(FTy, D.IAD->AsmString, D.IAD->Constraints, + D.IAD->HasSideEffects); + D.destroy(); // Free InlineAsmDescriptor. + return IA; + } + default: + assert(0 && "Unhandled case!"); + return 0; + } // End of switch + + assert(0 && "Unhandled case!"); + return 0; +} + +// getVal - This function is identical to getValNonImprovising, except that if a +// value is not already defined, it "improvises" by creating a placeholder var +// that looks and acts just like the requested variable. When the value is +// defined later, all uses of the placeholder variable are replaced with the +// real thing. +// +static Value *getVal(const Type *Ty, const ValID &ID) { + if (Ty == Type::LabelTy) + ThrowException("Cannot use a basic block here"); + + // See if the value has already been defined. + Value *V = getValNonImprovising(Ty, ID); + if (V) return V; + + if (!Ty->isFirstClassType() && !isa(Ty)) + ThrowException("Invalid use of a composite type!"); + + // If we reached here, we referenced either a symbol that we don't know about + // or an id number that hasn't been read yet. We may be referencing something + // forward, so just create an entry to be resolved later and get to it... + // + V = new Argument(Ty); + + // Remember where this forward reference came from. FIXME, shouldn't we try + // to recycle these things?? + CurModule.PlaceHolderInfo.insert(std::make_pair(V, std::make_pair(ID, + llvmAsmlineno))); + + if (inFunctionScope()) + InsertValue(V, CurFun.LateResolveValues); + else + InsertValue(V, CurModule.LateResolveValues); + return V; +} + +/// getBBVal - This is used for two purposes: +/// * If isDefinition is true, a new basic block with the specified ID is being +/// defined. +/// * If isDefinition is true, this is a reference to a basic block, which may +/// or may not be a forward reference. +/// +static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) { + assert(inFunctionScope() && "Can't get basic block at global scope!"); + + std::string Name; + BasicBlock *BB = 0; + switch (ID.Type) { + default: ThrowException("Illegal label reference " + ID.getName()); + case ValID::NumberVal: // Is it a numbered definition? + if (unsigned(ID.Num) >= CurFun.NumberedBlocks.size()) + CurFun.NumberedBlocks.resize(ID.Num+1); + BB = CurFun.NumberedBlocks[ID.Num]; + break; + case ValID::NameVal: // Is it a named definition? + Name = ID.Name; + if (Value *N = CurFun.CurrentFunction-> + getSymbolTable().lookup(Type::LabelTy, Name)) + BB = cast(N); + break; + } + + // See if the block has already been defined. + if (BB) { + // If this is the definition of the block, make sure the existing value was + // just a forward reference. If it was a forward reference, there will be + // an entry for it in the PlaceHolderInfo map. + if (isDefinition && !CurFun.BBForwardRefs.erase(BB)) + // The existing value was a definition, not a forward reference. + ThrowException("Redefinition of label " + ID.getName()); + + ID.destroy(); // Free strdup'd memory. + return BB; + } + + // Otherwise this block has not been seen before. + BB = new BasicBlock("", CurFun.CurrentFunction); + if (ID.Type == ValID::NameVal) { + BB->setName(ID.Name); + } else { + CurFun.NumberedBlocks[ID.Num] = BB; + } + + // If this is not a definition, keep track of it so we can use it as a forward + // reference. + if (!isDefinition) { + // Remember where this forward reference came from. + CurFun.BBForwardRefs[BB] = std::make_pair(ID, llvmAsmlineno); + } else { + // The forward declaration could have been inserted anywhere in the + // function: insert it into the correct place now. + CurFun.CurrentFunction->getBasicBlockList().remove(BB); + CurFun.CurrentFunction->getBasicBlockList().push_back(BB); + } + ID.destroy(); + return BB; +} + + +//===----------------------------------------------------------------------===// +// Code to handle forward references in instructions +//===----------------------------------------------------------------------===// +// +// This code handles the late binding needed with statements that reference +// values not defined yet... for example, a forward branch, or the PHI node for +// a loop body. +// +// This keeps a table (CurFun.LateResolveValues) of all such forward references +// and back patchs after we are done. +// + +// ResolveDefinitions - If we could not resolve some defs at parsing +// time (forward branches, phi functions for loops, etc...) resolve the +// defs now... +// +static void +ResolveDefinitions(std::map &LateResolvers, + std::map *FutureLateResolvers) { + // Loop over LateResolveDefs fixing up stuff that couldn't be resolved + for (std::map::iterator LRI = LateResolvers.begin(), + E = LateResolvers.end(); LRI != E; ++LRI) { + ValueList &List = LRI->second; + while (!List.empty()) { + Value *V = List.back(); + List.pop_back(); + + std::map >::iterator PHI = + CurModule.PlaceHolderInfo.find(V); + assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error!"); + + ValID &DID = PHI->second.first; + + Value *TheRealValue = getValNonImprovising(LRI->first, DID); + if (TheRealValue) { + V->replaceAllUsesWith(TheRealValue); + delete V; + CurModule.PlaceHolderInfo.erase(PHI); + } else if (FutureLateResolvers) { + // Functions have their unresolved items forwarded to the module late + // resolver table + InsertValue(V, *FutureLateResolvers); + } else { + if (DID.Type == ValID::NameVal) + ThrowException("Reference to an invalid definition: '" +DID.getName()+ + "' of type '" + V->getType()->getDescription() + "'", + PHI->second.second); + else + ThrowException("Reference to an invalid definition: #" + + itostr(DID.Num) + " of type '" + + V->getType()->getDescription() + "'", + PHI->second.second); + } + } + } + + LateResolvers.clear(); +} + +// ResolveTypeTo - A brand new type was just declared. This means that (if +// name is not null) things referencing Name can be resolved. Otherwise, things +// refering to the number can be resolved. Do this now. +// +static void ResolveTypeTo(char *Name, const Type *ToTy) { + ValID D; + if (Name) D = ValID::create(Name); + else D = ValID::create((int)CurModule.Types.size()); + + std::map::iterator I = + CurModule.LateResolveTypes.find(D); + if (I != CurModule.LateResolveTypes.end()) { + ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); + CurModule.LateResolveTypes.erase(I); + } +} + +// setValueName - Set the specified value to the name given. The name may be +// null potentially, in which case this is a noop. The string passed in is +// assumed to be a malloc'd string buffer, and is free'd by this function. +// +static void setValueName(Value *V, char *NameStr) { + if (NameStr) { + std::string Name(NameStr); // Copy string + free(NameStr); // Free old string + + if (V->getType() == Type::VoidTy) + ThrowException("Can't assign name '" + Name+"' to value with void type!"); + + assert(inFunctionScope() && "Must be in function scope!"); + SymbolTable &ST = CurFun.CurrentFunction->getSymbolTable(); + if (ST.lookup(V->getType(), Name)) + ThrowException("Redefinition of value named '" + Name + "' in the '" + + V->getType()->getDescription() + "' type plane!"); + + // Set the name. + V->setName(Name); + } +} + +/// ParseGlobalVariable - Handle parsing of a global. If Initializer is null, +/// this is a declaration, otherwise it is a definition. +static GlobalVariable * +ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, + bool isConstantGlobal, const Type *Ty, + Constant *Initializer) { + if (isa(Ty)) + ThrowException("Cannot declare global vars of function type!"); + + const PointerType *PTy = PointerType::get(Ty); + + std::string Name; + if (NameStr) { + Name = NameStr; // Copy string + free(NameStr); // Free old string + } + + // See if this global value was forward referenced. If so, recycle the + // object. + ValID ID; + if (!Name.empty()) { + ID = ValID::create((char*)Name.c_str()); + } else { + ID = ValID::create((int)CurModule.Values[PTy].size()); + } + + if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) { + // Move the global to the end of the list, from whereever it was + // previously inserted. + GlobalVariable *GV = cast(FWGV); + CurModule.CurrentModule->getGlobalList().remove(GV); + CurModule.CurrentModule->getGlobalList().push_back(GV); + GV->setInitializer(Initializer); + GV->setLinkage(Linkage); + GV->setConstant(isConstantGlobal); + InsertValue(GV, CurModule.Values); + return GV; + } + + // If this global has a name, check to see if there is already a definition + // of this global in the module. If so, merge as appropriate. Note that + // this is really just a hack around problems in the CFE. :( + if (!Name.empty()) { + // We are a simple redefinition of a value, check to see if it is defined + // the same as the old one. + if (GlobalVariable *EGV = + CurModule.CurrentModule->getGlobalVariable(Name, Ty)) { + // We are allowed to redefine a global variable in two circumstances: + // 1. If at least one of the globals is uninitialized or + // 2. If both initializers have the same value. + // + if (!EGV->hasInitializer() || !Initializer || + EGV->getInitializer() == Initializer) { + + // Make sure the existing global version gets the initializer! Make + // sure that it also gets marked const if the new version is. + if (Initializer && !EGV->hasInitializer()) + EGV->setInitializer(Initializer); + if (isConstantGlobal) + EGV->setConstant(true); + EGV->setLinkage(Linkage); + return EGV; + } + + ThrowException("Redefinition of global variable named '" + Name + + "' in the '" + Ty->getDescription() + "' type plane!"); + } + } + + // Otherwise there is no existing GV to use, create one now. + GlobalVariable *GV = + new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, + CurModule.CurrentModule); + InsertValue(GV, CurModule.Values); + return GV; +} + +// setTypeName - Set the specified type to the name given. The name may be +// null potentially, in which case this is a noop. The string passed in is +// assumed to be a malloc'd string buffer, and is freed by this function. +// +// This function returns true if the type has already been defined, but is +// allowed to be redefined in the specified context. If the name is a new name +// for the type plane, it is inserted and false is returned. +static bool setTypeName(const Type *T, char *NameStr) { + assert(!inFunctionScope() && "Can't give types function-local names!"); + if (NameStr == 0) return false; + + std::string Name(NameStr); // Copy string + free(NameStr); // Free old string + + // We don't allow assigning names to void type + if (T == Type::VoidTy) + ThrowException("Can't assign name '" + Name + "' to the void type!"); + + // Set the type name, checking for conflicts as we do so. + bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, T); + + if (AlreadyExists) { // Inserting a name that is already defined??? + const Type *Existing = CurModule.CurrentModule->getTypeByName(Name); + assert(Existing && "Conflict but no matching type?"); + + // There is only one case where this is allowed: when we are refining an + // opaque type. In this case, Existing will be an opaque type. + if (const OpaqueType *OpTy = dyn_cast(Existing)) { + // We ARE replacing an opaque type! + const_cast(OpTy)->refineAbstractTypeTo(T); + return true; + } + + // Otherwise, this is an attempt to redefine a type. That's okay if + // the redefinition is identical to the original. This will be so if + // Existing and T point to the same Type object. In this one case we + // allow the equivalent redefinition. + if (Existing == T) return true; // Yes, it's equal. + + // Any other kind of (non-equivalent) redefinition is an error. + ThrowException("Redefinition of type named '" + Name + "' in the '" + + T->getDescription() + "' type plane!"); + } + + return false; +} + +//===----------------------------------------------------------------------===// +// Code for handling upreferences in type names... +// + +// TypeContains - Returns true if Ty directly contains E in it. +// +static bool TypeContains(const Type *Ty, const Type *E) { + return std::find(Ty->subtype_begin(), Ty->subtype_end(), + E) != Ty->subtype_end(); +} + +namespace { + struct UpRefRecord { + // NestingLevel - The number of nesting levels that need to be popped before + // this type is resolved. + unsigned NestingLevel; + + // LastContainedTy - This is the type at the current binding level for the + // type. Every time we reduce the nesting level, this gets updated. + const Type *LastContainedTy; + + // UpRefTy - This is the actual opaque type that the upreference is + // represented with. + OpaqueType *UpRefTy; + + UpRefRecord(unsigned NL, OpaqueType *URTy) + : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) {} + }; +} + +// UpRefs - A list of the outstanding upreferences that need to be resolved. +static std::vector UpRefs; + +/// HandleUpRefs - Every time we finish a new layer of types, this function is +/// called. It loops through the UpRefs vector, which is a list of the +/// currently active types. For each type, if the up reference is contained in +/// the newly completed type, we decrement the level count. When the level +/// count reaches zero, the upreferenced type is the type that is passed in: +/// thus we can complete the cycle. +/// +static PATypeHolder HandleUpRefs(const Type *ty) { + if (!ty->isAbstract()) return ty; + PATypeHolder Ty(ty); + UR_OUT("Type '" << Ty->getDescription() << + "' newly formed. Resolving upreferences.\n" << + UpRefs.size() << " upreferences active!\n"); + + // If we find any resolvable upreferences (i.e., those whose NestingLevel goes + // to zero), we resolve them all together before we resolve them to Ty. At + // the end of the loop, if there is anything to resolve to Ty, it will be in + // this variable. + OpaqueType *TypeToResolve = 0; + + for (unsigned i = 0; i != UpRefs.size(); ++i) { + UR_OUT(" UR#" << i << " - TypeContains(" << Ty->getDescription() << ", " + << UpRefs[i].second->getDescription() << ") = " + << (TypeContains(Ty, UpRefs[i].second) ? "true" : "false") << "\n"); + if (TypeContains(Ty, UpRefs[i].LastContainedTy)) { + // Decrement level of upreference + unsigned Level = --UpRefs[i].NestingLevel; + UpRefs[i].LastContainedTy = Ty; + UR_OUT(" Uplevel Ref Level = " << Level << "\n"); + if (Level == 0) { // Upreference should be resolved! + if (!TypeToResolve) { + TypeToResolve = UpRefs[i].UpRefTy; + } else { + UR_OUT(" * Resolving upreference for " + << UpRefs[i].second->getDescription() << "\n"; + std::string OldName = UpRefs[i].UpRefTy->getDescription()); + UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve); + UR_OUT(" * Type '" << OldName << "' refined upreference to: " + << (const void*)Ty << ", " << Ty->getDescription() << "\n"); + } + UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list... + --i; // Do not skip the next element... + } + } + } + + if (TypeToResolve) { + UR_OUT(" * Resolving upreference for " + << UpRefs[i].second->getDescription() << "\n"; + std::string OldName = TypeToResolve->getDescription()); + TypeToResolve->refineAbstractTypeTo(Ty); + } + + return Ty; +} + + +// common code from the two 'RunVMAsmParser' functions + static Module * RunParser(Module * M) { + + llvmAsmlineno = 1; // Reset the current line number... + ObsoleteVarArgs = false; + NewVarArgs = false; + + CurModule.CurrentModule = M; + yyparse(); // Parse the file, potentially throwing exception + + Module *Result = ParserResult; + ParserResult = 0; + + //Not all functions use vaarg, so make a second check for ObsoleteVarArgs + { + Function* F; + if ((F = Result->getNamedFunction("llvm.va_start")) + && F->getFunctionType()->getNumParams() == 0) + ObsoleteVarArgs = true; + if((F = Result->getNamedFunction("llvm.va_copy")) + && F->getFunctionType()->getNumParams() == 1) + ObsoleteVarArgs = true; + } + + if (ObsoleteVarArgs && NewVarArgs) + ThrowException("This file is corrupt: it uses both new and old style varargs"); + + if(ObsoleteVarArgs) { + if(Function* F = Result->getNamedFunction("llvm.va_start")) { + if (F->arg_size() != 0) + ThrowException("Obsolete va_start takes 0 argument!"); + + //foo = va_start() + // -> + //bar = alloca typeof(foo) + //va_start(bar) + //foo = load bar + + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getReturnType(); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = Result->getOrInsertFunction("llvm.va_start", + RetTy, ArgTyPtr, (Type *)0); + + while (!F->use_empty()) { + CallInst* CI = cast(F->use_back()); + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI); + new CallInst(NF, bar, "", CI); + Value* foo = new LoadInst(bar, "vastart.fix.2", CI); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + Result->getFunctionList().erase(F); + } + + if(Function* F = Result->getNamedFunction("llvm.va_end")) { + if(F->arg_size() != 1) + ThrowException("Obsolete va_end takes 1 argument!"); + + //vaend foo + // -> + //bar = alloca 1 of typeof(foo) + //vaend bar + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getParamType(0); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = Result->getOrInsertFunction("llvm.va_end", + RetTy, ArgTyPtr, (Type *)0); + + while (!F->use_empty()) { + CallInst* CI = cast(F->use_back()); + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI); + new StoreInst(CI->getOperand(1), bar, CI); + new CallInst(NF, bar, "", CI); + CI->getParent()->getInstList().erase(CI); + } + Result->getFunctionList().erase(F); + } + + if(Function* F = Result->getNamedFunction("llvm.va_copy")) { + if(F->arg_size() != 1) + ThrowException("Obsolete va_copy takes 1 argument!"); + //foo = vacopy(bar) + // -> + //a = alloca 1 of typeof(foo) + //b = alloca 1 of typeof(foo) + //store bar -> b + //vacopy(a, b) + //foo = load a + + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getReturnType(); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = Result->getOrInsertFunction("llvm.va_copy", + RetTy, ArgTyPtr, ArgTyPtr, + (Type *)0); + + while (!F->use_empty()) { + CallInst* CI = cast(F->use_back()); + AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); + AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI); + new StoreInst(CI->getOperand(1), b, CI); + new CallInst(NF, a, b, "", CI); + Value* foo = new LoadInst(a, "vacopy.fix.3", CI); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + Result->getFunctionList().erase(F); + } + } + + return Result; + + } + +//===----------------------------------------------------------------------===// +// RunVMAsmParser - Define an interface to this parser +//===----------------------------------------------------------------------===// +// +Module *llvm::RunVMAsmParser(const std::string &Filename, FILE *F) { + set_scan_file(F); + + CurFilename = Filename; + return RunParser(new Module(CurFilename)); +} + +Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { + set_scan_string(AsmString); + + CurFilename = "from_memory"; + if (M == NULL) { + return RunParser(new Module (CurFilename)); + } else { + return RunParser(M); + } +} + +%} + +%union { + llvm::Module *ModuleVal; + llvm::Function *FunctionVal; + std::pair *ArgVal; + llvm::BasicBlock *BasicBlockVal; + llvm::TerminatorInst *TermInstVal; + llvm::Instruction *InstVal; + llvm::Constant *ConstVal; + + const llvm::Type *PrimType; + llvm::PATypeHolder *TypeVal; + llvm::Value *ValueVal; + + std::vector > *ArgList; + std::vector *ValueList; + std::list *TypeList; + // Represent the RHS of PHI node + std::list > *PHIList; + std::vector > *JumpTable; + std::vector *ConstVector; + + llvm::GlobalValue::LinkageTypes Linkage; + int64_t SInt64Val; + uint64_t UInt64Val; + int SIntVal; + unsigned UIntVal; + double FPVal; + bool BoolVal; + + char *StrVal; // This memory is strdup'd! + llvm::ValID ValIDVal; // strdup'd memory maybe! + + llvm::Instruction::BinaryOps BinaryOpVal; + llvm::Instruction::TermOps TermOpVal; + llvm::Instruction::MemoryOps MemOpVal; + llvm::Instruction::OtherOps OtherOpVal; + llvm::Module::Endianness Endianness; +} + +%type Module FunctionList +%type Function FunctionProto FunctionHeader BasicBlockList +%type BasicBlock InstructionList +%type BBTerminatorInst +%type Inst InstVal MemoryInst +%type ConstVal ConstExpr +%type ConstVector +%type ArgList ArgListH +%type ArgVal +%type PHIList +%type ValueRefList ValueRefListE // For call param lists +%type IndexList // For GEP derived indices +%type TypeListI ArgTypeListI +%type JumpTable +%type GlobalType // GLOBAL or CONSTANT? +%type OptVolatile // 'volatile' or not +%type OptTailCall // TAIL CALL or plain CALL. +%type OptSideEffect // 'sideeffect' or not. +%type OptLinkage +%type BigOrLittle + +// ValueRef - Unresolved reference to a definition or BB +%type ValueRef ConstValueRef SymbolicValueRef +%type ResolvedVal // pair +// Tokens and types for handling constant integer values +// +// ESINT64VAL - A negative number within long long range +%token ESINT64VAL + +// EUINT64VAL - A positive number within uns. long long range +%token EUINT64VAL +%type EINT64VAL + +%token SINTVAL // Signed 32 bit ints... +%token UINTVAL // Unsigned 32 bit ints... +%type INTVAL +%token FPVAL // Float or Double constant + +// Built in types... +%type Types TypesV UpRTypes UpRTypesV +%type SIntType UIntType IntType FPType PrimType // Classifications +%token VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG +%token FLOAT DOUBLE TYPE LABEL + +%token VAR_ID LABELSTR STRINGCONSTANT +%type Name OptName OptAssign +%type OptAlign OptCAlign +%type OptSection SectionString + +%token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK +%token DECLARE GLOBAL CONSTANT SECTION VOLATILE +%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING +%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN +%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT +%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK +%type OptCallingConv + +// Basic Block Terminating Operators +%token RET BR SWITCH INVOKE UNWIND UNREACHABLE + +// Binary Operators +%type ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories +%token ADD SUB MUL DIV REM AND OR XOR +%token SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comarators + +// Memory Instructions +%token MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR + +// Other Operators +%type ShiftOps +%token PHI_TOK CAST SELECT SHL SHR VAARG +%token EXTRACTELEMENT INSERTELEMENT +%token VAARG_old VANEXT_old //OBSOLETE + + +%start Module +%% + +// Handle constant integer size restriction and conversion... +// +INTVAL : SINTVAL; +INTVAL : UINTVAL { + if ($1 > (uint32_t)INT32_MAX) // Outside of my range! + ThrowException("Value too large for type!"); + $$ = (int32_t)$1; +}; + + +EINT64VAL : ESINT64VAL; // These have same type and can't cause problems... +EINT64VAL : EUINT64VAL { + if ($1 > (uint64_t)INT64_MAX) // Outside of my range! + ThrowException("Value too large for type!"); + $$ = (int64_t)$1; +}; + +// Operations that are notably excluded from this list include: +// RET, BR, & SWITCH because they end basic blocks and are treated specially. +// +ArithmeticOps: ADD | SUB | MUL | DIV | REM; +LogicalOps : AND | OR | XOR; +SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE; + +ShiftOps : SHL | SHR; + +// These are some types that allow classification if we only want a particular +// thing... for example, only a signed, unsigned, or integral type. +SIntType : LONG | INT | SHORT | SBYTE; +UIntType : ULONG | UINT | USHORT | UBYTE; +IntType : SIntType | UIntType; +FPType : FLOAT | DOUBLE; + +// OptAssign - Value producing statements have an optional assignment component +OptAssign : Name '=' { + $$ = $1; + } + | /*empty*/ { + $$ = 0; + }; + +OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } | + LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } | + WEAK { $$ = GlobalValue::WeakLinkage; } | + APPENDING { $$ = GlobalValue::AppendingLinkage; } | + /*empty*/ { $$ = GlobalValue::ExternalLinkage; }; + +OptCallingConv : /*empty*/ { $$ = CallingConv::C; } | + CCC_TOK { $$ = CallingConv::C; } | + FASTCC_TOK { $$ = CallingConv::Fast; } | + COLDCC_TOK { $$ = CallingConv::Cold; } | + CC_TOK EUINT64VAL { + if ((unsigned)$2 != $2) + ThrowException("Calling conv too large!"); + $$ = $2; + }; + +// OptAlign/OptCAlign - An optional alignment, and an optional alignment with +// a comma before it. +OptAlign : /*empty*/ { $$ = 0; } | + ALIGN EUINT64VAL { + $$ = $2; + if ($$ != 0 && !isPowerOf2_32($$)) + ThrowException("Alignment must be a power of two!"); +}; +OptCAlign : /*empty*/ { $$ = 0; } | + ',' ALIGN EUINT64VAL { + $$ = $3; + if ($$ != 0 && !isPowerOf2_32($$)) + ThrowException("Alignment must be a power of two!"); +}; + + +SectionString : SECTION STRINGCONSTANT { + for (unsigned i = 0, e = strlen($2); i != e; ++i) + if ($2[i] == '"' || $2[i] == '\\') + ThrowException("Invalid character in section name!"); + $$ = $2; +}; + +OptSection : /*empty*/ { $$ = 0; } | + SectionString { $$ = $1; }; + +// GlobalVarAttributes - Used to pass the attributes string on a global. CurGV +// is set to be the global we are processing. +// +GlobalVarAttributes : /* empty */ {} | + ',' GlobalVarAttribute GlobalVarAttributes {}; +GlobalVarAttribute : SectionString { + CurGV->setSection($1); + free($1); + } + | ALIGN EUINT64VAL { + if ($2 != 0 && !isPowerOf2_32($2)) + ThrowException("Alignment must be a power of two!"); + CurGV->setAlignment($2); + }; + +//===----------------------------------------------------------------------===// +// Types includes all predefined types... except void, because it can only be +// used in specific contexts (function returning void for example). To have +// access to it, a user must explicitly use TypesV. +// + +// TypesV includes all of 'Types', but it also includes the void type. +TypesV : Types | VOID { $$ = new PATypeHolder($1); }; +UpRTypesV : UpRTypes | VOID { $$ = new PATypeHolder($1); }; + +Types : UpRTypes { + if (!UpRefs.empty()) + ThrowException("Invalid upreference in type: " + (*$1)->getDescription()); + $$ = $1; + }; + + +// Derived types are added later... +// +PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ; +PrimType : LONG | ULONG | FLOAT | DOUBLE | TYPE | LABEL; +UpRTypes : OPAQUE { + $$ = new PATypeHolder(OpaqueType::get()); + } + | PrimType { + $$ = new PATypeHolder($1); + }; +UpRTypes : SymbolicValueRef { // Named types are also simple types... + $$ = new PATypeHolder(getTypeVal($1)); +}; + +// Include derived types in the Types production. +// +UpRTypes : '\\' EUINT64VAL { // Type UpReference + if ($2 > (uint64_t)~0U) ThrowException("Value out of range!"); + OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder + UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector... + $$ = new PATypeHolder(OT); + UR_OUT("New Upreference!\n"); + } + | UpRTypesV '(' ArgTypeListI ')' { // Function derived type? + std::vector Params; + for (std::list::iterator I = $3->begin(), + E = $3->end(); I != E; ++I) + Params.push_back(*I); + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; + if (isVarArg) Params.pop_back(); + + $$ = new PATypeHolder(HandleUpRefs(FunctionType::get(*$1,Params,isVarArg))); + delete $3; // Delete the argument list + delete $1; // Delete the return type handle + } + | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type? + $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2))); + delete $4; + } + | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type? + const llvm::Type* ElemTy = $4->get(); + if ((unsigned)$2 != $2) + ThrowException("Unsigned result not equal to signed result"); + if (!ElemTy->isPrimitiveType()) + ThrowException("Elemental type of a PackedType must be primitive"); + if (!isPowerOf2_32($2)) + ThrowException("Vector length should be a power of 2!"); + $$ = new PATypeHolder(HandleUpRefs(PackedType::get(*$4, (unsigned)$2))); + delete $4; + } + | '{' TypeListI '}' { // Structure type? + std::vector Elements; + for (std::list::iterator I = $2->begin(), + E = $2->end(); I != E; ++I) + Elements.push_back(*I); + + $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); + delete $2; + } + | '{' '}' { // Empty structure type? + $$ = new PATypeHolder(StructType::get(std::vector())); + } + | UpRTypes '*' { // Pointer type? + $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1))); + delete $1; + }; + +// TypeList - Used for struct declarations and as a basis for function type +// declaration type lists +// +TypeListI : UpRTypes { + $$ = new std::list(); + $$->push_back(*$1); delete $1; + } + | TypeListI ',' UpRTypes { + ($$=$1)->push_back(*$3); delete $3; + }; + +// ArgTypeList - List of types for a function type declaration... +ArgTypeListI : TypeListI + | TypeListI ',' DOTDOTDOT { + ($$=$1)->push_back(Type::VoidTy); + } + | DOTDOTDOT { + ($$ = new std::list())->push_back(Type::VoidTy); + } + | /*empty*/ { + $$ = new std::list(); + }; + +// ConstVal - The various declarations that go into the constant pool. This +// production is used ONLY to represent constants that show up AFTER a 'const', +// 'constant' or 'global' token at global scope. Constants that can be inlined +// into other expressions (such as integers and constexprs) are handled by the +// ResolvedVal, ValueRef and ConstValueRef productions. +// +ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr + const ArrayType *ATy = dyn_cast($1->get()); + if (ATy == 0) + ThrowException("Cannot make array constant with type: '" + + (*$1)->getDescription() + "'!"); + const Type *ETy = ATy->getElementType(); + int NumElements = ATy->getNumElements(); + + // Verify that we have the correct size... + if (NumElements != -1 && NumElements != (int)$3->size()) + ThrowException("Type mismatch: constant sized array initialized with " + + utostr($3->size()) + " arguments, but has size of " + + itostr(NumElements) + "!"); + + // Verify all elements are correct type! + for (unsigned i = 0; i < $3->size(); i++) { + if (ETy != (*$3)[i]->getType()) + ThrowException("Element #" + utostr(i) + " is not of type '" + + ETy->getDescription() +"' as required!\nIt is of type '"+ + (*$3)[i]->getType()->getDescription() + "'."); + } + + $$ = ConstantArray::get(ATy, *$3); + delete $1; delete $3; + } + | Types '[' ']' { + const ArrayType *ATy = dyn_cast($1->get()); + if (ATy == 0) + ThrowException("Cannot make array constant with type: '" + + (*$1)->getDescription() + "'!"); + + int NumElements = ATy->getNumElements(); + if (NumElements != -1 && NumElements != 0) + ThrowException("Type mismatch: constant sized array initialized with 0" + " arguments, but has size of " + itostr(NumElements) +"!"); + $$ = ConstantArray::get(ATy, std::vector()); + delete $1; + } + | Types 'c' STRINGCONSTANT { + const ArrayType *ATy = dyn_cast($1->get()); + if (ATy == 0) + ThrowException("Cannot make array constant with type: '" + + (*$1)->getDescription() + "'!"); + + int NumElements = ATy->getNumElements(); + const Type *ETy = ATy->getElementType(); + char *EndStr = UnEscapeLexed($3, true); + if (NumElements != -1 && NumElements != (EndStr-$3)) + ThrowException("Can't build string constant of size " + + itostr((int)(EndStr-$3)) + + " when array has size " + itostr(NumElements) + "!"); + std::vector Vals; + if (ETy == Type::SByteTy) { + for (signed char *C = (signed char *)$3; C != (signed char *)EndStr; ++C) + Vals.push_back(ConstantSInt::get(ETy, *C)); + } else if (ETy == Type::UByteTy) { + for (unsigned char *C = (unsigned char *)$3; + C != (unsigned char*)EndStr; ++C) + Vals.push_back(ConstantUInt::get(ETy, *C)); + } else { + free($3); + ThrowException("Cannot build string arrays of non byte sized elements!"); + } + free($3); + $$ = ConstantArray::get(ATy, Vals); + delete $1; + } + | Types '<' ConstVector '>' { // Nonempty unsized arr + const PackedType *PTy = dyn_cast($1->get()); + if (PTy == 0) + ThrowException("Cannot make packed constant with type: '" + + (*$1)->getDescription() + "'!"); + const Type *ETy = PTy->getElementType(); + int NumElements = PTy->getNumElements(); + + // Verify that we have the correct size... + if (NumElements != -1 && NumElements != (int)$3->size()) + ThrowException("Type mismatch: constant sized packed initialized with " + + utostr($3->size()) + " arguments, but has size of " + + itostr(NumElements) + "!"); + + // Verify all elements are correct type! + for (unsigned i = 0; i < $3->size(); i++) { + if (ETy != (*$3)[i]->getType()) + ThrowException("Element #" + utostr(i) + " is not of type '" + + ETy->getDescription() +"' as required!\nIt is of type '"+ + (*$3)[i]->getType()->getDescription() + "'."); + } + + $$ = ConstantPacked::get(PTy, *$3); + delete $1; delete $3; + } + | Types '{' ConstVector '}' { + const StructType *STy = dyn_cast($1->get()); + if (STy == 0) + ThrowException("Cannot make struct constant with type: '" + + (*$1)->getDescription() + "'!"); + + if ($3->size() != STy->getNumContainedTypes()) + ThrowException("Illegal number of initializers for structure type!"); + + // Check to ensure that constants are compatible with the type initializer! + for (unsigned i = 0, e = $3->size(); i != e; ++i) + if ((*$3)[i]->getType() != STy->getElementType(i)) + ThrowException("Expected type '" + + STy->getElementType(i)->getDescription() + + "' for element #" + utostr(i) + + " of structure initializer!"); + + $$ = ConstantStruct::get(STy, *$3); + delete $1; delete $3; + } + | Types '{' '}' { + const StructType *STy = dyn_cast($1->get()); + if (STy == 0) + ThrowException("Cannot make struct constant with type: '" + + (*$1)->getDescription() + "'!"); + + if (STy->getNumContainedTypes() != 0) + ThrowException("Illegal number of initializers for structure type!"); + + $$ = ConstantStruct::get(STy, std::vector()); + delete $1; + } + | Types NULL_TOK { + const PointerType *PTy = dyn_cast($1->get()); + if (PTy == 0) + ThrowException("Cannot make null pointer constant with type: '" + + (*$1)->getDescription() + "'!"); + + $$ = ConstantPointerNull::get(PTy); + delete $1; + } + | Types UNDEF { + $$ = UndefValue::get($1->get()); + delete $1; + } + | Types SymbolicValueRef { + const PointerType *Ty = dyn_cast($1->get()); + if (Ty == 0) + ThrowException("Global const reference must be a pointer type!"); + + // ConstExprs can exist in the body of a function, thus creating + // GlobalValues whenever they refer to a variable. Because we are in + // the context of a function, getValNonImprovising will search the functions + // symbol table instead of the module symbol table for the global symbol, + // which throws things all off. To get around this, we just tell + // getValNonImprovising that we are at global scope here. + // + Function *SavedCurFn = CurFun.CurrentFunction; + CurFun.CurrentFunction = 0; + + Value *V = getValNonImprovising(Ty, $2); + + CurFun.CurrentFunction = SavedCurFn; + + // If this is an initializer for a constant pointer, which is referencing a + // (currently) undefined variable, create a stub now that shall be replaced + // in the future with the right type of variable. + // + if (V == 0) { + assert(isa(Ty) && "Globals may only be used as pointers!"); + const PointerType *PT = cast(Ty); + + // First check to see if the forward references value is already created! + PerModuleInfo::GlobalRefsType::iterator I = + CurModule.GlobalRefs.find(std::make_pair(PT, $2)); + + if (I != CurModule.GlobalRefs.end()) { + V = I->second; // Placeholder already exists, use it... + $2.destroy(); + } else { + std::string Name; + if ($2.Type == ValID::NameVal) Name = $2.Name; + + // Create the forward referenced global. + GlobalValue *GV; + if (const FunctionType *FTy = + dyn_cast(PT->getElementType())) { + GV = new Function(FTy, GlobalValue::ExternalLinkage, Name, + CurModule.CurrentModule); + } else { + GV = new GlobalVariable(PT->getElementType(), false, + GlobalValue::ExternalLinkage, 0, + Name, CurModule.CurrentModule); + } + + // Keep track of the fact that we have a forward ref to recycle it + CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, $2), GV)); + V = GV; + } + } + + $$ = cast(V); + delete $1; // Free the type handle + } + | Types ConstExpr { + if ($1->get() != $2->getType()) + ThrowException("Mismatched types for constant expression!"); + $$ = $2; + delete $1; + } + | Types ZEROINITIALIZER { + const Type *Ty = $1->get(); + if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) + ThrowException("Cannot create a null initialized value of this type!"); + $$ = Constant::getNullValue(Ty); + delete $1; + }; + +ConstVal : SIntType EINT64VAL { // integral constants + if (!ConstantSInt::isValueValidForType($1, $2)) + ThrowException("Constant value doesn't fit in type!"); + $$ = ConstantSInt::get($1, $2); + } + | UIntType EUINT64VAL { // integral constants + if (!ConstantUInt::isValueValidForType($1, $2)) + ThrowException("Constant value doesn't fit in type!"); + $$ = ConstantUInt::get($1, $2); + } + | BOOL TRUETOK { // Boolean constants + $$ = ConstantBool::True; + } + | BOOL FALSETOK { // Boolean constants + $$ = ConstantBool::False; + } + | FPType FPVAL { // Float & Double constants + if (!ConstantFP::isValueValidForType($1, $2)) + ThrowException("Floating point constant invalid for type!!"); + $$ = ConstantFP::get($1, $2); + }; + + +ConstExpr: CAST '(' ConstVal TO Types ')' { + if (!$3->getType()->isFirstClassType()) + ThrowException("cast constant expression from a non-primitive type: '" + + $3->getType()->getDescription() + "'!"); + if (!$5->get()->isFirstClassType()) + ThrowException("cast constant expression to a non-primitive type: '" + + $5->get()->getDescription() + "'!"); + $$ = ConstantExpr::getCast($3, $5->get()); + delete $5; + } + | GETELEMENTPTR '(' ConstVal IndexList ')' { + if (!isa($3->getType())) + ThrowException("GetElementPtr requires a pointer operand!"); + + // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte struct + // indices to uint struct indices for compatibility. + generic_gep_type_iterator::iterator> + GTI = gep_type_begin($3->getType(), $4->begin(), $4->end()), + GTE = gep_type_end($3->getType(), $4->begin(), $4->end()); + for (unsigned i = 0, e = $4->size(); i != e && GTI != GTE; ++i, ++GTI) + if (isa(*GTI)) // Only change struct indices + if (ConstantUInt *CUI = dyn_cast((*$4)[i])) + if (CUI->getType() == Type::UByteTy) + (*$4)[i] = ConstantExpr::getCast(CUI, Type::UIntTy); + + const Type *IdxTy = + GetElementPtrInst::getIndexedType($3->getType(), *$4, true); + if (!IdxTy) + ThrowException("Index list invalid for constant getelementptr!"); + + std::vector IdxVec; + for (unsigned i = 0, e = $4->size(); i != e; ++i) + if (Constant *C = dyn_cast((*$4)[i])) + IdxVec.push_back(C); + else + ThrowException("Indices to constant getelementptr must be constants!"); + + delete $4; + + $$ = ConstantExpr::getGetElementPtr($3, IdxVec); + } + | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' { + if ($3->getType() != Type::BoolTy) + ThrowException("Select condition must be of boolean type!"); + if ($5->getType() != $7->getType()) + ThrowException("Select operand types must match!"); + $$ = ConstantExpr::getSelect($3, $5, $7); + } + | ArithmeticOps '(' ConstVal ',' ConstVal ')' { + if ($3->getType() != $5->getType()) + ThrowException("Binary operator types must match!"); + // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs. + // To retain backward compatibility with these early compilers, we emit a + // cast to the appropriate integer type automatically if we are in the + // broken case. See PR424 for more information. + if (!isa($3->getType())) { + $$ = ConstantExpr::get($1, $3, $5); + } else { + const Type *IntPtrTy = 0; + switch (CurModule.CurrentModule->getPointerSize()) { + case Module::Pointer32: IntPtrTy = Type::IntTy; break; + case Module::Pointer64: IntPtrTy = Type::LongTy; break; + default: ThrowException("invalid pointer binary constant expr!"); + } + $$ = ConstantExpr::get($1, ConstantExpr::getCast($3, IntPtrTy), + ConstantExpr::getCast($5, IntPtrTy)); + $$ = ConstantExpr::getCast($$, $3->getType()); + } + } + | LogicalOps '(' ConstVal ',' ConstVal ')' { + if ($3->getType() != $5->getType()) + ThrowException("Logical operator types must match!"); + if (!$3->getType()->isIntegral()) { + if (!isa($3->getType()) || + !cast($3->getType())->getElementType()->isIntegral()) + ThrowException("Logical operator requires integral operands!"); + } + $$ = ConstantExpr::get($1, $3, $5); + } + | SetCondOps '(' ConstVal ',' ConstVal ')' { + if ($3->getType() != $5->getType()) + ThrowException("setcc operand types must match!"); + $$ = ConstantExpr::get($1, $3, $5); + } + | ShiftOps '(' ConstVal ',' ConstVal ')' { + if ($5->getType() != Type::UByteTy) + ThrowException("Shift count for shift constant must be unsigned byte!"); + if (!$3->getType()->isInteger()) + ThrowException("Shift constant expression requires integer operand!"); + $$ = ConstantExpr::get($1, $3, $5); + } + | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { + if (!isa($3->getType())) + ThrowException("First operand of extractelement must be " + "packed type!"); + if ($5->getType() != Type::UIntTy) + ThrowException("Second operand of extractelement must be uint!"); + $$ = ConstantExpr::getExtractElement($3, $5); + }; + +// ConstVector - A list of comma separated constants. +ConstVector : ConstVector ',' ConstVal { + ($$ = $1)->push_back($3); + } + | ConstVal { + $$ = new std::vector(); + $$->push_back($1); + }; + + +// GlobalType - Match either GLOBAL or CONSTANT for global declarations... +GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }; + + +//===----------------------------------------------------------------------===// +// Rules to match Modules +//===----------------------------------------------------------------------===// + +// Module rule: Capture the result of parsing the whole file into a result +// variable... +// +Module : FunctionList { + $$ = ParserResult = $1; + CurModule.ModuleDone(); +}; + +// FunctionList - A list of functions, preceeded by a constant pool. +// +FunctionList : FunctionList Function { + $$ = $1; + CurFun.FunctionDone(); + } + | FunctionList FunctionProto { + $$ = $1; + } + | FunctionList MODULE ASM_TOK AsmBlock { + $$ = $1; + } + | FunctionList IMPLEMENTATION { + $$ = $1; + } + | ConstPool { + $$ = CurModule.CurrentModule; + // Emit an error if there are any unresolved types left. + if (!CurModule.LateResolveTypes.empty()) { + const ValID &DID = CurModule.LateResolveTypes.begin()->first; + if (DID.Type == ValID::NameVal) + ThrowException("Reference to an undefined type: '"+DID.getName() + "'"); + else + ThrowException("Reference to an undefined type: #" + itostr(DID.Num)); + } + }; + +// ConstPool - Constants with optional names assigned to them. +ConstPool : ConstPool OptAssign TYPE TypesV { + // Eagerly resolve types. This is not an optimization, this is a + // requirement that is due to the fact that we could have this: + // + // %list = type { %list * } + // %list = type { %list * } ; repeated type decl + // + // If types are not resolved eagerly, then the two types will not be + // determined to be the same type! + // + ResolveTypeTo($2, *$4); + + if (!setTypeName(*$4, $2) && !$2) { + // If this is a named type that is not a redefinition, add it to the slot + // table. + CurModule.Types.push_back(*$4); + } + + delete $4; + } + | ConstPool FunctionProto { // Function prototypes can be in const pool + } + | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool + } + | ConstPool OptAssign OptLinkage GlobalType ConstVal { + if ($5 == 0) ThrowException("Global value initializer is not a constant!"); + CurGV = ParseGlobalVariable($2, $3, $4, $5->getType(), $5); + } GlobalVarAttributes { + CurGV = 0; + } + | ConstPool OptAssign EXTERNAL GlobalType Types { + CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, + $4, *$5, 0); + delete $5; + } GlobalVarAttributes { + CurGV = 0; + } + | ConstPool TARGET TargetDefinition { + } + | ConstPool DEPLIBS '=' LibrariesDefinition { + } + | /* empty: end of list */ { + }; + + +AsmBlock : STRINGCONSTANT { + const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); + char *EndStr = UnEscapeLexed($1, true); + std::string NewAsm($1, EndStr); + free($1); + + if (AsmSoFar.empty()) + CurModule.CurrentModule->setModuleInlineAsm(NewAsm); + else + CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+NewAsm); +}; + +BigOrLittle : BIG { $$ = Module::BigEndian; }; +BigOrLittle : LITTLE { $$ = Module::LittleEndian; }; + +TargetDefinition : ENDIAN '=' BigOrLittle { + CurModule.CurrentModule->setEndianness($3); + } + | POINTERSIZE '=' EUINT64VAL { + if ($3 == 32) + CurModule.CurrentModule->setPointerSize(Module::Pointer32); + else if ($3 == 64) + CurModule.CurrentModule->setPointerSize(Module::Pointer64); + else + ThrowException("Invalid pointer size: '" + utostr($3) + "'!"); + } + | TRIPLE '=' STRINGCONSTANT { + CurModule.CurrentModule->setTargetTriple($3); + free($3); + }; + +LibrariesDefinition : '[' LibList ']'; + +LibList : LibList ',' STRINGCONSTANT { + CurModule.CurrentModule->addLibrary($3); + free($3); + } + | STRINGCONSTANT { + CurModule.CurrentModule->addLibrary($1); + free($1); + } + | /* empty: end of list */ { + } + ; + +//===----------------------------------------------------------------------===// +// Rules to match Function Headers +//===----------------------------------------------------------------------===// + +Name : VAR_ID | STRINGCONSTANT; +OptName : Name | /*empty*/ { $$ = 0; }; + +ArgVal : Types OptName { + if (*$1 == Type::VoidTy) + ThrowException("void typed arguments are invalid!"); + $$ = new std::pair($1, $2); +}; + +ArgListH : ArgListH ',' ArgVal { + $$ = $1; + $1->push_back(*$3); + delete $3; + } + | ArgVal { + $$ = new std::vector >(); + $$->push_back(*$1); + delete $1; + }; + +ArgList : ArgListH { + $$ = $1; + } + | ArgListH ',' DOTDOTDOT { + $$ = $1; + $$->push_back(std::pair(new PATypeHolder(Type::VoidTy), 0)); + } + | DOTDOTDOT { + $$ = new std::vector >(); + $$->push_back(std::make_pair(new PATypeHolder(Type::VoidTy), (char*)0)); + } + | /* empty */ { + $$ = 0; + }; + +FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' + OptSection OptAlign { + UnEscapeLexed($3); + std::string FunctionName($3); + free($3); // Free strdup'd memory! + + if (!(*$2)->isFirstClassType() && *$2 != Type::VoidTy) + ThrowException("LLVM functions cannot return aggregate types!"); + + std::vector ParamTypeList; + if ($5) { // If there are arguments... + for (std::vector >::iterator I = $5->begin(); + I != $5->end(); ++I) + ParamTypeList.push_back(I->first->get()); + } + + bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; + if (isVarArg) ParamTypeList.pop_back(); + + const FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg); + const PointerType *PFT = PointerType::get(FT); + delete $2; + + ValID ID; + if (!FunctionName.empty()) { + ID = ValID::create((char*)FunctionName.c_str()); + } else { + ID = ValID::create((int)CurModule.Values[PFT].size()); + } + + Function *Fn = 0; + // 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(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, FT))) { + // If this is the case, either we need to be a forward decl, or it needs + // to be. + if (!CurFun.isDeclare && !Fn->isExternal()) + ThrowException("Redefinition of function '" + FunctionName + "'!"); + + // Make sure to strip off any argument names so we can't get conflicts. + if (Fn->isExternal()) + 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); + } + + CurFun.FunctionStart(Fn); + Fn->setCallingConv($1); + Fn->setAlignment($8); + if ($7) { + Fn->setSection($7); + free($7); + } + + // 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->get() == Type::VoidTy && $5->back().second == 0&& + "Not a varargs marker!"); + delete $5->back().first; + $5->pop_back(); // Delete the last entry + } + Function::arg_iterator ArgIt = Fn->arg_begin(); + for (std::vector >::iterator I = $5->begin(); + I != $5->end(); ++I, ++ArgIt) { + delete I->first; // Delete the typeholder... + + setValueName(ArgIt, I->second); // Insert arg into symtab... + InsertValue(ArgIt); + } + + delete $5; // We're now done with the argument list + } +}; + +BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function + +FunctionHeader : OptLinkage FunctionHeaderH BEGIN { + $$ = CurFun.CurrentFunction; + + // Make sure that we keep track of the linkage type even if there was a + // previous "declare". + $$->setLinkage($1); +}; + +END : ENDTOK | '}'; // Allow end of '}' to end a function + +Function : BasicBlockList END { + $$ = $1; +}; + +FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH { + $$ = CurFun.CurrentFunction; + CurFun.FunctionDone(); +}; + +//===----------------------------------------------------------------------===// +// Rules to match Basic Blocks +//===----------------------------------------------------------------------===// + +OptSideEffect : /* empty */ { + $$ = false; + } + | SIDEEFFECT { + $$ = true; + }; + +ConstValueRef : ESINT64VAL { // A reference to a direct constant + $$ = ValID::create($1); + } + | EUINT64VAL { + $$ = ValID::create($1); + } + | FPVAL { // Perhaps it's an FP constant? + $$ = ValID::create($1); + } + | TRUETOK { + $$ = ValID::create(ConstantBool::True); + } + | FALSETOK { + $$ = ValID::create(ConstantBool::False); + } + | NULL_TOK { + $$ = ValID::createNull(); + } + | UNDEF { + $$ = ValID::createUndef(); + } + | ZEROINITIALIZER { // A vector zero constant. + $$ = ValID::createZeroInit(); + } + | '<' ConstVector '>' { // Nonempty unsized packed vector + const Type *ETy = (*$2)[0]->getType(); + int NumElements = $2->size(); + + PackedType* pt = PackedType::get(ETy, NumElements); + PATypeHolder* PTy = new PATypeHolder( + HandleUpRefs( + PackedType::get( + ETy, + NumElements) + ) + ); + + // Verify all elements are correct type! + for (unsigned i = 0; i < $2->size(); i++) { + if (ETy != (*$2)[i]->getType()) + ThrowException("Element #" + utostr(i) + " is not of type '" + + ETy->getDescription() +"' as required!\nIt is of type '" + + (*$2)[i]->getType()->getDescription() + "'."); + } + + $$ = ValID::create(ConstantPacked::get(pt, *$2)); + delete PTy; delete $2; + } + | ConstExpr { + $$ = ValID::create($1); + } + | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT { + char *End = UnEscapeLexed($3, true); + std::string AsmStr = std::string($3, End); + End = UnEscapeLexed($5, true); + std::string Constraints = std::string($5, End); + $$ = ValID::createInlineAsm(AsmStr, Constraints, $2); + free($3); + free($5); + }; + +// SymbolicValueRef - Reference to one of two ways of symbolically refering to +// another value. +// +SymbolicValueRef : INTVAL { // Is it an integer reference...? + $$ = ValID::create($1); + } + | Name { // Is it a named reference...? + $$ = ValID::create($1); + }; + +// ValueRef - A reference to a definition... either constant or symbolic +ValueRef : SymbolicValueRef | ConstValueRef; + + +// ResolvedVal - a pair. This is used only in cases where the +// type immediately preceeds the value reference, and allows complex constant +// pool references (for things like: 'ret [2 x int] [ int 12, int 42]') +ResolvedVal : Types ValueRef { + $$ = getVal(*$1, $2); delete $1; + }; + +BasicBlockList : BasicBlockList BasicBlock { + $$ = $1; + } + | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks + $$ = $1; + }; + + +// Basic blocks are terminated by branching instructions: +// br, br/cc, switch, ret +// +BasicBlock : InstructionList OptAssign BBTerminatorInst { + setValueName($3, $2); + InsertValue($3); + + $1->getInstList().push_back($3); + InsertValue($1); + $$ = $1; + }; + +InstructionList : InstructionList Inst { + $1->getInstList().push_back($2); + $$ = $1; + } + | /* empty */ { + $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); + + // Make sure to move the basic block to the correct location in the + // function, instead of leaving it inserted wherever it was first + // referenced. + Function::BasicBlockListType &BBL = + CurFun.CurrentFunction->getBasicBlockList(); + BBL.splice(BBL.end(), BBL, $$); + } + | LABELSTR { + $$ = CurBB = getBBVal(ValID::create($1), true); + + // Make sure to move the basic block to the correct location in the + // function, instead of leaving it inserted wherever it was first + // referenced. + Function::BasicBlockListType &BBL = + CurFun.CurrentFunction->getBasicBlockList(); + BBL.splice(BBL.end(), BBL, $$); + }; + +BBTerminatorInst : RET ResolvedVal { // Return with a result... + $$ = new ReturnInst($2); + } + | RET VOID { // Return with no result... + $$ = new ReturnInst(); + } + | BR LABEL ValueRef { // Unconditional Branch... + $$ = new BranchInst(getBBVal($3)); + } // Conditional Branch... + | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef { + $$ = new BranchInst(getBBVal($6), getBBVal($9), getVal(Type::BoolTy, $3)); + } + | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' { + SwitchInst *S = new SwitchInst(getVal($2, $3), getBBVal($6), $8->size()); + $$ = S; + + std::vector >::iterator I = $8->begin(), + E = $8->end(); + for (; I != E; ++I) { + if (ConstantInt *CI = dyn_cast(I->first)) + S->addCase(CI, I->second); + else + ThrowException("Switch case is constant, but not a simple integer!"); + } + delete $8; + } + | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' { + SwitchInst *S = new SwitchInst(getVal($2, $3), getBBVal($6), 0); + $$ = S; + } + | INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')' + TO LABEL ValueRef UNWIND LABEL ValueRef { + const PointerType *PFTy; + const FunctionType *Ty; + + if (!(PFTy = dyn_cast($3->get())) || + !(Ty = dyn_cast(PFTy->getElementType()))) { + // Pull out the types of all of the arguments... + std::vector ParamTypes; + if ($6) { + for (std::vector::iterator I = $6->begin(), E = $6->end(); + I != E; ++I) + ParamTypes.push_back((*I)->getType()); + } + + bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; + if (isVarArg) ParamTypes.pop_back(); + + Ty = FunctionType::get($3->get(), ParamTypes, isVarArg); + PFTy = PointerType::get(Ty); + } + + Value *V = getVal(PFTy, $4); // Get the function we're calling... + + BasicBlock *Normal = getBBVal($10); + BasicBlock *Except = getBBVal($13); + + // Create the call node... + if (!$6) { // Has no arguments? + $$ = new InvokeInst(V, Normal, Except, std::vector()); + } else { // Has arguments? + // Loop through FunctionType's arguments and ensure they are specified + // correctly! + // + FunctionType::param_iterator I = Ty->param_begin(); + FunctionType::param_iterator E = Ty->param_end(); + std::vector::iterator ArgI = $6->begin(), ArgE = $6->end(); + + for (; ArgI != ArgE && I != E; ++ArgI, ++I) + if ((*ArgI)->getType() != *I) + ThrowException("Parameter " +(*ArgI)->getName()+ " is not of type '" + + (*I)->getDescription() + "'!"); + + if (I != E || (ArgI != ArgE && !Ty->isVarArg())) + ThrowException("Invalid number of parameters detected!"); + + $$ = new InvokeInst(V, Normal, Except, *$6); + } + cast($$)->setCallingConv($2); + + delete $3; + delete $6; + } + | UNWIND { + $$ = new UnwindInst(); + } + | UNREACHABLE { + $$ = new UnreachableInst(); + }; + + + +JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef { + $$ = $1; + Constant *V = cast(getValNonImprovising($2, $3)); + if (V == 0) + ThrowException("May only switch on a constant pool value!"); + + $$->push_back(std::make_pair(V, getBBVal($6))); + } + | IntType ConstValueRef ',' LABEL ValueRef { + $$ = new std::vector >(); + Constant *V = cast(getValNonImprovising($1, $2)); + + if (V == 0) + ThrowException("May only switch on a constant pool value!"); + + $$->push_back(std::make_pair(V, getBBVal($5))); + }; + +Inst : OptAssign InstVal { + // Is this definition named?? if so, assign the name... + setValueName($2, $1); + InsertValue($2); + $$ = $2; +}; + +PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes + $$ = new std::list >(); + $$->push_back(std::make_pair(getVal(*$1, $3), getBBVal($5))); + delete $1; + } + | PHIList ',' '[' ValueRef ',' ValueRef ']' { + $$ = $1; + $1->push_back(std::make_pair(getVal($1->front().first->getType(), $4), + getBBVal($6))); + }; + + +ValueRefList : ResolvedVal { // Used for call statements, and memory insts... + $$ = new std::vector(); + $$->push_back($1); + } + | ValueRefList ',' ResolvedVal { + $$ = $1; + $1->push_back($3); + }; + +// ValueRefListE - Just like ValueRefList, except that it may also be empty! +ValueRefListE : ValueRefList | /*empty*/ { $$ = 0; }; + +OptTailCall : TAIL CALL { + $$ = true; + } + | CALL { + $$ = false; + }; + + + +InstVal : ArithmeticOps Types ValueRef ',' ValueRef { + if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint() && + !isa((*$2).get())) + ThrowException( + "Arithmetic operator requires integer, FP, or packed operands!"); + if (isa((*$2).get()) && $1 == Instruction::Rem) + ThrowException("Rem not supported on packed types!"); + $$ = BinaryOperator::create($1, getVal(*$2, $3), getVal(*$2, $5)); + if ($$ == 0) + ThrowException("binary operator returned null!"); + delete $2; + } + | LogicalOps Types ValueRef ',' ValueRef { + if (!(*$2)->isIntegral()) { + if (!isa($2->get()) || + !cast($2->get())->getElementType()->isIntegral()) + ThrowException("Logical operator requires integral operands!"); + } + $$ = BinaryOperator::create($1, getVal(*$2, $3), getVal(*$2, $5)); + if ($$ == 0) + ThrowException("binary operator returned null!"); + delete $2; + } + | SetCondOps Types ValueRef ',' ValueRef { + if(isa((*$2).get())) { + ThrowException( + "PackedTypes currently not supported in setcc instructions!"); + } + $$ = new SetCondInst($1, getVal(*$2, $3), getVal(*$2, $5)); + if ($$ == 0) + ThrowException("binary operator returned null!"); + delete $2; + } + | NOT ResolvedVal { + std::cerr << "WARNING: Use of eliminated 'not' instruction:" + << " Replacing with 'xor'.\n"; + + Value *Ones = ConstantIntegral::getAllOnesValue($2->getType()); + if (Ones == 0) + ThrowException("Expected integral type for not instruction!"); + + $$ = BinaryOperator::create(Instruction::Xor, $2, Ones); + if ($$ == 0) + ThrowException("Could not create a xor instruction!"); + } + | ShiftOps ResolvedVal ',' ResolvedVal { + if ($4->getType() != Type::UByteTy) + ThrowException("Shift amount must be ubyte!"); + if (!$2->getType()->isInteger()) + ThrowException("Shift constant expression requires integer operand!"); + $$ = new ShiftInst($1, $2, $4); + } + | CAST ResolvedVal TO Types { + if (!$4->get()->isFirstClassType()) + ThrowException("cast instruction to a non-primitive type: '" + + $4->get()->getDescription() + "'!"); + $$ = new CastInst($2, *$4); + delete $4; + } + | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { + if ($2->getType() != Type::BoolTy) + ThrowException("select condition must be boolean!"); + if ($4->getType() != $6->getType()) + ThrowException("select value types should match!"); + $$ = new SelectInst($2, $4, $6); + } + | VAARG ResolvedVal ',' Types { + NewVarArgs = true; + $$ = new VAArgInst($2, *$4); + delete $4; + } + | VAARG_old ResolvedVal ',' Types { + ObsoleteVarArgs = true; + const Type* ArgTy = $2->getType(); + Function* NF = CurModule.CurrentModule-> + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0); + + //b = vaarg a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //b = vaarg foo, t + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix"); + CurBB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, $2); + CurBB->getInstList().push_back(bar); + CurBB->getInstList().push_back(new StoreInst(bar, foo)); + $$ = new VAArgInst(foo, *$4); + delete $4; + } + | VANEXT_old ResolvedVal ',' Types { + ObsoleteVarArgs = true; + const Type* ArgTy = $2->getType(); + Function* NF = CurModule.CurrentModule-> + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0); + + //b = vanext a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //tmp = vaarg foo, t + //b = load foo + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix"); + CurBB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, $2); + CurBB->getInstList().push_back(bar); + CurBB->getInstList().push_back(new StoreInst(bar, foo)); + Instruction* tmp = new VAArgInst(foo, *$4); + CurBB->getInstList().push_back(tmp); + $$ = new LoadInst(foo); + delete $4; + } + | EXTRACTELEMENT ResolvedVal ',' ResolvedVal { + if (!isa($2->getType())) + ThrowException("First operand of extractelement must be " + "packed type!"); + if ($4->getType() != Type::UIntTy) + ThrowException("Second operand of extractelement must be uint!"); + $$ = new ExtractElementInst($2, $4); + } + | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal { + if (!isa($2->getType())) + ThrowException("First operand of insertelement must be " + "packed type!"); + if ($4->getType() != + cast($2->getType())->getElementType()) + ThrowException("Second operand of insertelement must be " + "packed element type!"); + if ($6->getType() != Type::UIntTy) + ThrowException("Third operand of insertelement must be uint!"); + $$ = new InsertElementInst($2, $4, $6); + } + | PHI_TOK PHIList { + const Type *Ty = $2->front().first->getType(); + if (!Ty->isFirstClassType()) + ThrowException("PHI node operands must be of first class type!"); + $$ = new PHINode(Ty); + ((PHINode*)$$)->reserveOperandSpace($2->size()); + while ($2->begin() != $2->end()) { + if ($2->front().first->getType() != Ty) + ThrowException("All elements of a PHI node must be of the same type!"); + cast($$)->addIncoming($2->front().first, $2->front().second); + $2->pop_front(); + } + delete $2; // Free the list... + } + | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' { + const PointerType *PFTy; + const FunctionType *Ty; + + if (!(PFTy = dyn_cast($3->get())) || + !(Ty = dyn_cast(PFTy->getElementType()))) { + // Pull out the types of all of the arguments... + std::vector ParamTypes; + if ($6) { + for (std::vector::iterator I = $6->begin(), E = $6->end(); + I != E; ++I) + ParamTypes.push_back((*I)->getType()); + } + + bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; + if (isVarArg) ParamTypes.pop_back(); + + if (!(*$3)->isFirstClassType() && *$3 != Type::VoidTy) + ThrowException("LLVM functions cannot return aggregate types!"); + + Ty = FunctionType::get($3->get(), ParamTypes, isVarArg); + PFTy = PointerType::get(Ty); + } + + Value *V = getVal(PFTy, $4); // Get the function we're calling... + + // Create the call node... + if (!$6) { // Has no arguments? + // Make sure no arguments is a good thing! + if (Ty->getNumParams() != 0) + ThrowException("No arguments passed to a function that " + "expects arguments!"); + + $$ = new CallInst(V, std::vector()); + } else { // Has arguments? + // Loop through FunctionType's arguments and ensure they are specified + // correctly! + // + FunctionType::param_iterator I = Ty->param_begin(); + FunctionType::param_iterator E = Ty->param_end(); + std::vector::iterator ArgI = $6->begin(), ArgE = $6->end(); + + for (; ArgI != ArgE && I != E; ++ArgI, ++I) + if ((*ArgI)->getType() != *I) + ThrowException("Parameter " +(*ArgI)->getName()+ " is not of type '" + + (*I)->getDescription() + "'!"); + + if (I != E || (ArgI != ArgE && !Ty->isVarArg())) + ThrowException("Invalid number of parameters detected!"); + + $$ = new CallInst(V, *$6); + } + cast($$)->setTailCall($1); + cast($$)->setCallingConv($2); + delete $3; + delete $6; + } + | MemoryInst { + $$ = $1; + }; + + +// IndexList - List of indices for GEP based instructions... +IndexList : ',' ValueRefList { + $$ = $2; + } | /* empty */ { + $$ = new std::vector(); + }; + +OptVolatile : VOLATILE { + $$ = true; + } + | /* empty */ { + $$ = false; + }; + + + +MemoryInst : MALLOC Types OptCAlign { + $$ = new MallocInst(*$2, 0, $3); + delete $2; + } + | MALLOC Types ',' UINT ValueRef OptCAlign { + $$ = new MallocInst(*$2, getVal($4, $5), $6); + delete $2; + } + | ALLOCA Types OptCAlign { + $$ = new AllocaInst(*$2, 0, $3); + delete $2; + } + | ALLOCA Types ',' UINT ValueRef OptCAlign { + $$ = new AllocaInst(*$2, getVal($4, $5), $6); + delete $2; + } + | FREE ResolvedVal { + if (!isa($2->getType())) + ThrowException("Trying to free nonpointer type " + + $2->getType()->getDescription() + "!"); + $$ = new FreeInst($2); + } + + | OptVolatile LOAD Types ValueRef { + if (!isa($3->get())) + ThrowException("Can't load from nonpointer type: " + + (*$3)->getDescription()); + if (!cast($3->get())->getElementType()->isFirstClassType()) + ThrowException("Can't load from pointer of non-first-class type: " + + (*$3)->getDescription()); + $$ = new LoadInst(getVal(*$3, $4), "", $1); + delete $3; + } + | OptVolatile STORE ResolvedVal ',' Types ValueRef { + const PointerType *PT = dyn_cast($5->get()); + if (!PT) + ThrowException("Can't store to a nonpointer type: " + + (*$5)->getDescription()); + const Type *ElTy = PT->getElementType(); + if (ElTy != $3->getType()) + ThrowException("Can't store '" + $3->getType()->getDescription() + + "' into space of type '" + ElTy->getDescription() + "'!"); + + $$ = new StoreInst($3, getVal(*$5, $6), $1); + delete $5; + } + | GETELEMENTPTR Types ValueRef IndexList { + if (!isa($2->get())) + ThrowException("getelementptr insn requires pointer operand!"); + + // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte struct + // indices to uint struct indices for compatibility. + generic_gep_type_iterator::iterator> + GTI = gep_type_begin($2->get(), $4->begin(), $4->end()), + GTE = gep_type_end($2->get(), $4->begin(), $4->end()); + for (unsigned i = 0, e = $4->size(); i != e && GTI != GTE; ++i, ++GTI) + if (isa(*GTI)) // Only change struct indices + if (ConstantUInt *CUI = dyn_cast((*$4)[i])) + if (CUI->getType() == Type::UByteTy) + (*$4)[i] = ConstantExpr::getCast(CUI, Type::UIntTy); + + if (!GetElementPtrInst::getIndexedType(*$2, *$4, true)) + ThrowException("Invalid getelementptr indices for type '" + + (*$2)->getDescription()+ "'!"); + $$ = new GetElementPtrInst(getVal(*$2, $3), *$4); + delete $2; delete $4; + }; + + +%% +int yyerror(const char *ErrorMsg) { + std::string where + = std::string((CurFilename == "-") ? std::string("") : CurFilename) + + ":" + utostr((unsigned) llvmAsmlineno) + ": "; + std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading "; + if (yychar == YYEMPTY || yychar == 0) + errMsg += "end-of-file."; + else + errMsg += "token: '" + std::string(llvmAsmtext, llvmAsmleng) + "'"; + ThrowException(errMsg); + return 0; +}