Author: Alexis Engelke
Date: 2026-06-28T07:17:02+02:00
New Revision: 3288c8f43dad7915cb5cb2e4dbf4c9ad7164b378

URL: 
https://github.com/llvm/llvm-project/commit/3288c8f43dad7915cb5cb2e4dbf4c9ad7164b378
DIFF: 
https://github.com/llvm/llvm-project/commit/3288c8f43dad7915cb5cb2e4dbf4c9ad7164b378.diff

LOG: [CodeView][NFC] Use compact enum tables. (#206071)

Largely a straight-forward replacement.

Added: 
    

Modified: 
    lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
    llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
    llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h
    llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/lib/DebugInfo/CodeView/EnumTables.cpp
    llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
    llvm/lib/DebugInfo/LogicalView/Core/LVSourceLanguage.cpp
    llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
    llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
    llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
    llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp

Removed: 
    


################################################################################
diff  --git 
a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp 
b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
index f28509acbf79f..32644aad98405 100644
--- 
a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ 
b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -14,10 +14,10 @@
 #include "lldb/Utility/Stream.h"
 #include "llvm/ADT/DenseMap.h"
 
+#include "llvm/ADT/Enum.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/Support/ScopedPrinter.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -36,18 +36,17 @@ static uint32_t ResolveLLDBRegisterNum(llvm::StringRef 
reg_name, llvm::Triple::A
       break;
   }
 
-  llvm::ArrayRef<llvm::EnumEntry<uint16_t>> register_names =
+  llvm::EnumStrings<uint16_t> register_names =
       llvm::codeview::getRegisterNames(cpu_type);
-  auto it = llvm::find_if(
-      register_names,
-      [&reg_name](const llvm::EnumEntry<uint16_t> &register_entry) {
-        return reg_name.compare_insensitive(register_entry.Name) == 0;
+  auto it =
+      llvm::find_if(register_names, [&reg_name](const auto &register_entry) {
+        return reg_name.compare_insensitive(register_entry.name()) == 0;
       });
 
   if (it == register_names.end())
     return LLDB_INVALID_REGNUM;
 
-  auto reg_id = static_cast<llvm::codeview::RegisterId>(it->Value);
+  auto reg_id = static_cast<llvm::codeview::RegisterId>(it->value());
   return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
 }
 

diff  --git a/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h 
b/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
index d4b48d932806f..0dfa3d5b0942a 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -9,47 +9,46 @@
 #ifndef LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
 #define LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
 
-#include "llvm/ADT/ArrayRef.h"
 #include "llvm/BinaryFormat/COFF.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/Support/Compiler.h"
 #include <cstdint>
 
 namespace llvm {
-template <typename T> struct EnumEntry;
+template <typename, unsigned> class EnumStrings;
 namespace codeview {
 
-LLVM_ABI ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();
-LLVM_ABI ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu);
-LLVM_ABI ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames();
-LLVM_ABI ArrayRef<EnumEntry<SourceLanguage>> getSourceLanguageNames();
-LLVM_ABI ArrayRef<EnumEntry<uint32_t>> getCompileSym2FlagNames();
-LLVM_ABI ArrayRef<EnumEntry<uint32_t>> getCompileSym3FlagNames();
-LLVM_ABI ArrayRef<EnumEntry<uint32_t>> getFileChecksumNames();
-LLVM_ABI ArrayRef<EnumEntry<unsigned>> getCPUTypeNames();
-LLVM_ABI ArrayRef<EnumEntry<uint32_t>> getFrameProcSymFlagNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getExportSymFlagNames();
-LLVM_ABI ArrayRef<EnumEntry<uint32_t>> getModuleSubstreamKindNames();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getTrampolineNames();
-LLVM_ABI ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
+LLVM_ABI EnumStrings<SymbolKind, 1> getSymbolTypeNames();
+LLVM_ABI EnumStrings<TypeLeafKind, 1> getTypeLeafNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getRegisterNames(CPUType Cpu);
+LLVM_ABI EnumStrings<uint32_t, 1> getPublicSymFlagNames();
+LLVM_ABI EnumStrings<uint8_t, 1> getProcSymFlagNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getLocalFlagNames();
+LLVM_ABI EnumStrings<uint8_t, 1> getFrameCookieKindNames();
+LLVM_ABI EnumStrings<SourceLanguage, 1> getSourceLanguageNames();
+LLVM_ABI EnumStrings<uint32_t, 1> getCompileSym2FlagNames();
+LLVM_ABI EnumStrings<uint32_t, 1> getCompileSym3FlagNames();
+LLVM_ABI EnumStrings<uint32_t, 1> getFileChecksumNames();
+LLVM_ABI EnumStrings<unsigned, 1> getCPUTypeNames();
+LLVM_ABI EnumStrings<uint32_t, 1> getFrameProcSymFlagNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getExportSymFlagNames();
+LLVM_ABI EnumStrings<uint32_t, 1> getModuleSubstreamKindNames();
+LLVM_ABI EnumStrings<uint8_t, 1> getThunkOrdinalNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getTrampolineNames();
+LLVM_ABI EnumStrings<COFF::SectionCharacteristics, 1>
 getImageSectionCharacteristicNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getClassOptionNames();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getMemberKindNames();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getPtrKindNames();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getPtrModeNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getCallingConventions();
-LLVM_ABI ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum();
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getJumpTableEntrySizeNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getClassOptionNames();
+LLVM_ABI EnumStrings<uint8_t, 1> getMemberAccessNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getMethodOptionNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getMemberKindNames();
+LLVM_ABI EnumStrings<uint8_t, 1> getPtrKindNames();
+LLVM_ABI EnumStrings<uint8_t, 1> getPtrModeNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getPtrMemberRepNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getTypeModifierNames();
+LLVM_ABI EnumStrings<uint8_t, 1> getCallingConventions();
+LLVM_ABI EnumStrings<uint8_t, 1> getFunctionOptionEnum();
+LLVM_ABI EnumStrings<uint16_t, 1> getLabelTypeEnum();
+LLVM_ABI EnumStrings<uint16_t, 1> getJumpTableEntrySizeNames();
 
 } // end namespace codeview
 } // end namespace llvm

diff  --git a/llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h 
b/llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h
index 1226fb877ee8d..9b3775c6aed07 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h
@@ -12,9 +12,9 @@
 #include "llvm/ADT/ArrayRef.h"
 
 namespace llvm {
-template <typename T> struct EnumEntry;
+template <typename, unsigned> class EnumStrings;
 namespace pdb {
-LLVM_ABI ArrayRef<EnumEntry<uint16_t>> getOMFSegMapDescFlagNames();
+LLVM_ABI EnumStrings<uint16_t, 1> getOMFSegMapDescFlagNames();
 }
 }
 

diff  --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp 
b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index ccec0b5910658..06353a0e039db 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -3189,13 +3189,6 @@ void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) {
   OS.emitValueToAlignment(Align(4));
 }
 
-static StringRef getSymbolName(SymbolKind SymKind) {
-  for (const EnumEntry<SymbolKind> &EE : getSymbolTypeNames())
-    if (EE.Value == SymKind)
-      return EE.Name;
-  return "";
-}
-
 MCSymbol *CodeViewDebug::beginSymbolRecord(SymbolKind SymKind) {
   MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),
            *EndLabel = MMI->getContext().createTempSymbol();
@@ -3203,7 +3196,7 @@ MCSymbol *CodeViewDebug::beginSymbolRecord(SymbolKind 
SymKind) {
   OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
   OS.emitLabel(BeginLabel);
   if (OS.isVerboseAsm())
-    OS.AddComment("Record kind: " + getSymbolName(SymKind));
+    OS.AddComment("Record kind: " + getSymbolTypeNames().toString(SymKind));
   OS.emitInt16(unsigned(SymKind));
   return EndLabel;
 }
@@ -3221,7 +3214,7 @@ void CodeViewDebug::emitEndSymbolRecord(SymbolKind 
EndKind) {
   OS.AddComment("Record length");
   OS.emitInt16(2);
   if (OS.isVerboseAsm())
-    OS.AddComment("Record kind: " + getSymbolName(EndKind));
+    OS.AddComment("Record kind: " + getSymbolTypeNames().toString(EndKind));
   OS.emitInt16(uint16_t(EndKind)); // Record Kind
 }
 

diff  --git a/llvm/lib/DebugInfo/CodeView/EnumTables.cpp 
b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
index 1ff34bd27e368..383922d5c6ff7 100644
--- a/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -7,578 +7,619 @@
 
//===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/ADT/Enum.h"
 #include <type_traits>
 
 using namespace llvm;
 using namespace codeview;
 
 #define CV_ENUM_CLASS_ENT(enum_class, enum)                                    
