X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FllvmAsmParser.y.cvs;h=90fe540b8df3c74460115a3a6b87a5328309d792;hb=fdfef0da6ba2ed8c3a75df517c564a54f857daaa;hp=fd2713f3071118fdec65b1be280ac45a96e0ce05;hpb=1013b4d7491752b4d04a09a25b4937c92b24f20b;p=oota-llvm.git diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs index fd2713f3071..90fe540b8df 100644 --- a/lib/AsmParser/llvmAsmParser.y.cvs +++ b/lib/AsmParser/llvmAsmParser.y.cvs @@ -2,8 +2,8 @@ // // 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 is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -18,6 +18,7 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" +#include "llvm/AutoUpgrade.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/CommandLine.h" #include "llvm/ADT/SmallVector.h" @@ -28,9 +29,6 @@ #include #include #include -#ifndef NDEBUG -#define YYDEBUG 1 -#endif // The following is a gross hack. In order to rid the libAsmParser library of // exceptions, we have to have a way of getting the yyparse function to go into @@ -50,15 +48,6 @@ static bool TriggerError = false; int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit int yylex(); // declaration" of xxx warnings. int yyparse(); - -namespace llvm { - std::string CurFilename; -#if YYDEBUG -static cl::opt -Debug("debug-yacc", cl::desc("Print yacc debug state changes"), - cl::Hidden, cl::init(false)); -#endif -} using namespace llvm; static Module *ParserResult; @@ -131,6 +120,11 @@ static struct PerModuleInfo { return; } + // Look for intrinsic functions and CallInst that need to be upgraded + for (Module::iterator FI = CurrentModule->begin(), + FE = CurrentModule->end(); FI != FE; ) + UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove + Values.clear(); // Clear out function local definitions Types.clear(); CurrentModule = 0; @@ -384,7 +378,8 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) { // 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 (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) { + if (!isa(Ty) || + !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) { GenerateError("Signed integral constant '" + itostr(D.ConstPool64) + "' is invalid for type '" + Ty->getDescription() + "'"); @@ -393,24 +388,32 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) { return ConstantInt::get(Ty, D.ConstPool64, true); case ValID::ConstUIntVal: // Is it an unsigned const pool reference? - if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) { - if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) { - GenerateError("Integral constant '" + utostr(D.UConstPool64) + - "' is invalid or out of range"); - return 0; - } else { // This is really a signed reference. Transmogrify. - return ConstantInt::get(Ty, D.ConstPool64, true); - } - } else { + if (isa(Ty) && + ConstantInt::isValueValidForType(Ty, D.UConstPool64)) return ConstantInt::get(Ty, D.UConstPool64); + + if (!isa(Ty) || + !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) { + GenerateError("Integral constant '" + utostr(D.UConstPool64) + + "' is invalid or out of range for type '" + + Ty->getDescription() + "'"); + return 0; } + // This is really a signed reference. Transmogrify. + return ConstantInt::get(Ty, D.ConstPool64, true); case ValID::ConstFPVal: // Is it a floating point const pool reference? - if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) { + if (!Ty->isFloatingPoint() || + !ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) { GenerateError("FP constant invalid for type"); return 0; } - return ConstantFP::get(Ty, D.ConstPoolFP); + // Lexer has no type info, so builds all float and double FP constants + // as double. Fix this here. Long double does not need this. + if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble && + Ty==Type::FloatTy) + D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + return ConstantFP::get(*D.ConstPoolFP); case ValID::ConstNullVal: // Is it a null value? if (!isa(Ty)) { @@ -490,9 +493,10 @@ 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); + V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage, 0, "", + (Module*)0, false, PTy->getAddressSpace()); break; } default: @@ -502,7 +506,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) { // 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))); + LLLgetLineNo()))); if (inFunctionScope()) InsertValue(V, CurFun.LateResolveValues); @@ -543,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; } @@ -574,12 +575,13 @@ static BasicBlock *getBBVal(const ValID &ID) { } if (ID.Type == ValID::LocalName) { std::string Name = ID.getName(); Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name); - if (N) + if (N) { if (N->getType()->getTypeID() == Type::LabelTyID) BB = cast(N); else GenerateError("Reference to label '" + Name + "' is actually of type '"+ N->getType()->getDescription() + "'"); + } } else if (ID.Type == ValID::LocalID) { if (ID.Num < CurFun.NextValNum && ID.Num < CurFun.Values.size()) { if (CurFun.Values[ID.Num]->getType()->getTypeID() == Type::LabelTyID) @@ -604,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; @@ -723,13 +725,14 @@ ParseGlobalVariable(std::string *NameStr, GlobalValue::LinkageTypes Linkage, GlobalValue::VisibilityTypes Visibility, bool isConstantGlobal, const Type *Ty, - Constant *Initializer, bool IsThreadLocal) { + Constant *Initializer, bool IsThreadLocal, + unsigned AddressSpace = 0) { if (isa(Ty)) { GenerateError("Cannot declare global vars of function type"); return 0; } - const PointerType *PTy = PointerType::get(Ty); + const PointerType *PTy = PointerType::get(Ty, AddressSpace); std::string Name; if (NameStr) { @@ -781,7 +784,7 @@ ParseGlobalVariable(std::string *NameStr, // Otherwise there is no existing GV to use, create one now. GlobalVariable *GV = new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, - CurModule.CurrentModule, IsThreadLocal); + CurModule.CurrentModule, IsThreadLocal, AddressSpace); GV->setVisibility(Visibility); InsertValue(GV, CurModule.Values); return GV; @@ -934,22 +937,11 @@ static PATypeHolder HandleUpRefs(const Type *ty) { // static Module* RunParser(Module * M); -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); - } +Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { + InitLLLexer(MB); + Module *M = RunParser(new Module(LLLgetFilename())); + FreeLexer(); + return M; } %} @@ -970,7 +962,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { llvm::ArgListType *ArgList; llvm::TypeWithAttrs TypeWithAttrs; llvm::TypeWithAttrsList *TypeWithAttrsList; - llvm::ValueRefList *ValueRefList; + llvm::ParamList *ParamList; // Represent the RHS of PHI node std::list ConstVector %type ArgList ArgListH %type PHIList -%type ValueRefList // For call param lists & GEP indices +%type ParamList // For call param lists & GEP indices %type IndexList // For GEP indices %type TypeListI %type ArgTypeList ArgTypeListI @@ -1029,6 +1021,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { // 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 @@ -1050,7 +1043,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %type Types ResultTypes %type IntType FPType PrimType // Classifications %token VOID INTTYPE -%token FLOAT DOUBLE LABEL +%token FLOAT DOUBLE X86_FP80 FP128 PPC_FP128 LABEL %token TYPE @@ -1058,15 +1051,15 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token STRINGCONSTANT ATSTRINGCONSTANT PCTSTRINGCONSTANT %type LocalName OptLocalName OptLocalAssign %type GlobalName OptGlobalAssign GlobalAssign -%type OptSection SectionString +%type OptSection SectionString OptGC -%type OptAlign OptCAlign +%type OptAlign OptCAlign OptAddrSpace %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 OPAQUE EXTERNAL TARGET TRIPLE ALIGN +%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 %token DATALAYOUT @@ -1082,7 +1075,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %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 @@ -1099,9 +1092,11 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { // Other Operators %token PHI_TOK SELECT VAARG %token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR +%token GETRESULT // Function Attributes %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST +%token READNONE READONLY GC // Visibility Styles %token DEFAULT HIDDEN PROTECTED @@ -1141,11 +1136,14 @@ FPredicates // These are some types that allow classification if we only want a particular // thing... for example, only a signed, unsigned, or integral type. IntType : INTTYPE; -FPType : FLOAT | DOUBLE; +FPType : FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80; LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ; OptLocalName : LocalName | /*empty*/ { $$ = 0; }; +OptAddrSpace : ADDRSPACE '(' EUINT64VAL ')' { $$=$3; } + | /*empty*/ { $$=0; }; + /// OptLocalAssign - Value producing statements have an optional assignment /// component. OptLocalAssign : LocalName '=' { @@ -1176,6 +1174,7 @@ GVInternalLinkage | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } | APPENDING { $$ = GlobalValue::AppendingLinkage; } | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } + | COMMON { $$ = GlobalValue::CommonLinkage; } ; GVExternalLinkage @@ -1233,6 +1232,8 @@ ParamAttr : ZEROEXT { $$ = ParamAttr::ZExt; } | NOALIAS { $$ = ParamAttr::NoAlias; } | BYVAL { $$ = ParamAttr::ByVal; } | NEST { $$ = ParamAttr::Nest; } + | ALIGN EUINT64VAL { $$ = + ParamAttr::constructAlignmentFromInt($2); } ; OptParamAttrs : /* empty */ { $$ = ParamAttr::None; } @@ -1245,6 +1246,8 @@ FuncAttr : NORETURN { $$ = ParamAttr::NoReturn; } | NOUNWIND { $$ = ParamAttr::NoUnwind; } | ZEROEXT { $$ = ParamAttr::ZExt; } | SIGNEXT { $$ = ParamAttr::SExt; } + | READNONE { $$ = ParamAttr::ReadNone; } + | READONLY { $$ = ParamAttr::ReadOnly; } ; OptFuncAttrs : /* empty */ { $$ = ParamAttr::None; } @@ -1253,6 +1256,12 @@ OptFuncAttrs : /* empty */ { $$ = ParamAttr::None; } } ; +OptGC : /* empty */ { $$ = 0; } + | GC STRINGCONSTANT { + $$ = $2; + } + ; + // OptAlign/OptCAlign - An optional alignment, and an optional alignment with // a comma before it. OptAlign : /*empty*/ { $$ = 0; } | @@ -1271,6 +1280,7 @@ OptCAlign : /*empty*/ { $$ = 0; } | }; + SectionString : SECTION STRINGCONSTANT { for (unsigned i = 0, e = $2->length(); i != e; ++i) if ((*$2)[i] == '"' || (*$2)[i] == '\\') @@ -1305,7 +1315,7 @@ GlobalVarAttribute : SectionString { // Derived types are added later... // -PrimType : INTTYPE | FLOAT | DOUBLE | LABEL ; +PrimType : INTTYPE | FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80 | LABEL ; Types : OPAQUE { @@ -1316,10 +1326,10 @@ Types $$ = new PATypeHolder($1); CHECK_FOR_ERROR } - | Types '*' { // Pointer type? + | Types OptAddrSpace '*' { // Pointer type? if (*$1 == Type::LabelTy) GEN_ERROR("Cannot form a pointer to a basic block"); - $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1))); + $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $2))); delete $1; CHECK_FOR_ERROR } @@ -1337,61 +1347,54 @@ Types CHECK_FOR_ERROR } | 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 (!FunctionType::isValidReturnType(RetTy)) + GEN_ERROR("Invalid result type for LLVM function"); + std::vector Params; - ParamAttrsVector Attrs; - if ($5 != ParamAttr::None) { - ParamAttrsWithIndex X; X.index = 0; X.attrs = $5; - Attrs.push_back(X); - } - unsigned index = 1; TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); - for (; I != E; ++I, ++index) { + for (; I != E; ++I ) { const Type *Ty = I->Ty->get(); Params.push_back(Ty); - if (Ty != Type::VoidTy) - if (I->Attrs != ParamAttr::None) { - ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs; - Attrs.push_back(X); - } } + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - ParamAttrsList *ActualAttrs = 0; - if (!Attrs.empty()) - ActualAttrs = ParamAttrsList::get(Attrs); - FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, ActualAttrs); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR + + FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); delete $3; // Delete the argument list delete $1; // Delete the return type handle $$ = new PATypeHolder(HandleUpRefs(FT)); CHECK_FOR_ERROR } | VOID '(' ArgTypeListI ')' OptFuncAttrs { + // Allow but ignore attributes on function types; this permits auto-upgrade. + // FIXME: remove in LLVM 3.0. std::vector Params; - ParamAttrsVector Attrs; - if ($5 != ParamAttr::None) { - ParamAttrsWithIndex X; X.index = 0; X.attrs = $5; - Attrs.push_back(X); - } TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); - unsigned index = 1; - for ( ; I != E; ++I, ++index) { + for ( ; I != E; ++I ) { const Type* Ty = I->Ty->get(); Params.push_back(Ty); - if (Ty != Type::VoidTy) - if (I->Attrs != ParamAttr::None) { - ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs; - Attrs.push_back(X); - } } + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - ParamAttrsList *ActualAttrs = 0; - if (!Attrs.empty()) - ActualAttrs = ParamAttrsList::get(Attrs); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR - FunctionType *FT = FunctionType::get($1, Params, isVarArg, ActualAttrs); + FunctionType *FT = FunctionType::get($1, Params, isVarArg); delete $3; // Delete the argument list $$ = new PATypeHolder(HandleUpRefs(FT)); CHECK_FOR_ERROR @@ -1408,8 +1411,6 @@ Types GEN_ERROR("Unsigned result not equal to signed result"); if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger()) GEN_ERROR("Element type of a VectorType must be primitive"); - if (!isPowerOf2_32($2)) - GEN_ERROR("Vector length should be a power of 2"); $$ = new PATypeHolder(HandleUpRefs(VectorType::get(*$4, (unsigned)$2))); delete $4; CHECK_FOR_ERROR @@ -1445,9 +1446,11 @@ Types ; ArgType - : Types OptParamAttrs { + : Types OptParamAttrs { + // Allow but ignore attributes on function types; this permits auto-upgrade. + // FIXME: remove in LLVM 3.0. $$.Ty = $1; - $$.Attrs = $2; + $$.Attrs = ParamAttr::None; } ; @@ -1455,7 +1458,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; } @@ -1732,7 +1735,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); const PointerType *Ty = dyn_cast($1->get()); if (Ty == 0) - GEN_ERROR("Global const reference must be a pointer type"); + GEN_ERROR("Global const reference must be a pointer type " + (*$1)->getDescription()); // ConstExprs can exist in the body of a function, thus creating // GlobalValues whenever they refer to a variable. Because we are in @@ -1775,8 +1778,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, @@ -1855,10 +1858,15 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr $$ = ConstantInt::getFalse(); CHECK_FOR_ERROR } - | FPType FPVAL { // Float & Double constants - if (!ConstantFP::isValueValidForType($1, $2)) + | FPType FPVAL { // Floating point constants + if (!ConstantFP::isValueValidForType($1, *$2)) GEN_ERROR("Floating point constant invalid for type"); - $$ = ConstantFP::get($1, $2); + // Lexer has no type info, so builds all float and double FP constants + // as double. Fix this here. Long double is done right. + if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy) + $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + $$ = ConstantFP::get(*$2); + delete $2; CHECK_FOR_ERROR }; @@ -1880,8 +1888,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { GEN_ERROR("GetElementPtr requires a pointer operand"); const Type *IdxTy = - GetElementPtrInst::getIndexedType($3->getType(), &(*$4)[0], $4->size(), - true); + GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end()); if (!IdxTy) GEN_ERROR("Index list invalid for constant getelementptr"); @@ -1932,6 +1939,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"); @@ -1974,6 +1991,7 @@ ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; }; AliaseeRef : ResultTypes SymbolicValueRef { const Type* VTy = $1->get(); Value *V = getVal(VTy, $2); + CHECK_FOR_ERROR GlobalValue* Aliasee = dyn_cast(V); if (!Aliasee) GEN_ERROR("Aliases can be created only to global values"); @@ -2066,30 +2084,31 @@ Definition } CHECK_FOR_ERROR } - | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal { + | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal + OptAddrSpace { /* "Externally Visible" Linkage */ if ($5 == 0) GEN_ERROR("Global value initializer is not a constant"); CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage, - $2, $4, $5->getType(), $5, $3); + $2, $4, $5->getType(), $5, $3, $6); CHECK_FOR_ERROR } GlobalVarAttributes { CurGV = 0; } | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType - ConstVal { + ConstVal OptAddrSpace { if ($6 == 0) GEN_ERROR("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4); + CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4, $7); CHECK_FOR_ERROR } GlobalVarAttributes { CurGV = 0; } | OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType - Types { + Types OptAddrSpace { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription()); - CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4); + CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4, $7); CHECK_FOR_ERROR delete $6; } GlobalVarAttributes { @@ -2113,6 +2132,27 @@ Definition CurModule.CurrentModule); GA->setVisibility($2); InsertValue(GA, CurModule.Values); + + + // If there was a forward reference of this alias, resolve it now. + + ValID ID; + if (!Name.empty()) + ID = ValID::createGlobalName(Name); + else + ID = ValID::createGlobalID(CurModule.Values.size()-1); + + if (GlobalValue *FWGV = + CurModule.GetForwardRefForGlobal(GA->getType(), ID)) { + // Replace uses of the fwdref with the actual alias. + FWGV->replaceAllUsesWith(GA); + if (GlobalVariable *GV = dyn_cast(FWGV)) + GV->eraseFromParent(); + else + cast(FWGV)->eraseFromParent(); + } + ID.destroy(); + CHECK_FOR_ERROR } | TARGET TargetDefinition { @@ -2213,7 +2253,7 @@ ArgList : ArgListH { }; FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' - OptFuncAttrs OptSection OptAlign { + OptFuncAttrs OptSection OptAlign OptGC { std::string FunctionName(*$3); delete $3; // Free strdup'd memory! @@ -2222,12 +2262,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) { @@ -2235,23 +2276,20 @@ 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(); - 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, PAL); - const PointerType *PFT = PointerType::get(FT); + FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg); + const PointerType *PFT = PointerType::getUnqual(FT); delete $2; ValID ID; @@ -2267,28 +2305,33 @@ 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().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? (Fn = CurModule.CurrentModule->getFunction(FunctionName))) { - if (Fn->getFunctionType() != FT) { + if (Fn->getFunctionType() != FT ) { // The existing function doesn't have the same type. This is an overload // error. GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); + } else if (Fn->getParamAttrs() != PAL) { + // The existing function doesn't have the same parameter attributes. + // This is an overload error. + GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); } else if (!CurFun.isDeclare && !Fn->isDeclaration()) { // Neither the existing or the current function is a declaration and they // have the same name and same type. Clearly this is a redefinition. GEN_ERROR("Redefinition of function '" + FunctionName + "'"); - } if (Fn->isDeclaration()) { + } else if (Fn->isDeclaration()) { // Make sure to strip off any argument names so we can't get conflicts. 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::ExternalWeakLinkage, FunctionName, - CurModule.CurrentModule); - + Fn = Function::Create(FT, GlobalValue::ExternalWeakLinkage, FunctionName, + CurModule.CurrentModule); InsertValue(Fn, CurModule.Values); } @@ -2302,11 +2345,16 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' Fn->setVisibility(CurFun.Visibility); } Fn->setCallingConv($1); + Fn->setParamAttrs(PAL); Fn->setAlignment($9); if ($8) { Fn->setSection(*$8); delete $8; } + if ($10) { + Fn->setCollector($10->c_str()); + delete $10; + } // Add all of the arguments we parsed to the function... if ($5) { // Is null if empty... @@ -2478,6 +2526,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 @@ -2520,18 +2578,22 @@ 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?"); @@ -2541,14 +2603,14 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... 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(), @@ -2567,11 +2629,11 @@ 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 } - | INVOKE OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' OptFuncAttrs + | INVOKE OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs TO LABEL ValueRef UNWIND LABEL ValueRef { // Handle the short syntax @@ -2581,29 +2643,19 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector ParamTypes; - ParamAttrsVector Attrs; - if ($8 != ParamAttr::None) { - ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8; - Attrs.push_back(PAWI); - } - ValueRefList::iterator I = $6->begin(), E = $6->end(); - unsigned index = 1; - for (; I != E; ++I, ++index) { + ParamList::iterator I = $6->begin(), E = $6->end(); + for (; I != E; ++I) { const Type *Ty = I->Val->getType(); if (Ty == Type::VoidTy) GEN_ERROR("Short call syntax cannot be used with varargs"); ParamTypes.push_back(Ty); - if (I->Attrs != ParamAttr::None) { - ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs; - Attrs.push_back(PAWI); - } } + + if (!FunctionType::isValidReturnType(*$3)) + GEN_ERROR("Invalid result type for LLVM function"); - ParamAttrsList *PAL = 0; - if (!Attrs.empty()) - PAL = ParamAttrsList::get(Attrs); - Ty = FunctionType::get($3->get(), ParamTypes, false, PAL); - PFTy = PointerType::get(Ty); + Ty = FunctionType::get($3->get(), ParamTypes, false); + PFTy = PointerType::getUnqual(Ty); } delete $3; @@ -2615,6 +2667,10 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... BasicBlock *Except = getBBVal($14); CHECK_FOR_ERROR + SmallVector Attrs; + if ($8 != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(0, $8)); + // Check the arguments ValueList Args; if ($6->empty()) { // Has no arguments? @@ -2627,26 +2683,38 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... // correctly! FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator E = Ty->param_end(); - ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end(); + ParamList::iterator ArgI = $6->begin(), ArgE = $6->end(); + unsigned index = 1; - for (; ArgI != ArgE && I != E; ++ArgI, ++I) { + for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { if (ArgI->Val->getType() != *I) GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + (*I)->getDescription() + "'"); Args.push_back(ArgI->Val); + if (ArgI->Attrs != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs)); } if (Ty->isVarArg()) { if (I == E) - for (; ArgI != ArgE; ++ArgI) + for (; ArgI != ArgE; ++ArgI, ++index) { Args.push_back(ArgI->Val); // push the remaining varargs + 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"); } + PAListPtr PAL; + if (!Attrs.empty()) + PAL = PAListPtr::get(Attrs.begin(), Attrs.end()); + // Create the InvokeInst - InvokeInst *II = new InvokeInst(V, Normal, Except, &Args[0], Args.size()); + InvokeInst *II = InvokeInst::Create(V, Normal, Except, + Args.begin(), Args.end()); II->setCallingConv($2); + II->setParamAttrs(PAL); $$ = II; delete $6; CHECK_FOR_ERROR @@ -2717,25 +2785,43 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes }; -ValueRefList : Types ValueRef OptParamAttrs { +ParamList : Types OptParamAttrs ValueRef OptParamAttrs { + // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); // Used for call and invoke instructions - $$ = new ValueRefList(); - ValueRefListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2); + $$ = new ParamList(); + ParamListEntry E; E.Attrs = $2 | $4; E.Val = getVal($1->get(), $3); $$->push_back(E); delete $1; + CHECK_FOR_ERROR + } + | LABEL OptParamAttrs ValueRef OptParamAttrs { + // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 + // Labels are only valid in ASMs + $$ = new ParamList(); + ParamListEntry E; E.Attrs = $2 | $4; E.Val = getBBVal($3); + $$->push_back(E); + CHECK_FOR_ERROR } - | ValueRefList ',' Types ValueRef OptParamAttrs { + | ParamList ',' Types OptParamAttrs ValueRef OptParamAttrs { + // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); $$ = $1; - ValueRefListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4); + ParamListEntry E; E.Attrs = $4 | $6; E.Val = getVal($3->get(), $5); $$->push_back(E); delete $3; CHECK_FOR_ERROR } - | /*empty*/ { $$ = new ValueRefList(); }; + | ParamList ',' LABEL OptParamAttrs ValueRef OptParamAttrs { + // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 + $$ = $1; + ParamListEntry E; E.Attrs = $4 | $6; E.Val = getBBVal($5); + $$->push_back(E); + CHECK_FOR_ERROR + } + | /*empty*/ { $$ = new ParamList(); }; IndexList // Used for gep instructions and constant expressions : /*empty*/ { $$ = new std::vector(); } @@ -2762,11 +2848,6 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { !isa((*$2).get())) GEN_ERROR( "Arithmetic operator requires integer, FP, or packed operands"); - if (isa((*$2).get()) && - ($1 == Instruction::URem || - $1 == Instruction::SRem || - $1 == Instruction::FRem)) - GEN_ERROR("Remainder not supported on vector types"); Value* val1 = getVal(*$2, $3); CHECK_FOR_ERROR Value* val2 = getVal(*$2, $5); @@ -2821,6 +2902,34 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { 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; + } | CastOps ResolvedVal TO Types { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription()); @@ -2838,7 +2947,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 { @@ -2857,7 +2966,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 { @@ -2870,7 +2979,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) @@ -2881,7 +2990,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { delete $2; // Free the list... CHECK_FOR_ERROR } - | OptTailCall OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' + | OptTailCall OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs { // Handle the short syntax @@ -2891,30 +3000,19 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector ParamTypes; - ParamAttrsVector Attrs; - if ($8 != ParamAttr::None) { - ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8; - Attrs.push_back(PAWI); - } - unsigned index = 1; - ValueRefList::iterator I = $6->begin(), E = $6->end(); - for (; I != E; ++I, ++index) { + ParamList::iterator I = $6->begin(), E = $6->end(); + for (; I != E; ++I) { const Type *Ty = I->Val->getType(); if (Ty == Type::VoidTy) GEN_ERROR("Short call syntax cannot be used with varargs"); ParamTypes.push_back(Ty); - if (I->Attrs != ParamAttr::None) { - ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs; - Attrs.push_back(PAWI); - } } - ParamAttrsList *PAL = 0; - if (!Attrs.empty()) - PAL = ParamAttrsList::get(Attrs); + if (!FunctionType::isValidReturnType(*$3)) + GEN_ERROR("Invalid result type for LLVM function"); - Ty = FunctionType::get($3->get(), ParamTypes, false, PAL); - PFTy = PointerType::get(Ty); + Ty = FunctionType::get($3->get(), ParamTypes, false); + PFTy = PointerType::getUnqual(Ty); } Value *V = getVal(PFTy, $4); // Get the function we're calling... @@ -2929,6 +3027,10 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { theF->getName() + "'"); } + // Set up the ParamAttrs for the function + SmallVector Attrs; + if ($8 != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(0, $8)); // Check the arguments ValueList Args; if ($6->empty()) { // Has no arguments? @@ -2938,29 +3040,41 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { "expects arguments"); } else { // Has arguments? // Loop through FunctionType's arguments and ensure they are specified - // correctly! - // + // correctly. Also, gather any parameter attributes. FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator E = Ty->param_end(); - ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end(); + ParamList::iterator ArgI = $6->begin(), ArgE = $6->end(); + unsigned index = 1; - for (; ArgI != ArgE && I != E; ++ArgI, ++I) { + for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { if (ArgI->Val->getType() != *I) GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + (*I)->getDescription() + "'"); Args.push_back(ArgI->Val); + if (ArgI->Attrs != ParamAttr::None) + Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs)); } if (Ty->isVarArg()) { if (I == E) - for (; ArgI != ArgE; ++ArgI) + for (; ArgI != ArgE; ++ArgI, ++index) { Args.push_back(ArgI->Val); // push the remaining varargs + 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 + PAListPtr PAL; + if (!Attrs.empty()) + PAL = PAListPtr::get(Attrs.begin(), Attrs.end()); + // Create the call node - CallInst *CI = new CallInst(V, &Args[0], Args.size()); + CallInst *CI = CallInst::Create(V, Args.begin(), Args.end()); CI->setTailCall($1); CI->setCallingConv($2); + CI->setParamAttrs(PAL); $$ = CI; delete $6; delete $3; @@ -3051,18 +3165,26 @@ MemoryInst : MALLOC Types OptCAlign { $$ = new StoreInst($3, tmpVal, $1, $7); delete $5; } +| 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 { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); if (!isa($2->get())) GEN_ERROR("getelementptr insn requires pointer operand"); - if (!GetElementPtrInst::getIndexedType(*$2, &(*$4)[0], $4->size(), 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)[0], $4->size()); + $$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end()); delete $2; delete $4; }; @@ -3072,13 +3194,7 @@ MemoryInst : MALLOC Types OptCAlign { // common code from the two 'RunVMAsmParser' functions static Module* RunParser(Module * M) { - - llvmAsmlineno = 1; // Reset the current line number... CurModule.CurrentModule = M; -#if YYDEBUG - yydebug = Debug; -#endif - // Check to make sure the parser succeeded if (yyparse()) { if (ParserResult) @@ -3130,21 +3246,21 @@ static Module* RunParser(Module * M) { } void llvm::GenerateError(const std::string &message, int LineNo) { - if (LineNo == -1) LineNo = llvmAsmlineno; + if (LineNo == -1) LineNo = LLLgetLineNo(); // TODO: column number in exception if (TheParseError) - TheParseError->setError(CurFilename, message, LineNo); + TheParseError->setError(LLLgetFilename(), message, LineNo); TriggerError = 1; } int yyerror(const char *ErrorMsg) { - std::string where - = std::string((CurFilename == "-") ? std::string("") : CurFilename) - + ":" + utostr((unsigned) llvmAsmlineno) + ": "; + std::string where = LLLgetFilename() + ":" + utostr(LLLgetLineNo()) + ": "; std::string errMsg = where + "error: " + std::string(ErrorMsg); - if (yychar != YYEMPTY && yychar != 0) - errMsg += " while reading token: '" + std::string(llvmAsmtext, llvmAsmleng)+ - "'"; + if (yychar != YYEMPTY && yychar != 0) { + errMsg += " while reading token: '"; + errMsg += std::string(LLLgetTokenStart(), + LLLgetTokenStart()+LLLgetTokenLength()) + "'"; + } GenerateError(errMsg); return 0; }