[llvm] 98a640a - [MC] Move VariantKind info to MCAsmInfo

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 2 20:36:25 PST 2025


Author: Fangrui Song
Date: 2025-03-02T20:36:20-08:00
New Revision: 98a640a2faf4d5557e3a949dd87a01ba900745d6

URL: https://github.com/llvm/llvm-project/commit/98a640a2faf4d5557e3a949dd87a01ba900745d6
DIFF: https://github.com/llvm/llvm-project/commit/98a640a2faf4d5557e3a949dd87a01ba900745d6.diff

LOG: [MC] Move VariantKind info to MCAsmInfo

Follow-up to 14951a5a3120e50084b3c5fb217e2d47992a24d1

* Unify getVariantKindName and getVariantKindForName
* Allow each target to specify the preferred case (albeit ignored in MCParser)

Note: targets that use variant kinds should call MCExpr::print with a
non-null MAI to print variant kinds. operator<< passes a nullptr to
`MCExpr::print`, which should be avoided (e.g. Hexagon; fixed in
commit cf00ac81ac049cddb80aec1d6d88b8fab4f209e8).

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCAsmInfo.h
    llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
    llvm/lib/MC/MCAsmInfo.cpp
    llvm/lib/MC/MCExpr.cpp
    llvm/lib/MC/MCParser/AsmParser.cpp
    llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
    llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
    llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
    llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
    llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp
    llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
    llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
    llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
    llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
    llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
    llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
    llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
    llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
    llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
    llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h
index 5ae28b22b1ebb..aba8eaed82d1a 100644
--- a/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/llvm/include/llvm/MC/MCAsmInfo.h
@@ -15,6 +15,8 @@
 #ifndef LLVM_MC_MCASMINFO_H
 #define LLVM_MC_MCASMINFO_H
 
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/MC/MCDirectives.h"
 #include "llvm/MC/MCTargetOptions.h"
@@ -63,6 +65,11 @@ class MCAsmInfo {
                             /// quote, e.g., `'A`.
   };
 
+  struct VariantKindDesc {
+    uint32_t Kind;
+    StringRef Name;
+  };
+
 protected:
   //===------------------------------------------------------------------===//
   // Properties to be set by the target writer, used to configure asm printer.
@@ -417,6 +424,10 @@ class MCAsmInfo {
   // If true, use Motorola-style integers in Assembly (ex. $0ac).
   bool UseMotorolaIntegers = false;
 
+  llvm::DenseMap<uint32_t, StringRef> VariantKindToName;
+  llvm::StringMap<uint32_t> NameToVariantKind;
+  void initializeVariantKinds(ArrayRef<VariantKindDesc> Descs);
+
 public:
   explicit MCAsmInfo();
   virtual ~MCAsmInfo();
@@ -696,6 +707,9 @@ class MCAsmInfo {
   bool shouldUseLogicalShr() const { return UseLogicalShr; }
 
   bool shouldUseMotorolaIntegers() const { return UseMotorolaIntegers; }
+
+  StringRef getVariantKindName(uint32_t Kind) const;
+  uint32_t getVariantKindForName(StringRef Name) const;
 };
 
 } // end namespace llvm