\
-  { #enum, std::underlying_type_t<enum_class>(enum_class::enum) }
+  {{#enum}, std::underlying_type_t<enum_class>(enum_class::enum)}
 
-#define CV_ENUM_ENT(ns, enum)                                                  
\
-  { #enum, ns::enum }
+#define CV_ENUM_ENT(ns, enum) {{#enum}, ns::enum}
 
-static const EnumEntry<SymbolKind> SymbolTypeNames[] = {
-#define CV_SYMBOL(enum, val) {#enum, enum},
+namespace llvm {
+namespace codeview {
+
+EnumStrings<SymbolKind> getSymbolTypeNames() {
+  constexpr EnumStringDef<SymbolKind> SymbolTypeNameDefs[] = {
+#define CV_SYMBOL(enum, val) {{#enum}, enum},
 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
 #undef CV_SYMBOL
-};
+  };
+  static constexpr auto SymbolTypeNames =
+      BUILD_ENUM_STRINGS(SymbolTypeNameDefs);
+  return SymbolTypeNames;
+}
 
-static const EnumEntry<TypeLeafKind> TypeLeafNames[] = {
-#define CV_TYPE(name, val) {#name, name},
+EnumStrings<TypeLeafKind> getTypeLeafNames() {
+  constexpr EnumStringDef<TypeLeafKind> TypeLeafNameDefs[] = {
+#define CV_TYPE(name, val) {{#name}, name},
 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
 #undef CV_TYPE
-};
+  };
+  static constexpr auto TypeLeafNames = BUILD_ENUM_STRINGS(TypeLeafNameDefs);
+  return TypeLeafNames;
+}
 
-static const EnumEntry<uint16_t> RegisterNames_X86[] = {
+EnumStrings<uint16_t> getRegisterNames(CPUType Cpu) {
+  constexpr EnumStringDef<uint16_t> RegisterNameDefs_X86[] = {
 #define CV_REGISTERS_X86
 #define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
 #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
 #undef CV_REGISTER
 #undef CV_REGISTERS_X86
-};
+  };
+  static constexpr auto RegisterNames_X86 =
+      BUILD_ENUM_STRINGS(RegisterNameDefs_X86);
 
-static const EnumEntry<uint16_t> RegisterNames_ARM[] = {
+  constexpr EnumStringDef<uint16_t> RegisterNameDefs_ARM[] = {
 #define CV_REGISTERS_ARM
 #define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
 #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
 #undef CV_REGISTER
 #undef CV_REGISTERS_ARM
-};
+  };
+  static constexpr auto RegisterNames_ARM =
+      BUILD_ENUM_STRINGS(RegisterNameDefs_ARM);
 
-static const EnumEntry<uint16_t> RegisterNames_ARM64[] = {
+  constexpr EnumStringDef<uint16_t> RegisterNameDefs_ARM64[] = {
 #define CV_REGISTERS_ARM64
 #define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
 #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
 #undef CV_REGISTER
 #undef CV_REGISTERS_ARM64
-};
-
-static const EnumEntry<uint32_t> PublicSymFlagNames[] = {
-    CV_ENUM_CLASS_ENT(PublicSymFlags, Code),
-    CV_ENUM_CLASS_ENT(PublicSymFlags, Function),
-    CV_ENUM_CLASS_ENT(PublicSymFlags, Managed),
-    CV_ENUM_CLASS_ENT(PublicSymFlags, MSIL),
-};
-
-static const EnumEntry<uint8_t> ProcSymFlagNames[] = {
-    CV_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
-    CV_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
-    CV_ENUM_CLASS_ENT(ProcSymFlags, HasFRET),
-    CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn),
-    CV_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable),
-    CV_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv),
-    CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline),
-    CV_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
-};
-
-static const EnumEntry<uint16_t> LocalFlags[] = {
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
-    CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
-};
-
-static const EnumEntry<uint8_t> FrameCookieKinds[] = {
-    CV_ENUM_CLASS_ENT(FrameCookieKind, Copy),
-    CV_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
-    CV_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
-    CV_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
-};
-
-static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
-    CV_ENUM_ENT(SourceLanguage, C),        CV_ENUM_ENT(SourceLanguage, Cpp),
-    CV_ENUM_ENT(SourceLanguage, Fortran),  CV_ENUM_ENT(SourceLanguage, Masm),
-    CV_ENUM_ENT(SourceLanguage, Pascal),   CV_ENUM_ENT(SourceLanguage, Basic),
-    CV_ENUM_ENT(SourceLanguage, Cobol),    CV_ENUM_ENT(SourceLanguage, Link),
-    CV_ENUM_ENT(SourceLanguage, Cvtres),   CV_ENUM_ENT(SourceLanguage, Cvtpgd),
-    CV_ENUM_ENT(SourceLanguage, CSharp),   CV_ENUM_ENT(SourceLanguage, VB),
-    CV_ENUM_ENT(SourceLanguage, ILAsm),    CV_ENUM_ENT(SourceLanguage, Java),
-    CV_ENUM_ENT(SourceLanguage, JScript),  CV_ENUM_ENT(SourceLanguage, MSIL),
-    CV_ENUM_ENT(SourceLanguage, HLSL),     CV_ENUM_ENT(SourceLanguage, D),
-    CV_ENUM_ENT(SourceLanguage, Swift),    CV_ENUM_ENT(SourceLanguage, Rust),
-    CV_ENUM_ENT(SourceLanguage, ObjC),     CV_ENUM_ENT(SourceLanguage, ObjCpp),
-    CV_ENUM_ENT(SourceLanguage, AliasObj), CV_ENUM_ENT(SourceLanguage, Go),
-    {"Swift", SourceLanguage::OldSwift},
-};
-
-static const EnumEntry<uint32_t> CompileSym2FlagNames[] = {
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, EC),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDbgInfo),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, LTCG),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDataAlign),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, ManagedPresent),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, SecurityChecks),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, HotPatch),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, CVTCIL),
-    CV_ENUM_CLASS_ENT(CompileSym2Flags, MSILModule),
-};
-
-static const EnumEntry<uint32_t> CompileSym3FlagNames[] = {
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, EC),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
-    CV_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
-};
-
-static const EnumEntry<uint32_t> FileChecksumNames[] = {
-    CV_ENUM_CLASS_ENT(FileChecksumKind, None),
-    CV_ENUM_CLASS_ENT(FileChecksumKind, MD5),
-    CV_ENUM_CLASS_ENT(FileChecksumKind, SHA1),
-    CV_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
-};
-
-static const EnumEntry<unsigned> CPUTypeNames[] = {
-    CV_ENUM_CLASS_ENT(CPUType, Intel8080),
-    CV_ENUM_CLASS_ENT(CPUType, Intel8086),
-    CV_ENUM_CLASS_ENT(CPUType, Intel80286),
-    CV_ENUM_CLASS_ENT(CPUType, Intel80386),
-    CV_ENUM_CLASS_ENT(CPUType, Intel80486),
-    CV_ENUM_CLASS_ENT(CPUType, Pentium),
-    CV_ENUM_CLASS_ENT(CPUType, PentiumPro),
-    CV_ENUM_CLASS_ENT(CPUType, Pentium3),
-    CV_ENUM_CLASS_ENT(CPUType, MIPS),
-    CV_ENUM_CLASS_ENT(CPUType, MIPS16),
-    CV_ENUM_CLASS_ENT(CPUType, MIPS32),
-    CV_ENUM_CLASS_ENT(CPUType, MIPS64),
-    CV_ENUM_CLASS_ENT(CPUType, MIPSI),
-    CV_ENUM_CLASS_ENT(CPUType, MIPSII),
-    CV_ENUM_CLASS_ENT(CPUType, MIPSIII),
-    CV_ENUM_CLASS_ENT(CPUType, MIPSIV),
-    CV_ENUM_CLASS_ENT(CPUType, MIPSV),
-    CV_ENUM_CLASS_ENT(CPUType, M68000),
-    CV_ENUM_CLASS_ENT(CPUType, M68010),
-    CV_ENUM_CLASS_ENT(CPUType, M68020),
-    CV_ENUM_CLASS_ENT(CPUType, M68030),
-    CV_ENUM_CLASS_ENT(CPUType, M68040),
-    CV_ENUM_CLASS_ENT(CPUType, Alpha),
-    CV_ENUM_CLASS_ENT(CPUType, Alpha21164),
-    CV_ENUM_CLASS_ENT(CPUType, Alpha21164A),
-    CV_ENUM_CLASS_ENT(CPUType, Alpha21264),
-    CV_ENUM_CLASS_ENT(CPUType, Alpha21364),
-    CV_ENUM_CLASS_ENT(CPUType, PPC601),
-    CV_ENUM_CLASS_ENT(CPUType, PPC603),
-    CV_ENUM_CLASS_ENT(CPUType, PPC604),
-    CV_ENUM_CLASS_ENT(CPUType, PPC620),
-    CV_ENUM_CLASS_ENT(CPUType, PPCFP),
-    CV_ENUM_CLASS_ENT(CPUType, PPCBE),
-    CV_ENUM_CLASS_ENT(CPUType, SH3),
-    CV_ENUM_CLASS_ENT(CPUType, SH3E),
-    CV_ENUM_CLASS_ENT(CPUType, SH3DSP),
-    CV_ENUM_CLASS_ENT(CPUType, SH4),
-    CV_ENUM_CLASS_ENT(CPUType, SHMedia),
-    CV_ENUM_CLASS_ENT(CPUType, ARM3),
-    CV_ENUM_CLASS_ENT(CPUType, ARM4),
-    CV_ENUM_CLASS_ENT(CPUType, ARM4T),
-    CV_ENUM_CLASS_ENT(CPUType, ARM5),
-    CV_ENUM_CLASS_ENT(CPUType, ARM5T),
-    CV_ENUM_CLASS_ENT(CPUType, ARM6),
-    CV_ENUM_CLASS_ENT(CPUType, ARM_XMAC),
-    CV_ENUM_CLASS_ENT(CPUType, ARM_WMMX),
-    CV_ENUM_CLASS_ENT(CPUType, ARM7),
-    CV_ENUM_CLASS_ENT(CPUType, Omni),
-    CV_ENUM_CLASS_ENT(CPUType, Ia64),
-    CV_ENUM_CLASS_ENT(CPUType, Ia64_2),
-    CV_ENUM_CLASS_ENT(CPUType, CEE),
-    CV_ENUM_CLASS_ENT(CPUType, AM33),
-    CV_ENUM_CLASS_ENT(CPUType, M32R),
-    CV_ENUM_CLASS_ENT(CPUType, TriCore),
-    CV_ENUM_CLASS_ENT(CPUType, X64),
-    CV_ENUM_CLASS_ENT(CPUType, EBC),
-    CV_ENUM_CLASS_ENT(CPUType, Thumb),
-    CV_ENUM_CLASS_ENT(CPUType, ARMNT),
-    CV_ENUM_CLASS_ENT(CPUType, ARM64),
-    CV_ENUM_CLASS_ENT(CPUType, HybridX86ARM64),
-    CV_ENUM_CLASS_ENT(CPUType, ARM64EC),
-    CV_ENUM_CLASS_ENT(CPUType, ARM64X),
-    CV_ENUM_CLASS_ENT(CPUType, Unknown),
-    CV_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
-};
-
-static const EnumEntry<uint32_t> FrameProcSymFlagNames[] = {
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasStructuredExceptionHandling),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, AsynchronousExceptionHandling),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, NoStackOrderingForSecurityChecks),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedLocalBasePointerMask),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedParamBasePointerMask),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
-    CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
-};
-
-static const EnumEntry<uint32_t> ModuleSubstreamKindNames[] = {
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, None),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, Symbols),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, Lines),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, StringTable),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, FileChecksums),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, FrameData),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, InlineeLines),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeImports),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeExports),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, ILLines),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, FuncMDTokenMap),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, TypeMDTokenMap),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, MergedAssemblyInput),
-    CV_ENUM_CLASS_ENT(DebugSubsectionKind, CoffSymbolRVA),
-};
-
-static const EnumEntry<uint16_t> ExportSymFlagNames[] = {
-    CV_ENUM_CLASS_ENT(ExportFlags, IsConstant),
-    CV_ENUM_CLASS_ENT(ExportFlags, IsData),
-    CV_ENUM_CLASS_ENT(ExportFlags, IsPrivate),
-    CV_ENUM_CLASS_ENT(ExportFlags, HasNoName),
-    CV_ENUM_CLASS_ENT(ExportFlags, HasExplicitOrdinal),
-    CV_ENUM_CLASS_ENT(ExportFlags, IsForwarder),
-};
-
-static const EnumEntry<uint8_t> ThunkOrdinalNames[] = {
-    CV_ENUM_CLASS_ENT(ThunkOrdinal, Standard),
-    CV_ENUM_CLASS_ENT(ThunkOrdinal, ThisAdjustor),
-    CV_ENUM_CLASS_ENT(ThunkOrdinal, Vcall),
-    CV_ENUM_CLASS_ENT(ThunkOrdinal, Pcode),
-    CV_ENUM_CLASS_ENT(ThunkOrdinal, UnknownLoad),
-    CV_ENUM_CLASS_ENT(ThunkOrdinal, TrampIncremental),
-    CV_ENUM_CLASS_ENT(ThunkOrdinal, BranchIsland),
-};
-
-static const EnumEntry<uint16_t> TrampolineNames[] = {
-    CV_ENUM_CLASS_ENT(TrampolineType, TrampIncremental),
-    CV_ENUM_CLASS_ENT(TrampolineType, BranchIsland),
-};
-
-static const EnumEntry<COFF::SectionCharacteristics>
-    ImageSectionCharacteristicNames[] = {
-        CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_GPREL),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ),
-        CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE)};
-
-static const EnumEntry<uint16_t> ClassOptionNames[] = {
-    CV_ENUM_CLASS_ENT(ClassOptions, Packed),
-    CV_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor),
-    CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator),
-    CV_ENUM_CLASS_ENT(ClassOptions, Nested),
-    CV_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass),
-    CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator),
-    CV_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator),
-    CV_ENUM_CLASS_ENT(ClassOptions, ForwardReference),
-    CV_ENUM_CLASS_ENT(ClassOptions, Scoped),
-    CV_ENUM_CLASS_ENT(ClassOptions, HasUniqueName),
-    CV_ENUM_CLASS_ENT(ClassOptions, Sealed),
-    CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
-};
-
-static const EnumEntry<uint8_t> MemberAccessNames[] = {
-    CV_ENUM_CLASS_ENT(MemberAccess, None),
-    CV_ENUM_CLASS_ENT(MemberAccess, Private),
-    CV_ENUM_CLASS_ENT(MemberAccess, Protected),
-    CV_ENUM_CLASS_ENT(MemberAccess, Public),
-};
-
-static const EnumEntry<uint16_t> MethodOptionNames[] = {
-    CV_ENUM_CLASS_ENT(MethodOptions, Pseudo),
-    CV_ENUM_CLASS_ENT(MethodOptions, NoInherit),
-    CV_ENUM_CLASS_ENT(MethodOptions, NoConstruct),
-    CV_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated),
-    CV_ENUM_CLASS_ENT(MethodOptions, Sealed),
-};
-
-static const EnumEntry<uint16_t> MemberKindNames[] = {
-    CV_ENUM_CLASS_ENT(MethodKind, Vanilla),
-    CV_ENUM_CLASS_ENT(MethodKind, Virtual),
-    CV_ENUM_CLASS_ENT(MethodKind, Static),
-    CV_ENUM_CLASS_ENT(MethodKind, Friend),
-    CV_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual),
-    CV_ENUM_CLASS_ENT(MethodKind, PureVirtual),
-    CV_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual),
-};
-
-static const EnumEntry<uint8_t> PtrKindNames[] = {
-    CV_ENUM_CLASS_ENT(PointerKind, Near16),
-    CV_ENUM_CLASS_ENT(PointerKind, Far16),
-    CV_ENUM_CLASS_ENT(PointerKind, Huge16),
-    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegment),
-    CV_ENUM_CLASS_ENT(PointerKind, BasedOnValue),
-    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue),
-    CV_ENUM_CLASS_ENT(PointerKind, BasedOnAddress),
-    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress),
-    CV_ENUM_CLASS_ENT(PointerKind, BasedOnType),
-    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSelf),
-    CV_ENUM_CLASS_ENT(PointerKind, Near32),
-    CV_ENUM_CLASS_ENT(PointerKind, Far32),
-    CV_ENUM_CLASS_ENT(PointerKind, Near64),
-};
-
-static const EnumEntry<uint8_t> PtrModeNames[] = {
-    CV_ENUM_CLASS_ENT(PointerMode, Pointer),
-    CV_ENUM_CLASS_ENT(PointerMode, LValueReference),
-    CV_ENUM_CLASS_ENT(PointerMode, PointerToDataMember),
-    CV_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction),
-    CV_ENUM_CLASS_ENT(PointerMode, RValueReference),
-};
-
-static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceData),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, MultipleInheritanceData),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, VirtualInheritanceData),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, 
SingleInheritanceFunction),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
-                      MultipleInheritanceFunction),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
-                      VirtualInheritanceFunction),
-    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction),
-};
-
-static const EnumEntry<uint16_t> TypeModifierNames[] = {
-    CV_ENUM_CLASS_ENT(ModifierOptions, Const),
-    CV_ENUM_CLASS_ENT(ModifierOptions, Volatile),
-    CV_ENUM_CLASS_ENT(ModifierOptions, Unaligned),
-};
-
-static const EnumEntry<uint8_t> CallingConventions[] = {
-    CV_ENUM_CLASS_ENT(CallingConvention, NearC),
-    CV_ENUM_CLASS_ENT(CallingConvention, FarC),
-    CV_ENUM_CLASS_ENT(CallingConvention, NearPascal),
-    CV_ENUM_CLASS_ENT(CallingConvention, FarPascal),
-    CV_ENUM_CLASS_ENT(CallingConvention, NearFast),
-    CV_ENUM_CLASS_ENT(CallingConvention, FarFast),
-    CV_ENUM_CLASS_ENT(CallingConvention, NearStdCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, FarStdCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, NearSysCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, FarSysCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, ThisCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, MipsCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, Generic),
-    CV_ENUM_CLASS_ENT(CallingConvention, AlphaCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, PpcCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, SHCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, ArmCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, AM33Call),
-    CV_ENUM_CLASS_ENT(CallingConvention, TriCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, SH5Call),
-    CV_ENUM_CLASS_ENT(CallingConvention, M32RCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, ClrCall),
-    CV_ENUM_CLASS_ENT(CallingConvention, Inline),
-    CV_ENUM_CLASS_ENT(CallingConvention, NearVector),
-    CV_ENUM_CLASS_ENT(CallingConvention, Swift),
-};
-
-static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
-    CV_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt),
-    CV_ENUM_CLASS_ENT(FunctionOptions, Constructor),
-    CV_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases),
-};
-
-static const EnumEntry<uint16_t> LabelTypeEnum[] = {
-    CV_ENUM_CLASS_ENT(LabelType, Near),
-    CV_ENUM_CLASS_ENT(LabelType, Far),
-};
-
-static const EnumEntry<uint16_t> JumpTableEntrySizeNames[] = {
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int8),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt8),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int16),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt16),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int32),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt32),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, Pointer),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt8ShiftLeft),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt16ShiftLeft),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int8ShiftLeft),
-    CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int16ShiftLeft),
-};
-
-namespace llvm {
-namespace codeview {
-
-ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames() {
-  return ArrayRef(SymbolTypeNames);
-}
-
-ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() {
-  return ArrayRef(TypeLeafNames);
-}
+  };
+  static constexpr auto RegisterNames_ARM64 =
+      BUILD_ENUM_STRINGS(RegisterNameDefs_ARM64);
 
-ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu) {
   if (Cpu == CPUType::ARMNT) {
-    return ArrayRef(RegisterNames_ARM);
+    return RegisterNames_ARM;
   } else if (Cpu == CPUType::ARM64) {
-    return ArrayRef(RegisterNames_ARM64);
+    return RegisterNames_ARM64;
   }
-  return ArrayRef(RegisterNames_X86);
+  return RegisterNames_X86;
 }
 
-ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames() {
-  return ArrayRef(PublicSymFlagNames);
+EnumStrings<uint32_t> getPublicSymFlagNames() {
+  constexpr EnumStringDef<uint32_t> PublicSymFlagNameDefs[] = {
+      CV_ENUM_CLASS_ENT(PublicSymFlags, Code),
+      CV_ENUM_CLASS_ENT(PublicSymFlags, Function),
+      CV_ENUM_CLASS_ENT(PublicSymFlags, Managed),
+      CV_ENUM_CLASS_ENT(PublicSymFlags, MSIL),
+  };
+  static constexpr auto PublicSymFlagNames =
+      BUILD_ENUM_STRINGS(PublicSymFlagNameDefs);
+  return PublicSymFlagNames;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames() {
-  return ArrayRef(ProcSymFlagNames);
+EnumStrings<uint8_t> getProcSymFlagNames() {
+  constexpr EnumStringDef<uint8_t> ProcSymFlagNameDefs[] = {
+      CV_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
+      CV_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
+      CV_ENUM_CLASS_ENT(ProcSymFlags, HasFRET),
+      CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn),
+      CV_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable),
+      CV_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv),
+      CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline),
+      CV_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
+  };
+  static constexpr auto ProcSymFlagNames =
+      BUILD_ENUM_STRINGS(ProcSymFlagNameDefs);
+  return ProcSymFlagNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames() {
-  return ArrayRef(LocalFlags);
+EnumStrings<uint16_t> getLocalFlagNames() {
+  constexpr EnumStringDef<uint16_t> LocalFlagDefs[] = {
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
+      CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
+  };
+  static constexpr auto LocalFlags = BUILD_ENUM_STRINGS(LocalFlagDefs);
+  return LocalFlags;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames() {
-  return ArrayRef(FrameCookieKinds);
+EnumStrings<uint8_t> getFrameCookieKindNames() {
+  constexpr EnumStringDef<uint8_t> FrameCookieKindDefs[] = {
+      CV_ENUM_CLASS_ENT(FrameCookieKind, Copy),
+      CV_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
+      CV_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
+      CV_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
+  };
+  static constexpr auto FrameCookieKinds =
+      BUILD_ENUM_STRINGS(FrameCookieKindDefs);
+  return FrameCookieKinds;
 }
 
-ArrayRef<EnumEntry<SourceLanguage>> getSourceLanguageNames() {
-  return ArrayRef(SourceLanguages);
+EnumStrings<SourceLanguage> getSourceLanguageNames() {
+  constexpr EnumStringDef<codeview::SourceLanguage> SourceLanguageDefs[] = {
+      CV_ENUM_ENT(SourceLanguage, C),
+      CV_ENUM_ENT(SourceLanguage, Cpp),
+      CV_ENUM_ENT(SourceLanguage, Fortran),
+      CV_ENUM_ENT(SourceLanguage, Masm),
+      CV_ENUM_ENT(SourceLanguage, Pascal),
+      CV_ENUM_ENT(SourceLanguage, Basic),
+      CV_ENUM_ENT(SourceLanguage, Cobol),
+      CV_ENUM_ENT(SourceLanguage, Link),
+      CV_ENUM_ENT(SourceLanguage, Cvtres),
+      CV_ENUM_ENT(SourceLanguage, Cvtpgd),
+      CV_ENUM_ENT(SourceLanguage, CSharp),
+      CV_ENUM_ENT(SourceLanguage, VB),
+      CV_ENUM_ENT(SourceLanguage, ILAsm),
+      CV_ENUM_ENT(SourceLanguage, Java),
+      CV_ENUM_ENT(SourceLanguage, JScript),
+      CV_ENUM_ENT(SourceLanguage, MSIL),
+      CV_ENUM_ENT(SourceLanguage, HLSL),
+      CV_ENUM_ENT(SourceLanguage, D),
+      CV_ENUM_ENT(SourceLanguage, Swift),
+      CV_ENUM_ENT(SourceLanguage, Rust),
+      CV_ENUM_ENT(SourceLanguage, ObjC),
+      CV_ENUM_ENT(SourceLanguage, ObjCpp),
+      CV_ENUM_ENT(SourceLanguage, AliasObj),
+      CV_ENUM_ENT(SourceLanguage, Go),
+      {{"Swift"}, SourceLanguage::OldSwift},
+  };
+  static constexpr auto SourceLanguages =
+      BUILD_ENUM_STRINGS(SourceLanguageDefs);
+  return SourceLanguages;
 }
 
-ArrayRef<EnumEntry<uint32_t>> getCompileSym2FlagNames() {
-  return ArrayRef(CompileSym2FlagNames);
+EnumStrings<uint32_t> getCompileSym2FlagNames() {
+  constexpr EnumStringDef<uint32_t> CompileSym2FlagNameDefs[] = {
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, EC),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDbgInfo),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, LTCG),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDataAlign),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, ManagedPresent),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, SecurityChecks),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, HotPatch),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, CVTCIL),
+      CV_ENUM_CLASS_ENT(CompileSym2Flags, MSILModule),
+  };
+  static constexpr auto CompileSym2FlagNames =
+      BUILD_ENUM_STRINGS(CompileSym2FlagNameDefs);
+  return CompileSym2FlagNames;
 }
 
