X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=6f67e48f21aae477afc01696adb0b0f4e8174c3e;hb=07aae2e7d58fe23e370e0cbb9e1a3def99434c36;hp=cdfacbebbfc3552bcad25b4333dd85b309a269fa;hpb=283c8caccd093f8e1d4f0bdd01ac240b4edbd20a;p=oota-llvm.git diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index cdfacbebbfc..6f67e48f21a 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -26,6 +26,13 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +static std::string getTypeString(Type *T) { + std::string Result; + raw_string_ostream Tmp(Result); + Tmp << *T; + return Tmp.str(); +} + /// Run: module ::= toplevelentity* bool LLParser::Run() { // Prime the lexer. @@ -59,24 +66,6 @@ bool LLParser::ValidateEndOfModule() { } - // Update auto-upgraded malloc calls to "malloc". - // FIXME: Remove in LLVM 3.0. - if (MallocF) { - MallocF->setName("malloc"); - // If setName() does not set the name to "malloc", then there is already a - // declaration of "malloc". In that case, iterate over all calls to MallocF - // and get them to call the declared "malloc" instead. - if (MallocF->getName() != "malloc") { - Constant *RealMallocF = M->getFunction("malloc"); - if (RealMallocF->getType() != MallocF->getType()) - RealMallocF = ConstantExpr::getBitCast(RealMallocF, MallocF->getType()); - MallocF->replaceAllUsesWith(RealMallocF); - MallocF->eraseFromParent(); - MallocF = NULL; - } - } - - // If there are entries in ForwardRefBlockAddresses at this point, they are // references after the function was defined. Resolve those now. while (!ForwardRefBlockAddresses.empty()) { @@ -100,15 +89,16 @@ bool LLParser::ValidateEndOfModule() { ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin()); } - - if (!ForwardRefTypes.empty()) - return Error(ForwardRefTypes.begin()->second.second, - "use of undefined type named '" + - ForwardRefTypes.begin()->first + "'"); - if (!ForwardRefTypeIDs.empty()) - return Error(ForwardRefTypeIDs.begin()->second.second, - "use of undefined type '%" + - Twine(ForwardRefTypeIDs.begin()->first) + "'"); + for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) + if (NumberedTypes[i].second.isValid()) + return Error(NumberedTypes[i].second, + "use of undefined type '%" + Twine(i) + "'"); + + for (StringMap >::iterator I = + NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) + if (I->second.second.isValid()) + return Error(I->second.second, + "use of undefined type named '" + I->getKey() + "'"); if (!ForwardRefVals.empty()) return Error(ForwardRefVals.begin()->second.second, @@ -130,8 +120,6 @@ bool LLParser::ValidateEndOfModule() { for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove - // Check debug info intrinsics. - CheckDebugInfoIntrinsics(M); return false; } @@ -176,15 +164,12 @@ bool LLParser::ParseTopLevelEntities() { switch (Lex.getKind()) { default: return TokError("expected top-level entity"); case lltok::Eof: return false; - //case lltok::kw_define: case lltok::kw_declare: if (ParseDeclare()) return true; break; case lltok::kw_define: if (ParseDefine()) return true; break; case lltok::kw_module: if (ParseModuleAsm()) return true; break; case lltok::kw_target: if (ParseTargetDefinition()) return true; break; case lltok::kw_deplibs: if (ParseDepLibs()) return true; break; - case lltok::kw_type: if (ParseUnnamedType()) return true; break; case lltok::LocalVarID: if (ParseUnnamedType()) return true; break; - case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0 case lltok::LocalVar: if (ParseNamedType()) return true; break; case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break; case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break; @@ -199,12 +184,13 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_private: // OptionalLinkage case lltok::kw_linker_private: // OptionalLinkage case lltok::kw_linker_private_weak: // OptionalLinkage - case lltok::kw_linker_private_weak_def_auto: // OptionalLinkage + case lltok::kw_linker_private_weak_def_auto: // FIXME: backwards compat. case lltok::kw_internal: // OptionalLinkage case lltok::kw_weak: // OptionalLinkage case lltok::kw_weak_odr: // OptionalLinkage case lltok::kw_linkonce: // OptionalLinkage case lltok::kw_linkonce_odr: // OptionalLinkage + case lltok::kw_linkonce_odr_auto_hide: // OptionalLinkage case lltok::kw_appending: // OptionalLinkage case lltok::kw_dllexport: // OptionalLinkage case lltok::kw_common: // OptionalLinkage @@ -249,11 +235,7 @@ bool LLParser::ParseModuleAsm() { if (ParseToken(lltok::kw_asm, "expected 'module asm'") || ParseStringConstant(AsmStr)) return true; - const std::string &AsmSoFar = M->getModuleInlineAsm(); - if (AsmSoFar.empty()) - M->setModuleInlineAsm(AsmStr); - else - M->setModuleInlineAsm(AsmSoFar+"\n"+AsmStr); + M->appendModuleInlineAsm(AsmStr); return false; } @@ -308,45 +290,35 @@ bool LLParser::ParseDepLibs() { } /// ParseUnnamedType: -/// ::= 'type' type /// ::= LocalVarID '=' 'type' type bool LLParser::ParseUnnamedType() { - unsigned TypeID = NumberedTypes.size(); - - // Handle the LocalVarID form. - if (Lex.getKind() == lltok::LocalVarID) { - if (Lex.getUIntVal() != TypeID) - return Error(Lex.getLoc(), "type expected to be numbered '%" + - Twine(TypeID) + "'"); - Lex.Lex(); // eat LocalVarID; - - if (ParseToken(lltok::equal, "expected '=' after name")) - return true; - } - LocTy TypeLoc = Lex.getLoc(); - if (ParseToken(lltok::kw_type, "expected 'type' after '='")) return true; + unsigned TypeID = Lex.getUIntVal(); + Lex.Lex(); // eat LocalVarID; - PATypeHolder Ty(Type::getVoidTy(Context)); - if (ParseType(Ty)) return true; - - // See if this type was previously referenced. - std::map >::iterator - FI = ForwardRefTypeIDs.find(TypeID); - if (FI != ForwardRefTypeIDs.end()) { - if (FI->second.first.get() == Ty) - return Error(TypeLoc, "self referential type is invalid"); + if (ParseToken(lltok::equal, "expected '=' after name") || + ParseToken(lltok::kw_type, "expected 'type' after '='")) + return true; - cast(FI->second.first.get())->refineAbstractTypeTo(Ty); - Ty = FI->second.first.get(); - ForwardRefTypeIDs.erase(FI); + if (TypeID >= NumberedTypes.size()) + NumberedTypes.resize(TypeID+1); + + Type *Result = 0; + if (ParseStructDefinition(TypeLoc, "", + NumberedTypes[TypeID], Result)) return true; + + if (!isa(Result)) { + std::pair &Entry = NumberedTypes[TypeID]; + if (Entry.first) + return Error(TypeLoc, "non-struct types may not be recursive"); + Entry.first = Result; + Entry.second = SMLoc(); } - NumberedTypes.push_back(Ty); - return false; } + /// toplevelentity /// ::= LocalVar '=' 'type' type bool LLParser::ParseNamedType() { @@ -354,42 +326,23 @@ bool LLParser::ParseNamedType() { LocTy NameLoc = Lex.getLoc(); Lex.Lex(); // eat LocalVar. - PATypeHolder Ty(Type::getVoidTy(Context)); - if (ParseToken(lltok::equal, "expected '=' after name") || - ParseToken(lltok::kw_type, "expected 'type' after name") || - ParseType(Ty)) + ParseToken(lltok::kw_type, "expected 'type' after name")) return true; - - // Set the type name, checking for conflicts as we do so. - bool AlreadyExists = M->addTypeName(Name, Ty); - if (!AlreadyExists) return false; - - // See if this type is a forward reference. We need to eagerly resolve - // types to allow recursive type redefinitions below. - std::map >::iterator - FI = ForwardRefTypes.find(Name); - if (FI != ForwardRefTypes.end()) { - if (FI->second.first.get() == Ty) - return Error(NameLoc, "self referential type is invalid"); - - cast(FI->second.first.get())->refineAbstractTypeTo(Ty); - Ty = FI->second.first.get(); - ForwardRefTypes.erase(FI); + + Type *Result = 0; + if (ParseStructDefinition(NameLoc, Name, + NamedTypes[Name], Result)) return true; + + if (!isa(Result)) { + std::pair &Entry = NamedTypes[Name]; + if (Entry.first) + return Error(NameLoc, "non-struct types may not be recursive"); + Entry.first = Result; + Entry.second = SMLoc(); } - - // Inserting a name that is already defined, get the existing name. - const Type *Existing = M->getTypeByName(Name); - assert(Existing && "Conflict but no matching type?!"); - - // Otherwise, this is an attempt to redefine a type. That's okay if - // the redefinition is identical to the original. - // FIXME: REMOVE REDEFINITIONS IN LLVM 3.0 - if (Existing == Ty) return false; - - // Any other kind of (non-equivalent) redefinition is an error. - return Error(NameLoc, "redefinition of type named '" + Name + "' of type '" + - Ty->getDescription() + "'"); + + return false; } @@ -518,7 +471,7 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) { if (Result) return false; // Otherwise, create MDNode forward reference. - MDNode *FwdNode = MDNode::getTemporary(Context, 0, 0); + MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef()); ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); if (NumberedMetadata.size() <= MID) @@ -565,7 +518,7 @@ bool LLParser::ParseStandaloneMetadata() { unsigned MetadataID = 0; LocTy TyLoc; - PATypeHolder Ty(Type::getVoidTy(Context)); + Type *Ty = 0; SmallVector Elts; if (ParseUInt32(MetadataID) || ParseToken(lltok::equal, "expected '=' here") || @@ -576,7 +529,7 @@ bool LLParser::ParseStandaloneMetadata() { ParseToken(lltok::rbrace, "expected end of metadata node")) return true; - MDNode *Init = MDNode::get(Context, Elts.data(), Elts.size()); + MDNode *Init = MDNode::get(Context, Elts); // See if this was forward referenced, if so, handle it. std::map, LocTy> >::iterator @@ -624,8 +577,7 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, Linkage != GlobalValue::InternalLinkage && Linkage != GlobalValue::PrivateLinkage && Linkage != GlobalValue::LinkerPrivateLinkage && - Linkage != GlobalValue::LinkerPrivateWeakLinkage && - Linkage != GlobalValue::LinkerPrivateWeakDefAutoLinkage) + Linkage != GlobalValue::LinkerPrivateWeakLinkage) return Error(LinkageLoc, "invalid linkage type for alias"); Constant *Aliasee; @@ -693,12 +645,13 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility) { unsigned AddrSpace; - bool ThreadLocal, IsConstant, UnnamedAddr; + bool IsConstant, UnnamedAddr; + GlobalVariable::ThreadLocalMode TLM; LocTy UnnamedAddrLoc; LocTy TyLoc; - PATypeHolder Ty(Type::getVoidTy(Context)); - if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) || + Type *Ty = 0; + if (ParseOptionalThreadLocal(TLM) || ParseOptionalAddrSpace(AddrSpace) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || @@ -739,7 +692,8 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (GV == 0) { GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, 0, - Name, 0, false, AddrSpace); + Name, 0, GlobalVariable::NotThreadLocal, + AddrSpace); } else { if (GV->getType()->getElementType() != Ty) return Error(TyLoc, @@ -758,7 +712,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); - GV->setThreadLocal(ThreadLocal); + GV->setThreadLocalMode(TLM); GV->setUnnamedAddr(UnnamedAddr); // Parse attributes on the global. @@ -790,9 +744,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, /// GetGlobalVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. -GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, +GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, LocTy Loc) { - const PointerType *PTy = dyn_cast(Ty); + PointerType *PTy = dyn_cast(Ty); if (PTy == 0) { Error(Loc, "global variable reference must have pointer type"); return 0; @@ -815,31 +769,24 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, if (Val) { if (Val->getType() == Ty) return Val; Error(Loc, "'@" + Name + "' defined with type '" + - Val->getType()->getDescription() + "'"); + getTypeString(Val->getType()) + "'"); return 0; } // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal; - if (const FunctionType *FT = dyn_cast(PTy->getElementType())) { - // Function types can return opaque but functions can't. - if (FT->getReturnType()->isOpaqueTy()) { - Error(Loc, "function may not return opaque type"); - return 0; - } - + if (FunctionType *FT = dyn_cast(PTy->getElementType())) FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); - } else { + else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, GlobalValue::ExternalWeakLinkage, 0, Name); - } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; } -GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { - const PointerType *PTy = dyn_cast(Ty); +GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { + PointerType *PTy = dyn_cast(Ty); if (PTy == 0) { Error(Loc, "global variable reference must have pointer type"); return 0; @@ -860,23 +807,17 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { if (Val) { if (Val->getType() == Ty) return Val; Error(Loc, "'@" + Twine(ID) + "' defined with type '" + - Val->getType()->getDescription() + "'"); + getTypeString(Val->getType()) + "'"); return 0; } // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal; - if (const FunctionType *FT = dyn_cast(PTy->getElementType())) { - // Function types can return opaque but functions can't. - if (FT->getReturnType()->isOpaqueTy()) { - Error(Loc, "function may not return opaque type"); - return 0; - } + if (FunctionType *FT = dyn_cast(PTy->getElementType())) FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); - } else { + else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, GlobalValue::ExternalWeakLinkage, 0, ""); - } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -919,6 +860,46 @@ bool LLParser::ParseUInt32(unsigned &Val) { return false; } +/// ParseTLSModel +/// := 'localdynamic' +/// := 'initialexec' +/// := 'localexec' +bool LLParser::ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM) { + switch (Lex.getKind()) { + default: + return TokError("expected localdynamic, initialexec or localexec"); + case lltok::kw_localdynamic: + TLM = GlobalVariable::LocalDynamicTLSModel; + break; + case lltok::kw_initialexec: + TLM = GlobalVariable::InitialExecTLSModel; + break; + case lltok::kw_localexec: + TLM = GlobalVariable::LocalExecTLSModel; + break; + } + + Lex.Lex(); + return false; +} + +/// ParseOptionalThreadLocal +/// := /*empty*/ +/// := 'thread_local' +/// := 'thread_local' '(' tlsmodel ')' +bool LLParser::ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) { + TLM = GlobalVariable::NotThreadLocal; + if (!EatIfPresent(lltok::kw_thread_local)) + return false; + + TLM = GlobalVariable::GeneralDynamicTLSModel; + if (Lex.getKind() == lltok::lparen) { + Lex.Lex(); + return ParseTLSModel(TLM) || + ParseToken(lltok::rparen, "expected ')' after thread local model"); + } + return false; +} /// ParseOptionalAddrSpace /// := /*empty*/ @@ -935,65 +916,49 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { /// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind /// indicates what kind of attribute list this is: 0: function arg, 1: result, /// 2: function attr. -/// 3: function arg after value: FIXME: REMOVE IN LLVM 3.0 -bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { - Attrs = Attribute::None; +bool LLParser::ParseOptionalAttrs(Attributes::Builder &B, unsigned AttrKind) { LocTy AttrLoc = Lex.getLoc(); + bool HaveError = false; + + B.clear(); while (1) { - switch (Lex.getKind()) { - case lltok::kw_sext: - case lltok::kw_zext: - // Treat these as signext/zeroext if they occur in the argument list after - // the value, as in "call i8 @foo(i8 10 sext)". If they occur before the - // value, as in "call i8 @foo(i8 sext (" then it is part of a constant - // expr. - // FIXME: REMOVE THIS IN LLVM 3.0 - if (AttrKind == 3) { - if (Lex.getKind() == lltok::kw_sext) - Attrs |= Attribute::SExt; - else - Attrs |= Attribute::ZExt; - break; - } - // FALL THROUGH. + 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"); - - if (AttrKind != 0 && AttrKind != 3 && (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_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_hotpatch: Attrs |= Attribute::Hotpatch; break; + return HaveError; + case lltok::kw_zeroext: B.addAttribute(Attributes::ZExt); break; + case lltok::kw_signext: B.addAttribute(Attributes::SExt); break; + case lltok::kw_inreg: B.addAttribute(Attributes::InReg); break; + case lltok::kw_sret: B.addAttribute(Attributes::StructRet); break; + case lltok::kw_noalias: B.addAttribute(Attributes::NoAlias); break; + case lltok::kw_nocapture: B.addAttribute(Attributes::NoCapture); break; + case lltok::kw_byval: B.addAttribute(Attributes::ByVal); break; + case lltok::kw_nest: B.addAttribute(Attributes::Nest); break; + + case lltok::kw_noreturn: B.addAttribute(Attributes::NoReturn); break; + case lltok::kw_nounwind: B.addAttribute(Attributes::NoUnwind); break; + case lltok::kw_uwtable: B.addAttribute(Attributes::UWTable); break; + case lltok::kw_returns_twice: B.addAttribute(Attributes::ReturnsTwice); break; + case lltok::kw_noinline: B.addAttribute(Attributes::NoInline); break; + case lltok::kw_readnone: B.addAttribute(Attributes::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attributes::ReadOnly); break; + case lltok::kw_inlinehint: B.addAttribute(Attributes::InlineHint); break; + case lltok::kw_alwaysinline: B.addAttribute(Attributes::AlwaysInline); break; + case lltok::kw_optsize: B.addAttribute(Attributes::OptimizeForSize); break; + case lltok::kw_ssp: B.addAttribute(Attributes::StackProtect); break; + case lltok::kw_sspreq: B.addAttribute(Attributes::StackProtectReq); break; + case lltok::kw_noredzone: B.addAttribute(Attributes::NoRedZone); break; + case lltok::kw_noimplicitfloat: B.addAttribute(Attributes::NoImplicitFloat); break; + case lltok::kw_naked: B.addAttribute(Attributes::Naked); break; + case lltok::kw_nonlazybind: B.addAttribute(Attributes::NonLazyBind); break; + case lltok::kw_address_safety: B.addAttribute(Attributes::AddressSafety); break; case lltok::kw_alignstack: { unsigned Alignment; if (ParseOptionalStackAlignment(Alignment)) return true; - Attrs |= Attribute::constructStackAlignmentFromInt(Alignment); + B.addStackAlignmentAttr(Alignment); continue; } @@ -1001,11 +966,56 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { unsigned Alignment; if (ParseOptionalAlignment(Alignment)) return true; - Attrs |= Attribute::constructAlignmentFromInt(Alignment); + B.addAlignmentAttr(Alignment); continue; } } + + // Perform some error checking. + switch (Token) { + default: + if (AttrKind == 2) + HaveError |= Error(AttrLoc, "invalid use of attribute on a function"); + break; + case lltok::kw_align: + // As a hack, we allow "align 2" on functions as a synonym for + // "alignstack 2". + break; + + // Parameter Only: + case lltok::kw_sret: + case lltok::kw_nocapture: + case lltok::kw_byval: + case lltok::kw_nest: + if (AttrKind != 0) + HaveError |= Error(AttrLoc, "invalid use of parameter-only attribute"); + break; + + // Function Only: + case lltok::kw_noreturn: + case lltok::kw_nounwind: + case lltok::kw_readnone: + case lltok::kw_readonly: + case lltok::kw_noinline: + 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_inlinehint: + case lltok::kw_alignstack: + case lltok::kw_uwtable: + case lltok::kw_nonlazybind: + case lltok::kw_returns_twice: + case lltok::kw_address_safety: + if (AttrKind != 2) + HaveError |= Error(AttrLoc, "invalid use of function-only attribute"); + break; + } + Lex.Lex(); } } @@ -1015,12 +1025,12 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { /// ::= 'private' /// ::= 'linker_private' /// ::= 'linker_private_weak' -/// ::= 'linker_private_weak_def_auto' /// ::= 'internal' /// ::= 'weak' /// ::= 'weak_odr' /// ::= 'linkonce' /// ::= 'linkonce_odr' +/// ::= 'linkonce_odr_auto_hide' /// ::= 'available_externally' /// ::= 'appending' /// ::= 'dllexport' @@ -1037,14 +1047,15 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { case lltok::kw_linker_private_weak: Res = GlobalValue::LinkerPrivateWeakLinkage; break; - case lltok::kw_linker_private_weak_def_auto: - Res = GlobalValue::LinkerPrivateWeakDefAutoLinkage; - break; case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break; case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break; case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break; case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break; case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break; + case lltok::kw_linkonce_odr_auto_hide: + case lltok::kw_linker_private_weak_def_auto: // FIXME: For backwards compat. + Res = GlobalValue::LinkOnceODRAutoHideLinkage; + break; case lltok::kw_available_externally: Res = GlobalValue::AvailableExternallyLinkage; break; @@ -1091,6 +1102,8 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { /// ::= 'msp430_intrcc' /// ::= 'ptx_kernel' /// ::= 'ptx_device' +/// ::= 'spir_func' +/// ::= 'spir_kernel' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { @@ -1108,16 +1121,16 @@ 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_cc: { unsigned ArbitraryCC; Lex.Lex(); - if (ParseUInt32(ArbitraryCC)) { + if (ParseUInt32(ArbitraryCC)) return true; - } else - CC = static_cast(ArbitraryCC); - return false; + CC = static_cast(ArbitraryCC); + return false; } - break; } Lex.Lex(); @@ -1133,7 +1146,7 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst, return TokError("expected metadata after comma"); std::string Name = Lex.getStrVal(); - unsigned MDK = M->getMDKindID(Name.c_str()); + unsigned MDK = M->getMDKindID(Name); Lex.Lex(); MDNode *Node; @@ -1212,6 +1225,32 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment, return false; } +/// ParseScopeAndOrdering +/// if isAtomic: ::= 'singlethread'? AtomicOrdering +/// else: ::= +/// +/// This sets Scope and Ordering to the parsed values. +bool LLParser::ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope, + AtomicOrdering &Ordering) { + if (!isAtomic) + return false; + + Scope = CrossThread; + if (EatIfPresent(lltok::kw_singlethread)) + Scope = SingleThread; + switch (Lex.getKind()) { + default: return TokError("Expected ordering on atomic instruction"); + case lltok::kw_unordered: Ordering = Unordered; break; + case lltok::kw_monotonic: Ordering = Monotonic; break; + case lltok::kw_acquire: Ordering = Acquire; break; + case lltok::kw_release: Ordering = Release; break; + case lltok::kw_acq_rel: Ordering = AcquireRelease; break; + case lltok::kw_seq_cst: Ordering = SequentiallyConsistent; break; + } + Lex.Lex(); + return false; +} + /// ParseOptionalStackAlignment /// ::= /* empty */ /// ::= 'alignstack' '(' 4 ')' @@ -1265,166 +1304,68 @@ bool LLParser::ParseIndexList(SmallVectorImpl &Indices, // Type Parsing. //===----------------------------------------------------------------------===// -/// ParseType - Parse and resolve a full type. -bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) { - LocTy TypeLoc = Lex.getLoc(); - if (ParseTypeRec(Result)) return true; - - // Verify no unresolved uprefs. - if (!UpRefs.empty()) - return Error(UpRefs.back().Loc, "invalid unresolved type up reference"); - - if (!AllowVoid && Result.get()->isVoidTy()) - return Error(TypeLoc, "void type only allowed for function results"); - - return false; -} - -/// HandleUpRefs - Every time we finish a new layer of types, this function is -/// called. It loops through the UpRefs vector, which is a list of the -/// currently active types. For each type, if the up-reference is contained in -/// the newly completed type, we decrement the level count. When the level -/// count reaches zero, the up-referenced type is the type that is passed in: -/// thus we can complete the cycle. -/// -PATypeHolder LLParser::HandleUpRefs(const Type *ty) { - // If Ty isn't abstract, or if there are no up-references in it, then there is - // nothing to resolve here. - if (!ty->isAbstract() || UpRefs.empty()) return ty; - - PATypeHolder Ty(ty); -#if 0 - dbgs() << "Type '" << Ty->getDescription() - << "' newly formed. Resolving upreferences.\n" - << UpRefs.size() << " upreferences active!\n"; -#endif - - // If we find any resolvable upreferences (i.e., those whose NestingLevel goes - // to zero), we resolve them all together before we resolve them to Ty. At - // the end of the loop, if there is anything to resolve to Ty, it will be in - // this variable. - OpaqueType *TypeToResolve = 0; - - for (unsigned i = 0; i != UpRefs.size(); ++i) { - // Determine if 'Ty' directly contains this up-references 'LastContainedTy'. - bool ContainsType = - std::find(Ty->subtype_begin(), Ty->subtype_end(), - UpRefs[i].LastContainedTy) != Ty->subtype_end(); - -#if 0 - dbgs() << " UR#" << i << " - TypeContains(" << Ty->getDescription() << ", " - << UpRefs[i].LastContainedTy->getDescription() << ") = " - << (ContainsType ? "true" : "false") - << " level=" << UpRefs[i].NestingLevel << "\n"; -#endif - if (!ContainsType) - continue; - - // Decrement level of upreference - unsigned Level = --UpRefs[i].NestingLevel; - UpRefs[i].LastContainedTy = Ty; - - // If the Up-reference has a non-zero level, it shouldn't be resolved yet. - if (Level != 0) - continue; - -#if 0 - dbgs() << " * Resolving upreference for " << UpRefs[i].UpRefTy << "\n"; -#endif - if (!TypeToResolve) - TypeToResolve = UpRefs[i].UpRefTy; - else - UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve); - UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list. - --i; // Do not skip the next element. - } - - if (TypeToResolve) - TypeToResolve->refineAbstractTypeTo(Ty); - - return Ty; -} - - -/// ParseTypeRec - The recursive function used to process the internal -/// implementation details of types. -bool LLParser::ParseTypeRec(PATypeHolder &Result) { +/// ParseType - Parse a type. +bool LLParser::ParseType(Type *&Result, bool AllowVoid) { + SMLoc TypeLoc = Lex.getLoc(); switch (Lex.getKind()) { default: return TokError("expected type"); case lltok::Type: - // TypeRec ::= 'float' | 'void' (etc) + // Type ::= 'float' | 'void' (etc) Result = Lex.getTyVal(); Lex.Lex(); break; - case lltok::kw_opaque: - // TypeRec ::= 'opaque' - Result = OpaqueType::get(Context); - Lex.Lex(); - break; case lltok::lbrace: - // TypeRec ::= '{' ... '}' - if (ParseStructType(Result, false)) + // Type ::= StructType + if (ParseAnonStructType(Result, false)) return true; break; case lltok::lsquare: - // TypeRec ::= '[' ... ']' + // Type ::= '[' ... ']' Lex.Lex(); // eat the lsquare. if (ParseArrayVectorType(Result, false)) return true; break; case lltok::less: // Either vector or packed struct. - // TypeRec ::= '<' ... '>' + // Type ::= '<' ... '>' Lex.Lex(); if (Lex.getKind() == lltok::lbrace) { - if (ParseStructType(Result, true) || + if (ParseAnonStructType(Result, true) || ParseToken(lltok::greater, "expected '>' at end of packed struct")) return true; } else if (ParseArrayVectorType(Result, true)) return true; break; - case lltok::LocalVar: - case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0 - // TypeRec ::= %foo - if (const Type *T = M->getTypeByName(Lex.getStrVal())) { - Result = T; - } else { - Result = OpaqueType::get(Context); - ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(), - std::make_pair(Result, - Lex.getLoc()))); - M->addTypeName(Lex.getStrVal(), Result.get()); + case lltok::LocalVar: { + // Type ::= %foo + std::pair &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) { + Entry.first = StructType::create(Context, Lex.getStrVal()); + Entry.second = Lex.getLoc(); } + Result = Entry.first; Lex.Lex(); break; + } - case lltok::LocalVarID: - // TypeRec ::= %4 - if (Lex.getUIntVal() < NumberedTypes.size()) - Result = NumberedTypes[Lex.getUIntVal()]; - else { - std::map >::iterator - I = ForwardRefTypeIDs.find(Lex.getUIntVal()); - if (I != ForwardRefTypeIDs.end()) - Result = I->second.first; - else { - Result = OpaqueType::get(Context); - ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(), - std::make_pair(Result, - Lex.getLoc()))); - } + case lltok::LocalVarID: { + // Type ::= %4 + if (Lex.getUIntVal() >= NumberedTypes.size()) + NumberedTypes.resize(Lex.getUIntVal()+1); + std::pair &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) { + Entry.first = StructType::create(Context); + Entry.second = Lex.getLoc(); } + Result = Entry.first; Lex.Lex(); break; - case lltok::backslash: { - // TypeRec ::= '\' 4 - Lex.Lex(); - unsigned Val; - if (ParseUInt32(Val)) return true; - OpaqueType *OT = OpaqueType::get(Context); //Use temporary placeholder. - UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT)); - Result = OT; - break; } } @@ -1432,34 +1373,37 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { while (1) { switch (Lex.getKind()) { // End of type. - default: return false; + default: + if (!AllowVoid && Result->isVoidTy()) + return Error(TypeLoc, "void type only allowed for function results"); + return false; - // TypeRec ::= TypeRec '*' + // Type ::= Type '*' case lltok::star: - if (Result.get()->isLabelTy()) + if (Result->isLabelTy()) return TokError("basic block pointers are invalid"); - if (Result.get()->isVoidTy()) - return TokError("pointers to void are invalid; use i8* instead"); - if (!PointerType::isValidElementType(Result.get())) + if (Result->isVoidTy()) + return TokError("pointers to void are invalid - use i8* instead"); + if (!PointerType::isValidElementType(Result)) return TokError("pointer to this type is invalid"); - Result = HandleUpRefs(PointerType::getUnqual(Result.get())); + Result = PointerType::getUnqual(Result); Lex.Lex(); break; - // TypeRec ::= TypeRec 'addrspace' '(' uint32 ')' '*' + // Type ::= Type 'addrspace' '(' uint32 ')' '*' case lltok::kw_addrspace: { - if (Result.get()->isLabelTy()) + if (Result->isLabelTy()) return TokError("basic block pointers are invalid"); - if (Result.get()->isVoidTy()) + if (Result->isVoidTy()) return TokError("pointers to void are invalid; use i8* instead"); - if (!PointerType::isValidElementType(Result.get())) + if (!PointerType::isValidElementType(Result)) return TokError("pointer to this type is invalid"); unsigned AddrSpace; if (ParseOptionalAddrSpace(AddrSpace) || ParseToken(lltok::star, "expected '*' in address space")) return true; - Result = HandleUpRefs(PointerType::get(Result.get(), AddrSpace)); + Result = PointerType::get(Result, AddrSpace); break; } @@ -1490,21 +1434,17 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, // Parse the argument. LocTy ArgLoc; - PATypeHolder ArgTy(Type::getVoidTy(Context)); - unsigned ArgAttrs1 = Attribute::None; - unsigned ArgAttrs2 = Attribute::None; + Type *ArgTy = 0; + Attributes::Builder ArgAttrs; Value *V; if (ParseType(ArgTy, ArgLoc)) return true; // Otherwise, handle normal operands. - if (ParseOptionalAttrs(ArgAttrs1, 0) || - ParseValue(ArgTy, V, PFS) || - // FIXME: Should not allow attributes after the argument, remove this - // in LLVM 3.0. - ParseOptionalAttrs(ArgAttrs2, 3)) + if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS)) return true; - ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2)); + ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(V->getContext(), + ArgAttrs))); } Lex.Lex(); // Lex the ')'. @@ -1514,7 +1454,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, /// ParseArgumentList - Parse the argument list for a function type or function -/// prototype. If 'inType' is true then we are parsing a FunctionType. +/// prototype. /// ::= '(' ArgTypeListI ')' /// ArgTypeListI /// ::= /*empty*/ @@ -1522,8 +1462,8 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, /// ::= ArgTypeList ',' '...' /// ::= ArgType (',' ArgType)* /// -bool LLParser::ParseArgumentList(std::vector &ArgList, - bool &isVarArg, bool inType) { +bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, + bool &isVarArg){ isVarArg = false; assert(Lex.getKind() == lltok::lparen); Lex.Lex(); // eat the (. @@ -1535,21 +1475,17 @@ bool LLParser::ParseArgumentList(std::vector &ArgList, Lex.Lex(); } else { LocTy TypeLoc = Lex.getLoc(); - PATypeHolder ArgTy(Type::getVoidTy(Context)); - unsigned Attrs; + Type *ArgTy = 0; + Attributes::Builder Attrs; std::string Name; - // If we're parsing a type, use ParseTypeRec, because we allow recursive - // types (such as a function returning a pointer to itself). If parsing a - // function prototype, we require fully resolved types. - if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) || + if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); - if (Lex.getKind() == lltok::LocalVar || - Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0 + if (Lex.getKind() == lltok::LocalVar) { Name = Lex.getStrVal(); Lex.Lex(); } @@ -1557,7 +1493,9 @@ bool LLParser::ParseArgumentList(std::vector &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, + Attributes::get(ArgTy->getContext(), + Attrs), Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1568,24 +1506,24 @@ bool LLParser::ParseArgumentList(std::vector &ArgList, // Otherwise must be an argument type. TypeLoc = Lex.getLoc(); - if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) || - ParseOptionalAttrs(Attrs, 0)) return true; + if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); - if (Lex.getKind() == lltok::LocalVar || - Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0 + if (Lex.getKind() == lltok::LocalVar) { Name = Lex.getStrVal(); Lex.Lex(); } else { Name = ""; } - if (!ArgTy->isFirstClassType() && !ArgTy->isOpaqueTy()) + 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, + Attributes::get(ArgTy->getContext(), Attrs), + Name)); } } @@ -1594,94 +1532,142 @@ bool LLParser::ParseArgumentList(std::vector &ArgList, /// ParseFunctionType /// ::= Type ArgumentList OptionalAttrs -bool LLParser::ParseFunctionType(PATypeHolder &Result) { +bool LLParser::ParseFunctionType(Type *&Result) { assert(Lex.getKind() == lltok::lparen); if (!FunctionType::isValidReturnType(Result)) return TokError("invalid function return type"); - std::vector ArgList; + SmallVector ArgList; bool isVarArg; - unsigned Attrs; - if (ParseArgumentList(ArgList, isVarArg, true) || - // FIXME: Allow, but ignore attributes on function types! - // FIXME: Remove in LLVM 3.0 - ParseOptionalAttrs(Attrs, 2)) + if (ParseArgumentList(ArgList, isVarArg)) return true; // Reject names on the arguments lists. 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 != 0) { - // Allow but ignore attributes on function types; this permits - // auto-upgrade. - // FIXME: REJECT ATTRIBUTES ON FUNCTION TYPES in LLVM 3.0 - } + if (ArgList[i].Attrs.hasAttributes()) + return Error(ArgList[i].Loc, + "argument attributes invalid in function type"); } - std::vector ArgListTy; + SmallVector ArgListTy; for (unsigned i = 0, e = ArgList.size(); i != e; ++i) - ArgListTy.push_back(ArgList[i].Type); + ArgListTy.push_back(ArgList[i].Ty); + + Result = FunctionType::get(Result, ArgListTy, isVarArg); + return false; +} - Result = HandleUpRefs(FunctionType::get(Result.get(), - ArgListTy, isVarArg)); +/// ParseAnonStructType - Parse an anonymous struct type, which is inlined into +/// other structs. +bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) { + SmallVector Elts; + if (ParseStructBody(Elts)) return true; + + Result = StructType::get(Context, Elts, Packed); return false; } +/// ParseStructDefinition - Parse a struct in a 'type' definition. +bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, + std::pair &Entry, + Type *&ResultTy) { + // 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); + + // If we don't have a struct, then we have a random type alias, which we + // accept for compatibility with old files. These types are not allowed to be + // forward referenced and not allowed to be recursive. + 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(Entry.first); + + SmallVector Body; + if (ParseStructBody(Body) || + (isPacked && ParseToken(lltok::greater, "expected '>' in packed struct"))) + return true; + + STy->setBody(Body, isPacked); + ResultTy = STy; + return false; +} + + /// ParseStructType: Handles packed and unpacked types. parsed elsewhere. -/// TypeRec +/// StructType /// ::= '{' '}' -/// ::= '{' TypeRec (',' TypeRec)* '}' +/// ::= '{' Type (',' Type)* '}' /// ::= '<' '{' '}' '>' -/// ::= '<' '{' TypeRec (',' TypeRec)* '}' '>' -bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) { +/// ::= '<' '{' Type (',' Type)* '}' '>' +bool LLParser::ParseStructBody(SmallVectorImpl &Body) { assert(Lex.getKind() == lltok::lbrace); Lex.Lex(); // Consume the '{' - if (EatIfPresent(lltok::rbrace)) { - Result = StructType::get(Context, Packed); + // Handle the empty struct. + if (EatIfPresent(lltok::rbrace)) return false; - } - std::vector ParamsList; LocTy EltTyLoc = Lex.getLoc(); - if (ParseTypeRec(Result)) return true; - ParamsList.push_back(Result); + Type *Ty = 0; + if (ParseType(Ty)) return true; + Body.push_back(Ty); - if (Result->isVoidTy()) - return Error(EltTyLoc, "struct element can not have void type"); - if (!StructType::isValidElementType(Result)) + if (!StructType::isValidElementType(Ty)) return Error(EltTyLoc, "invalid element type for struct"); while (EatIfPresent(lltok::comma)) { EltTyLoc = Lex.getLoc(); - if (ParseTypeRec(Result)) return true; + if (ParseType(Ty)) return true; - if (Result->isVoidTy()) - return Error(EltTyLoc, "struct element can not have void type"); - if (!StructType::isValidElementType(Result)) + if (!StructType::isValidElementType(Ty)) return Error(EltTyLoc, "invalid element type for struct"); - ParamsList.push_back(Result); + Body.push_back(Ty); } - if (ParseToken(lltok::rbrace, "expected '}' at end of struct")) - return true; - - std::vector ParamsListTy; - for (unsigned i = 0, e = ParamsList.size(); i != e; ++i) - ParamsListTy.push_back(ParamsList[i].get()); - Result = HandleUpRefs(StructType::get(Context, ParamsListTy, Packed)); - return false; + return ParseToken(lltok::rbrace, "expected '}' at end of struct"); } /// ParseArrayVectorType - Parse an array or vector type, assuming the first /// token has already been consumed. -/// TypeRec +/// Type /// ::= '[' APSINTVAL 'x' Types ']' /// ::= '<' APSINTVAL 'x' Types '>' -bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) { +bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() || Lex.getAPSIntVal().getBitWidth() > 64) return TokError("expected number in address space"); @@ -1694,11 +1680,8 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) { return true; LocTy TypeLoc = Lex.getLoc(); - PATypeHolder EltTy(Type::getVoidTy(Context)); - if (ParseTypeRec(EltTy)) return true; - - if (EltTy->isVoidTy()) - return Error(TypeLoc, "array and vector element type cannot be void"); + Type *EltTy = 0; + if (ParseType(EltTy)) return true; if (ParseToken(isVector ? lltok::greater : lltok::rsquare, "expected end of sequential type")) @@ -1710,12 +1693,13 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &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 or integer"); + return Error(TypeLoc, + "vector element type must be fp, integer or a pointer to these types"); Result = VectorType::get(EltTy, unsigned(Size)); } else { if (!ArrayType::isValidElementType(EltTy)) return Error(TypeLoc, "invalid array element type"); - Result = HandleUpRefs(ArrayType::get(EltTy, Size)); + Result = ArrayType::get(EltTy, Size); } return false; } @@ -1795,7 +1779,7 @@ bool LLParser::PerFunctionState::FinishFunction() { /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. Value *LLParser::PerFunctionState::GetVal(const std::string &Name, - const Type *Ty, LocTy Loc) { + Type *Ty, LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = F.getValueSymbolTable().lookup(Name); @@ -1815,12 +1799,12 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, P.Error(Loc, "'%" + Name + "' is not a basic block"); else P.Error(Loc, "'%" + Name + "' defined with type '" + - Val->getType()->getDescription() + "'"); + getTypeString(Val->getType()) + "'"); return 0; } // Don't make placeholders with invalid type. - if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { P.Error(Loc, "invalid use of a non-first-class type"); return 0; } @@ -1836,7 +1820,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, return FwdVal; } -Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty, +Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0; @@ -1857,11 +1841,11 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty, P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block"); else P.Error(Loc, "'%" + Twine(ID) + "' defined with type '" + - Val->getType()->getDescription() + "'"); + getTypeString(Val->getType()) + "'"); return 0; } - if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { P.Error(Loc, "invalid use of a non-first-class type"); return 0; } @@ -1905,7 +1889,7 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, if (FI != ForwardRefValIDs.end()) { if (FI->second.first->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + - FI->second.first->getType()->getDescription() + "'"); + getTypeString(FI->second.first->getType()) + "'"); FI->second.first->replaceAllUsesWith(Inst); delete FI->second.first; ForwardRefValIDs.erase(FI); @@ -1921,7 +1905,7 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, if (FI != ForwardRefVals.end()) { if (FI->second.first->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + - FI->second.first->getType()->getDescription() + "'"); + getTypeString(FI->second.first->getType()) + "'"); FI->second.first->replaceAllUsesWith(Inst); delete FI->second.first; ForwardRefVals.erase(FI); @@ -2004,7 +1988,6 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ID.Kind = ValID::t_LocalID; break; case lltok::LocalVar: // %foo - case lltok::StringConstant: // "foo" - FIXME: REMOVE IN LLVM 3.0 ID.StrVal = Lex.getStrVal(); ID.Kind = ValID::t_LocalName; break; @@ -2038,9 +2021,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ParseToken(lltok::rbrace, "expected end of struct constant")) return true; - ID.ConstantVal = ConstantStruct::get(Context, Elts.data(), - Elts.size(), false); - ID.Kind = ValID::t_Constant; + ID.ConstantStructElts = new Constant*[Elts.size()]; + ID.UIntVal = Elts.size(); + memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0])); + ID.Kind = ValID::t_ConstantStruct; return false; } case lltok::less: { @@ -2058,9 +2042,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (isPackedStruct) { - ID.ConstantVal = - ConstantStruct::get(Context, Elts.data(), Elts.size(), true); - ID.Kind = ValID::t_Constant; + ID.ConstantStructElts = new Constant*[Elts.size()]; + memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0])); + ID.UIntVal = Elts.size(); + ID.Kind = ValID::t_PackedConstantStruct; return false; } @@ -2068,16 +2053,17 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return Error(ID.Loc, "constant vector must not be empty"); if (!Elts[0]->getType()->isIntegerTy() && - !Elts[0]->getType()->isFloatingPointTy()) + !Elts[0]->getType()->isFloatingPointTy() && + !Elts[0]->getType()->isPointerTy()) return Error(FirstEltLoc, - "vector elements must have integer or floating point type"); + "vector elements must have integer, pointer or floating point type"); // Verify that all the vector elements have the same type. for (unsigned i = 1, e = Elts.size(); i != e; ++i) if (Elts[i]->getType() != Elts[0]->getType()) return Error(FirstEltLoc, "vector element #" + Twine(i) + - " is not of type '" + Elts[0]->getType()->getDescription()); + " is not of type '" + getTypeString(Elts[0]->getType())); ID.ConstantVal = ConstantVector::get(Elts); ID.Kind = ValID::t_Constant; @@ -2101,7 +2087,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (!Elts[0]->getType()->isFirstClassType()) return Error(FirstEltLoc, "invalid array element type: " + - Elts[0]->getType()->getDescription()); + getTypeString(Elts[0]->getType())); ArrayType *ATy = ArrayType::get(Elts[0]->getType(), Elts.size()); @@ -2110,32 +2096,35 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (Elts[i]->getType() != Elts[0]->getType()) return Error(FirstEltLoc, "array element #" + Twine(i) + - " is not of type '" +Elts[0]->getType()->getDescription()); + " is not of type '" + getTypeString(Elts[0]->getType())); } - ID.ConstantVal = ConstantArray::get(ATy, Elts.data(), Elts.size()); + ID.ConstantVal = ConstantArray::get(ATy, Elts); ID.Kind = ValID::t_Constant; return false; } case lltok::kw_c: // c "foo" Lex.Lex(); - ID.ConstantVal = ConstantArray::get(Context, Lex.getStrVal(), false); + ID.ConstantVal = ConstantDataArray::getString(Context, Lex.getStrVal(), + false); if (ParseToken(lltok::StringConstant, "expected string")) return true; ID.Kind = ValID::t_Constant; return false; case lltok::kw_asm: { // ValID ::= 'asm' SideEffect? AlignStack? STRINGCONSTANT ',' STRINGCONSTANT - bool HasSideEffect, AlignStack; + bool HasSideEffect, AlignStack, AsmDialect; Lex.Lex(); if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) || ParseOptionalToken(lltok::kw_alignstack, AlignStack) || + ParseOptionalToken(lltok::kw_inteldialect, AsmDialect) || ParseStringConstant(ID.StrVal) || ParseToken(lltok::comma, "expected comma in inline asm expression") || ParseToken(lltok::StringConstant, "expected constraint string")) return true; ID.StrVal2 = Lex.getStrVal(); - ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1); + ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1) | + (unsigned(AsmDialect)<<2); ID.Kind = ValID::t_InlineAsm; return false; } @@ -2182,7 +2171,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { case lltok::kw_inttoptr: case lltok::kw_ptrtoint: { unsigned Opc = Lex.getUIntVal(); - PATypeHolder DestTy(Type::getVoidTy(Context)); + Type *DestTy = 0; Constant *SrcVal; Lex.Lex(); if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") || @@ -2193,8 +2182,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (!CastInst::castIsValid((Instruction::CastOps)Opc, SrcVal, DestTy)) return Error(ID.Loc, "invalid cast opcode for cast from '" + - SrcVal->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); + getTypeString(SrcVal->getType()) + "' to '" + + getTypeString(DestTy) + "'"); ID.ConstantVal = ConstantExpr::getCast((Instruction::CastOps)Opc, SrcVal, DestTy); ID.Kind = ValID::t_Constant; @@ -2212,11 +2201,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (!Val->getType()->isAggregateType()) return Error(ID.Loc, "extractvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(), - Indices.end())) + if (!ExtractValueInst::getIndexedType(Val->getType(), Indices)) return Error(ID.Loc, "invalid indices for extractvalue"); - ID.ConstantVal = - ConstantExpr::getExtractValue(Val, Indices.data(), Indices.size()); + ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices); ID.Kind = ValID::t_Constant; return false; } @@ -2233,11 +2220,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (!Val0->getType()->isAggregateType()) return Error(ID.Loc, "insertvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(), - Indices.end())) + if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices)) return Error(ID.Loc, "invalid indices for insertvalue"); - ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, - Indices.data(), Indices.size()); + ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, Indices); ID.Kind = ValID::t_Constant; return false; } @@ -2266,7 +2251,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { } else { assert(Opc == Instruction::ICmp && "Unexpected opcode for CmpInst!"); if (!Val0->getType()->isIntOrIntVectorTy() && - !Val0->getType()->isPointerTy()) + !Val0->getType()->getScalarType()->isPointerTy()) return Error(ID.Loc, "icmp requires pointer or integer operands"); ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1); } @@ -2400,19 +2385,15 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (Opc == Instruction::GetElementPtr) { - if (Elts.size() == 0 || !Elts[0]->getType()->isPointerTy()) + if (Elts.size() == 0 || + !Elts[0]->getType()->getScalarType()->isPointerTy()) return Error(ID.Loc, "getelementptr requires pointer operand"); - if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), - (Value**)(Elts.data() + 1), - Elts.size() - 1)) + ArrayRef Indices(Elts.begin() + 1, Elts.end()); + if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), Indices)) return Error(ID.Loc, "invalid indices for getelementptr"); - ID.ConstantVal = InBounds ? - ConstantExpr::getInBoundsGetElementPtr(Elts[0], - Elts.data() + 1, - Elts.size() - 1) : - ConstantExpr::getGetElementPtr(Elts[0], - Elts.data() + 1, Elts.size() - 1); + ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices, + InBounds); } else if (Opc == Instruction::Select) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to select"); @@ -2453,7 +2434,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { } /// ParseGlobalValue - Parse a global value with the specified type. -bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&C) { +bool LLParser::ParseGlobalValue(Type *Ty, Constant *&C) { C = 0; ValID ID; Value *V = NULL; @@ -2465,9 +2446,9 @@ bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&C) { } bool LLParser::ParseGlobalTypeAndValue(Constant *&V) { - PATypeHolder Type(Type::getVoidTy(Context)); - return ParseType(Type) || - ParseGlobalValue(Type, V); + Type *Ty = 0; + return ParseType(Ty) || + ParseGlobalValue(Ty, V); } /// ParseGlobalValueVector @@ -2502,7 +2483,7 @@ bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) { ParseToken(lltok::rbrace, "expected end of metadata node")) return true; - ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size()); + ID.MDNodeVal = MDNode::get(Context, Elts); ID.Kind = ValID::t_MDNode; return false; } @@ -2540,13 +2521,12 @@ bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) { // Function Parsing. //===----------------------------------------------------------------------===// -bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, +bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, PerFunctionState *PFS) { if (Ty->isFunctionTy()) return Error(ID.Loc, "functions are not values, refer to them as pointers"); switch (ID.Kind) { - default: llvm_unreachable("Unknown ValID!"); case ValID::t_LocalID: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc); @@ -2556,12 +2536,13 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); return (V == 0); case ValID::t_InlineAsm: { - const PointerType *PTy = dyn_cast(Ty); - const FunctionType *FTy = + PointerType *PTy = dyn_cast(Ty); + FunctionType *FTy = PTy ? dyn_cast(PTy->getElementType()) : 0; if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2)) return Error(ID.Loc, "invalid type for inline asm constraint string"); - V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, ID.UIntVal>>1); + V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, + (ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2))); return false; } case ValID::t_MDNode: @@ -2591,19 +2572,22 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, !ConstantFP::isValueValidForType(Ty, ID.APFloatVal)) return Error(ID.Loc, "floating point constant invalid for type"); - // The 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 (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble && - Ty->isFloatTy()) { + // The lexer has no type info, so builds all half, float, and double FP + // constants as double. Fix this here. Long double does not need this. + if (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble) { bool Ignored; - ID.APFloatVal.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, - &Ignored); + if (Ty->isHalfTy()) + ID.APFloatVal.convert(APFloat::IEEEhalf, APFloat::rmNearestTiesToEven, + &Ignored); + else if (Ty->isFloatTy()) + ID.APFloatVal.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, + &Ignored); } V = ConstantFP::get(Context, ID.APFloatVal); if (V->getType() != Ty) return Error(ID.Loc, "floating point constant does not have type '" + - Ty->getDescription() + "'"); + getTypeString(Ty) + "'"); return false; case ValID::t_Null: @@ -2613,8 +2597,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, return false; case ValID::t_Undef: // FIXME: LabelTy should not be a first-class type. - if ((!Ty->isFirstClassType() || Ty->isLabelTy()) && - !Ty->isOpaqueTy()) + if (!Ty->isFirstClassType() || Ty->isLabelTy()) return Error(ID.Loc, "invalid type for undef constant"); V = UndefValue::get(Ty); return false; @@ -2635,20 +2618,41 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, V = ID.ConstantVal; return false; + case ValID::t_ConstantStruct: + case ValID::t_PackedConstantStruct: + if (StructType *ST = dyn_cast(Ty)) { + if (ST->getNumElements() != ID.UIntVal) + return Error(ID.Loc, + "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 + return Error(ID.Loc, "constant expression type mismatch"); + return false; } + llvm_unreachable("Invalid ValID"); } -bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) { +bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { V = 0; ValID ID; - return ParseValID(ID, &PFS) || - ConvertValIDToValue(Ty, ID, V, &PFS); + return ParseValID(ID, PFS) || + ConvertValIDToValue(Ty, ID, V, PFS); } -bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) { - PATypeHolder T(Type::getVoidTy(Context)); - return ParseType(T) || - ParseValue(T, V, PFS); +bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) { + Type *Ty = 0; + return ParseType(Ty) || + ParseValue(Ty, V, PFS); } bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, @@ -2672,9 +2676,10 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { LocTy LinkageLoc = Lex.getLoc(); unsigned Linkage; - unsigned Visibility, RetAttrs; + unsigned Visibility; + Attributes::Builder RetAttrs; CallingConv::ID CC; - PATypeHolder RetType(Type::getVoidTy(Context)); + Type *RetType = 0; LocTy RetTypeLoc = Lex.getLoc(); if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || @@ -2695,11 +2700,11 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { case GlobalValue::PrivateLinkage: case GlobalValue::LinkerPrivateLinkage: case GlobalValue::LinkerPrivateWeakLinkage: - case GlobalValue::LinkerPrivateWeakDefAutoLinkage: case GlobalValue::InternalLinkage: case GlobalValue::AvailableExternallyLinkage: case GlobalValue::LinkOnceAnyLinkage: case GlobalValue::LinkOnceODRLinkage: + case GlobalValue::LinkOnceODRAutoHideLinkage: case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: case GlobalValue::DLLExportLinkage: @@ -2711,8 +2716,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { return Error(LinkageLoc, "invalid function linkage type"); } - if (!FunctionType::isValidReturnType(RetType) || - RetType->isOpaqueTy()) + if (!FunctionType::isValidReturnType(RetType)) return Error(RetTypeLoc, "invalid function return type"); LocTy NameLoc = Lex.getLoc(); @@ -2735,16 +2739,16 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (Lex.getKind() != lltok::lparen) return TokError("expected '(' in function argument list"); - std::vector ArgList; + SmallVector ArgList; bool isVarArg; - unsigned FuncAttrs; + Attributes::Builder FuncAttrs; std::string Section; unsigned Alignment; std::string GC; bool UnnamedAddr; LocTy UnnamedAddrLoc; - if (ParseArgumentList(ArgList, isVarArg, false) || + if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || ParseOptionalAttrs(FuncAttrs, 2) || @@ -2756,43 +2760,43 @@ 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(Attributes::Alignment); } // Okay, if we got here, the function is syntactically valid. Convert types // and do semantic checks. - std::vector ParamTypeList; + std::vector ParamTypeList; SmallVector Attrs; - // FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - // attributes. - unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg; - if (FuncAttrs & ObsoleteFuncAttrs) { - RetAttrs |= FuncAttrs & ObsoleteFuncAttrs; - FuncAttrs &= ~ObsoleteFuncAttrs; - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + if (RetAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttrListPtr::ReturnIndex, + Attributes::get(RetType->getContext(), + RetAttrs))); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { - ParamTypeList.push_back(ArgList[i].Type); - if (ArgList[i].Attrs != Attribute::None) + ParamTypeList.push_back(ArgList[i].Ty); + 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(AttrListPtr::FunctionIndex, + Attributes::get(RetType->getContext(), + FuncAttrs))); - AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + AttrListPtr PAL = AttrListPtr::get(Attrs); - if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy()) + if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) && + !RetType->isVoidTy()) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); - const FunctionType *FT = + FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg); - const PointerType *PFT = PointerType::getUnqual(FT); + PointerType *PFT = PointerType::getUnqual(FT); Fn = 0; if (!FunctionName.empty()) { @@ -2802,27 +2806,18 @@ 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))) { - // If this function already exists in the symbol table, then it is - // multiply defined. We accept a few cases for old backwards compat. - // FIXME: Remove this stuff for LLVM 3.0. - if (Fn->getType() != PFT || Fn->getAttributes() != PAL || - (!Fn->isDeclaration() && isDefine)) { - // If the redefinition has different type or different attributes, - // reject it. If both have bodies, reject it. - return Error(NameLoc, "invalid redefinition of function '" + - FunctionName + "'"); - } 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(""); - } + // Reject redefinitions. + return Error(NameLoc, "invalid redefinition of function '" + + FunctionName + "'"); } else if (M->getNamedValue(FunctionName)) { return Error(NameLoc, "redefinition of function '@" + FunctionName + "'"); } @@ -2861,10 +2856,6 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Add all of the arguments we parsed to the function. Function::arg_iterator ArgIt = Fn->arg_begin(); for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) { - // If we run out of arguments in the Function prototype, exit early. - // FIXME: REMOVE THIS IN LLVM 3.0, this is just for the mismatch case above. - if (ArgIt == Fn->arg_end()) break; - // If the argument has a name, insert it into the argument symbol table. if (ArgList[i].Name.empty()) continue; @@ -2882,10 +2873,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { /// ParseFunctionBody /// ::= '{' BasicBlock+ '}' -/// ::= 'begin' BasicBlock+ 'end' // FIXME: remove in LLVM 3.0 /// bool LLParser::ParseFunctionBody(Function &Fn) { - if (Lex.getKind() != lltok::lbrace && Lex.getKind() != lltok::kw_begin) + if (Lex.getKind() != lltok::lbrace) return TokError("expected '{' in function body"); Lex.Lex(); // eat the {. @@ -2895,10 +2885,10 @@ bool LLParser::ParseFunctionBody(Function &Fn) { PerFunctionState PFS(*this, Fn, FunctionNumber); // We need at least one basic block. - if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_end) + if (Lex.getKind() == lltok::rbrace) return TokError("function body requires at least one basic block"); - while (Lex.getKind() != lltok::rbrace && Lex.getKind() != lltok::kw_end) + while (Lex.getKind() != lltok::rbrace) if (ParseBasicBlock(PFS)) return true; // Eat the }. @@ -2939,9 +2929,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { Lex.Lex(); if (ParseToken(lltok::equal, "expected '=' after instruction id")) return true; - } else if (Lex.getKind() == lltok::LocalVar || - // FIXME: REMOVE IN LLVM 3.0 - Lex.getKind() == lltok::StringConstant) { + } else if (Lex.getKind() == lltok::LocalVar) { NameStr = Lex.getStrVal(); Lex.Lex(); if (ParseToken(lltok::equal, "expected '=' after instruction name")) @@ -2949,7 +2937,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { } switch (ParseInstruction(Inst, BB, PFS)) { - default: assert(0 && "Unknown ParseInstruction result!"); + default: llvm_unreachable("Unknown ParseInstruction result!"); case InstError: return true; case InstNormal: BB->getInstList().push_back(Inst); @@ -2995,19 +2983,18 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, switch (Token) { default: return Error(Loc, "expected instruction opcode"); // Terminator Instructions. - case lltok::kw_unwind: Inst = new UnwindInst(Context); return false; case lltok::kw_unreachable: Inst = new UnreachableInst(Context); return false; case lltok::kw_ret: return ParseRet(Inst, BB, PFS); case lltok::kw_br: return ParseBr(Inst, PFS); case lltok::kw_switch: return ParseSwitch(Inst, PFS); case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); + case lltok::kw_resume: return ParseResume(Inst, PFS); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: case lltok::kw_mul: case lltok::kw_shl: { - LocTy ModifierLoc = Lex.getLoc(); bool NUW = EatIfPresent(lltok::kw_nuw); bool NSW = EatIfPresent(lltok::kw_nsw); if (!NUW) NUW = EatIfPresent(lltok::kw_nuw); @@ -3062,22 +3049,16 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_insertelement: return ParseInsertElement(Inst, PFS); case lltok::kw_shufflevector: return ParseShuffleVector(Inst, PFS); case lltok::kw_phi: return ParsePHI(Inst, PFS); + case lltok::kw_landingpad: return ParseLandingPad(Inst, PFS); case lltok::kw_call: return ParseCall(Inst, PFS, false); case lltok::kw_tail: return ParseCall(Inst, PFS, true); // Memory. case lltok::kw_alloca: return ParseAlloc(Inst, PFS); - case lltok::kw_malloc: return ParseAlloc(Inst, PFS, BB, false); - case lltok::kw_free: return ParseFree(Inst, PFS, BB); - case lltok::kw_load: return ParseLoad(Inst, PFS, false); - case lltok::kw_store: return ParseStore(Inst, PFS, false); - case lltok::kw_volatile: - if (EatIfPresent(lltok::kw_load)) - return ParseLoad(Inst, PFS, true); - else if (EatIfPresent(lltok::kw_store)) - return ParseStore(Inst, PFS, true); - else - return TokError("expected 'load' or 'store'"); - case lltok::kw_getresult: return ParseGetResult(Inst, PFS); + case lltok::kw_load: return ParseLoad(Inst, PFS); + case lltok::kw_store: return ParseStore(Inst, PFS); + case lltok::kw_cmpxchg: return ParseCmpXchg(Inst, PFS); + case lltok::kw_atomicrmw: return ParseAtomicRMW(Inst, PFS); + case lltok::kw_fence: return ParseFence(Inst, PFS); case lltok::kw_getelementptr: return ParseGetElementPtr(Inst, PFS); case lltok::kw_extractvalue: return ParseExtractValue(Inst, PFS); case lltok::kw_insertvalue: return ParseInsertValue(Inst, PFS); @@ -3132,14 +3113,19 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { /// ParseRet - Parse a return instruction. /// ::= 'ret' void (',' !dbg, !1)* /// ::= 'ret' TypeAndValue (',' !dbg, !1)* -/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ (',' !dbg, !1)* -/// [[obsolete: LLVM 3.0]] -int LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, - PerFunctionState &PFS) { - PATypeHolder Ty(Type::getVoidTy(Context)); +bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, + PerFunctionState &PFS) { + SMLoc TypeLoc = Lex.getLoc(); + Type *Ty = 0; 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; } @@ -3147,38 +3133,12 @@ int LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, Value *RV; if (ParseValue(Ty, RV, PFS)) return true; - bool ExtraComma = false; - if (EatIfPresent(lltok::comma)) { - // Parse optional custom metadata, e.g. !dbg - if (Lex.getKind() == lltok::MetadataVar) { - ExtraComma = true; - } else { - // The normal case is one return value. - // FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring - // use of 'ret {i32,i32} {i32 1, i32 2}' - SmallVector RVs; - RVs.push_back(RV); - - do { - // If optional custom metadata, e.g. !dbg is seen then this is the - // end of MRV. - if (Lex.getKind() == lltok::MetadataVar) - break; - if (ParseTypeAndValue(RV, PFS)) return true; - RVs.push_back(RV); - } while (EatIfPresent(lltok::comma)); - - RV = UndefValue::get(PFS.getFunction().getReturnType()); - for (unsigned i = 0, e = RVs.size(); i != e; ++i) { - Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv"); - BB->getInstList().push_back(I); - RV = I; - } - } - } - + if (ResType != RV->getType()) + return Error(TypeLoc, "value doesn't match function result type '" + + getTypeString(ResType) + "'"); + Inst = ReturnInst::Create(Context, RV); - return ExtraComma ? InstExtraComma : InstNormal; + return false; } @@ -3302,9 +3262,9 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { /// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy CallLoc = Lex.getLoc(); - unsigned RetAttrs, FnAttrs; + Attributes::Builder RetAttrs, FnAttrs; CallingConv::ID CC; - PATypeHolder RetType(Type::getVoidTy(Context)); + Type *RetType = 0; LocTy RetTypeLoc; ValID CalleeID; SmallVector ArgList; @@ -3325,12 +3285,12 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; + PointerType *PFTy = 0; + FunctionType *Ty = 0; if (!(PFTy = dyn_cast(RetType)) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... - std::vector ParamTypes; + std::vector ParamTypes; for (unsigned i = 0, e = ArgList.size(); i != e; ++i) ParamTypes.push_back(ArgList[i].V->getType()); @@ -3345,18 +3305,13 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional - // function attributes. - unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg; - if (FnAttrs & ObsoleteFuncAttrs) { - RetAttrs |= FnAttrs & ObsoleteFuncAttrs; - FnAttrs &= ~ObsoleteFuncAttrs; - } - // Set up the Attributes for the function. SmallVector Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + if (RetAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttrListPtr::ReturnIndex, + Attributes::get(Callee->getContext(), + RetAttrs))); SmallVector Args; @@ -3365,7 +3320,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator E = Ty->param_end(); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { - const Type *ExpectedTy = 0; + Type *ExpectedTy = 0; if (I != E) { ExpectedTy = *I++; } else if (!Ty->isVarArg()) { @@ -3374,30 +3329,42 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { if (ExpectedTy && ExpectedTy != ArgList[i].V->getType()) return Error(ArgList[i].Loc, "argument is not of expected type '" + - ExpectedTy->getDescription() + "'"); + 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(AttrListPtr::FunctionIndex, + Attributes::get(Callee->getContext(), + FnAttrs))); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + AttrListPtr PAL = AttrListPtr::get(Attrs); - InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, - Args.begin(), Args.end()); + InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); II->setCallingConv(CC); II->setAttributes(PAL); Inst = II; return false; } +/// ParseResume +/// ::= 'resume' TypeAndValue +bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { + Value *Exn; LocTy ExnLoc; + if (ParseTypeAndValue(Exn, ExnLoc, PFS)) + return true; + ResumeInst *RI = ResumeInst::Create(Exn); + Inst = RI; + return false; +} //===----------------------------------------------------------------------===// // Binary Operators. @@ -3474,7 +3441,7 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS, } else { assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!"); if (!LHS->getType()->isIntOrIntVectorTy() && - !LHS->getType()->isPointerTy()) + !LHS->getType()->getScalarType()->isPointerTy()) return Error(Loc, "icmp requires integer operands"); Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS); } @@ -3490,8 +3457,9 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS, /// ::= CastOpc TypeAndValue 'to' Type bool LLParser::ParseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { - LocTy Loc; Value *Op; - PATypeHolder DestTy(Type::getVoidTy(Context)); + LocTy Loc; + Value *Op; + Type *DestTy = 0; if (ParseTypeAndValue(Op, Loc, PFS) || ParseToken(lltok::kw_to, "expected 'to' after cast value") || ParseType(DestTy)) @@ -3500,8 +3468,8 @@ bool LLParser::ParseCast(Instruction *&Inst, PerFunctionState &PFS, if (!CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy)) { CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy); return Error(Loc, "invalid cast opcode for cast from '" + - Op->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); + getTypeString(Op->getType()) + "' to '" + + getTypeString(DestTy) + "'"); } Inst = CastInst::Create((Instruction::CastOps)Opc, Op, DestTy); return false; @@ -3530,7 +3498,7 @@ bool LLParser::ParseSelect(Instruction *&Inst, PerFunctionState &PFS) { /// ::= 'va_arg' TypeAndValue ',' Type bool LLParser::ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS) { Value *Op; - PATypeHolder EltTy(Type::getVoidTy(Context)); + Type *EltTy = 0; LocTy TypeLoc; if (ParseTypeAndValue(Op, PFS) || ParseToken(lltok::comma, "expected ',' after vaarg operand") || @@ -3593,7 +3561,7 @@ bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { return true; if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2)) - return Error(Loc, "invalid extractelement operands"); + return Error(Loc, "invalid shufflevector operands"); Inst = new ShuffleVectorInst(Op0, Op1, Op2); return false; @@ -3602,11 +3570,10 @@ bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { /// ParsePHI /// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')* int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { - PATypeHolder Ty(Type::getVoidTy(Context)); + Type *Ty = 0; LocTy TypeLoc; Value *Op0, *Op1; - LocTy TypeLoc = Lex.getLoc(); - if (ParseType(Ty) || + if (ParseType(Ty, TypeLoc) || ParseToken(lltok::lsquare, "expected '[' in phi value list") || ParseValue(Ty, Op0, PFS) || ParseToken(lltok::comma, "expected ',' after insertelement value") || @@ -3638,22 +3605,71 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { if (!Ty->isFirstClassType()) return Error(TypeLoc, "phi node must have first class type"); - PHINode *PN = PHINode::Create(Ty); - PN->reserveOperandSpace(PHIVals.size()); + PHINode *PN = PHINode::Create(Ty, PHIVals.size()); for (unsigned i = 0, e = PHIVals.size(); i != e; ++i) PN->addIncoming(PHIVals[i].first, PHIVals[i].second); Inst = PN; return AteExtraComma ? InstExtraComma : InstNormal; } +/// ParseLandingPad +/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+ +/// Clause +/// ::= 'catch' TypeAndValue +/// ::= 'filter' +/// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* +bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { + Type *Ty = 0; LocTy TyLoc; + Value *PersFn; LocTy PersFnLoc; + + if (ParseType(Ty, TyLoc) || + ParseToken(lltok::kw_personality, "expected 'personality'") || + ParseTypeAndValue(PersFn, PersFnLoc, PFS)) + return true; + + LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0); + LP->setCleanup(EatIfPresent(lltok::kw_cleanup)); + + while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){ + LandingPadInst::ClauseType CT; + if (EatIfPresent(lltok::kw_catch)) + CT = LandingPadInst::Catch; + else if (EatIfPresent(lltok::kw_filter)) + CT = LandingPadInst::Filter; + else + return TokError("expected 'catch' or 'filter' clause type"); + + Value *V; LocTy VLoc; + if (ParseTypeAndValue(V, VLoc, PFS)) { + delete LP; + return true; + } + + // A 'catch' type expects a non-array constant. A filter clause expects an + // array constant. + if (CT == LandingPadInst::Catch) { + if (isa(V->getType())) + Error(VLoc, "'catch' clause has an invalid type"); + } else { + if (!isa(V->getType())) + Error(VLoc, "'filter' clause has an invalid type"); + } + + LP->addClause(V); + } + + Inst = LP; + return false; +} + /// ParseCall /// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value /// ParameterList OptionalAttrs bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, bool isTail) { - unsigned RetAttrs, FnAttrs; + Attributes::Builder RetAttrs, FnAttrs; CallingConv::ID CC; - PATypeHolder RetType(Type::getVoidTy(Context)); + Type *RetType = 0; LocTy RetTypeLoc; ValID CalleeID; SmallVector ArgList; @@ -3671,12 +3687,12 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; + PointerType *PFTy = 0; + FunctionType *Ty = 0; if (!(PFTy = dyn_cast(RetType)) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... - std::vector ParamTypes; + std::vector ParamTypes; for (unsigned i = 0, e = ArgList.size(); i != e; ++i) ParamTypes.push_back(ArgList[i].V->getType()); @@ -3691,18 +3707,13 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional - // function attributes. - unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg; - if (FnAttrs & ObsoleteFuncAttrs) { - RetAttrs |= FnAttrs & ObsoleteFuncAttrs; - FnAttrs &= ~ObsoleteFuncAttrs; - } - // Set up the Attributes for the function. SmallVector Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + if (RetAttrs.hasAttributes()) + Attrs.push_back( + AttributeWithIndex::get(AttrListPtr::ReturnIndex, + Attributes::get(Callee->getContext(), + RetAttrs))); SmallVector Args; @@ -3711,7 +3722,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator E = Ty->param_end(); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { - const Type *ExpectedTy = 0; + Type *ExpectedTy = 0; if (I != E) { ExpectedTy = *I++; } else if (!Ty->isVarArg()) { @@ -3720,22 +3731,25 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, if (ExpectedTy && ExpectedTy != ArgList[i].V->getType()) return Error(ArgList[i].Loc, "argument is not of expected type '" + - ExpectedTy->getDescription() + "'"); + 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(AttrListPtr::FunctionIndex, + Attributes::get(Callee->getContext(), + FnAttrs))); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + AttrListPtr PAL = AttrListPtr::get(Attrs); - CallInst *CI = CallInst::Create(Callee, Args.begin(), Args.end()); + CallInst *CI = CallInst::Create(Callee, Args); CI->setTailCall(isTail); CI->setCallingConv(CC); CI->setAttributes(PAL); @@ -3748,14 +3762,12 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, //===----------------------------------------------------------------------===// /// ParseAlloc -/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)? /// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)? -int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS, - BasicBlock* BB, bool isAlloca) { - PATypeHolder Ty(Type::getVoidTy(Context)); +int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { Value *Size = 0; LocTy SizeLoc; unsigned Alignment = 0; + Type *Ty = 0; if (ParseType(Ty)) return true; bool AteExtraComma = false; @@ -3774,68 +3786,78 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS, if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - if (isAlloca) { - Inst = new AllocaInst(Ty, Size, Alignment); - return AteExtraComma ? InstExtraComma : InstNormal; - } - - // Autoupgrade old malloc instruction to malloc call. - // FIXME: Remove in LLVM 3.0. - if (Size && !Size->getType()->isIntegerTy(32)) - return Error(SizeLoc, "element count must be i32"); - const Type *IntPtrTy = Type::getInt32Ty(Context); - Constant *AllocSize = ConstantExpr::getSizeOf(Ty); - AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, IntPtrTy); - if (!MallocF) - // Prototype malloc as "void *(int32)". - // This function is renamed as "malloc" in ValidateEndOfModule(). - MallocF = cast( - M->getOrInsertFunction("", Type::getInt8PtrTy(Context), IntPtrTy, NULL)); - Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, AllocSize, Size, MallocF); -return AteExtraComma ? InstExtraComma : InstNormal; -} - -/// ParseFree -/// ::= 'free' TypeAndValue -bool LLParser::ParseFree(Instruction *&Inst, PerFunctionState &PFS, - BasicBlock* BB) { - Value *Val; LocTy Loc; - if (ParseTypeAndValue(Val, Loc, PFS)) return true; - if (!Val->getType()->isPointerTy()) - return Error(Loc, "operand to free must be a pointer"); - Inst = CallInst::CreateFree(Val, BB); - return false; + Inst = new AllocaInst(Ty, Size, Alignment); + return AteExtraComma ? InstExtraComma : InstNormal; } /// ParseLoad -/// ::= 'volatile'? 'load' TypeAndValue (',' OptionalInfo)? -int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS, - bool isVolatile) { +/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)? +/// ::= 'load' 'atomic' 'volatile'? TypeAndValue +/// 'singlethread'? AtomicOrdering (',' 'align' i32)? +int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { Value *Val; LocTy Loc; unsigned Alignment = 0; bool AteExtraComma = false; + bool isAtomic = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + + if (Lex.getKind() == lltok::kw_atomic) { + isAtomic = true; + Lex.Lex(); + } + + bool isVolatile = false; + if (Lex.getKind() == lltok::kw_volatile) { + isVolatile = true; + Lex.Lex(); + } + if (ParseTypeAndValue(Val, Loc, PFS) || + ParseScopeAndOrdering(isAtomic, Scope, Ordering) || ParseOptionalCommaAlign(Alignment, AteExtraComma)) return true; if (!Val->getType()->isPointerTy() || !cast(Val->getType())->getElementType()->isFirstClassType()) return Error(Loc, "load operand must be a pointer to a first class type"); + if (isAtomic && !Alignment) + return Error(Loc, "atomic load must have explicit non-zero alignment"); + if (Ordering == Release || Ordering == AcquireRelease) + return Error(Loc, "atomic load cannot use Release ordering"); - Inst = new LoadInst(Val, "", isVolatile, Alignment); + Inst = new LoadInst(Val, "", isVolatile, Alignment, Ordering, Scope); return AteExtraComma ? InstExtraComma : InstNormal; } /// ParseStore -/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)? -int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS, - bool isVolatile) { + +/// ::= 'store' 'volatile'? TypeAndValue ',' TypeAndValue (',' 'align' i32)? +/// ::= 'store' 'atomic' 'volatile'? TypeAndValue ',' TypeAndValue +/// 'singlethread'? AtomicOrdering (',' 'align' i32)? +int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) { Value *Val, *Ptr; LocTy Loc, PtrLoc; unsigned Alignment = 0; bool AteExtraComma = false; + bool isAtomic = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + + if (Lex.getKind() == lltok::kw_atomic) { + isAtomic = true; + Lex.Lex(); + } + + bool isVolatile = false; + if (Lex.getKind() == lltok::kw_volatile) { + isVolatile = true; + Lex.Lex(); + } + if (ParseTypeAndValue(Val, Loc, PFS) || ParseToken(lltok::comma, "expected ',' after store operand") || ParseTypeAndValue(Ptr, PtrLoc, PFS) || + ParseScopeAndOrdering(isAtomic, Scope, Ordering) || ParseOptionalCommaAlign(Alignment, AteExtraComma)) return true; @@ -3845,40 +3867,143 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS, return Error(Loc, "store operand must be a first class value"); if (cast(Ptr->getType())->getElementType() != Val->getType()) return Error(Loc, "stored value and pointer type do not match"); + if (isAtomic && !Alignment) + return Error(Loc, "atomic store must have explicit non-zero alignment"); + if (Ordering == Acquire || Ordering == AcquireRelease) + return Error(Loc, "atomic store cannot use Acquire ordering"); - Inst = new StoreInst(Val, Ptr, isVolatile, Alignment); + Inst = new StoreInst(Val, Ptr, isVolatile, Alignment, Ordering, Scope); return AteExtraComma ? InstExtraComma : InstNormal; } -/// ParseGetResult -/// ::= 'getresult' TypeAndValue ',' i32 -/// FIXME: Remove support for getresult in LLVM 3.0 -bool LLParser::ParseGetResult(Instruction *&Inst, PerFunctionState &PFS) { - Value *Val; LocTy ValLoc, EltLoc; - unsigned Element; - if (ParseTypeAndValue(Val, ValLoc, PFS) || - ParseToken(lltok::comma, "expected ',' after getresult operand") || - ParseUInt32(Element, EltLoc)) +/// ParseCmpXchg +/// ::= 'cmpxchg' 'volatile'? TypeAndValue ',' TypeAndValue ',' TypeAndValue +/// 'singlethread'? AtomicOrdering +int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { + Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc; + bool AteExtraComma = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + bool isVolatile = false; + + if (EatIfPresent(lltok::kw_volatile)) + isVolatile = true; + + if (ParseTypeAndValue(Ptr, PtrLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after cmpxchg address") || + ParseTypeAndValue(Cmp, CmpLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") || + ParseTypeAndValue(New, NewLoc, PFS) || + ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering)) return true; - if (!Val->getType()->isStructTy() && !Val->getType()->isArrayTy()) - return Error(ValLoc, "getresult inst requires an aggregate operand"); - if (!ExtractValueInst::getIndexedType(Val->getType(), Element)) - return Error(EltLoc, "invalid getresult index for value"); - Inst = ExtractValueInst::Create(Val, Element); - return false; + if (Ordering == Unordered) + return TokError("cmpxchg cannot be unordered"); + if (!Ptr->getType()->isPointerTy()) + return Error(PtrLoc, "cmpxchg operand must be a pointer"); + if (cast(Ptr->getType())->getElementType() != Cmp->getType()) + return Error(CmpLoc, "compare value and pointer type do not match"); + if (cast(Ptr->getType())->getElementType() != New->getType()) + return Error(NewLoc, "new value and pointer type do not match"); + if (!New->getType()->isIntegerTy()) + return Error(NewLoc, "cmpxchg operand must be an integer"); + unsigned Size = New->getType()->getPrimitiveSizeInBits(); + if (Size < 8 || (Size & (Size - 1))) + return Error(NewLoc, "cmpxchg operand must be power-of-two byte-sized" + " integer"); + + AtomicCmpXchgInst *CXI = + new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, Scope); + CXI->setVolatile(isVolatile); + Inst = CXI; + return AteExtraComma ? InstExtraComma : InstNormal; +} + +/// ParseAtomicRMW +/// ::= 'atomicrmw' 'volatile'? BinOp TypeAndValue ',' TypeAndValue +/// 'singlethread'? AtomicOrdering +int LLParser::ParseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { + Value *Ptr, *Val; LocTy PtrLoc, ValLoc; + bool AteExtraComma = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + bool isVolatile = false; + AtomicRMWInst::BinOp Operation; + + if (EatIfPresent(lltok::kw_volatile)) + isVolatile = true; + + switch (Lex.getKind()) { + default: return TokError("expected binary operation in atomicrmw"); + case lltok::kw_xchg: Operation = AtomicRMWInst::Xchg; break; + case lltok::kw_add: Operation = AtomicRMWInst::Add; break; + case lltok::kw_sub: Operation = AtomicRMWInst::Sub; break; + case lltok::kw_and: Operation = AtomicRMWInst::And; break; + case lltok::kw_nand: Operation = AtomicRMWInst::Nand; break; + case lltok::kw_or: Operation = AtomicRMWInst::Or; break; + case lltok::kw_xor: Operation = AtomicRMWInst::Xor; break; + case lltok::kw_max: Operation = AtomicRMWInst::Max; break; + case lltok::kw_min: Operation = AtomicRMWInst::Min; break; + case lltok::kw_umax: Operation = AtomicRMWInst::UMax; break; + case lltok::kw_umin: Operation = AtomicRMWInst::UMin; break; + } + Lex.Lex(); // Eat the operation. + + if (ParseTypeAndValue(Ptr, PtrLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after atomicrmw address") || + ParseTypeAndValue(Val, ValLoc, PFS) || + ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering)) + return true; + + if (Ordering == Unordered) + return TokError("atomicrmw cannot be unordered"); + if (!Ptr->getType()->isPointerTy()) + return Error(PtrLoc, "atomicrmw operand must be a pointer"); + if (cast(Ptr->getType())->getElementType() != Val->getType()) + return Error(ValLoc, "atomicrmw value and pointer type do not match"); + if (!Val->getType()->isIntegerTy()) + return Error(ValLoc, "atomicrmw operand must be an integer"); + unsigned Size = Val->getType()->getPrimitiveSizeInBits(); + if (Size < 8 || (Size & (Size - 1))) + return Error(ValLoc, "atomicrmw operand must be power-of-two byte-sized" + " integer"); + + AtomicRMWInst *RMWI = + new AtomicRMWInst(Operation, Ptr, Val, Ordering, Scope); + RMWI->setVolatile(isVolatile); + Inst = RMWI; + return AteExtraComma ? InstExtraComma : InstNormal; +} + +/// ParseFence +/// ::= 'fence' 'singlethread'? AtomicOrdering +int LLParser::ParseFence(Instruction *&Inst, PerFunctionState &PFS) { + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + if (ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering)) + return true; + + if (Ordering == Unordered) + return TokError("fence cannot be unordered"); + if (Ordering == Monotonic) + return TokError("fence cannot be monotonic"); + + Inst = new FenceInst(Context, Ordering, Scope); + return InstNormal; } /// ParseGetElementPtr /// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)* int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { - Value *Ptr, *Val; LocTy Loc, EltLoc; + Value *Ptr = 0; + Value *Val = 0; + LocTy Loc, EltLoc; bool InBounds = EatIfPresent(lltok::kw_inbounds); if (ParseTypeAndValue(Ptr, Loc, PFS)) return true; - if (!Ptr->getType()->isPointerTy()) + if (!Ptr->getType()->getScalarType()->isPointerTy()) return Error(Loc, "base of getelementptr must be a pointer"); SmallVector Indices; @@ -3889,15 +4014,26 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { break; } if (ParseTypeAndValue(Val, EltLoc, PFS)) return true; - if (!Val->getType()->isIntegerTy()) + if (!Val->getType()->getScalarType()->isIntegerTy()) return Error(EltLoc, "getelementptr index must be an integer"); + if (Val->getType()->isVectorTy() != Ptr->getType()->isVectorTy()) + return Error(EltLoc, "getelementptr index type missmatch"); + if (Val->getType()->isVectorTy()) { + unsigned ValNumEl = cast(Val->getType())->getNumElements(); + unsigned PtrNumEl = cast(Ptr->getType())->getNumElements(); + if (ValNumEl != PtrNumEl) + return Error(EltLoc, + "getelementptr vector index has a wrong number of elements"); + } Indices.push_back(Val); } - if (!GetElementPtrInst::getIndexedType(Ptr->getType(), - Indices.begin(), Indices.end())) + 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.begin(), Indices.end()); + Inst = GetElementPtrInst::Create(Ptr, Indices); if (InBounds) cast(Inst)->setIsInBounds(true); return AteExtraComma ? InstExtraComma : InstNormal; @@ -3916,10 +4052,9 @@ int LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) { if (!Val->getType()->isAggregateType()) return Error(Loc, "extractvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(), - Indices.end())) + if (!ExtractValueInst::getIndexedType(Val->getType(), Indices)) return Error(Loc, "invalid indices for extractvalue"); - Inst = ExtractValueInst::Create(Val, Indices.begin(), Indices.end()); + Inst = ExtractValueInst::Create(Val, Indices); return AteExtraComma ? InstExtraComma : InstNormal; } @@ -3938,10 +4073,9 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { if (!Val0->getType()->isAggregateType()) return Error(Loc0, "insertvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(), - Indices.end())) + if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices)) return Error(Loc0, "invalid indices for insertvalue"); - Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end()); + Inst = InsertValueInst::Create(Val0, Val1, Indices); return AteExtraComma ? InstExtraComma : InstNormal; } @@ -3967,12 +4101,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, } Value *V = 0; - PATypeHolder Ty(Type::getVoidTy(Context)); - ValID ID; - if (ParseType(Ty) || ParseValID(ID, PFS) || - ConvertValIDToValue(Ty, ID, V, PFS)) - return true; - + if (ParseTypeAndValue(V, PFS)) return true; Elts.push_back(V); } while (EatIfPresent(lltok::comma));