diff  --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
index e84484aa17a4c..536c7a42bab59 100644
--- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -505,10 +505,6 @@ class MCTargetAsmParser : public MCAsmParserExtension {
   // Return whether this parser accept star as start of statement
   virtual bool starIsStartOfStatement() { return false; };
 
-  virtual MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const {
-    return MCSymbolRefExpr::getVariantKindForName(Name);
-  }
   virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
                                             MCSymbolRefExpr::VariantKind,
                                             MCContext &Ctx) {

diff  --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp
index 2cb0bf044ee96..2ad411d200a17 100644
--- a/llvm/lib/MC/MCAsmInfo.cpp
+++ b/llvm/lib/MC/MCAsmInfo.cpp
@@ -124,3 +124,33 @@ bool MCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {
   return SectionName == ".text" || SectionName == ".data" ||
         (SectionName == ".bss" && !usesELFSectionDirectiveForBSS());
 }
+
+void MCAsmInfo::initializeVariantKinds(ArrayRef<VariantKindDesc> Descs) {
+  assert(VariantKindToName.empty() && "cannot initialize twice");
+  for (auto Desc : Descs) {
+    [[maybe_unused]] auto It =
+        VariantKindToName.try_emplace(Desc.Kind, Desc.Name);
+    assert(It.second && "duplicate Kind");
+    [[maybe_unused]] auto It2 =
+        NameToVariantKind.try_emplace(Desc.Name.lower(), Desc.Kind);
+    // Workaround for VK_PPC_L/VK_PPC_LO ("l"), VK_PPC_TLSGD, and VK_PPC_TLSLD.
+    assert(It2.second ||
+           (Desc.Name == "l" || Desc.Name == "tlsgd" || Desc.Name == "tlsld"));
+  }
+}
+
+StringRef MCAsmInfo::getVariantKindName(uint32_t Kind) const {
+  if (!VariantKindToName.empty())
+    return VariantKindToName.find(Kind)->second;
+  return MCSymbolRefExpr::getVariantKindName(
+      MCSymbolRefExpr::VariantKind(Kind));
+}
+
+uint32_t MCAsmInfo::getVariantKindForName(StringRef Name) const {
+  if (NameToVariantKind.empty())
+    return MCSymbolRefExpr::getVariantKindForName(Name);
+  auto It = NameToVariantKind.find(Name.lower());
+  if (It != NameToVariantKind.end())
+    return It->second;
+  return MCSymbolRefExpr::VK_Invalid;
+}

diff  --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 9999a80a43a20..2cbb26cb1caf5 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -87,7 +87,9 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
     const MCSymbolRefExpr::VariantKind Kind = SRE.getKind();
     if (Kind != MCSymbolRefExpr::VK_None) {
       if (MAI && MAI->useParensForSymbolVariant()) // ARM
-        OS << '(' << MCSymbolRefExpr::getVariantKindName(Kind) << ')';
+        OS << '(' << MAI->getVariantKindName(Kind) << ')';
+      else if (MAI)
+        OS << '@' << MAI->getVariantKindName(Kind);
       else
         OS << '@' << MCSymbolRefExpr::getVariantKindName(Kind);
     }
@@ -246,11 +248,11 @@ const MCSymbolRefExpr *MCSymbolRefExpr::create(StringRef Name, VariantKind Kind,
   return create(Ctx.getOrCreateSymbol(Name), Kind, Ctx);
 }
 
-// TODO: Move target-specific Kinds to lib/Target/.
+// TODO: Move target-specific Kinds to lib/Target/*/MCTargetDesc/*AsmInfo.cpp.
 StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
   switch (Kind) {
     // clang-format off
-  case VK_Invalid: return "<<invalid>>";
+  case VK_Invalid: default: return "<<invalid>>";
   case VK_None: return "<<none>>";
 
   case VK_DTPOFF: return "DTPOFF";
@@ -261,18 +263,14 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
   case VK_GOTREL: return "GOTREL";
   case VK_PCREL: return "PCREL";
   case VK_GOTPCREL: return "GOTPCREL";
-  case VK_GOTPCREL_NORELAX: return "GOTPCREL_NORELAX";
   case VK_GOTTPOFF: return "GOTTPOFF";
-  case VK_GOTTPOFF_FDPIC: return "gottpoff_fdpic";
   case VK_INDNTPOFF: return "INDNTPOFF";
   case VK_NTPOFF: return "NTPOFF";
   case VK_GOTNTPOFF: return "GOTNTPOFF";
   case VK_PLT: return "PLT";
   case VK_TLSGD: return "TLSGD";
-  case VK_TLSGD_FDPIC: return "tlsgd_fdpic";
   case VK_TLSLD: return "TLSLD";
   case VK_TLSLDM: return "TLSLDM";
-  case VK_TLSLDM_FDPIC: return "tlsldm_fdpic";
   case VK_TPOFF: return "TPOFF";
   case VK_TPREL: return "TPREL";
   case VK_TLSCALL: return "tlscall";
@@ -285,148 +283,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
   case VK_GOTPAGE: return "GOTPAGE";
   case VK_GOTPAGEOFF: return "GOTPAGEOFF";
   case VK_SECREL: return "SECREL32";
-  case VK_SIZE: return "SIZE";
   case VK_WEAKREF: return "WEAKREF";
-  case VK_FUNCDESC: return "FUNCDESC";
-  case VK_GOTFUNCDESC: return "GOTFUNCDESC";
-  case VK_GOTOFFFUNCDESC: return "GOTOFFFUNCDESC";
-  case VK_X86_ABS8: return "ABS8";
-  case VK_X86_PLTOFF: return "PLTOFF";
-  case VK_ARM_NONE: return "none";
-  case VK_ARM_GOT_PREL: return "GOT_PREL";
-  case VK_ARM_TARGET1: return "target1";
-  case VK_ARM_TARGET2: return "target2";
-  case VK_ARM_PREL31: return "prel31";
-  case VK_ARM_SBREL: return "sbrel";
-  case VK_ARM_TLSLDO: return "tlsldo";
-  case VK_ARM_TLSDESCSEQ: return "tlsdescseq";
-  case VK_AVR_NONE: return "none";
-  case VK_AVR_LO8: return "lo8";
-  case VK_AVR_HI8: return "hi8";
-  case VK_AVR_HLO8: return "hlo8";
-  case VK_AVR_DIFF8: return "
diff 8";
-  case VK_AVR_DIFF16: return "
diff 16";
-  case VK_AVR_DIFF32: return "
diff 32";
-  case VK_AVR_PM: return "pm";
-  case VK_PPC_LO: return "l";
-  case VK_PPC_HI: return "h";
-  case VK_PPC_HA: return "ha";
-  case VK_PPC_HIGH: return "high";
-  case VK_PPC_HIGHA: return "higha";
-  case VK_PPC_HIGHER: return "higher";
-  case VK_PPC_HIGHERA: return "highera";
-  case VK_PPC_HIGHEST: return "highest";
-  case VK_PPC_HIGHESTA: return "highesta";
-  case VK_PPC_GOT_LO: return "got at l";
-  case VK_PPC_GOT_HI: return "got at h";
-  case VK_PPC_GOT_HA: return "got at ha";
-  case VK_PPC_TOCBASE: return "tocbase";
-  case VK_PPC_TOC: return "toc";
-  case VK_PPC_TOC_LO: return "toc at l";
-  case VK_PPC_TOC_HI: return "toc at h";
-  case VK_PPC_TOC_HA: return "toc at ha";
-  case VK_PPC_U: return "u";
-  case VK_PPC_L: return "l";
-  case VK_PPC_DTPMOD: return "dtpmod";
-  case VK_PPC_TPREL_LO: return "tprel at l";
-  case VK_PPC_TPREL_HI: return "tprel at h";
-  case VK_PPC_TPREL_HA: return "tprel at ha";
-  case VK_PPC_TPREL_HIGH: return "tprel at high";
-  case VK_PPC_TPREL_HIGHA: return "tprel at higha";
-  case VK_PPC_TPREL_HIGHER: return "tprel at higher";
-  case VK_PPC_TPREL_HIGHERA: return "tprel at highera";
-  case VK_PPC_TPREL_HIGHEST: return "tprel at highest";
-  case VK_PPC_TPREL_HIGHESTA: return "tprel at highesta";
-  case VK_PPC_DTPREL_LO: return "dtprel at l";
-  case VK_PPC_DTPREL_HI: return "dtprel at h";
-  case VK_PPC_DTPREL_HA: return "dtprel at ha";
-  case VK_PPC_DTPREL_HIGH: return "dtprel at high";
-  case VK_PPC_DTPREL_HIGHA: return "dtprel at higha";
-  case VK_PPC_DTPREL_HIGHER: return "dtprel at higher";
-  case VK_PPC_DTPREL_HIGHERA: return "dtprel at highera";
-  case VK_PPC_DTPREL_HIGHEST: return "dtprel at highest";
-  case VK_PPC_DTPREL_HIGHESTA: return "dtprel at highesta";
-  case VK_PPC_GOT_TPREL: return "got at tprel";
-  case VK_PPC_GOT_TPREL_LO: return "got at tprel@l";
-  case VK_PPC_GOT_TPREL_HI: return "got at tprel@h";
-  case VK_PPC_GOT_TPREL_HA: return "got at tprel@ha";
-  case VK_PPC_GOT_DTPREL: return "got at dtprel";
-  case VK_PPC_GOT_DTPREL_LO: return "got at dtprel@l";
-  case VK_PPC_GOT_DTPREL_HI: return "got at dtprel@h";
-  case VK_PPC_GOT_DTPREL_HA: return "got at dtprel@ha";
-  case VK_PPC_TLS: return "tls";
-  case VK_PPC_GOT_TLSGD: return "got at tlsgd";
-  case VK_PPC_GOT_TLSGD_LO: return "got at tlsgd@l";
-  case VK_PPC_GOT_TLSGD_HI: return "got at tlsgd@h";
-  case VK_PPC_GOT_TLSGD_HA: return "got at tlsgd@ha";
-  case VK_PPC_TLSGD: return "tlsgd";
-  case VK_PPC_AIX_TLSGD:
-    return "gd";
-  case VK_PPC_AIX_TLSGDM:
-    return "m";
-  case VK_PPC_AIX_TLSIE:
-    return "ie";
-  case VK_PPC_AIX_TLSLE:
-    return "le";
-  case VK_PPC_AIX_TLSLD:
-    return "ld";
-  case VK_PPC_AIX_TLSML:
-    return "ml";
-  case VK_PPC_GOT_TLSLD: return "got at tlsld";
-  case VK_PPC_GOT_TLSLD_LO: return "got at tlsld@l";
-  case VK_PPC_GOT_TLSLD_HI: return "got at tlsld@h";
-  case VK_PPC_GOT_TLSLD_HA: return "got at tlsld@ha";
-  case VK_PPC_GOT_PCREL:
-    return "got at pcrel";
-  case VK_PPC_GOT_TLSGD_PCREL:
-    return "got at tlsgd@pcrel";
-  case VK_PPC_GOT_TLSLD_PCREL:
-    return "got at tlsld@pcrel";
-  case VK_PPC_GOT_TPREL_PCREL:
-    return "got at tprel@pcrel";
-  case VK_PPC_TLS_PCREL:
-    return "tls at pcrel";
-  case VK_PPC_TLSLD: return "tlsld";
-  case VK_PPC_LOCAL: return "local";
-  case VK_PPC_NOTOC: return "notoc";
-  case VK_PPC_PCREL_OPT: return "<<invalid>>";
   case VK_COFF_IMGREL32: return "IMGREL";
-  case VK_Hexagon_LO16: return "LO16";
-  case VK_Hexagon_HI16: return "HI16";
-  case VK_Hexagon_GPREL: return "GPREL";
-  case VK_Hexagon_GD_GOT: return "GDGOT";
-  case VK_Hexagon_LD_GOT: return "LDGOT";
-  case VK_Hexagon_GD_PLT: return "GDPLT";
-  case VK_Hexagon_LD_PLT: return "LDPLT";
-  case VK_Hexagon_IE: return "IE";
-  case VK_Hexagon_IE_GOT: return "IEGOT";
-  case VK_WASM_TYPEINDEX: return "TYPEINDEX";
-  case VK_WASM_MBREL: return "MBREL";
-  case VK_WASM_TLSREL: return "TLSREL";
-  case VK_WASM_TBREL: return "TBREL";
-  case VK_WASM_GOT_TLS: return "GOT at TLS";
-  case VK_WASM_FUNCINDEX: return "FUNCINDEX";
-  case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32 at lo";
-  case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32 at hi";
-  case VK_AMDGPU_REL32_LO: return "rel32 at lo";
-  case VK_AMDGPU_REL32_HI: return "rel32 at hi";
-  case VK_AMDGPU_REL64: return "rel64";
-  case VK_AMDGPU_ABS32_LO: return "abs32 at lo";
-  case VK_AMDGPU_ABS32_HI: return "abs32 at hi";
-  case VK_VE_HI32: return "hi";
-  case VK_VE_LO32: return "lo";
-  case VK_VE_PC_HI32: return "pc_hi";
-  case VK_VE_PC_LO32: return "pc_lo";
-  case VK_VE_GOT_HI32: return "got_hi";
-  case VK_VE_GOT_LO32: return "got_lo";
-  case VK_VE_GOTOFF_HI32: return "gotoff_hi";
-  case VK_VE_GOTOFF_LO32: return "gotoff_lo";
-  case VK_VE_PLT_HI32: return "plt_hi";
-  case VK_VE_PLT_LO32: return "plt_lo";
-  case VK_VE_TLS_GD_HI32: return "tls_gd_hi";
-  case VK_VE_TLS_GD_LO32: return "tls_gd_lo";
-  case VK_VE_TPOFF_HI32: return "tpoff_hi";
-  case VK_VE_TPOFF_LO32: return "tpoff_lo";
     // clang-format on
   }
   llvm_unreachable("Invalid variant kind");

diff  --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index fca6b3785fe6a..88398de66f410 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1229,7 +1229,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
 
     // Lookup the symbol variant if used.
     if (!Split.second.empty()) {
-      Variant = getTargetParser().getVariantKindForName(Split.second);
+      Variant =
+          MCSymbolRefExpr::VariantKind(MAI.getVariantKindForName(Split.second));
       if (Variant != MCSymbolRefExpr::VK_Invalid) {
         SymbolName = Split.first;
       } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
@@ -1279,7 +1280,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
       std::pair<StringRef, StringRef> Split = IDVal.split('@');
       MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
       if (Split.first.size() != IDVal.size()) {
-        Variant = getTargetParser().getVariantKindForName(Split.second);
+        Variant = MCSymbolRefExpr::VariantKind(
+            MAI.getVariantKindForName(Split.second));
         if (Variant == MCSymbolRefExpr::VK_Invalid)
           return TokError("invalid variant '" + Split.second + "'");
         IDVal = Split.first;
@@ -1469,8 +1471,8 @@ bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
     if (Lexer.isNot(AsmToken::Identifier))
       return TokError("unexpected symbol modifier following '@'");
 
-    MCSymbolRefExpr::VariantKind Variant =
-        TS.getVariantKindForName(getTok().getIdentifier());
+    auto Variant = MCSymbolRefExpr::VariantKind(
+        MAI.getVariantKindForName(getTok().getIdentifier()));
     if (Variant == MCSymbolRefExpr::VK_Invalid)
       return TokError("invalid variant '" + getTok().getIdentifier() + "'");
 

diff  --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 3a8210b693c87..54ed3789326cb 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -1612,8 +1612,6 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
                                OperandVector &Operands, MCStreamer &Out,
                                uint64_t &ErrorInfo,
                                bool MatchingInlineAsm) override;
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
   bool ParseDirective(AsmToken DirectiveID) override;
   ParseStatus parseOperand(OperandVector &Operands, StringRef Mnemonic,
                            OperandMode Mode = OperandMode_Default);
@@ -5452,20 +5450,6 @@ bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   llvm_unreachable("Implement any new match types added!");
 }
 
-MCSymbolRefExpr::VariantKind
-AMDGPUAsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("gotpcrel", MCSymbolRefExpr::VK_GOTPCREL)
-      .Case("gotpcrel32 at lo", MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO)
-      .Case("gotpcrel32 at hi", MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI)
-      .Case("rel32 at lo", MCSymbolRefExpr::VK_AMDGPU_REL32_LO)
-      .Case("rel32 at hi", MCSymbolRefExpr::VK_AMDGPU_REL32_HI)
-      .Case("rel64", MCSymbolRefExpr::VK_AMDGPU_REL64)
-      .Case("abs32 at lo", MCSymbolRefExpr::VK_AMDGPU_ABS32_LO)
-      .Case("abs32 at hi", MCSymbolRefExpr::VK_AMDGPU_ABS32_HI)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}
-
 bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
   int64_t Tmp = -1;
   if (!isToken(AsmToken::Integer) && !isToken(AsmToken::Identifier)) {

diff  --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
index 56ed29ede02c2..b55d90737f960 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
@@ -9,11 +9,23 @@
 
 #include "AMDGPUMCAsmInfo.h"
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
+#include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_GOTPCREL, "gotpcrel"},
+    {MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO, "gotpcrel32 at lo"},
+    {MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI, "gotpcrel32 at hi"},
+    {MCSymbolRefExpr::VK_AMDGPU_REL32_LO, "rel32 at lo"},
+    {MCSymbolRefExpr::VK_AMDGPU_REL32_HI, "rel32 at hi"},
+    {MCSymbolRefExpr::VK_AMDGPU_REL64, "rel64"},
+    {MCSymbolRefExpr::VK_AMDGPU_ABS32_LO, "abs32 at lo"},
+    {MCSymbolRefExpr::VK_AMDGPU_ABS32_HI, "abs32 at hi"},
+};
+
 AMDGPUMCAsmInfo::AMDGPUMCAsmInfo(const Triple &TT,
                                  const MCTargetOptions &Options) {
   CodePointerSize = (TT.getArch() == Triple::amdgcn) ? 8 : 4;
@@ -42,6 +54,7 @@ AMDGPUMCAsmInfo::AMDGPUMCAsmInfo(const Triple &TT,
   DwarfRegNumForCFI = true;
 
   UseIntegratedAssembler = false;
+  initializeVariantKinds(variantKindDescs);
 }
 
 bool AMDGPUMCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {

diff  --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 7c24dc8b3268f..3a0d5ea03dd53 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -749,9 +749,6 @@ class ARMAsmParser : public MCTargetAsmParser {
   void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
                         OperandVector &Operands);
 
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
-
   void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) override;
 
   void onLabelParsed(MCSymbol *Symbol) override;
@@ -11677,37 +11674,6 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
   return false;
 }
 