-ArrayRef<EnumEntry<uint32_t>> getCompileSym3FlagNames() {
-  return ArrayRef(CompileSym3FlagNames);
+EnumStrings<uint32_t> getCompileSym3FlagNames() {
+  constexpr EnumStringDef<uint32_t> CompileSym3FlagNameDefs[] = {
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, EC),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
+      CV_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
+  };
+  static constexpr auto CompileSym3FlagNames =
+      BUILD_ENUM_STRINGS(CompileSym3FlagNameDefs);
+  return CompileSym3FlagNames;
 }
 
-ArrayRef<EnumEntry<uint32_t>> getFileChecksumNames() {
-  return ArrayRef(FileChecksumNames);
+EnumStrings<uint32_t> getFileChecksumNames() {
+  constexpr EnumStringDef<uint32_t> FileChecksumNameDefs[] = {
+      CV_ENUM_CLASS_ENT(FileChecksumKind, None),
+      CV_ENUM_CLASS_ENT(FileChecksumKind, MD5),
+      CV_ENUM_CLASS_ENT(FileChecksumKind, SHA1),
+      CV_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
+  };
+  static constexpr auto FileChecksumNames =
+      BUILD_ENUM_STRINGS(FileChecksumNameDefs);
+  return FileChecksumNames;
 }
 
-ArrayRef<EnumEntry<unsigned>> getCPUTypeNames() {
-  return ArrayRef(CPUTypeNames);
+EnumStrings<unsigned> getCPUTypeNames() {
+  constexpr EnumStringDef<unsigned> CPUTypeNameDefs[] = {
+      CV_ENUM_CLASS_ENT(CPUType, Intel8080),
+      CV_ENUM_CLASS_ENT(CPUType, Intel8086),
+      CV_ENUM_CLASS_ENT(CPUType, Intel80286),
+      CV_ENUM_CLASS_ENT(CPUType, Intel80386),
+      CV_ENUM_CLASS_ENT(CPUType, Intel80486),
+      CV_ENUM_CLASS_ENT(CPUType, Pentium),
+      CV_ENUM_CLASS_ENT(CPUType, PentiumPro),
+      CV_ENUM_CLASS_ENT(CPUType, Pentium3),
+      CV_ENUM_CLASS_ENT(CPUType, MIPS),
+      CV_ENUM_CLASS_ENT(CPUType, MIPS16),
+      CV_ENUM_CLASS_ENT(CPUType, MIPS32),
+      CV_ENUM_CLASS_ENT(CPUType, MIPS64),
+      CV_ENUM_CLASS_ENT(CPUType, MIPSI),
+      CV_ENUM_CLASS_ENT(CPUType, MIPSII),
+      CV_ENUM_CLASS_ENT(CPUType, MIPSIII),
+      CV_ENUM_CLASS_ENT(CPUType, MIPSIV),
+      CV_ENUM_CLASS_ENT(CPUType, MIPSV),
+      CV_ENUM_CLASS_ENT(CPUType, M68000),
+      CV_ENUM_CLASS_ENT(CPUType, M68010),
+      CV_ENUM_CLASS_ENT(CPUType, M68020),
+      CV_ENUM_CLASS_ENT(CPUType, M68030),
+      CV_ENUM_CLASS_ENT(CPUType, M68040),
+      CV_ENUM_CLASS_ENT(CPUType, Alpha),
+      CV_ENUM_CLASS_ENT(CPUType, Alpha21164),
+      CV_ENUM_CLASS_ENT(CPUType, Alpha21164A),
+      CV_ENUM_CLASS_ENT(CPUType, Alpha21264),
+      CV_ENUM_CLASS_ENT(CPUType, Alpha21364),
+      CV_ENUM_CLASS_ENT(CPUType, PPC601),
+      CV_ENUM_CLASS_ENT(CPUType, PPC603),
+      CV_ENUM_CLASS_ENT(CPUType, PPC604),
+      CV_ENUM_CLASS_ENT(CPUType, PPC620),
+      CV_ENUM_CLASS_ENT(CPUType, PPCFP),
+      CV_ENUM_CLASS_ENT(CPUType, PPCBE),
+      CV_ENUM_CLASS_ENT(CPUType, SH3),
+      CV_ENUM_CLASS_ENT(CPUType, SH3E),
+      CV_ENUM_CLASS_ENT(CPUType, SH3DSP),
+      CV_ENUM_CLASS_ENT(CPUType, SH4),
+      CV_ENUM_CLASS_ENT(CPUType, SHMedia),
+      CV_ENUM_CLASS_ENT(CPUType, ARM3),
+      CV_ENUM_CLASS_ENT(CPUType, ARM4),
+      CV_ENUM_CLASS_ENT(CPUType, ARM4T),
+      CV_ENUM_CLASS_ENT(CPUType, ARM5),
+      CV_ENUM_CLASS_ENT(CPUType, ARM5T),
+      CV_ENUM_CLASS_ENT(CPUType, ARM6),
+      CV_ENUM_CLASS_ENT(CPUType, ARM_XMAC),
+      CV_ENUM_CLASS_ENT(CPUType, ARM_WMMX),
+      CV_ENUM_CLASS_ENT(CPUType, ARM7),
+      CV_ENUM_CLASS_ENT(CPUType, Omni),
+      CV_ENUM_CLASS_ENT(CPUType, Ia64),
+      CV_ENUM_CLASS_ENT(CPUType, Ia64_2),
+      CV_ENUM_CLASS_ENT(CPUType, CEE),
+      CV_ENUM_CLASS_ENT(CPUType, AM33),
+      CV_ENUM_CLASS_ENT(CPUType, M32R),
+      CV_ENUM_CLASS_ENT(CPUType, TriCore),
+      CV_ENUM_CLASS_ENT(CPUType, X64),
+      CV_ENUM_CLASS_ENT(CPUType, EBC),
+      CV_ENUM_CLASS_ENT(CPUType, Thumb),
+      CV_ENUM_CLASS_ENT(CPUType, ARMNT),
+      CV_ENUM_CLASS_ENT(CPUType, ARM64),
+      CV_ENUM_CLASS_ENT(CPUType, HybridX86ARM64),
+      CV_ENUM_CLASS_ENT(CPUType, ARM64EC),
+      CV_ENUM_CLASS_ENT(CPUType, ARM64X),
+      CV_ENUM_CLASS_ENT(CPUType, Unknown),
+      CV_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
+  };
+  static constexpr auto CPUTypeNames = BUILD_ENUM_STRINGS(CPUTypeNameDefs);
+  return CPUTypeNames;
 }
 
-ArrayRef<EnumEntry<uint32_t>> getFrameProcSymFlagNames() {
-  return ArrayRef(FrameProcSymFlagNames);
+EnumStrings<uint32_t> getFrameProcSymFlagNames() {
+  constexpr EnumStringDef<uint32_t> FrameProcSymFlagNameDefs[] = {
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasStructuredExceptionHandling),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, AsynchronousExceptionHandling),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions,
+                        NoStackOrderingForSecurityChecks),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedLocalBasePointerMask),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedParamBasePointerMask),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
+      CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
+  };
+  static constexpr auto FrameProcSymFlagNames =
+      BUILD_ENUM_STRINGS(FrameProcSymFlagNameDefs);
+  return FrameProcSymFlagNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getExportSymFlagNames() {
-  return ArrayRef(ExportSymFlagNames);
+EnumStrings<uint16_t> getExportSymFlagNames() {
+  constexpr EnumStringDef<uint16_t> ExportSymFlagNameDefs[] = {
+      CV_ENUM_CLASS_ENT(ExportFlags, IsConstant),
+      CV_ENUM_CLASS_ENT(ExportFlags, IsData),
+      CV_ENUM_CLASS_ENT(ExportFlags, IsPrivate),
+      CV_ENUM_CLASS_ENT(ExportFlags, HasNoName),
+      CV_ENUM_CLASS_ENT(ExportFlags, HasExplicitOrdinal),
+      CV_ENUM_CLASS_ENT(ExportFlags, IsForwarder),
+  };
+  static constexpr auto ExportSymFlagNames =
+      BUILD_ENUM_STRINGS(ExportSymFlagNameDefs);
+  return ExportSymFlagNames;
 }
 
-ArrayRef<EnumEntry<uint32_t>> getModuleSubstreamKindNames() {
-  return ArrayRef(ModuleSubstreamKindNames);
+EnumStrings<uint32_t> getModuleSubstreamKindNames() {
+  constexpr EnumStringDef<uint32_t> ModuleSubstreamKindNameDefs[] = {
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, None),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, Symbols),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, Lines),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, StringTable),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, FileChecksums),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, FrameData),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, InlineeLines),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeImports),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeExports),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, ILLines),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, FuncMDTokenMap),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, TypeMDTokenMap),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, MergedAssemblyInput),
+      CV_ENUM_CLASS_ENT(DebugSubsectionKind, CoffSymbolRVA),
+  };
+  static constexpr auto ModuleSubstreamKindNames =
+      BUILD_ENUM_STRINGS(ModuleSubstreamKindNameDefs);
+  return ModuleSubstreamKindNames;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames() {
-  return ArrayRef(ThunkOrdinalNames);
+EnumStrings<uint8_t> getThunkOrdinalNames() {
+  constexpr EnumStringDef<uint8_t> ThunkOrdinalNameDefs[] = {
+      CV_ENUM_CLASS_ENT(ThunkOrdinal, Standard),
+      CV_ENUM_CLASS_ENT(ThunkOrdinal, ThisAdjustor),
+      CV_ENUM_CLASS_ENT(ThunkOrdinal, Vcall),
+      CV_ENUM_CLASS_ENT(ThunkOrdinal, Pcode),
+      CV_ENUM_CLASS_ENT(ThunkOrdinal, UnknownLoad),
+      CV_ENUM_CLASS_ENT(ThunkOrdinal, TrampIncremental),
+      CV_ENUM_CLASS_ENT(ThunkOrdinal, BranchIsland),
+  };
+  static constexpr auto ThunkOrdinalNames =
+      BUILD_ENUM_STRINGS(ThunkOrdinalNameDefs);
+  return ThunkOrdinalNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getTrampolineNames() {
-  return ArrayRef(TrampolineNames);
+EnumStrings<uint16_t> getTrampolineNames() {
+  constexpr EnumStringDef<uint16_t> TrampolineNameDefs[] = {
+      CV_ENUM_CLASS_ENT(TrampolineType, TrampIncremental),
+      CV_ENUM_CLASS_ENT(TrampolineType, BranchIsland),
+  };
+  static constexpr auto TrampolineNames =
+      BUILD_ENUM_STRINGS(TrampolineNameDefs);
+  return TrampolineNames;
 }
 
-ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
-getImageSectionCharacteristicNames() {
-  return ArrayRef(ImageSectionCharacteristicNames);
+EnumStrings<COFF::SectionCharacteristics> getImageSectionCharacteristicNames() 
{
+  constexpr EnumStringDef<COFF::SectionCharacteristics>
+      ImageSectionCharacteristicNameDefs[] = {
+          CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_GPREL),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ),
+          CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE)};
+  static constexpr auto ImageSectionCharacteristicNames =
+      BUILD_ENUM_STRINGS(ImageSectionCharacteristicNameDefs);
+  return ImageSectionCharacteristicNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getClassOptionNames() {
-  return ArrayRef(ClassOptionNames);
+EnumStrings<uint16_t> getClassOptionNames() {
+  constexpr EnumStringDef<uint16_t> ClassOptionNameDefs[] = {
+      CV_ENUM_CLASS_ENT(ClassOptions, Packed),
+      CV_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor),
+      CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator),
+      CV_ENUM_CLASS_ENT(ClassOptions, Nested),
+      CV_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass),
+      CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator),
+      CV_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator),
+      CV_ENUM_CLASS_ENT(ClassOptions, ForwardReference),
+      CV_ENUM_CLASS_ENT(ClassOptions, Scoped),
+      CV_ENUM_CLASS_ENT(ClassOptions, HasUniqueName),
+      CV_ENUM_CLASS_ENT(ClassOptions, Sealed),
+      CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
+  };
+  static constexpr auto ClassOptionNames =
+      BUILD_ENUM_STRINGS(ClassOptionNameDefs);
+  return ClassOptionNames;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames() {
-  return ArrayRef(MemberAccessNames);
+EnumStrings<uint8_t> getMemberAccessNames() {
+  constexpr EnumStringDef<uint8_t> MemberAccessNameDefs[] = {
+      CV_ENUM_CLASS_ENT(MemberAccess, None),
+      CV_ENUM_CLASS_ENT(MemberAccess, Private),
+      CV_ENUM_CLASS_ENT(MemberAccess, Protected),
+      CV_ENUM_CLASS_ENT(MemberAccess, Public),
+  };
+  static constexpr auto MemberAccessNames =
+      BUILD_ENUM_STRINGS(MemberAccessNameDefs);
+  return MemberAccessNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames() {
-  return ArrayRef(MethodOptionNames);
+EnumStrings<uint16_t> getMethodOptionNames() {
+  constexpr EnumStringDef<uint16_t> MethodOptionNameDefs[] = {
+      CV_ENUM_CLASS_ENT(MethodOptions, Pseudo),
+      CV_ENUM_CLASS_ENT(MethodOptions, NoInherit),
+      CV_ENUM_CLASS_ENT(MethodOptions, NoConstruct),
+      CV_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated),
+      CV_ENUM_CLASS_ENT(MethodOptions, Sealed),
+  };
+  static constexpr auto MethodOptionNames =
+      BUILD_ENUM_STRINGS(MethodOptionNameDefs);
+  return MethodOptionNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getMemberKindNames() {
-  return ArrayRef(MemberKindNames);
+EnumStrings<uint16_t> getMemberKindNames() {
+  constexpr EnumStringDef<uint16_t> MemberKindNameDefs[] = {
+      CV_ENUM_CLASS_ENT(MethodKind, Vanilla),
+      CV_ENUM_CLASS_ENT(MethodKind, Virtual),
+      CV_ENUM_CLASS_ENT(MethodKind, Static),
+      CV_ENUM_CLASS_ENT(MethodKind, Friend),
+      CV_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual),
+      CV_ENUM_CLASS_ENT(MethodKind, PureVirtual),
+      CV_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual),
+  };
+  static constexpr auto MemberKindNames =
+      BUILD_ENUM_STRINGS(MemberKindNameDefs);
+  return MemberKindNames;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getPtrKindNames() {
-  return ArrayRef(PtrKindNames);
+EnumStrings<uint8_t> getPtrKindNames() {
+  constexpr EnumStringDef<uint8_t> PtrKindNameDefs[] = {
+      CV_ENUM_CLASS_ENT(PointerKind, Near16),
+      CV_ENUM_CLASS_ENT(PointerKind, Far16),
+      CV_ENUM_CLASS_ENT(PointerKind, Huge16),
+      CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegment),
+      CV_ENUM_CLASS_ENT(PointerKind, BasedOnValue),
+      CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue),
+      CV_ENUM_CLASS_ENT(PointerKind, BasedOnAddress),
+      CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress),
+      CV_ENUM_CLASS_ENT(PointerKind, BasedOnType),
+      CV_ENUM_CLASS_ENT(PointerKind, BasedOnSelf),
+      CV_ENUM_CLASS_ENT(PointerKind, Near32),
+      CV_ENUM_CLASS_ENT(PointerKind, Far32),
+      CV_ENUM_CLASS_ENT(PointerKind, Near64),
+  };
+  static constexpr auto PtrKindNames = BUILD_ENUM_STRINGS(PtrKindNameDefs);
+  return PtrKindNames;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getPtrModeNames() {
-  return ArrayRef(PtrModeNames);
+EnumStrings<uint8_t> getPtrModeNames() {
+  constexpr EnumStringDef<uint8_t> PtrModeNameDefs[] = {
+      CV_ENUM_CLASS_ENT(PointerMode, Pointer),
+      CV_ENUM_CLASS_ENT(PointerMode, LValueReference),
+      CV_ENUM_CLASS_ENT(PointerMode, PointerToDataMember),
+      CV_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction),
+      CV_ENUM_CLASS_ENT(PointerMode, RValueReference),
+  };
+  static constexpr auto PtrModeNames = BUILD_ENUM_STRINGS(PtrModeNameDefs);
+  return PtrModeNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames() {
-  return ArrayRef(PtrMemberRepNames);
+EnumStrings<uint16_t> getPtrMemberRepNames() {
+  constexpr EnumStringDef<uint16_t> PtrMemberRepNameDefs[] = {
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceData),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, 
MultipleInheritanceData),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, VirtualInheritanceData),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+                        SingleInheritanceFunction),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+                        MultipleInheritanceFunction),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+                        VirtualInheritanceFunction),
+      CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction),
+  };
+  static constexpr auto PtrMemberRepNames =
+      BUILD_ENUM_STRINGS(PtrMemberRepNameDefs);
+  return PtrMemberRepNames;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames() {
-  return ArrayRef(TypeModifierNames);
+EnumStrings<uint16_t> getTypeModifierNames() {
+  constexpr EnumStringDef<uint16_t> TypeModifierNameDefs[] = {
+      CV_ENUM_CLASS_ENT(ModifierOptions, Const),
+      CV_ENUM_CLASS_ENT(ModifierOptions, Volatile),
+      CV_ENUM_CLASS_ENT(ModifierOptions, Unaligned),
+  };
+  static constexpr auto TypeModifierNames =
+      BUILD_ENUM_STRINGS(TypeModifierNameDefs);
+  return TypeModifierNames;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getCallingConventions() {
-  return ArrayRef(CallingConventions);
+EnumStrings<uint8_t> getCallingConventions() {
+  constexpr EnumStringDef<uint8_t> CallingConventionDefs[] = {
+      CV_ENUM_CLASS_ENT(CallingConvention, NearC),
+      CV_ENUM_CLASS_ENT(CallingConvention, FarC),
+      CV_ENUM_CLASS_ENT(CallingConvention, NearPascal),
+      CV_ENUM_CLASS_ENT(CallingConvention, FarPascal),
+      CV_ENUM_CLASS_ENT(CallingConvention, NearFast),
+      CV_ENUM_CLASS_ENT(CallingConvention, FarFast),
+      CV_ENUM_CLASS_ENT(CallingConvention, NearStdCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, FarStdCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, NearSysCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, FarSysCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, ThisCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, MipsCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, Generic),
+      CV_ENUM_CLASS_ENT(CallingConvention, AlphaCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, PpcCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, SHCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, ArmCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, AM33Call),
+      CV_ENUM_CLASS_ENT(CallingConvention, TriCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, SH5Call),
+      CV_ENUM_CLASS_ENT(CallingConvention, M32RCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, ClrCall),
+      CV_ENUM_CLASS_ENT(CallingConvention, Inline),
+      CV_ENUM_CLASS_ENT(CallingConvention, NearVector),
+      CV_ENUM_CLASS_ENT(CallingConvention, Swift),
+  };
+  static constexpr auto CallingConventions =
+      BUILD_ENUM_STRINGS(CallingConventionDefs);
+  return CallingConventions;
 }
 
-ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum() {
-  return ArrayRef(FunctionOptionEnum);
+EnumStrings<uint8_t> getFunctionOptionEnum() {
+  constexpr EnumStringDef<uint8_t> FunctionOptionEnumDefs[] = {
+      CV_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt),
+      CV_ENUM_CLASS_ENT(FunctionOptions, Constructor),
+      CV_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases),
+  };
+  static constexpr auto FunctionOptionEnum =
+      BUILD_ENUM_STRINGS(FunctionOptionEnumDefs);
+  return FunctionOptionEnum;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum() {
-  return ArrayRef(LabelTypeEnum);
+EnumStrings<uint16_t> getLabelTypeEnum() {
+  constexpr EnumStringDef<uint16_t> LabelTypeEnumDefs[] = {
+      CV_ENUM_CLASS_ENT(LabelType, Near),
+      CV_ENUM_CLASS_ENT(LabelType, Far),
+  };
+  static constexpr auto LabelTypeEnum = BUILD_ENUM_STRINGS(LabelTypeEnumDefs);
+  return LabelTypeEnum;
 }
 
-ArrayRef<EnumEntry<uint16_t>> getJumpTableEntrySizeNames() {
-  return ArrayRef(JumpTableEntrySizeNames);
+EnumStrings<uint16_t> getJumpTableEntrySizeNames() {
+  constexpr EnumStringDef<uint16_t> JumpTableEntrySizeNameDefs[] = {
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int8),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt8),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int16),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt16),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int32),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt32),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, Pointer),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt8ShiftLeft),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, UInt16ShiftLeft),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int8ShiftLeft),
+      CV_ENUM_CLASS_ENT(JumpTableEntrySize, Int16ShiftLeft),
+  };
+  static constexpr auto JumpTableEntrySizeNames =
+      BUILD_ENUM_STRINGS(JumpTableEntrySizeNameDefs);
+  return JumpTableEntrySizeNames;
 }
 
 } // end namespace codeview

