diff mbox series

New lang hook

Message ID f5a76014-714b-db9d-ac9d-b6a053f4a1e6@acm.org
State New
Headers show
Series New lang hook | expand

Commit Message

Nathan Sidwell Nov. 14, 2017, 12:31 p.m. UTC
This patch addresses c++/82836 & c++/82737.  The root cause was a bad 
assumption I made when moving the mangling alias machinery to its own 
hash table.

I had thought that once we SET_DECL_ASSEMBLER_NAME, it never becomes 
unset (or changed).  That is false.  There are paths in the compiler 
that set it back to zero, and at least one path where we remangled 
because of a bad assumption about the templatedness of a friend.

Previously, we placed mangling aliases in the global namespace mapping 
an identifier (the mangled name) to the decl.  Resetting the assembler 
name didn't break this map -- but may have led to unneeded aliases, I guess.

Moving the alias machinery to its own hash-map allowed me to make 
namespace hashes a simple hash, keyed by DECL_NAME (rather than a 
hash-map from identifier->decl).

Finally converting the alias hash-map to a hash-table keyed by 
DECL_ASSEMBLER_NAME shrunk that table too.  But exposed this problem.

I did contemplate reverting that change, but tried this first, and it 
seems good.

1) rename the args of COPY_DECL_ASSEMBLER_NAME from DECL1 & DECL2 to the 
more semantic SRC_DECL and DST_DECL.  Same for COPY_DECL_RTL.  These 
macros smell rather memcpy-like, but the args are the wrong way round, 
so the more clues the better. (My comment in 82737 was misled by this.)

2) change SET_DECL_ASSEMBLER_NAME to a function call, similar to 
DECL_ASSEMBLER_NAME.

3) have that call forward to a new lang hook, 
override_decl_assembler_name, if it is changing the name. 
(set_decl_assembler_name already having been taken.)

4) the new lang hook default simply stores the new name via 
DECL_ASSEMBLER_NAME_RAW.

5) the C++ FE overrides this.  If the current name is in the alias map 
and maps to this decl, we take it out of the map.  Then set the new name.

6) excitingly, mangle_decl can be called with a non-null 
DECL_ASSEMBLER_NAME, so that function's use of SET_DECL_ASSEMBLER_NAME 
works just fine.

booted on all languages.

ok?

nathan

Comments

Richard Biener Nov. 16, 2017, 12:03 p.m. UTC | #1
On Tue, Nov 14, 2017 at 1:31 PM, Nathan Sidwell <nathan@acm.org> wrote:
> This patch addresses c++/82836 & c++/82737.  The root cause was a bad
> assumption I made when moving the mangling alias machinery to its own hash
> table.
>
> I had thought that once we SET_DECL_ASSEMBLER_NAME, it never becomes unset
> (or changed).  That is false.  There are paths in the compiler that set it
> back to zero, and at least one path where we remangled because of a bad
> assumption about the templatedness of a friend.
>
> Previously, we placed mangling aliases in the global namespace mapping an
> identifier (the mangled name) to the decl.  Resetting the assembler name
> didn't break this map -- but may have led to unneeded aliases, I guess.
>
> Moving the alias machinery to its own hash-map allowed me to make namespace
> hashes a simple hash, keyed by DECL_NAME (rather than a hash-map from
> identifier->decl).
>
> Finally converting the alias hash-map to a hash-table keyed by
> DECL_ASSEMBLER_NAME shrunk that table too.  But exposed this problem.
>
> I did contemplate reverting that change, but tried this first, and it seems
> good.
>
> 1) rename the args of COPY_DECL_ASSEMBLER_NAME from DECL1 & DECL2 to the
> more semantic SRC_DECL and DST_DECL.  Same for COPY_DECL_RTL.  These macros
> smell rather memcpy-like, but the args are the wrong way round, so the more
> clues the better. (My comment in 82737 was misled by this.)
>
> 2) change SET_DECL_ASSEMBLER_NAME to a function call, similar to
> DECL_ASSEMBLER_NAME.
>
> 3) have that call forward to a new lang hook, override_decl_assembler_name,
> if it is changing the name. (set_decl_assembler_name already having been
> taken.)
>
> 4) the new lang hook default simply stores the new name via
> DECL_ASSEMBLER_NAME_RAW.
>
> 5) the C++ FE overrides this.  If the current name is in the alias map and
> maps to this decl, we take it out of the map.  Then set the new name.
>
> 6) excitingly, mangle_decl can be called with a non-null
> DECL_ASSEMBLER_NAME, so that function's use of SET_DECL_ASSEMBLER_NAME works
> just fine.
>
> booted on all languages.
>
> ok?

Looks reasonable apart from

+  /* Overwrite the DECL_ASSEMBLER_NAME for a node.  The name is being
+     changed (including to or from NULL_TREE).  */

