DW_LANG_Nim and DW_LNAME_Nim were added to the DWARF languages.

While adding them, and the default lower bounds, I noticed DW_LANG_V
and DW_LANG_Algol68 where missing in srclang_to_language an internal
helper function.

Testing through the public api is not that easy since you need a
Dwarf_Die with the right attributes. So this patch adds a way to
compile an individual source file with an optional main function that
can directly access the internal/static functions.

Note that it is almost generic. But even though using .SECONDEXPANSION
I couldn't figure out how to create the equivalent of a rule starting
with %_check$(EXEEXT) target. So for now the rule has to repeated for
every new _check TEST. And there needs to be a line to tell make dist
to not expect the fake source: nodist_src_check_SOURCES = src_check.c

The new test pointed out that there were a few more bugs with
DW_LANG_Dylan and DW_LNAME_Mojo. Also fix those.

        * libdw/dwarf.h: Add DW_LANG_Nim and DW_LNAME_Nim.
        * libdw/Makefile.am: Add check_PROGRAMS and TESTS for
        dwarf_srclang_check.
        * libdw/dwarf_default_lower_bound.c
        (dwarf_default_lower_bound): Add DW_LANG_Nim.
        (dwarf_language_lower_bound): Add DW_LNAME_Nim.
        * libdw/dwarf_srclang.c (srclang_to_language): Handle
        DW_LANG_Dylan, DW_LANG_V, DW_LANG_Algol68 and DW_LANG_Nim.
        (language_to_srclang): Fix DW_LNAME_Mojo. Add DW_LNAME_Nim.
        (test_lang): New function guarded by MAIN_CHECK.
        (main): Likewise.

Signed-off-by: Mark Wielaard <m...@klomp.org>
---
 libdw/Makefile.am                 | 11 ++++
 libdw/dwarf.h                     |  2 +
 libdw/dwarf_default_lower_bound.c |  2 +
 libdw/dwarf_srclang.c             | 87 ++++++++++++++++++++++++++++++-
 4 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 8cbe0f327a32..9dadc19b6a68 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -160,3 +160,14 @@ libdw.manifest: $(libdw_a_OBJECTS)
 MOSTLYCLEANFILES = $(am_libdw_a_OBJECTS) $(am_libdw_pic_a_OBJECTS) 
libdw.so.$(VERSION)
 CLEANFILES = libdw.so $(EXTRA_libdw_a_DEPENDENCIES)
 MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h
+
+# Internal checks
+check_PROGRAMS = dwarf_srclang_check
+TESTS = $(check_PROGRAMS)
+
+CHECK_DEF_FLAGS = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 
-DMAIN_CHECK=1
+
+.SECONDEXPANSION:
+dwarf_srclang_check$(EXEEXT): $$(filter-out $$(subst 
_check,,$$@).o,$(libdw_a_OBJECTS)) $$(subst _check,,$$@).c
+       $(AM_V_CC)$(CC) $(CHECK_DEF_FLAGS) -o $@ $^ $(filter-out 
libdw_pic.a,$(libdw_so_LIBS)) $(libdw_so_LDLIBS)
+nodist_dwarf_srclang_check_SOURCES = dwarf_srclang_check.c
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 5c8563128644..e1808096ca5f 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -777,6 +777,7 @@ enum
     DW_LANG_Hylo = 0x0042,          /* Hylo */
     DW_LANG_V = 0x0043,                     /* V Programming Language */
     DW_LANG_Algol68 = 0x0044,       /* Algol68 */
+    DW_LANG_Nim = 0x0045,           /* Nim */
 
     DW_LANG_lo_user = 0x8000,
     DW_LANG_Mips_Assembler = 0x8001, /* Assembler */
@@ -835,6 +836,7 @@ enum
     DW_LNAME_Metal = 0x002c,
     DW_LNAME_V = 0x002d,
     DW_LNAME_Algol68 = 0x002e,
+    DW_LNAME_Nim = 0x002f,
 
     DW_LNAME_lo_user = 0x8000,
     DW_LNAME_hi_user = 0xffff
diff --git a/libdw/dwarf_default_lower_bound.c 
b/libdw/dwarf_default_lower_bound.c
index 7cc808b22488..71a313fe577c 100644
--- a/libdw/dwarf_default_lower_bound.c
+++ b/libdw/dwarf_default_lower_bound.c
@@ -89,6 +89,7 @@ dwarf_default_lower_bound (int lang, Dwarf_Sword *result)
     case DW_LANG_Move:
     case DW_LANG_Hylo:
     case DW_LANG_V:
+    case DW_LANG_Nim:
       *result = 0;
       return 0;
 