diff  --git a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp 
b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index de2d3dfc9d7f9..e8c9744935bf7 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -52,38 +52,31 @@ static StringRef getLeafTypeName(TypeLeafKind LT) {
   return "UnknownLeaf";
 }
 
-template <typename T>
-static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
-  return lhs.Name < rhs.Name;
-}
-
 template <typename T, typename TFlag>
 static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
-                                ArrayRef<EnumEntry<TFlag>> Flags) {
+                                EnumStrings<TFlag> Flags) {
   if (!IO.isStreaming())
     return std::string("");
-  typedef EnumEntry<TFlag> FlagEntry;
-  typedef SmallVector<FlagEntry, 10> FlagVector;
-  FlagVector SetFlags;
-  for (const auto &Flag : Flags) {
-    if (Flag.Value == 0)
-      continue;
-    if ((Value & Flag.Value) == Flag.Value) {
-      SetFlags.push_back(Flag);
-    }
-  }
+  typedef const typename EnumStrings<TFlag>::EnumString *FlagEntry;
+  SmallVector<FlagEntry, 10> SetFlags;
+  for (const auto &Flag : Flags)
+    if (Flag.value() != 0 && (Value & Flag.value()) == Flag.value())
+      SetFlags.push_back(&Flag);
 
-  llvm::sort(SetFlags, &compEnumNames<TFlag>);
+  llvm::sort(SetFlags, [](FlagEntry LHS, FlagEntry RHS) {
+    return LHS->name() < RHS->name();
+  });
 
   std::string FlagLabel;
   bool FirstOcc = true;
-  for (const auto &Flag : SetFlags) {
+  for (FlagEntry Flag : SetFlags) {
     if (FirstOcc)
       FirstOcc = false;
     else
       FlagLabel += (" | ");
 
-    FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
+    FlagLabel +=
+        (std::string(Flag->name()) + " (0x" + utohexstr(Flag->value()) + ")");
   }
 
   if (!FlagLabel.empty()) {
@@ -96,18 +89,8 @@ static std::string getFlagNames(CodeViewRecordIO &IO, T 
Value,
 
 template <typename T, typename TEnum>
 static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
-                             ArrayRef<EnumEntry<TEnum>> EnumValues) {
-  if (!IO.isStreaming())
-    return "";
-  StringRef Name;
-  for (const auto &EnumItem : EnumValues) {
-    if (EnumItem.Value == Value) {
-      Name = EnumItem.Name;
-      break;
-    }
-  }
-
-  return Name;
+                             EnumStrings<TEnum> EnumValues) {
+  return IO.isStreaming() ? EnumValues.toString(Value) : "";
 }
 
 static std::string getMemberAttributes(CodeViewRecordIO &IO,
@@ -115,17 +98,17 @@ static std::string getMemberAttributes(CodeViewRecordIO 
&IO,
                                        MethodOptions Options) {
   if (!IO.isStreaming())
     return "";
-  std::string AccessSpecifier = std::string(
-      getEnumName(IO, uint8_t(Access), ArrayRef(getMemberAccessNames())));
+  std::string AccessSpecifier =
+      std::string(getEnumName(IO, uint8_t(Access), getMemberAccessNames()));
   std::string MemberAttrs(AccessSpecifier);
   if (Kind != MethodKind::Vanilla) {
-    std::string MethodKind = std::string(
-        getEnumName(IO, unsigned(Kind), ArrayRef(getMemberKindNames())));
+    std::string MethodKind =
+        std::string(getEnumName(IO, unsigned(Kind), getMemberKindNames()));
     MemberAttrs += ", " + MethodKind;
   }
   if (Options != MethodOptions::None) {
     std::string MethodOptions =
-        getFlagNames(IO, unsigned(Options), ArrayRef(getMethodOptionNames()));
+        getFlagNames(IO, unsigned(Options), getMethodOptionNames());
     MemberAttrs += ", " + MethodOptions;
   }
   return MemberAttrs;
@@ -304,9 +287,8 @@ Error TypeRecordMapping::visitMemberEnd(CVMemberRecord 
&Record) {
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) 
{
-  std::string ModifierNames =
-      getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
-                   ArrayRef(getTypeModifierNames()));
+  std::string ModifierNames = getFlagNames(
+      IO, static_cast<uint16_t>(Record.Modifiers), getTypeModifierNames());
   error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
   error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
   return Error::success();
@@ -314,11 +296,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, 
ModifierRecord &Record) {
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                           ProcedureRecord &Record) {
-  std::string CallingConvName = std::string(getEnumName(
-      IO, uint8_t(Record.CallConv), ArrayRef(getCallingConventions())));
-  std::string FuncOptionNames =
-      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
-                   ArrayRef(getFunctionOptionEnum()));
+  std::string CallingConvName = std::string(
+      getEnumName(IO, uint8_t(Record.CallConv), getCallingConventions()));
+  std::string FuncOptionNames = getFlagNames(
+      IO, static_cast<uint16_t>(Record.Options), getFunctionOptionEnum());
   error(IO.mapInteger(Record.ReturnType, "ReturnType"));
   error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
   error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
@@ -330,11 +311,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                           MemberFunctionRecord &Record) {
-  std::string CallingConvName = std::string(getEnumName(
-      IO, uint8_t(Record.CallConv), ArrayRef(getCallingConventions())));
-  std::string FuncOptionNames =
-      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
-                   ArrayRef(getFunctionOptionEnum()));
+  std::string CallingConvName = std::string(
+      getEnumName(IO, uint8_t(Record.CallConv), getCallingConventions()));
+  std::string FuncOptionNames = getFlagNames(
+      IO, static_cast<uint16_t>(Record.Options), getFunctionOptionEnum());
   error(IO.mapInteger(Record.ReturnType, "ReturnType"));
   error(IO.mapInteger(Record.ClassType, "ClassType"));
   error(IO.mapInteger(Record.ThisType, "ThisType"));
@@ -374,12 +354,12 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, 
PointerRecord &Record) {
   SmallString<128> Attr("Attrs: ");
 
   if (IO.isStreaming()) {
-    std::string PtrType = std::string(getEnumName(
-        IO, unsigned(Record.getPointerKind()), ArrayRef(getPtrKindNames())));
+    std::string PtrType = std::string(
+        getEnumName(IO, unsigned(Record.getPointerKind()), getPtrKindNames()));
     Attr += "[ Type: " + PtrType;
 
-    std::string PtrMode = std::string(getEnumName(
-        IO, unsigned(Record.getMode()), ArrayRef(getPtrModeNames())));
+    std::string PtrMode = std::string(
+        getEnumName(IO, unsigned(Record.getMode()), getPtrModeNames()));
     Attr += ", Mode: " + PtrMode;
 
     auto PtrSizeOf = Record.getSize();
@@ -411,8 +391,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, 
PointerRecord &Record) {
 
     MemberPointerInfo &M = *Record.MemberInfo;
     error(IO.mapInteger(M.ContainingType, "ClassType"));
-    std::string PtrMemberGetRepresentation = std::string(getEnumName(
-        IO, uint16_t(M.Representation), ArrayRef(getPtrMemberRepNames())));
+    std::string PtrMemberGetRepresentation = std::string(
+        getEnumName(IO, uint16_t(M.Representation), getPtrMemberRepNames()));
     error(IO.mapEnum(M.Representation,
                      "Representation: " + PtrMemberGetRepresentation));
   }
@@ -434,9 +414,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, 
ClassRecord &Record) {
          (CVR.kind() == TypeLeafKind::LF_CLASS) ||
          (CVR.kind() == TypeLeafKind::LF_INTERFACE));
 
-  std::string PropertiesNames =
-      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
-                   ArrayRef(getClassOptionNames()));
+  std::string PropertiesNames = getFlagNames(
+      IO, static_cast<uint16_t>(Record.Options), getClassOptionNames());
   error(IO.mapInteger(Record.MemberCount, "MemberCount"));
   error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
   error(IO.mapInteger(Record.FieldList, "FieldList"));
@@ -450,9 +429,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, 
ClassRecord &Record) {
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
-  std::string PropertiesNames =
-      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
-                   ArrayRef(getClassOptionNames()));
+  std::string PropertiesNames = getFlagNames(
+      IO, static_cast<uint16_t>(Record.Options), getClassOptionNames());
   error(IO.mapInteger(Record.MemberCount, "MemberCount"));
   error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
   error(IO.mapInteger(Record.FieldList, "FieldList"));
