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 <[email protected]>
---
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