diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index aa0344fc1f9..2c2860dad8d 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5254,15 +5254,52 @@ bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { return true; } + enum { + COFF = (1 << MCObjectFileInfo::IsCOFF), + ELF = (1 << MCObjectFileInfo::IsELF), + MACHO = (1 << MCObjectFileInfo::IsMachO) + }; + static const struct PrefixEntry { + const char *Spelling; + ARMMCExpr::VariantKind VariantKind; + uint8_t SupportedFormats; + } PrefixEntries[] = { + { "lower16", ARMMCExpr::VK_ARM_LO16, COFF | ELF | MACHO }, + { "upper16", ARMMCExpr::VK_ARM_HI16, COFF | ELF | MACHO }, + }; + StringRef IDVal = Parser.getTok().getIdentifier(); - if (IDVal == "lower16") { - RefKind = ARMMCExpr::VK_ARM_LO16; - } else if (IDVal == "upper16") { - RefKind = ARMMCExpr::VK_ARM_HI16; - } else { + + const auto &Prefix = + std::find_if(std::begin(PrefixEntries), std::end(PrefixEntries), + [&IDVal](const PrefixEntry &PE) { + return PE.Spelling == IDVal; + }); + if (Prefix == std::end(PrefixEntries)) { Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); return true; } + + uint8_t CurrentFormat; + switch (getContext().getObjectFileInfo()->getObjectFileType()) { + case MCObjectFileInfo::IsMachO: + CurrentFormat = MACHO; + break; + case MCObjectFileInfo::IsELF: + CurrentFormat = ELF; + break; + case MCObjectFileInfo::IsCOFF: + CurrentFormat = COFF; + break; + } + + if (~Prefix->SupportedFormats & CurrentFormat) { + Error(Parser.getTok().getLoc(), + "cannot represent relocation in the current file format"); + return true; + } + + RefKind = Prefix->VariantKind; Parser.Lex(); if (getLexer().isNot(AsmToken::Colon)) { @@ -5270,6 +5307,7 @@ bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { return true; } Parser.Lex(); // Eat the last ':' + return false; } |