@@ -464,9 +442,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, 
UnionRecord &Record) {
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) {
-  std::string PropertiesNames =
-      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
-                   ArrayRef(getClassOptionNames()));
+  std::string PropertiesNames = getFlagNames(
+      IO, static_cast<uint16_t>(Record.Options), getClassOptionNames());
   error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
   error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
   error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
@@ -618,8 +595,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) {
-  std::string ModeName = std::string(
-      getEnumName(IO, uint16_t(Record.Mode), ArrayRef(getLabelTypeEnum())));
+  std::string ModeName =
+      std::string(getEnumName(IO, uint16_t(Record.Mode), getLabelTypeEnum()));
   error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
   return Error::success();
 }

diff  --git a/llvm/lib/DebugInfo/LogicalView/Core/LVSourceLanguage.cpp 
b/llvm/lib/DebugInfo/LogicalView/Core/LVSourceLanguage.cpp
index e7b122de1bba5..ed24c6782dcd5 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVSourceLanguage.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVSourceLanguage.cpp
@@ -23,10 +23,8 @@ StringRef LVSourceLanguage::getName() const {
   switch (getTag()) {
   case LVSourceLanguage::TagDwarf:
     return llvm::dwarf::LanguageString(getLang());
-  case LVSourceLanguage::TagCodeView: {
-    static auto LangNames = llvm::codeview::getSourceLanguageNames();
-    return LangNames[getLang()].Name;
-  }
+  case LVSourceLanguage::TagCodeView:
+    return llvm::codeview::getSourceLanguageNames().toString(getLang());
   default:
     llvm_unreachable("Unsupported language");
   }

diff  --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp 
b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
index fddb39733b048..7320a188051bb 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -70,11 +70,6 @@ static TypeIndex getTrueType(TypeIndex &TI) {
   return TI;
 }
 
-static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
-#define CV_TYPE(enum, val) {#enum, enum},
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
-};
-
 // Return the type name pointed by the type index. It uses the kind to query
 // the associated name for the record type.
 static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI) {
@@ -1800,7 +1795,7 @@ void LVLogicalVisitor::printTypeBegin(CVType &Record, 
TypeIndex TI,
   W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
   W.getOStream() << " {\n";
   W.indent();
-  W.printEnum("TypeLeafKind", unsigned(Record.kind()), 
ArrayRef(LeafTypeNames));
+  W.printEnum("TypeLeafKind", unsigned(Record.kind()), getTypeLeafNames());
   printTypeIndex("TI", TI, StreamIdx);
   W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
                 << Element->getName() << "\n";
@@ -1819,7 +1814,7 @@ void LVLogicalVisitor::printMemberBegin(CVMemberRecord 
&Record, TypeIndex TI,
   W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
   W.getOStream() << " {\n";
   W.indent();
-  W.printEnum("TypeLeafKind", unsigned(Record.Kind), ArrayRef(LeafTypeNames));
+  W.printEnum("TypeLeafKind", unsigned(Record.Kind), getTypeLeafNames());
   printTypeIndex("TI", TI, StreamIdx);
   W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
                 << Element->getName() << "\n";

diff  --git a/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp 
b/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
index c8df2c306a762..9964f7cfb6ef0 100644
--- a/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
@@ -7,32 +7,25 @@
 
//===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/PDB/Native/EnumTables.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
-#include "llvm/Support/ScopedPrinter.h"
 
 using namespace llvm;
-using namespace llvm::pdb;
 
+EnumStrings<uint16_t> llvm::pdb::getOMFSegMapDescFlagNames() {
 #define PDB_ENUM_CLASS_ENT(enum_class, enum)                                   
\
-  { #enum, std::underlying_type_t<enum_class>(enum_class::enum) }
-
-#define PDB_ENUM_ENT(ns, enum)                                                 
\
-  { #enum, ns::enum }
-
-static const EnumEntry<uint16_t> OMFSegMapDescFlagNames[] = {
-    PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Read),
-    PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Write),
-    PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Execute),
-    PDB_ENUM_CLASS_ENT(OMFSegDescFlags, AddressIs32Bit),
-    PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsSelector),
-    PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsAbsoluteAddress),
-    PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsGroup),
-};
-
-namespace llvm {
-namespace pdb {
-ArrayRef<EnumEntry<uint16_t>> getOMFSegMapDescFlagNames() {
-  return ArrayRef(OMFSegMapDescFlagNames);
-}
-}
+  {                                                                            
\
+    {#enum}, std::underlying_type_t<enum_class>(enum_class::enum)              
\
+  }
+  constexpr EnumStringDef<uint16_t> Defs[] = {
+      PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Read),
+      PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Write),
+      PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Execute),
+      PDB_ENUM_CLASS_ENT(OMFSegDescFlags, AddressIs32Bit),
+      PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsSelector),
+      PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsAbsoluteAddress),
+      PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsGroup),
+  };
+  static constexpr auto Names = BUILD_ENUM_STRINGS(Defs);
+  return EnumStrings(Names);
 }