-MCSymbolRefExpr::VariantKind
-ARMAsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("funcdesc", MCSymbolRefExpr::VK_FUNCDESC)
-      .Case("got", MCSymbolRefExpr::VK_GOT)
-      .Case("got_prel", MCSymbolRefExpr::VK_ARM_GOT_PREL)
-      .Case("gotfuncdesc", MCSymbolRefExpr::VK_GOTFUNCDESC)
-      .Case("gotoff", MCSymbolRefExpr::VK_GOTOFF)
-      .Case("gotofffuncdesc", MCSymbolRefExpr::VK_GOTOFFFUNCDESC)
-      .Case("gottpoff", MCSymbolRefExpr::VK_GOTTPOFF)
-      .Case("gottpoff_fdpic", MCSymbolRefExpr::VK_GOTTPOFF_FDPIC)
-      .Case("imgrel", MCSymbolRefExpr::VK_COFF_IMGREL32)
-      .Case("none", MCSymbolRefExpr::VK_ARM_NONE)
-      .Case("plt", MCSymbolRefExpr::VK_PLT)
-      .Case("prel31", MCSymbolRefExpr::VK_ARM_PREL31)
-      .Case("sbrel", MCSymbolRefExpr::VK_ARM_SBREL)
-      .Case("secrel32", MCSymbolRefExpr::VK_SECREL)
-      .Case("target1", MCSymbolRefExpr::VK_ARM_TARGET1)
-      .Case("target2", MCSymbolRefExpr::VK_ARM_TARGET2)
-      .Case("tlscall", MCSymbolRefExpr::VK_TLSCALL)
-      .Case("tlsdesc", MCSymbolRefExpr::VK_TLSDESC)
-      .Case("tlsgd", MCSymbolRefExpr::VK_TLSGD)
-      .Case("tlsgd_fdpic", MCSymbolRefExpr::VK_TLSGD_FDPIC)
-      .Case("tlsld", MCSymbolRefExpr::VK_TLSLD)
-      .Case("tlsldm", MCSymbolRefExpr::VK_TLSLDM)
-      .Case("tlsldm_fdpic", MCSymbolRefExpr::VK_TLSLDM_FDPIC)
-      .Case("tlsldo", MCSymbolRefExpr::VK_ARM_TLSLDO)
-      .Case("tpoff", MCSymbolRefExpr::VK_TPOFF)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}
-
 void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
   // We need to flush the current implicit IT block on a label, because it is
   // not legal to branch into an IT block.

