[trimmed cc list because of big attachments]

On 8/16/16 4:22 PM, Jim Nasby wrote:
> Joy, do you have an idea what a *minimally invasive* patch for C++ 
> support would look like? That's certainly the first step here.

I developed a minimally invasive patch for C++ support a few years ago
shortly after I wrote that blog post.  Since there appears to have been
some interest here now, I have updated that and split it up into logical
chunks.

So here you go.

To build this, you need to configure with g++ <= version 5.  (4.x works,
too.)  g++ version 6 does not work yet because of the issues described
in patch 0013.

Then you also need to edit src/Makefile.custom and set

    COPT = -fpermissive -Wno-sign-compare -Wno-write-strings

The -W options are optional just to reduce some noise.  Cleaning up
those warnings can be a separate project that might also have some
benefit under C.

The -fpermissive option is a g++ specific option that reduces some
errors to warnings.  (So this won't work with clang or other compilers
at all at this point.)  In particular, C++ does not allow casting from
or to void pointers without a cast, but -fpermissive allows that.  The
step from this to "real" C++ would be adding a bunch of casts around
things like malloc and palloc and other places.  That would be mostly
busy work, so I have excluded that here.

The patches are numbered approximately in increasing order of dubiosity.
 So 0001 is probably a straight bug fix, 0002 and 0003 are arguably
minor bug fixes as well.  The patches through 0012 can probably be
considered for committing in some form.  After that it gets a bit hackish.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From 86dbd4a5a0ab3212cd340e1fa56f03e864aa8e1a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 01/27] Fix use of offsetof()

Using offsetof() with a run-time computed argument is not allowed in
either C or C++.  Apparently, gcc allows it, but g++ doesn't.
---
 contrib/bloom/blutils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c
index debf4f4..b68a0d1 100644
--- a/contrib/bloom/blutils.c
+++ b/contrib/bloom/blutils.c
@@ -75,7 +75,7 @@ _PG_init(void)
 		bl_relopt_tab[i + 1].optname = MemoryContextStrdup(TopMemoryContext,
 														   buf);
 		bl_relopt_tab[i + 1].opttype = RELOPT_TYPE_INT;
-		bl_relopt_tab[i + 1].offset = offsetof(BloomOptions, bitSize[i]);
+		bl_relopt_tab[i + 1].offset = offsetof(BloomOptions, bitSize[0]) + sizeof(int) * i;
 	}
 }
 
-- 
2.9.3

From d3c7c1fbb346fd5c040a7a379d971db7b5129581 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 02/27] Use return instead of exit() in configure

Using exit() requires stdlib.h, which is not included.  Use return
instead.  Also add return type for main().
---
 config/c-compiler.m4 |  4 +++-
 config/c-library.m4  |  4 +++-
 configure            | 12 +++++++++---
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index a7f6773..7d901e1 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -71,8 +71,10 @@ int does_int64_work()
     return 0;
   return 1;
 }
+
+int
 main() {
-  exit(! does_int64_work());
+  return (! does_int64_work());
 }])],
 [Ac_cachevar=yes],
 [Ac_cachevar=no],
diff --git a/config/c-library.m4 b/config/c-library.m4
index 50d068d..56658b5 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -204,8 +204,10 @@ int does_int64_snprintf_work()
     return 0;			/* either multiply or snprintf is busted */
   return 1;
 }
+
+int
 main() {
-  exit(! does_int64_snprintf_work());
+  return (! does_int64_snprintf_work());
 }]])],
 [pgac_cv_snprintf_long_long_int_modifier=$pgac_modifier; break],
 [],
diff --git a/configure b/configure
index 45c8eef..36d9a54 100755
--- a/configure
+++ b/configure
@@ -13563,8 +13563,10 @@ int does_int64_work()
     return 0;
   return 1;
 }
+
+int
 main() {
-  exit(! does_int64_work());
+  return (! does_int64_work());
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
@@ -13645,8 +13647,10 @@ int does_int64_work()
     return 0;
   return 1;
 }
+
+int
 main() {
-  exit(! does_int64_work());
+  return (! does_int64_work());
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
@@ -13739,8 +13743,10 @@ int does_int64_snprintf_work()
     return 0;			/* either multiply or snprintf is busted */
   return 1;
 }
+
+int
 main() {
-  exit(! does_int64_snprintf_work());
+  return (! does_int64_snprintf_work());
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-- 
2.9.3

From 54ed07be5a29d4955a9485316e68da5c6896797b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 03/27] Add missing include files to configure tests

atoi() needs stdlib.h
strcmp() needs string.h
---
 config/c-library.m4 | 4 +++-
 configure           | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/config/c-library.m4 b/config/c-library.m4
index 56658b5..8a9da36 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -42,7 +42,8 @@ if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
 fi
 AC_CACHE_CHECK(for tzname, ac_cv_var_tzname,
 [AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[#include <time.h>
+[[#include <stdlib.h>
+#include <time.h>
 #ifndef tzname /* For SGI.  */
 extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
 #endif
@@ -184,6 +185,7 @@ AC_DEFUN([PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER],
 AC_CACHE_VAL(pgac_cv_snprintf_long_long_int_modifier,
 [for pgac_modifier in 'll' 'q' 'I64'; do
 AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
+#include <string.h>
 typedef long long int ac_int64;
 #define INT64_FORMAT "%${pgac_modifier}d"
 
diff --git a/configure b/configure
index 36d9a54..2308c61 100755
--- a/configure
+++ b/configure
@@ -11538,6 +11538,7 @@ if ${ac_cv_var_tzname+:} false; then :
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#include <stdlib.h>
 #include <time.h>
 #ifndef tzname /* For SGI.  */
 extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
@@ -13723,6 +13724,7 @@ else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdio.h>
+#include <string.h>
 typedef long long int ac_int64;
 #define INT64_FORMAT "%${pgac_modifier}d"
 
-- 
2.9.3

From ee7e69813784e7cf120165ba222e93f91d0d8f42 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 04/27] Fix LDFLAGS test for C++

The test looks to link to particular function, so we need to make that
function have C linkage.
---
 config/c-compiler.m4 |  9 ++++++++-
 configure            | 27 ++++++++++++++++++++++++---
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 7d901e1..21fb464 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -353,7 +353,14 @@ AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
 AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
 [pgac_save_LDFLAGS=$LDFLAGS
 LDFLAGS="$pgac_save_LDFLAGS $1"
-AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])],
+AC_RUN_IFELSE([AC_LANG_PROGRAM([#ifdef __cplusplus
+extern "C" {
+#endif
+extern void $2 ();
+#ifdef __cplusplus
+}
+#endif
+void (*fptr) () = $2;],[])],
               [Ac_cachevar=yes],
               [Ac_cachevar=no],
               [Ac_cachevar="assuming no"])
diff --git a/configure b/configure
index 2308c61..d74b25f 100755
--- a/configure
+++ b/configure
@@ -15748,7 +15748,14 @@ if test "$cross_compiling" = yes; then :
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-extern void $link_test_func (); void (*fptr) () = $link_test_func;
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void $link_test_func ();
+#ifdef __cplusplus
+}
+#endif
+void (*fptr) () = $link_test_func;
 int
 main ()
 {
@@ -15787,7 +15794,14 @@ if test "$cross_compiling" = yes; then :
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-extern void $link_test_func (); void (*fptr) () = $link_test_func;
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void $link_test_func ();
+#ifdef __cplusplus
+}
+#endif
+void (*fptr) () = $link_test_func;
 int
 main ()
 {
@@ -15826,7 +15840,14 @@ if test "$cross_compiling" = yes; then :
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-extern void $link_test_func (); void (*fptr) () = $link_test_func;
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void $link_test_func ();
+#ifdef __cplusplus
+}
+#endif
+void (*fptr) () = $link_test_func;
 int
 main ()
 {
-- 
2.9.3

From 98b10d21551df4d038e10287f9bb447922897342 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 05/27] Add test for -Wmissing-prototypes

This was part of the hard-coded default warnings set in C, but the
option is not valid for C++ (since prototypes are always required).
---
 configure    | 38 +++++++++++++++++++++++++++++++++++++-
 configure.in |  4 +++-
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index d74b25f..7821c2f 100755
--- a/configure
+++ b/configure
@@ -4418,7 +4418,43 @@ fi
 # but has its own.  Also check other compiler-specific flags here.
 
 if test "$GCC" = yes -a "$ICC" = no; then
-  CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith"
+  CFLAGS="-Wall -Wpointer-arith"
+  # not valid for C++
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wmissing-prototypes" >&5
+$as_echo_n "checking whether $CC supports -Wmissing-prototypes... " >&6; }
+if ${pgac_cv_prog_cc_cflags__Wmissing_prototypes+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  pgac_save_CFLAGS=$CFLAGS
+CFLAGS="$pgac_save_CFLAGS -Wmissing-prototypes"
+ac_save_c_werror_flag=$ac_c_werror_flag
+ac_c_werror_flag=yes
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  pgac_cv_prog_cc_cflags__Wmissing_prototypes=yes
+else
+  pgac_cv_prog_cc_cflags__Wmissing_prototypes=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_c_werror_flag=$ac_save_c_werror_flag
+CFLAGS="$pgac_save_CFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_cflags__Wmissing_prototypes" >&5
+$as_echo "$pgac_cv_prog_cc_cflags__Wmissing_prototypes" >&6; }
+if test x"$pgac_cv_prog_cc_cflags__Wmissing_prototypes" = x"yes"; then
+  CFLAGS="$CFLAGS -Wmissing-prototypes"
+fi
+
   # These work in some but not all gcc versions
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wdeclaration-after-statement" >&5
 $as_echo_n "checking whether $CC supports -Wdeclaration-after-statement... " >&6; }
diff --git a/configure.in b/configure.in
index c878b4e..011e4c4 100644
--- a/configure.in
+++ b/configure.in
@@ -440,7 +440,9 @@ fi
 # but has its own.  Also check other compiler-specific flags here.
 
 if test "$GCC" = yes -a "$ICC" = no; then
-  CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith"
+  CFLAGS="-Wall -Wpointer-arith"
+  # not valid for C++
+  PGAC_PROG_CC_CFLAGS_OPT([-Wmissing-prototypes])
   # These work in some but not all gcc versions
   PGAC_PROG_CC_CFLAGS_OPT([-Wdeclaration-after-statement])
   PGAC_PROG_CC_CFLAGS_OPT([-Wendif-labels])
-- 
2.9.3

From 69259fa4f5fb0f28cbceda63fb2f2f425bcab7d8 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 06/27] Remove unnecessary prototypes

Prototypes for functions implementing V1-callable functions are no
longer necessary.
---
 contrib/bloom/bloom.h           |  1 -
 contrib/btree_gist/btree_gist.h | 10 ----------
 contrib/dblink/dblink.h         | 24 ------------------------
 contrib/isn/isn.h               | 19 -------------------
 contrib/pgcrypto/pgcrypto.h     | 13 -------------
 contrib/tablefunc/tablefunc.h   |  9 ---------
 6 files changed, 76 deletions(-)

diff --git a/contrib/bloom/bloom.h b/contrib/bloom/bloom.h
index bc451a0..18f5127 100644
--- a/contrib/bloom/bloom.h
+++ b/contrib/bloom/bloom.h
@@ -174,7 +174,6 @@ typedef BloomScanOpaqueData *BloomScanOpaque;
 
 /* blutils.c */
 extern void _PG_init(void);
-extern Datum blhandler(PG_FUNCTION_ARGS);
 extern void initBloomState(BloomState *state, Relation index);
 extern void BloomFillMetapage(Relation index, Page metaPage);
 extern void BloomInitMetapage(Relation index);
diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h
index dcffbb5..191202a 100644
--- a/contrib/btree_gist/btree_gist.h
+++ b/contrib/btree_gist/btree_gist.h
@@ -34,14 +34,4 @@ enum gbtree_type
 	gbt_t_inet
 };
 