diff  --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp 
b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 7f12db8404600..2cdf363254725 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -46,16 +46,15 @@ static raw_ostream &printFlags(raw_ostream &OS, const T 
Value,
   return OS;
 }
 
-static const EnumEntry<RegisterType> RegisterNames[] = {
-    {"b", RegisterType::BReg},
-    {"t", RegisterType::TReg},
-    {"u", RegisterType::UReg},
-    {"s", RegisterType::SReg},
-};
-
 static raw_ostream &operator<<(raw_ostream &OS, const Register &Reg) {
-  OS << enumToStringRef(Reg.ViewType, ArrayRef(RegisterNames)) << Reg.Number;
-
+  constexpr EnumStringDef<RegisterType> RegisterNameDefs[] = {
+      {{"b"}, RegisterType::BReg},
+      {{"t"}, RegisterType::TReg},
+      {{"u"}, RegisterType::UReg},
+      {{"s"}, RegisterType::SReg},
+  };
+  static constexpr auto RegisterNames = BUILD_ENUM_STRINGS(RegisterNameDefs);
+  OS << EnumStrings(RegisterNames).toString(Reg.ViewType) << Reg.Number;
   return OS;
 }
 

diff  --git a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp 
b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
index 9bc3312753540..b985adaea9cee 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -80,7 +80,7 @@ void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
                                                       SymbolKind &Value) {
   auto SymbolNames = getSymbolTypeNames();
   for (const auto &E : SymbolNames)
-    io.enumCase(Value, E.Name, E.Value);
+    io.enumCase(Value, E.name(), E.value());
   io.enumFallback<yaml::Hex16>(Value);
 }
 
