diff --git a/gdb/guile/scm-symbol.c b/gdb/guile/scm-symbol.c
index 801c3f13b96..bf5fe24f23d 100644
--- a/gdb/guile/scm-symbol.c
+++ b/gdb/guile/scm-symbol.c
@@ -693,16 +693,18 @@ static const scheme_integer_constant symbol_integer_constants[] =
   X (LOC_OPTIMIZED_OUT),
   X (LOC_COMPUTED),
   X (LOC_REGPARM_ADDR),
-
-  X (UNDEF_DOMAIN),
-  X (VAR_DOMAIN),
-  X (STRUCT_DOMAIN),
-  X (LABEL_DOMAIN),
-  X (VARIABLES_DOMAIN),
-  X (FUNCTIONS_DOMAIN),
-  X (TYPES_DOMAIN),
 #undef X
 
+#define DOMAIN(X) \
+  { "SYMBOL_" #X "_DOMAIN", X ## _DOMAIN },
+#include "sym-domains.def"
+#undef DOMAIN
+
+  /* These were never correct.  */
+  { "SYMBOL_VARIABLES_DOMAIN", VAR_DOMAIN },
+  { "SYMBOL_FUNCTIONS_DOMAIN", VAR_DOMAIN },
+  { "SYMBOL_TYPES_DOMAIN", VAR_DOMAIN },
+
   END_INTEGER_CONSTANTS
 };
 
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 82ea5c59c63..52a25b632e0 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -670,20 +670,15 @@ gdbpy_initialize_symbols (void)
       || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_COMMON_BLOCK",
 				  LOC_COMMON_BLOCK) < 0
       || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGPARM_ADDR",
-				  LOC_REGPARM_ADDR) < 0
-      || PyModule_AddIntConstant (gdb_module, "SYMBOL_UNDEF_DOMAIN",
-				  UNDEF_DOMAIN) < 0
-      || PyModule_AddIntConstant (gdb_module, "SYMBOL_VAR_DOMAIN",
-				  VAR_DOMAIN) < 0
-      || PyModule_AddIntConstant (gdb_module, "SYMBOL_STRUCT_DOMAIN",
-				  STRUCT_DOMAIN) < 0
-      || PyModule_AddIntConstant (gdb_module, "SYMBOL_LABEL_DOMAIN",
-				  LABEL_DOMAIN) < 0
-      || PyModule_AddIntConstant (gdb_module, "SYMBOL_MODULE_DOMAIN",
-				  MODULE_DOMAIN) < 0
-      || PyModule_AddIntConstant (gdb_module, "SYMBOL_COMMON_BLOCK_DOMAIN",
-				  COMMON_BLOCK_DOMAIN) < 0)
+				  LOC_REGPARM_ADDR) < 0)
+    return -1;
+
+#define DOMAIN(X)							\
+  if (PyModule_AddIntConstant (gdb_module, "SYMBOL_" #X "_DOMAIN",	\
+			       X ## _DOMAIN) < 0)			\
     return -1;
+#include "sym-domains.def"
+#undef DOMAIN
 
   /* These remain defined for compatibility, but as they were never
      correct, they are no longer documented.  Eventually we can remove
diff --git a/gdb/sym-domains.def b/gdb/sym-domains.def
new file mode 100644
index 00000000000..251c66fa04b
--- /dev/null
+++ b/gdb/sym-domains.def
@@ -0,0 +1,47 @@
+/* Symbol domains  -*- c++ -*-
+
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* UNDEF_DOMAIN is used when a domain has not been discovered or
+   none of the following apply.  This usually indicates an error either
+   in the symbol information or in gdb's handling of symbols.  */
+
+DOMAIN (UNDEF)
+
+/* VAR_DOMAIN is the usual domain.  In C, this contains variables,
+   function names, typedef names and enum type values.  */
+
+DOMAIN (VAR)
+
+/* STRUCT_DOMAIN is used in C to hold struct, union and enum type names.
+   Thus, if `struct foo' is used in a C program, it produces a symbol named
+   `foo' in the STRUCT_DOMAIN.  */
+
+DOMAIN (STRUCT)
+
+/* MODULE_DOMAIN is used in Fortran to hold module type names.  */
+
+DOMAIN (MODULE)
+
+/* LABEL_DOMAIN may be used for names of labels (for gotos).  */
+
+DOMAIN (LABEL)
+
+/* Fortran common blocks.  Their naming must be separate from VAR_DOMAIN.
+   They also always use LOC_COMMON_BLOCK.  */
+DOMAIN (COMMON_BLOCK)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 2020210c5f4..b1deb9d6767 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -305,12 +305,10 @@ domain_name (domain_enum e)
 {
   switch (e)
     {
-    case UNDEF_DOMAIN: return "UNDEF_DOMAIN";
-    case VAR_DOMAIN: return "VAR_DOMAIN";
-    case STRUCT_DOMAIN: return "STRUCT_DOMAIN";
-    case MODULE_DOMAIN: return "MODULE_DOMAIN";
-    case LABEL_DOMAIN: return "LABEL_DOMAIN";
-    case COMMON_BLOCK_DOMAIN: return "COMMON_BLOCK_DOMAIN";
+#define DOMAIN(X)				\
+      case X ## _DOMAIN: return #X "_DOMAIN";
+#include "sym-domains.def"
+#undef DOMAIN
     default: gdb_assert_not_reached ("bad domain_enum");
     }
 }
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 0a5f2633fe8..7e841c4033f 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -894,34 +894,9 @@ struct minimal_symbol : public general_symbol_info
 
 enum domain_enum
 {
-  /* UNDEF_DOMAIN is used when a domain has not been discovered or
-     none of the following apply.  This usually indicates an error either
-     in the symbol information or in gdb's handling of symbols.  */
-
-  UNDEF_DOMAIN,
-
-  /* VAR_DOMAIN is the usual domain.  In C, this contains variables,
-     function names, typedef names and enum type values.  */
-
-  VAR_DOMAIN,
-
-  /* STRUCT_DOMAIN is used in C to hold struct, union and enum type names.
-     Thus, if `struct foo' is used in a C program, it produces a symbol named
-     `foo' in the STRUCT_DOMAIN.  */
-
-  STRUCT_DOMAIN,
-
-  /* MODULE_DOMAIN is used in Fortran to hold module type names.  */
-
-  MODULE_DOMAIN,
-
-  /* LABEL_DOMAIN may be used for names of labels (for gotos).  */
-
-  LABEL_DOMAIN,
-
-  /* Fortran common blocks.  Their naming must be separate from VAR_DOMAIN.
-     They also always use LOC_COMMON_BLOCK.  */
-  COMMON_BLOCK_DOMAIN,
+#define DOMAIN(X) X ## _DOMAIN,
+#include "sym-domains.def"
+#undef DOMAIN
 };
 
 /* The number of bits in a symbol used to represent the domain.  */