diff  --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
index 46b4750e89996..b66fde007accc 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
@@ -11,10 +11,39 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARMMCAsmInfo.h"
+#include "llvm/MC/MCExpr.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_ARM_GOT_PREL, "GOT_PREL"},
+    {MCSymbolRefExpr::VK_ARM_NONE, "none"},
+    {MCSymbolRefExpr::VK_ARM_PREL31, "prel31"},
+    {MCSymbolRefExpr::VK_ARM_SBREL, "sbrel"},
+    {MCSymbolRefExpr::VK_ARM_TARGET1, "target1"},
+    {MCSymbolRefExpr::VK_ARM_TARGET2, "target2"},
+    {MCSymbolRefExpr::VK_ARM_TLSLDO, "TLSLDO"},
+    {MCSymbolRefExpr::VK_COFF_IMGREL32, "imgrel"},
+    {MCSymbolRefExpr::VK_FUNCDESC, "FUNCDESC"},
+    {MCSymbolRefExpr::VK_GOT, "GOT"},
+    {MCSymbolRefExpr::VK_GOTFUNCDESC, "GOTFUNCDESC"},
+    {MCSymbolRefExpr::VK_GOTOFF, "GOTOFF"},
+    {MCSymbolRefExpr::VK_GOTOFFFUNCDESC, "GOTOFFFUNCDESC"},
+    {MCSymbolRefExpr::VK_GOTTPOFF, "GOTTPOFF"},
+    {MCSymbolRefExpr::VK_GOTTPOFF_FDPIC, "gottpoff_fdpic"},
+    {MCSymbolRefExpr::VK_PLT, "PLT"},
+    {MCSymbolRefExpr::VK_SECREL, "SECREL32"},
+    {MCSymbolRefExpr::VK_TLSCALL, "tlscall"},
+    {MCSymbolRefExpr::VK_TLSDESC, "tlsdesc"},
+    {MCSymbolRefExpr::VK_TLSGD, "TLSGD"},
+    {MCSymbolRefExpr::VK_TLSGD_FDPIC, "tlsgd_fdpic"},
+    {MCSymbolRefExpr::VK_TLSLD, "TLSLD"},
+    {MCSymbolRefExpr::VK_TLSLDM, "TLSLDM"},
+    {MCSymbolRefExpr::VK_TLSLDM_FDPIC, "tlsldm_fdpic"},
+    {MCSymbolRefExpr::VK_TPOFF, "TPOFF"},
+};
+
 void ARMMCAsmInfoDarwin::anchor() { }
 
 ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin(const Triple &TheTriple) {
@@ -37,6 +66,8 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin(const Triple &TheTriple) {
   ExceptionsType = (TheTriple.isOSDarwin() && !TheTriple.isWatchABI())
                        ? ExceptionHandling::SjLj
                        : ExceptionHandling::DwarfCFI;
+
+  initializeVariantKinds(variantKindDescs);
 }
 
 void ARMELFMCAsmInfo::anchor() { }
@@ -71,6 +102,8 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo(const Triple &TheTriple) {
 
   // foo(plt) instead of foo at plt
   UseParensForSymbolVariant = true;
+
+  initializeVariantKinds(variantKindDescs);
 }
 
 void ARMELFMCAsmInfo::setUseIntegratedAssembler(bool Value) {
@@ -119,4 +152,6 @@ ARMCOFFMCAsmInfoGNU::ARMCOFFMCAsmInfoGNU() {
 
   // Conditional Thumb 4-byte instructions can have an implicit IT.
   MaxInstLength = 6;
+
+  initializeVariantKinds(variantKindDescs);
 }

diff  --git a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
index ae63877c7fc27..68bd89f624b8a 100644
--- a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
+++ b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
@@ -77,9 +77,6 @@ class AVRAsmParser : public MCTargetAsmParser {
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
 
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
-
   MCRegister toDREG(MCRegister Reg, unsigned From = AVR::sub_lo) {
     MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
     return MRI->getMatchingSuperReg(Reg, From, Class);
@@ -786,12 +783,3 @@ unsigned AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
   }
   return Match_InvalidOperand;
 }
-
-MCSymbolRefExpr::VariantKind
-AVRAsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("lo8", MCSymbolRefExpr::VK_AVR_LO8)
-      .Case("hi8", MCSymbolRefExpr::VK_AVR_HI8)
-      .Case("hlo8", MCSymbolRefExpr::VK_AVR_HLO8)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}

diff  --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp
index 66786eb3244e4..1ec106ce576b2 100644
--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp
+++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp
@@ -11,10 +11,21 @@
 //===----------------------------------------------------------------------===//
 
 #include "AVRMCAsmInfo.h"
-
+#include "llvm/MC/MCExpr.h"
 #include "llvm/TargetParser/Triple.h"
 
-namespace llvm {
+using namespace llvm;
+
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_AVR_DIFF16, "
diff 16"},
+    {MCSymbolRefExpr::VK_AVR_DIFF32, "
diff 32"},
+    {MCSymbolRefExpr::VK_AVR_DIFF8, "
diff 8"},
+    {MCSymbolRefExpr::VK_AVR_HI8, "hi8"},
+    {MCSymbolRefExpr::VK_AVR_HLO8, "hlo8"},
+    {MCSymbolRefExpr::VK_AVR_LO8, "lo8"},
+    {MCSymbolRefExpr::VK_AVR_NONE, "none"},
+    {MCSymbolRefExpr::VK_AVR_PM, "pm"},
+};
 
 AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) {
   CodePointerSize = 2;
@@ -25,6 +36,5 @@ AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) {
   PrivateLabelPrefix = ".L";
   UsesELFSectionDirectiveForBSS = true;
   SupportsDebugInformation = true;
+  initializeVariantKinds(variantKindDescs);
 }
-
-} // end of namespace llvm

diff  --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
index 4535237683227..f8c57fc5e0058 100644
--- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
+++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
@@ -140,8 +140,6 @@ class HexagonAsmParser : public MCTargetAsmParser {
 
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
   bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
   int processInstruction(MCInst &Inst, OperandVector const &Operands,
                          SMLoc IDLoc);
@@ -1332,24 +1330,6 @@ unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
   return Match_InvalidOperand;
 }
 
-MCSymbolRefExpr::VariantKind
-HexagonAsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("dtprel", MCSymbolRefExpr::VK_DTPREL)
-      .Case("gdgot", MCSymbolRefExpr::VK_Hexagon_GD_GOT)
-      .Case("gdplt", MCSymbolRefExpr::VK_Hexagon_GD_PLT)
-      .Case("got", MCSymbolRefExpr::VK_GOT)
-      .Case("gotrel", MCSymbolRefExpr::VK_GOTREL)
-      .Case("ie", MCSymbolRefExpr::VK_Hexagon_IE)
-      .Case("iegot", MCSymbolRefExpr::VK_Hexagon_IE_GOT)
-      .Case("ldgot", MCSymbolRefExpr::VK_Hexagon_LD_GOT)
-      .Case("ldplt", MCSymbolRefExpr::VK_Hexagon_LD_PLT)
-      .Case("pcrel", MCSymbolRefExpr::VK_PCREL)
-      .Case("plt", MCSymbolRefExpr::VK_PLT)
-      .Case("tprel", MCSymbolRefExpr::VK_TPREL)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}
-
 // FIXME: Calls to OutOfRange should propagate failure up to parseStatement.
 bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
   std::string errStr;

