diff options
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
| -rw-r--r-- | lib/AsmParser/LLParser.cpp | 486 |
1 files changed, 300 insertions, 186 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index b0b64d8..fea5ec8 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -12,16 +12,16 @@ //===----------------------------------------------------------------------===// #include "LLParser.h" -#include "llvm/AutoUpgrade.h" -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Operator.h" -#include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/AutoUpgrade.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -52,10 +52,10 @@ bool LLParser::ValidateEndOfModule() { I != E; ++I) { Instruction *Inst = I->first; const std::vector<MDRef> &MDList = I->second; - + for (unsigned i = 0, e = MDList.size(); i != e; ++i) { unsigned SlotNo = MDList[i].MDSlot; - + if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0) return Error(MDList[i].Loc, "use of undefined metadata '!" + Twine(SlotNo) + "'"); @@ -64,8 +64,8 @@ bool LLParser::ValidateEndOfModule() { } ForwardRefInstMetadata.clear(); } - - + + // If there are entries in ForwardRefBlockAddresses at this point, they are // references after the function was defined. Resolve those now. while (!ForwardRefBlockAddresses.empty()) { @@ -76,19 +76,19 @@ bool LLParser::ValidateEndOfModule() { TheFn = M->getFunction(Fn.StrVal); else if (Fn.UIntVal < NumberedVals.size()) TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]); - + if (TheFn == 0) return Error(Fn.Loc, "unknown function referenced by blockaddress"); - + // Resolve all these references. - if (ResolveForwardRefBlockAddresses(TheFn, + if (ResolveForwardRefBlockAddresses(TheFn, ForwardRefBlockAddresses.begin()->second, 0)) return true; - + ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin()); } - + for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) if (NumberedTypes[i].second.isValid()) return Error(NumberedTypes[i].second, @@ -123,7 +123,7 @@ bool LLParser::ValidateEndOfModule() { return false; } -bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, +bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, std::vector<std::pair<ValID, GlobalValue*> > &Refs, PerFunctionState *PFS) { // Loop over all the references, resolving them. @@ -141,11 +141,11 @@ bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, Res = dyn_cast_or_null<BasicBlock>( TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal)); } - + if (Res == 0) return Error(Refs[i].first.Loc, "referenced value is not a basic block"); - + // Get the BlockAddress for this and update references to use it. BlockAddress *BA = BlockAddress::get(TheFn, Res); Refs[i].second->replaceAllUsesWith(BA); @@ -267,6 +267,7 @@ bool LLParser::ParseTargetDefinition() { /// toplevelentity /// ::= 'deplibs' '=' '[' ']' /// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']' +/// FIXME: Remove in 4.0. Currently parse, but ignore. bool LLParser::ParseDepLibs() { assert(Lex.getKind() == lltok::kw_deplibs); Lex.Lex(); @@ -277,14 +278,10 @@ bool LLParser::ParseDepLibs() { if (EatIfPresent(lltok::rsquare)) return false; - std::string Str; - if (ParseStringConstant(Str)) return true; - M->addLibrary(Str); - - while (EatIfPresent(lltok::comma)) { + do { + std::string Str; if (ParseStringConstant(Str)) return true; - M->addLibrary(Str); - } + } while (EatIfPresent(lltok::comma)); return ParseToken(lltok::rsquare, "expected ']' at end of list"); } @@ -302,11 +299,11 @@ bool LLParser::ParseUnnamedType() { if (TypeID >= NumberedTypes.size()) NumberedTypes.resize(TypeID+1); - + Type *Result = 0; if (ParseStructDefinition(TypeLoc, "", NumberedTypes[TypeID], Result)) return true; - + if (!isa<StructType>(Result)) { std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID]; if (Entry.first) @@ -329,11 +326,11 @@ bool LLParser::ParseNamedType() { if (ParseToken(lltok::equal, "expected '=' after name") || ParseToken(lltok::kw_type, "expected 'type' after name")) return true; - + Type *Result = 0; if (ParseStructDefinition(NameLoc, Name, NamedTypes[Name], Result)) return true; - + if (!isa<StructType>(Result)) { std::pair<Type*, LocTy> &Entry = NamedTypes[Name]; if (Entry.first) @@ -341,7 +338,7 @@ bool LLParser::ParseNamedType() { Entry.first = Result; Entry.second = SMLoc(); } - + return false; } @@ -473,7 +470,7 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) { // Otherwise, create MDNode forward reference. MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef<Value*>()); ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); - + if (NumberedMetadata.size() <= MID) NumberedMetadata.resize(MID+1); NumberedMetadata[MID] = FwdNode; @@ -498,7 +495,7 @@ bool LLParser::ParseNamedMetadata() { do { if (ParseToken(lltok::exclaim, "Expected '!' here")) return true; - + MDNode *N = 0; if (ParseMDNodeID(N)) return true; NMD->addOperand(N); @@ -530,7 +527,7 @@ bool LLParser::ParseStandaloneMetadata() { return true; MDNode *Init = MDNode::get(Context, Elts); - + // See if this was forward referenced, if so, handle it. std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator FI = ForwardRefMDNodes.find(MetadataID); @@ -539,7 +536,7 @@ bool LLParser::ParseStandaloneMetadata() { Temp->replaceAllUsesWith(Init); MDNode::deleteTemporary(Temp); ForwardRefMDNodes.erase(FI); - + assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work"); } else { if (MetadataID >= NumberedMetadata.size()) @@ -779,7 +776,9 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, Name); + GlobalValue::ExternalWeakLinkage, 0, Name, + 0, GlobalVariable::NotThreadLocal, + PTy->getAddressSpace()); ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -913,73 +912,153 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { ParseToken(lltok::rparen, "expected ')' in address space"); } -/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind -/// indicates what kind of attribute list this is: 0: function arg, 1: result, -/// 2: function attr. -bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) { - Attrs = Attribute::None; - LocTy AttrLoc = Lex.getLoc(); +/// ParseOptionalFuncAttrs - Parse a potentially empty list of function attributes. +bool LLParser::ParseOptionalFuncAttrs(AttrBuilder &B) { + bool HaveError = false; + + B.clear(); while (1) { - switch (Lex.getKind()) { + lltok::Kind Token = Lex.getKind(); + switch (Token) { default: // End of attributes. - if (AttrKind != 2 && (Attrs & Attribute::FunctionOnly)) - return Error(AttrLoc, "invalid use of function-only attribute"); - - // As a hack, we allow "align 2" on functions as a synonym for - // "alignstack 2". - if (AttrKind == 2 && - (Attrs & ~(Attribute::FunctionOnly | Attribute::Alignment))) - return Error(AttrLoc, "invalid use of attribute on a function"); - - if (AttrKind != 0 && (Attrs & Attribute::ParameterOnly)) - return Error(AttrLoc, "invalid use of parameter-only attribute"); - - return false; - case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break; - case lltok::kw_signext: Attrs |= Attribute::SExt; break; - case lltok::kw_inreg: Attrs |= Attribute::InReg; break; - case lltok::kw_sret: Attrs |= Attribute::StructRet; break; - case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break; - case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break; - case lltok::kw_byval: Attrs |= Attribute::ByVal; break; - case lltok::kw_nest: Attrs |= Attribute::Nest; break; - - case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break; - case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break; - case lltok::kw_uwtable: Attrs |= Attribute::UWTable; break; - case lltok::kw_returns_twice: Attrs |= Attribute::ReturnsTwice; break; - case lltok::kw_noinline: Attrs |= Attribute::NoInline; break; - case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break; - case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break; - case lltok::kw_inlinehint: Attrs |= Attribute::InlineHint; break; - case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break; - case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break; - case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break; - case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; - case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; - case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break; - case lltok::kw_naked: Attrs |= Attribute::Naked; break; - case lltok::kw_nonlazybind: Attrs |= Attribute::NonLazyBind; break; - case lltok::kw_address_safety: Attrs |= Attribute::AddressSafety; break; - + return HaveError; case lltok::kw_alignstack: { unsigned Alignment; if (ParseOptionalStackAlignment(Alignment)) return true; - Attrs |= Attribute::constructStackAlignmentFromInt(Alignment); + B.addStackAlignmentAttr(Alignment); + continue; + } + case lltok::kw_align: { + // As a hack, we allow "align 2" on functions as a synonym for "alignstack + // 2". + unsigned Alignment; + if (ParseOptionalAlignment(Alignment)) + return true; + B.addAlignmentAttr(Alignment); continue; } + case lltok::kw_address_safety: B.addAttribute(Attribute::AddressSafety); break; + case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; + case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; + case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; + case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; + case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; + case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; + case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; + case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break; + case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; + case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; + case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; + case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; + case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break; + case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; + case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; + case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; + case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break; + + // Error handling. + case lltok::kw_zeroext: + case lltok::kw_signext: + case lltok::kw_inreg: + HaveError |= Error(Lex.getLoc(), "invalid use of attribute on a function"); + break; + case lltok::kw_sret: case lltok::kw_noalias: + case lltok::kw_nocapture: case lltok::kw_byval: + case lltok::kw_nest: + HaveError |= + Error(Lex.getLoc(), "invalid use of parameter-only attribute on a function"); + break; + } + + Lex.Lex(); + } +} + +/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes. +bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { + bool HaveError = false; + + B.clear(); + while (1) { + lltok::Kind Token = Lex.getKind(); + switch (Token) { + default: // End of attributes. + return HaveError; case lltok::kw_align: { unsigned Alignment; if (ParseOptionalAlignment(Alignment)) return true; - Attrs |= Attribute::constructAlignmentFromInt(Alignment); + B.addAlignmentAttr(Alignment); continue; } + case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break; + case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; + case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; + case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; + case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break; + case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; + case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break; + case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; + + case lltok::kw_noreturn: case lltok::kw_nounwind: + case lltok::kw_uwtable: case lltok::kw_returns_twice: + case lltok::kw_noinline: case lltok::kw_readnone: + case lltok::kw_readonly: case lltok::kw_inlinehint: + case lltok::kw_alwaysinline: case lltok::kw_optsize: + case lltok::kw_ssp: case lltok::kw_sspreq: + case lltok::kw_noredzone: case lltok::kw_noimplicitfloat: + case lltok::kw_naked: case lltok::kw_nonlazybind: + case lltok::kw_address_safety: case lltok::kw_minsize: + case lltok::kw_alignstack: + HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); + break; + } + Lex.Lex(); + } +} + +/// ParseOptionalReturnAttrs - Parse a potentially empty list of return attributes. +bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { + bool HaveError = false; + + B.clear(); + + while (1) { + lltok::Kind Token = Lex.getKind(); + switch (Token) { + default: // End of attributes. + return HaveError; + case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; + case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; + case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; + case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; + + // Error handling. + case lltok::kw_sret: case lltok::kw_nocapture: + case lltok::kw_byval: case lltok::kw_nest: + HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute"); + break; + + case lltok::kw_noreturn: case lltok::kw_nounwind: + case lltok::kw_uwtable: case lltok::kw_returns_twice: + case lltok::kw_noinline: case lltok::kw_readnone: + case lltok::kw_readonly: case lltok::kw_inlinehint: + case lltok::kw_alwaysinline: case lltok::kw_optsize: + case lltok::kw_ssp: case lltok::kw_sspreq: + case lltok::kw_noredzone: case lltok::kw_noimplicitfloat: + case lltok::kw_naked: case lltok::kw_nonlazybind: + case lltok::kw_address_safety: case lltok::kw_minsize: + case lltok::kw_alignstack: case lltok::kw_align: + case lltok::kw_noduplicate: + HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); + break; } + Lex.Lex(); } } @@ -1056,6 +1135,7 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { /// ::= /*empty*/ /// ::= 'ccc' /// ::= 'fastcc' +/// ::= 'kw_intel_ocl_bicc' /// ::= 'coldcc' /// ::= 'x86_stdcallcc' /// ::= 'x86_fastcallcc' @@ -1066,6 +1146,8 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { /// ::= 'msp430_intrcc' /// ::= 'ptx_kernel' /// ::= 'ptx_device' +/// ::= 'spir_func' +/// ::= 'spir_kernel' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { @@ -1083,6 +1165,9 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break; case lltok::kw_ptx_kernel: CC = CallingConv::PTX_Kernel; break; case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break; + case lltok::kw_spir_kernel: CC = CallingConv::SPIR_KERNEL; break; + case lltok::kw_spir_func: CC = CallingConv::SPIR_FUNC; break; + case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break; case lltok::kw_cc: { unsigned ArbitraryCC; Lex.Lex(); @@ -1161,7 +1246,7 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { } /// ParseOptionalCommaAlign -/// ::= +/// ::= /// ::= ',' align 4 /// /// This returns with AteExtraComma set to true if it ate an excess comma at the @@ -1175,7 +1260,7 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment, AteExtraComma = true; return false; } - + if (Lex.getKind() != lltok::kw_align) return Error(Lex.getLoc(), "expected metadata or 'align'"); @@ -1243,7 +1328,7 @@ bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) { bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices, bool &AteExtraComma) { AteExtraComma = false; - + if (Lex.getKind() != lltok::comma) return TokError("expected ',' as start of index list"); @@ -1299,7 +1384,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { case lltok::LocalVar: { // Type ::= %foo std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()]; - + // If the type hasn't been defined yet, create a forward definition and // remember where that forward def'n was seen (in case it never is defined). if (Entry.first == 0) { @@ -1316,7 +1401,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { if (Lex.getUIntVal() >= NumberedTypes.size()) NumberedTypes.resize(Lex.getUIntVal()+1); std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()]; - + // If the type hasn't been defined yet, create a forward definition and // remember where that forward def'n was seen (in case it never is defined). if (Entry.first == 0) { @@ -1395,16 +1480,16 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, // Parse the argument. LocTy ArgLoc; Type *ArgTy = 0; - Attributes ArgAttrs1; - Attributes ArgAttrs2; + AttrBuilder ArgAttrs; Value *V; if (ParseType(ArgTy, ArgLoc)) return true; // Otherwise, handle normal operands. - if (ParseOptionalAttrs(ArgAttrs1, 0) || ParseValue(ArgTy, V, PFS)) + if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS)) return true; - ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2)); + ArgList.push_back(ParamInfo(ArgLoc, V, Attribute::get(V->getContext(), + ArgAttrs))); } Lex.Lex(); // Lex the ')'. @@ -1436,11 +1521,11 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, } else { LocTy TypeLoc = Lex.getLoc(); Type *ArgTy = 0; - Attributes Attrs; + AttrBuilder Attrs; std::string Name; if (ParseType(ArgTy) || - ParseOptionalAttrs(Attrs, 0)) return true; + ParseOptionalParamAttrs(Attrs)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); @@ -1453,7 +1538,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, + Attribute::get(ArgTy->getContext(), + Attrs), Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1464,7 +1551,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, // Otherwise must be an argument type. TypeLoc = Lex.getLoc(); - if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true; + if (ParseType(ArgTy) || ParseOptionalParamAttrs(Attrs)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); @@ -1479,7 +1566,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, + Attribute::get(ArgTy->getContext(), Attrs), + Name)); } } @@ -1503,7 +1592,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { if (!ArgList[i].Name.empty()) return Error(ArgList[i].Loc, "argument name invalid in function type"); - if (ArgList[i].Attrs) + if (ArgList[i].Attrs.hasAttributes()) return Error(ArgList[i].Loc, "argument attributes invalid in function type"); } @@ -1521,7 +1610,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) { SmallVector<Type*, 8> Elts; if (ParseStructBody(Elts)) return true; - + Result = StructType::get(Context, Elts, Packed); return false; } @@ -1533,20 +1622,20 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, // If the type was already defined, diagnose the redefinition. if (Entry.first && !Entry.second.isValid()) return Error(TypeLoc, "redefinition of type"); - + // If we have opaque, just return without filling in the definition for the // struct. This counts as a definition as far as the .ll file goes. if (EatIfPresent(lltok::kw_opaque)) { // This type is being defined, so clear the location to indicate this. Entry.second = SMLoc(); - + // If this type number has never been uttered, create it. if (Entry.first == 0) Entry.first = StructType::create(Context, Name); ResultTy = Entry.first; return false; } - + // If the type starts with '<', then it is either a packed struct or a vector. bool isPacked = EatIfPresent(lltok::less); @@ -1556,27 +1645,27 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, if (Lex.getKind() != lltok::lbrace) { if (Entry.first) return Error(TypeLoc, "forward references to non-struct type"); - + ResultTy = 0; if (isPacked) return ParseArrayVectorType(ResultTy, true); return ParseType(ResultTy); } - + // This type is being defined, so clear the location to indicate this. Entry.second = SMLoc(); - + // If this type number has never been uttered, create it. if (Entry.first == 0) Entry.first = StructType::create(Context, Name); - + StructType *STy = cast<StructType>(Entry.first); - + SmallVector<Type*, 8> Body; if (ParseStructBody(Body) || (isPacked && ParseToken(lltok::greater, "expected '>' in packed struct"))) return true; - + STy->setBody(Body, isPacked); ResultTy = STy; return false; @@ -1649,8 +1738,7 @@ bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { if ((unsigned)Size != Size) return Error(SizeLoc, "size too large for vector"); if (!VectorType::isValidElementType(EltTy)) - return Error(TypeLoc, - "vector element type must be fp, integer or a pointer to these types"); + return Error(TypeLoc, "invalid vector element type"); Result = VectorType::get(EltTy, unsigned(Size)); } else { if (!ArrayType::isValidElementType(EltTy)) @@ -1707,18 +1795,18 @@ bool LLParser::PerFunctionState::FinishFunction() { FunctionID.Kind = ValID::t_GlobalID; FunctionID.UIntVal = FunctionNumber; } - + std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator FRBAI = P.ForwardRefBlockAddresses.find(FunctionID); if (FRBAI != P.ForwardRefBlockAddresses.end()) { // Resolve all these references. if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this)) return true; - + P.ForwardRefBlockAddresses.erase(FRBAI); } } - + if (!ForwardRefVals.empty()) return P.Error(ForwardRefVals.begin()->second.second, "use of undefined value '%" + ForwardRefVals.begin()->first + @@ -2091,19 +2179,19 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ValID Fn, Label; LocTy FnLoc, LabelLoc; - + if (ParseToken(lltok::lparen, "expected '(' in block address expression") || ParseValID(Fn) || ParseToken(lltok::comma, "expected comma in block address expression")|| ParseValID(Label) || ParseToken(lltok::rparen, "expected ')' in block address expression")) return true; - + if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName) return Error(Fn.Loc, "expected function name in blockaddress"); if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName) return Error(Label.Loc, "expected basic block name in blockaddress"); - + // Make a global variable as a placeholder for this reference. GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false, GlobalValue::InternalLinkage, @@ -2113,7 +2201,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ID.Kind = ValID::t_Constant; return false; } - + case lltok::kw_trunc: case lltok::kw_zext: case lltok::kw_sext: @@ -2493,7 +2581,7 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, return (V == 0); case ValID::t_InlineAsm: { PointerType *PTy = dyn_cast<PointerType>(Ty); - FunctionType *FTy = + FunctionType *FTy = PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0; if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2)) return Error(ID.Loc, "invalid type for inline asm constraint string"); @@ -2582,13 +2670,13 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, "initializer with struct type has wrong # elements"); if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct)) return Error(ID.Loc, "packed'ness of initializer and type don't match"); - + // Verify that the elements are compatible with the structtype. for (unsigned i = 0, e = ID.UIntVal; i != e; ++i) if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i)) return Error(ID.Loc, "element " + Twine(i) + " of struct initializer doesn't match struct element type"); - + V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts, ID.UIntVal)); } else @@ -2633,14 +2721,14 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { unsigned Linkage; unsigned Visibility; - Attributes RetAttrs; + AttrBuilder RetAttrs; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc = Lex.getLoc(); if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/)) return true; @@ -2697,7 +2785,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { SmallVector<ArgInfo, 8> ArgList; bool isVarArg; - Attributes FuncAttrs; + AttrBuilder FuncAttrs; std::string Section; unsigned Alignment; std::string GC; @@ -2707,7 +2795,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || - ParseOptionalAttrs(FuncAttrs, 2) || + ParseOptionalFuncAttrs(FuncAttrs) || (EatIfPresent(lltok::kw_section) && ParseStringConstant(Section)) || ParseOptionalAlignment(Alignment) || @@ -2716,9 +2804,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { return true; // If the alignment was parsed as an attribute, move to the alignment field. - if (FuncAttrs & Attribute::Alignment) { - Alignment = Attribute::getAlignmentFromAttrs(FuncAttrs); - FuncAttrs &= ~Attribute::Alignment; + if (FuncAttrs.hasAlignmentAttr()) { + Alignment = FuncAttrs.getAlignment(); + FuncAttrs.removeAttribute(Attribute::Alignment); } // Okay, if we got here, the function is syntactically valid. Convert types @@ -2726,21 +2814,27 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { std::vector<Type*> ParamTypeList; SmallVector<AttributeWithIndex, 8> Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + if (RetAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttributeSet::ReturnIndex, + Attribute::get(RetType->getContext(), + RetAttrs))); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); - if (ArgList[i].Attrs != Attribute::None) + if (ArgList[i].Attrs.hasAttributes()) Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); } - if (FuncAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs)); + if (FuncAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttributeSet::FunctionIndex, + Attribute::get(RetType->getContext(), + FuncAttrs))); - AttrListPtr PAL = AttrListPtr::get(Attrs); + AttributeSet PAL = AttributeSet::get(Context, Attrs); - if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy()) + if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy()) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); FunctionType *FT = @@ -2755,10 +2849,13 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { ForwardRefVals.find(FunctionName); if (FRVI != ForwardRefVals.end()) { Fn = M->getFunction(FunctionName); + if (!Fn) + return Error(FRVI->second.second, "invalid forward reference to " + "function as global value!"); if (Fn->getType() != PFT) return Error(FRVI->second.second, "invalid forward reference to " "function '" + FunctionName + "' with wrong type!"); - + ForwardRefVals.erase(FRVI); } else if ((Fn = M->getFunction(FunctionName))) { // Reject redefinitions. @@ -2827,13 +2924,13 @@ bool LLParser::ParseFunctionBody(Function &Fn) { int FunctionNumber = -1; if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1; - + PerFunctionState PFS(*this, Fn, FunctionNumber); // We need at least one basic block. if (Lex.getKind() == lltok::rbrace) return TokError("function body requires at least one basic block"); - + while (Lex.getKind() != lltok::rbrace) if (ParseBasicBlock(PFS)) return true; @@ -2901,7 +2998,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { // *must* be followed by metadata. if (ParseInstructionMetadata(Inst, &PFS)) return true; - break; + break; } // Set the name on the instruction. @@ -2944,16 +3041,26 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, bool NUW = EatIfPresent(lltok::kw_nuw); bool NSW = EatIfPresent(lltok::kw_nsw); if (!NUW) NUW = EatIfPresent(lltok::kw_nuw); - + if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true; - + if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true); if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true); return false; } case lltok::kw_fadd: case lltok::kw_fsub: - case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2); + case lltok::kw_fmul: + case lltok::kw_fdiv: + case lltok::kw_frem: { + FastMathFlags FMF = EatFastMathFlagsIfPresent(); + int Res = ParseArithmetic(Inst, PFS, KeywordVal, 2); + if (Res != 0) + return Res; + if (FMF.any()) + Inst->setFastMathFlags(FMF); + return 0; + } case lltok::kw_sdiv: case lltok::kw_udiv: @@ -2968,8 +3075,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_urem: case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1); - case lltok::kw_fdiv: - case lltok::kw_frem: return ParseArithmetic(Inst, PFS, KeywordVal, 2); case lltok::kw_and: case lltok::kw_or: case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal); @@ -3015,7 +3120,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { if (Opc == Instruction::FCmp) { switch (Lex.getKind()) { - default: TokError("expected fcmp predicate (e.g. 'oeq')"); + default: return TokError("expected fcmp predicate (e.g. 'oeq')"); case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break; case lltok::kw_one: P = CmpInst::FCMP_ONE; break; case lltok::kw_olt: P = CmpInst::FCMP_OLT; break; @@ -3035,7 +3140,7 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { } } else { switch (Lex.getKind()) { - default: TokError("expected icmp predicate (e.g. 'eq')"); + default: return TokError("expected icmp predicate (e.g. 'eq')"); case lltok::kw_eq: P = CmpInst::ICMP_EQ; break; case lltok::kw_ne: P = CmpInst::ICMP_NE; break; case lltok::kw_slt: P = CmpInst::ICMP_SLT; break; @@ -3066,12 +3171,12 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, if (ParseType(Ty, true /*void allowed*/)) return true; Type *ResType = PFS.getFunction().getReturnType(); - + if (Ty->isVoidTy()) { if (!ResType->isVoidTy()) return Error(TypeLoc, "value doesn't match function result type '" + getTypeString(ResType) + "'"); - + Inst = ReturnInst::Create(Context); return false; } @@ -3082,7 +3187,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, if (ResType != RV->getType()) return Error(TypeLoc, "value doesn't match function result type '" + getTypeString(ResType) + "'"); - + Inst = ReturnInst::Create(Context, RV); return false; } @@ -3144,7 +3249,7 @@ bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) { ParseToken(lltok::comma, "expected ',' after case value") || ParseTypeAndBasicBlock(DestBB, PFS)) return true; - + if (!SeenCases.insert(Constant)) return Error(CondLoc, "duplicate case value in switch"); if (!isa<ConstantInt>(Constant)) @@ -3172,26 +3277,26 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { ParseToken(lltok::comma, "expected ',' after indirectbr address") || ParseToken(lltok::lsquare, "expected '[' with indirectbr")) return true; - + if (!Address->getType()->isPointerTy()) return Error(AddrLoc, "indirectbr address must have pointer type"); - + // Parse the destination list. SmallVector<BasicBlock*, 16> DestList; - + if (Lex.getKind() != lltok::rsquare) { BasicBlock *DestBB; if (ParseTypeAndBasicBlock(DestBB, PFS)) return true; DestList.push_back(DestBB); - + while (EatIfPresent(lltok::comma)) { if (ParseTypeAndBasicBlock(DestBB, PFS)) return true; DestList.push_back(DestBB); } } - + if (ParseToken(lltok::rsquare, "expected ']' at end of block list")) return true; @@ -3208,7 +3313,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { /// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy CallLoc = Lex.getLoc(); - Attributes RetAttrs, FnAttrs; + AttrBuilder RetAttrs, FnAttrs; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3217,11 +3322,11 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { BasicBlock *NormalBB, *UnwindBB; if (ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseOptionalAttrs(FnAttrs, 2) || + ParseOptionalFuncAttrs(FnAttrs) || ParseToken(lltok::kw_to, "expected 'to' in invoke") || ParseTypeAndBasicBlock(NormalBB, PFS) || ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") || @@ -3251,10 +3356,13 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // Set up the Attributes for the function. + // Set up the Attribute for the function. SmallVector<AttributeWithIndex, 8> Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + if (RetAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttributeSet::ReturnIndex, + Attribute::get(Callee->getContext(), + RetAttrs))); SmallVector<Value*, 8> Args; @@ -3274,18 +3382,21 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs != Attribute::None) + if (ArgList[i].Attrs.hasAttributes()) Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); + if (FnAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttributeSet::FunctionIndex, + Attribute::get(Callee->getContext(), + FnAttrs))); - // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs); + // Finish off the Attribute and check them + AttributeSet PAL = AttributeSet::get(Context, Attrs); InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); II->setCallingConv(CC); @@ -3607,7 +3718,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { /// ParameterList OptionalAttrs bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, bool isTail) { - Attributes RetAttrs, FnAttrs; + AttrBuilder RetAttrs, FnAttrs; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3617,11 +3728,11 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) || ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseOptionalAttrs(FnAttrs, 2)) + ParseOptionalFuncAttrs(FnAttrs)) return true; // If RetType is a non-function pointer type, then this is the short syntax @@ -3647,10 +3758,13 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // Set up the Attributes for the function. + // Set up the Attribute for the function. SmallVector<AttributeWithIndex, 8> Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + if (RetAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttributeSet::ReturnIndex, + Attribute::get(Callee->getContext(), + RetAttrs))); SmallVector<Value*, 8> Args; @@ -3670,18 +3784,21 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs != Attribute::None) + if (ArgList[i].Attrs.hasAttributes()) Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); + if (FnAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttributeSet::FunctionIndex, + Attribute::get(Callee->getContext(), + FnAttrs))); - // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs); + // Finish off the Attribute and check them + AttributeSet PAL = AttributeSet::get(Context, Attrs); CallInst *CI = CallInst::Create(Callee, Args); CI->setTailCall(isTail); @@ -3726,7 +3843,7 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { /// ParseLoad /// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)? -/// ::= 'load' 'atomic' 'volatile'? TypeAndValue +/// ::= 'load' 'atomic' 'volatile'? TypeAndValue /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { Value *Val; LocTy Loc; @@ -3962,9 +4079,6 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.push_back(Val); } - if (Val && Val->getType()->isVectorTy() && Indices.size() != 1) - return Error(EltLoc, "vector getelementptrs must have a single index"); - if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices)) return Error(Loc, "invalid getelementptr indices"); Inst = GetElementPtrInst::Create(Ptr, Indices); @@ -4003,7 +4117,7 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndValue(Val1, Loc1, PFS) || ParseIndexList(Indices, AteExtraComma)) return true; - + if (!Val0->getType()->isAggregateType()) return Error(Loc0, "insertvalue operand must be aggregate type"); @@ -4033,7 +4147,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts, Elts.push_back(0); continue; } - + Value *V = 0; if (ParseTypeAndValue(V, PFS)) return true; Elts.push_back(V); |
