X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=b463d49af52b6c285748dbf1a49ecef4188b787c;hb=fbd8cc09269d6c7c5ca615a4757e41899a18283f;hp=271691b85cb3b88c563b08097bb2034b27179f01;hpb=4e2132e7ae4b41ff6093bbaebcb852105277ac53;p=oota-llvm.git diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 271691b85cb..b463d49af52 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -12,16 +12,17 @@ //===----------------------------------------------------------------------===// #include "LLParser.h" -#include "llvm/AutoUpgrade.h" -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Operator.h" -#include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/AutoUpgrade.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -52,11 +53,12 @@ bool LLParser::ValidateEndOfModule() { I != E; ++I) { Instruction *Inst = I->first; const std::vector &MDList = I->second; - + for (unsigned i = 0, e = MDList.size(); i != e; ++i) { unsigned SlotNo = MDList[i].MDSlot; - - if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0) + + if (SlotNo >= NumberedMetadata.size() || + NumberedMetadata[SlotNo] == nullptr) return Error(MDList[i].Loc, "use of undefined metadata '!" + Twine(SlotNo) + "'"); Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]); @@ -64,31 +66,92 @@ bool LLParser::ValidateEndOfModule() { } ForwardRefInstMetadata.clear(); } - - + + for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++) + UpgradeInstWithTBAATag(InstsWithTBAATag[I]); + + // Handle any function attribute group forward references. + for (std::map >::iterator + I = ForwardRefAttrGroups.begin(), E = ForwardRefAttrGroups.end(); + I != E; ++I) { + Value *V = I->first; + std::vector &Vec = I->second; + AttrBuilder B; + + for (std::vector::iterator VI = Vec.begin(), VE = Vec.end(); + VI != VE; ++VI) + B.merge(NumberedAttrBuilders[*VI]); + + if (Function *Fn = dyn_cast(V)) { + AttributeSet AS = Fn->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); + AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, + AS.getFnAttributes()); + + FnAttrs.merge(B); + + // If the alignment was parsed as an attribute, move to the alignment + // field. + if (FnAttrs.hasAlignmentAttr()) { + Fn->setAlignment(FnAttrs.getAlignment()); + FnAttrs.removeAttribute(Attribute::Alignment); + } + + AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, + AttributeSet::get(Context, + AttributeSet::FunctionIndex, + FnAttrs)); + Fn->setAttributes(AS); + } else if (CallInst *CI = dyn_cast(V)) { + AttributeSet AS = CI->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); + AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, + AS.getFnAttributes()); + FnAttrs.merge(B); + AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, + AttributeSet::get(Context, + AttributeSet::FunctionIndex, + FnAttrs)); + CI->setAttributes(AS); + } else if (InvokeInst *II = dyn_cast(V)) { + AttributeSet AS = II->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); + AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, + AS.getFnAttributes()); + FnAttrs.merge(B); + AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, + AttributeSet::get(Context, + AttributeSet::FunctionIndex, + FnAttrs)); + II->setAttributes(AS); + } else { + llvm_unreachable("invalid object with forward attribute group reference"); + } + } + // If there are entries in ForwardRefBlockAddresses at this point, they are // references after the function was defined. Resolve those now. while (!ForwardRefBlockAddresses.empty()) { // Okay, we are referencing an already-parsed function, resolve them now. - Function *TheFn = 0; + Function *TheFn = nullptr; const ValID &Fn = ForwardRefBlockAddresses.begin()->first; if (Fn.Kind == ValID::t_GlobalName) TheFn = M->getFunction(Fn.StrVal); else if (Fn.UIntVal < NumberedVals.size()) TheFn = dyn_cast(NumberedVals[Fn.UIntVal]); - - if (TheFn == 0) + + if (!TheFn) return Error(Fn.Loc, "unknown function referenced by blockaddress"); - + // Resolve all these references. - if (ResolveForwardRefBlockAddresses(TheFn, + if (ResolveForwardRefBlockAddresses(TheFn, ForwardRefBlockAddresses.begin()->second, - 0)) + nullptr)) return true; - + ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin()); } - + for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) if (NumberedTypes[i].second.isValid()) return Error(NumberedTypes[i].second, @@ -120,10 +183,12 @@ bool LLParser::ValidateEndOfModule() { for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove + UpgradeDebugInfo(*M); + return false; } -bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, +bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, std::vector > &Refs, PerFunctionState *PFS) { // Loop over all the references, resolving them. @@ -141,11 +206,11 @@ bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, Res = dyn_cast_or_null( TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal)); } - - if (Res == 0) + + if (!Res) return Error(Refs[i].first.Loc, "referenced value is not a basic block"); - + // Get the BlockAddress for this and update references to use it. BlockAddress *BA = BlockAddress::get(TheFn, Res); Refs[i].second->replaceAllUsesWith(BA); @@ -174,42 +239,40 @@ bool LLParser::ParseTopLevelEntities() { case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break; case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break; case lltok::exclaim: if (ParseStandaloneMetadata()) return true; break; - case lltok::MetadataVar: if (ParseNamedMetadata()) return true; break; + case lltok::MetadataVar:if (ParseNamedMetadata()) return true; break; // The Global variable production with no name can have many different // optional leading prefixes, the production is: - // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal - // OptionalAddrSpace OptionalUnNammedAddr + // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass + // OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr // ('constant'|'global') ... 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: // FIXME: backwards compat. case lltok::kw_internal: // OptionalLinkage + case lltok::kw_linker_private: // Obsolete OptionalLinkage + case lltok::kw_linker_private_weak: // Obsolete 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 - case lltok::kw_dllimport: // OptionalLinkage case lltok::kw_extern_weak: // OptionalLinkage case lltok::kw_external: { // OptionalLinkage - unsigned Linkage, Visibility; + unsigned Linkage, Visibility, DLLStorageClass; if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || - ParseGlobal("", SMLoc(), Linkage, true, Visibility)) + ParseOptionalDLLStorageClass(DLLStorageClass) || + ParseGlobal("", SMLoc(), Linkage, true, Visibility, DLLStorageClass)) return true; break; } case lltok::kw_default: // OptionalVisibility case lltok::kw_hidden: // OptionalVisibility case lltok::kw_protected: { // OptionalVisibility - unsigned Visibility; + unsigned Visibility, DLLStorageClass; if (ParseOptionalVisibility(Visibility) || - ParseGlobal("", SMLoc(), 0, false, Visibility)) + ParseOptionalDLLStorageClass(DLLStorageClass) || + ParseGlobal("", SMLoc(), 0, false, Visibility, DLLStorageClass)) return true; break; } @@ -218,8 +281,10 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_addrspace: // OptionalAddrSpace case lltok::kw_constant: // GlobalType case lltok::kw_global: // GlobalType - if (ParseGlobal("", SMLoc(), 0, false, 0)) return true; + if (ParseGlobal("", SMLoc(), 0, false, 0, 0)) return true; break; + + case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break; } } } @@ -267,6 +332,7 @@ bool LLParser::ParseTargetDefinition() { /// toplevelentity /// ::= 'deplibs' '=' '[' ']' /// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']' +/// FIXME: Remove in 4.0. Currently parse, but ignore. bool LLParser::ParseDepLibs() { assert(Lex.getKind() == lltok::kw_deplibs); Lex.Lex(); @@ -277,14 +343,10 @@ bool LLParser::ParseDepLibs() { if (EatIfPresent(lltok::rsquare)) return false; - std::string Str; - if (ParseStringConstant(Str)) return true; - M->addLibrary(Str); - - while (EatIfPresent(lltok::comma)) { + do { + std::string Str; if (ParseStringConstant(Str)) return true; - M->addLibrary(Str); - } + } while (EatIfPresent(lltok::comma)); return ParseToken(lltok::rsquare, "expected ']' at end of list"); } @@ -302,11 +364,11 @@ bool LLParser::ParseUnnamedType() { if (TypeID >= NumberedTypes.size()) NumberedTypes.resize(TypeID+1); - - Type *Result = 0; + + Type *Result = nullptr; if (ParseStructDefinition(TypeLoc, "", NumberedTypes[TypeID], Result)) return true; - + if (!isa(Result)) { std::pair &Entry = NumberedTypes[TypeID]; if (Entry.first) @@ -329,11 +391,11 @@ bool LLParser::ParseNamedType() { if (ParseToken(lltok::equal, "expected '=' after name") || ParseToken(lltok::kw_type, "expected 'type' after name")) return true; - - Type *Result = 0; + + Type *Result = nullptr; if (ParseStructDefinition(NameLoc, Name, NamedTypes[Name], Result)) return true; - + if (!isa(Result)) { std::pair &Entry = NamedTypes[Name]; if (Entry.first) @@ -341,7 +403,7 @@ bool LLParser::ParseNamedType() { Entry.first = Result; Entry.second = SMLoc(); } - + return false; } @@ -385,9 +447,11 @@ bool LLParser::ParseGlobalType(bool &IsConstant) { /// ParseUnnamedGlobal: /// OptionalVisibility ALIAS ... -/// OptionalLinkage OptionalVisibility ... -> global variable +/// OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// ... -> global variable /// GlobalID '=' OptionalVisibility ALIAS ... -/// GlobalID '=' OptionalLinkage OptionalVisibility ... -> global variable +/// GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// ... -> global variable bool LLParser::ParseUnnamedGlobal() { unsigned VarID = NumberedVals.size(); std::string Name; @@ -405,19 +469,22 @@ bool LLParser::ParseUnnamedGlobal() { } bool HasLinkage; - unsigned Linkage, Visibility; + unsigned Linkage, Visibility, DLLStorageClass; if (ParseOptionalLinkage(Linkage, HasLinkage) || - ParseOptionalVisibility(Visibility)) + ParseOptionalVisibility(Visibility) || + ParseOptionalDLLStorageClass(DLLStorageClass)) return true; if (HasLinkage || Lex.getKind() != lltok::kw_alias) - return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility); - return ParseAlias(Name, NameLoc, Visibility); + return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, + DLLStorageClass); + return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass); } /// ParseNamedGlobal: /// GlobalVar '=' OptionalVisibility ALIAS ... -/// GlobalVar '=' OptionalLinkage OptionalVisibility ... -> global variable +/// GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// ... -> global variable bool LLParser::ParseNamedGlobal() { assert(Lex.getKind() == lltok::GlobalVar); LocTy NameLoc = Lex.getLoc(); @@ -425,15 +492,17 @@ bool LLParser::ParseNamedGlobal() { Lex.Lex(); bool HasLinkage; - unsigned Linkage, Visibility; + unsigned Linkage, Visibility, DLLStorageClass; if (ParseToken(lltok::equal, "expected '=' in global variable") || ParseOptionalLinkage(Linkage, HasLinkage) || - ParseOptionalVisibility(Visibility)) + ParseOptionalVisibility(Visibility) || + ParseOptionalDLLStorageClass(DLLStorageClass)) return true; if (HasLinkage || Lex.getKind() != lltok::kw_alias) - return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility); - return ParseAlias(Name, NameLoc, Visibility); + return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, + DLLStorageClass); + return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass); } // MDString: @@ -455,10 +524,10 @@ bool LLParser::ParseMDNodeID(MDNode *&Result, unsigned &SlotNo) { if (ParseUInt32(SlotNo)) return true; // Check existing MDNode. - if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != 0) + if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != nullptr) Result = NumberedMetadata[SlotNo]; else - Result = 0; + Result = nullptr; return false; } @@ -471,9 +540,9 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) { if (Result) return false; // Otherwise, create MDNode forward reference. - MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef()); + MDNode *FwdNode = MDNode::getTemporary(Context, None); ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); - + if (NumberedMetadata.size() <= MID) NumberedMetadata.resize(MID+1); NumberedMetadata[MID] = FwdNode; @@ -498,8 +567,8 @@ bool LLParser::ParseNamedMetadata() { do { if (ParseToken(lltok::exclaim, "Expected '!' here")) return true; - - MDNode *N = 0; + + MDNode *N = nullptr; if (ParseMDNodeID(N)) return true; NMD->addOperand(N); } while (EatIfPresent(lltok::comma)); @@ -518,19 +587,19 @@ bool LLParser::ParseStandaloneMetadata() { unsigned MetadataID = 0; LocTy TyLoc; - Type *Ty = 0; + Type *Ty = nullptr; SmallVector Elts; if (ParseUInt32(MetadataID) || ParseToken(lltok::equal, "expected '=' here") || ParseType(Ty, TyLoc) || ParseToken(lltok::exclaim, "Expected '!' here") || ParseToken(lltok::lbrace, "Expected '{' here") || - ParseMDNodeVector(Elts, NULL) || + ParseMDNodeVector(Elts, nullptr) || ParseToken(lltok::rbrace, "expected end of metadata node")) return true; MDNode *Init = MDNode::get(Context, Elts); - + // See if this was forward referenced, if so, handle it. std::map, LocTy> >::iterator FI = ForwardRefMDNodes.find(MetadataID); @@ -539,13 +608,13 @@ bool LLParser::ParseStandaloneMetadata() { Temp->replaceAllUsesWith(Init); MDNode::deleteTemporary(Temp); ForwardRefMDNodes.erase(FI); - + assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work"); } else { if (MetadataID >= NumberedMetadata.size()) NumberedMetadata.resize(MetadataID+1); - if (NumberedMetadata[MetadataID] != 0) + if (NumberedMetadata[MetadataID] != nullptr) return TokError("Metadata id is already used"); NumberedMetadata[MetadataID] = Init; } @@ -553,55 +622,85 @@ bool LLParser::ParseStandaloneMetadata() { return false; } +static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { + return !GlobalValue::isLocalLinkage((GlobalValue::LinkageTypes)L) || + (GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility; +} + /// ParseAlias: -/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee +/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias' +/// OptionalLinkage Aliasee +/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias' +/// OptionalLinkage OptionalAddrSpace Type, Aliasee +/// /// Aliasee /// ::= TypeAndValue -/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')' -/// ::= 'getelementptr' 'inbounds'? '(' ... ')' /// -/// Everything through visibility has already been parsed. +/// Everything through DLL storage class has already been parsed. /// bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, - unsigned Visibility) { + unsigned Visibility, unsigned DLLStorageClass) { assert(Lex.getKind() == lltok::kw_alias); Lex.Lex(); - unsigned Linkage; LocTy LinkageLoc = Lex.getLoc(); - if (ParseOptionalLinkage(Linkage)) + unsigned L; + if (ParseOptionalLinkage(L)) return true; - if (Linkage != GlobalValue::ExternalLinkage && - Linkage != GlobalValue::WeakAnyLinkage && - Linkage != GlobalValue::WeakODRLinkage && - Linkage != GlobalValue::InternalLinkage && - Linkage != GlobalValue::PrivateLinkage && - Linkage != GlobalValue::LinkerPrivateLinkage && - Linkage != GlobalValue::LinkerPrivateWeakLinkage) + GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L; + + if(!GlobalAlias::isValidLinkage(Linkage)) return Error(LinkageLoc, "invalid linkage type for alias"); - Constant *Aliasee; - LocTy AliaseeLoc = Lex.getLoc(); - if (Lex.getKind() != lltok::kw_bitcast && - Lex.getKind() != lltok::kw_getelementptr) { - if (ParseGlobalTypeAndValue(Aliasee)) return true; + if (!isValidVisibilityForLinkage(Visibility, L)) + return Error(LinkageLoc, + "symbol with local linkage must have default visibility"); + + bool HasAddrSpace = Lex.getKind() == lltok::kw_addrspace; + unsigned AddrSpace; + LocTy AddrSpaceLoc = Lex.getLoc(); + if (ParseOptionalAddrSpace(AddrSpace)) + return true; + + LocTy TyLoc = Lex.getLoc(); + Type *Ty = nullptr; + if (ParseType(Ty)) + return true; + + bool DifferentType = EatIfPresent(lltok::comma); + if (HasAddrSpace && !DifferentType) + return Error(AddrSpaceLoc, "A type is required if addrspace is given"); + + Type *AliaseeType = nullptr; + if (DifferentType) { + if (ParseType(AliaseeType)) + return true; } else { - // The bitcast dest type is not present, it is implied by the dest type. - ValID ID; - if (ParseValID(ID)) return true; - if (ID.Kind != ValID::t_Constant) - return Error(AliaseeLoc, "invalid aliasee"); - Aliasee = ID.ConstantVal; + AliaseeType = Ty; + auto *PTy = dyn_cast(Ty); + if (!PTy) + return Error(TyLoc, "An alias must have pointer type"); + Ty = PTy->getElementType(); + AddrSpace = PTy->getAddressSpace(); } - if (!Aliasee->getType()->isPointerTy()) - return Error(AliaseeLoc, "alias must have pointer type"); + LocTy AliaseeLoc = Lex.getLoc(); + Constant *C; + if (ParseGlobalValue(AliaseeType, C)) + return true; + + auto *Aliasee = dyn_cast(C); + if (!Aliasee) + return Error(AliaseeLoc, "Alias must point to function or variable"); + + assert(Aliasee->getType()->isPointerTy()); // Okay, create the alias but do not insert it into the module yet. - GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), - (GlobalValue::LinkageTypes)Linkage, Name, - Aliasee); + std::unique_ptr GA( + new GlobalAlias(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage, Name, + Aliasee, /*Parent*/ nullptr)); GA->setVisibility((GlobalValue::VisibilityTypes)Visibility); + GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); // See if this value already exists in the symbol table. If so, it is either // a redefinition or a definition of a forward reference. @@ -621,49 +720,67 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, // If they agree, just RAUW the old value with the alias and remove the // forward ref info. - Val->replaceAllUsesWith(GA); + for (auto *User : Val->users()) { + if (auto *GA = dyn_cast(User)) + return Error(NameLoc, "Alias is pointed by alias " + GA->getName()); + } + + Val->replaceAllUsesWith(GA.get()); Val->eraseFromParent(); ForwardRefVals.erase(I); } // Insert into the module, we know its name won't collide now. - M->getAliasList().push_back(GA); + M->getAliasList().push_back(GA.get()); assert(GA->getName() == Name && "Should not be a name conflict!"); + // The module owns this now + GA.release(); + return false; } /// ParseGlobal -/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal -/// OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const -/// ::= OptionalLinkage OptionalVisibility OptionalThreadLocal -/// OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const +/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr +/// OptionalExternallyInitialized GlobalType Type Const +/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr +/// OptionalExternallyInitialized GlobalType Type Const /// -/// Everything through visibility has been parsed already. +/// Everything up to and including OptionalDLLStorageClass has been parsed +/// already. /// bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, - unsigned Visibility) { + unsigned Visibility, unsigned DLLStorageClass) { + if (!isValidVisibilityForLinkage(Visibility, Linkage)) + return Error(NameLoc, + "symbol with local linkage must have default visibility"); + unsigned AddrSpace; - bool IsConstant, UnnamedAddr; + bool IsConstant, UnnamedAddr, IsExternallyInitialized; GlobalVariable::ThreadLocalMode TLM; LocTy UnnamedAddrLoc; + LocTy IsExternallyInitializedLoc; LocTy TyLoc; - Type *Ty = 0; + Type *Ty = nullptr; if (ParseOptionalThreadLocal(TLM) || ParseOptionalAddrSpace(AddrSpace) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || + ParseOptionalToken(lltok::kw_externally_initialized, + IsExternallyInitialized, + &IsExternallyInitializedLoc) || ParseGlobalType(IsConstant) || ParseType(Ty, TyLoc)) return true; // If the linkage is specified and is external, then no initializer is // present. - Constant *Init = 0; - if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage && - Linkage != GlobalValue::ExternalWeakLinkage && + Constant *Init = nullptr; + if (!HasLinkage || (Linkage != GlobalValue::ExternalWeakLinkage && Linkage != GlobalValue::ExternalLinkage)) { if (ParseGlobalValue(Ty, Init)) return true; @@ -672,7 +789,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (Ty->isFunctionTy() || Ty->isLabelTy()) return Error(TyLoc, "invalid type for global variable"); - GlobalVariable *GV = 0; + GlobalVariable *GV = nullptr; // See if the global was forward referenced, if so, use the global. if (!Name.empty()) { @@ -690,9 +807,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, } } - if (GV == 0) { - GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, 0, - Name, 0, GlobalVariable::NotThreadLocal, + if (!GV) { + GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr, + Name, nullptr, GlobalVariable::NotThreadLocal, AddrSpace); } else { if (GV->getType()->getElementType() != Ty) @@ -712,6 +829,8 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); + GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); + GV->setExternallyInitialized(IsExternallyInitialized); GV->setThreadLocalMode(TLM); GV->setUnnamedAddr(UnnamedAddr); @@ -736,6 +855,165 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, return false; } +/// ParseUnnamedAttrGrp +/// ::= 'attributes' AttrGrpID '=' '{' AttrValPair+ '}' +bool LLParser::ParseUnnamedAttrGrp() { + assert(Lex.getKind() == lltok::kw_attributes); + LocTy AttrGrpLoc = Lex.getLoc(); + Lex.Lex(); + + assert(Lex.getKind() == lltok::AttrGrpID); + unsigned VarID = Lex.getUIntVal(); + std::vector unused; + LocTy BuiltinLoc; + Lex.Lex(); + + if (ParseToken(lltok::equal, "expected '=' here") || + ParseToken(lltok::lbrace, "expected '{' here") || + ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true, + BuiltinLoc) || + ParseToken(lltok::rbrace, "expected end of attribute group")) + return true; + + if (!NumberedAttrBuilders[VarID].hasAttributes()) + return Error(AttrGrpLoc, "attribute group has no attributes"); + + return false; +} + +/// ParseFnAttributeValuePairs +/// ::= | '=' +bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, + std::vector &FwdRefAttrGrps, + bool inAttrGrp, LocTy &BuiltinLoc) { + bool HaveError = false; + + B.clear(); + + while (true) { + lltok::Kind Token = Lex.getKind(); + if (Token == lltok::kw_builtin) + BuiltinLoc = Lex.getLoc(); + switch (Token) { + default: + if (!inAttrGrp) return HaveError; + return Error(Lex.getLoc(), "unterminated attribute group"); + case lltok::rbrace: + // Finished. + return false; + + case lltok::AttrGrpID: { + // Allow a function to reference an attribute group: + // + // define void @foo() #1 { ... } + if (inAttrGrp) + HaveError |= + Error(Lex.getLoc(), + "cannot have an attribute group reference in an attribute group"); + + unsigned AttrGrpNum = Lex.getUIntVal(); + if (inAttrGrp) break; + + // Save the reference to the attribute group. We'll fill it in later. + FwdRefAttrGrps.push_back(AttrGrpNum); + break; + } + // Target-dependent attributes: + case lltok::StringConstant: { + std::string Attr = Lex.getStrVal(); + Lex.Lex(); + std::string Val; + if (EatIfPresent(lltok::equal) && + ParseStringConstant(Val)) + return true; + + B.addAttribute(Attr, Val); + continue; + } + + // Target-independent attributes: + case lltok::kw_align: { + // As a hack, we allow function alignment to be initially parsed as an + // attribute on a function declaration/definition or added to an attribute + // group and later moved to the alignment field. + unsigned Alignment; + if (inAttrGrp) { + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' here") || + ParseUInt32(Alignment)) + return true; + } else { + if (ParseOptionalAlignment(Alignment)) + return true; + } + B.addAlignmentAttr(Alignment); + continue; + } + case lltok::kw_alignstack: { + unsigned Alignment; + if (inAttrGrp) { + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' here") || + ParseUInt32(Alignment)) + return true; + } else { + if (ParseOptionalStackAlignment(Alignment)) + return true; + } + B.addStackAlignmentAttr(Alignment); + continue; + } + case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; + case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break; + case lltok::kw_cold: B.addAttribute(Attribute::Cold); break; + case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; + case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; + case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; + case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break; + case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break; + case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break; + case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; + case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; + case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; + case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; + case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; + case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break; + case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; + case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; + case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break; + case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; + case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; + case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break; + case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break; + case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break; + case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break; + case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; + + // Error handling. + case lltok::kw_inreg: + case lltok::kw_signext: + case lltok::kw_zeroext: + HaveError |= + Error(Lex.getLoc(), + "invalid use of attribute on a function"); + break; + case lltok::kw_byval: + case lltok::kw_inalloca: + case lltok::kw_nest: + case lltok::kw_noalias: + case lltok::kw_nocapture: + case lltok::kw_returned: + case lltok::kw_sret: + HaveError |= + Error(Lex.getLoc(), + "invalid use of parameter-only attribute on a function"); + break; + } + + Lex.Lex(); + } +} //===----------------------------------------------------------------------===// // GlobalValue Reference/Resolution Routines. @@ -747,9 +1025,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, LocTy Loc) { PointerType *PTy = dyn_cast(Ty); - if (PTy == 0) { + if (!PTy) { Error(Loc, "global variable reference must have pointer type"); - return 0; + return nullptr; } // Look this name up in the normal function symbol table. @@ -758,7 +1036,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, // If this is a forward reference for the value, see if we already created a // forward ref record. - if (Val == 0) { + if (!Val) { std::map >::iterator I = ForwardRefVals.find(Name); if (I != ForwardRefVals.end()) @@ -770,7 +1048,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, if (Val->getType() == Ty) return Val; Error(Loc, "'@" + Name + "' defined with type '" + getTypeString(Val->getType()) + "'"); - return 0; + return nullptr; } // Otherwise, create a new forward reference for this value and remember it. @@ -779,7 +1057,9 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, Name); + GlobalValue::ExternalWeakLinkage, nullptr, Name, + nullptr, GlobalVariable::NotThreadLocal, + PTy->getAddressSpace()); ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -787,16 +1067,16 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { PointerType *PTy = dyn_cast(Ty); - if (PTy == 0) { + if (!PTy) { Error(Loc, "global variable reference must have pointer type"); - return 0; + return nullptr; } - GlobalValue *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0; + GlobalValue *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr; // If this is a forward reference for the value, see if we already created a // forward ref record. - if (Val == 0) { + if (!Val) { std::map >::iterator I = ForwardRefValIDs.find(ID); if (I != ForwardRefValIDs.end()) @@ -808,7 +1088,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { if (Val->getType() == Ty) return Val; Error(Loc, "'@" + Twine(ID) + "' defined with type '" + getTypeString(Val->getType()) + "'"); - return 0; + return nullptr; } // Otherwise, create a new forward reference for this value and remember it. @@ -817,7 +1097,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, ""); + GlobalValue::ExternalWeakLinkage, nullptr, ""); ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -913,73 +1193,129 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { ParseToken(lltok::rparen, "expected ')' in address space"); } -/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind -/// indicates what kind of attribute list this is: 0: function arg, 1: result, -/// 2: function attr. -bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) { - Attrs = Attribute::None; - LocTy AttrLoc = Lex.getLoc(); +/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes. +bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { + bool HaveError = false; + + B.clear(); while (1) { - switch (Lex.getKind()) { + lltok::Kind Token = Lex.getKind(); + switch (Token) { default: // End of attributes. - if (AttrKind != 2 && (Attrs & Attribute::FunctionOnly)) - return Error(AttrLoc, "invalid use of function-only attribute"); - - // As a hack, we allow "align 2" on functions as a synonym for - // "alignstack 2". - if (AttrKind == 2 && - (Attrs & ~(Attribute::FunctionOnly | Attribute::Alignment))) - return Error(AttrLoc, "invalid use of attribute on a function"); - - if (AttrKind != 0 && (Attrs & Attribute::ParameterOnly)) - return Error(AttrLoc, "invalid use of parameter-only attribute"); - - return false; - case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break; - case lltok::kw_signext: Attrs |= Attribute::SExt; break; - case lltok::kw_inreg: Attrs |= Attribute::InReg; break; - case lltok::kw_sret: Attrs |= Attribute::StructRet; break; - case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break; - case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break; - case lltok::kw_byval: Attrs |= Attribute::ByVal; break; - case lltok::kw_nest: Attrs |= Attribute::Nest; break; - - case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break; - case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break; - case lltok::kw_uwtable: Attrs |= Attribute::UWTable; break; - case lltok::kw_returns_twice: Attrs |= Attribute::ReturnsTwice; break; - case lltok::kw_noinline: Attrs |= Attribute::NoInline; break; - case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break; - case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break; - case lltok::kw_inlinehint: Attrs |= Attribute::InlineHint; break; - case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break; - case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break; - case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break; - case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; - case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; - case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break; - case lltok::kw_naked: Attrs |= Attribute::Naked; break; - case lltok::kw_nonlazybind: Attrs |= Attribute::NonLazyBind; break; - case lltok::kw_address_safety: Attrs |= Attribute::AddressSafety; break; - - case lltok::kw_alignstack: { - unsigned Alignment; - if (ParseOptionalStackAlignment(Alignment)) - return true; - Attrs |= Attribute::constructStackAlignmentFromInt(Alignment); - continue; - } - + return HaveError; case lltok::kw_align: { unsigned Alignment; if (ParseOptionalAlignment(Alignment)) return true; - Attrs |= Attribute::constructAlignmentFromInt(Alignment); + B.addAlignmentAttr(Alignment); continue; } + case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break; + case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break; + case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; + case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; + case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; + case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break; + case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; + case lltok::kw_returned: B.addAttribute(Attribute::Returned); break; + case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; + case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break; + case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; + + case lltok::kw_alignstack: + case lltok::kw_alwaysinline: + case lltok::kw_builtin: + case lltok::kw_inlinehint: + case lltok::kw_minsize: + case lltok::kw_naked: + case lltok::kw_nobuiltin: + case lltok::kw_noduplicate: + case lltok::kw_noimplicitfloat: + case lltok::kw_noinline: + case lltok::kw_nonlazybind: + case lltok::kw_noredzone: + case lltok::kw_noreturn: + case lltok::kw_nounwind: + case lltok::kw_optnone: + case lltok::kw_optsize: + case lltok::kw_returns_twice: + case lltok::kw_sanitize_address: + case lltok::kw_sanitize_memory: + case lltok::kw_sanitize_thread: + case lltok::kw_ssp: + case lltok::kw_sspreq: + case lltok::kw_sspstrong: + case lltok::kw_uwtable: + HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); + break; + } + Lex.Lex(); + } +} + +/// ParseOptionalReturnAttrs - Parse a potentially empty list of return attributes. +bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { + bool HaveError = false; + + B.clear(); + + while (1) { + lltok::Kind Token = Lex.getKind(); + switch (Token) { + default: // End of attributes. + return HaveError; + case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; + case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; + case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; + case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; + + // Error handling. + case lltok::kw_align: + case lltok::kw_byval: + case lltok::kw_inalloca: + case lltok::kw_nest: + case lltok::kw_nocapture: + case lltok::kw_returned: + case lltok::kw_sret: + HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute"); + break; + + case lltok::kw_alignstack: + case lltok::kw_alwaysinline: + case lltok::kw_builtin: + case lltok::kw_cold: + case lltok::kw_inlinehint: + case lltok::kw_minsize: + case lltok::kw_naked: + case lltok::kw_nobuiltin: + case lltok::kw_noduplicate: + case lltok::kw_noimplicitfloat: + case lltok::kw_noinline: + case lltok::kw_nonlazybind: + case lltok::kw_noredzone: + case lltok::kw_noreturn: + case lltok::kw_nounwind: + case lltok::kw_optnone: + case lltok::kw_optsize: + case lltok::kw_returns_twice: + case lltok::kw_sanitize_address: + case lltok::kw_sanitize_memory: + case lltok::kw_sanitize_thread: + case lltok::kw_ssp: + case lltok::kw_sspreq: + case lltok::kw_sspstrong: + case lltok::kw_uwtable: + HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); + break; + + case lltok::kw_readnone: + case lltok::kw_readonly: + HaveError |= Error(Lex.getLoc(), "invalid use of attribute on return type"); } + Lex.Lex(); } } @@ -987,48 +1323,46 @@ bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) { /// ParseOptionalLinkage /// ::= /*empty*/ /// ::= 'private' -/// ::= 'linker_private' -/// ::= 'linker_private_weak' /// ::= 'internal' /// ::= 'weak' /// ::= 'weak_odr' /// ::= 'linkonce' /// ::= 'linkonce_odr' -/// ::= 'linkonce_odr_auto_hide' /// ::= 'available_externally' /// ::= 'appending' -/// ::= 'dllexport' /// ::= 'common' -/// ::= 'dllimport' /// ::= 'extern_weak' /// ::= 'external' +/// +/// Deprecated Values: +/// ::= 'linker_private' +/// ::= 'linker_private_weak' bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { HasLinkage = false; switch (Lex.getKind()) { default: Res=GlobalValue::ExternalLinkage; return false; case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break; - case lltok::kw_linker_private: Res = GlobalValue::LinkerPrivateLinkage; break; - case lltok::kw_linker_private_weak: - Res = GlobalValue::LinkerPrivateWeakLinkage; - 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; case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break; - case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break; case lltok::kw_common: Res = GlobalValue::CommonLinkage; break; - case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break; case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break; case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; + + case lltok::kw_linker_private: + case lltok::kw_linker_private_weak: + Lex.Warning("'" + Lex.getStrVal() + "' is deprecated, treating as" + " PrivateLinkage"); + Lex.Lex(); + // treat linker_private and linker_private_weak as PrivateLinkage + Res = GlobalValue::PrivateLinkage; + return false; } Lex.Lex(); HasLinkage = true; @@ -1052,10 +1386,26 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { return false; } +/// ParseOptionalDLLStorageClass +/// ::= /*empty*/ +/// ::= 'dllimport' +/// ::= 'dllexport' +/// +bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { + switch (Lex.getKind()) { + default: Res = GlobalValue::DefaultStorageClass; return false; + case lltok::kw_dllimport: Res = GlobalValue::DLLImportStorageClass; break; + case lltok::kw_dllexport: Res = GlobalValue::DLLExportStorageClass; break; + } + Lex.Lex(); + return false; +} + /// ParseOptionalCallingConv /// ::= /*empty*/ /// ::= 'ccc' /// ::= 'fastcc' +/// ::= 'kw_intel_ocl_bicc' /// ::= 'coldcc' /// ::= 'x86_stdcallcc' /// ::= 'x86_fastcallcc' @@ -1066,6 +1416,14 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { /// ::= 'msp430_intrcc' /// ::= 'ptx_kernel' /// ::= 'ptx_device' +/// ::= 'spir_func' +/// ::= 'spir_kernel' +/// ::= 'x86_64_sysvcc' +/// ::= 'x86_64_win64cc' +/// ::= 'webkit_jscc' +/// ::= 'anyregcc' +/// ::= 'preserve_mostcc' +/// ::= 'preserve_allcc' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { @@ -1083,6 +1441,15 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break; case lltok::kw_ptx_kernel: CC = CallingConv::PTX_Kernel; break; case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break; + case lltok::kw_spir_kernel: CC = CallingConv::SPIR_KERNEL; break; + case lltok::kw_spir_func: CC = CallingConv::SPIR_FUNC; break; + case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break; + case lltok::kw_x86_64_sysvcc: CC = CallingConv::X86_64_SysV; break; + case lltok::kw_x86_64_win64cc: CC = CallingConv::X86_64_Win64; break; + case lltok::kw_webkit_jscc: CC = CallingConv::WebKit_JS; break; + case lltok::kw_anyregcc: CC = CallingConv::AnyReg; break; + case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break; + case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break; case lltok::kw_cc: { unsigned ArbitraryCC; Lex.Lex(); @@ -1139,6 +1506,9 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst, } } + if (MDK == LLVMContext::MD_tbaa) + InstsWithTBAATag.push_back(Inst); + // If this is the end of the list, we're done. } while (EatIfPresent(lltok::comma)); return false; @@ -1161,7 +1531,7 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { } /// ParseOptionalCommaAlign -/// ::= +/// ::= /// ::= ',' align 4 /// /// This returns with AteExtraComma set to true if it ate an excess comma at the @@ -1175,7 +1545,7 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment, AteExtraComma = true; return false; } - + if (Lex.getKind() != lltok::kw_align) return Error(Lex.getLoc(), "expected metadata or 'align'"); @@ -1198,6 +1568,15 @@ bool LLParser::ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope, Scope = CrossThread; if (EatIfPresent(lltok::kw_singlethread)) Scope = SingleThread; + + return ParseOrdering(Ordering); +} + +/// ParseOrdering +/// ::= AtomicOrdering +/// +/// This sets Ordering to the parsed value. +bool LLParser::ParseOrdering(AtomicOrdering &Ordering) { switch (Lex.getKind()) { default: return TokError("Expected ordering on atomic instruction"); case lltok::kw_unordered: Ordering = Unordered; break; @@ -1243,7 +1622,7 @@ bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) { bool LLParser::ParseIndexList(SmallVectorImpl &Indices, bool &AteExtraComma) { AteExtraComma = false; - + if (Lex.getKind() != lltok::comma) return TokError("expected ',' as start of index list"); @@ -1299,10 +1678,10 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { 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) { + if (!Entry.first) { Entry.first = StructType::create(Context, Lex.getStrVal()); Entry.second = Lex.getLoc(); } @@ -1316,10 +1695,10 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { 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) { + if (!Entry.first) { Entry.first = StructType::create(Context); Entry.second = Lex.getLoc(); } @@ -1386,6 +1765,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, if (ParseToken(lltok::lparen, "expected '(' in call")) return true; + unsigned AttrIndex = 1; while (Lex.getKind() != lltok::rparen) { // If this isn't the first argument, we need a comma. if (!ArgList.empty() && @@ -1394,17 +1774,18 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, // Parse the argument. LocTy ArgLoc; - Type *ArgTy = 0; - Attributes ArgAttrs1; - Attributes ArgAttrs2; + Type *ArgTy = nullptr; + AttrBuilder ArgAttrs; Value *V; if (ParseType(ArgTy, ArgLoc)) return true; // Otherwise, handle normal operands. - if (ParseOptionalAttrs(ArgAttrs1, 0) || ParseValue(ArgTy, V, PFS)) + if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS)) return true; - ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2)); + ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(), + AttrIndex++, + ArgAttrs))); } Lex.Lex(); // Lex the ')'. @@ -1435,12 +1816,12 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, Lex.Lex(); } else { LocTy TypeLoc = Lex.getLoc(); - Type *ArgTy = 0; - Attributes Attrs; + Type *ArgTy = nullptr; + AttrBuilder Attrs; std::string Name; if (ParseType(ArgTy) || - ParseOptionalAttrs(Attrs, 0)) return true; + ParseOptionalParamAttrs(Attrs)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); @@ -1453,7 +1834,10 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + unsigned AttrIndex = 1; + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, + AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1464,7 +1848,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, // Otherwise must be an argument type. TypeLoc = Lex.getLoc(); - if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true; + if (ParseType(ArgTy) || ParseOptionalParamAttrs(Attrs)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); @@ -1479,7 +1863,10 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, + AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), + Name)); } } @@ -1503,7 +1890,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { if (!ArgList[i].Name.empty()) return Error(ArgList[i].Loc, "argument name invalid in function type"); - if (ArgList[i].Attrs) + if (ArgList[i].Attrs.hasAttributes(i + 1)) return Error(ArgList[i].Loc, "argument attributes invalid in function type"); } @@ -1521,7 +1908,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) { SmallVector Elts; if (ParseStructBody(Elts)) return true; - + Result = StructType::get(Context, Elts, Packed); return false; } @@ -1533,20 +1920,20 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, // If the type was already defined, diagnose the redefinition. if (Entry.first && !Entry.second.isValid()) return Error(TypeLoc, "redefinition of type"); - + // If we have opaque, just return without filling in the definition for the // struct. This counts as a definition as far as the .ll file goes. if (EatIfPresent(lltok::kw_opaque)) { // This type is being defined, so clear the location to indicate this. Entry.second = SMLoc(); - + // If this type number has never been uttered, create it. - if (Entry.first == 0) + if (!Entry.first) Entry.first = StructType::create(Context, Name); ResultTy = Entry.first; return false; } - + // If the type starts with '<', then it is either a packed struct or a vector. bool isPacked = EatIfPresent(lltok::less); @@ -1556,27 +1943,27 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, if (Lex.getKind() != lltok::lbrace) { if (Entry.first) return Error(TypeLoc, "forward references to non-struct type"); - - ResultTy = 0; + + ResultTy = nullptr; 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) + if (!Entry.first) 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; @@ -1598,7 +1985,7 @@ bool LLParser::ParseStructBody(SmallVectorImpl &Body) { return false; LocTy EltTyLoc = Lex.getLoc(); - Type *Ty = 0; + Type *Ty = nullptr; if (ParseType(Ty)) return true; Body.push_back(Ty); @@ -1636,7 +2023,7 @@ bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { return true; LocTy TypeLoc = Lex.getLoc(); - Type *EltTy = 0; + Type *EltTy = nullptr; if (ParseType(EltTy)) return true; if (ParseToken(isVector ? lltok::greater : lltok::rsquare, @@ -1649,8 +2036,7 @@ bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { if ((unsigned)Size != Size) return Error(SizeLoc, "size too large for vector"); if (!VectorType::isValidElementType(EltTy)) - return Error(TypeLoc, - "vector element type must be fp, integer or a pointer to these types"); + return Error(TypeLoc, "invalid vector element type"); Result = VectorType::get(EltTy, unsigned(Size)); } else { if (!ArrayType::isValidElementType(EltTy)) @@ -1683,7 +2069,7 @@ LLParser::PerFunctionState::~PerFunctionState() { I->second.first->replaceAllUsesWith( UndefValue::get(I->second.first->getType())); delete I->second.first; - I->second.first = 0; + I->second.first = nullptr; } for (std::map >::iterator @@ -1692,7 +2078,7 @@ LLParser::PerFunctionState::~PerFunctionState() { I->second.first->replaceAllUsesWith( UndefValue::get(I->second.first->getType())); delete I->second.first; - I->second.first = 0; + I->second.first = nullptr; } } @@ -1707,18 +2093,18 @@ bool LLParser::PerFunctionState::FinishFunction() { FunctionID.Kind = ValID::t_GlobalID; FunctionID.UIntVal = FunctionNumber; } - + std::map > >::iterator FRBAI = P.ForwardRefBlockAddresses.find(FunctionID); if (FRBAI != P.ForwardRefBlockAddresses.end()) { // Resolve all these references. if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this)) return true; - + P.ForwardRefBlockAddresses.erase(FRBAI); } } - + if (!ForwardRefVals.empty()) return P.Error(ForwardRefVals.begin()->second.second, "use of undefined value '%" + ForwardRefVals.begin()->first + @@ -1741,7 +2127,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, // If this is a forward reference for the value, see if we already created a // forward ref record. - if (Val == 0) { + if (!Val) { std::map >::iterator I = ForwardRefVals.find(Name); if (I != ForwardRefVals.end()) @@ -1756,13 +2142,13 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, else P.Error(Loc, "'%" + Name + "' defined with type '" + getTypeString(Val->getType()) + "'"); - return 0; + return nullptr; } // Don't make placeholders with invalid type. if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { P.Error(Loc, "invalid use of a non-first-class type"); - return 0; + return nullptr; } // Otherwise, create a new forward reference for this value and remember it. @@ -1779,11 +2165,11 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, 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; + Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr; // If this is a forward reference for the value, see if we already created a // forward ref record. - if (Val == 0) { + if (!Val) { std::map >::iterator I = ForwardRefValIDs.find(ID); if (I != ForwardRefValIDs.end()) @@ -1798,12 +2184,12 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, else P.Error(Loc, "'%" + Twine(ID) + "' defined with type '" + getTypeString(Val->getType()) + "'"); - return 0; + return nullptr; } if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { P.Error(Loc, "invalid use of a non-first-class type"); - return 0; + return nullptr; } // Otherwise, create a new forward reference for this value and remember it. @@ -1899,7 +2285,7 @@ BasicBlock *LLParser::PerFunctionState::DefineBB(const std::string &Name, BB = GetBB(NumberedVals.size(), Loc); else BB = GetBB(Name, Loc); - if (BB == 0) return 0; // Already diagnosed error. + if (!BB) return nullptr; // Already diagnosed error. // Move the block to the end of the function. Forward ref'd blocks are // inserted wherever they happen to be referenced. @@ -2068,17 +2454,20 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return false; case lltok::kw_asm: { - // ValID ::= 'asm' SideEffect? AlignStack? STRINGCONSTANT ',' STRINGCONSTANT - bool HasSideEffect, AlignStack; + // ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ',' + // STRINGCONSTANT + 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; } @@ -2088,36 +2477,36 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { Lex.Lex(); ValID Fn, Label; - LocTy FnLoc, LabelLoc; - + if (ParseToken(lltok::lparen, "expected '(' in block address expression") || ParseValID(Fn) || ParseToken(lltok::comma, "expected comma in block address expression")|| ParseValID(Label) || ParseToken(lltok::rparen, "expected ')' in block address expression")) return true; - + if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName) return Error(Fn.Loc, "expected function name in blockaddress"); if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName) return Error(Label.Loc, "expected basic block name in blockaddress"); - + // Make a global variable as a placeholder for this reference. GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false, GlobalValue::InternalLinkage, - 0, ""); + nullptr, ""); ForwardRefBlockAddresses[Fn].push_back(std::make_pair(Label, FwdRef)); ID.ConstantVal = FwdRef; ID.Kind = ValID::t_Constant; return false; } - + case lltok::kw_trunc: case lltok::kw_zext: case lltok::kw_sext: case lltok::kw_fptrunc: case lltok::kw_fpext: case lltok::kw_bitcast: + case lltok::kw_addrspacecast: case lltok::kw_uitofp: case lltok::kw_sitofp: case lltok::kw_fptoui: @@ -2125,7 +2514,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { case lltok::kw_inttoptr: case lltok::kw_ptrtoint: { unsigned Opc = Lex.getUIntVal(); - Type *DestTy = 0; + Type *DestTy = nullptr; Constant *SrcVal; Lex.Lex(); if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") || @@ -2389,18 +2778,18 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { /// ParseGlobalValue - Parse a global value with the specified type. bool LLParser::ParseGlobalValue(Type *Ty, Constant *&C) { - C = 0; + C = nullptr; ValID ID; - Value *V = NULL; + Value *V = nullptr; bool Parsed = ParseValID(ID) || - ConvertValIDToValue(Ty, ID, V, NULL); + ConvertValIDToValue(Ty, ID, V, nullptr); if (V && !(C = dyn_cast(V))) return Error(ID.Loc, "global values must be constants"); return Parsed; } bool LLParser::ParseGlobalTypeAndValue(Constant *&V) { - Type *Ty = 0; + Type *Ty = nullptr; return ParseType(Ty) || ParseGlobalValue(Ty, V); } @@ -2484,18 +2873,19 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, case ValID::t_LocalID: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc); - return (V == 0); + return V == nullptr; case ValID::t_LocalName: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); - return (V == 0); + return V == nullptr; case ValID::t_InlineAsm: { PointerType *PTy = dyn_cast(Ty); - FunctionType *FTy = - PTy ? dyn_cast(PTy->getElementType()) : 0; + FunctionType *FTy = + PTy ? dyn_cast(PTy->getElementType()) : nullptr; 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: @@ -2510,10 +2900,10 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, return false; case ValID::t_GlobalName: V = GetGlobalVal(ID.StrVal, Ty, ID.Loc); - return V == 0; + return V == nullptr; case ValID::t_GlobalID: V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc); - return V == 0; + return V == nullptr; case ValID::t_APSInt: if (!Ty->isIntegerTy()) return Error(ID.Loc, "integer constant must have integer type"); @@ -2579,13 +2969,13 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, "initializer with struct type has wrong # elements"); if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct)) return Error(ID.Loc, "packed'ness of initializer and type don't match"); - + // Verify that the elements are compatible with the structtype. for (unsigned i = 0, e = ID.UIntVal; i != e; ++i) if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i)) return Error(ID.Loc, "element " + Twine(i) + " of struct initializer doesn't match struct element type"); - + V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts, ID.UIntVal)); } else @@ -2596,14 +2986,14 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, } bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { - V = 0; + V = nullptr; ValID ID; return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS); } bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) { - Type *Ty = 0; + Type *Ty = nullptr; return ParseType(Ty) || ParseValue(Ty, V, PFS); } @@ -2623,21 +3013,23 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, /// FunctionHeader /// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs /// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection -/// OptionalAlign OptGC +/// OptionalAlign OptGC OptionalPrefix bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Parse the linkage. LocTy LinkageLoc = Lex.getLoc(); unsigned Linkage; unsigned Visibility; - Attributes RetAttrs; + unsigned DLLStorageClass; + AttrBuilder RetAttrs; CallingConv::ID CC; - Type *RetType = 0; + Type *RetType = nullptr; LocTy RetTypeLoc = Lex.getLoc(); if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || + ParseOptionalDLLStorageClass(DLLStorageClass) || ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/)) return true; @@ -2645,22 +3037,17 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { switch ((GlobalValue::LinkageTypes)Linkage) { case GlobalValue::ExternalLinkage: break; // always ok. - case GlobalValue::DLLImportLinkage: case GlobalValue::ExternalWeakLinkage: if (isDefine) return Error(LinkageLoc, "invalid linkage for function definition"); break; case GlobalValue::PrivateLinkage: - case GlobalValue::LinkerPrivateLinkage: - case GlobalValue::LinkerPrivateWeakLinkage: case GlobalValue::InternalLinkage: case GlobalValue::AvailableExternallyLinkage: case GlobalValue::LinkOnceAnyLinkage: case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::LinkOnceODRAutoHideLinkage: case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: - case GlobalValue::DLLExportLinkage: if (!isDefine) return Error(LinkageLoc, "invalid linkage for function declaration"); break; @@ -2669,6 +3056,10 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { return Error(LinkageLoc, "invalid function linkage type"); } + if (!isValidVisibilityForLinkage(Visibility, Linkage)) + return Error(LinkageLoc, + "symbol with local linkage must have default visibility"); + if (!FunctionType::isValidReturnType(RetType)) return Error(RetTypeLoc, "invalid function return type"); @@ -2694,57 +3085,72 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { SmallVector ArgList; bool isVarArg; - Attributes FuncAttrs; + AttrBuilder FuncAttrs; + std::vector FwdRefAttrGrps; + LocTy BuiltinLoc; std::string Section; unsigned Alignment; std::string GC; bool UnnamedAddr; LocTy UnnamedAddrLoc; + Constant *Prefix = nullptr; if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || - ParseOptionalAttrs(FuncAttrs, 2) || + ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false, + BuiltinLoc) || (EatIfPresent(lltok::kw_section) && ParseStringConstant(Section)) || ParseOptionalAlignment(Alignment) || (EatIfPresent(lltok::kw_gc) && - ParseStringConstant(GC))) + ParseStringConstant(GC)) || + (EatIfPresent(lltok::kw_prefix) && + ParseGlobalTypeAndValue(Prefix))) return true; + if (FuncAttrs.contains(Attribute::Builtin)) + return Error(BuiltinLoc, "'builtin' attribute not valid on function"); + // If the alignment was parsed as an attribute, move to the alignment field. - if (FuncAttrs & Attribute::Alignment) { - Alignment = Attribute::getAlignmentFromAttrs(FuncAttrs); - FuncAttrs &= ~Attribute::Alignment; + if (FuncAttrs.hasAlignmentAttr()) { + Alignment = FuncAttrs.getAlignment(); + FuncAttrs.removeAttribute(Attribute::Alignment); } // Okay, if we got here, the function is syntactically valid. Convert types // and do semantic checks. std::vector ParamTypeList; - SmallVector Attrs; + SmallVector Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + if (RetAttrs.hasAttributes()) + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::ReturnIndex, + RetAttrs)); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); - if (ArgList[i].Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); + Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); + } } - if (FuncAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs)); + if (FuncAttrs.hasAttributes()) + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::FunctionIndex, + FuncAttrs)); - AttrListPtr PAL = AttrListPtr::get(Attrs); + AttributeSet PAL = AttributeSet::get(Context, Attrs); - if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy()) + if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy()) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg); PointerType *PFT = PointerType::getUnqual(FT); - Fn = 0; + Fn = nullptr; if (!FunctionName.empty()) { // If this was a definition of a forward reference, remove the definition // from the forward reference table and fill in the forward ref. @@ -2752,10 +3158,13 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { ForwardRefVals.find(FunctionName); if (FRVI != ForwardRefVals.end()) { Fn = M->getFunction(FunctionName); + if (!Fn) + return Error(FRVI->second.second, "invalid forward reference to " + "function as global value!"); if (Fn->getType() != PFT) return Error(FRVI->second.second, "invalid forward reference to " "function '" + FunctionName + "' with wrong type!"); - + ForwardRefVals.erase(FRVI); } else if ((Fn = M->getFunction(FunctionName))) { // Reject redefinitions. @@ -2779,7 +3188,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { } } - if (Fn == 0) + if (!Fn) Fn = Function::Create(FT, GlobalValue::ExternalLinkage, FunctionName, M); else // Move the forward-reference to the correct spot in the module. M->getFunctionList().splice(M->end(), M->getFunctionList(), Fn); @@ -2789,12 +3198,15 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); + Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); Fn->setCallingConv(CC); Fn->setAttributes(PAL); Fn->setUnnamedAddr(UnnamedAddr); Fn->setAlignment(Alignment); Fn->setSection(Section); if (!GC.empty()) Fn->setGC(GC.c_str()); + Fn->setPrefixData(Prefix); + ForwardRefAttrGroups[Fn] = FwdRefAttrGrps; // Add all of the arguments we parsed to the function. Function::arg_iterator ArgIt = Fn->arg_begin(); @@ -2824,13 +3236,13 @@ bool LLParser::ParseFunctionBody(Function &Fn) { int FunctionNumber = -1; if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1; - + PerFunctionState PFS(*this, Fn, FunctionNumber); // We need at least one basic block. if (Lex.getKind() == lltok::rbrace) return TokError("function body requires at least one basic block"); - + while (Lex.getKind() != lltok::rbrace) if (ParseBasicBlock(PFS)) return true; @@ -2853,13 +3265,12 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { } BasicBlock *BB = PFS.DefineBB(Name, NameLoc); - if (BB == 0) return true; + if (!BB) return true; std::string NameStr; // Parse the instructions in this block until we get a terminator. Instruction *Inst; - SmallVector, 4> MetadataOnInst; do { // This instruction may have three possibilities for a name: a) none // specified, b) name specified "%foo =", c) number specified: "%4 =". @@ -2898,7 +3309,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { // *must* be followed by metadata. if (ParseInstructionMetadata(Inst, &PFS)) return true; - break; + break; } // Set the name on the instruction. @@ -2941,16 +3352,26 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, bool NUW = EatIfPresent(lltok::kw_nuw); bool NSW = EatIfPresent(lltok::kw_nsw); if (!NUW) NUW = EatIfPresent(lltok::kw_nuw); - + if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true; - + if (NUW) cast(Inst)->setHasNoUnsignedWrap(true); if (NSW) cast(Inst)->setHasNoSignedWrap(true); return false; } case lltok::kw_fadd: case lltok::kw_fsub: - case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2); + case lltok::kw_fmul: + case lltok::kw_fdiv: + case lltok::kw_frem: { + FastMathFlags FMF = EatFastMathFlagsIfPresent(); + int Res = ParseArithmetic(Inst, PFS, KeywordVal, 2); + if (Res != 0) + return Res; + if (FMF.any()) + Inst->setFastMathFlags(FMF); + return 0; + } case lltok::kw_sdiv: case lltok::kw_udiv: @@ -2965,8 +3386,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_urem: case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1); - case lltok::kw_fdiv: - case lltok::kw_frem: return ParseArithmetic(Inst, PFS, KeywordVal, 2); case lltok::kw_and: case lltok::kw_or: case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal); @@ -2979,6 +3398,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_fptrunc: case lltok::kw_fpext: case lltok::kw_bitcast: + case lltok::kw_addrspacecast: case lltok::kw_uitofp: case lltok::kw_sitofp: case lltok::kw_fptoui: @@ -2993,8 +3413,10 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, 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); + // Call. + case lltok::kw_call: return ParseCall(Inst, PFS, CallInst::TCK_None); + case lltok::kw_tail: return ParseCall(Inst, PFS, CallInst::TCK_Tail); + case lltok::kw_musttail: return ParseCall(Inst, PFS, CallInst::TCK_MustTail); // Memory. case lltok::kw_alloca: return ParseAlloc(Inst, PFS); case lltok::kw_load: return ParseLoad(Inst, PFS); @@ -3012,7 +3434,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { if (Opc == Instruction::FCmp) { switch (Lex.getKind()) { - default: TokError("expected fcmp predicate (e.g. 'oeq')"); + default: return TokError("expected fcmp predicate (e.g. 'oeq')"); case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break; case lltok::kw_one: P = CmpInst::FCMP_ONE; break; case lltok::kw_olt: P = CmpInst::FCMP_OLT; break; @@ -3032,7 +3454,7 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { } } else { switch (Lex.getKind()) { - default: TokError("expected icmp predicate (e.g. 'eq')"); + default: return TokError("expected icmp predicate (e.g. 'eq')"); case lltok::kw_eq: P = CmpInst::ICMP_EQ; break; case lltok::kw_ne: P = CmpInst::ICMP_NE; break; case lltok::kw_slt: P = CmpInst::ICMP_SLT; break; @@ -3059,16 +3481,16 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS) { SMLoc TypeLoc = Lex.getLoc(); - Type *Ty = 0; + Type *Ty = nullptr; 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; } @@ -3079,7 +3501,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, if (ResType != RV->getType()) return Error(TypeLoc, "value doesn't match function result type '" + getTypeString(ResType) + "'"); - + Inst = ReturnInst::Create(Context, RV); return false; } @@ -3141,7 +3563,7 @@ bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) { ParseToken(lltok::comma, "expected ',' after case value") || ParseTypeAndBasicBlock(DestBB, PFS)) return true; - + if (!SeenCases.insert(Constant)) return Error(CondLoc, "duplicate case value in switch"); if (!isa(Constant)) @@ -3169,26 +3591,26 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { ParseToken(lltok::comma, "expected ',' after indirectbr address") || ParseToken(lltok::lsquare, "expected '[' with indirectbr")) return true; - + if (!Address->getType()->isPointerTy()) return Error(AddrLoc, "indirectbr address must have pointer type"); - + // Parse the destination list. SmallVector DestList; - + if (Lex.getKind() != lltok::rsquare) { BasicBlock *DestBB; if (ParseTypeAndBasicBlock(DestBB, PFS)) return true; DestList.push_back(DestBB); - + while (EatIfPresent(lltok::comma)) { if (ParseTypeAndBasicBlock(DestBB, PFS)) return true; DestList.push_back(DestBB); } } - + if (ParseToken(lltok::rsquare, "expected ']' at end of block list")) return true; @@ -3205,20 +3627,23 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { /// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy CallLoc = Lex.getLoc(); - Attributes RetAttrs, FnAttrs; + AttrBuilder RetAttrs, FnAttrs; + std::vector FwdRefAttrGrps; + LocTy NoBuiltinLoc; CallingConv::ID CC; - Type *RetType = 0; + Type *RetType = nullptr; LocTy RetTypeLoc; ValID CalleeID; SmallVector ArgList; BasicBlock *NormalBB, *UnwindBB; if (ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseOptionalAttrs(FnAttrs, 2) || + ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, + NoBuiltinLoc) || ParseToken(lltok::kw_to, "expected 'to' in invoke") || ParseTypeAndBasicBlock(NormalBB, PFS) || ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") || @@ -3228,8 +3653,8 @@ 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. - PointerType *PFTy = 0; - FunctionType *Ty = 0; + PointerType *PFTy = nullptr; + FunctionType *Ty = nullptr; if (!(PFTy = dyn_cast(RetType)) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... @@ -3248,10 +3673,12 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // Set up the Attributes for the function. - SmallVector Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + // Set up the Attribute for the function. + SmallVector Attrs; + if (RetAttrs.hasAttributes()) + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::ReturnIndex, + RetAttrs)); SmallVector Args; @@ -3260,7 +3687,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) { - Type *ExpectedTy = 0; + Type *ExpectedTy = nullptr; if (I != E) { ExpectedTy = *I++; } else if (!Ty->isVarArg()) { @@ -3271,22 +3698,27 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); + Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); + } } 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(AttributeSet::get(RetType->getContext(), + AttributeSet::FunctionIndex, + FnAttrs)); - // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs); + // Finish off the Attribute and check them + AttributeSet PAL = AttributeSet::get(Context, Attrs); InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); II->setCallingConv(CC); II->setAttributes(PAL); + ForwardRefAttrGroups[II] = FwdRefAttrGrps; Inst = II; return false; } @@ -3396,7 +3828,7 @@ bool LLParser::ParseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { LocTy Loc; Value *Op; - Type *DestTy = 0; + Type *DestTy = nullptr; if (ParseTypeAndValue(Op, Loc, PFS) || ParseToken(lltok::kw_to, "expected 'to' after cast value") || ParseType(DestTy)) @@ -3435,7 +3867,7 @@ bool LLParser::ParseSelect(Instruction *&Inst, PerFunctionState &PFS) { /// ::= 'va_arg' TypeAndValue ',' Type bool LLParser::ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS) { Value *Op; - Type *EltTy = 0; + Type *EltTy = nullptr; LocTy TypeLoc; if (ParseTypeAndValue(Op, PFS) || ParseToken(lltok::comma, "expected ',' after vaarg operand") || @@ -3507,7 +3939,7 @@ bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { /// ParsePHI /// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')* int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { - Type *Ty = 0; LocTy TypeLoc; + Type *Ty = nullptr; LocTy TypeLoc; Value *Op0, *Op1; if (ParseType(Ty, TypeLoc) || @@ -3556,7 +3988,7 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { /// ::= 'filter' /// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { - Type *Ty = 0; LocTy TyLoc; + Type *Ty = nullptr; LocTy TyLoc; Value *PersFn; LocTy PersFnLoc; if (ParseType(Ty, TyLoc) || @@ -3600,32 +4032,40 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { } /// ParseCall -/// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value +/// ::= 'call' OptionalCallingConv OptionalAttrs Type Value +/// ParameterList OptionalAttrs +/// ::= 'tail' 'call' OptionalCallingConv OptionalAttrs Type Value +/// ParameterList OptionalAttrs +/// ::= 'musttail' 'call' OptionalCallingConv OptionalAttrs Type Value /// ParameterList OptionalAttrs bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, - bool isTail) { - Attributes RetAttrs, FnAttrs; + CallInst::TailCallKind TCK) { + AttrBuilder RetAttrs, FnAttrs; + std::vector FwdRefAttrGrps; + LocTy BuiltinLoc; CallingConv::ID CC; - Type *RetType = 0; + Type *RetType = nullptr; LocTy RetTypeLoc; ValID CalleeID; SmallVector ArgList; LocTy CallLoc = Lex.getLoc(); - if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) || + if ((TCK != CallInst::TCK_None && + ParseToken(lltok::kw_call, "expected 'tail call'")) || ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseOptionalAttrs(FnAttrs, 2)) + ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, + BuiltinLoc)) return true; // 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. - PointerType *PFTy = 0; - FunctionType *Ty = 0; + PointerType *PFTy = nullptr; + FunctionType *Ty = nullptr; if (!(PFTy = dyn_cast(RetType)) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... @@ -3644,10 +4084,12 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // Set up the Attributes for the function. - SmallVector Attrs; - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + // Set up the Attribute for the function. + SmallVector Attrs; + if (RetAttrs.hasAttributes()) + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::ReturnIndex, + RetAttrs)); SmallVector Args; @@ -3656,7 +4098,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) { - Type *ExpectedTy = 0; + Type *ExpectedTy = nullptr; if (I != E) { ExpectedTy = *I++; } else if (!Ty->isVarArg()) { @@ -3667,23 +4109,28 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); + Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); + } } 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(AttributeSet::get(RetType->getContext(), + AttributeSet::FunctionIndex, + FnAttrs)); - // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs); + // Finish off the Attribute and check them + AttributeSet PAL = AttributeSet::get(Context, Attrs); CallInst *CI = CallInst::Create(Callee, Args); - CI->setTailCall(isTail); + CI->setTailCallKind(TCK); CI->setCallingConv(CC); CI->setAttributes(PAL); + ForwardRefAttrGroups[CI] = FwdRefAttrGrps; Inst = CI; return false; } @@ -3693,12 +4140,15 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, //===----------------------------------------------------------------------===// /// ParseAlloc -/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)? +/// ::= 'alloca' 'inalloca'? Type (',' TypeAndValue)? (',' 'align' i32)? int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { - Value *Size = 0; + Value *Size = nullptr; LocTy SizeLoc; unsigned Alignment = 0; - Type *Ty = 0; + Type *Ty = nullptr; + + bool IsInAlloca = EatIfPresent(lltok::kw_inalloca); + if (ParseType(Ty)) return true; bool AteExtraComma = false; @@ -3717,13 +4167,15 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - Inst = new AllocaInst(Ty, Size, Alignment); + AllocaInst *AI = new AllocaInst(Ty, Size, Alignment); + AI->setUsedWithInAlloca(IsInAlloca); + Inst = AI; return AteExtraComma ? InstExtraComma : InstNormal; } /// ParseLoad /// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)? -/// ::= 'load' 'atomic' 'volatile'? TypeAndValue +/// ::= 'load' 'atomic' 'volatile'? TypeAndValue /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { Value *Val; LocTy Loc; @@ -3809,11 +4261,12 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) { /// ParseCmpXchg /// ::= 'cmpxchg' 'volatile'? TypeAndValue ',' TypeAndValue ',' TypeAndValue -/// 'singlethread'? AtomicOrdering +/// 'singlethread'? AtomicOrdering AtomicOrdering int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc; bool AteExtraComma = false; - AtomicOrdering Ordering = NotAtomic; + AtomicOrdering SuccessOrdering = NotAtomic; + AtomicOrdering FailureOrdering = NotAtomic; SynchronizationScope Scope = CrossThread; bool isVolatile = false; @@ -3825,11 +4278,16 @@ int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndValue(Cmp, CmpLoc, PFS) || ParseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") || ParseTypeAndValue(New, NewLoc, PFS) || - ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering)) + ParseScopeAndOrdering(true /*Always atomic*/, Scope, SuccessOrdering) || + ParseOrdering(FailureOrdering)) return true; - if (Ordering == Unordered) + if (SuccessOrdering == Unordered || FailureOrdering == Unordered) return TokError("cmpxchg cannot be unordered"); + if (SuccessOrdering < FailureOrdering) + return TokError("cmpxchg must be at least as ordered on success as failure"); + if (FailureOrdering == Release || FailureOrdering == AcquireRelease) + return TokError("cmpxchg failure ordering cannot include release semantics"); if (!Ptr->getType()->isPointerTy()) return Error(PtrLoc, "cmpxchg operand must be a pointer"); if (cast(Ptr->getType())->getElementType() != Cmp->getType()) @@ -3843,8 +4301,8 @@ int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { return Error(NewLoc, "cmpxchg operand must be power-of-two byte-sized" " integer"); - AtomicCmpXchgInst *CXI = - new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, Scope); + AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, + FailureOrdering, Scope); CXI->setVolatile(isVolatile); Inst = CXI; return AteExtraComma ? InstExtraComma : InstNormal; @@ -3926,15 +4384,17 @@ int LLParser::ParseFence(Instruction *&Inst, PerFunctionState &PFS) { /// ParseGetElementPtr /// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)* int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { - Value *Ptr = 0; - Value *Val = 0; + Value *Ptr = nullptr; + Value *Val = nullptr; LocTy Loc, EltLoc; bool InBounds = EatIfPresent(lltok::kw_inbounds); if (ParseTypeAndValue(Ptr, Loc, PFS)) return true; - if (!Ptr->getType()->getScalarType()->isPointerTy()) + Type *BaseType = Ptr->getType(); + PointerType *BasePointerType = dyn_cast(BaseType->getScalarType()); + if (!BasePointerType) return Error(Loc, "base of getelementptr must be a pointer"); SmallVector Indices; @@ -3959,10 +4419,10 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.push_back(Val); } - if (Val && Val->getType()->isVectorTy() && Indices.size() != 1) - return Error(EltLoc, "vector getelementptrs must have a single index"); + if (!Indices.empty() && !BasePointerType->getElementType()->isSized()) + return Error(Loc, "base element of getelementptr must be sized"); - if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices)) + if (!GetElementPtrInst::getIndexedType(BaseType, Indices)) return Error(Loc, "invalid getelementptr indices"); Inst = GetElementPtrInst::Create(Ptr, Indices); if (InBounds) @@ -4000,7 +4460,7 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndValue(Val1, Loc1, PFS) || ParseIndexList(Indices, AteExtraComma)) return true; - + if (!Val0->getType()->isAggregateType()) return Error(Loc0, "insertvalue operand must be aggregate type"); @@ -4027,11 +4487,11 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, do { // Null is a special case since it is typeless. if (EatIfPresent(lltok::kw_null)) { - Elts.push_back(0); + Elts.push_back(nullptr); continue; } - - Value *V = 0; + + Value *V = nullptr; if (ParseTypeAndValue(V, PFS)) return true; Elts.push_back(V); } while (EatIfPresent(lltok::comma));