diff  --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
index f3da675623209..6cf4ceb3de927 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
@@ -11,9 +11,25 @@
 //===----------------------------------------------------------------------===//
 
 #include "HexagonMCAsmInfo.h"
+#include "llvm/MC/MCExpr.h"
 
 using namespace llvm;
 
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_DTPREL, "DTPREL"},
+    {MCSymbolRefExpr::VK_Hexagon_GD_GOT, "GDGOT"},
+    {MCSymbolRefExpr::VK_Hexagon_GD_PLT, "GDPLT"},
+    {MCSymbolRefExpr::VK_GOT, "GOT"},
+    {MCSymbolRefExpr::VK_GOTREL, "GOTREL"},
+    {MCSymbolRefExpr::VK_Hexagon_IE, "IE"},
+    {MCSymbolRefExpr::VK_Hexagon_IE_GOT, "IEGOT"},
+    {MCSymbolRefExpr::VK_Hexagon_LD_GOT, "LDGOT"},
+    {MCSymbolRefExpr::VK_Hexagon_LD_PLT, "LDPLT"},
+    {MCSymbolRefExpr::VK_PCREL, "PCREL"},
+    {MCSymbolRefExpr::VK_PLT, "PLT"},
+    {MCSymbolRefExpr::VK_TPREL, "TPREL"},
+};
+
 // Pin the vtable to this file.
 void HexagonMCAsmInfo::anchor() {}
 
@@ -34,4 +50,6 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(const Triple &TT) {
   UsesELFSectionDirectiveForBSS  = true;
   ExceptionsType = ExceptionHandling::DwarfCFI;
   UseLogicalShr = false;
+
+  initializeVariantKinds(variantKindDescs);
 }

diff  --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 8f30fd5ebf142..a3646532c4530 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -156,8 +156,6 @@ class PPCAsmParser : public MCTargetAsmParser {
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
 
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
   const MCExpr *applyModifierToExpr(const MCExpr *E,
                                     MCSymbolRefExpr::VariantKind,
                                     MCContext &Ctx) override;
@@ -1903,81 +1901,6 @@ unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
   return Match_InvalidOperand;
 }
 
