X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FllvmAsmParser.y;h=a8f0f9bf2fd044da4c1ffd8650368f73dd18792d;hb=46e803b3e649c20ee3141341b2e58d5d64489e33;hp=9e9da4723dca3eae625704cde6eb4893b6470fdc;hpb=4aefd6b7d4dadf8109221a89742725c116d8f8e0;p=oota-llvm.git diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 9e9da4723dc..a8f0f9bf2fd 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -408,12 +408,12 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) { GenerateError("FP constant invalid for type"); return 0; } - // Lexer has no type info, so builds all float and double FP constants + // Lexer has no type info, so builds all float and double FP constants // as double. Fix this here. Long double does not need this. if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble && Ty==Type::FloatTy) D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); - return ConstantFP::get(Ty, *D.ConstPoolFP); + return ConstantFP::get(*D.ConstPoolFP); case ValID::ConstNullVal: // Is it a null value? if (!isa(Ty)) { @@ -475,7 +475,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) { if (TriggerError) return 0; if (!Ty->isFirstClassType() && !isa(Ty)) { - GenerateError("Invalid use of a composite type"); + GenerateError("Invalid use of a non-first-class type"); return 0; } @@ -493,7 +493,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) { } const Type* ElTy = PTy->getElementType(); if (const FunctionType *FTy = dyn_cast(ElTy)) - V = new Function(FTy, GlobalValue::ExternalLinkage); + V = Function::Create(FTy, GlobalValue::ExternalLinkage); else V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage, 0, "", (Module*)0, false, PTy->getAddressSpace()); @@ -547,21 +547,18 @@ static BasicBlock *defineBBVal(const ValID &ID) { assert(ID.Num == CurFun.NextValNum && "Invalid new block number"); InsertValue(BB); } - - ID.destroy(); - return BB; - } - - // We haven't seen this BB before and its first mention is a definition. - // Just create it and return it. - std::string Name (ID.Type == ValID::LocalName ? ID.getName() : ""); - BB = new BasicBlock(Name, CurFun.CurrentFunction); - if (ID.Type == ValID::LocalID) { - assert(ID.Num == CurFun.NextValNum && "Invalid new block number"); - InsertValue(BB); + } else { + // We haven't seen this BB before and its first mention is a definition. + // Just create it and return it. + std::string Name (ID.Type == ValID::LocalName ? ID.getName() : ""); + BB = BasicBlock::Create(Name, CurFun.CurrentFunction); + if (ID.Type == ValID::LocalID) { + assert(ID.Num == CurFun.NextValNum && "Invalid new block number"); + InsertValue(BB); + } } - ID.destroy(); // Free strdup'd memory + ID.destroy(); return BB; } @@ -609,7 +606,7 @@ static BasicBlock *getBBVal(const ValID &ID) { std::string Name; if (ID.Type == ValID::LocalName) Name = ID.getName(); - BB = new BasicBlock(Name, CurFun.CurrentFunction); + BB = BasicBlock::Create(Name, CurFun.CurrentFunction); // Insert it in the forward refs map. CurFun.BBForwardRefs[ID] = BB; @@ -734,6 +731,10 @@ ParseGlobalVariable(std::string *NameStr, GenerateError("Cannot declare global vars of function type"); return 0; } + if (Ty == Type::LabelTy) { + GenerateError("Cannot declare global vars of label type"); + return 0; + } const PointerType *PTy = PointerType::get(Ty, AddressSpace); @@ -962,6 +963,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { llvm::PATypeHolder *TypeVal; llvm::Value *ValueVal; std::vector *ValueList; + std::vector *ConstantList; llvm::ArgListType *ArgList; llvm::TypeWithAttrs TypeWithAttrs; llvm::TypeWithAttrsList *TypeWithAttrsList; @@ -1007,6 +1009,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %type PHIList %type ParamList // For call param lists & GEP indices %type IndexList // For GEP indices +%type ConstantIndexList // For insertvalue/extractvalue indices %type TypeListI %type ArgTypeList ArgTypeListI %type ArgType @@ -1024,6 +1027,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { // ValueRef - Unresolved reference to a definition or BB %type ValueRef ConstValueRef SymbolicValueRef %type ResolvedVal // pair +%type ReturnedVal // Tokens and types for handling constant integer values // // ESINT64VAL - A negative number within long long range @@ -1060,7 +1064,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK %token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL %token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING -%token DLLIMPORT DLLEXPORT EXTERN_WEAK +%token DLLIMPORT DLLEXPORT EXTERN_WEAK COMMON %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT %token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK @@ -1077,7 +1081,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %token ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR %token SHL LSHR ASHR -%token ICMP FCMP +%token ICMP FCMP VICMP VFCMP %type IPredicates %type FPredicates %token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE @@ -1095,6 +1099,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %token PHI_TOK SELECT VAARG %token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR %token GETRESULT +%token EXTRACTVALUE INSERTVALUE // Function Attributes %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST @@ -1176,6 +1181,7 @@ GVInternalLinkage | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } | APPENDING { $$ = GlobalValue::AppendingLinkage; } | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } + | COMMON { $$ = GlobalValue::CommonLinkage; } ; GVExternalLinkage @@ -1233,6 +1239,8 @@ ParamAttr : ZEROEXT { $$ = ParamAttr::ZExt; } | NOALIAS { $$ = ParamAttr::NoAlias; } | BYVAL { $$ = ParamAttr::ByVal; } | NEST { $$ = ParamAttr::Nest; } + | ALIGN EUINT64VAL { $$ = + ParamAttr::constructAlignmentFromInt($2); } ; OptParamAttrs : /* empty */ { $$ = ParamAttr::None; } @@ -1348,11 +1356,10 @@ Types | Types '(' ArgTypeListI ')' OptFuncAttrs { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. - const Type* RetTy = *$1; - if (!(RetTy->isFirstClassType() || RetTy == Type::VoidTy || - isa(RetTy))) - GEN_ERROR("LLVM Functions cannot return aggregates"); - + const Type *RetTy = *$1; + if (!FunctionType::isValidReturnType(RetTy)) + GEN_ERROR("Invalid result type for LLVM function"); + std::vector Params; TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for (; I != E; ++I ) { @@ -1401,7 +1408,7 @@ Types } | '[' EUINT64VAL 'x' Types ']' { // Sized array type? - $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2))); + $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, $2))); delete $4; CHECK_FOR_ERROR } @@ -1458,7 +1465,7 @@ ResultTypes : Types { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if (!(*$1)->isFirstClassType()) + if (!(*$1)->isFirstClassType() && !isa($1->get())) GEN_ERROR("LLVM functions cannot return aggregate types"); $$ = $1; } @@ -1528,13 +1535,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr GEN_ERROR("Cannot make array constant with type: '" + (*$1)->getDescription() + "'"); const Type *ETy = ATy->getElementType(); - int NumElements = ATy->getNumElements(); + uint64_t NumElements = ATy->getNumElements(); // Verify that we have the correct size... - if (NumElements != -1 && NumElements != (int)$3->size()) + if (NumElements != uint64_t(-1) && NumElements != $3->size()) GEN_ERROR("Type mismatch: constant sized array initialized with " + utostr($3->size()) + " arguments, but has size of " + - itostr(NumElements) + ""); + utostr(NumElements) + ""); // Verify all elements are correct type! for (unsigned i = 0; i < $3->size(); i++) { @@ -1556,10 +1563,10 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr GEN_ERROR("Cannot make array constant with type: '" + (*$1)->getDescription() + "'"); - int NumElements = ATy->getNumElements(); - if (NumElements != -1 && NumElements != 0) + uint64_t NumElements = ATy->getNumElements(); + if (NumElements != uint64_t(-1) && NumElements != 0) GEN_ERROR("Type mismatch: constant sized array initialized with 0" - " arguments, but has size of " + itostr(NumElements) +""); + " arguments, but has size of " + utostr(NumElements) +""); $$ = ConstantArray::get(ATy, std::vector()); delete $1; CHECK_FOR_ERROR @@ -1572,15 +1579,15 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr GEN_ERROR("Cannot make array constant with type: '" + (*$1)->getDescription() + "'"); - int NumElements = ATy->getNumElements(); + uint64_t NumElements = ATy->getNumElements(); const Type *ETy = ATy->getElementType(); - if (NumElements != -1 && NumElements != int($3->length())) + if (NumElements != uint64_t(-1) && NumElements != $3->length()) GEN_ERROR("Can't build string constant of size " + - itostr((int)($3->length())) + - " when array has size " + itostr(NumElements) + ""); + utostr($3->length()) + + " when array has size " + utostr(NumElements) + ""); std::vector Vals; if (ETy == Type::Int8Ty) { - for (unsigned i = 0; i < $3->length(); ++i) + for (uint64_t i = 0; i < $3->length(); ++i) Vals.push_back(ConstantInt::get(ETy, (*$3)[i])); } else { delete $3; @@ -1599,13 +1606,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr GEN_ERROR("Cannot make packed constant with type: '" + (*$1)->getDescription() + "'"); const Type *ETy = PTy->getElementType(); - int NumElements = PTy->getNumElements(); + unsigned NumElements = PTy->getNumElements(); // Verify that we have the correct size... - if (NumElements != -1 && NumElements != (int)$3->size()) + if (NumElements != unsigned(-1) && NumElements != (unsigned)$3->size()) GEN_ERROR("Type mismatch: constant sized packed initialized with " + utostr($3->size()) + " arguments, but has size of " + - itostr(NumElements) + ""); + utostr(NumElements) + ""); // Verify all elements are correct type! for (unsigned i = 0; i < $3->size(); i++) { @@ -1778,8 +1785,8 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr GlobalValue *GV; if (const FunctionType *FTy = dyn_cast(PT->getElementType())) { - GV = new Function(FTy, GlobalValue::ExternalWeakLinkage, Name, - CurModule.CurrentModule); + GV = Function::Create(FTy, GlobalValue::ExternalWeakLinkage, Name, + CurModule.CurrentModule); } else { GV = new GlobalVariable(PT->getElementType(), false, GlobalValue::ExternalWeakLinkage, 0, @@ -1849,12 +1856,14 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr CHECK_FOR_ERROR } | INTTYPE TRUETOK { // Boolean constants - assert(cast($1)->getBitWidth() == 1 && "Not Bool?"); + if (cast($1)->getBitWidth() != 1) + GEN_ERROR("Constant true must have type i1"); $$ = ConstantInt::getTrue(); CHECK_FOR_ERROR } | INTTYPE FALSETOK { // Boolean constants - assert(cast($1)->getBitWidth() == 1 && "Not Bool?"); + if (cast($1)->getBitWidth() != 1) + GEN_ERROR("Constant false must have type i1"); $$ = ConstantInt::getFalse(); CHECK_FOR_ERROR } @@ -1865,7 +1874,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr // as double. Fix this here. Long double is done right. if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy) $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); - $$ = ConstantFP::get($1, *$2); + $$ = ConstantFP::get(*$2); delete $2; CHECK_FOR_ERROR }; @@ -1888,8 +1897,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { GEN_ERROR("GetElementPtr requires a pointer operand"); const Type *IdxTy = - GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end(), - true); + GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end()); if (!IdxTy) GEN_ERROR("Index list invalid for constant getelementptr"); @@ -1940,6 +1948,16 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { GEN_ERROR("fcmp operand types must match"); $$ = ConstantExpr::getFCmp($2, $4, $6); } + | VICMP IPredicates '(' ConstVal ',' ConstVal ')' { + if ($4->getType() != $6->getType()) + GEN_ERROR("vicmp operand types must match"); + $$ = ConstantExpr::getVICmp($2, $4, $6); + } + | VFCMP FPredicates '(' ConstVal ',' ConstVal ')' { + if ($4->getType() != $6->getType()) + GEN_ERROR("vfcmp operand types must match"); + $$ = ConstantExpr::getVFCmp($2, $4, $6); + } | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { if (!ExtractElementInst::isValidOperands($3, $5)) GEN_ERROR("Invalid extractelement operands"); @@ -1957,6 +1975,22 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { GEN_ERROR("Invalid shufflevector operands"); $$ = ConstantExpr::getShuffleVector($3, $5, $7); CHECK_FOR_ERROR + } + | EXTRACTVALUE '(' ConstVal ConstantIndexList ')' { + if (!isa($3->getType()) && !isa($3->getType())) + GEN_ERROR("ExtractValue requires an aggregate operand"); + + $$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size()); + delete $4; + CHECK_FOR_ERROR + } + | INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' { + if (!isa($3->getType()) && !isa($3->getType())) + GEN_ERROR("InsertValue requires an aggregate operand"); + + $$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size()); + delete $6; + CHECK_FOR_ERROR }; @@ -2198,8 +2232,8 @@ LibList : LibList ',' STRINGCONSTANT { ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (*$3 == Type::VoidTy) - GEN_ERROR("void typed arguments are invalid"); + if (!(*$3)->isFirstClassType()) + GEN_ERROR("Argument types must be first-class"); ArgListEntry E; E.Attrs = $4; E.Ty = $3; E.Name = $5; $$ = $1; $1->push_back(E); @@ -2208,8 +2242,8 @@ ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName { | Types OptParamAttrs OptLocalName { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if (*$1 == Type::VoidTy) - GEN_ERROR("void typed arguments are invalid"); + if (!(*$1)->isFirstClassType()) + GEN_ERROR("Argument types must be first-class"); ArgListEntry E; E.Attrs = $2; E.Ty = $1; E.Name = $3; $$ = new ArgListType; $$->push_back(E); @@ -2253,14 +2287,13 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2)) GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription()); + if (!FunctionType::isValidReturnType(*$2)) + GEN_ERROR("Invalid result type for LLVM function"); + std::vector ParamTypeList; - ParamAttrsVector Attrs; - if ($7 != ParamAttr::None) { - ParamAttrsWithIndex PAWI; - PAWI.index = 0; - PAWI.attrs = $7; - Attrs.push_back(PAWI); - } + SmallVector Attrs; + if ($7 != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(0, $7)); if ($5) { // If there are arguments... unsigned index = 1; for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) { @@ -2268,22 +2301,17 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty)) GEN_ERROR("Reference to abstract argument: " + Ty->getDescription()); ParamTypeList.push_back(Ty); - if (Ty != Type::VoidTy) - if (I->Attrs != ParamAttr::None) { - ParamAttrsWithIndex PAWI; - PAWI.index = index; - PAWI.attrs = I->Attrs; - Attrs.push_back(PAWI); - } + if (Ty != Type::VoidTy && I->Attrs != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(index, I->Attrs)); } } bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; if (isVarArg) ParamTypeList.pop_back(); - const ParamAttrsList *PAL = 0; + PAListPtr PAL; if (!Attrs.empty()) - PAL = ParamAttrsList::get(Attrs); + PAL = PAListPtr::get(Attrs.begin(), Attrs.end()); FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg); const PointerType *PFT = PointerType::getUnqual(FT); @@ -2302,7 +2330,8 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' // Move the function to the end of the list, from whereever it was // previously inserted. Fn = cast(FWRef); - assert(!Fn->getParamAttrs() && "Forward reference has parameter attributes!"); + assert(Fn->getParamAttrs().isEmpty() && + "Forward reference has parameter attributes!"); CurModule.CurrentModule->getFunctionList().remove(Fn); CurModule.CurrentModule->getFunctionList().push_back(Fn); } else if (!FunctionName.empty() && // Merge with an earlier prototype? @@ -2326,8 +2355,8 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' AI->setName(""); } } else { // Not already defined? - Fn = new Function(FT, GlobalValue::ExternalWeakLinkage, FunctionName, - CurModule.CurrentModule); + Fn = Function::Create(FT, GlobalValue::ExternalWeakLinkage, FunctionName, + CurModule.CurrentModule); InsertValue(Fn, CurModule.Values); } @@ -2450,16 +2479,13 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant } | '<' ConstVector '>' { // Nonempty unsized packed vector const Type *ETy = (*$2)[0]->getType(); - int NumElements = $2->size(); + unsigned NumElements = $2->size(); + + if (!ETy->isInteger() && !ETy->isFloatingPoint()) + GEN_ERROR("Invalid vector element type: " + ETy->getDescription()); VectorType* pt = VectorType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder( - HandleUpRefs( - VectorType::get( - ETy, - NumElements) - ) - ); + PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt)); // Verify all elements are correct type! for (unsigned i = 0; i < $2->size(); i++) { @@ -2473,6 +2499,82 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant delete PTy; delete $2; CHECK_FOR_ERROR } + | '[' ConstVector ']' { // Nonempty unsized arr + const Type *ETy = (*$2)[0]->getType(); + uint64_t NumElements = $2->size(); + + if (!ETy->isFirstClassType()) + GEN_ERROR("Invalid array element type: " + ETy->getDescription()); + + ArrayType *ATy = ArrayType::get(ETy, NumElements); + PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(ATy)); + + // Verify all elements are correct type! + for (unsigned i = 0; i < $2->size(); i++) { + if (ETy != (*$2)[i]->getType()) + GEN_ERROR("Element #" + utostr(i) + " is not of type '" + + ETy->getDescription() +"' as required!\nIt is of type '"+ + (*$2)[i]->getType()->getDescription() + "'."); + } + + $$ = ValID::create(ConstantArray::get(ATy, *$2)); + delete PTy; delete $2; + CHECK_FOR_ERROR + } + | '[' ']' { + // Use undef instead of an array because it's inconvenient to determine + // the element type at this point, there being no elements to examine. + $$ = ValID::createUndef(); + CHECK_FOR_ERROR + } + | 'c' STRINGCONSTANT { + uint64_t NumElements = $2->length(); + const Type *ETy = Type::Int8Ty; + + ArrayType *ATy = ArrayType::get(ETy, NumElements); + + std::vector Vals; + for (unsigned i = 0; i < $2->length(); ++i) + Vals.push_back(ConstantInt::get(ETy, (*$2)[i])); + delete $2; + $$ = ValID::create(ConstantArray::get(ATy, Vals)); + CHECK_FOR_ERROR + } + | '{' ConstVector '}' { + std::vector Elements($2->size()); + for (unsigned i = 0, e = $2->size(); i != e; ++i) + Elements[i] = (*$2)[i]->getType(); + + const StructType *STy = StructType::get(Elements); + PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); + + $$ = ValID::create(ConstantStruct::get(STy, *$2)); + delete PTy; delete $2; + CHECK_FOR_ERROR + } + | '{' '}' { + const StructType *STy = StructType::get(std::vector()); + $$ = ValID::create(ConstantStruct::get(STy, std::vector())); + CHECK_FOR_ERROR + } + | '<' '{' ConstVector '}' '>' { + std::vector Elements($3->size()); + for (unsigned i = 0, e = $3->size(); i != e; ++i) + Elements[i] = (*$3)[i]->getType(); + + const StructType *STy = StructType::get(Elements, /*isPacked=*/true); + PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); + + $$ = ValID::create(ConstantStruct::get(STy, *$3)); + delete PTy; delete $3; + CHECK_FOR_ERROR + } + | '<' '{' '}' '>' { + const StructType *STy = StructType::get(std::vector(), + /*isPacked=*/true); + $$ = ValID::create(ConstantStruct::get(STy, std::vector())); + CHECK_FOR_ERROR + } | ConstExpr { $$ = ValID::create($1); CHECK_FOR_ERROR @@ -2522,6 +2624,16 @@ ResolvedVal : Types ValueRef { } ; +ReturnedVal : ResolvedVal { + $$ = new std::vector(); + $$->push_back($1); + CHECK_FOR_ERROR + } + | ReturnedVal ',' ResolvedVal { + ($$=$1)->push_back($3); + CHECK_FOR_ERROR + }; + BasicBlockList : BasicBlockList BasicBlock { $$ = $1; CHECK_FOR_ERROR @@ -2564,35 +2676,40 @@ InstructionList : InstructionList Inst { }; -BBTerminatorInst : RET ResolvedVal { // Return with a result... - $$ = new ReturnInst($2); +BBTerminatorInst : + RET ReturnedVal { // Return with a result... + ValueList &VL = *$2; + assert(!VL.empty() && "Invalid ret operands!"); + $$ = ReturnInst::Create(&VL[0], VL.size()); + delete $2; CHECK_FOR_ERROR } | RET VOID { // Return with no result... - $$ = new ReturnInst(); + $$ = ReturnInst::Create(); CHECK_FOR_ERROR } | BR LABEL ValueRef { // Unconditional Branch... BasicBlock* tmpBB = getBBVal($3); CHECK_FOR_ERROR - $$ = new BranchInst(tmpBB); + $$ = BranchInst::Create(tmpBB); } // Conditional Branch... | BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef { - assert(cast($2)->getBitWidth() == 1 && "Not Bool?"); + if (cast($2)->getBitWidth() != 1) + GEN_ERROR("Branch condition must have type i1"); BasicBlock* tmpBBA = getBBVal($6); CHECK_FOR_ERROR BasicBlock* tmpBBB = getBBVal($9); CHECK_FOR_ERROR Value* tmpVal = getVal(Type::Int1Ty, $3); CHECK_FOR_ERROR - $$ = new BranchInst(tmpBBA, tmpBBB, tmpVal); + $$ = BranchInst::Create(tmpBBA, tmpBBB, tmpVal); } | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' { Value* tmpVal = getVal($2, $3); CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal($6); CHECK_FOR_ERROR - SwitchInst *S = new SwitchInst(tmpVal, tmpBB, $8->size()); + SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, $8->size()); $$ = S; std::vector >::iterator I = $8->begin(), @@ -2611,7 +2728,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal($6); CHECK_FOR_ERROR - SwitchInst *S = new SwitchInst(tmpVal, tmpBB, 0); + SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, 0); $$ = S; CHECK_FOR_ERROR } @@ -2632,6 +2749,10 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... GEN_ERROR("Short call syntax cannot be used with varargs"); ParamTypes.push_back(Ty); } + + if (!FunctionType::isValidReturnType(*$3)) + GEN_ERROR("Invalid result type for LLVM function"); + Ty = FunctionType::get($3->get(), ParamTypes, false); PFTy = PointerType::getUnqual(Ty); } @@ -2645,11 +2766,9 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... BasicBlock *Except = getBBVal($14); CHECK_FOR_ERROR - ParamAttrsVector Attrs; - if ($8 != ParamAttr::None) { - ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8; - Attrs.push_back(PAWI); - } + SmallVector Attrs; + if ($8 != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(0, $8)); // Check the arguments ValueList Args; @@ -2671,35 +2790,28 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + (*I)->getDescription() + "'"); Args.push_back(ArgI->Val); - if (ArgI->Attrs != ParamAttr::None) { - ParamAttrsWithIndex PAWI; - PAWI.index = index; - PAWI.attrs = ArgI->Attrs; - Attrs.push_back(PAWI); - } + if (ArgI->Attrs != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs)); } if (Ty->isVarArg()) { if (I == E) for (; ArgI != ArgE; ++ArgI, ++index) { Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != ParamAttr::None) { - ParamAttrsWithIndex PAWI; - PAWI.index = index; - PAWI.attrs = ArgI->Attrs; - Attrs.push_back(PAWI); - } + if (ArgI->Attrs != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs)); } } else if (I != E || ArgI != ArgE) GEN_ERROR("Invalid number of parameters detected"); } - const ParamAttrsList *PAL = 0; + PAListPtr PAL; if (!Attrs.empty()) - PAL = ParamAttrsList::get(Attrs); + PAL = PAListPtr::get(Attrs.begin(), Attrs.end()); // Create the InvokeInst - InvokeInst *II = new InvokeInst(V, Normal, Except, Args.begin(), Args.end()); + InvokeInst *II = InvokeInst::Create(V, Normal, Except, + Args.begin(), Args.end()); II->setCallingConv($2); II->setParamAttrs(PAL); $$ = II; @@ -2819,6 +2931,22 @@ IndexList // Used for gep instructions and constant expressions } ; +ConstantIndexList // Used for insertvalue and extractvalue instructions + : ',' EUINT64VAL { + $$ = new std::vector(); + if ((unsigned)$2 != $2) + GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue."); + $$->push_back($2); + } + | ConstantIndexList ',' EUINT64VAL { + $$ = $1; + if ((unsigned)$3 != $3) + GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue."); + $$->push_back($3); + CHECK_FOR_ERROR + } + ; + OptTailCall : TAIL CALL { $$ = true; CHECK_FOR_ERROR @@ -2839,7 +2967,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { CHECK_FOR_ERROR Value* val2 = getVal(*$2, $5); CHECK_FOR_ERROR - $$ = BinaryOperator::create($1, val1, val2); + $$ = BinaryOperator::Create($1, val1, val2); if ($$ == 0) GEN_ERROR("binary operator returned null"); delete $2; @@ -2856,7 +2984,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { CHECK_FOR_ERROR Value* tmpVal2 = getVal(*$2, $5); CHECK_FOR_ERROR - $$ = BinaryOperator::create($1, tmpVal1, tmpVal2); + $$ = BinaryOperator::Create($1, tmpVal1, tmpVal2); if ($$ == 0) GEN_ERROR("binary operator returned null"); delete $2; @@ -2870,7 +2998,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { CHECK_FOR_ERROR Value* tmpVal2 = getVal(*$3, $6); CHECK_FOR_ERROR - $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2); + $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); if ($$ == 0) GEN_ERROR("icmp operator returned null"); delete $3; @@ -2884,7 +3012,35 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { CHECK_FOR_ERROR Value* tmpVal2 = getVal(*$3, $6); CHECK_FOR_ERROR - $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2); + $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); + if ($$ == 0) + GEN_ERROR("fcmp operator returned null"); + delete $3; + } + | VICMP IPredicates Types ValueRef ',' ValueRef { + if (!UpRefs.empty()) + GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); + if (!isa((*$3).get())) + GEN_ERROR("Scalar types not supported by vicmp instruction"); + Value* tmpVal1 = getVal(*$3, $4); + CHECK_FOR_ERROR + Value* tmpVal2 = getVal(*$3, $6); + CHECK_FOR_ERROR + $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); + if ($$ == 0) + GEN_ERROR("icmp operator returned null"); + delete $3; + } + | VFCMP FPredicates Types ValueRef ',' ValueRef { + if (!UpRefs.empty()) + GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); + if (!isa((*$3).get())) + GEN_ERROR("Scalar types not supported by vfcmp instruction"); + Value* tmpVal1 = getVal(*$3, $4); + CHECK_FOR_ERROR + Value* tmpVal2 = getVal(*$3, $6); + CHECK_FOR_ERROR + $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); if ($$ == 0) GEN_ERROR("fcmp operator returned null"); delete $3; @@ -2898,7 +3054,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { GEN_ERROR("invalid cast opcode for cast from '" + Val->getType()->getDescription() + "' to '" + DestTy->getDescription() + "'"); - $$ = CastInst::create($1, Val, DestTy); + $$ = CastInst::Create($1, Val, DestTy); delete $4; } | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { @@ -2906,7 +3062,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { GEN_ERROR("select condition must be boolean"); if ($4->getType() != $6->getType()) GEN_ERROR("select value types should match"); - $$ = new SelectInst($2, $4, $6); + $$ = SelectInst::Create($2, $4, $6); CHECK_FOR_ERROR } | VAARG ResolvedVal ',' Types { @@ -2925,7 +3081,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal { if (!InsertElementInst::isValidOperands($2, $4, $6)) GEN_ERROR("Invalid insertelement operands"); - $$ = new InsertElementInst($2, $4, $6); + $$ = InsertElementInst::Create($2, $4, $6); CHECK_FOR_ERROR } | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal { @@ -2938,7 +3094,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { const Type *Ty = $2->front().first->getType(); if (!Ty->isFirstClassType()) GEN_ERROR("PHI node operands must be of first class type"); - $$ = new PHINode(Ty); + $$ = PHINode::Create(Ty); ((PHINode*)$$)->reserveOperandSpace($2->size()); while ($2->begin() != $2->end()) { if ($2->front().first->getType() != Ty) @@ -2966,6 +3122,10 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { GEN_ERROR("Short call syntax cannot be used with varargs"); ParamTypes.push_back(Ty); } + + if (!FunctionType::isValidReturnType(*$3)) + GEN_ERROR("Invalid result type for LLVM function"); + Ty = FunctionType::get($3->get(), ParamTypes, false); PFTy = PointerType::getUnqual(Ty); } @@ -2983,13 +3143,9 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { } // Set up the ParamAttrs for the function - ParamAttrsVector Attrs; - if ($8 != ParamAttr::None) { - ParamAttrsWithIndex PAWI; - PAWI.index = 0; - PAWI.attrs = $8; - Attrs.push_back(PAWI); - } + SmallVector Attrs; + if ($8 != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(0, $8)); // Check the arguments ValueList Args; if ($6->empty()) { // Has no arguments? @@ -3010,35 +3166,27 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + (*I)->getDescription() + "'"); Args.push_back(ArgI->Val); - if (ArgI->Attrs != ParamAttr::None) { - ParamAttrsWithIndex PAWI; - PAWI.index = index; - PAWI.attrs = ArgI->Attrs; - Attrs.push_back(PAWI); - } + if (ArgI->Attrs != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs)); } if (Ty->isVarArg()) { if (I == E) for (; ArgI != ArgE; ++ArgI, ++index) { Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != ParamAttr::None) { - ParamAttrsWithIndex PAWI; - PAWI.index = index; - PAWI.attrs = ArgI->Attrs; - Attrs.push_back(PAWI); - } + if (ArgI->Attrs != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs)); } } else if (I != E || ArgI != ArgE) GEN_ERROR("Invalid number of parameters detected"); } // Finish off the ParamAttrs and check them - const ParamAttrsList *PAL = 0; + PAListPtr PAL; if (!Attrs.empty()) - PAL = ParamAttrsList::get(Attrs); + PAL = PAListPtr::get(Attrs.begin(), Attrs.end()); // Create the call node - CallInst *CI = new CallInst(V, Args.begin(), Args.end()); + CallInst *CI = CallInst::Create(V, Args.begin(), Args.end()); CI->setTailCall($1); CI->setCallingConv($2); CI->setParamAttrs(PAL); @@ -3073,6 +3221,8 @@ MemoryInst : MALLOC Types OptCAlign { | MALLOC Types ',' INTTYPE ValueRef OptCAlign { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); + if ($4 != Type::Int32Ty) + GEN_ERROR("Malloc array size is not a 32-bit integer!"); Value* tmpVal = getVal($4, $5); CHECK_FOR_ERROR $$ = new MallocInst(*$2, tmpVal, $6); @@ -3088,6 +3238,8 @@ MemoryInst : MALLOC Types OptCAlign { | ALLOCA Types ',' INTTYPE ValueRef OptCAlign { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); + if ($4 != Type::Int32Ty) + GEN_ERROR("Alloca array size is not a 32-bit integer!"); Value* tmpVal = getVal($4, $5); CHECK_FOR_ERROR $$ = new AllocaInst(*$2, tmpVal, $6); @@ -3132,12 +3284,12 @@ MemoryInst : MALLOC Types OptCAlign { $$ = new StoreInst($3, tmpVal, $1, $7); delete $5; } -| GETRESULT Types LocalName ',' ConstVal { - ValID TmpVID = ValID::createLocalName(*$3); - Value *TmpVal = getVal($2->get(), TmpVID); + | GETRESULT Types ValueRef ',' EUINT64VAL { + Value *TmpVal = getVal($2->get(), $3); if (!GetResultInst::isValidOperands(TmpVal, $5)) GEN_ERROR("Invalid getresult operands"); $$ = new GetResultInst(TmpVal, $5); + delete $2; CHECK_FOR_ERROR } | GETELEMENTPTR Types ValueRef IndexList { @@ -3146,14 +3298,46 @@ MemoryInst : MALLOC Types OptCAlign { if (!isa($2->get())) GEN_ERROR("getelementptr insn requires pointer operand"); - if (!GetElementPtrInst::getIndexedType(*$2, $4->begin(), $4->end(), true)) + if (!GetElementPtrInst::getIndexedType(*$2, $4->begin(), $4->end())) GEN_ERROR("Invalid getelementptr indices for type '" + (*$2)->getDescription()+ "'"); Value* tmpVal = getVal(*$2, $3); CHECK_FOR_ERROR - $$ = new GetElementPtrInst(tmpVal, $4->begin(), $4->end()); + $$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end()); + delete $2; + delete $4; + } + | EXTRACTVALUE Types ValueRef ConstantIndexList { + if (!UpRefs.empty()) + GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); + if (!isa($2->get()) && !isa($2->get())) + GEN_ERROR("extractvalue insn requires an aggregate operand"); + + if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end())) + GEN_ERROR("Invalid extractvalue indices for type '" + + (*$2)->getDescription()+ "'"); + Value* tmpVal = getVal(*$2, $3); + CHECK_FOR_ERROR + $$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end()); delete $2; delete $4; + } + | INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList { + if (!UpRefs.empty()) + GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); + if (!isa($2->get()) && !isa($2->get())) + GEN_ERROR("extractvalue insn requires an aggregate operand"); + + if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get()) + GEN_ERROR("Invalid insertvalue indices for type '" + + (*$2)->getDescription()+ "'"); + Value* aggVal = getVal(*$2, $3); + Value* tmpVal = getVal(*$5, $6); + CHECK_FOR_ERROR + $$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end()); + delete $2; + delete $5; + delete $7; };