@@ -170,6 +171,7 @@ dwarf_language_lower_bound (Dwarf_Word lang, Dwarf_Sword 
*result)
     case DW_LNAME_P4:
     case DW_LNAME_Metal:
     case DW_LNAME_V:
+    case DW_LNAME_Nim:
       *result = 0;
       return 0;
 
diff --git a/libdw/dwarf_srclang.c b/libdw/dwarf_srclang.c
index 948f44cb455e..10dfce8be3e3 100644
--- a/libdw/dwarf_srclang.c
+++ b/libdw/dwarf_srclang.c
@@ -118,6 +118,10 @@ static int srclang_to_language (Dwarf_Word srclang,
       *lname = DW_LNAME_D;
       *lversion = 0;
       return 0;
+    case DW_LANG_Dylan:
+      *lname = DW_LNAME_Dylan;
+      *lversion = 0;
+      return 0;
     case DW_LANG_Python:
       *lname = DW_LNAME_Python;
       *lversion = 0;
@@ -299,6 +303,18 @@ static int srclang_to_language (Dwarf_Word srclang,
       *lname = DW_LNAME_Hylo;
       *lversion = 0;
       return 0;
+    case DW_LANG_V:
+      *lname = DW_LNAME_V;
+      *lversion = 0;
+      return 0;
+    case DW_LANG_Algol68:
+      *lname = DW_LNAME_Algol68;
+      *lversion = 0;
+      return 0;
+    case DW_LANG_Nim:
+      *lname = DW_LNAME_Nim;
+      *lversion = 0;
+      return 0;
     default:
       __libdw_seterrno (DWARF_E_UNKNOWN_LANGUAGE);
       return -1;
@@ -447,7 +463,7 @@ language_to_srclang (Dwarf_Word lname, Dwarf_Word lversion, 
Dwarf_Word *value)
       *value = DW_LANG_C_sharp;
       return 0;
     case DW_LNAME_Mojo:
-      *value = DW_LANG_Move;
+      *value = DW_LANG_Mojo;
       return 0;
     case DW_LNAME_GLSL:
       *value = DW_LANG_GLSL;
@@ -494,6 +510,9 @@ language_to_srclang (Dwarf_Word lname, Dwarf_Word lversion, 
Dwarf_Word *value)
     case DW_LNAME_Algol68:
       *value = DW_LANG_Algol68;
       return 0;
+    case DW_LNAME_Nim:
+      *value = DW_LANG_Nim;
+      return 0;
     default:
       __libdw_seterrno (DWARF_E_UNKNOWN_LANGUAGE);
       return -1;
@@ -574,3 +593,69 @@ dwarf_language (Dwarf_Die *cudie, Dwarf_Word *lname, 
Dwarf_Word *lversion)
   return res;
 }
 INTDEF (dwarf_language)
+
+#ifdef MAIN_CHECK
+#include "known-dwarf.h"
+#include <inttypes.h>
+#include <stdio.h>
+
+void
+test_lang (const char *name, Dwarf_Word lang)
+{
+  printf ("Testing %s: 0x%" PRIx64 "\n", name, lang);
+
+  Dwarf_Word lname;
+  Dwarf_Word lversion;
+  int res = srclang_to_language (lang, &lname, &lversion);
+  if (res != 0)
+    {
+      printf ("srclang_to_language failed (%d) for %s\n", res, name);
+      exit (-1);
+    }
+
+  Dwarf_Word rlang;
+  res = language_to_srclang (lname, lversion, &rlang);
+  if (res != 0)
+    {
+      printf ("language_to_srclang (%" PRId64 ", %" PRId64 ") failed (%d)\n",
+             lname, lversion, res);
+      exit (-1);
+    }
+
+  /* Most langs should roundtrip, but there are some exceptions.  */
+  switch (lang)
+    {
+    case DW_LANG_Assembly:
+      if (rlang != DW_LANG_Mips_Assembler)
+       {
+         printf ("For compatibility Assembly should go to Mips_Assembler\n");
+         exit (-1);
+       }
+      break;
+    case DW_LANG_C_plus_plus_03:
+      if (rlang != DW_LANG_C_plus_plus)
+       {
+         printf ("For c++03 doesn't exist it is just c++\n");
+         exit (-1);
+       }
+      break;
+    default:
+      if (lang != rlang)
+       {
+         printf ("going from srclang to lang and back gives different name "
+                 "for %s (%" PRId64 " != %" PRId64 ")\n", name, lang, rlang);
+         exit (-1);
+       }
+    }
+}
+
+int
+main (void)
+{
+  /* Test all known language codes.  */
+#define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) test_lang (#NAME, CODE);
+  DWARF_ALL_KNOWN_DW_LANG
+#undef DWARF_ONE_KNOWN_DW_LANG
+  return 0;
+}
+#endif
-- 
2.48.1

Reply via email to