@@ -88,7 +88,7 @@ void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
                                                   CompileSym2Flags &Flags) {
   auto FlagNames = getCompileSym2FlagNames();
   for (const auto &E : FlagNames) {
-    io.bitSetCase(Flags, E.Name, static_cast<CompileSym2Flags>(E.Value));
+    io.bitSetCase(Flags, E.name(), static_cast<CompileSym2Flags>(E.value()));
   }
 }
 
@@ -96,35 +96,35 @@ void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
                                                   CompileSym3Flags &Flags) {
   auto FlagNames = getCompileSym3FlagNames();
   for (const auto &E : FlagNames) {
-    io.bitSetCase(Flags, E.Name, static_cast<CompileSym3Flags>(E.Value));
+    io.bitSetCase(Flags, E.name(), static_cast<CompileSym3Flags>(E.value()));
   }
 }
 
 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
   auto FlagNames = getExportSymFlagNames();
   for (const auto &E : FlagNames) {
-    io.bitSetCase(Flags, E.Name, static_cast<ExportFlags>(E.Value));
+    io.bitSetCase(Flags, E.name(), static_cast<ExportFlags>(E.value()));
   }
 }
 
 void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) 
{
   auto FlagNames = getPublicSymFlagNames();
   for (const auto &E : FlagNames) {
-    io.bitSetCase(Flags, E.Name, static_cast<PublicSymFlags>(E.Value));
+    io.bitSetCase(Flags, E.name(), static_cast<PublicSymFlags>(E.value()));
   }
 }
 
 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
   auto FlagNames = getLocalFlagNames();
   for (const auto &E : FlagNames) {
-    io.bitSetCase(Flags, E.Name, static_cast<LocalSymFlags>(E.Value));
+    io.bitSetCase(Flags, E.name(), static_cast<LocalSymFlags>(E.value()));
   }
 }
 
 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
   auto FlagNames = getProcSymFlagNames();
   for (const auto &E : FlagNames) {
-    io.bitSetCase(Flags, E.Name, static_cast<ProcSymFlags>(E.Value));
+    io.bitSetCase(Flags, E.name(), static_cast<ProcSymFlags>(E.value()));
   }
 }
 
@@ -132,14 +132,15 @@ void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
     IO &io, FrameProcedureOptions &Flags) {
   auto FlagNames = getFrameProcSymFlagNames();
   for (const auto &E : FlagNames) {
-    io.bitSetCase(Flags, E.Name, static_cast<FrameProcedureOptions>(E.Value));
+    io.bitSetCase(Flags, E.name(),
+                  static_cast<FrameProcedureOptions>(E.value()));
   }
 }
 
 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
   auto CpuNames = getCPUTypeNames();
   for (const auto &E : CpuNames) {
-    io.enumCase(Cpu, E.Name, static_cast<CPUType>(E.Value));
+    io.enumCase(Cpu, E.name(), static_cast<CPUType>(E.value()));
   }
 }
 
@@ -148,7 +149,6 @@ void ScalarEnumerationTraits<RegisterId>::enumeration(IO 
&io, RegisterId &Reg) {
   assert(Header && "The IO context is not initialized");
 
   std::optional<CPUType> CpuType;
-  ArrayRef<EnumEntry<uint16_t>> RegNames;
 
   switch (Header->Machine) {
   case COFF::IMAGE_FILE_MACHINE_I386:
@@ -168,11 +168,9 @@ void ScalarEnumerationTraits<RegisterId>::enumeration(IO 
&io, RegisterId &Reg) {
   }
 
   if (CpuType)
-    RegNames = getRegisterNames(*CpuType);
+    for (const auto &E : getRegisterNames(*CpuType))
+      io.enumCase(Reg, E.name(), static_cast<RegisterId>(E.value()));
 
-  for (const auto &E : RegNames) {
-    io.enumCase(Reg, E.Name, static_cast<RegisterId>(E.Value));
-  }
   io.enumFallback<Hex16>(Reg);
 }
 
@@ -180,7 +178,7 @@ void ScalarEnumerationTraits<TrampolineType>::enumeration(
     IO &io, TrampolineType &Tramp) {
   auto TrampNames = getTrampolineNames();
   for (const auto &E : TrampNames) {
-    io.enumCase(Tramp, E.Name, static_cast<TrampolineType>(E.Value));
+    io.enumCase(Tramp, E.name(), static_cast<TrampolineType>(E.value()));
   }
 }
 
@@ -188,7 +186,7 @@ void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO 
&io,
                                                         ThunkOrdinal &Ord) {
   auto ThunkNames = getThunkOrdinalNames();
   for (const auto &E : ThunkNames) {
-    io.enumCase(Ord, E.Name, static_cast<ThunkOrdinal>(E.Value));
+    io.enumCase(Ord, E.name(), static_cast<ThunkOrdinal>(E.value()));
   }
 }
 
@@ -196,7 +194,7 @@ void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
     IO &io, FrameCookieKind &FC) {
   auto ThunkNames = getFrameCookieKindNames();
   for (const auto &E : ThunkNames) {
-    io.enumCase(FC, E.Name, static_cast<FrameCookieKind>(E.Value));
+    io.enumCase(FC, E.name(), static_cast<FrameCookieKind>(E.value()));
   }
 }
 
@@ -204,7 +202,7 @@ void 
ScalarEnumerationTraits<JumpTableEntrySize>::enumeration(
     IO &io, JumpTableEntrySize &FC) {
   auto ThunkNames = getJumpTableEntrySizeNames();
   for (const auto &E : ThunkNames) {
-    io.enumCase(FC, E.Name, static_cast<JumpTableEntrySize>(E.Value));
+    io.enumCase(FC, E.name(), static_cast<JumpTableEntrySize>(E.value()));
   }
 }
 


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to