-MCSymbolRefExpr::VariantKind
-PPCAsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("dtprel", MCSymbolRefExpr::VK_DTPREL)
-      .Case("got", MCSymbolRefExpr::VK_GOT)
-      .Case("pcrel", MCSymbolRefExpr::VK_PCREL)
-      .Case("plt", MCSymbolRefExpr::VK_PLT)
-      .Case("tlsgd", MCSymbolRefExpr::VK_TLSGD)
-      .Case("tlsld", MCSymbolRefExpr::VK_TLSLD)
-      .Case("tprel", MCSymbolRefExpr::VK_TPREL)
-      .Case("l", MCSymbolRefExpr::VK_PPC_LO)
-      .Case("h", MCSymbolRefExpr::VK_PPC_HI)
-      .Case("ha", MCSymbolRefExpr::VK_PPC_HA)
-      .Case("high", MCSymbolRefExpr::VK_PPC_HIGH)
-      .Case("higha", MCSymbolRefExpr::VK_PPC_HIGHA)
-      .Case("higher", MCSymbolRefExpr::VK_PPC_HIGHER)
-      .Case("highera", MCSymbolRefExpr::VK_PPC_HIGHERA)
-      .Case("highest", MCSymbolRefExpr::VK_PPC_HIGHEST)
-      .Case("highesta", MCSymbolRefExpr::VK_PPC_HIGHESTA)
-      .Case("got at l", MCSymbolRefExpr::VK_PPC_GOT_LO)
-      .Case("got at h", MCSymbolRefExpr::VK_PPC_GOT_HI)
-      .Case("got at ha", MCSymbolRefExpr::VK_PPC_GOT_HA)
-      .Case("local", MCSymbolRefExpr::VK_PPC_LOCAL)
-      .Case("tocbase", MCSymbolRefExpr::VK_PPC_TOCBASE)
-      .Case("toc", MCSymbolRefExpr::VK_PPC_TOC)
-      .Case("toc at l", MCSymbolRefExpr::VK_PPC_TOC_LO)
-      .Case("toc at h", MCSymbolRefExpr::VK_PPC_TOC_HI)
-      .Case("toc at ha", MCSymbolRefExpr::VK_PPC_TOC_HA)
-      .Case("u", MCSymbolRefExpr::VK_PPC_U)
-      // .Case("l", MCSymbolRefExpr::VK_PPC_L) VK_PPC_LO?
-      .Case("tls", MCSymbolRefExpr::VK_PPC_TLS)
-      .Case("dtpmod", MCSymbolRefExpr::VK_PPC_DTPMOD)
-      .Case("tprel at l", MCSymbolRefExpr::VK_PPC_TPREL_LO)
-      .Case("tprel at h", MCSymbolRefExpr::VK_PPC_TPREL_HI)
-      .Case("tprel at ha", MCSymbolRefExpr::VK_PPC_TPREL_HA)
-      .Case("tprel at high", MCSymbolRefExpr::VK_PPC_TPREL_HIGH)
-      .Case("tprel at higha", MCSymbolRefExpr::VK_PPC_TPREL_HIGHA)
-      .Case("tprel at higher", MCSymbolRefExpr::VK_PPC_TPREL_HIGHER)
-      .Case("tprel at highera", MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA)
-      .Case("tprel at highest", MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST)
-      .Case("tprel at highesta", MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA)
-      .Case("dtprel at l", MCSymbolRefExpr::VK_PPC_DTPREL_LO)
-      .Case("dtprel at h", MCSymbolRefExpr::VK_PPC_DTPREL_HI)
-      .Case("dtprel at ha", MCSymbolRefExpr::VK_PPC_DTPREL_HA)
-      .Case("dtprel at high", MCSymbolRefExpr::VK_PPC_DTPREL_HIGH)
-      .Case("dtprel at higha", MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA)
-      .Case("dtprel at higher", MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER)
-      .Case("dtprel at highera", MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA)
-      .Case("dtprel at highest", MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST)
-      .Case("dtprel at highesta", MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA)
-      .Case("got at tprel", MCSymbolRefExpr::VK_PPC_GOT_TPREL)
-      .Case("got at tprel@l", MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO)
-      .Case("got at tprel@h", MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI)
-      .Case("got at tprel@ha", MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA)
-      .Case("got at dtprel", MCSymbolRefExpr::VK_PPC_GOT_DTPREL)
-      .Case("got at dtprel@l", MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO)
-      .Case("got at dtprel@h", MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI)
-      .Case("got at dtprel@ha", MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA)
-      .Case("got at tlsgd", MCSymbolRefExpr::VK_PPC_GOT_TLSGD)
-      .Case("got at tlsgd@l", MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO)
-      .Case("got at tlsgd@h", MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI)
-      .Case("got at tlsgd@ha", MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA)
-      .Case("got at tlsld", MCSymbolRefExpr::VK_PPC_GOT_TLSLD)
-      .Case("got at tlsld@l", MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO)
-      .Case("got at tlsld@h", MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI)
-      .Case("got at tlsld@ha", MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA)
-      .Case("got at pcrel", MCSymbolRefExpr::VK_PPC_GOT_PCREL)
-      .Case("got at tlsgd@pcrel", MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL)
-      .Case("got at tlsld@pcrel", MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL)
-      .Case("got at tprel@pcrel", MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL)
-      .Case("tls at pcrel", MCSymbolRefExpr::VK_PPC_TLS_PCREL)
-      .Case("notoc", MCSymbolRefExpr::VK_PPC_NOTOC)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}
-
 const MCExpr *
 PPCAsmParser::applyModifierToExpr(const MCExpr *E,
                                   MCSymbolRefExpr::VariantKind Variant,

diff  --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index 74404822757ed..faf9c38879ba4 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -580,13 +580,13 @@ void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
   // end like __tls_get_addr(x at tlsgd)@notoc. Instead we want it to look
   // like __tls_get_addr at notoc(x at tlsgd).
   if (RefExp->getKind() == MCSymbolRefExpr::VK_PPC_NOTOC)
-    O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
+    O << '@' << MAI.getVariantKindName(RefExp->getKind());
   O << '(';
   printOperand(MI, OpNo + 1, STI, O);
   O << ')';
   if (RefExp->getKind() != MCSymbolRefExpr::VK_None &&
       RefExp->getKind() != MCSymbolRefExpr::VK_PPC_NOTOC)
-    O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
+    O << '@' << MAI.getVariantKindName(RefExp->getKind());
   if (Rhs) {
     SmallString<0> Buf;
     raw_svector_ostream Tmp(Buf);

diff  --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
index 4716e37b34432..b6d1fd7a581a5 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
@@ -11,12 +11,94 @@
 //===----------------------------------------------------------------------===//
 
 #include "PPCMCAsmInfo.h"
+#include "llvm/MC/MCExpr.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
 void PPCELFMCAsmInfo::anchor() { }
 
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_DTPREL, "DTPREL"},
+    {MCSymbolRefExpr::VK_GOT, "GOT"},
+    {MCSymbolRefExpr::VK_PCREL, "PCREL"},
+    {MCSymbolRefExpr::VK_PLT, "PLT"},
+    {MCSymbolRefExpr::VK_TLSGD, "TLSGD"},
+    {MCSymbolRefExpr::VK_TLSLD, "TLSLD"},
+    {MCSymbolRefExpr::VK_TPREL, "TPREL"},
+    {MCSymbolRefExpr::VK_PPC_LO, "l"},
+    {MCSymbolRefExpr::VK_PPC_HI, "h"},
+    {MCSymbolRefExpr::VK_PPC_HA, "ha"},
+    {MCSymbolRefExpr::VK_PPC_HIGH, "high"},
+    {MCSymbolRefExpr::VK_PPC_HIGHA, "higha"},
+    {MCSymbolRefExpr::VK_PPC_HIGHER, "higher"},
+    {MCSymbolRefExpr::VK_PPC_HIGHERA, "highera"},
+    {MCSymbolRefExpr::VK_PPC_HIGHEST, "highest"},
+    {MCSymbolRefExpr::VK_PPC_HIGHESTA, "highesta"},
+    {MCSymbolRefExpr::VK_PPC_GOT_LO, "got at l"},
+    {MCSymbolRefExpr::VK_PPC_GOT_HI, "got at h"},
+    {MCSymbolRefExpr::VK_PPC_GOT_HA, "got at ha"},
+    {MCSymbolRefExpr::VK_PPC_TOCBASE, "tocbase"},
+    {MCSymbolRefExpr::VK_PPC_TOC, "toc"},
+    {MCSymbolRefExpr::VK_PPC_TOC_LO, "toc at l"},
+    {MCSymbolRefExpr::VK_PPC_TOC_HI, "toc at h"},
+    {MCSymbolRefExpr::VK_PPC_TOC_HA, "toc at ha"},
+    {MCSymbolRefExpr::VK_PPC_U, "u"},
+    {MCSymbolRefExpr::VK_PPC_L, "l"}, // FIXME: share the name with VK_PPC_LO
+    {MCSymbolRefExpr::VK_PPC_DTPMOD, "dtpmod"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_LO, "tprel at l"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HI, "tprel at h"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HA, "tprel at ha"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HIGH, "tprel at high"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HIGHA, "tprel at higha"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HIGHER, "tprel at higher"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA, "tprel at highera"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST, "tprel at highest"},
+    {MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA, "tprel at highesta"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_LO, "dtprel at l"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HI, "dtprel at h"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HA, "dtprel at ha"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HIGH, "dtprel at high"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA, "dtprel at higha"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER, "dtprel at higher"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA, "dtprel at highera"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST, "dtprel at highest"},
+    {MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA, "dtprel at highesta"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TPREL, "got at tprel"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO, "got at tprel@l"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI, "got at tprel@h"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, "got at tprel@ha"},
+    {MCSymbolRefExpr::VK_PPC_GOT_DTPREL, "got at dtprel"},
+    {MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO, "got at dtprel@l"},
+    {MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI, "got at dtprel@h"},
+    {MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA, "got at dtprel@ha"},
+    {MCSymbolRefExpr::VK_PPC_TLS, "tls"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSGD, "got at tlsgd"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO, "got at tlsgd@l"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI, "got at tlsgd@h"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, "got at tlsgd@ha"},
+    {MCSymbolRefExpr::VK_PPC_TLSGD, "tlsgd"},
+    {MCSymbolRefExpr::VK_PPC_AIX_TLSGD, "gd"},
+    {MCSymbolRefExpr::VK_PPC_AIX_TLSGDM, "m"},
+    {MCSymbolRefExpr::VK_PPC_AIX_TLSIE, "ie"},
+    {MCSymbolRefExpr::VK_PPC_AIX_TLSLE, "le"},
+    {MCSymbolRefExpr::VK_PPC_AIX_TLSLD, "ld"},
+    {MCSymbolRefExpr::VK_PPC_AIX_TLSML, "ml"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSLD, "got at tlsld"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO, "got at tlsld@l"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI, "got at tlsld@h"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, "got at tlsld@ha"},
+    {MCSymbolRefExpr::VK_PPC_GOT_PCREL, "got at pcrel"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL, "got at tlsgd@pcrel"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL, "got at tlsld@pcrel"},
+    {MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL, "got at tprel@pcrel"},
+    {MCSymbolRefExpr::VK_PPC_TLS_PCREL, "tls at pcrel"},
+    {MCSymbolRefExpr::VK_PPC_TLSLD, "tlsld"},
+    {MCSymbolRefExpr::VK_PPC_LOCAL, "local"},
+    {MCSymbolRefExpr::VK_PPC_NOTOC, "notoc"},
+    {MCSymbolRefExpr::VK_PPC_PCREL_OPT, "<<invalid>>"},
+};
+
 PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
   // FIXME: This is not always needed. For example, it is not needed in the
   // v2 abi.