-
-
-/*
- * Generic btree functions
- */
-
-Datum		gbtreekey_in(PG_FUNCTION_ARGS);
-
-Datum		gbtreekey_out(PG_FUNCTION_ARGS);
-
 #endif
diff --git a/contrib/dblink/dblink.h b/contrib/dblink/dblink.h
index 1b94912..1102236 100644
--- a/contrib/dblink/dblink.h
+++ b/contrib/dblink/dblink.h
@@ -36,28 +36,4 @@
 
 #include "fmgr.h"
 
-/*
- * External declarations
- */
-extern Datum dblink_connect(PG_FUNCTION_ARGS);
-extern Datum dblink_disconnect(PG_FUNCTION_ARGS);
-extern Datum dblink_open(PG_FUNCTION_ARGS);
-extern Datum dblink_close(PG_FUNCTION_ARGS);
-extern Datum dblink_fetch(PG_FUNCTION_ARGS);
-extern Datum dblink_record(PG_FUNCTION_ARGS);
-extern Datum dblink_send_query(PG_FUNCTION_ARGS);
-extern Datum dblink_get_result(PG_FUNCTION_ARGS);
-extern Datum dblink_get_connections(PG_FUNCTION_ARGS);
-extern Datum dblink_is_busy(PG_FUNCTION_ARGS);
-extern Datum dblink_cancel_query(PG_FUNCTION_ARGS);
-extern Datum dblink_error_message(PG_FUNCTION_ARGS);
-extern Datum dblink_exec(PG_FUNCTION_ARGS);
-extern Datum dblink_get_pkey(PG_FUNCTION_ARGS);
-extern Datum dblink_build_sql_insert(PG_FUNCTION_ARGS);
-extern Datum dblink_build_sql_delete(PG_FUNCTION_ARGS);
-extern Datum dblink_build_sql_update(PG_FUNCTION_ARGS);
-extern Datum dblink_current_query(PG_FUNCTION_ARGS);
-extern Datum dblink_get_notify(PG_FUNCTION_ARGS);
-extern Datum dblink_fdw_validator(PG_FUNCTION_ARGS);
-
 #endif   /* DBLINK_H */
diff --git a/contrib/isn/isn.h b/contrib/isn/isn.h
index d8291c2..e1a52b2 100644
--- a/contrib/isn/isn.h
+++ b/contrib/isn/isn.h
@@ -30,25 +30,6 @@ typedef uint64 ean13;
 #define PG_GETARG_EAN13(n) PG_GETARG_INT64(n)
 #define PG_RETURN_EAN13(x) PG_RETURN_INT64(x)
 
-extern Datum isn_out(PG_FUNCTION_ARGS);
-extern Datum ean13_out(PG_FUNCTION_ARGS);
-extern Datum ean13_in(PG_FUNCTION_ARGS);
-extern Datum isbn_in(PG_FUNCTION_ARGS);
-extern Datum ismn_in(PG_FUNCTION_ARGS);
-extern Datum issn_in(PG_FUNCTION_ARGS);
-extern Datum upc_in(PG_FUNCTION_ARGS);
-
-extern Datum isbn_cast_from_ean13(PG_FUNCTION_ARGS);
-extern Datum ismn_cast_from_ean13(PG_FUNCTION_ARGS);
-extern Datum issn_cast_from_ean13(PG_FUNCTION_ARGS);
-extern Datum upc_cast_from_ean13(PG_FUNCTION_ARGS);
-
-extern Datum is_valid(PG_FUNCTION_ARGS);
-extern Datum make_valid(PG_FUNCTION_ARGS);
-
-extern Datum accept_weak_input(PG_FUNCTION_ARGS);
-extern Datum weak_input_status(PG_FUNCTION_ARGS);
-
 extern void initialize(void);
 
 #endif   /* ISN_H */
diff --git a/contrib/pgcrypto/pgcrypto.h b/contrib/pgcrypto/pgcrypto.h
index dfc7a10..65a1ed3 100644
--- a/contrib/pgcrypto/pgcrypto.h
+++ b/contrib/pgcrypto/pgcrypto.h
@@ -34,17 +34,4 @@
 
 #include "fmgr.h"
 
-/* exported functions */
-Datum		pg_digest(PG_FUNCTION_ARGS);
-Datum		pg_hmac(PG_FUNCTION_ARGS);
-Datum		pg_gen_salt(PG_FUNCTION_ARGS);
-Datum		pg_gen_salt_rounds(PG_FUNCTION_ARGS);
-Datum		pg_crypt(PG_FUNCTION_ARGS);
-Datum		pg_encrypt(PG_FUNCTION_ARGS);
-Datum		pg_decrypt(PG_FUNCTION_ARGS);
-Datum		pg_encrypt_iv(PG_FUNCTION_ARGS);
-Datum		pg_decrypt_iv(PG_FUNCTION_ARGS);
-Datum		pg_random_bytes(PG_FUNCTION_ARGS);
-Datum		pg_random_uuid(PG_FUNCTION_ARGS);
-
 #endif
diff --git a/contrib/tablefunc/tablefunc.h b/contrib/tablefunc/tablefunc.h
index 3477ed8..34d44a8 100644
--- a/contrib/tablefunc/tablefunc.h
+++ b/contrib/tablefunc/tablefunc.h
@@ -36,13 +36,4 @@
 
 #include "fmgr.h"
 
-/*
- * External declarations
- */
-extern Datum normal_rand(PG_FUNCTION_ARGS);
-extern Datum crosstab(PG_FUNCTION_ARGS);
-extern Datum crosstab_hash(PG_FUNCTION_ARGS);
-extern Datum connectby_text(PG_FUNCTION_ARGS);
-extern Datum connectby_text_serial(PG_FUNCTION_ARGS);
-
 #endif   /* TABLEFUNC_H */
-- 
2.9.3

From be0494cefb5e4a34c57f491ff44829395374720d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 07/27] Fix incorrect type cast

---
 src/backend/access/gin/ginscan.c | 2 +-
 src/include/access/gin_private.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
index bfa86b5..77ca097 100644
--- a/src/backend/access/gin/ginscan.c
+++ b/src/backend/access/gin/ginscan.c
@@ -147,7 +147,7 @@ ginFillScanKey(GinScanOpaque so, OffsetNumber attnum,
 	key->nuserentries = nUserQueryValues;
 
 	key->scanEntry = (GinScanEntry *) palloc(sizeof(GinScanEntry) * nQueryValues);
-	key->entryRes = (bool *) palloc0(sizeof(bool) * nQueryValues);
+	key->entryRes = (GinTernaryValue *) palloc0(sizeof(GinTernaryValue) * nQueryValues);
 
 	key->query = query;
 	key->queryValues = queryValues;
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index 68cfe0c..fa6ddad 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -788,7 +788,7 @@ typedef struct GinScanKeyData
 	int			nadditional;
 
 	/* array of check flags, reported to consistentFn */
-	bool	   *entryRes;
+	GinTernaryValue *entryRes;
 	bool		(*boolConsistentFn) (GinScanKey key);
 	GinTernaryValue (*triConsistentFn) (GinScanKey key);
 	FmgrInfo   *consistentFmgrInfo;
-- 
2.9.3

From fc1fc82238496f527e870df489694f2c8e7844bb Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 08/27] Add necessary type cast

---
 src/backend/utils/adt/tsginidx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/utils/adt/tsginidx.c b/src/backend/utils/adt/tsginidx.c
index c953f53..d4945b0 100644
--- a/src/backend/utils/adt/tsginidx.c
+++ b/src/backend/utils/adt/tsginidx.c
@@ -302,7 +302,7 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS)
 		 * query.
 		 */
 		gcv.first_item = item = GETQUERY(query);
-		gcv.check = check;
+		gcv.check = (GinTernaryValue *) check;
 		gcv.map_item_operand = (int *) (extra_data[0]);
 		gcv.need_recheck = recheck;
 
-- 
2.9.3

From 34a45d8172fb36790523b90a6d7ee238d4adbf8b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 09/27] Rename some typedefs to avoid name conflicts

C++ does not like that in struct _archiveHandle some of the fields have
the same name as a typedef.  This changes the meaning of the typedef in
the scope of the struct, causing warnings and possibly other problems.

Rename the types so they have names distinct from the struct fields.
---
 src/bin/pg_dump/pg_backup.h          |   4 +-
 src/bin/pg_dump/pg_backup_archiver.c |  10 +--
 src/bin/pg_dump/pg_backup_archiver.h | 114 +++++++++++++++++------------------
 3 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 4afa92f..dac8383 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -221,7 +221,7 @@ typedef int DumpId;
 
 typedef int (*DataDumperPtr) (Archive *AH, void *userArg);
 
-typedef void (*SetupWorkerPtr) (Archive *AH);
+typedef void (*SetupWorkerPtrType) (Archive *AH);
 
 /*
  * Main archiver interface.
@@ -268,7 +268,7 @@ extern Archive *OpenArchive(const char *FileSpec, const ArchiveFormat fmt);
 /* Create a new archive */
 extern Archive *CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
 			  const int compression, ArchiveMode mode,
-			  SetupWorkerPtr setupDumpWorker);
+			  SetupWorkerPtrType setupDumpWorker);
 
 /* The --list option */
 extern void PrintTOCSummary(Archive *AH);
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 05bdbdb..5a0c1fb 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -56,7 +56,7 @@ static const char *modulename = gettext_noop("archiver");
 
 
 static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
-	 const int compression, ArchiveMode mode, SetupWorkerPtr setupWorkerPtr);
+	 const int compression, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr);
 static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
 					  ArchiveHandle *AH);
 static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData, bool acl_pass);
@@ -197,7 +197,7 @@ setupRestoreWorker(Archive *AHX)
 /* Public */
 Archive *
 CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