which suggests the default implementation of set_decl_assembler_name would
call this hook (which it doesn't).  Any particular reason?  Maybe just document
(including to NULL_TREE), thus exclude from NULL_TREE?

Thanks,
Richard.

>
> nathan
> --
> Nathan Sidwell
Nathan Sidwell Nov. 16, 2017, 2:54 p.m. UTC | #2
On 11/16/2017 07:03 AM, Richard Biener wrote:

> Looks reasonable apart from
> 
> +  /* Overwrite the DECL_ASSEMBLER_NAME for a node.  The name is being
> +     changed (including to or from NULL_TREE).  */
> 
> which suggests the default implementation of set_decl_assembler_name would
> call this hook (which it doesn't).  Any particular reason?  Maybe just document
> (including to NULL_TREE), thus exclude from NULL_TREE?

As discussed on IRC, this variant calls the new hook from the default 
set_decl_assembler_name hook.  Applying.

nathan
Andreas Schwab Nov. 18, 2017, 3:42 p.m. UTC | #3
FAIL: g++.dg/pr82836.C   (test for excess errors)
Excess errors:
/opt/gcc/gcc-20171118/gcc/testsuite/g++.dg/pr82836.C:13:3: error: '__float128' does not name a type; did you mean '__Float16x8_t'?

Andreas.
diff mbox series

Patch

2017-11-13  Nathan Sidwell  <nathan@acm.org>

	PR c++/82836
	PR c++/82737
	* tree.h (COPY_DECL_RTL): Rename parms for clarity.
	(SET_DECL_ASSEMBLER_NAME): Forward to
	overwrite_decl_assembler_name.
	(COPY_DECL_ASSEMBLER_NAME): Rename parms for clarity.
	(overwrite_decl_assembler_name): Declare.
	* tree.c (overwrite_decl_assembler_name): New.
	* langhooks-def.h (lhd_overwrite_decl_assembler_name): Declare.
	(LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME): Provide default.
	(LANG_HOOKS_INITIALIZER): Add it.
	* langhooks.h (struct lang_hooks): Add overwrite_decl_assembler_name.
	* langhooks.c (lhd_overwrite_decl_assembler_name): Default
	implementation.

	gcc/cp/
	* cp-objcp-common.h (LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME):
	Override.
	* cp-tree.h (overwrite_mangling): Declare.
	* decl2.c (struct mangled_decl_hash): Entries are deletable.
	(overwrite_mangling): New.

	gcc/testsuite/
	* g++.dg/pr82836.C: New.

Index: tree.c
===================================================================
--- tree.c	(revision 254703)
+++ tree.c	(working copy)
@@ -674,6 +674,17 @@  decl_assembler_name (tree decl)
   return DECL_ASSEMBLER_NAME_RAW (decl);
 }
 
+/* The DECL_ASSEMBLER_NAME_RAW of DECL is being explicitly set to NAME
+   (which may be NULL).  Inform the FE, if this is changing the
+   name.  */
+
+void
+overwrite_decl_assembler_name (tree decl, tree name)
+{
+  if (DECL_ASSEMBLER_NAME_RAW (decl) != name)
+    lang_hooks.overwrite_decl_assembler_name (decl, name);
+}
+
 /* When the target supports COMDAT groups, this indicates which group the
    DECL is associated with.  This can be either an IDENTIFIER_NODE or a
    decl, in which case its DECL_ASSEMBLER_NAME identifies the group.  */
Index: tree.h
===================================================================
--- tree.h	(revision 254703)
+++ tree.h	(working copy)
@@ -2528,11 +2528,11 @@  extern void decl_value_expr_insert (tree
 #define DECL_RTL_SET_P(NODE) \
   (HAS_RTL_P (NODE) && DECL_WRTL_CHECK (NODE)->decl_with_rtl.rtl != NULL)
 
-/* Copy the RTL from NODE1 to NODE2.  If the RTL was not set for
-   NODE1, it will not be set for NODE2; this is a lazy copy.  */
-#define COPY_DECL_RTL(NODE1, NODE2) \
-  (DECL_WRTL_CHECK (NODE2)->decl_with_rtl.rtl \
-   = DECL_WRTL_CHECK (NODE1)->decl_with_rtl.rtl)
+/* Copy the RTL from SRC_DECL to DST_DECL.  If the RTL was not set for
+   SRC_DECL, it will not be set for DST_DECL; this is a lazy copy.  */
+#define COPY_DECL_RTL(SRC_DECL, DST_DECL) \
+  (DECL_WRTL_CHECK (DST_DECL)->decl_with_rtl.rtl \
+   = DECL_WRTL_CHECK (SRC_DECL)->decl_with_rtl.rtl)
 
 /* The DECL_RTL for NODE, if it is set, or NULL, if it is not set.  */
 #define DECL_RTL_IF_SET(NODE) (DECL_RTL_SET_P (NODE) ? DECL_RTL (NODE) : NULL)
@@ -2723,19 +2723,21 @@  extern void decl_value_expr_insert (tree
 
 /* Set the DECL_ASSEMBLER_NAME for NODE to NAME.  */
 #define SET_DECL_ASSEMBLER_NAME(NODE, NAME) \
-  (DECL_ASSEMBLER_NAME_RAW (NODE) = (NAME))
+  overwrite_decl_assembler_name (NODE, NAME)
 
-/* Copy the DECL_ASSEMBLER_NAME from DECL1 to DECL2.  Note that if DECL1's
-   DECL_ASSEMBLER_NAME has not yet been set, using this macro will not cause
-   the DECL_ASSEMBLER_NAME of either DECL to be set.  In other words, the
-   semantics of using this macro, are different than saying:
+/* Copy the DECL_ASSEMBLER_NAME from SRC_DECL to DST_DECL.  Note that
+   if SRC_DECL's DECL_ASSEMBLER_NAME has not yet been set, using this
+   macro will not cause the DECL_ASSEMBLER_NAME to be set, but will
+   clear DECL_ASSEMBLER_NAME of DST_DECL, if it was already set.  In
+   other words, the semantics of using this macro, are different than
+   saying:
 
-     SET_DECL_ASSEMBLER_NAME(DECL2, DECL_ASSEMBLER_NAME (DECL1))
+     SET_DECL_ASSEMBLER_NAME(DST_DECL, DECL_ASSEMBLER_NAME (SRC_DECL))
 
-   which will try to set the DECL_ASSEMBLER_NAME for DECL1.  */
+   which will try to set the DECL_ASSEMBLER_NAME for SRC_DECL.  */
 
-#define COPY_DECL_ASSEMBLER_NAME(DECL1, DECL2)				\
-  SET_DECL_ASSEMBLER_NAME (DECL2, DECL_ASSEMBLER_NAME_RAW (DECL1))
+#define COPY_DECL_ASSEMBLER_NAME(SRC_DECL, DST_DECL)			\
+  SET_DECL_ASSEMBLER_NAME (DST_DECL, DECL_ASSEMBLER_NAME_RAW (SRC_DECL))
 
 /* Records the section name in a section attribute.  Used to pass
    the name from decl_attributes to make_function_rtl and make_decl_rtl.  */
@@ -3872,6 +3874,7 @@  id_equal (const char *str, const_tree id
    || ((NODE) && TREE_TYPE ((NODE)) == error_mark_node))
 
 extern tree decl_assembler_name (tree);
+extern void overwrite_decl_assembler_name (tree decl, tree name);
 extern tree decl_comdat_group (const_tree);
 extern tree decl_comdat_group_id (const_tree);
 extern const char *decl_section_name (const_tree);
Index: cp/cp-objcp-common.h
===================================================================
--- cp/cp-objcp-common.h	(revision 254703)
+++ cp/cp-objcp-common.h	(working copy)
@@ -73,6 +73,8 @@  extern void cp_register_dumps (gcc::dump
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
 #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
 #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME mangle_decl
+#undef LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME overwrite_mangling
 #undef LANG_HOOKS_PRINT_STATISTICS
 #define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics
 #undef LANG_HOOKS_PRINT_XNODE
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 254703)
+++ cp/cp-tree.h	(working copy)
@@ -6188,6 +6188,7 @@  extern tree cxx_maybe_build_cleanup		(tr
 
 /* in decl2.c */
 extern void record_mangling			(tree, bool);
+extern void overwrite_mangling			(tree, tree);
 extern void note_mangling_alias			(tree, tree);
 extern void generate_mangling_aliases		(void);
 extern tree build_memfn_type			(tree, tree, cp_cv_quals, cp_ref_qualifier);
Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 254703)
+++ cp/decl2.c	(working copy)
@@ -123,9 +123,14 @@  struct mangled_decl_hash : ggc_remove <t
   static inline void mark_empty (value_type &p) {p = NULL_TREE;}
   static inline bool is_empty (value_type p) {return !p;}
 
-  /* Nothing is deletable.  Everything is insertable.  */
-  static bool is_deleted (value_type) { return false; }
-  static void mark_deleted (value_type) { gcc_unreachable (); }
+  static bool is_deleted (value_type e)
+  {
+    return e == reinterpret_cast <value_type> (1);
+  }
+  static void mark_deleted (value_type &e)
+  {
+    e = reinterpret_cast <value_type> (1);
+  }
 };
 
 /* A hash table of decls keyed by mangled name.  Used to figure out if
@@ -4439,6 +4444,33 @@  record_mangling (tree decl, bool need_wa
     }
 }
 
+/* The mangled name of DECL is being forcibly changed to NAME.  Remove
+   any existing knowledge of DECL's mangled name meaning DECL.  */
+
+void
+overwrite_mangling (tree decl, tree name)
+{
+  if (tree id = DECL_ASSEMBLER_NAME_RAW (decl))
+    if ((TREE_CODE (decl) == VAR_DECL
+	 || TREE_CODE (decl) == FUNCTION_DECL)
+	&& mangled_decls)
+      if (tree *slot
+	  = mangled_decls->find_slot_with_hash (id, IDENTIFIER_HASH_VALUE (id),
+						NO_INSERT))
+	if (*slot == decl)
+	  {
+	    mangled_decls->clear_slot (slot);
+
+	    /* If this is an alias, remove it from the symbol table.  */
+	    if (DECL_ARTIFICIAL (decl) && DECL_IGNORED_P (decl))
+	      if (symtab_node *n = symtab_node::get (decl))
+		if (n->cpp_implicit_alias)
+		  n->remove ();
+	  }
+
+  DECL_ASSEMBLER_NAME_RAW (decl) = name;
+}
+
 /* The entire file is now complete.  If requested, dump everything
    to a file.  */
 
Index: langhooks-def.h
===================================================================
--- langhooks-def.h	(revision 254703)
+++ langhooks-def.h	(working copy)
@@ -51,7 +51,8 @@  extern const char *lhd_dwarf_name (tree,
 extern int lhd_types_compatible_p (tree, tree);
 extern void lhd_print_error_function (diagnostic_context *,
 				      const char *, struct diagnostic_info *);
-extern void lhd_set_decl_assembler_name (tree);
+extern void lhd_set_decl_assembler_name (tree decl);
+extern void lhd_overwrite_decl_assembler_name (tree decl, tree name);
 extern bool lhd_warn_unused_global_decl (const_tree);
 extern tree lhd_type_for_size (unsigned precision, int unsignedp);
 extern void lhd_incomplete_type_error (location_t, const_tree, const_tree);
@@ -107,6 +108,7 @@  extern int lhd_type_dwarf_attribute (con
 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
 #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
+#define LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME lhd_overwrite_decl_assembler_name
 #define LANG_HOOKS_PRINT_STATISTICS	lhd_do_nothing
 #define LANG_HOOKS_PRINT_XNODE		lhd_print_tree_nothing
 #define LANG_HOOKS_PRINT_DECL		lhd_print_tree_nothing
@@ -310,6 +312,7 @@  extern void lhd_end_section (void);
   LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
   LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
   LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, \
+  LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME, \
   LANG_HOOKS_PRINT_STATISTICS, \
   LANG_HOOKS_PRINT_XNODE, \
   LANG_HOOKS_PRINT_DECL, \
Index: langhooks.c
===================================================================
--- langhooks.c	(revision 254703)
+++ langhooks.c	(working copy)
@@ -171,8 +171,15 @@  lhd_set_decl_assembler_name (tree decl)
       ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
       id = get_identifier (label);
     }
-  SET_DECL_ASSEMBLER_NAME (decl, id);
 
+  DECL_ASSEMBLER_NAME_RAW (decl) = id;
+}
+
+/* Forcibly overwrite the DECL_ASSEMBLER_NAME for DECL to NAME.  */
+void
+lhd_overwrite_decl_assembler_name (tree decl, tree name)
+{
+  DECL_ASSEMBLER_NAME_RAW (decl) = name;
 }
 
 /* Type promotion for variable arguments.  */
Index: langhooks.h
===================================================================
--- langhooks.h	(revision 254703)
+++ langhooks.h	(working copy)
@@ -395,6 +395,10 @@  struct lang_hooks
      assembler does not talk about it.  */
   void (*set_decl_assembler_name) (tree);
 
+  /* Overwrite the DECL_ASSEMBLER_NAME for a node.  The name is being
+     changed (including to or from NULL_TREE).  */
+  void (*overwrite_decl_assembler_name) (tree, tree);
+
   /* The front end can add its own statistics to -fmem-report with
      this hook.  It should output to stderr.  */
   void (*print_statistics) (void);
Index: testsuite/g++.dg/pr82836.C
===================================================================
--- testsuite/g++.dg/pr82836.C	(revision 0)
+++ testsuite/g++.dg/pr82836.C	(working copy)
@@ -0,0 +1,628 @@ 
+// PR c++/82836
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-Wno-pedantic" }
+// We were resetting DECL_ASSEMBLER_NAME when processing pragma weak,
+// breaking C++'s mangling alias hash table.  That hash table needs to
+// be tickled in just the right way to hit the problem.
+
+namespace std {
+typedef long unsigned size_t;
+inline namespace __cxx11 {}
+double abs() {}
+__int128 abs(__int128 ) {}
+__float128 abs(__float128 ) {}
+
+  
+#pragma weak pthread_create
+typedef int luaL_Reg;
+typedef int swig_lua_const_info;
+typedef int swig_lua_attribute;
+typedef int swig_lua_class;
+}
+static int swig_types;
+static int swig_module;
+namespace std {
+  template < typename > class allocator;
+  template < class > struct char_traits;
+  namespace __cxx11 {
+  template < typename _CharT, typename =  _CharT ,
+             typename =  _CharT  >
+  class basic_string;
+  typedef basic_string< char > string;
+  }
+}
+namespace __gnu_cxx {
+  template < typename > struct __numeric_traits_integer;
+  struct __conditional_type {
+    typedef __numeric_traits_integer< int > __type;
+  }__is_null_pointer0;
+  template < typename _Value > struct __numeric_traits_integer {
+    static const _Value __min = 0;
+    static const _Value __max = 0;
+  };
+  template < typename _Value >
+  const _Value __numeric_traits_integer< _Value >::__min;
+  template < typename _Value >
+  const _Value __numeric_traits_integer< _Value >::__max;
+  template < typename >
+  struct __numeric_traits : __conditional_type::__type {};
+}
+namespace std {
+  template < typename _Tp, _Tp __v > struct integral_constant {
+    static constexpr _Tp value = __v;
+  };
+  template < typename _Tp, _Tp __v >
+  constexpr _Tp integral_constant< _Tp, __v >::value;
+  typedef integral_constant< bool, false > false_type;
+  struct __is_void_helper : false_type {};
+  struct is_void : __is_void_helper{};
+  template < int > struct conditional  ;
+  template < typename , typename ,
+             template < typename... > class >
+  struct __detector {
+       ;
+  };
+  template < typename _Default, template < typename > class _Op>
+  using __detected_or = __detector< _Default, void, _Op>;
+  template < typename _Default, template < typename> class _Op
+               >
+  using __detected_or_t =
+      typename __detected_or< _Default, _Op>::type;
+  struct  {}piecewise_construct ;
+  struct random_access_iterator_tag ;
+  template < typename , typename > struct iterator {
+    typedef int difference_type;
+    typedef int reference;
+  };
+  using __make_not_void = conditional< is_void::value >;
+      struct pointer_traits 
+    ;
+  
+  template <> struct char_traits< char > {
+    typedef char char_type;
+    typedef int int_type;
+    void assign() {}
+    bool eq() {}
+    bool lt() {}
+    int compare() {}
+    size_t length() {}
+    char_type find() {}
+    char_type move() {}
+    char_type copy() {}
+    char_type assign(char_type ) {}
+    char_type to_char_type() {}
+    int_type to_int_type() {}
+    bool eq_int_type() {}
+    int_type eof() {}
+    int_type not_eof() {}
+  };
+  template <> struct char_traits< wchar_t > {
+    typedef wchar_t char_type;
+    typedef int int_type;
+    void assign() {}
+    bool eq() {}
+    bool lt() {}
+    int compare() {}
+    size_t length() {}
+    char_type find() {}
+    char_type move() {}
+    char_type copy() {}
+    char_type assign(char_type ) {}
+    char_type to_char_type() {}
+    int_type to_int_type() {}
+    bool eq_int_type() {}
+    int_type eof() {}
+    int_type not_eof() {}
+  };
+}
+typedef int uint_least16_t;
+typedef int uint_least32_t;
+namespace std {
+template <> struct char_traits< char16_t > {
+  typedef char16_t char_type;
+  typedef uint_least16_t int_type;
+  void assign() {}
+  bool eq() {}
+  bool lt() {}
+  int compare() {}
+  size_t length() {}
+  char_type find() {}
+  char_type move() {}
+  char_type copy() {}
+  char_type assign(char_type ) {}
+  char_type to_char_type() {}
+  int_type to_int_type() {}
+  bool eq_int_type() {}
+  int_type eof() {}
+  int_type not_eof() {}
+};
+template <> struct char_traits< char32_t > {
+  typedef char32_t char_type;
+  typedef uint_least32_t int_type;
+  void assign() {}
+  bool eq() {}
+  bool lt() {}
+  int compare() {}
+  size_t length() {}
+  char_type find() {}
+  char_type move() {}
+  char_type copy() {}
+  char_type assign(char_type ) {}
+  char_type to_char_type() {}
+  int_type to_int_type() {}
+  bool eq_int_type() {}
+  int_type eof() {}
+  int_type not_eof() {}
+};
+}
+void *operator new(std::size_t) {}
+void *operator new[](std::size_t) {}
+void operator delete(void *){}
+void operator delete[](void *) {}
+namespace  {
+        ;
+}
+namespace std {
+
+template < typename  > class allocator {
+public:
+  
+  
+  ~allocator();
+}
+;
+template < typename _Tp >
+struct less {
+  bool operator()( _Tp ,  _Tp ) {}
+};
+}
+typedef int _Atomic_word;
+namespace {
+  _Atomic_word __exchange_and_add_single0;
+  static void __atomic_add_single();
+  _Atomic_word __attribute____exchange_and_add_dispatch0;
+  static void __attribute____atomic_add_dispatch();
+}
+namespace std {
+  struct __allocator_traits_base {
+    template < typename = void > struct __rebind {
+      using type =
+          allocator< char >;
+    }
+
+  ;
+  };
+  template < typename , typename >
+  using __alloc_rebind =
+      __allocator_traits_base::__rebind<>::type;
+  template < typename >
+  struct allocator_traits   {
+       
+    template < typename _Tp >
+    using rebind_alloc = __alloc_rebind<  char , _Tp >;
+  };
+}
+namespace __gnu_cxx {
+  template < typename >
+  struct __alloc_traits : std::allocator_traits< std::allocator< char > > {
+    template < typename > struct rebind {
+      typedef rebind_alloc< int >
+          other;
+    };
+  };
+}
+namespace std {
+  namespace __cxx11 {
+  template < typename , typename , typename >
+  class basic_string {
+    typedef __gnu_cxx::__alloc_traits<  char  >::
+        rebind< int >::other _Char_alloc_type
+    ;
+    struct  : _Char_alloc_type {}_M_dataplus;
+    int _S_compare() {
+      
+      if (__gnu_cxx::__numeric_traits< int >::__max)
+        
+       (__gnu_cxx::__numeric_traits< int >::__min)
+        ;
+    }
+  };
+  }
+  template < typename _CharT, typename _Traits, typename _Alloc >
+  basic_string<  _Traits> operator+(
+       basic_string<   _Alloc > );
+  template < typename _CharT, typename _Traits, typename _Alloc >
+  basic_string<  _Traits> operator+(
+        _Alloc  );
+  template < typename _CharT, typename _Traits, typename _Alloc >
+  basic_string<  _Traits> operator+(
+        _Alloc  );
+  template < typename , typename > struct __hash_base ;
+  template < typename > struct hash;
+  template <> struct hash< char > {
+    void operator0() {}
+  };
+  template <> struct hash< signed char > {
+    void operator0() {}
+  };
+  template <> struct hash< unsigned char > {
+    void operator0() {}
+  };
+  template <> struct hash< wchar_t > {
+    void operator0() {}
+  };
+  template <> struct __hash_base< size_t, char16_t > {
+    size_t operator0() {}
+  };
+  template <> struct __hash_base< size_t, char32_t > {
+    size_t operator0() {}
+  };
+  template <> struct hash< short > {
+    void operator0() {}
+  };
+  template <> struct hash< int > {
+    void operator0() {}
+  };
+  template <> struct hash< long > {
+    void operator0() {}
+  };
+  template <> struct hash< long long > {
+    void operator0() {}
+  };
+  template <> struct hash< unsigned short > {
+    void operator0() {}
+  };
+  template <> struct hash< unsigned > {
+    void operator0() {}
+  };
+  template <> struct hash< unsigned long > {
+    void operator0() {}
+  };
+  template <> struct hash< unsigned long long > {
+    void operator0() {}
+  };
+  template <> struct hash< __int128 > {
+    void operator0() {}
+  };
+  template <> struct hash< __int128 unsigned > {
+    void operator0() {}
+  };
+  typedef long _Bit_type;
+  struct _Bit_reference {
+     ;
+    _Bit_type _M_mask;
+    _Bit_reference  () {}
+    operator bool() {}
+    _Bit_reference (bool ) {}
+    _Bit_reference operator=(_Bit_reference ) {}
+    bool operator==(_Bit_reference ) {}
+    bool operator<(_Bit_reference ) {}
+    void flip() {}
+  };
+  void swap() {}
+  void swap(bool ) {}
+  void swap(_Bit_reference ) {}
+  struct _Bit_iterator_base
+      :iterator< random_access_iterator_tag, bool > {
+    _Bit_type *_M_p;
+    int _M_offset;
+    _Bit_iterator_base(_Bit_type *, int 
+         _M_offset) {}
+    void _M_bump_up() {}
+    void _M_bump_down() {}
+    void _M_incr() {}
+    bool operator==(_Bit_iterator_base ) {}
+    bool operator<(_Bit_iterator_base ) {}
+    bool operator!=(_Bit_iterator_base ) {}
+    bool operator>(_Bit_iterator_base ) {}
+    bool operator<=(_Bit_iterator_base ) {}
+    bool operator>=(_Bit_iterator_base ) {}
+  };
+  struct _Bit_iterator : _Bit_iterator_base {
+    _Bit_iterator() : _Bit_iterator_base(0, 0) {}
+    _Bit_iterator(_Bit_type *__x, int __y)
+        : _Bit_iterator_base(__x, __y) {}
+    iterator _M_const_cast() {}
+    iterator operator+() {}
+    iterator operator-() {}
+    reference operator[](difference_type ) {}
+  };
+  void operator+(_Bit_iterator ) {}
+  struct _Bit_const_iterator : _Bit_iterator_base {
+    _Bit_const_iterator() : _Bit_iterator_base(0, 0) {}
+    _Bit_type _Bit_const_iterator___x;
+    _Bit_const_iterator(int __y)
+        : _Bit_iterator_base(&_Bit_const_iterator___x, __y) {}
+    _Bit_const_iterator(_Bit_iterator __x)
+        : _Bit_iterator_base(_M_p, _M_offset) {}
+    void _M_const_cast() {}
+    void operator*() {}
+    void operator++() {}
+    void operator++(int) {}
+    void operator--() {}
+  };
+  class runtime_error {
+  public:
+    runtime_error(const string );
+  };
+  inline namespace _V2 {
+  class error_category {
+    bool operator<(error_category __other) {
+      less< error_category * >()(this, &__other);
+    }
+    bool operator==(error_category ) {}
+    bool operator!=(error_category ) {}
+  };
+  }
+  struct error_code {
+    error_code() : _M_cat() {}
+    error_code(error_category ) : _M_cat() {}
+    void assign() {}
+    void clear() {}
+    int value() {}
+    error_category category() {}
+    string message() {}
+    error_category _M_cat;
+  };
+  inline error_code make_error_code() noexcept {}
+  inline bool operator<(const error_code ,
+                        const error_code ) noexcept {}
+  struct error_condition {
+    error_condition() {}
+    error_condition(const error_category ) {}
+    void assign() noexcept {}
+    void clear() noexcept {}
+    int value() {}
+    const error_category &category() {}
+    string message_M_cat;
+  };
+  inline error_condition make_error_condition() noexcept {}
+  inline bool operator<(const error_condition ,
+                        const error_condition ) noexcept {}
+  inline bool operator==(const error_code ,
+                         const error_code ) noexcept {}
+  inline bool operator==(const error_code ,
+                         const error_condition ) noexcept {}
+  inline bool operator==(const error_condition ,
+                         const error_code ) noexcept {}
+  inline bool operator==(const error_condition ,
+                         const error_condition ) noexcept {}
+  inline bool operator!=(const error_code ,
+                         const error_code ) noexcept {}
+  inline bool operator!=(const error_code ,
+                         const error_condition ) noexcept {}
+  inline bool operator!=(const error_condition ,
+                         const error_code ) noexcept {}
+  inline bool operator!=(const error_condition ,
+                         const error_condition ) noexcept {}
+  class system_error : public runtime_error {
+  error_code _M_code;
+
+  system_error(error_code __ec = error_code())
+        : runtime_error(__ec.message()) {}
+    system_error(error_code __ec, const string &__what)
+        : runtime_error(__ec.message()) {}
+    system_error(error_code __ec, const char *__what)
+        : runtime_error((__ec.message())) {}
+    system_error(const char )
+        : system_error() {}
+    system_error(const error_category )
+        : runtime_error(error_code().message()) {}
+    system_error(const string &__what)
+        : runtime_error(error_code().message()) {}
+    const error_code &code() {}
+    void operator0() {}
+  };
+  enum _Ios_Fmtflags {};
+  _Ios_Fmtflags operator&(_Ios_Fmtflags __a__b) {}
+  _Ios_Fmtflags operator|(_Ios_Fmtflags __a,
+                                           _Ios_Fmtflags __b) {}
+  _Ios_Fmtflags operator^(_Ios_Fmtflags __a,
+                                           _Ios_Fmtflags __b) {}
+  _Ios_Fmtflags operator~(_Ios_Fmtflags __a) {}
+  _Ios_Fmtflags &operator|=(_Ios_Fmtflags ,
+                                         _Ios_Fmtflags __b) {}
+  _Ios_Fmtflags &operator&=(_Ios_Fmtflags ,
+                                         _Ios_Fmtflags __b) {}
+  _Ios_Fmtflags &operator^=(_Ios_Fmtflags ,
+                                         _Ios_Fmtflags __b) {}
+  enum _Ios_Openmode {
+    _S_ios_openmode_max };
+  _Ios_Openmode operator&(_Ios_Openmode __a__b) {}
+  _Ios_Openmode operator|(_Ios_Openmode __a,
+                                           _Ios_Openmode __b) {}
+  _Ios_Openmode operator^(_Ios_Openmode __a,
+                                           _Ios_Openmode __b) {}
+  _Ios_Openmode operator~(_Ios_Openmode __a) {}
+  _Ios_Openmode &operator|=(_Ios_Openmode ,
+                                         _Ios_Openmode __b) {}
+  _Ios_Openmode &operator&=(_Ios_Openmode ,
+                                         _Ios_Openmode __b) {}
+  _Ios_Openmode &operator^=(_Ios_Openmode ,
+                                         _Ios_Openmode __b) {}
+  enum _Ios_Iostate {
+    _S_ios_iostate_max };
+  _Ios_Iostate operator&(_Ios_Iostate __a__b) {}
+  _Ios_Iostate operator|(_Ios_Iostate __a, _Ios_Iostate __b) {}
+  _Ios_Iostate operator^(_Ios_Iostate __a, _Ios_Iostate __b) {}
+  _Ios_Iostate operator~(_Ios_Iostate __a) {}
+  _Ios_Iostate &operator|=(_Ios_Iostate , _Ios_Iostate __b) {}
+  _Ios_Iostate &operator&=(_Ios_Iostate , _Ios_Iostate __b) {}
+  _Ios_Iostate &operator^=(_Ios_Iostate , _Ios_Iostate __b) {}
+  enum class io_errc;
+  inline error_code make_error_code(io_errc __e) noexcept {}
+  inline error_condition make_error_condition_wrap_class_string;
+static luaL_Reg swig_ClientProfile_methods;
+static luaL_Reg swig_ClientProfile_meta;
+static swig_lua_attribute swig_ClientProfile_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_ClientProfile_Sf_SwigStatic_constants;
+static luaL_Reg swig_ClientProfile_Sf_SwigStatic_methods;
+static swig_lua_class swig_ClientProfile_Sf_SwigStatic_classes;
+static int swig_ClientProfile_Sf_SwigStatic;
+static swig_lua_class swig_ClientProfile_bases;
+static const char *swig_ClientProfile_base_names;
+static swig_lua_class _wrap_class_ClientProfile;
+static int _proxy__wrap_new_Connection0;
+static swig_lua_attribute swig_Connection_attributes;
+static luaL_Reg swig_Connection_methods;
+static luaL_Reg swig_Connection_meta;
+static swig_lua_attribute swig_Connection_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_Connection_Sf_SwigStatic_constants;
+static luaL_Reg swig_Connection_Sf_SwigStatic_methods;
+static swig_lua_class swig_Connection_Sf_SwigStatic_classes;
+static int swig_Connection_Sf_SwigStatic;
+static swig_lua_class swig_Connection_bases;
+static const char swig_Connection_base_names = 0;
+static swig_lua_class _wrap_class_Connection;
+static int _proxy__wrap_new_ConnectionPool0;
+static swig_lua_attribute swig_ConnectionPool_attributes;
+static luaL_Reg swig_ConnectionPool_methods;
+static luaL_Reg swig_ConnectionPool_meta;
+static swig_lua_attribute swig_ConnectionPool_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_ConnectionPool_Sf_SwigStatic_constants;
+static luaL_Reg swig_ConnectionPool_Sf_SwigStatic_methods;
+static swig_lua_class swig_ConnectionPool_Sf_SwigStatic_classes;
+static int swig_ConnectionPool_Sf_SwigStatic;
+static swig_lua_class *swig_ConnectionPool_bases ;
+static const char *swig_ConnectionPool_base_names ;
+static swig_lua_class _wrap_class_ConnectionPool;
+static int _proxy__wrap_new_Client0;
+static swig_lua_attribute swig_Client_attributes;
+static luaL_Reg swig_Client_methods;
+static luaL_Reg swig_Client_meta;
+static swig_lua_attribute swig_Client_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_Client_Sf_SwigStatic_constants;
+static luaL_Reg swig_Client_Sf_SwigStatic_methods;
+static swig_lua_class swig_Client_Sf_SwigStatic_classes;
+static int swig_Client_Sf_SwigStatic;
+static swig_lua_class *swig_Client_bases;
+static const char *swig_Client_base_names;
+static swig_lua_class _wrap_class_Client;
+static int _proxy__wrap_new_PreludeLog0;
+static swig_lua_attribute swig_PreludeLog_attributes;
+static luaL_Reg swig_PreludeLog_methods;
+static luaL_Reg swig_PreludeLog_meta;
+static swig_lua_attribute swig_PreludeLog_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_PreludeLog_Sf_SwigStatic_constants;
+static luaL_Reg swig_PreludeLog_Sf_SwigStatic_methods;
+static swig_lua_class swig_PreludeLog_Sf_SwigStatic_classes;
+static int swig_PreludeLog_Sf_SwigStatic;
+static swig_lua_class swig_PreludeLog_bases;
+static const char *swig_PreludeLog_base_names;
+static swig_lua_class _wrap_class_PreludeLog;
+static int _proxy__wrap_new_PreludeError0;
+static swig_lua_attribute swig_PreludeError_attributes;
+static luaL_Reg swig_PreludeError_methods;
+static luaL_Reg swig_PreludeError_meta;
+static swig_lua_attribute swig_PreludeError_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_PreludeError_Sf_SwigStatic_constants;
+static luaL_Reg swig_PreludeError_Sf_SwigStatic_methods;
+static swig_lua_class swig_PreludeError_Sf_SwigStatic_classes;
+static int swig_PreludeError_Sf_SwigStatic;
+static swig_lua_class swig_PreludeError_bases;
+static const char *swig_PreludeError_base_names;
+static swig_lua_class _wrap_class_PreludeError;
+static int _proxy__wrap_new_ClientEasy0;
+static swig_lua_attribute swig_ClientEasy_attributes;
+static luaL_Reg swig_ClientEasy_methods;
+static luaL_Reg swig_ClientEasy_meta;
+static swig_lua_attribute swig_ClientEasy_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_ClientEasy_Sf_SwigStatic_constants;
+static luaL_Reg swig_ClientEasy_Sf_SwigStatic_methods;
+static swig_lua_class swig_ClientEasy_Sf_SwigStatic_classes;
+static int swig_ClientEasy_Sf_SwigStatic;
+static swig_lua_class *swig_ClientEasy_bases;
+static const char *swig_ClientEasy_base_names;
+static swig_lua_class _wrap_class_ClientEasy;
+static int _proxy__wrap_new_IDMEFCriterion0;
+static swig_lua_attribute swig_IDMEFCriterion_attributes;
+static luaL_Reg swig_IDMEFCriterion_methods;
+static luaL_Reg swig_IDMEFCriterion_meta;
+static swig_lua_attribute swig_IDMEFCriterion_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_IDMEFCriterion_Sf_SwigStatic_constants;
+static luaL_Reg swig_IDMEFCriterion_Sf_SwigStatic_methods;
+static swig_lua_class swig_IDMEFCriterion_Sf_SwigStatic_classes;
+static int swig_IDMEFCriterion_Sf_SwigStatic;
+static swig_lua_class swig_IDMEFCriterion_bases;
+static const char *swig_IDMEFCriterion_base_names;
+static swig_lua_class _wrap_class_IDMEFCriterion;
+static int _proxy__wrap_new_IDMEFCriteria0;
+static swig_lua_attribute swig_IDMEFCriteria_attributes;
+static luaL_Reg swig_IDMEFCriteria_methods;
+static luaL_Reg swig_IDMEFCriteria_meta;
+static swig_lua_attribute swig_IDMEFCriteria_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_IDMEFCriteria_Sf_SwigStatic_constants;
+static luaL_Reg swig_IDMEFCriteria_Sf_SwigStatic_methods;
+static swig_lua_class swig_IDMEFCriteria_Sf_SwigStatic_classes;
+static int swig_IDMEFCriteria_Sf_SwigStatic;
+static swig_lua_class swig_IDMEFCriteria_bases;
+static const char *swig_IDMEFCriteria_base_names;
+static swig_lua_class _wrap_class_IDMEFCriteria;
+static int _proxy__wrap_new_IDMEFValue0;
+static swig_lua_attribute swig_IDMEFValue_attributes;
+static luaL_Reg swig_IDMEFValue_methods;
+static luaL_Reg swig_IDMEFValue_meta;
+static swig_lua_attribute swig_IDMEFValue_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_IDMEFValue_Sf_SwigStatic_constants;
+static luaL_Reg swig_IDMEFValue_Sf_SwigStatic_methods;
+static swig_lua_class swig_IDMEFValue_Sf_SwigStatic_classes;
+static int swig_IDMEFValue_Sf_SwigStatic;
+static swig_lua_class swig_IDMEFValue_bases;
+static const char *swig_IDMEFValue_base_names;
+static swig_lua_class _wrap_class_IDMEFValue;
+static int _proxy__wrap_new_IDMEFPath0;
+static swig_lua_attribute swig_IDMEFPath_attributes;
+static luaL_Reg swig_IDMEFPath_methods;
+static luaL_Reg swig_IDMEFPath_meta;
+static swig_lua_attribute swig_IDMEFPath_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_IDMEFPath_Sf_SwigStatic_constants;
+static luaL_Reg swig_IDMEFPath_Sf_SwigStatic_methods;
+static swig_lua_class swig_IDMEFPath_Sf_SwigStatic_classes;
+static int swig_IDMEFPath_Sf_SwigStatic;
+static swig_lua_class swig_IDMEFPath_bases;
+static const char *swig_IDMEFPath_base_names;
+static swig_lua_class _wrap_class_IDMEFPath;
+static int _proxy__wrap_new_IDMEFTime0;
+static swig_lua_attribute swig_IDMEFTime_attributes;
+static luaL_Reg swig_IDMEFTime_methods;
+static luaL_Reg swig_IDMEFTime_meta;
+static swig_lua_attribute swig_IDMEFTime_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_IDMEFTime_Sf_SwigStatic_constants;
+static luaL_Reg swig_IDMEFTime_Sf_SwigStatic_methods;
+static swig_lua_class swig_IDMEFTime_Sf_SwigStatic_classes;
+static int swig_IDMEFTime_Sf_SwigStatic;
+static swig_lua_class swig_IDMEFTime_bases;
+static const char *swig_IDMEFTime_base_names;
+static swig_lua_class _wrap_class_IDMEFTime;
+static int _proxy__wrap_new_IDMEFClass0;
+static swig_lua_attribute swig_IDMEFClass_attributes;
+static luaL_Reg swig_IDMEFClass_methods;
+static luaL_Reg swig_IDMEFClass_meta;
+static swig_lua_attribute swig_IDMEFClass_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_IDMEFClass_Sf_SwigStatic_constants;
+static luaL_Reg swig_IDMEFClass_Sf_SwigStatic_methods;
+static swig_lua_class swig_IDMEFClass_Sf_SwigStatic_classes;
+static int swig_IDMEFClass_Sf_SwigStatic;
+static swig_lua_class swig_IDMEFClass_bases;
+static const char *swig_IDMEFClass_base_names;
+static swig_lua_class _wrap_class_IDMEFClass;
+static int _proxy__wrap_new_IDMEF0;
+static swig_lua_attribute swig_IDMEF_attributes;
+static luaL_Reg swig_IDMEF_methods;
+static luaL_Reg swig_IDMEF_meta;
+static swig_lua_attribute swig_IDMEF_Sf_SwigStatic_attributes;
+static swig_lua_const_info swig_IDMEF_Sf_SwigStatic_constants;
+static luaL_Reg swig_IDMEF_Sf_SwigStatic_methods;
+static swig_lua_class swig_IDMEF_Sf_SwigStatic_classes;
+static int swig_IDMEF_Sf_SwigStatic;
+static swig_lua_class swig_IDMEF_bases;
+static const char *swig_IDMEF_base_names;
+static swig_lua_class _wrap_class_IDMEF;
+static swig_lua_attribute swig_SwigModule_attributes;
+static swig_lua_const_info swig_SwigModule_constants;
+static luaL_Reg swig_SwigModule_methods;
+static swig_lua_class *swig_SwigModule_classes;
+static int swig_SwigModule_namespaces;
+static int swig_SwigModule;
+}
+static void *_p_Prelude__ClientTo_p_Prelude__ClientProfile0;