@@ -51,6 +133,8 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
   Data64bitsDirective = is64Bit ? "\t.quad\t" : nullptr;
   AssemblerDialect = 1;           // New-Style mnemonics.
   LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
+
+  initializeVariantKinds(variantKindDescs);
 }
 
 void PPCXCOFFMCAsmInfo::anchor() {}
@@ -71,4 +155,6 @@ PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) {
 
   // Support $ as PC in inline asm
   DollarIsPC = true;
+
+  initializeVariantKinds(variantKindDescs);
 }

diff  --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index 5dde48fba5605..3454ef02ac174 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -228,7 +228,7 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD ||
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML)
         OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
-           << MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
+           << getContext().getAsmInfo()->getVariantKindName(Kind) << '\n';
       else
         OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n';
 

diff  --git a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
index 0093544cc3e7f..0190e6072d76a 100644
--- a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
+++ b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
@@ -63,9 +63,6 @@ class VEAsmParser : public MCTargetAsmParser {
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
 
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
-
   // Custom parse functions for VE specific operands.
   ParseStatus parseMEMOperand(OperandVector &Operands);
   ParseStatus parseMEMAsOperand(OperandVector &Operands);
@@ -1586,23 +1583,3 @@ unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
   }
   return Match_InvalidOperand;
 }
-
-MCSymbolRefExpr::VariantKind
-VEAsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("hi", MCSymbolRefExpr::VK_VE_HI32)
-      .Case("lo", MCSymbolRefExpr::VK_VE_LO32)
-      .Case("pc_hi", MCSymbolRefExpr::VK_VE_PC_HI32)
-      .Case("pc_lo", MCSymbolRefExpr::VK_VE_PC_LO32)
-      .Case("got_hi", MCSymbolRefExpr::VK_VE_GOT_HI32)
-      .Case("got_lo", MCSymbolRefExpr::VK_VE_GOT_LO32)
-      .Case("gotoff_hi", MCSymbolRefExpr::VK_VE_GOTOFF_HI32)
-      .Case("gotoff_lo", MCSymbolRefExpr::VK_VE_GOTOFF_LO32)
-      .Case("plt_hi", MCSymbolRefExpr::VK_VE_PLT_HI32)
-      .Case("plt_lo", MCSymbolRefExpr::VK_VE_PLT_LO32)
-      .Case("tls_gd_hi", MCSymbolRefExpr::VK_VE_TLS_GD_HI32)
-      .Case("tls_gd_lo", MCSymbolRefExpr::VK_VE_TLS_GD_LO32)
-      .Case("tpoff_hi", MCSymbolRefExpr::VK_VE_TPOFF_HI32)
-      .Case("tpoff_lo", MCSymbolRefExpr::VK_VE_TPOFF_LO32)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}

diff  --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
index 03c000b9bcb60..b4691231d0fbe 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
@@ -11,11 +11,29 @@
 //===----------------------------------------------------------------------===//
 
 #include "VEMCAsmInfo.h"
+#include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_VE_HI32, "hi"},
+    {MCSymbolRefExpr::VK_VE_LO32, "lo"},
+    {MCSymbolRefExpr::VK_VE_PC_HI32, "pc_hi"},
+    {MCSymbolRefExpr::VK_VE_PC_LO32, "pc_lo"},
+    {MCSymbolRefExpr::VK_VE_GOT_HI32, "got_hi"},
+    {MCSymbolRefExpr::VK_VE_GOT_LO32, "got_lo"},
+    {MCSymbolRefExpr::VK_VE_GOTOFF_HI32, "gotoff_hi"},
+    {MCSymbolRefExpr::VK_VE_GOTOFF_LO32, "gotoff_lo"},
+    {MCSymbolRefExpr::VK_VE_PLT_HI32, "plt_hi"},
+    {MCSymbolRefExpr::VK_VE_PLT_LO32, "plt_lo"},
+    {MCSymbolRefExpr::VK_VE_TLS_GD_HI32, "tls_gd_hi"},
+    {MCSymbolRefExpr::VK_VE_TLS_GD_LO32, "tls_gd_lo"},
+    {MCSymbolRefExpr::VK_VE_TPOFF_HI32, "tpoff_hi"},
+    {MCSymbolRefExpr::VK_VE_TPOFF_LO32, "tpoff_lo"},
+};
+
 void VEELFMCAsmInfo::anchor() {}
 
 VEELFMCAsmInfo::VEELFMCAsmInfo(const Triple &TheTriple) {
@@ -34,4 +52,6 @@ VEELFMCAsmInfo::VEELFMCAsmInfo(const Triple &TheTriple) {
   UsesELFSectionDirectiveForBSS = true;
 
   SupportsDebugInformation = true;
+
+  initializeVariantKinds(variantKindDescs);
 }

diff  --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index 55175f9859705..2a4e2c897b18d 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -1210,9 +1210,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
     llvm_unreachable("Implement any new match types added!");
   }
 
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
-
   void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) override {
     // Code below only applies to labels in text sections.
     auto *CWS = cast<MCSectionWasm>(getStreamer().getCurrentSectionOnly());
@@ -1283,19 +1280,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
 };
 } // end anonymous namespace
 