-	 const int compression, ArchiveMode mode, SetupWorkerPtr setupDumpWorker)
+	 const int compression, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker)
 
 {
 	ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, mode, setupDumpWorker);
@@ -2217,7 +2217,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
  */
 static ArchiveHandle *
 _allocAH(const char *FileSpec, const ArchiveFormat fmt,
-	  const int compression, ArchiveMode mode, SetupWorkerPtr setupWorkerPtr)
+	  const int compression, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
 {
 	ArchiveHandle *AH;
 
@@ -2371,8 +2371,8 @@ WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
 void
 WriteDataChunksForTocEntry(ArchiveHandle *AH, TocEntry *te)
 {
-	StartDataPtr startPtr;
-	EndDataPtr	endPtr;
+	StartDataPtrType startPtr;
+	EndDataPtrType	endPtr;
 
 	AH->currToc = te;
 
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 0376f2b..b33793f 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -136,40 +136,40 @@ typedef enum T_Action
 	ACT_RESTORE
 } T_Action;
 
-typedef void (*ClosePtr) (ArchiveHandle *AH);
-typedef void (*ReopenPtr) (ArchiveHandle *AH);
-typedef void (*ArchiveEntryPtr) (ArchiveHandle *AH, TocEntry *te);
-
-typedef void (*StartDataPtr) (ArchiveHandle *AH, TocEntry *te);
-typedef void (*WriteDataPtr) (ArchiveHandle *AH, const void *data, size_t dLen);
-typedef void (*EndDataPtr) (ArchiveHandle *AH, TocEntry *te);
-
-typedef void (*StartBlobsPtr) (ArchiveHandle *AH, TocEntry *te);
-typedef void (*StartBlobPtr) (ArchiveHandle *AH, TocEntry *te, Oid oid);
-typedef void (*EndBlobPtr) (ArchiveHandle *AH, TocEntry *te, Oid oid);
-typedef void (*EndBlobsPtr) (ArchiveHandle *AH, TocEntry *te);
-
-typedef int (*WriteBytePtr) (ArchiveHandle *AH, const int i);
-typedef int (*ReadBytePtr) (ArchiveHandle *AH);
-typedef void (*WriteBufPtr) (ArchiveHandle *AH, const void *c, size_t len);
-typedef void (*ReadBufPtr) (ArchiveHandle *AH, void *buf, size_t len);
-typedef void (*SaveArchivePtr) (ArchiveHandle *AH);
-typedef void (*WriteExtraTocPtr) (ArchiveHandle *AH, TocEntry *te);
-typedef void (*ReadExtraTocPtr) (ArchiveHandle *AH, TocEntry *te);
-typedef void (*PrintExtraTocPtr) (ArchiveHandle *AH, TocEntry *te);
-typedef void (*PrintTocDataPtr) (ArchiveHandle *AH, TocEntry *te);
-
-typedef void (*ClonePtr) (ArchiveHandle *AH);
-typedef void (*DeClonePtr) (ArchiveHandle *AH);
-
-typedef char *(*WorkerJobRestorePtr) (ArchiveHandle *AH, TocEntry *te);
-typedef char *(*WorkerJobDumpPtr) (ArchiveHandle *AH, TocEntry *te);
-typedef char *(*MasterStartParallelItemPtr) (ArchiveHandle *AH, TocEntry *te,
+typedef void (*ClosePtrType) (ArchiveHandle *AH);
+typedef void (*ReopenPtrType) (ArchiveHandle *AH);
+typedef void (*ArchiveEntryPtrType) (ArchiveHandle *AH, TocEntry *te);
+
+typedef void (*StartDataPtrType) (ArchiveHandle *AH, TocEntry *te);
+typedef void (*WriteDataPtrType) (ArchiveHandle *AH, const void *data, size_t dLen);
+typedef void (*EndDataPtrType) (ArchiveHandle *AH, TocEntry *te);
+
+typedef void (*StartBlobsPtrType) (ArchiveHandle *AH, TocEntry *te);
+typedef void (*StartBlobPtrType) (ArchiveHandle *AH, TocEntry *te, Oid oid);
+typedef void (*EndBlobPtrType) (ArchiveHandle *AH, TocEntry *te, Oid oid);
+typedef void (*EndBlobsPtrType) (ArchiveHandle *AH, TocEntry *te);
+
+typedef int (*WriteBytePtrType) (ArchiveHandle *AH, const int i);
+typedef int (*ReadBytePtrType) (ArchiveHandle *AH);
+typedef void (*WriteBufPtrType) (ArchiveHandle *AH, const void *c, size_t len);
+typedef void (*ReadBufPtrType) (ArchiveHandle *AH, void *buf, size_t len);
+typedef void (*SaveArchivePtrType) (ArchiveHandle *AH);
+typedef void (*WriteExtraTocPtrType) (ArchiveHandle *AH, TocEntry *te);
+typedef void (*ReadExtraTocPtrType) (ArchiveHandle *AH, TocEntry *te);
+typedef void (*PrintExtraTocPtrType) (ArchiveHandle *AH, TocEntry *te);
+typedef void (*PrintTocDataPtrType) (ArchiveHandle *AH, TocEntry *te);
+
+typedef void (*ClonePtrType) (ArchiveHandle *AH);
+typedef void (*DeClonePtrType) (ArchiveHandle *AH);
+
+typedef char *(*WorkerJobRestorePtrType) (ArchiveHandle *AH, TocEntry *te);
+typedef char *(*WorkerJobDumpPtrType) (ArchiveHandle *AH, TocEntry *te);
+typedef char *(*MasterStartParallelItemPtrType) (ArchiveHandle *AH, TocEntry *te,
 														 T_Action act);
-typedef int (*MasterEndParallelItemPtr) (ArchiveHandle *AH, TocEntry *te,
+typedef int (*MasterEndParallelItemPtrType) (ArchiveHandle *AH, TocEntry *te,
 											  const char *str, T_Action act);
 
-typedef size_t (*CustomOutPtr) (ArchiveHandle *AH, const void *buf, size_t len);
+typedef size_t (*CustomOutPtrType) (ArchiveHandle *AH, const void *buf, size_t len);
 
 typedef enum
 {
@@ -242,42 +242,42 @@ struct _archiveHandle
 	size_t		lookaheadLen;	/* Length of data in lookahead */
 	pgoff_t		lookaheadPos;	/* Current read position in lookahead buffer */
 
-	ArchiveEntryPtr ArchiveEntryPtr;	/* Called for each metadata object */
-	StartDataPtr StartDataPtr;	/* Called when table data is about to be
+	ArchiveEntryPtrType ArchiveEntryPtr;	/* Called for each metadata object */
+	StartDataPtrType StartDataPtr;	/* Called when table data is about to be
 								 * dumped */
-	WriteDataPtr WriteDataPtr;	/* Called to send some table data to the
+	WriteDataPtrType WriteDataPtr;	/* Called to send some table data to the
 								 * archive */
-	EndDataPtr EndDataPtr;		/* Called when table data dump is finished */
-	WriteBytePtr WriteBytePtr;	/* Write a byte to output */
-	ReadBytePtr ReadBytePtr;	/* Read a byte from an archive */
-	WriteBufPtr WriteBufPtr;	/* Write a buffer of output to the archive */
-	ReadBufPtr ReadBufPtr;		/* Read a buffer of input from the archive */
-	ClosePtr ClosePtr;			/* Close the archive */
-	ReopenPtr ReopenPtr;		/* Reopen the archive */
-	WriteExtraTocPtr WriteExtraTocPtr;	/* Write extra TOC entry data
+	EndDataPtrType EndDataPtr;		/* Called when table data dump is finished */
+	WriteBytePtrType WriteBytePtr;	/* Write a byte to output */
+	ReadBytePtrType ReadBytePtr;	/* Read a byte from an archive */
+	WriteBufPtrType WriteBufPtr;	/* Write a buffer of output to the archive */
+	ReadBufPtrType ReadBufPtr;		/* Read a buffer of input from the archive */
+	ClosePtrType ClosePtr;			/* Close the archive */
+	ReopenPtrType ReopenPtr;		/* Reopen the archive */
+	WriteExtraTocPtrType WriteExtraTocPtr;	/* Write extra TOC entry data
 										 * associated with the current archive
 										 * format */
-	ReadExtraTocPtr ReadExtraTocPtr;	/* Read extr info associated with
+	ReadExtraTocPtrType ReadExtraTocPtr;	/* Read extr info associated with
 										 * archie format */
-	PrintExtraTocPtr PrintExtraTocPtr;	/* Extra TOC info for format */
-	PrintTocDataPtr PrintTocDataPtr;
+	PrintExtraTocPtrType PrintExtraTocPtr;	/* Extra TOC info for format */
+	PrintTocDataPtrType PrintTocDataPtr;
 
-	StartBlobsPtr StartBlobsPtr;
-	EndBlobsPtr EndBlobsPtr;
-	StartBlobPtr StartBlobPtr;
-	EndBlobPtr EndBlobPtr;
+	StartBlobsPtrType StartBlobsPtr;
+	EndBlobsPtrType EndBlobsPtr;
+	StartBlobPtrType StartBlobPtr;
+	EndBlobPtrType EndBlobPtr;
 
-	MasterStartParallelItemPtr MasterStartParallelItemPtr;
-	MasterEndParallelItemPtr MasterEndParallelItemPtr;
+	MasterStartParallelItemPtrType MasterStartParallelItemPtr;
+	MasterEndParallelItemPtrType MasterEndParallelItemPtr;
 
-	SetupWorkerPtr SetupWorkerPtr;
-	WorkerJobDumpPtr WorkerJobDumpPtr;
-	WorkerJobRestorePtr WorkerJobRestorePtr;
+	SetupWorkerPtrType SetupWorkerPtr;
+	WorkerJobDumpPtrType WorkerJobDumpPtr;
+	WorkerJobRestorePtrType WorkerJobRestorePtr;
 
-	ClonePtr ClonePtr;			/* Clone format-specific fields */
-	DeClonePtr DeClonePtr;		/* Clean up cloned fields */
+	ClonePtrType ClonePtr;			/* Clone format-specific fields */
+	DeClonePtrType DeClonePtr;		/* Clean up cloned fields */
 
-	CustomOutPtr CustomOutPtr;	/* Alternative script output routine */
+	CustomOutPtrType CustomOutPtr;	/* Alternative script output routine */
 
 	/* Stuff for direct DB connection */
 	char	   *archdbname;		/* DB name *read* from archive */
-- 
2.9.3

From c8363af9978e978cb860e0410fe31a39d49a7366 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 10/27] Reorder some things

Forward declarations of static variables are not possible in C++, so
move the full definition before its use.
---
 src/port/pg_crc32c_sb8.c | 136 +++++++++++++++++++++++------------------------
 1 file changed, 67 insertions(+), 69 deletions(-)

diff --git a/src/port/pg_crc32c_sb8.c b/src/port/pg_crc32c_sb8.c
index 2680e36..c7e03e9 100644
--- a/src/port/pg_crc32c_sb8.c
+++ b/src/port/pg_crc32c_sb8.c
@@ -22,8 +22,6 @@
 
 #include "port/pg_crc32c.h"
 
-static const uint32 pg_crc32c_table[8][256];
-
 /* Accumulate one input byte */
 #ifdef WORDS_BIGENDIAN
 #define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
@@ -31,73 +29,6 @@ static const uint32 pg_crc32c_table[8][256];
 #define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
 #endif
 
-pg_crc32c
-pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len)
-{
-	const unsigned char *p = data;
-	const uint32 *p4;
-
-	/*
-	 * Handle 0-3 initial bytes one at a time, so that the loop below starts
-	 * with a pointer aligned to four bytes.
-	 */
-	while (len > 0 && ((uintptr_t) p & 3))
-	{
-		crc = CRC8(*p++);
-		len--;
-	}
-
-	/*
-	 * Process eight bytes of data at a time.
-	 */
-	p4 = (const uint32 *) p;
-	while (len >= 8)
-	{
-		uint32		a = *p4++ ^ crc;
-		uint32		b = *p4++;
-
-#ifdef WORDS_BIGENDIAN
-		const uint8 c0 = b;
-		const uint8 c1 = b >> 8;
-		const uint8 c2 = b >> 16;
-		const uint8 c3 = b >> 24;
-		const uint8 c4 = a;
-		const uint8 c5 = a >> 8;
-		const uint8 c6 = a >> 16;
-		const uint8 c7 = a >> 24;
-#else
-		const uint8 c0 = b >> 24;
-		const uint8 c1 = b >> 16;
-		const uint8 c2 = b >> 8;
-		const uint8 c3 = b;
-		const uint8 c4 = a >> 24;
-		const uint8 c5 = a >> 16;
-		const uint8 c6 = a >> 8;
-		const uint8 c7 = a;
-#endif
-
-		crc =
-			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
-			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
-			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
-			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
-
-		len -= 8;
-	}
-
-	/*
-	 * Handle any remaining bytes one at a time.
-	 */
-	p = (const unsigned char *) p4;
-	while (len > 0)
-	{
-		crc = CRC8(*p++);
-		len--;
-	}
-
-	return crc;
-}
-
 /*
  * Lookup tables for the slicing-by-8 algorithm, for the so-called Castagnoli
  * polynomial (the same that is used e.g. in iSCSI), 0x1EDC6F41. Using
@@ -1167,3 +1098,70 @@ static const uint32 pg_crc32c_table[8][256] = {
 	}
 #endif   /* WORDS_BIGENDIAN */
 };
+
+pg_crc32c
+pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p4;
+
+	/*
+	 * Handle 0-3 initial bytes one at a time, so that the loop below starts
+	 * with a pointer aligned to four bytes.
+	 */
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+	p4 = (const uint32 *) p;
+	while (len >= 8)
+	{
+		uint32		a = *p4++ ^ crc;
+		uint32		b = *p4++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+	p = (const unsigned char *) p4;
+	while (len > 0)
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	return crc;
+}
-- 
2.9.3

From d37cbfa16ce3676fc0dc5436a135953b963a4caa Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 11/27] Add missing fields in struct initializations

