summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r--gnu/llvm/lib/AsmParser/LLParser.cpp157
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;
+ }
+ }
}
}