-MCSymbolRefExpr::VariantKind
-WebAssemblyAsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("typeindex", MCSymbolRefExpr::VK_WASM_TYPEINDEX)
-      .Case("tbrel", MCSymbolRefExpr::VK_WASM_TBREL)
-      .Case("mbrel", MCSymbolRefExpr::VK_WASM_MBREL)
-      .Case("tlsrel", MCSymbolRefExpr::VK_WASM_TLSREL)
-      .Case("got", MCSymbolRefExpr::VK_GOT)
-      .Case("got at tls", MCSymbolRefExpr::VK_WASM_GOT_TLS)
-      .Case("funcindex", MCSymbolRefExpr::VK_WASM_FUNCINDEX)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}
-
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyAsmParser() {
   RegisterMCAsmParser<WebAssemblyAsmParser> X(getTheWebAssemblyTarget32());

diff  --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
index a23f52b8aa907..ffa63ed8146ae 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
@@ -14,12 +14,23 @@
 
 #include "WebAssemblyMCAsmInfo.h"
 #include "WebAssemblyMCTargetDesc.h"
+#include "llvm/MC/MCExpr.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
 #define DEBUG_TYPE "wasm-mc-asm-info"
 
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_WASM_TYPEINDEX, "TYPEINDEX"},
+    {MCSymbolRefExpr::VK_WASM_TBREL, "TBREL"},
+    {MCSymbolRefExpr::VK_WASM_MBREL, "MBREL"},
+    {MCSymbolRefExpr::VK_WASM_TLSREL, "TLSREL"},
+    {MCSymbolRefExpr::VK_GOT, "GOT"},
+    {MCSymbolRefExpr::VK_WASM_GOT_TLS, "GOT at TLS"},
+    {MCSymbolRefExpr::VK_WASM_FUNCINDEX, "FUNCINDEX"},
+};
+
 WebAssemblyMCAsmInfo::~WebAssemblyMCAsmInfo() = default; // anchor.
 
 WebAssemblyMCAsmInfo::WebAssemblyMCAsmInfo(const Triple &T,
@@ -52,4 +63,6 @@ WebAssemblyMCAsmInfo::WebAssemblyMCAsmInfo(const Triple &T,
   // clang, so we make sure this info is set correctly.
   if (WebAssembly::WasmEnableEH || WebAssembly::WasmEnableSjLj)
     ExceptionsType = ExceptionHandling::Wasm;
+
+  initializeVariantKinds(variantKindDescs);
 }

diff  --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 2b69ef5fc2af6..a6285a55f4155 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1182,9 +1182,6 @@ class X86AsmParser : public MCTargetAsmParser {
 
   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
 
-  MCSymbolRefExpr::VariantKind
-  getVariantKindForName(StringRef Name) const override;
-
   bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
   bool processInstruction(MCInst &Inst, const OperandVector &Ops);
 
@@ -4250,40 +4247,6 @@ unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
   return Match_Success;
 }
 
-MCSymbolRefExpr::VariantKind
-X86AsmParser::getVariantKindForName(StringRef Name) const {
-  return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
-      .Case("abs8", MCSymbolRefExpr::VK_X86_ABS8)
-      .Case("dtpoff", MCSymbolRefExpr::VK_DTPOFF)
-      .Case("dtprel", MCSymbolRefExpr::VK_DTPREL)
-      .Case("got", MCSymbolRefExpr::VK_GOT)
-      .Case("gotent", MCSymbolRefExpr::VK_GOTENT)
-      .Case("gotntpoff", MCSymbolRefExpr::VK_GOTNTPOFF)
-      .Case("gotoff", MCSymbolRefExpr::VK_GOTOFF)
-      .Case("gotpcrel", MCSymbolRefExpr::VK_GOTPCREL)
-      .Case("gotpcrel_norelax", MCSymbolRefExpr::VK_GOTPCREL_NORELAX)
-      .Case("gotrel", MCSymbolRefExpr::VK_GOTREL)
-      .Case("gottpoff", MCSymbolRefExpr::VK_GOTTPOFF)
-      .Case("indntpoff", MCSymbolRefExpr::VK_INDNTPOFF)
-      .Case("imgrel", MCSymbolRefExpr::VK_COFF_IMGREL32)
-      .Case("ntpoff", MCSymbolRefExpr::VK_NTPOFF)
-      .Case("pcrel", MCSymbolRefExpr::VK_PCREL)
-      .Case("plt", MCSymbolRefExpr::VK_PLT)
-      .Case("pltoff", MCSymbolRefExpr::VK_X86_PLTOFF)
-      .Case("secrel32", MCSymbolRefExpr::VK_SECREL)
-      .Case("size", MCSymbolRefExpr::VK_SIZE)
-      .Case("tlscall", MCSymbolRefExpr::VK_TLSCALL)
-      .Case("tlsdesc", MCSymbolRefExpr::VK_TLSDESC)
-      .Case("tlsgd", MCSymbolRefExpr::VK_TLSGD)
-      .Case("tlsld", MCSymbolRefExpr::VK_TLSLD)
-      .Case("tlsldm", MCSymbolRefExpr::VK_TLSLDM)
-      .Case("tlvp", MCSymbolRefExpr::VK_TLVP)
-      .Case("tlvppage", MCSymbolRefExpr::VK_TLVPPAGE)
-      .Case("tlvppageoff", MCSymbolRefExpr::VK_TLVPPAGEOFF)
-      .Case("tpoff", MCSymbolRefExpr::VK_TPOFF)
-      .Default(MCSymbolRefExpr::VK_Invalid);
-}
-
 bool X86AsmParser::matchAndEmitATTInstruction(
     SMLoc IDLoc, unsigned &Opcode, MCInst &Inst, OperandVector &Operands,
     MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) {

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
index fff518e7daf07..cc108c5aa688c 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
@@ -34,6 +34,37 @@ MarkedJTDataRegions("mark-data-regions", cl::init(true),
   cl::desc("Mark code section jump table data regions."),
   cl::Hidden);
 
+const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+    {MCSymbolRefExpr::VK_X86_ABS8, "ABS8"},
+    {MCSymbolRefExpr::VK_DTPOFF, "DTPOFF"},
+    {MCSymbolRefExpr::VK_DTPREL, "DTPREL"},
+    {MCSymbolRefExpr::VK_GOT, "GOT"},
+    {MCSymbolRefExpr::VK_GOTENT, "GOTENT"},
+    {MCSymbolRefExpr::VK_GOTNTPOFF, "GOTNTPOFF"},
+    {MCSymbolRefExpr::VK_GOTOFF, "GOTOFF"},
+    {MCSymbolRefExpr::VK_GOTPCREL, "GOTPCREL"},
+    {MCSymbolRefExpr::VK_GOTPCREL_NORELAX, "GOTPCREL_NORELAX"},
+    {MCSymbolRefExpr::VK_GOTREL, "GOTREL"},
+    {MCSymbolRefExpr::VK_GOTTPOFF, "GOTTPOFF"},
+    {MCSymbolRefExpr::VK_INDNTPOFF, "INDNTPOFF"},
+    {MCSymbolRefExpr::VK_COFF_IMGREL32, "IMGREL"},
+    {MCSymbolRefExpr::VK_NTPOFF, "NTPOFF"},
+    {MCSymbolRefExpr::VK_PCREL, "PCREL"},
+    {MCSymbolRefExpr::VK_PLT, "PLT"},
+    {MCSymbolRefExpr::VK_X86_PLTOFF, "PLTOFF"},
+    {MCSymbolRefExpr::VK_SECREL, "SECREL32"},
+    {MCSymbolRefExpr::VK_SIZE, "SIZE"},
+    {MCSymbolRefExpr::VK_TLSCALL, "tlscall"},
+    {MCSymbolRefExpr::VK_TLSDESC, "tlsdesc"},
+    {MCSymbolRefExpr::VK_TLSGD, "TLSGD"},
+    {MCSymbolRefExpr::VK_TLSLD, "TLSLD"},
+    {MCSymbolRefExpr::VK_TLSLDM, "TLSLDM"},
+    {MCSymbolRefExpr::VK_TLVP, "TLVP"},
+    {MCSymbolRefExpr::VK_TLVPPAGE, "TLVPPAGE"},
+    {MCSymbolRefExpr::VK_TLVPPAGEOFF, "TLVPPAGEOFF"},
+    {MCSymbolRefExpr::VK_TPOFF, "TPOFF"},
+};
+
 void X86MCAsmInfoDarwin::anchor() { }
 
 X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T) {
@@ -69,6 +100,8 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T) {
   // (actually, must, since otherwise the non-extern relocations we produce
   // overwhelm ld64's tiny little mind and it fails).
   DwarfFDESymbolsUseAbsDiff = true;
+
+  initializeVariantKinds(variantKindDescs);
 }
 
 X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple)
@@ -96,6 +129,8 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) {
 
   // Exceptions handling
   ExceptionsType = ExceptionHandling::DwarfCFI;
+
+  initializeVariantKinds(variantKindDescs);
 }
 
 const MCExpr *
@@ -129,6 +164,8 @@ X86MCAsmInfoMicrosoft::X86MCAsmInfoMicrosoft(const Triple &Triple) {
   AssemblerDialect = X86AsmSyntax;
 
   AllowAtInName = true;
+
+  initializeVariantKinds(variantKindDescs);
 }
 
 void X86MCAsmInfoMicrosoftMASM::anchor() { }
@@ -162,4 +199,6 @@ X86MCAsmInfoGNUCOFF::X86MCAsmInfoGNUCOFF(const Triple &Triple) {
   AssemblerDialect = X86AsmSyntax;
 
   AllowAtInName = true;
+
+  initializeVariantKinds(variantKindDescs);
 }


        


More information about the llvm-commits mailing list