---
 src/bin/psql/tab-complete.c | 64 ++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 1345e4e..c5e5dbc 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -884,54 +884,54 @@ typedef struct
 #define THING_NO_SHOW		(THING_NO_CREATE | THING_NO_DROP)
 
 static const pgsql_thing_t words_after_create[] = {
-	{"ACCESS METHOD", NULL, NULL},
-	{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
-	{"CAST", NULL, NULL},		/* Casts have complex structures for names, so
+	{"ACCESS METHOD", NULL, NULL, 0},
+	{"AGGREGATE", NULL, &Query_for_list_of_aggregates, 0},
+	{"CAST", NULL, NULL, 0},	/* Casts have complex structures for names, so
 								 * skip it */
-	{"COLLATION", "SELECT pg_catalog.quote_ident(collname) FROM pg_catalog.pg_collation WHERE collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding())) AND substring(pg_catalog.quote_ident(collname),1,%d)='%s'"},
+	{"COLLATION", "SELECT pg_catalog.quote_ident(collname) FROM pg_catalog.pg_collation WHERE collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding())) AND substring(pg_catalog.quote_ident(collname),1,%d)='%s'", NULL, 0},
 
 	/*
 	 * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
 	 * to be used only by pg_dump.
 	 */
 	{"CONFIGURATION", Query_for_list_of_ts_configurations, NULL, THING_NO_SHOW},
-	{"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"},
-	{"DATABASE", Query_for_list_of_databases},
+	{"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'", NULL, 0},
+	{"DATABASE", Query_for_list_of_databases, NULL, 0},
 	{"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, THING_NO_SHOW},
-	{"DOMAIN", NULL, &Query_for_list_of_domains},
-	{"EVENT TRIGGER", NULL, NULL},
-	{"EXTENSION", Query_for_list_of_extensions},
-	{"FOREIGN DATA WRAPPER", NULL, NULL},
-	{"FOREIGN TABLE", NULL, NULL},
-	{"FUNCTION", NULL, &Query_for_list_of_functions},
-	{"GROUP", Query_for_list_of_roles},
-	{"LANGUAGE", Query_for_list_of_languages},
-	{"INDEX", NULL, &Query_for_list_of_indexes},
-	{"MATERIALIZED VIEW", NULL, &Query_for_list_of_matviews},
-	{"OPERATOR", NULL, NULL},	/* Querying for this is probably not such a
+	{"DOMAIN", NULL, &Query_for_list_of_domains, 0},
+	{"EVENT TRIGGER", NULL, NULL, 0},
+	{"EXTENSION", Query_for_list_of_extensions, NULL, 0},
+	{"FOREIGN DATA WRAPPER", NULL, NULL, 0},
+	{"FOREIGN TABLE", NULL, NULL, 0},
+	{"FUNCTION", NULL, &Query_for_list_of_functions, 0},
+	{"GROUP", Query_for_list_of_roles, NULL, 0},
+	{"LANGUAGE", Query_for_list_of_languages, NULL, 0},
+	{"INDEX", NULL, &Query_for_list_of_indexes, 0},
+	{"MATERIALIZED VIEW", NULL, &Query_for_list_of_matviews, 0},
+	{"OPERATOR", NULL, NULL, 0},/* Querying for this is probably not such a
 								 * good idea. */
 	{"OWNED", NULL, NULL, THING_NO_CREATE},		/* for DROP OWNED BY ... */
 	{"PARSER", Query_for_list_of_ts_parsers, NULL, THING_NO_SHOW},
-	{"POLICY", NULL, NULL},
-	{"ROLE", Query_for_list_of_roles},
-	{"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
-	{"SCHEMA", Query_for_list_of_schemas},
-	{"SEQUENCE", NULL, &Query_for_list_of_sequences},
-	{"SERVER", Query_for_list_of_servers},
-	{"TABLE", NULL, &Query_for_list_of_tables},
-	{"TABLESPACE", Query_for_list_of_tablespaces},
+	{"POLICY", NULL, NULL, 0},
+	{"ROLE", Query_for_list_of_roles, NULL, 0},
+	{"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'", NULL, 0},
+	{"SCHEMA", Query_for_list_of_schemas, NULL, 0},
+	{"SEQUENCE", NULL, &Query_for_list_of_sequences, 0},
+	{"SERVER", Query_for_list_of_servers, NULL, 0},
+	{"TABLE", NULL, &Query_for_list_of_tables, 0},
+	{"TABLESPACE", Query_for_list_of_tablespaces, NULL, 0},
 	{"TEMP", NULL, NULL, THING_NO_DROP},		/* for CREATE TEMP TABLE ... */
 	{"TEMPLATE", Query_for_list_of_ts_templates, NULL, THING_NO_SHOW},
-	{"TEXT SEARCH", NULL, NULL},
-	{"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s' AND NOT tgisinternal"},
-	{"TYPE", NULL, &Query_for_list_of_datatypes},
+	{"TEXT SEARCH", NULL, NULL, 0},
+	{"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s' AND NOT tgisinternal", NULL, 0},
+	{"TYPE", NULL, &Query_for_list_of_datatypes, 0},
 	{"UNIQUE", NULL, NULL, THING_NO_DROP},		/* for CREATE UNIQUE INDEX ... */
 	{"UNLOGGED", NULL, NULL, THING_NO_DROP},	/* for CREATE UNLOGGED TABLE
 												 * ... */
-	{"USER", Query_for_list_of_roles},
-	{"USER MAPPING FOR", NULL, NULL},
-	{"VIEW", NULL, &Query_for_list_of_views},
-	{NULL}						/* end of list */
+	{"USER", Query_for_list_of_roles, NULL, 0},
+	{"USER MAPPING FOR", NULL, NULL, 0},
+	{"VIEW", NULL, &Query_for_list_of_views, 0},
+	{NULL, NULL, NULL, 0}						/* end of list */
 };
 
 
-- 
2.9.3

From 9dfb2949af5c764bcf553ded32c827dbb9b5eba6 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 12/27] Separate enum from struct

Otherwise the enum symbols are not visible outside the struct in C++.
---
 src/include/utils/jsonb.h | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h
index fa52afc..48ca9dc 100644
--- a/src/include/utils/jsonb.h
+++ b/src/include/utils/jsonb.h
@@ -219,6 +219,20 @@ typedef struct
 #define JB_ROOT_IS_ARRAY(jbp_)	( *(uint32*) VARDATA(jbp_) & JB_FARRAY)
 
 
+enum jbvType
+{
+	/* Scalar types */
+	jbvNull = 0x0,
+	jbvString,
+	jbvNumeric,
+	jbvBool,
+	/* Composite types */
+	jbvArray = 0x10,
+	jbvObject,
+	/* Binary (i.e. struct Jsonb) jbvArray/jbvObject */
+	jbvBinary
+};
+
 /*
  * JsonbValue:	In-memory representation of Jsonb.  This is a convenient
  * deserialized representation, that can easily support using the "val"
@@ -227,19 +241,7 @@ typedef struct
  */
 struct JsonbValue
 {
-	enum
-	{
-		/* Scalar types */
-		jbvNull = 0x0,
-		jbvString,
-		jbvNumeric,
-		jbvBool,
-		/* Composite types */
-		jbvArray = 0x10,
-		jbvObject,
-		/* Binary (i.e. struct Jsonb) jbvArray/jbvObject */
-		jbvBinary
-	}			type;			/* Influences sort order */
+	jbvType		type;			/* Influences sort order */
 
 	union
 	{
-- 
2.9.3

From 5f83d64832d71fe271b8f27898b33e83c8cee4b8 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 13/27] Avoid C++ key words

This is not a long-term solution, because C header files that are
included somewhere might have C++ awareness and will break if the key
word is defined away.  But this shows the list of words that would have
to be renamed around the code.
---
 src/include/c.h                                  | 16 ++++++++++++++++
 src/interfaces/ecpg/include/ecpg-pthread-win32.h |  2 ++
 src/interfaces/libpq/libpq-int.h                 |  2 ++
 src/pl/plperl/plperl.h                           |  2 ++
 4 files changed, 22 insertions(+)

diff --git a/src/include/c.h b/src/include/c.h
index 4ab3f80..a9515d1 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -45,6 +45,22 @@
 #ifndef C_H
 #define C_H
 
+#ifdef __cplusplus
+#define class class_
+#define constexpr constexpr_
+#define delete delete_
+#define friend friend_
+#define namespace namespace_
+#define new new_
+#define operator operator_
+#define private private_
+#define public public_
+#define template template_
+#define this this_
+#define typeid typeid_
+#define typename typename_
+#endif
+
 #include "postgres_ext.h"
 
 /* Must undef pg_config_ext.h symbols before including pg_config.h */
diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
index 7e59357..505838f 100644
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
@@ -9,6 +9,8 @@
 
 #ifndef WIN32
 
+#undef class
+#undef public
 #include <pthread.h>
 #else
 
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index a94ead0..b2f2d74 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -34,6 +34,8 @@
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
+#undef class
+#undef public
 #include <pthread.h>
 #endif
 #include <signal.h>
diff --git a/src/pl/plperl/plperl.h b/src/pl/plperl/plperl.h
index 0146d60..1ed68a4 100644
--- a/src/pl/plperl/plperl.h
+++ b/src/pl/plperl/plperl.h
@@ -43,6 +43,8 @@
 #endif
 
 
+#undef class
+#undef public
 /* required for perl API */
 #include "EXTERN.h"
 #include "perl.h"
-- 
2.9.3

From dc0be2c9b096545d7f95bf44336a9e92715c629c Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 14/27] Set up for static asserts in C++

This doesn't appear to work yet.  It might need a really new compiler.
---
 src/include/c.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/include/c.h b/src/include/c.h
index a9515d1..cbefc47 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -756,14 +756,26 @@ typedef NameData *Name;
  * about a negative width for a struct bit-field.  This will not include a
  * helpful error message, but it beats not getting an error at all.
  */
+#ifdef __cplusplus
+#if __cpp_static_assert >= 201411
+#define _Static_assert(condition, errmessage) static_assert(condition, errmessage)
+#define HAVE__STATIC_ASSERT 1
+#endif
+#endif
+
 #ifdef HAVE__STATIC_ASSERT
 #define StaticAssertStmt(condition, errmessage) \
 	do { _Static_assert(condition, errmessage); } while(0)
 #define StaticAssertExpr(condition, errmessage) \
 	({ StaticAssertStmt(condition, errmessage); true; })
 #else							/* !HAVE__STATIC_ASSERT */
+#ifdef __cplusplus
+#define  StaticAssertStmt(condition, errmessage) \
+	((void) 0)
+#else
 #define StaticAssertStmt(condition, errmessage) \
 	((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
+#endif
 #define StaticAssertExpr(condition, errmessage) \
 	StaticAssertStmt(condition, errmessage)
 #endif   /* HAVE__STATIC_ASSERT */
-- 
2.9.3

From b8eb3e6c31d50f1e2d14e0f4996cc58debdc6aac Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 15/27] Fix function prototypes for C++

C++ needs to have the right number of arguments in function signatures.
---
 src/backend/nodes/nodeFuncs.c | 28 ++++++++++++++--------------
 src/include/nodes/nodeFuncs.h | 20 ++++++++++----------
 2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 3997441..311b86d 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -28,10 +28,10 @@
 static bool expression_returns_set_walker(Node *node, void *context);
 static int	leftmostLoc(int loc1, int loc2);
 static bool fix_opfuncids_walker(Node *node, void *context);
-static bool planstate_walk_subplans(List *plans, bool (*walker) (),
+static bool planstate_walk_subplans(List *plans, bool (*walker) (void *, void *),
 												void *context);
 static bool planstate_walk_members(List *plans, PlanState **planstates,
-					   bool (*walker) (), void *context);
+								   bool (*walker) (void *, void *), void *context);
 
 
 /*
@@ -1849,7 +1849,7 @@ check_functions_in_node(Node *node, check_function_callback checker,
 
 bool
 expression_tree_walker(Node *node,
-					   bool (*walker) (),
+					   bool (*walker) (void *, void *),
 					   void *context)
 {
 	ListCell   *temp;
@@ -2236,7 +2236,7 @@ expression_tree_walker(Node *node,
  */
 bool
 query_tree_walker(Query *query,
-				  bool (*walker) (),
+				  bool (*walker) (void *, void *),
 				  void *context,
 				  int flags)
 {
@@ -2280,7 +2280,7 @@ query_tree_walker(Query *query,
  */
 bool
 range_table_walker(List *rtable,
-				   bool (*walker) (),
+				   bool (*walker) (void *, void *),
 				   void *context,
 				   int flags)
 {
@@ -2395,7 +2395,7 @@ range_table_walker(List *rtable,
 
 Node *
 expression_tree_mutator(Node *node,
-						Node *(*mutator) (),
+						Node *(*mutator) (void *, void *),
 						void *context)
 {
 	/*
@@ -3038,7 +3038,7 @@ expression_tree_mutator(Node *node,
  */
 Query *
 query_tree_mutator(Query *query,
-				   Node *(*mutator) (),
+				   Node *(*mutator) (void *, void *),
 				   void *context,
 				   int flags)
 {
@@ -3077,7 +3077,7 @@ query_tree_mutator(Query *query,
  */
 List *
 range_table_mutator(List *rtable,
-					Node *(*mutator) (),
+					Node *(*mutator) (void *, void *),
 					void *context,
 					int flags)
 {
@@ -3144,7 +3144,7 @@ range_table_mutator(List *rtable,
  */
 bool
 query_or_expression_tree_walker(Node *node,
-								bool (*walker) (),
+								bool (*walker) (void *, void *),
 								void *context,
 								int flags)
 {
@@ -3167,7 +3167,7 @@ query_or_expression_tree_walker(Node *node,
  */
 Node *
 query_or_expression_tree_mutator(Node *node,
-								 Node *(*mutator) (),
+								 Node *(*mutator) (void *, void *),
 								 void *context,
 								 int flags)
 {
@@ -3198,7 +3198,7 @@ query_or_expression_tree_mutator(Node *node,
  */
 bool
 raw_expression_tree_walker(Node *node,
-						   bool (*walker) (),
+						   bool (*walker) (void *, void *),
 						   void *context)
 {
 	ListCell   *temp;
@@ -3638,7 +3638,7 @@ raw_expression_tree_walker(Node *node,
  */
 bool
 planstate_tree_walker(PlanState *planstate,
-					  bool (*walker) (),
+					  bool (*walker) (void *, void *),
 					  void *context)
 {
 	Plan	   *plan = planstate->plan;
@@ -3722,7 +3722,7 @@ planstate_tree_walker(PlanState *planstate,
  */
 static bool
 planstate_walk_subplans(List *plans,
-						bool (*walker) (),
+						bool (*walker) (void *, void *),
 						void *context)
 {
 	ListCell   *lc;
@@ -3748,7 +3748,7 @@ planstate_walk_subplans(List *plans,
  */
 static bool
 planstate_walk_members(List *plans, PlanState **planstates,
-					   bool (*walker) (), void *context)
+					   bool (*walker) (void *, void *), void *context)
 {
 	int			nplans = list_length(plans);
 	int			j;
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index 97af142..82add17 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -50,31 +50,31 @@ extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
 extern bool check_functions_in_node(Node *node, check_function_callback checker,
 						void *context);
 
-extern bool expression_tree_walker(Node *node, bool (*walker) (),
+extern bool expression_tree_walker(Node *node, bool (*walker) (void *, void *),
 											   void *context);
-extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (),
+extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (void *, void *),
 												 void *context);
 
-extern bool query_tree_walker(Query *query, bool (*walker) (),
+extern bool query_tree_walker(Query *query, bool (*walker) (void *, void *),
 										  void *context, int flags);
-extern Query *query_tree_mutator(Query *query, Node *(*mutator) (),
+extern Query *query_tree_mutator(Query *query, Node *(*mutator) (void *, void *),
 											 void *context, int flags);
 
-extern bool range_table_walker(List *rtable, bool (*walker) (),
+extern bool range_table_walker(List *rtable, bool (*walker) (void *, void *),
 										   void *context, int flags);
-extern List *range_table_mutator(List *rtable, Node *(*mutator) (),
+extern List *range_table_mutator(List *rtable, Node *(*mutator) (void *, void *),
 											 void *context, int flags);
 
-extern bool query_or_expression_tree_walker(Node *node, bool (*walker) (),
+extern bool query_or_expression_tree_walker(Node *node, bool (*walker) (void *, void *),
 												   void *context, int flags);
-extern Node *query_or_expression_tree_mutator(Node *node, Node *(*mutator) (),
+extern Node *query_or_expression_tree_mutator(Node *node, Node *(*mutator) (void *, void *),
 												   void *context, int flags);
 
-extern bool raw_expression_tree_walker(Node *node, bool (*walker) (),
+extern bool raw_expression_tree_walker(Node *node, bool (*walker) (void *, void *),
 												   void *context);
 
 struct PlanState;
-extern bool planstate_tree_walker(struct PlanState *planstate, bool (*walker) (),
+extern bool planstate_tree_walker(struct PlanState *planstate, bool (*walker) (void *, void *),
 											  void *context);
 
 #endif   /* NODEFUNCS_H */
-- 
2.9.3

From 4cbdafcc7a7979b9eeea1ce0def9f528e6125d49 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 16/27] Fix fmgr_oldstyle for C++

C++ needs the function pointer to have the right number of arguments, so
some casts are needed here.
---
 src/backend/utils/fmgr/fmgr.c | 56 ++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 7e6a60d..1da553b 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -53,11 +53,29 @@ PGDLLIMPORT fmgr_hook_type fmgr_hook = NULL;
  * with suitably ugly casts in fmgr_oldstyle().
  */
 #if (defined(__mc68000__) || (defined(__m68k__))) && defined(__ELF__)
-typedef int32 (*func_ptr) ();
+#define func_ptr_ret int32
 #else
-typedef char *(*func_ptr) ();
+#define func_ptr_ret char*
 #endif
 
+typedef func_ptr_ret (*func_ptr) ();
+typedef func_ptr_ret (*func1_ptr) (Datum, bool);
+typedef func_ptr_ret (*func2_ptr) (Datum, Datum);
+typedef func_ptr_ret (*func3_ptr) (Datum, Datum, Datum);
+typedef func_ptr_ret (*func4_ptr) (Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func5_ptr) (Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func6_ptr) (Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func7_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func8_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func9_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func10_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func11_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func12_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func13_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func14_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func15_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+typedef func_ptr_ret (*func16_ptr) (Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum, Datum);
+
 /*
  * For an oldstyle function, fn_extra points to a record like this:
  */
@@ -658,7 +676,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 	switch (n_arguments)
 	{
 		case 0:
-			returnValue = (char *) (*user_fn) ();
+			returnValue = (char *) (user_fn) ();
 			break;
 		case 1:
 
@@ -667,33 +685,33 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 			 * there are other functions still out there that also rely on
 			 * this undocumented hack?
 			 */
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func1_ptr) user_fn) (fcinfo->arg[0],
 											   &fcinfo->isnull);
 			break;
 		case 2:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func2_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1]);
 			break;
 		case 3:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func3_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2]);
 			break;
 		case 4:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func4_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3]);
 			break;
 		case 5:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func5_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
 											   fcinfo->arg[4]);
 			break;
 		case 6:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func6_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -701,7 +719,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[5]);
 			break;
 		case 7:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func7_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -710,7 +728,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[6]);
 			break;
 		case 8:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func8_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -720,7 +738,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[7]);
 			break;
 		case 9:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func9_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -731,7 +749,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[8]);
 			break;
 		case 10:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func10_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -743,7 +761,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[9]);
 			break;
 		case 11:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func11_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -756,7 +774,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[10]);
 			break;
 		case 12:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func12_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -770,7 +788,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[11]);
 			break;
 		case 13:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func13_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -785,7 +803,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[12]);
 			break;
 		case 14:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func14_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -801,7 +819,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[13]);
 			break;
 		case 15:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func15_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
@@ -818,7 +836,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
 											   fcinfo->arg[14]);
 			break;
 		case 16:
-			returnValue = (char *) (*user_fn) (fcinfo->arg[0],
+			returnValue = (char *) ((func16_ptr) user_fn) (fcinfo->arg[0],
 											   fcinfo->arg[1],
 											   fcinfo->arg[2],
 											   fcinfo->arg[3],
-- 
2.9.3

From f75db7835d76456a4152aa12a8878c8f5ba47662 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 17/27] Don't define bool in C++

---
 src/test/thread/thread_test.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/test/thread/thread_test.c b/src/test/thread/thread_test.c
index 26d1949..d7cf5ef 100644
--- a/src/test/thread/thread_test.c
+++ b/src/test/thread/thread_test.c
@@ -24,6 +24,8 @@
 #include "postgres.h"
 #else
 /* From src/include/c.h" */
+#ifndef __cplusplus
+
 #ifndef bool
 typedef char bool;
 #endif
@@ -37,6 +39,8 @@ typedef char bool;
 #endif
 #endif
 
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-- 
2.9.3

From de2fa8c6ecd92449c893db07dc3458a713c2269d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 18/27] Change TimeoutId from enum to integer

RegisterTimeout() treats it like an integer.  C++ doesn't like enums to
be treated that way.
---
 src/include/utils/timeout.h | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/include/utils/timeout.h b/src/include/utils/timeout.h
index 260c013..15a0f09 100644
--- a/src/include/utils/timeout.h
+++ b/src/include/utils/timeout.h
@@ -20,22 +20,21 @@
  * Identifiers for timeout reasons.  Note that in case multiple timeouts
  * trigger at the same time, they are serviced in the order of this enum.
  */
-typedef enum TimeoutId
-{
+typedef int TimeoutId;
+
 	/* Predefined timeout reasons */
-	STARTUP_PACKET_TIMEOUT,
-	DEADLOCK_TIMEOUT,
-	LOCK_TIMEOUT,
-	STATEMENT_TIMEOUT,
-	STANDBY_DEADLOCK_TIMEOUT,
-	STANDBY_TIMEOUT,
-	STANDBY_LOCK_TIMEOUT,
-	IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
+const int STARTUP_PACKET_TIMEOUT = 1;
+const int DEADLOCK_TIMEOUT = 2;
+const int LOCK_TIMEOUT = 3;
+const int STATEMENT_TIMEOUT = 4;
+const int STANDBY_DEADLOCK_TIMEOUT = 5;
+const int STANDBY_TIMEOUT = 6;
+const int STANDBY_LOCK_TIMEOUT = 7;
+const int IDLE_IN_TRANSACTION_SESSION_TIMEOUT = 8;
 	/* First user-definable timeout reason */
-	USER_TIMEOUT,
+const int USER_TIMEOUT = 9;
 	/* Maximum number of timeout reasons */
-	MAX_TIMEOUTS = 16
-} TimeoutId;
+const int MAX_TIMEOUTS = 16;
 
 /* callback function signature */
 typedef void (*timeout_handler_proc) (void);
-- 
2.9.3

From a8f8b2ea81f0364cc31d125800b705c701a9105f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 19/27] Add explicit cast for casting away volatile

---
 contrib/pg_stat_statements/pg_stat_statements.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 8ce24e0..37aac98 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -1547,7 +1547,7 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
 			volatile pgssEntry *e = (volatile pgssEntry *) entry;
 
 			SpinLockAcquire(&e->mutex);
-			tmp = e->counters;
+			tmp = const_cast<pgssEntry *>(e)->counters;
 			SpinLockRelease(&e->mutex);
 		}
 
-- 
2.9.3

From 42c4728e8cc0937485e4d3957d1768d6b6736e7d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 20/27] Add more extern key words

C++ needs those to make the definitions visible externally.  This is not
compatible with C.
---
 src/backend/access/rmgrdesc/xlogdesc.c | 2 +-
 src/backend/access/transam/xlog.c      | 4 ++--
 src/backend/storage/ipc/dsm_impl.c     | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index 62ed1dc..d3ea5e6 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -23,7 +23,7 @@
 /*
  * GUC support
  */
-const struct config_enum_entry wal_level_options[] = {
+extern const struct config_enum_entry wal_level_options[] = {
 	{"minimal", WAL_LEVEL_MINIMAL, false},
 	{"replica", WAL_LEVEL_REPLICA, false},
 	{"archive", WAL_LEVEL_REPLICA, true},		/* deprecated */
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index acd95aa..6732151 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -125,7 +125,7 @@ static double PrevCheckPointDistance = 0;
 /*
  * GUC support
  */
-const struct config_enum_entry sync_method_options[] = {
+extern const struct config_enum_entry sync_method_options[] = {
 	{"fsync", SYNC_METHOD_FSYNC, false},
 #ifdef HAVE_FSYNC_WRITETHROUGH
 	{"fsync_writethrough", SYNC_METHOD_FSYNC_WRITETHROUGH, false},
@@ -147,7 +147,7 @@ const struct config_enum_entry sync_method_options[] = {
  * Although only "on", "off", and "always" are documented,
  * we accept all the likely variants of "on" and "off".
  */
-const struct config_enum_entry archive_mode_options[] = {
+extern const struct config_enum_entry archive_mode_options[] = {
 	{"always", ARCHIVE_MODE_ALWAYS, false},
 	{"on", ARCHIVE_MODE_ON, false},
 	{"off", ARCHIVE_MODE_OFF, false},
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index c07a5c6..3b6a710 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -91,7 +91,7 @@ static bool dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
 #endif
 static int	errcode_for_dynamic_shared_memory(void);
 
-const struct config_enum_entry dynamic_shared_memory_options[] = {
+extern const struct config_enum_entry dynamic_shared_memory_options[] = {
 #ifdef USE_DSM_POSIX
 	{"posix", DSM_IMPL_POSIX, false},
 #endif
-- 
2.9.3

From c420d60d7e54f3e7799a15210413f34eb133de95 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 21/27] Workaround for using typdef'ed ints in loops

Types made from int don't have a ++ operator in C++, so they can't be
used in for loops without further work.

Needs more research
---
 src/backend/access/transam/xact.c | 4 ++--
 src/backend/commands/tablecmds.c  | 2 +-
 src/backend/storage/smgr/md.c     | 8 ++++----
 src/backend/storage/smgr/smgr.c   | 6 +++---
 src/backend/utils/adt/dbsize.c    | 6 +++---
 src/bin/pgbench/pgbench.c         | 5 ++++-
 src/common/relpath.c              | 4 ++--
 7 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index e11b229..6fd16e7 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -5456,7 +5456,7 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
 		for (i = 0; i < parsed->nrels; i++)
 		{
 			SMgrRelation srel = smgropen(parsed->xnodes[i], InvalidBackendId);
-			ForkNumber	fork;
+			int			fork;
 
 			for (fork = 0; fork <= MAX_FORKNUM; fork++)
 				XLogDropRelation(parsed->xnodes[i], fork);
@@ -5566,7 +5566,7 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid)
 	for (i = 0; i < parsed->nrels; i++)
 	{
 		SMgrRelation srel = smgropen(parsed->xnodes[i], InvalidBackendId);
-		ForkNumber	fork;
+		int			fork;
 
 		for (fork = 0; fork <= MAX_FORKNUM; fork++)
 			XLogDropRelation(parsed->xnodes[i], fork);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 86e9814..d10d8bc 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -9557,7 +9557,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
 	Relation	pg_class;
 	HeapTuple	tuple;
 	Form_pg_class rd_rel;
-	ForkNumber	forkNum;
+	int			forkNum;
 	List	   *reltoastidxids = NIL;
 	ListCell   *lc;
 
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 1287142..21bc909 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -400,7 +400,7 @@ mdunlink(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo)
 	/* Now do the per-fork work */
 	if (forkNum == InvalidForkNumber)
 	{
-		for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+		for (int forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
 			mdunlinkfork(rnode, forkNum, isRedo);
 	}
 	else
@@ -1127,7 +1127,7 @@ mdsync(void)
 	hash_seq_init(&hstat, pendingOpsTable);
 	while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL)
 	{
-		ForkNumber	forknum;
+		int		forknum;
 
 		/*
 		 * If the entry is new then don't process it this time; it might
@@ -1532,7 +1532,7 @@ RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
 			if (forknum == InvalidForkNumber)
 			{
 				/* remove requests for all forks */
-				for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
+				for (int forknum = 0; forknum <= MAX_FORKNUM; forknum++)
 				{
 					bms_free(entry->requests[forknum]);
 					entry->requests[forknum] = NULL;
@@ -1564,7 +1564,7 @@ RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
 			if (entry->rnode.dbNode == rnode.dbNode)
 			{
 				/* remove requests for all forks */
-				for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
+				for (int forknum = 0; forknum <= MAX_FORKNUM; forknum++)
 				{
 					bms_free(entry->requests[forknum]);
 					entry->requests[forknum] = NULL;
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 94aa952..73eb118 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -296,7 +296,7 @@ void
 smgrclose(SMgrRelation reln)
 {
 	SMgrRelation *owner;
-	ForkNumber	forknum;
+	int			forknum;
 
 	for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
 		(*(smgrsw[reln->smgr_which].smgr_close)) (reln, forknum);
@@ -415,7 +415,7 @@ smgrdounlink(SMgrRelation reln, bool isRedo)
 {
 	RelFileNodeBackend rnode = reln->smgr_rnode;
 	int			which = reln->smgr_which;
-	ForkNumber	forknum;
+	int			forknum;
 
 	/* Close the forks at smgr level */
 	for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
@@ -472,7 +472,7 @@ smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo)
 {
 	int			i = 0;
 	RelFileNodeBackend *rnodes;
-	ForkNumber	forknum;
+	int			forknum;
 
 	if (nrels == 0)
 		return;
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 3167bad..dd43033 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -342,7 +342,7 @@ calculate_toast_table_size(Oid toastrelid)
 {
 	int64		size = 0;
 	Relation	toastRel;
-	ForkNumber	forkNum;
+	int			forkNum;
 	ListCell   *lc;
 	List	   *indexlist;
 
@@ -387,7 +387,7 @@ static int64
 calculate_table_size(Relation rel)
 {
 	int64		size = 0;
-	ForkNumber	forkNum;
+	int			forkNum;
 
 	/*
 	 * heap size, including FSM and VM
@@ -427,7 +427,7 @@ calculate_indexes_size(Relation rel)
 		{
 			Oid			idxOid = lfirst_oid(cell);
 			Relation	idxRel;
-			ForkNumber	forkNum;
+			int			forkNum;
 
 			idxRel = relation_open(idxOid, AccessShareLock);
 
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 8027955..78c3872 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -3655,9 +3655,12 @@ main(int argc, char **argv)
 					fprintf(stderr, "query mode (-M) should be specified before any transaction scripts (-f or -b)\n");
 					exit(1);
 				}
-				for (querymode = 0; querymode < NUM_QUERYMODE; querymode++)
+				for (int qm = 0; qm < NUM_QUERYMODE; qm++)
 					if (strcmp(optarg, QUERYMODE[querymode]) == 0)
+					{
+						querymode = qm;
 						break;
+					}
 				if (querymode >= NUM_QUERYMODE)
 				{
 					fprintf(stderr, "invalid query mode (-M): \"%s\"\n",
diff --git a/src/common/relpath.c b/src/common/relpath.c
index 1aacb81..8bb918a 100644
--- a/src/common/relpath.c
+++ b/src/common/relpath.c
@@ -47,7 +47,7 @@ const char *const forkNames[] = {
 ForkNumber
 forkname_to_number(const char *forkName)
 {
-	ForkNumber	forkNum;
+	int		forkNum;
 
 	for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
 		if (strcmp(forkNames[forkNum], forkName) == 0)
@@ -78,7 +78,7 @@ forkname_to_number(const char *forkName)
 int
 forkname_chars(const char *str, ForkNumber *fork)
 {
-	ForkNumber	forkNum;
+	int			forkNum;
 
 	for (forkNum = 1; forkNum <= MAX_FORKNUM; forkNum++)
 	{
-- 
2.9.3

From 75495adef7bc6e3fe01e7b859a353efd5174cb4a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 22/27] Disable conflicting function

This function conflicts with a function in the backend.  FIXME
---
 contrib/xml2/xpath.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/contrib/xml2/xpath.c b/contrib/xml2/xpath.c
index ac28996..d654884 100644
--- a/contrib/xml2/xpath.c
+++ b/contrib/xml2/xpath.c
@@ -90,6 +90,7 @@ pgxml_parser_init(PgXmlStrictness strictness)
  * definitions for the contrib module, this won't be called.
  */
 
+#ifdef BROKEN
 PG_FUNCTION_INFO_V1(xml_is_well_formed);
 
 Datum
@@ -124,6 +125,7 @@ xml_is_well_formed(PG_FUNCTION_ARGS)
 
 	PG_RETURN_BOOL(result);
 }
+#endif
 
 
 /* Encodes special characters (<, >, &, " and \r) as XML entities */
-- 
2.9.3

From e23bbc59fed34b155bcdbff5317eea776e06a72d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 23/27] Add C linkage to replacement declaration of fdatasync

---
 src/include/c.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/include/c.h b/src/include/c.h
index cbefc47..18af261 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1099,7 +1099,7 @@ extern int	vsnprintf(char *str, size_t count, const char *fmt, va_list args);
 #endif
 
 #if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC
-extern int	fdatasync(int fildes);
+extern "C" int	fdatasync(int fildes);
 #endif
 
 /* If strtoq() exists, rename it to the more standard strtoll() */
-- 
2.9.3

From 27910bcbea854f36ee993af79a63ad184933c98a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 24/27] Make inet_net_?to? C linkage

These functions can also be declared by the operating system, so we need
to match the linkage.
---
 src/include/port.h           | 2 +-
 src/include/utils/builtins.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/include/port.h b/src/include/port.h
index 455f723..2607a3d 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -450,7 +450,7 @@ extern int	pg_codepage_to_encoding(UINT cp);
 #endif
 
 /* port/inet_net_ntop.c */
-extern char *inet_net_ntop(int af, const void *src, int bits,
+extern "C" char *inet_net_ntop(int af, const void *src, int bits,
 			  char *dst, size_t size);
 
 /* port/pgcheckdir.c */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 2ae212a..3f71457 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -947,7 +947,7 @@ extern char *inet_cidr_ntop(int af, const void *src, int bits,
 			   char *dst, size_t size);
 
 /* inet_net_pton.c */
-extern int inet_net_pton(int af, const char *src,
+extern "C" int inet_net_pton(int af, const char *src,
 			  void *dst, size_t size);
 
 /* network.c */
-- 
2.9.3

From a3124209270fde6c7cc1fd00244eb968326b7e1f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 25/27] Add C linkage to functions exported by plugins

This is required so dlsym() can find them reliably.
---
 contrib/bloom/bloom.h                           | 2 +-
 contrib/earthdistance/earthdistance.c           | 2 +-
 contrib/hstore/hstore.h                         | 4 ++--
 contrib/ltree/ltree.h                           | 2 ++
 contrib/pg_stat_statements/pg_stat_statements.c | 2 ++
 contrib/seg/seg.c                               | 6 ++++++
 src/include/fmgr.h                              | 6 +++---
 src/pl/plperl/plperl.c                          | 2 ++
 src/pl/plpgsql/src/plpgsql.h                    | 2 +-
 src/pl/plpython/plpy_main.c                     | 2 ++
 src/pl/tcl/pltcl.c                              | 2 ++
 src/test/regress/regress.c                      | 8 +++++---
 12 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/contrib/bloom/bloom.h b/contrib/bloom/bloom.h
index 18f5127..c80d9b0 100644
--- a/contrib/bloom/bloom.h
+++ b/contrib/bloom/bloom.h
@@ -173,7 +173,7 @@ typedef struct BloomScanOpaqueData
 typedef BloomScanOpaqueData *BloomScanOpaque;
 
 /* blutils.c */
-extern void _PG_init(void);
+extern "C" void _PG_init(void);
 extern void initBloomState(BloomState *state, Relation index);
 extern void BloomFillMetapage(Relation index, Page metaPage);
 extern void BloomInitMetapage(Relation index);
diff --git a/contrib/earthdistance/earthdistance.c b/contrib/earthdistance/earthdistance.c
index 861b166..305be5d 100644
--- a/contrib/earthdistance/earthdistance.c
+++ b/contrib/earthdistance/earthdistance.c
@@ -112,7 +112,7 @@ geo_distance(PG_FUNCTION_ARGS)
 }
 #else							/* !USE_FLOAT8_BYVAL */
 
-double	   *geo_distance(Point *pt1, Point *pt2);
+extern "C" double	   *geo_distance(Point *pt1, Point *pt2);
 
 double *
 geo_distance(Point *pt1, Point *pt2)
diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h
index 6bab08b..373a5f1 100644
--- a/contrib/hstore/hstore.h
+++ b/contrib/hstore/hstore.h
@@ -194,8 +194,8 @@ extern Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs);
 #if HSTORE_POLLUTE_NAMESPACE
 #define HSTORE_POLLUTE(newname_,oldname_) \
 	PG_FUNCTION_INFO_V1(oldname_);		  \
-	Datum newname_(PG_FUNCTION_ARGS);	  \
-	Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
+	extern "C" Datum newname_(PG_FUNCTION_ARGS);	  \
+	extern "C" Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
 	extern int no_such_variable
 #else
 #define HSTORE_POLLUTE(newname_,oldname_) \
diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h
index c604357..277b9a4 100644
--- a/contrib/ltree/ltree.h
+++ b/contrib/ltree/ltree.h
@@ -130,6 +130,7 @@ typedef struct
 
 
 /* use in array iterator */
+extern "C" {
 Datum		ltree_isparent(PG_FUNCTION_ARGS);
 Datum		ltree_risparent(PG_FUNCTION_ARGS);
 Datum		ltq_regex(PG_FUNCTION_ARGS);
@@ -154,6 +155,7 @@ Datum		ltree_textadd(PG_FUNCTION_ARGS);
 
 /* Util function */
 Datum		ltree_in(PG_FUNCTION_ARGS);
+}
 
 bool ltree_execute(ITEM *curitem, void *checkval,
 			  bool calcnot, bool (*chkcond) (void *checkval, ITEM *val));
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 37aac98..fb6bd82 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -275,8 +275,10 @@ static bool pgss_save;			/* whether to save stats across shutdown */
 
 /*---- Function declarations ----*/
 
+extern "C" {
 void		_PG_init(void);
 void		_PG_fini(void);
+}
 
 PG_FUNCTION_INFO_V1(pg_stat_statements_reset);
 PG_FUNCTION_INFO_V1(pg_stat_statements_1_2);
diff --git a/contrib/seg/seg.c b/contrib/seg/seg.c
index c6c082b..45d3503 100644
--- a/contrib/seg/seg.c
+++ b/contrib/seg/seg.c
@@ -47,6 +47,7 @@ PG_FUNCTION_INFO_V1(seg_center);
 /*
 ** GiST support methods
 */
+extern "C" {
 bool gseg_consistent(GISTENTRY *entry,
 				SEG *query,
 				StrategyNumber strategy,
@@ -61,11 +62,13 @@ bool		gseg_internal_consistent(SEG *key, SEG *query, StrategyNumber strategy);
 SEG		   *gseg_union(GistEntryVector *entryvec, int *sizep);
 SEG		   *gseg_binary_union(SEG *r1, SEG *r2, int *sizep);
 bool	   *gseg_same(SEG *b1, SEG *b2, bool *result);
+}
 
 
 /*
 ** R-tree support functions
 */
+extern "C" {
 bool		seg_same(SEG *a, SEG *b);
 bool		seg_contains_int(SEG *a, int *b);
 bool		seg_contains_float4(SEG *a, float4 *b);
@@ -80,16 +83,19 @@ bool		seg_over_right(SEG *a, SEG *b);
 SEG		   *seg_union(SEG *a, SEG *b);
 SEG		   *seg_inter(SEG *a, SEG *b);
 void		rt_seg_size(SEG *a, float *sz);
+}
 
 /*
 ** Various operators
 */
+extern "C" {
 int32		seg_cmp(SEG *a, SEG *b);
 bool		seg_lt(SEG *a, SEG *b);
 bool		seg_le(SEG *a, SEG *b);
 bool		seg_gt(SEG *a, SEG *b);
 bool		seg_ge(SEG *a, SEG *b);
 bool		seg_different(SEG *a, SEG *b);
+}
 
 /*
 ** Auxiliary funxtions
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 0491e2e..191235f 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -348,8 +348,8 @@ typedef const Pg_finfo_record *(*PGFInfoFunction) (void);
  *	doesn't hurt to add PGDLLIMPORT in case they don't.
  */
 #define PG_FUNCTION_INFO_V1(funcname) \
-Datum funcname(PG_FUNCTION_ARGS); \
-extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \
+extern "C" Datum funcname(PG_FUNCTION_ARGS); \
+extern "C" PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \
 const Pg_finfo_record * \
 CppConcat(pg_finfo_,funcname) (void) \
 { \
@@ -418,7 +418,7 @@ typedef const Pg_magic_struct *(*PGModuleMagicFunction) (void);
 #define PG_MAGIC_FUNCTION_NAME_STRING "Pg_magic_func"
 
 #define PG_MODULE_MAGIC \
-extern PGDLLEXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \
+extern "C" PGDLLEXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \
 const Pg_magic_struct * \
 PG_MAGIC_FUNCTION_NAME(void) \
 { \
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 2cd7614..c5c0617 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -244,7 +244,9 @@ static plperl_call_data *current_call_data = NULL;
 /**********************************************************************
  * Forward declarations
  **********************************************************************/
+extern "C" {
 void		_PG_init(void);
+}
 
 static PerlInterpreter *plperl_init_interp(void);
 static void plperl_destroy_interp(PerlInterpreter **);
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index b416e50..f2ddd94 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -1085,7 +1085,7 @@ extern void plpgsql_HashTableInit(void);
 /*
  * Functions in pl_handler.c
  */
-extern void _PG_init(void);
+extern "C" void _PG_init(void);
 
 /*
  * Functions in pl_exec.c
diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
index 860b804..efd3bf0 100644
--- a/src/pl/plpython/plpy_main.c
+++ b/src/pl/plpython/plpy_main.c
@@ -39,7 +39,9 @@
 #define plpython_inline_handler plpython3_inline_handler
 #endif
 
+extern "C" {
 extern void _PG_init(void);
+}
 
 PG_MODULE_MAGIC;
 
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 2a335aa..20578ad 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -205,7 +205,9 @@ static const TclExceptionNameMap exception_name_map[] = {
 /**********************************************************************
  * Forward declarations
  **********************************************************************/
+extern "C" {
 void		_PG_init(void);
+}
 
 static void pltcl_init_interp(pltcl_interp_desc *interp_desc, bool pltrusted);
 static pltcl_interp_desc *pltcl_fetch_interp(bool pltrusted);
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index e7826a4..9621cc1 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -45,8 +45,8 @@
 
 extern PATH *poly2path(POLYGON *poly);
 extern void regress_lseg_construct(LSEG *lseg, Point *pt1, Point *pt2);
-extern char *reverse_name(char *string);
-extern int	oldstyle_length(int n, text *t);
+extern "C" char *reverse_name(char *string);
+extern "C" int	oldstyle_length(int n, text *t);
 
 #ifdef PG_MODULE_MAGIC
 PG_MODULE_MAGIC;
@@ -240,8 +240,10 @@ typedef struct
 	double		radius;
 } WIDGET;
 
+extern "C" {
 WIDGET	   *widget_in(char *str);
-char	   *widget_out(WIDGET *widget);
+char	   *widget_out(WIDGET * widget);
+}
 
 #define NARGS	3
 
-- 
2.9.3

From 92ff0ab38c864c2edea49a83ec0e46c33bf71e64 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 26/27] Add C linkage to client libraries in non-systematic
 ways

---
 src/backend/utils/mb/encnames.c     |  3 +++
 src/include/mb/pg_wchar.h           | 12 ++++++++++++
 src/include/port.h                  |  6 ++++++
 src/interfaces/ecpg/pgtypeslib/dt.h |  2 +-
 src/interfaces/libpq/Makefile       |  2 +-
 src/interfaces/libpq/libpq-fe.h     |  1 +
 src/interfaces/libpq/pqexpbuffer.h  |  9 +++++++++
 7 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/backend/utils/mb/encnames.c b/src/backend/utils/mb/encnames.c
index 11099b8..dc62e90 100644
--- a/src/backend/utils/mb/encnames.c
+++ b/src/backend/utils/mb/encnames.c
@@ -6,6 +6,9 @@
  */
 #ifdef FRONTEND
 #include "postgres_fe.h"
+#ifdef LIBPQ
+#include "libpq-fe.h"
+#endif
 #else
 #include "postgres.h"
 #include "utils/builtins.h"
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 24e8d0d..f5dd098 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -491,11 +491,23 @@ extern int	pg_bind_textdomain_codeset(const char *domainname);
 #endif
 
 extern int	pg_valid_client_encoding(const char *name);
+#ifdef LIBPQ
+extern "C" {
+#endif
 extern int	pg_valid_server_encoding(const char *name);
+#ifdef LIBPQ
+}
+#endif
 
 extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
 extern pg_wchar utf8_to_unicode(const unsigned char *c);
+#ifdef LIBPQ
+extern "C" {
+#endif
 extern int	pg_utf_mblen(const unsigned char *);
+#ifdef LIBPQ
+}
+#endif
 extern unsigned char *pg_do_encoding_conversion(unsigned char *src, int len,
 						  int src_encoding,
 						  int dest_encoding);
diff --git a/src/include/port.h b/src/include/port.h
index 2607a3d..831e9be 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -460,8 +460,14 @@ extern int	pg_check_dir(const char *dir);
 extern int	pg_mkdir_p(char *path, int omode);
 
 /* port/pqsignal.c */
+#ifdef LIBPQ
+extern "C" {
+#endif
 typedef void (*pqsigfunc) (int signo);
 extern pqsigfunc pqsignal(int signo, pqsigfunc func);
+#ifdef LIBPQ
+}
+#endif
 
 /* port/quotes.c */
 extern char *escape_single_quotes_ascii(const char *src);
diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.h
index c0c3ac1..ad77b05 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt.h
+++ b/src/interfaces/ecpg/pgtypeslib/dt.h
@@ -365,7 +365,7 @@ void		GetCurrentDateTime(struct tm *);
 int			date2j(int, int, int);
 void		TrimTrailingZeros(char *);
 void		dt2time(double, int *, int *, int *, fsec_t *);
-int PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
+extern "C" int PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
 							int *year, int *month, int *day,
 							int *hour, int *minute, int *second,
 							int *tz);
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 0b4065e..d71b2c0 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -19,7 +19,7 @@ NAME= pq
 SO_MAJOR_VERSION= 5
 SO_MINOR_VERSION= $(MAJORVERSION)
 
-override CPPFLAGS :=  -DFRONTEND -DUNSAFE_STAT_OK -I$(srcdir) $(CPPFLAGS) -I$(top_builddir)/src/port -I$(top_srcdir)/src/port
+override CPPFLAGS :=  -DFRONTEND -DLIBPQ -DUNSAFE_STAT_OK -I$(srcdir) $(CPPFLAGS) -I$(top_builddir)/src/port -I$(top_srcdir)/src/port
 ifneq ($(PORTNAME), win32)
 override CFLAGS += $(PTHREAD_CFLAGS)
 endif
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 9ca0756..c8f5293 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -501,6 +501,7 @@ extern void PQclear(PGresult *res);
 extern void PQfreemem(void *ptr);
 
 /* Exists for backward compatibility.  bjm 2003-03-24 */
+extern void PQfreeNotify(PGnotify *notify);
 #define PQfreeNotify(ptr) PQfreemem(ptr)
 
 /* Error when no password was given. */
diff --git a/src/interfaces/libpq/pqexpbuffer.h b/src/interfaces/libpq/pqexpbuffer.h
index ce87cd5..ba4ac74 100644
--- a/src/interfaces/libpq/pqexpbuffer.h
+++ b/src/interfaces/libpq/pqexpbuffer.h
@@ -25,6 +25,11 @@
 #ifndef PQEXPBUFFER_H
 #define PQEXPBUFFER_H
 
+#ifdef __cplusplus
+extern      "C"
+{
+#endif
+
 /*-------------------------
  * PQExpBufferData holds information about an extensible string.
  *		data	is the current buffer for the string (allocated with malloc).
@@ -179,4 +184,8 @@ extern void appendPQExpBufferChar(PQExpBuffer str, char ch);
 extern void appendBinaryPQExpBuffer(PQExpBuffer str,
 						const char *data, size_t datalen);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif   /* PQEXPBUFFER_H */
-- 
2.9.3

From 1af627d7881ebcb2a974eb0934a455cb9f806db2 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Tue, 30 Aug 2016 12:00:00 -0400
Subject: [PATCH 27/27] Hack: Disable volatile that causes mysterious compiler
 errors

---
 src/backend/commands/async.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 716f1c3..c727788 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -385,7 +385,7 @@ static double asyncQueueUsage(void);
 static void asyncQueueFillWarning(void);
 static bool SignalBackends(void);
 static void asyncQueueReadAllNotifications(void);
-static bool asyncQueueProcessPageEntries(volatile QueuePosition *current,
+static bool asyncQueueProcessPageEntries(/*volatile*/ QueuePosition *current,
 							 QueuePosition stop,
 							 char *page_buffer);
 static void asyncQueueAdvanceTail(void);
@@ -1741,7 +1741,7 @@ ProcessNotifyInterrupt(void)
 static void
 asyncQueueReadAllNotifications(void)
 {
-	volatile QueuePosition pos;
+	/*volatile*/ QueuePosition pos;
 	QueuePosition oldpos;
 	QueuePosition head;
 	bool		advanceTail;
@@ -1901,7 +1901,7 @@ asyncQueueReadAllNotifications(void)
  * The QueuePosition *current is advanced past all processed messages.
  */
 static bool
-asyncQueueProcessPageEntries(volatile QueuePosition *current,
+asyncQueueProcessPageEntries(/*volatile*/ QueuePosition *current,
 							 QueuePosition stop,
 							 char *page_buffer)
 {
-- 
2.9.3

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to