diff options
Diffstat (limited to 'gnu/llvm/lib/AsmParser/LLParser.cpp')
| -rw-r--r-- | gnu/llvm/lib/AsmParser/LLParser.cpp | 157 |
1 files changed, 115 insertions, 42 deletions
diff --git a/gnu/llvm/lib/AsmParser/LLParser.cpp b/gnu/llvm/lib/AsmParser/LLParser.cpp index 234805a0524..c3ab95550e0 100644 --- a/gnu/llvm/lib/AsmParser/LLParser.cpp +++ b/gnu/llvm/lib/AsmParser/LLParser.cpp @@ -237,7 +237,8 @@ bool LLParser::ValidateEndOfModule() { } } - UpgradeDebugInfo(*M); + if (UpgradeDebugInfo) + llvm::UpgradeDebugInfo(*M); UpgradeModuleFlags(*M); UpgradeSectionAttributes(*M); @@ -482,10 +483,12 @@ bool LLParser::ParseOptionalUnnamedAddr( /// ParseUnnamedGlobal: /// OptionalVisibility (ALIAS | IFUNC) ... -/// OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility +/// OptionalDLLStorageClass /// ... -> global variable /// GlobalID '=' OptionalVisibility (ALIAS | IFUNC) ... -/// GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// GlobalID '=' OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility +/// OptionalDLLStorageClass /// ... -> global variable bool LLParser::ParseUnnamedGlobal() { unsigned VarID = NumberedVals.size(); @@ -505,23 +508,26 @@ bool LLParser::ParseUnnamedGlobal() { bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; + bool DSOLocal; GlobalVariable::ThreadLocalMode TLM; GlobalVariable::UnnamedAddr UnnamedAddr; - if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || + if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass, + DSOLocal) || ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr)) return true; if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLStorageClass, DSOLocal, TLM, UnnamedAddr); return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLStorageClass, DSOLocal, TLM, UnnamedAddr); } /// ParseNamedGlobal: /// GlobalVar '=' OptionalVisibility (ALIAS | IFUNC) ... -/// GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier +/// OptionalVisibility OptionalDLLStorageClass /// ... -> global variable bool LLParser::ParseNamedGlobal() { assert(Lex.getKind() == lltok::GlobalVar); @@ -531,19 +537,21 @@ bool LLParser::ParseNamedGlobal() { bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; + bool DSOLocal; GlobalVariable::ThreadLocalMode TLM; GlobalVariable::UnnamedAddr UnnamedAddr; if (ParseToken(lltok::equal, "expected '=' in global variable") || - ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || + ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass, + DSOLocal) || ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr)) return true; if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLStorageClass, DSOLocal, TLM, UnnamedAddr); return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLStorageClass, DSOLocal, TLM, UnnamedAddr); } bool LLParser::parseComdat() { @@ -644,11 +652,18 @@ bool LLParser::ParseNamedMetadata() { NamedMDNode *NMD = M->getOrInsertNamedMetadata(Name); if (Lex.getKind() != lltok::rbrace) do { - if (ParseToken(lltok::exclaim, "Expected '!' here")) - return true; - MDNode *N = nullptr; - if (ParseMDNodeID(N)) return true; + // Parse DIExpressions inline as a special case. They are still MDNodes, + // so they can still appear in named metadata. Remove this logic if they + // become plain Metadata. + if (Lex.getKind() == lltok::MetadataVar && + Lex.getStrVal() == "DIExpression") { + if (ParseDIExpression(N, /*IsDistinct=*/false)) + return true; + } else if (ParseToken(lltok::exclaim, "Expected '!' here") || + ParseMDNodeID(N)) { + return true; + } NMD->addOperand(N); } while (EatIfPresent(lltok::comma)); @@ -701,19 +716,21 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { } /// parseIndirectSymbol: -/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility -/// OptionalDLLStorageClass OptionalThreadLocal -/// OptionalUnnamedAddr 'alias|ifunc' IndirectSymbol +/// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier +/// OptionalVisibility OptionalDLLStorageClass +/// OptionalThreadLocal OptionalUnnamedAddr +// 'alias|ifunc' IndirectSymbol /// /// IndirectSymbol /// ::= TypeAndValue /// /// Everything through OptionalUnnamedAddr has already been parsed. /// -bool LLParser::parseIndirectSymbol( - const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility, - unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM, - GlobalVariable::UnnamedAddr UnnamedAddr) { +bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc, + unsigned L, unsigned Visibility, + unsigned DLLStorageClass, bool DSOLocal, + GlobalVariable::ThreadLocalMode TLM, + GlobalVariable::UnnamedAddr UnnamedAddr) { bool IsAlias; if (Lex.getKind() == lltok::kw_alias) IsAlias = true; @@ -732,6 +749,11 @@ bool LLParser::parseIndirectSymbol( return Error(NameLoc, "symbol with local linkage must have default visibility"); + if (DSOLocal && !IsAlias) { + return Error(NameLoc, + "dso_local is invalid on ifunc"); + } + Type *Ty; LocTy ExplicitTypeLoc = Lex.getLoc(); if (ParseType(Ty) || @@ -804,6 +826,7 @@ bool LLParser::parseIndirectSymbol( GA->setVisibility((GlobalValue::VisibilityTypes)Visibility); GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); GA->setUnnamedAddr(UnnamedAddr); + GA->setDSOLocal(DSOLocal); if (Name.empty()) NumberedVals.push_back(GA.get()); @@ -835,12 +858,14 @@ bool LLParser::parseIndirectSymbol( } /// ParseGlobal -/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace -/// OptionalExternallyInitialized GlobalType Type Const OptionalAttrs -/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass +/// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier +/// OptionalVisibility OptionalDLLStorageClass /// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const OptionalAttrs +/// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility +/// OptionalDLLStorageClass OptionalThreadLocal OptionalUnnamedAddr +/// OptionalAddrSpace OptionalExternallyInitialized GlobalType Type +/// Const OptionalAttrs /// /// Everything up to and including OptionalUnnamedAddr has been parsed /// already. @@ -848,7 +873,7 @@ bool LLParser::parseIndirectSymbol( bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility, unsigned DLLStorageClass, - GlobalVariable::ThreadLocalMode TLM, + bool DSOLocal, GlobalVariable::ThreadLocalMode TLM, GlobalVariable::UnnamedAddr UnnamedAddr) { if (!isValidVisibilityForLinkage(Visibility, Linkage)) return Error(NameLoc, @@ -922,6 +947,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GV->setInitializer(Init); GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); + GV->setDSOLocal(DSOLocal); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); GV->setExternallyInitialized(IsExternallyInitialized); @@ -1118,10 +1144,13 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break; case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break; + case lltok::kw_sanitize_hwaddress: + B.addAttribute(Attribute::SanitizeHWAddress); break; case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break; case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break; + case lltok::kw_strictfp: B.addAttribute(Attribute::StrictFP); break; case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break; @@ -1441,12 +1470,14 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_optsize: case lltok::kw_returns_twice: case lltok::kw_sanitize_address: + case lltok::kw_sanitize_hwaddress: 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_safestack: + case lltok::kw_strictfp: case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; @@ -1532,12 +1563,14 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_optsize: case lltok::kw_returns_twice: case lltok::kw_sanitize_address: + case lltok::kw_sanitize_hwaddress: 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_safestack: + case lltok::kw_strictfp: case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; @@ -1597,15 +1630,38 @@ static unsigned parseOptionalLinkageAux(lltok::Kind Kind, bool &HasLinkage) { /// ::= 'external' bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage, unsigned &Visibility, - unsigned &DLLStorageClass) { + unsigned &DLLStorageClass, + bool &DSOLocal) { Res = parseOptionalLinkageAux(Lex.getKind(), HasLinkage); if (HasLinkage) Lex.Lex(); + ParseOptionalDSOLocal(DSOLocal); ParseOptionalVisibility(Visibility); ParseOptionalDLLStorageClass(DLLStorageClass); + + if (DSOLocal && DLLStorageClass == GlobalValue::DLLImportStorageClass) { + return Error(Lex.getLoc(), "dso_location and DLL-StorageClass mismatch"); + } + return false; } +void LLParser::ParseOptionalDSOLocal(bool &DSOLocal) { + switch (Lex.getKind()) { + default: + DSOLocal = false; + break; + case lltok::kw_dso_local: + DSOLocal = true; + Lex.Lex(); + break; + case lltok::kw_dso_preemptable: + DSOLocal = false; + Lex.Lex(); + break; + } +} + /// ParseOptionalVisibility /// ::= /*empty*/ /// ::= 'default' @@ -1683,7 +1739,9 @@ void LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'hhvm_ccc' /// ::= 'cxx_fast_tlscc' /// ::= 'amdgpu_vs' +/// ::= 'amdgpu_ls' /// ::= 'amdgpu_hs' +/// ::= 'amdgpu_es' /// ::= 'amdgpu_gs' /// ::= 'amdgpu_ps' /// ::= 'amdgpu_cs' @@ -1725,7 +1783,9 @@ bool LLParser::ParseOptionalCallingConv(unsigned &CC) { case lltok::kw_hhvm_ccc: CC = CallingConv::HHVM_C; break; case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break; case lltok::kw_amdgpu_vs: CC = CallingConv::AMDGPU_VS; break; + case lltok::kw_amdgpu_ls: CC = CallingConv::AMDGPU_LS; break; case lltok::kw_amdgpu_hs: CC = CallingConv::AMDGPU_HS; break; + case lltok::kw_amdgpu_es: CC = CallingConv::AMDGPU_ES; break; case lltok::kw_amdgpu_gs: CC = CallingConv::AMDGPU_GS; break; case lltok::kw_amdgpu_ps: CC = CallingConv::AMDGPU_PS; break; case lltok::kw_amdgpu_cs: CC = CallingConv::AMDGPU_CS; break; @@ -4090,7 +4150,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(macros, MDField, ); \ OPTIONAL(dwoId, MDUnsignedField, ); \ OPTIONAL(splitDebugInlining, MDBoolField, = true); \ - OPTIONAL(debugInfoForProfiling, MDBoolField, = false); + OPTIONAL(debugInfoForProfiling, MDBoolField, = false); \ + OPTIONAL(gnuPubnames, MDBoolField, = false); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4098,7 +4159,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, - splitDebugInlining.Val, debugInfoForProfiling.Val); + splitDebugInlining.Val, debugInfoForProfiling.Val, gnuPubnames.Val); return false; } @@ -4374,7 +4435,7 @@ bool LLParser::ParseDIGlobalVariableExpression(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(var, MDField, ); \ - OPTIONAL(expr, MDField, ); + REQUIRED(expr, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4683,22 +4744,24 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, } /// FunctionHeader -/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs -/// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection -/// OptionalAlign OptGC OptionalPrefix OptionalPrologue OptPersonalityFn +/// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility +/// OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName +/// '(' ArgList ')' OptFuncAttrs OptSection OptionalAlign OptGC +/// OptionalPrefix OptionalPrologue OptPersonalityFn bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Parse the linkage. LocTy LinkageLoc = Lex.getLoc(); unsigned Linkage; - unsigned Visibility; unsigned DLLStorageClass; + bool DSOLocal; AttrBuilder RetAttrs; unsigned CC; bool HasLinkage; Type *RetType = nullptr; LocTy RetTypeLoc = Lex.getLoc(); - if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || + if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass, + DSOLocal) || ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/)) return true; @@ -4762,7 +4825,6 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { unsigned Alignment; std::string GC; GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; - LocTy UnnamedAddrLoc; Constant *Prefix = nullptr; Constant *Prologue = nullptr; Constant *PersonalityFn = nullptr; @@ -4861,6 +4923,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { NumberedVals.push_back(Fn); Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); + Fn->setDSOLocal(DSOLocal); Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); Fn->setCallingConv(CC); @@ -5556,7 +5619,6 @@ bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { /// ::= 'catchswitch' within Parent bool LLParser::ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) { Value *ParentPad; - LocTy BBLoc; if (ParseToken(lltok::kw_within, "expected 'within' after catchswitch")) return true; @@ -6060,7 +6122,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, /// ParseAlloc /// ::= 'alloca' 'inalloca'? 'swifterror'? Type (',' TypeAndValue)? -/// (',' 'align' i32)? +/// (',' 'align' i32)? (',', 'addrspace(n))? int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { Value *Size = nullptr; LocTy SizeLoc, TyLoc, ASLoc; @@ -6090,11 +6152,22 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { } else if (Lex.getKind() == lltok::MetadataVar) { AteExtraComma = true; } else { - if (ParseTypeAndValue(Size, SizeLoc, PFS) || - ParseOptionalCommaAlign(Alignment, AteExtraComma) || - (!AteExtraComma && - ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))) + if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true; + if (EatIfPresent(lltok::comma)) { + if (Lex.getKind() == lltok::kw_align) { + if (ParseOptionalAlignment(Alignment)) + return true; + if (ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma)) + return true; + } else if (Lex.getKind() == lltok::kw_addrspace) { + ASLoc = Lex.getLoc(); + if (ParseOptionalAddrSpace(AddrSpace)) + return true; + } else if (Lex.getKind() == lltok::MetadataVar) { + AteExtraComma = true; + } + } } } |
