Create function prototype as part of PG_FUNCTION_INFO_V1

Started by Peter Eisentrautalmost 12 years ago17 messages
#1Peter Eisentraut
peter_e@gmx.net
1 attachment(s)

This idea has appeared at least twice now, in
/messages/by-id/1386301050.2743.17.camel@vanquo.pezone.net and /messages/by-id/52D25AA2.50108@2ndquadrant.com . Even if it doesn't help with Windows issues, as discussed in the second thread, it still seems like a win for reducing boilerplate and accidental compiler warnings. So here is a patch for consideration.

Attachments:

0001-Create-function-prototype-as-part-of-PG_FUNCTION_INF.patchtext/x-patch; charset=UTF-8; name=0001-Create-function-prototype-as-part-of-PG_FUNCTION_INF.patchDownload
>From 6cfaabccf08545fedf163234fea08d0fc2b8caa6 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Tue, 14 Jan 2014 20:47:45 -0500
Subject: [PATCH] Create function prototype as part of PG_FUNCTION_INFO_V1
 macro

Because of gcc -Wmissing-prototypes, all functions in dynamically
loadable modules must have a separate prototype declaration.  This is
meant to detect global functions that are not declared in header files,
but in cases where the function is called via dfmgr, this is redundant.
Besides filling up space with boilerplate, this is a frequent source of
compiler warnings in extension modules.

We can fix that by creating the function prototype as part of the
PG_FUNCTION_INFO_V1 macro, which such modules have to use anyway.  That
makes the code of modules cleaner, because there is one less place where
the entry points have to be listed, and creates an additional check that
functions have the right prototype.

Similarly, we can provide prototypes for _PG_init and _PG_fini in
fmgr.h, so that extension modules don't have to do it and get an
additional check that their implementations have the right signature.

Remove now redundant prototypes from contrib and other modules.
---
 contrib/adminpack/adminpack.c                      |  5 ---
 contrib/auth_delay/auth_delay.c                    |  2 --
 contrib/auto_explain/auto_explain.c                |  3 --
 contrib/btree_gin/btree_gin.c                      |  5 ---
 contrib/btree_gist/btree_bit.c                     |  8 -----
 contrib/btree_gist/btree_bytea.c                   |  7 ----
 contrib/btree_gist/btree_cash.c                    |  9 -----
 contrib/btree_gist/btree_date.c                    |  9 -----
 contrib/btree_gist/btree_float4.c                  |  9 -----
 contrib/btree_gist/btree_float8.c                  | 10 ------
 contrib/btree_gist/btree_gist.c                    |  2 --
 contrib/btree_gist/btree_inet.c                    |  7 ----
 contrib/btree_gist/btree_int2.c                    |  9 -----
 contrib/btree_gist/btree_int4.c                    |  9 -----
 contrib/btree_gist/btree_int8.c                    |  9 -----
 contrib/btree_gist/btree_interval.c                | 10 ------
 contrib/btree_gist/btree_macaddr.c                 |  7 ----
 contrib/btree_gist/btree_numeric.c                 |  7 ----
 contrib/btree_gist/btree_oid.c                     |  9 -----
 contrib/btree_gist/btree_text.c                    |  9 -----
 contrib/btree_gist/btree_time.c                    | 11 ------
 contrib/btree_gist/btree_ts.c                      | 13 -------
 contrib/btree_gist/btree_utils_var.c               |  1 -
 contrib/chkpass/chkpass.c                          | 12 -------
 contrib/citext/citext.c                            | 10 ------
 contrib/cube/cube.c                                | 40 ----------------------
 contrib/dict_int/dict_int.c                        |  3 --
 contrib/dict_xsyn/dict_xsyn.c                      |  3 --
 contrib/dummy_seclabel/dummy_seclabel.c            |  4 +--
 contrib/earthdistance/earthdistance.c              |  2 --
 contrib/file_fdw/file_fdw.c                        |  3 --
 contrib/fuzzystrmatch/dmetaphone.c                 |  3 --
 contrib/fuzzystrmatch/fuzzystrmatch.c              | 12 -------
 contrib/hstore/hstore.h                            |  1 -
 contrib/hstore/hstore_compat.c                     |  1 -
 contrib/hstore/hstore_gin.c                        |  3 --
 contrib/hstore/hstore_gist.c                       | 12 -------
 contrib/hstore/hstore_io.c                         | 11 ------
 contrib/hstore/hstore_op.c                         | 28 ---------------
 contrib/intarray/_int_bool.c                       |  8 -----
 contrib/intarray/_int_gin.c                        |  2 --
 contrib/intarray/_int_gist.c                       |  8 -----
 contrib/intarray/_int_op.c                         | 21 ------------
 contrib/intarray/_intbig_gist.c                    | 12 -------
 contrib/lo/lo.c                                    |  4 ---
 contrib/ltree/_ltree_gist.c                        | 11 ------
 contrib/ltree/_ltree_op.c                          |  8 -----
 contrib/ltree/ltree_gist.c                         | 16 ---------
 contrib/ltree/ltree_io.c                           |  7 ----
 contrib/ltree/ltree_op.c                           | 19 ----------
 contrib/ltree/ltxtquery_io.c                       |  3 --
 contrib/pageinspect/btreefuncs.c                   |  4 ---
 contrib/pageinspect/fsmfuncs.c                     |  2 --
 contrib/pageinspect/heapfuncs.c                    |  2 --
 contrib/pageinspect/rawpage.c                      |  4 ---
 contrib/passwordcheck/passwordcheck.c              |  2 --
 contrib/pg_buffercache/pg_buffercache_pages.c      |  2 --
 contrib/pg_freespacemap/pg_freespacemap.c          |  2 --
 contrib/pg_prewarm/pg_prewarm.c                    |  2 --
 contrib/pg_stat_statements/pg_stat_statements.c    |  6 ----
 contrib/pg_trgm/trgm_gin.c                         |  7 ----
 contrib/pg_trgm/trgm_gist.c                        | 19 ----------
 contrib/pg_trgm/trgm_op.c                          | 11 ------
 contrib/pg_upgrade_support/pg_upgrade_support.c    | 13 -------
 contrib/pgcrypto/pgp-pgsql.c                       | 17 ---------
 contrib/pgrowlocks/pgrowlocks.c                    |  2 --
 contrib/pgstattuple/pgstatindex.c                  |  6 ----
 contrib/pgstattuple/pgstattuple.c                  |  3 --
 contrib/postgres_fdw/option.c                      |  2 --
 contrib/postgres_fdw/postgres_fdw.c                |  2 --
 contrib/seg/seg.c                                  |  7 ----
 contrib/sepgsql/hooks.c                            |  5 ---
 contrib/spi/autoinc.c                              |  2 --
 contrib/spi/insert_username.c                      |  2 --
 contrib/spi/moddatetime.c                          |  2 --
 contrib/spi/refint.c                               |  4 ---
 contrib/spi/timetravel.c                           |  3 --
 contrib/sslinfo/sslinfo.c                          |  9 -----
 contrib/tcn/tcn.c                                  |  4 ---
 contrib/test_parser/test_parser.c                  | 12 +------
 contrib/tsearch2/tsearch2.c                        | 23 ++-----------
 contrib/unaccent/unaccent.c                        |  3 --
 contrib/uuid-ossp/uuid-ossp.c                      | 14 --------
 contrib/worker_spi/worker_spi.c                    |  2 --
 contrib/xml2/xpath.c                               | 11 ------
 contrib/xml2/xslt_proc.c                           |  4 ---
 .../libpqwalreceiver/libpqwalreceiver.c            |  2 --
 src/include/fmgr.h                                 |  4 +++
 src/pl/plperl/plperl.c                             |  8 -----
 src/pl/plpgsql/src/plpgsql.h                       |  9 -----
 src/pl/plpython/plpy_main.c                        | 13 +------
 src/pl/tcl/pltcl.c                                 |  4 ---
 src/test/regress/regress.c                         | 13 -------
 93 files changed, 9 insertions(+), 696 deletions(-)

diff --git a/contrib/adminpack/adminpack.c b/contrib/adminpack/adminpack.c
index 27cbcde..8193b1f 100644
--- a/contrib/adminpack/adminpack.c
+++ b/contrib/adminpack/adminpack.c
@@ -40,11 +40,6 @@
 
 PG_MODULE_MAGIC;
 
-Datum		pg_file_write(PG_FUNCTION_ARGS);
-Datum		pg_file_rename(PG_FUNCTION_ARGS);
-Datum		pg_file_unlink(PG_FUNCTION_ARGS);
-Datum		pg_logdir_ls(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(pg_file_write);
 PG_FUNCTION_INFO_V1(pg_file_rename);
 PG_FUNCTION_INFO_V1(pg_file_unlink);
diff --git a/contrib/auth_delay/auth_delay.c b/contrib/auth_delay/auth_delay.c
index 3131e82..b010f22 100644
--- a/contrib/auth_delay/auth_delay.c
+++ b/contrib/auth_delay/auth_delay.c
@@ -18,8 +18,6 @@
 
 PG_MODULE_MAGIC;
 
-void		_PG_init(void);
-
 /* GUC Variables */
 static int	auth_delay_milliseconds;
 
diff --git a/contrib/auto_explain/auto_explain.c b/contrib/auto_explain/auto_explain.c
index af68479..c1eccba 100644
--- a/contrib/auto_explain/auto_explain.c
+++ b/contrib/auto_explain/auto_explain.c
@@ -50,9 +50,6 @@
 	(auto_explain_log_min_duration >= 0 && \
 	 (nesting_level == 0 || auto_explain_log_nested_statements))
 
-void		_PG_init(void);
-void		_PG_fini(void);
-
 static void explain_ExecutorStart(QueryDesc *queryDesc, int eflags);
 static void explain_ExecutorRun(QueryDesc *queryDesc,
 					ScanDirection direction,
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index 5e6003f..87d23e0 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -32,7 +32,6 @@
 
 #define  GIN_EXTRACT_VALUE(type)											\
 PG_FUNCTION_INFO_V1(gin_extract_value_##type);								\
-Datum		gin_extract_value_##type(PG_FUNCTION_ARGS);						\
 Datum																		\
 gin_extract_value_##type(PG_FUNCTION_ARGS)									\
 {																			\
@@ -59,7 +58,6 @@
 
 #define GIN_EXTRACT_QUERY(type)												\
 PG_FUNCTION_INFO_V1(gin_extract_query_##type);								\
-Datum		gin_extract_query_##type(PG_FUNCTION_ARGS);						\
 Datum																		\
 gin_extract_query_##type(PG_FUNCTION_ARGS)									\
 {																			\
@@ -109,7 +107,6 @@
  */
 #define GIN_COMPARE_PREFIX(type)											\
 PG_FUNCTION_INFO_V1(gin_compare_prefix_##type);								\
-Datum		gin_compare_prefix_##type(PG_FUNCTION_ARGS);					\
 Datum																		\
 gin_compare_prefix_##type(PG_FUNCTION_ARGS)									\
 {																			\
@@ -182,7 +179,6 @@
 
 
 PG_FUNCTION_INFO_V1(gin_btree_consistent);
-Datum		gin_btree_consistent(PG_FUNCTION_ARGS);
 Datum
 gin_btree_consistent(PG_FUNCTION_ARGS)
 {
@@ -404,7 +400,6 @@
 #define NUMERIC_IS_LEFTMOST(x)	((x) == NULL)
 
 PG_FUNCTION_INFO_V1(gin_numeric_cmp);
-Datum		gin_numeric_cmp(PG_FUNCTION_ARGS);
 
 Datum
 gin_numeric_cmp(PG_FUNCTION_ARGS)
diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index d94abcb..edf75e0 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -19,14 +19,6 @@
 PG_FUNCTION_INFO_V1(gbt_bit_penalty);
 PG_FUNCTION_INFO_V1(gbt_bit_same);
 
-Datum		gbt_bit_compress(PG_FUNCTION_ARGS);
-Datum		gbt_bit_union(PG_FUNCTION_ARGS);
-Datum		gbt_bit_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_bit_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_bit_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_bit_same(PG_FUNCTION_ARGS);
-
-
 
 /* define for comparison */
 
diff --git a/contrib/btree_gist/btree_bytea.c b/contrib/btree_gist/btree_bytea.c
index 0dd4419..dfc25a4 100644
--- a/contrib/btree_gist/btree_bytea.c
+++ b/contrib/btree_gist/btree_bytea.c
@@ -18,13 +18,6 @@
 PG_FUNCTION_INFO_V1(gbt_bytea_penalty);
 PG_FUNCTION_INFO_V1(gbt_bytea_same);
 
-Datum		gbt_bytea_compress(PG_FUNCTION_ARGS);
-Datum		gbt_bytea_union(PG_FUNCTION_ARGS);
-Datum		gbt_bytea_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_bytea_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_bytea_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_bytea_same(PG_FUNCTION_ARGS);
-
 
 /* define for comparison */
 
diff --git a/contrib/btree_gist/btree_cash.c b/contrib/btree_gist/btree_cash.c
index 8e8495c..8de3716 100644
--- a/contrib/btree_gist/btree_cash.c
+++ b/contrib/btree_gist/btree_cash.c
@@ -24,14 +24,6 @@
 PG_FUNCTION_INFO_V1(gbt_cash_penalty);
 PG_FUNCTION_INFO_V1(gbt_cash_same);
 
-Datum		gbt_cash_compress(PG_FUNCTION_ARGS);
-Datum		gbt_cash_union(PG_FUNCTION_ARGS);
-Datum		gbt_cash_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_cash_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_cash_distance(PG_FUNCTION_ARGS);
-Datum		gbt_cash_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_cash_same(PG_FUNCTION_ARGS);
-
 static bool
 gbt_cashgt(const void *a, const void *b)
 {
@@ -97,7 +89,6 @@
 
 
 PG_FUNCTION_INFO_V1(cash_dist);
-Datum		cash_dist(PG_FUNCTION_ARGS);
 Datum
 cash_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_date.c b/contrib/btree_gist/btree_date.c
index 1c0c3ec..9cab7ec 100644
--- a/contrib/btree_gist/btree_date.c
+++ b/contrib/btree_gist/btree_date.c
@@ -24,14 +24,6 @@
 PG_FUNCTION_INFO_V1(gbt_date_penalty);
 PG_FUNCTION_INFO_V1(gbt_date_same);
 
-Datum		gbt_date_compress(PG_FUNCTION_ARGS);
-Datum		gbt_date_union(PG_FUNCTION_ARGS);
-Datum		gbt_date_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_date_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_date_distance(PG_FUNCTION_ARGS);
-Datum		gbt_date_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_date_same(PG_FUNCTION_ARGS);
-
 static bool
 gbt_dategt(const void *a, const void *b)
 {
@@ -115,7 +107,6 @@
 
 
 PG_FUNCTION_INFO_V1(date_dist);
-Datum		date_dist(PG_FUNCTION_ARGS);
 Datum
 date_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_float4.c b/contrib/btree_gist/btree_float4.c
index cf1e45a..55e1c4c 100644
--- a/contrib/btree_gist/btree_float4.c
+++ b/contrib/btree_gist/btree_float4.c
@@ -23,14 +23,6 @@
 PG_FUNCTION_INFO_V1(gbt_float4_penalty);
 PG_FUNCTION_INFO_V1(gbt_float4_same);
 
-Datum		gbt_float4_compress(PG_FUNCTION_ARGS);
-Datum		gbt_float4_union(PG_FUNCTION_ARGS);
-Datum		gbt_float4_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_float4_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_float4_distance(PG_FUNCTION_ARGS);
-Datum		gbt_float4_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_float4_same(PG_FUNCTION_ARGS);
-
 static bool
 gbt_float4gt(const void *a, const void *b)
 {
@@ -96,7 +88,6 @@
 
 
 PG_FUNCTION_INFO_V1(float4_dist);
-Datum		float4_dist(PG_FUNCTION_ARGS);
 Datum
 float4_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_float8.c b/contrib/btree_gist/btree_float8.c
index 3ce8764..9cd83a7 100644
--- a/contrib/btree_gist/btree_float8.c
+++ b/contrib/btree_gist/btree_float8.c
@@ -23,15 +23,6 @@
 PG_FUNCTION_INFO_V1(gbt_float8_penalty);
 PG_FUNCTION_INFO_V1(gbt_float8_same);
 
-Datum		gbt_float8_compress(PG_FUNCTION_ARGS);
-Datum		gbt_float8_union(PG_FUNCTION_ARGS);
-Datum		gbt_float8_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_float8_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_float8_distance(PG_FUNCTION_ARGS);
-Datum		gbt_float8_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_float8_same(PG_FUNCTION_ARGS);
-
-
 static bool
 gbt_float8gt(const void *a, const void *b)
 {
@@ -104,7 +95,6 @@
 
 
 PG_FUNCTION_INFO_V1(float8_dist);
-Datum		float8_dist(PG_FUNCTION_ARGS);
 Datum
 float8_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_gist.c b/contrib/btree_gist/btree_gist.c
index f2d2ed2..e1dc253 100644
--- a/contrib/btree_gist/btree_gist.c
+++ b/contrib/btree_gist/btree_gist.c
@@ -11,8 +11,6 @@
 PG_FUNCTION_INFO_V1(gbtreekey_in);
 PG_FUNCTION_INFO_V1(gbtreekey_out);
 
-Datum		gbt_decompress(PG_FUNCTION_ARGS);
-
 /**************************************************
  * In/Out for keys
  **************************************************/
diff --git a/contrib/btree_gist/btree_inet.c b/contrib/btree_gist/btree_inet.c
index c136296..24ae6bf 100644
--- a/contrib/btree_gist/btree_inet.c
+++ b/contrib/btree_gist/btree_inet.c
@@ -25,13 +25,6 @@
 PG_FUNCTION_INFO_V1(gbt_inet_penalty);
 PG_FUNCTION_INFO_V1(gbt_inet_same);
 
-Datum		gbt_inet_compress(PG_FUNCTION_ARGS);
-Datum		gbt_inet_union(PG_FUNCTION_ARGS);
-Datum		gbt_inet_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_inet_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_inet_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_inet_same(PG_FUNCTION_ARGS);
-
 
 static bool
 gbt_inetgt(const void *a, const void *b)
diff --git a/contrib/btree_gist/btree_int2.c b/contrib/btree_gist/btree_int2.c
index 6a438bf..d51ad0c 100644
--- a/contrib/btree_gist/btree_int2.c
+++ b/contrib/btree_gist/btree_int2.c
@@ -23,14 +23,6 @@
 PG_FUNCTION_INFO_V1(gbt_int2_penalty);
 PG_FUNCTION_INFO_V1(gbt_int2_same);
 
-Datum		gbt_int2_compress(PG_FUNCTION_ARGS);
-Datum		gbt_int2_union(PG_FUNCTION_ARGS);
-Datum		gbt_int2_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_int2_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_int2_distance(PG_FUNCTION_ARGS);
-Datum		gbt_int2_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_int2_same(PG_FUNCTION_ARGS);
-
 static bool
 gbt_int2gt(const void *a, const void *b)
 {
@@ -96,7 +88,6 @@
 
 
 PG_FUNCTION_INFO_V1(int2_dist);
-Datum		int2_dist(PG_FUNCTION_ARGS);
 Datum
 int2_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_int4.c b/contrib/btree_gist/btree_int4.c
index df2164f..e7641f2 100644
--- a/contrib/btree_gist/btree_int4.c
+++ b/contrib/btree_gist/btree_int4.c
@@ -23,14 +23,6 @@
 PG_FUNCTION_INFO_V1(gbt_int4_penalty);
 PG_FUNCTION_INFO_V1(gbt_int4_same);
 
-Datum		gbt_int4_compress(PG_FUNCTION_ARGS);
-Datum		gbt_int4_union(PG_FUNCTION_ARGS);
-Datum		gbt_int4_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_int4_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_int4_distance(PG_FUNCTION_ARGS);
-Datum		gbt_int4_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_int4_same(PG_FUNCTION_ARGS);
-
 
 static bool
 gbt_int4gt(const void *a, const void *b)
@@ -97,7 +89,6 @@
 
 
 PG_FUNCTION_INFO_V1(int4_dist);
-Datum		int4_dist(PG_FUNCTION_ARGS);
 Datum
 int4_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_int8.c b/contrib/btree_gist/btree_int8.c
index c05d868..8bc8cb5 100644
--- a/contrib/btree_gist/btree_int8.c
+++ b/contrib/btree_gist/btree_int8.c
@@ -23,14 +23,6 @@
 PG_FUNCTION_INFO_V1(gbt_int8_penalty);
 PG_FUNCTION_INFO_V1(gbt_int8_same);
 
-Datum		gbt_int8_compress(PG_FUNCTION_ARGS);
-Datum		gbt_int8_union(PG_FUNCTION_ARGS);
-Datum		gbt_int8_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_int8_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_int8_distance(PG_FUNCTION_ARGS);
-Datum		gbt_int8_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_int8_same(PG_FUNCTION_ARGS);
-
 
 static bool
 gbt_int8gt(const void *a, const void *b)
@@ -97,7 +89,6 @@
 
 
 PG_FUNCTION_INFO_V1(int8_dist);
-Datum		int8_dist(PG_FUNCTION_ARGS);
 Datum
 int8_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_interval.c b/contrib/btree_gist/btree_interval.c
index bb779ad..e406d71 100644
--- a/contrib/btree_gist/btree_interval.c
+++ b/contrib/btree_gist/btree_interval.c
@@ -26,15 +26,6 @@
 PG_FUNCTION_INFO_V1(gbt_intv_penalty);
 PG_FUNCTION_INFO_V1(gbt_intv_same);
 
-Datum		gbt_intv_compress(PG_FUNCTION_ARGS);
-Datum		gbt_intv_decompress(PG_FUNCTION_ARGS);
-Datum		gbt_intv_union(PG_FUNCTION_ARGS);
-Datum		gbt_intv_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_intv_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_intv_distance(PG_FUNCTION_ARGS);
-Datum		gbt_intv_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_intv_same(PG_FUNCTION_ARGS);
-
 
 static bool
 gbt_intvgt(const void *a, const void *b)
@@ -129,7 +120,6 @@
 }
 
 PG_FUNCTION_INFO_V1(interval_dist);
-Datum		interval_dist(PG_FUNCTION_ARGS);
 Datum
 interval_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_macaddr.c b/contrib/btree_gist/btree_macaddr.c
index 31125be..6255564 100644
--- a/contrib/btree_gist/btree_macaddr.c
+++ b/contrib/btree_gist/btree_macaddr.c
@@ -24,13 +24,6 @@
 PG_FUNCTION_INFO_V1(gbt_macad_penalty);
 PG_FUNCTION_INFO_V1(gbt_macad_same);
 
-Datum		gbt_macad_compress(PG_FUNCTION_ARGS);
-Datum		gbt_macad_union(PG_FUNCTION_ARGS);
-Datum		gbt_macad_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_macad_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_macad_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_macad_same(PG_FUNCTION_ARGS);
-
 
 static bool
 gbt_macadgt(const void *a, const void *b)
diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c
index 37938af..02ccca8 100644
--- a/contrib/btree_gist/btree_numeric.c
+++ b/contrib/btree_gist/btree_numeric.c
@@ -23,13 +23,6 @@
 PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
 PG_FUNCTION_INFO_V1(gbt_numeric_same);
 
-Datum		gbt_numeric_compress(PG_FUNCTION_ARGS);
-Datum		gbt_numeric_union(PG_FUNCTION_ARGS);
-Datum		gbt_numeric_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_numeric_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_numeric_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_numeric_same(PG_FUNCTION_ARGS);
-
 
 /* define for comparison */
 
diff --git a/contrib/btree_gist/btree_oid.c b/contrib/btree_gist/btree_oid.c
index e80a23c..dcd0765 100644
--- a/contrib/btree_gist/btree_oid.c
+++ b/contrib/btree_gist/btree_oid.c
@@ -23,14 +23,6 @@
 PG_FUNCTION_INFO_V1(gbt_oid_penalty);
 PG_FUNCTION_INFO_V1(gbt_oid_same);
 
-Datum		gbt_oid_compress(PG_FUNCTION_ARGS);
-Datum		gbt_oid_union(PG_FUNCTION_ARGS);
-Datum		gbt_oid_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_oid_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_oid_distance(PG_FUNCTION_ARGS);
-Datum		gbt_oid_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_oid_same(PG_FUNCTION_ARGS);
-
 
 static bool
 gbt_oidgt(const void *a, const void *b)
@@ -103,7 +95,6 @@
 
 
 PG_FUNCTION_INFO_V1(oid_dist);
-Datum		oid_dist(PG_FUNCTION_ARGS);
 Datum
 oid_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_text.c b/contrib/btree_gist/btree_text.c
index 56790a9..2e00cb6 100644
--- a/contrib/btree_gist/btree_text.c
+++ b/contrib/btree_gist/btree_text.c
@@ -19,15 +19,6 @@
 PG_FUNCTION_INFO_V1(gbt_text_penalty);
 PG_FUNCTION_INFO_V1(gbt_text_same);
 
-Datum		gbt_text_compress(PG_FUNCTION_ARGS);
-Datum		gbt_bpchar_compress(PG_FUNCTION_ARGS);
-Datum		gbt_text_union(PG_FUNCTION_ARGS);
-Datum		gbt_text_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_text_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_bpchar_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_text_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_text_same(PG_FUNCTION_ARGS);
-
 
 /* define for comparison */
 
diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c
index a148e5e..e0e3242 100644
--- a/contrib/btree_gist/btree_time.c
+++ b/contrib/btree_gist/btree_time.c
@@ -27,16 +27,6 @@
 PG_FUNCTION_INFO_V1(gbt_time_penalty);
 PG_FUNCTION_INFO_V1(gbt_time_same);
 
-Datum		gbt_time_compress(PG_FUNCTION_ARGS);
-Datum		gbt_timetz_compress(PG_FUNCTION_ARGS);
-Datum		gbt_time_union(PG_FUNCTION_ARGS);
-Datum		gbt_time_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_time_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_time_distance(PG_FUNCTION_ARGS);
-Datum		gbt_timetz_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_time_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_time_same(PG_FUNCTION_ARGS);
-
 
 #ifdef USE_FLOAT8_BYVAL
 #define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
@@ -145,7 +135,6 @@
 
 
 PG_FUNCTION_INFO_V1(time_dist);
-Datum		time_dist(PG_FUNCTION_ARGS);
 Datum
 time_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c
index bf82709..10f325d 100644
--- a/contrib/btree_gist/btree_ts.c
+++ b/contrib/btree_gist/btree_ts.c
@@ -28,17 +28,6 @@
 PG_FUNCTION_INFO_V1(gbt_ts_penalty);
 PG_FUNCTION_INFO_V1(gbt_ts_same);
 
-Datum		gbt_ts_compress(PG_FUNCTION_ARGS);
-Datum		gbt_tstz_compress(PG_FUNCTION_ARGS);
-Datum		gbt_ts_union(PG_FUNCTION_ARGS);
-Datum		gbt_ts_picksplit(PG_FUNCTION_ARGS);
-Datum		gbt_ts_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_ts_distance(PG_FUNCTION_ARGS);
-Datum		gbt_tstz_consistent(PG_FUNCTION_ARGS);
-Datum		gbt_tstz_distance(PG_FUNCTION_ARGS);
-Datum		gbt_ts_penalty(PG_FUNCTION_ARGS);
-Datum		gbt_ts_same(PG_FUNCTION_ARGS);
-
 
 #ifdef USE_FLOAT8_BYVAL
 #define TimestampGetDatumFast(X) TimestampGetDatum(X)
@@ -149,7 +138,6 @@
 
 
 PG_FUNCTION_INFO_V1(ts_dist);
-Datum		ts_dist(PG_FUNCTION_ARGS);
 Datum
 ts_dist(PG_FUNCTION_ARGS)
 {
@@ -178,7 +166,6 @@
 }
 
 PG_FUNCTION_INFO_V1(tstz_dist);
-Datum		tstz_dist(PG_FUNCTION_ARGS);
 Datum
 tstz_dist(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c
index c7c6faa..09b51fc 100644
--- a/contrib/btree_gist/btree_utils_var.c
+++ b/contrib/btree_gist/btree_utils_var.c
@@ -29,7 +29,6 @@
 
 
 PG_FUNCTION_INFO_V1(gbt_var_decompress);
-Datum		gbt_var_decompress(PG_FUNCTION_ARGS);
 
 
 Datum
diff --git a/contrib/chkpass/chkpass.c b/contrib/chkpass/chkpass.c
index 0c9fec0..411f88b 100644
--- a/contrib/chkpass/chkpass.c
+++ b/contrib/chkpass/chkpass.c
@@ -39,18 +39,6 @@
 	char		password[16];
 } chkpass;
 
-/*
- * Various forward declarations:
- */
-
-Datum		chkpass_in(PG_FUNCTION_ARGS);
-Datum		chkpass_out(PG_FUNCTION_ARGS);
-Datum		chkpass_rout(PG_FUNCTION_ARGS);
-
-/* Only equal or not equal make sense */
-Datum		chkpass_eq(PG_FUNCTION_ARGS);
-Datum		chkpass_ne(PG_FUNCTION_ARGS);
-
 
 /* This function checks that the password is a good one
  * It's just a placeholder for now */
diff --git a/contrib/citext/citext.c b/contrib/citext/citext.c
index a584f57..1174b70 100644
--- a/contrib/citext/citext.c
+++ b/contrib/citext/citext.c
@@ -19,16 +19,6 @@
  */
 
 static int32 citextcmp(text *left, text *right, Oid collid);
-extern Datum citext_cmp(PG_FUNCTION_ARGS);
-extern Datum citext_hash(PG_FUNCTION_ARGS);
-extern Datum citext_eq(PG_FUNCTION_ARGS);
-extern Datum citext_ne(PG_FUNCTION_ARGS);
-extern Datum citext_gt(PG_FUNCTION_ARGS);
-extern Datum citext_ge(PG_FUNCTION_ARGS);
-extern Datum citext_lt(PG_FUNCTION_ARGS);
-extern Datum citext_le(PG_FUNCTION_ARGS);
-extern Datum citext_smaller(PG_FUNCTION_ARGS);
-extern Datum citext_larger(PG_FUNCTION_ARGS);
 
 /*
  *		=================
diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
index 9524943..906cc9e 100644
--- a/contrib/cube/cube.c
+++ b/contrib/cube/cube.c
@@ -47,19 +47,6 @@
 PG_FUNCTION_INFO_V1(cube_ur_coord);
 PG_FUNCTION_INFO_V1(cube_subset);
 
-Datum		cube_in(PG_FUNCTION_ARGS);
-Datum		cube_a_f8_f8(PG_FUNCTION_ARGS);
-Datum		cube_a_f8(PG_FUNCTION_ARGS);
-Datum		cube_out(PG_FUNCTION_ARGS);
-Datum		cube_f8(PG_FUNCTION_ARGS);
-Datum		cube_f8_f8(PG_FUNCTION_ARGS);
-Datum		cube_c_f8(PG_FUNCTION_ARGS);
-Datum		cube_c_f8_f8(PG_FUNCTION_ARGS);
-Datum		cube_dim(PG_FUNCTION_ARGS);
-Datum		cube_ll_coord(PG_FUNCTION_ARGS);
-Datum		cube_ur_coord(PG_FUNCTION_ARGS);
-Datum		cube_subset(PG_FUNCTION_ARGS);
-
 /*
 ** GiST support methods
 */
@@ -72,14 +59,6 @@
 PG_FUNCTION_INFO_V1(g_cube_union);
 PG_FUNCTION_INFO_V1(g_cube_same);
 
-Datum		g_cube_consistent(PG_FUNCTION_ARGS);
-Datum		g_cube_compress(PG_FUNCTION_ARGS);
-Datum		g_cube_decompress(PG_FUNCTION_ARGS);
-Datum		g_cube_penalty(PG_FUNCTION_ARGS);
-Datum		g_cube_picksplit(PG_FUNCTION_ARGS);
-Datum		g_cube_union(PG_FUNCTION_ARGS);
-Datum		g_cube_same(PG_FUNCTION_ARGS);
-
 /*
 ** B-tree support functions
 */
@@ -91,14 +70,6 @@
 PG_FUNCTION_INFO_V1(cube_ge);
 PG_FUNCTION_INFO_V1(cube_cmp);
 
-Datum		cube_eq(PG_FUNCTION_ARGS);
-Datum		cube_ne(PG_FUNCTION_ARGS);
-Datum		cube_lt(PG_FUNCTION_ARGS);
-Datum		cube_gt(PG_FUNCTION_ARGS);
-Datum		cube_le(PG_FUNCTION_ARGS);
-Datum		cube_ge(PG_FUNCTION_ARGS);
-Datum		cube_cmp(PG_FUNCTION_ARGS);
-
 /*
 ** R-tree support functions
 */
@@ -110,13 +81,6 @@
 PG_FUNCTION_INFO_V1(cube_inter);
 PG_FUNCTION_INFO_V1(cube_size);
 
-Datum		cube_contains(PG_FUNCTION_ARGS);
-Datum		cube_contained(PG_FUNCTION_ARGS);
-Datum		cube_overlap(PG_FUNCTION_ARGS);
-Datum		cube_union(PG_FUNCTION_ARGS);
-Datum		cube_inter(PG_FUNCTION_ARGS);
-Datum		cube_size(PG_FUNCTION_ARGS);
-
 /*
 ** miscellaneous
 */
@@ -124,10 +88,6 @@
 PG_FUNCTION_INFO_V1(cube_is_point);
 PG_FUNCTION_INFO_V1(cube_enlarge);
 
-Datum		cube_distance(PG_FUNCTION_ARGS);
-Datum		cube_is_point(PG_FUNCTION_ARGS);
-Datum		cube_enlarge(PG_FUNCTION_ARGS);
-
 /*
 ** For internal use only
 */
diff --git a/contrib/dict_int/dict_int.c b/contrib/dict_int/dict_int.c
index b05138e..79067a8 100644
--- a/contrib/dict_int/dict_int.c
+++ b/contrib/dict_int/dict_int.c
@@ -26,10 +26,7 @@
 
 
 PG_FUNCTION_INFO_V1(dintdict_init);
-Datum		dintdict_init(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(dintdict_lexize);
-Datum		dintdict_lexize(PG_FUNCTION_ARGS);
 
 Datum
 dintdict_init(PG_FUNCTION_ARGS)
diff --git a/contrib/dict_xsyn/dict_xsyn.c b/contrib/dict_xsyn/dict_xsyn.c
index f0084a9..1c27565 100644
--- a/contrib/dict_xsyn/dict_xsyn.c
+++ b/contrib/dict_xsyn/dict_xsyn.c
@@ -40,10 +40,7 @@
 
 
 PG_FUNCTION_INFO_V1(dxsyn_init);
-Datum		dxsyn_init(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(dxsyn_lexize);
-Datum		dxsyn_lexize(PG_FUNCTION_ARGS);
 
 static char *
 find_word(char *in, char **end)
diff --git a/contrib/dummy_seclabel/dummy_seclabel.c b/contrib/dummy_seclabel/dummy_seclabel.c
index b5753cc..aeaeafa 100644
--- a/contrib/dummy_seclabel/dummy_seclabel.c
+++ b/contrib/dummy_seclabel/dummy_seclabel.c
@@ -18,9 +18,6 @@
 
 PG_MODULE_MAGIC;
 
-/* Entrypoint of the module */
-void		_PG_init(void);
-
 static void
 dummy_object_relabel(const ObjectAddress *object, const char *seclabel)
 {
@@ -43,6 +40,7 @@
 			 errmsg("'%s' is not a valid security label", seclabel)));
 }
 
+/* Entrypoint of the module */
 void
 _PG_init(void)
 {
diff --git a/contrib/earthdistance/earthdistance.c b/contrib/earthdistance/earthdistance.c
index 2f344a7..eadfce4 100644
--- a/contrib/earthdistance/earthdistance.c
+++ b/contrib/earthdistance/earthdistance.c
@@ -99,8 +99,6 @@
 
 #ifdef USE_FLOAT8_BYVAL
 
-Datum		geo_distance(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(geo_distance);
 
 Datum
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index 5639f4d..47d892d 100644
--- a/contrib/file_fdw/file_fdw.c
+++ b/contrib/file_fdw/file_fdw.c
@@ -102,9 +102,6 @@ struct FileFdwOption
 /*
  * SQL functions
  */
-extern Datum file_fdw_handler(PG_FUNCTION_ARGS);
-extern Datum file_fdw_validator(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(file_fdw_handler);
 PG_FUNCTION_INFO_V1(file_fdw_validator);
 
diff --git a/contrib/fuzzystrmatch/dmetaphone.c b/contrib/fuzzystrmatch/dmetaphone.c
index 19413b4..5001288 100644
--- a/contrib/fuzzystrmatch/dmetaphone.c
+++ b/contrib/fuzzystrmatch/dmetaphone.c
@@ -114,9 +114,6 @@
 #include <stdarg.h>
 #include <assert.h>
 
-extern Datum dmetaphone(PG_FUNCTION_ARGS);
-extern Datum dmetaphone_alt(PG_FUNCTION_ARGS);
-
 /* prototype for the main function we got from the perl module */
 static void DoubleMetaphone(char *, char **);
 
diff --git a/contrib/fuzzystrmatch/fuzzystrmatch.c b/contrib/fuzzystrmatch/fuzzystrmatch.c
index 218eced..7a53d8a 100644
--- a/contrib/fuzzystrmatch/fuzzystrmatch.c
+++ b/contrib/fuzzystrmatch/fuzzystrmatch.c
@@ -45,18 +45,6 @@
 
 PG_MODULE_MAGIC;
 
-
-/*
- * External declarations for exported functions
- */
-extern Datum levenshtein_with_costs(PG_FUNCTION_ARGS);
-extern Datum levenshtein(PG_FUNCTION_ARGS);
-extern Datum levenshtein_less_equal_with_costs(PG_FUNCTION_ARGS);
-extern Datum levenshtein_less_equal(PG_FUNCTION_ARGS);
-extern Datum metaphone(PG_FUNCTION_ARGS);
-extern Datum soundex(PG_FUNCTION_ARGS);
-extern Datum difference(PG_FUNCTION_ARGS);
-
 /*
  * Soundex
  */
diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h
index 23c8a6f..1dbccb4 100644
--- a/contrib/hstore/hstore.h
+++ b/contrib/hstore/hstore.h
@@ -185,7 +185,6 @@ extern Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs);
 #if HSTORE_POLLUTE_NAMESPACE
 #define HSTORE_POLLUTE(newname_,oldname_) \
 	PG_FUNCTION_INFO_V1(oldname_);		  \
-	Datum oldname_(PG_FUNCTION_ARGS);	  \
 	Datum newname_(PG_FUNCTION_ARGS);	  \
 	Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
 	extern int no_such_variable
diff --git a/contrib/hstore/hstore_compat.c b/contrib/hstore/hstore_compat.c
index 6327a8e..6364f03 100644
--- a/contrib/hstore/hstore_compat.c
+++ b/contrib/hstore/hstore_compat.c
@@ -357,7 +357,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_version_diag);
-Datum		hstore_version_diag(PG_FUNCTION_ARGS);
 Datum
 hstore_version_diag(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/hstore/hstore_gin.c b/contrib/hstore/hstore_gin.c
index 2007801..9f2de06 100644
--- a/contrib/hstore/hstore_gin.c
+++ b/contrib/hstore/hstore_gin.c
@@ -22,7 +22,6 @@
 #define NULLFLAG	'N'
 
 PG_FUNCTION_INFO_V1(gin_extract_hstore);
-Datum		gin_extract_hstore(PG_FUNCTION_ARGS);
 
 /* Build an indexable text value */
 static text *
@@ -76,7 +75,6 @@
 }
 
 PG_FUNCTION_INFO_V1(gin_extract_hstore_query);
-Datum		gin_extract_hstore_query(PG_FUNCTION_ARGS);
 
 Datum
 gin_extract_hstore_query(PG_FUNCTION_ARGS)
@@ -148,7 +146,6 @@
 }
 
 PG_FUNCTION_INFO_V1(gin_consistent_hstore);
-Datum		gin_consistent_hstore(PG_FUNCTION_ARGS);
 
 Datum
 gin_consistent_hstore(PG_FUNCTION_ARGS)
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index 9001180..6ad94b5 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -69,11 +69,7 @@
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
 
 PG_FUNCTION_INFO_V1(ghstore_in);
-Datum		ghstore_in(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ghstore_out);
-Datum		ghstore_out(PG_FUNCTION_ARGS);
-
 
 Datum
 ghstore_in(PG_FUNCTION_ARGS)
@@ -97,14 +93,6 @@
 PG_FUNCTION_INFO_V1(ghstore_union);
 PG_FUNCTION_INFO_V1(ghstore_same);
 
-Datum		ghstore_consistent(PG_FUNCTION_ARGS);
-Datum		ghstore_compress(PG_FUNCTION_ARGS);
-Datum		ghstore_decompress(PG_FUNCTION_ARGS);
-Datum		ghstore_penalty(PG_FUNCTION_ARGS);
-Datum		ghstore_picksplit(PG_FUNCTION_ARGS);
-Datum		ghstore_union(PG_FUNCTION_ARGS);
-Datum		ghstore_same(PG_FUNCTION_ARGS);
-
 Datum
 ghstore_compress(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index 973a126..339fae0 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -399,7 +399,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_in);
-Datum		hstore_in(PG_FUNCTION_ARGS);
 Datum
 hstore_in(PG_FUNCTION_ARGS)
 {
@@ -420,7 +419,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_recv);
-Datum		hstore_recv(PG_FUNCTION_ARGS);
 Datum
 hstore_recv(PG_FUNCTION_ARGS)
 {
@@ -479,7 +477,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_from_text);
-Datum		hstore_from_text(PG_FUNCTION_ARGS);
 Datum
 hstore_from_text(PG_FUNCTION_ARGS)
 {
@@ -516,7 +513,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_from_arrays);
-Datum		hstore_from_arrays(PG_FUNCTION_ARGS);
 Datum
 hstore_from_arrays(PG_FUNCTION_ARGS)
 {
@@ -627,7 +623,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_from_array);
-Datum		hstore_from_array(PG_FUNCTION_ARGS);
 Datum
 hstore_from_array(PG_FUNCTION_ARGS)
 {
@@ -734,7 +729,6 @@
 } RecordIOData;
 
 PG_FUNCTION_INFO_V1(hstore_from_record);
-Datum		hstore_from_record(PG_FUNCTION_ARGS);
 Datum
 hstore_from_record(PG_FUNCTION_ARGS)
 {
@@ -887,7 +881,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_populate_record);
-Datum		hstore_populate_record(PG_FUNCTION_ARGS);
 Datum
 hstore_populate_record(PG_FUNCTION_ARGS)
 {
@@ -1100,7 +1093,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_out);
-Datum		hstore_out(PG_FUNCTION_ARGS);
 Datum
 hstore_out(PG_FUNCTION_ARGS)
 {
@@ -1172,7 +1164,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_send);
-Datum		hstore_send(PG_FUNCTION_ARGS);
 Datum
 hstore_send(PG_FUNCTION_ARGS)
 {
@@ -1219,7 +1210,6 @@
  * (think zip codes or phone numbers starting with 0).
  */
 PG_FUNCTION_INFO_V1(hstore_to_json_loose);
-Datum		hstore_to_json_loose(PG_FUNCTION_ARGS);
 Datum
 hstore_to_json_loose(PG_FUNCTION_ARGS)
 {
@@ -1345,7 +1335,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_to_json);
-Datum		hstore_to_json(PG_FUNCTION_ARGS);
 Datum
 hstore_to_json(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
index 45edb04..0b91465 100644
--- a/contrib/hstore/hstore_op.c
+++ b/contrib/hstore/hstore_op.c
@@ -113,7 +113,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_fetchval);
-Datum		hstore_fetchval(PG_FUNCTION_ARGS);
 Datum
 hstore_fetchval(PG_FUNCTION_ARGS)
 {
@@ -135,7 +134,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_exists);
-Datum		hstore_exists(PG_FUNCTION_ARGS);
 Datum
 hstore_exists(PG_FUNCTION_ARGS)
 {
@@ -149,7 +147,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_exists_any);
-Datum		hstore_exists_any(PG_FUNCTION_ARGS);
 Datum
 hstore_exists_any(PG_FUNCTION_ARGS)
 {
@@ -184,7 +181,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_exists_all);
-Datum		hstore_exists_all(PG_FUNCTION_ARGS);
 Datum
 hstore_exists_all(PG_FUNCTION_ARGS)
 {
@@ -219,7 +215,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_defined);
-Datum		hstore_defined(PG_FUNCTION_ARGS);
 Datum
 hstore_defined(PG_FUNCTION_ARGS)
 {
@@ -235,7 +230,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_delete);
-Datum		hstore_delete(PG_FUNCTION_ARGS);
 Datum
 hstore_delete(PG_FUNCTION_ARGS)
 {
@@ -282,7 +276,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_delete_array);
-Datum		hstore_delete_array(PG_FUNCTION_ARGS);
 Datum
 hstore_delete_array(PG_FUNCTION_ARGS)
 {
@@ -362,7 +355,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_delete_hstore);
-Datum		hstore_delete_hstore(PG_FUNCTION_ARGS);
 Datum
 hstore_delete_hstore(PG_FUNCTION_ARGS)
 {
@@ -462,7 +454,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_concat);
-Datum		hstore_concat(PG_FUNCTION_ARGS);
 Datum
 hstore_concat(PG_FUNCTION_ARGS)
 {
@@ -561,7 +552,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_slice_to_array);
-Datum		hstore_slice_to_array(PG_FUNCTION_ARGS);
 Datum
 hstore_slice_to_array(PG_FUNCTION_ARGS)
 {
@@ -625,7 +615,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_slice_to_hstore);
-Datum		hstore_slice_to_hstore(PG_FUNCTION_ARGS);
 Datum
 hstore_slice_to_hstore(PG_FUNCTION_ARGS)
 {
@@ -687,7 +676,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_akeys);
-Datum		hstore_akeys(PG_FUNCTION_ARGS);
 Datum
 hstore_akeys(PG_FUNCTION_ARGS)
 {
@@ -723,7 +711,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_avals);
-Datum		hstore_avals(PG_FUNCTION_ARGS);
 Datum
 hstore_avals(PG_FUNCTION_ARGS)
 {
@@ -820,7 +807,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_to_array);
-Datum		hstore_to_array(PG_FUNCTION_ARGS);
 Datum
 hstore_to_array(PG_FUNCTION_ARGS)
 {
@@ -831,7 +817,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_to_matrix);
-Datum		hstore_to_matrix(PG_FUNCTION_ARGS);
 Datum
 hstore_to_matrix(PG_FUNCTION_ARGS)
 {
@@ -880,7 +865,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_skeys);
-Datum		hstore_skeys(PG_FUNCTION_ARGS);
 Datum
 hstore_skeys(PG_FUNCTION_ARGS)
 {
@@ -915,7 +899,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_svals);
-Datum		hstore_svals(PG_FUNCTION_ARGS);
 Datum
 hstore_svals(PG_FUNCTION_ARGS)
 {
@@ -964,7 +947,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_contains);
-Datum		hstore_contains(PG_FUNCTION_ARGS);
 Datum
 hstore_contains(PG_FUNCTION_ARGS)
 {
@@ -1011,7 +993,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_contained);
-Datum		hstore_contained(PG_FUNCTION_ARGS);
 Datum
 hstore_contained(PG_FUNCTION_ARGS)
 {
@@ -1023,7 +1004,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_each);
-Datum		hstore_each(PG_FUNCTION_ARGS);
 Datum
 hstore_each(PG_FUNCTION_ARGS)
 {
@@ -1085,7 +1065,6 @@
  */
 
 PG_FUNCTION_INFO_V1(hstore_cmp);
-Datum		hstore_cmp(PG_FUNCTION_ARGS);
 Datum
 hstore_cmp(PG_FUNCTION_ARGS)
 {
@@ -1167,7 +1146,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_eq);
-Datum		hstore_eq(PG_FUNCTION_ARGS);
 Datum
 hstore_eq(PG_FUNCTION_ARGS)
 {
@@ -1179,7 +1157,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_ne);
-Datum		hstore_ne(PG_FUNCTION_ARGS);
 Datum
 hstore_ne(PG_FUNCTION_ARGS)
 {
@@ -1191,7 +1168,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_gt);
-Datum		hstore_gt(PG_FUNCTION_ARGS);
 Datum
 hstore_gt(PG_FUNCTION_ARGS)
 {
@@ -1203,7 +1179,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_ge);
-Datum		hstore_ge(PG_FUNCTION_ARGS);
 Datum
 hstore_ge(PG_FUNCTION_ARGS)
 {
@@ -1215,7 +1190,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_lt);
-Datum		hstore_lt(PG_FUNCTION_ARGS);
 Datum
 hstore_lt(PG_FUNCTION_ARGS)
 {
@@ -1227,7 +1201,6 @@
 }
 
 PG_FUNCTION_INFO_V1(hstore_le);
-Datum		hstore_le(PG_FUNCTION_ARGS);
 Datum
 hstore_le(PG_FUNCTION_ARGS)
 {
@@ -1240,7 +1213,6 @@
 
 
 PG_FUNCTION_INFO_V1(hstore_hash);
-Datum		hstore_hash(PG_FUNCTION_ARGS);
 Datum
 hstore_hash(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/intarray/_int_bool.c b/contrib/intarray/_int_bool.c
index d0572af..7c7d702 100644
--- a/contrib/intarray/_int_bool.c
+++ b/contrib/intarray/_int_bool.c
@@ -10,17 +10,9 @@
 
 PG_FUNCTION_INFO_V1(bqarr_in);
 PG_FUNCTION_INFO_V1(bqarr_out);
-Datum		bqarr_in(PG_FUNCTION_ARGS);
-Datum		bqarr_out(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(boolop);
-Datum		boolop(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(rboolop);
-Datum		rboolop(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(querytree);
-Datum		querytree(PG_FUNCTION_ARGS);
 
 
 /* parser's states */
diff --git a/contrib/intarray/_int_gin.c b/contrib/intarray/_int_gin.c
index be71e5c..58352ca 100644
--- a/contrib/intarray/_int_gin.c
+++ b/contrib/intarray/_int_gin.c
@@ -10,7 +10,6 @@
 #include "_int.h"
 
 PG_FUNCTION_INFO_V1(ginint4_queryextract);
-Datum		ginint4_queryextract(PG_FUNCTION_ARGS);
 
 Datum
 ginint4_queryextract(PG_FUNCTION_ARGS)
@@ -108,7 +107,6 @@
 }
 
 PG_FUNCTION_INFO_V1(ginint4_consistent);
-Datum		ginint4_consistent(PG_FUNCTION_ARGS);
 
 Datum
 ginint4_consistent(PG_FUNCTION_ARGS)
diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
index 60de393..d64a81a 100644
--- a/contrib/intarray/_int_gist.c
+++ b/contrib/intarray/_int_gist.c
@@ -21,14 +21,6 @@
 PG_FUNCTION_INFO_V1(g_int_union);
 PG_FUNCTION_INFO_V1(g_int_same);
 
-Datum		g_int_consistent(PG_FUNCTION_ARGS);
-Datum		g_int_compress(PG_FUNCTION_ARGS);
-Datum		g_int_decompress(PG_FUNCTION_ARGS);
-Datum		g_int_penalty(PG_FUNCTION_ARGS);
-Datum		g_int_picksplit(PG_FUNCTION_ARGS);
-Datum		g_int_union(PG_FUNCTION_ARGS);
-Datum		g_int_same(PG_FUNCTION_ARGS);
-
 
 /*
 ** The GiST Consistent method for _intments
diff --git a/contrib/intarray/_int_op.c b/contrib/intarray/_int_op.c
index 4c2aa7a..70849be 100644
--- a/contrib/intarray/_int_op.c
+++ b/contrib/intarray/_int_op.c
@@ -17,14 +17,6 @@
 PG_FUNCTION_INFO_V1(_int_union);
 PG_FUNCTION_INFO_V1(_int_inter);
 
-Datum		_int_different(PG_FUNCTION_ARGS);
-Datum		_int_same(PG_FUNCTION_ARGS);
-Datum		_int_contains(PG_FUNCTION_ARGS);
-Datum		_int_contained(PG_FUNCTION_ARGS);
-Datum		_int_overlap(PG_FUNCTION_ARGS);
-Datum		_int_union(PG_FUNCTION_ARGS);
-Datum		_int_inter(PG_FUNCTION_ARGS);
-
 Datum
 _int_contained(PG_FUNCTION_ARGS)
 {
@@ -188,19 +180,6 @@
 PG_FUNCTION_INFO_V1(intarray_del_elem);
 PG_FUNCTION_INFO_V1(intset_union_elem);
 PG_FUNCTION_INFO_V1(intset_subtract);
-Datum		intset(PG_FUNCTION_ARGS);
-Datum		icount(PG_FUNCTION_ARGS);
-Datum		sort(PG_FUNCTION_ARGS);
-Datum		sort_asc(PG_FUNCTION_ARGS);
-Datum		sort_desc(PG_FUNCTION_ARGS);
-Datum		uniq(PG_FUNCTION_ARGS);
-Datum		idx(PG_FUNCTION_ARGS);
-Datum		subarray(PG_FUNCTION_ARGS);
-Datum		intarray_push_elem(PG_FUNCTION_ARGS);
-Datum		intarray_push_array(PG_FUNCTION_ARGS);
-Datum		intarray_del_elem(PG_FUNCTION_ARGS);
-Datum		intset_union_elem(PG_FUNCTION_ARGS);
-Datum		intset_subtract(PG_FUNCTION_ARGS);
 
 Datum
 intset(PG_FUNCTION_ARGS)
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index 1bad024..235db38 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -20,14 +20,6 @@
 PG_FUNCTION_INFO_V1(g_intbig_union);
 PG_FUNCTION_INFO_V1(g_intbig_same);
 
-Datum		g_intbig_consistent(PG_FUNCTION_ARGS);
-Datum		g_intbig_compress(PG_FUNCTION_ARGS);
-Datum		g_intbig_decompress(PG_FUNCTION_ARGS);
-Datum		g_intbig_penalty(PG_FUNCTION_ARGS);
-Datum		g_intbig_picksplit(PG_FUNCTION_ARGS);
-Datum		g_intbig_union(PG_FUNCTION_ARGS);
-Datum		g_intbig_same(PG_FUNCTION_ARGS);
-
 /* Number of one-bits in an unsigned byte */
 static const uint8 number_of_ones[256] = {
 	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
@@ -49,11 +41,7 @@
 };
 
 PG_FUNCTION_INFO_V1(_intbig_in);
-Datum		_intbig_in(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(_intbig_out);
-Datum		_intbig_out(PG_FUNCTION_ARGS);
-
 
 Datum
 _intbig_in(PG_FUNCTION_ARGS)
diff --git a/contrib/lo/lo.c b/contrib/lo/lo.c
index 757758f..4dee647 100644
--- a/contrib/lo/lo.c
+++ b/contrib/lo/lo.c
@@ -18,10 +18,6 @@
 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
 
 
-/* forward declarations */
-Datum		lo_manage(PG_FUNCTION_ARGS);
-
-
 /*
  * This is the trigger that protects us from orphaned large objects
  */
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 9350715..41be68d 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -14,22 +14,11 @@
 
 
 PG_FUNCTION_INFO_V1(_ltree_compress);
-Datum		_ltree_compress(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(_ltree_same);
-Datum		_ltree_same(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(_ltree_union);
-Datum		_ltree_union(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(_ltree_penalty);
-Datum		_ltree_penalty(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(_ltree_picksplit);
-Datum		_ltree_picksplit(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(_ltree_consistent);
-Datum		_ltree_consistent(PG_FUNCTION_ARGS);
 
 #define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key))
 #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
diff --git a/contrib/ltree/_ltree_op.c b/contrib/ltree/_ltree_op.c
index 1b53af8..44270d4 100644
--- a/contrib/ltree/_ltree_op.c
+++ b/contrib/ltree/_ltree_op.c
@@ -22,20 +22,12 @@
 PG_FUNCTION_INFO_V1(_ltxtq_exec);
 PG_FUNCTION_INFO_V1(_ltxtq_rexec);
 
-Datum		_ltree_r_isparent(PG_FUNCTION_ARGS);
-Datum		_ltree_r_risparent(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(_ltree_extract_isparent);
 PG_FUNCTION_INFO_V1(_ltree_extract_risparent);
 PG_FUNCTION_INFO_V1(_ltq_extract_regex);
 PG_FUNCTION_INFO_V1(_ltxtq_extract_exec);
-Datum		_ltree_extract_isparent(PG_FUNCTION_ARGS);
-Datum		_ltree_extract_risparent(PG_FUNCTION_ARGS);
-Datum		_ltq_extract_regex(PG_FUNCTION_ARGS);
-Datum		_ltxtq_extract_exec(PG_FUNCTION_ARGS);
 
 PG_FUNCTION_INFO_V1(_lca);
-Datum		_lca(PG_FUNCTION_ARGS);
 
 typedef Datum (*PGCALL2) (PG_FUNCTION_ARGS);
 
diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c
index 5324c65..2d89f1a 100644
--- a/contrib/ltree/ltree_gist.c
+++ b/contrib/ltree/ltree_gist.c
@@ -13,10 +13,7 @@
 #define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
 
 PG_FUNCTION_INFO_V1(ltree_gist_in);
-Datum		ltree_gist_in(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_gist_out);
-Datum		ltree_gist_out(PG_FUNCTION_ARGS);
 
 Datum
 ltree_gist_in(PG_FUNCTION_ARGS)
@@ -37,25 +34,12 @@
 }
 
 PG_FUNCTION_INFO_V1(ltree_compress);
-Datum		ltree_compress(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_decompress);
-Datum		ltree_decompress(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_same);
-Datum		ltree_same(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_union);
-Datum		ltree_union(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_penalty);
-Datum		ltree_penalty(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_picksplit);
-Datum		ltree_picksplit(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_consistent);
-Datum		ltree_consistent(PG_FUNCTION_ARGS);
 
 #define ISEQ(a,b)	( (a)->numlevel == (b)->numlevel && ltree_compare(a,b)==0 )
 #define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key))
diff --git a/contrib/ltree/ltree_io.c b/contrib/ltree/ltree_io.c
index 3e88b81..1980982 100644
--- a/contrib/ltree/ltree_io.c
+++ b/contrib/ltree/ltree_io.c
@@ -11,16 +11,9 @@
 #include "crc32.h"
 
 PG_FUNCTION_INFO_V1(ltree_in);
-Datum		ltree_in(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltree_out);
-Datum		ltree_out(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(lquery_in);
-Datum		lquery_in(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(lquery_out);
-Datum		lquery_out(PG_FUNCTION_ARGS);
 
 
 #define UNCHAR ereport(ERROR, \
diff --git a/contrib/ltree/ltree_op.c b/contrib/ltree/ltree_op.c
index 25b6db1..992106f 100644
--- a/contrib/ltree/ltree_op.c
+++ b/contrib/ltree/ltree_op.c
@@ -38,25 +38,6 @@
 PG_FUNCTION_INFO_V1(text2ltree);
 PG_FUNCTION_INFO_V1(ltreeparentsel);
 
-Datum		ltree_cmp(PG_FUNCTION_ARGS);
-Datum		ltree_lt(PG_FUNCTION_ARGS);
-Datum		ltree_le(PG_FUNCTION_ARGS);
-Datum		ltree_eq(PG_FUNCTION_ARGS);
-Datum		ltree_ne(PG_FUNCTION_ARGS);
-Datum		ltree_ge(PG_FUNCTION_ARGS);
-Datum		ltree_gt(PG_FUNCTION_ARGS);
-Datum		nlevel(PG_FUNCTION_ARGS);
-Datum		subltree(PG_FUNCTION_ARGS);
-Datum		subpath(PG_FUNCTION_ARGS);
-Datum		ltree_index(PG_FUNCTION_ARGS);
-Datum		ltree_addltree(PG_FUNCTION_ARGS);
-Datum		ltree_addtext(PG_FUNCTION_ARGS);
-Datum		ltree_textadd(PG_FUNCTION_ARGS);
-Datum		lca(PG_FUNCTION_ARGS);
-Datum		ltree2text(PG_FUNCTION_ARGS);
-Datum		text2ltree(PG_FUNCTION_ARGS);
-Datum		ltreeparentsel(PG_FUNCTION_ARGS);
-
 int
 ltree_compare(const ltree *a, const ltree *b)
 {
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index 583ff2a..ea669b5 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -11,10 +11,7 @@
 #include "ltree.h"
 
 PG_FUNCTION_INFO_V1(ltxtq_in);
-Datum		ltxtq_in(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(ltxtq_out);
-Datum		ltxtq_out(PG_FUNCTION_ARGS);
 
 
 /* parser's states */
diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c
index e3f3c28..c1e83f3 100644
--- a/contrib/pageinspect/btreefuncs.c
+++ b/contrib/pageinspect/btreefuncs.c
@@ -35,10 +35,6 @@
 #include "utils/rel.h"
 
 
-extern Datum bt_metap(PG_FUNCTION_ARGS);
-extern Datum bt_page_items(PG_FUNCTION_ARGS);
-extern Datum bt_page_stats(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(bt_metap);
 PG_FUNCTION_INFO_V1(bt_page_items);
 PG_FUNCTION_INFO_V1(bt_page_stats);
diff --git a/contrib/pageinspect/fsmfuncs.c b/contrib/pageinspect/fsmfuncs.c
index bdae0a5..8c19604 100644
--- a/contrib/pageinspect/fsmfuncs.c
+++ b/contrib/pageinspect/fsmfuncs.c
@@ -25,8 +25,6 @@
 #include "storage/fsm_internals.h"
 #include "utils/builtins.h"
 
-Datum		fsm_page_contents(PG_FUNCTION_ARGS);
-
 /*
  * Dumps the contents of a FSM page.
  */
diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c
index 5e53255..dedc8fe 100644
--- a/contrib/pageinspect/heapfuncs.c
+++ b/contrib/pageinspect/heapfuncs.c
@@ -30,8 +30,6 @@
 #include "utils/builtins.h"
 #include "miscadmin.h"
 
-Datum		heap_page_items(PG_FUNCTION_ARGS);
-
 
 /*
  * bits_to_text
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index ff541ed..1f22339 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -26,10 +26,6 @@
 
 PG_MODULE_MAGIC;
 
-Datum		get_raw_page(PG_FUNCTION_ARGS);
-Datum		get_raw_page_fork(PG_FUNCTION_ARGS);
-Datum		page_header(PG_FUNCTION_ARGS);
-
 static bytea *get_raw_page_internal(text *relname, ForkNumber forknum,
 					  BlockNumber blkno);
 
diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c
index 405896d..b2b750f 100644
--- a/contrib/passwordcheck/passwordcheck.c
+++ b/contrib/passwordcheck/passwordcheck.c
@@ -30,8 +30,6 @@
 /* passwords shorter than this will be rejected */
 #define MIN_PWD_LENGTH 8
 
-extern void _PG_init(void);
-
 /*
  * check_password
  *
diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c
index dbf8030..9c1a9e8 100644
--- a/contrib/pg_buffercache/pg_buffercache_pages.c
+++ b/contrib/pg_buffercache/pg_buffercache_pages.c
@@ -19,8 +19,6 @@
 
 PG_MODULE_MAGIC;
 
-Datum		pg_buffercache_pages(PG_FUNCTION_ARGS);
-
 
 /*
  * Record structure holding the to be exposed cache data.
diff --git a/contrib/pg_freespacemap/pg_freespacemap.c b/contrib/pg_freespacemap/pg_freespacemap.c
index f6f7d2e..7805345 100644
--- a/contrib/pg_freespacemap/pg_freespacemap.c
+++ b/contrib/pg_freespacemap/pg_freespacemap.c
@@ -14,8 +14,6 @@
 
 PG_MODULE_MAGIC;
 
-Datum		pg_freespace(PG_FUNCTION_ARGS);
-
 /*
  * Returns the amount of free space on a given page, according to the
  * free space map.
diff --git a/contrib/pg_prewarm/pg_prewarm.c b/contrib/pg_prewarm/pg_prewarm.c
index f7e112a..d50726d 100644
--- a/contrib/pg_prewarm/pg_prewarm.c
+++ b/contrib/pg_prewarm/pg_prewarm.c
@@ -28,8 +28,6 @@
 
 PG_MODULE_MAGIC;
 
-extern Datum pg_prewarm(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(pg_prewarm);
 
 typedef enum
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 2f069b7..df43431 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -233,12 +233,6 @@
 
 /*---- Function declarations ----*/
 
-void		_PG_init(void);
-void		_PG_fini(void);
-
-Datum		pg_stat_statements_reset(PG_FUNCTION_ARGS);
-Datum		pg_stat_statements(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(pg_stat_statements_reset);
 PG_FUNCTION_INFO_V1(pg_stat_statements);
 
diff --git a/contrib/pg_trgm/trgm_gin.c b/contrib/pg_trgm/trgm_gin.c
index 1fbbd9c..ac18c7b 100644
--- a/contrib/pg_trgm/trgm_gin.c
+++ b/contrib/pg_trgm/trgm_gin.c
@@ -10,16 +10,9 @@
 
 
 PG_FUNCTION_INFO_V1(gin_extract_trgm);
-Datum		gin_extract_trgm(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gin_extract_value_trgm);
-Datum		gin_extract_value_trgm(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gin_extract_query_trgm);
-Datum		gin_extract_query_trgm(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gin_trgm_consistent);
-Datum		gin_trgm_consistent(PG_FUNCTION_ARGS);
 
 /*
  * This function can only be called if a pre-9.1 version of the GIN operator
diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c
index c572d0f..ede969f 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -28,34 +28,15 @@
 
 
 PG_FUNCTION_INFO_V1(gtrgm_in);
-Datum		gtrgm_in(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_out);
-Datum		gtrgm_out(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_compress);
-Datum		gtrgm_compress(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_decompress);
-Datum		gtrgm_decompress(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_consistent);
-Datum		gtrgm_consistent(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_distance);
-Datum		gtrgm_distance(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_union);
-Datum		gtrgm_union(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_same);
-Datum		gtrgm_same(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_penalty);
-Datum		gtrgm_penalty(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(gtrgm_picksplit);
-Datum		gtrgm_picksplit(PG_FUNCTION_ARGS);
 
 /* Number of one-bits in an unsigned byte */
 static const uint8 number_of_ones[256] = {
diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c
index dadbeea..c385e09 100644
--- a/contrib/pg_trgm/trgm_op.c
+++ b/contrib/pg_trgm/trgm_op.c
@@ -17,22 +17,11 @@
 float4		trgm_limit = 0.3f;
 
 PG_FUNCTION_INFO_V1(set_limit);
-Datum		set_limit(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(show_limit);
-Datum		show_limit(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(show_trgm);
-Datum		show_trgm(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(similarity);
-Datum		similarity(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(similarity_dist);
-Datum		similarity_dist(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(similarity_op);
-Datum		similarity_op(PG_FUNCTION_ARGS);
 
 
 Datum
diff --git a/contrib/pg_upgrade_support/pg_upgrade_support.c b/contrib/pg_upgrade_support/pg_upgrade_support.c
index 77a2c1f..edd41d0 100644
--- a/contrib/pg_upgrade_support/pg_upgrade_support.c
+++ b/contrib/pg_upgrade_support/pg_upgrade_support.c
@@ -25,19 +25,6 @@
 PG_MODULE_MAGIC;
 #endif
 
-Datum		set_next_pg_type_oid(PG_FUNCTION_ARGS);
-Datum		set_next_array_pg_type_oid(PG_FUNCTION_ARGS);
-Datum		set_next_toast_pg_type_oid(PG_FUNCTION_ARGS);
-
-Datum		set_next_heap_pg_class_oid(PG_FUNCTION_ARGS);
-Datum		set_next_index_pg_class_oid(PG_FUNCTION_ARGS);
-Datum		set_next_toast_pg_class_oid(PG_FUNCTION_ARGS);
-
-Datum		set_next_pg_enum_oid(PG_FUNCTION_ARGS);
-Datum		set_next_pg_authid_oid(PG_FUNCTION_ARGS);
-
-Datum		create_empty_extension(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(set_next_pg_type_oid);
 PG_FUNCTION_INFO_V1(set_next_array_pg_type_oid);
 PG_FUNCTION_INFO_V1(set_next_toast_pg_type_oid);
diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c
index d4eec03..1b0e24a 100644
--- a/contrib/pgcrypto/pgp-pgsql.c
+++ b/contrib/pgcrypto/pgp-pgsql.c
@@ -41,23 +41,6 @@
 /*
  * public functions
  */
-Datum		pgp_sym_encrypt_text(PG_FUNCTION_ARGS);
-Datum		pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS);
-Datum		pgp_sym_decrypt_text(PG_FUNCTION_ARGS);
-Datum		pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS);
-
-Datum		pgp_pub_encrypt_text(PG_FUNCTION_ARGS);
-Datum		pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS);
-Datum		pgp_pub_decrypt_text(PG_FUNCTION_ARGS);
-Datum		pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS);
-
-Datum		pgp_key_id_w(PG_FUNCTION_ARGS);
-
-Datum		pg_armor(PG_FUNCTION_ARGS);
-Datum		pg_dearmor(PG_FUNCTION_ARGS);
-
-/* function headers */
-
 PG_FUNCTION_INFO_V1(pgp_sym_encrypt_bytea);
 PG_FUNCTION_INFO_V1(pgp_sym_encrypt_text);
 PG_FUNCTION_INFO_V1(pgp_sym_decrypt_bytea);
diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c
index 636ff05..15d9704 100644
--- a/contrib/pgrowlocks/pgrowlocks.c
+++ b/contrib/pgrowlocks/pgrowlocks.c
@@ -43,8 +43,6 @@
 
 PG_FUNCTION_INFO_V1(pgrowlocks);
 
-extern Datum pgrowlocks(PG_FUNCTION_ARGS);
-
 /* ----------
  * pgrowlocks:
  * returns tids of rows being locked
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c
index 8939b78..f617d99 100644
--- a/contrib/pgstattuple/pgstatindex.c
+++ b/contrib/pgstattuple/pgstatindex.c
@@ -47,12 +47,6 @@
  * Those functions which have text-type input arg will be deprecated
  * in the future release.
  */
-extern Datum pgstatindex(PG_FUNCTION_ARGS);
-extern Datum pgstatindexbyid(PG_FUNCTION_ARGS);
-extern Datum pg_relpages(PG_FUNCTION_ARGS);
-extern Datum pg_relpagesbyid(PG_FUNCTION_ARGS);
-extern Datum pgstatginindex(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(pgstatindex);
 PG_FUNCTION_INFO_V1(pgstatindexbyid);
 PG_FUNCTION_INFO_V1(pg_relpages);
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index f9ba0a6..16b437b 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -42,9 +42,6 @@
 PG_FUNCTION_INFO_V1(pgstattuple);
 PG_FUNCTION_INFO_V1(pgstattuplebyid);
 
-extern Datum pgstattuple(PG_FUNCTION_ARGS);
-extern Datum pgstattuplebyid(PG_FUNCTION_ARGS);
-
 /*
  * struct pgstattuple_type
  *
diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c
index 8ba2be5..6f98dfc 100644
--- a/contrib/postgres_fdw/option.c
+++ b/contrib/postgres_fdw/option.c
@@ -57,8 +57,6 @@
  *
  * Raise an ERROR if the option or its value is considered invalid.
  */
-extern Datum postgres_fdw_validator(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(postgres_fdw_validator);
 
 Datum
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index ae3ab00..1c70d32 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -228,8 +228,6 @@ enum FdwModifyPrivateIndex
 /*
  * SQL functions
  */
-extern Datum postgres_fdw_handler(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(postgres_fdw_handler);
 
 /*
diff --git a/contrib/seg/seg.c b/contrib/seg/seg.c
index 0cf9853..0807e23 100644
--- a/contrib/seg/seg.c
+++ b/contrib/seg/seg.c
@@ -52,13 +52,6 @@
 PG_FUNCTION_INFO_V1(seg_upper);
 PG_FUNCTION_INFO_V1(seg_center);
 
-Datum		seg_in(PG_FUNCTION_ARGS);
-Datum		seg_out(PG_FUNCTION_ARGS);
-Datum		seg_size(PG_FUNCTION_ARGS);
-Datum		seg_lower(PG_FUNCTION_ARGS);
-Datum		seg_upper(PG_FUNCTION_ARGS);
-Datum		seg_center(PG_FUNCTION_ARGS);
-
 /*
 ** GiST support methods
 */
diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c
index 16e72b2..bf41dc6 100644
--- a/contrib/sepgsql/hooks.c
+++ b/contrib/sepgsql/hooks.c
@@ -28,11 +28,6 @@
 PG_MODULE_MAGIC;
 
 /*
- * Declarations
- */
-void		_PG_init(void);
-
-/*
  * Saved hook entries (if stacked)
  */
 static object_access_hook_type next_object_access_hook = NULL;
diff --git a/contrib/spi/autoinc.c b/contrib/spi/autoinc.c
index 54bbc43..41eae4f 100644
--- a/contrib/spi/autoinc.c
+++ b/contrib/spi/autoinc.c
@@ -12,8 +12,6 @@
 
 PG_MODULE_MAGIC;
 
-extern Datum autoinc(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(autoinc);
 
 Datum
diff --git a/contrib/spi/insert_username.c b/contrib/spi/insert_username.c
index 3bc51c7..8752078 100644
--- a/contrib/spi/insert_username.c
+++ b/contrib/spi/insert_username.c
@@ -17,8 +17,6 @@
 
 PG_MODULE_MAGIC;
 
-extern Datum insert_username(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(insert_username);
 
 Datum
diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c
index 2ec96540..c6d33b7 100644
--- a/contrib/spi/moddatetime.c
+++ b/contrib/spi/moddatetime.c
@@ -23,8 +23,6 @@
 
 PG_MODULE_MAGIC;
 
-extern Datum moddatetime(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(moddatetime);
 
 Datum
diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c
index fbed300..2602210 100644
--- a/contrib/spi/refint.c
+++ b/contrib/spi/refint.c
@@ -16,10 +16,6 @@
 
 PG_MODULE_MAGIC;
 
-extern Datum check_primary_key(PG_FUNCTION_ARGS);
-extern Datum check_foreign_key(PG_FUNCTION_ARGS);
-
-
 typedef struct
 {
 	char	   *ident;
diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c
index fa74dab..a97eaa1 100644
--- a/contrib/spi/timetravel.c
+++ b/contrib/spi/timetravel.c
@@ -22,9 +22,6 @@
 PG_MODULE_MAGIC;
 
 /* AbsoluteTime currabstime(void); */
-Datum		timetravel(PG_FUNCTION_ARGS);
-Datum		set_timetravel(PG_FUNCTION_ARGS);
-Datum		get_timetravel(PG_FUNCTION_ARGS);
 
 typedef struct
 {
diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c
index 7a58470..dc0f0a5 100644
--- a/contrib/sslinfo/sslinfo.c
+++ b/contrib/sslinfo/sslinfo.c
@@ -22,15 +22,6 @@
 PG_MODULE_MAGIC;
 
 
-Datum		ssl_is_used(PG_FUNCTION_ARGS);
-Datum		ssl_version(PG_FUNCTION_ARGS);
-Datum		ssl_cipher(PG_FUNCTION_ARGS);
-Datum		ssl_client_cert_present(PG_FUNCTION_ARGS);
-Datum		ssl_client_serial(PG_FUNCTION_ARGS);
-Datum		ssl_client_dn_field(PG_FUNCTION_ARGS);
-Datum		ssl_issuer_field(PG_FUNCTION_ARGS);
-Datum		ssl_client_dn(PG_FUNCTION_ARGS);
-Datum		ssl_issuer_dn(PG_FUNCTION_ARGS);
 Datum		X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
 Datum		X509_NAME_to_text(X509_NAME *name);
 Datum		ASN1_STRING_to_text(ASN1_STRING *str);
diff --git a/contrib/tcn/tcn.c b/contrib/tcn/tcn.c
index 701ae82..b472096 100644
--- a/contrib/tcn/tcn.c
+++ b/contrib/tcn/tcn.c
@@ -27,10 +27,6 @@
 PG_MODULE_MAGIC;
 
 
-/* forward declarations */
-Datum		triggered_change_notification(PG_FUNCTION_ARGS);
-
-
 /*
  * Copy from s (for source) to r (for result), wrapping with q (quote)
  * characters and doubling any quote characters found.
diff --git a/contrib/test_parser/test_parser.c b/contrib/test_parser/test_parser.c
index 932d924..c41d1eb 100644
--- a/contrib/test_parser/test_parser.c
+++ b/contrib/test_parser/test_parser.c
@@ -38,23 +38,13 @@
 } LexDescr;
 
 /*
- * prototypes
+ * functions
  */
 PG_FUNCTION_INFO_V1(testprs_start);
-Datum		testprs_start(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(testprs_getlexeme);
-Datum		testprs_getlexeme(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(testprs_end);
-Datum		testprs_end(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(testprs_lextype);
-Datum		testprs_lextype(PG_FUNCTION_ARGS);
 
-/*
- * functions
- */
 Datum
 testprs_start(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/tsearch2/tsearch2.c b/contrib/tsearch2/tsearch2.c
index e508b43..bd30d87 100644
--- a/contrib/tsearch2/tsearch2.c
+++ b/contrib/tsearch2/tsearch2.c
@@ -45,7 +45,7 @@
 					 CStringGetDatum(text_to_cstring(text))))
 
 #define UNSUPPORTED_FUNCTION(name)						\
-	Datum name(PG_FUNCTION_ARGS);						\
+	PG_FUNCTION_INFO_V1(name);							\
 	Datum												\
 	name(PG_FUNCTION_ARGS)								\
 	{													\
@@ -57,30 +57,11 @@
 		/* keep compiler quiet */						\
 		PG_RETURN_NULL();								\
 	}													\
-	PG_FUNCTION_INFO_V1(name)
+	extern int no_such_variable
 
 static Oid	GetCurrentDict(void);
 static Oid	GetCurrentParser(void);
 
-Datum		tsa_lexize_byname(PG_FUNCTION_ARGS);
-Datum		tsa_lexize_bycurrent(PG_FUNCTION_ARGS);
-Datum		tsa_set_curdict(PG_FUNCTION_ARGS);
-Datum		tsa_set_curdict_byname(PG_FUNCTION_ARGS);
-Datum		tsa_token_type_current(PG_FUNCTION_ARGS);
-Datum		tsa_set_curprs(PG_FUNCTION_ARGS);
-Datum		tsa_set_curprs_byname(PG_FUNCTION_ARGS);
-Datum		tsa_parse_current(PG_FUNCTION_ARGS);
-Datum		tsa_set_curcfg(PG_FUNCTION_ARGS);
-Datum		tsa_set_curcfg_byname(PG_FUNCTION_ARGS);
-Datum		tsa_to_tsvector_name(PG_FUNCTION_ARGS);
-Datum		tsa_to_tsquery_name(PG_FUNCTION_ARGS);
-Datum		tsa_plainto_tsquery_name(PG_FUNCTION_ARGS);
-Datum		tsa_headline_byname(PG_FUNCTION_ARGS);
-Datum		tsa_ts_stat(PG_FUNCTION_ARGS);
-Datum		tsa_tsearch2(PG_FUNCTION_ARGS);
-Datum		tsa_rewrite_accum(PG_FUNCTION_ARGS);
-Datum		tsa_rewrite_finish(PG_FUNCTION_ARGS);
-
 PG_FUNCTION_INFO_V1(tsa_lexize_byname);
 PG_FUNCTION_INFO_V1(tsa_lexize_bycurrent);
 PG_FUNCTION_INFO_V1(tsa_set_curdict);
diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c
index 10cc1e3..a337df6 100644
--- a/contrib/unaccent/unaccent.c
+++ b/contrib/unaccent/unaccent.c
@@ -216,7 +216,6 @@
 }
 
 PG_FUNCTION_INFO_V1(unaccent_init);
-Datum		unaccent_init(PG_FUNCTION_ARGS);
 Datum
 unaccent_init(PG_FUNCTION_ARGS)
 {
@@ -258,7 +257,6 @@
 }
 
 PG_FUNCTION_INFO_V1(unaccent_lexize);
-Datum		unaccent_lexize(PG_FUNCTION_ARGS);
 Datum
 unaccent_lexize(PG_FUNCTION_ARGS)
 {
@@ -313,7 +311,6 @@
  * Function-like wrapper for dictionary
  */
 PG_FUNCTION_INFO_V1(unaccent_dict);
-Datum		unaccent_dict(PG_FUNCTION_ARGS);
 Datum
 unaccent_dict(PG_FUNCTION_ARGS)
 {
diff --git a/contrib/uuid-ossp/uuid-ossp.c b/contrib/uuid-ossp/uuid-ossp.c
index 8e80c24..c9ce12f 100644
--- a/contrib/uuid-ossp/uuid-ossp.c
+++ b/contrib/uuid-ossp/uuid-ossp.c
@@ -38,20 +38,6 @@
 
 PG_MODULE_MAGIC;
 
-
-Datum		uuid_nil(PG_FUNCTION_ARGS);
-Datum		uuid_ns_dns(PG_FUNCTION_ARGS);
-Datum		uuid_ns_url(PG_FUNCTION_ARGS);
-Datum		uuid_ns_oid(PG_FUNCTION_ARGS);
-Datum		uuid_ns_x500(PG_FUNCTION_ARGS);
-
-Datum		uuid_generate_v1(PG_FUNCTION_ARGS);
-Datum		uuid_generate_v1mc(PG_FUNCTION_ARGS);
-Datum		uuid_generate_v3(PG_FUNCTION_ARGS);
-Datum		uuid_generate_v4(PG_FUNCTION_ARGS);
-Datum		uuid_generate_v5(PG_FUNCTION_ARGS);
-
-
 PG_FUNCTION_INFO_V1(uuid_nil);
 PG_FUNCTION_INFO_V1(uuid_ns_dns);
 PG_FUNCTION_INFO_V1(uuid_ns_url);
diff --git a/contrib/worker_spi/worker_spi.c b/contrib/worker_spi/worker_spi.c
index 23ace7a..c32d807 100644
--- a/contrib/worker_spi/worker_spi.c
+++ b/contrib/worker_spi/worker_spi.c
@@ -44,9 +44,7 @@
 PG_MODULE_MAGIC;
 PG_FUNCTION_INFO_V1(worker_spi_launch);
 
-void		_PG_init(void);
 void		worker_spi_main(Datum);
-Datum		worker_spi_launch(PG_FUNCTION_ARGS);
 
 /* flags set by signal handlers */
 static volatile sig_atomic_t got_sighup = false;
diff --git a/contrib/xml2/xpath.c b/contrib/xml2/xpath.c
index 41cb98d..156ed2f 100644
--- a/contrib/xml2/xpath.c
+++ b/contrib/xml2/xpath.c
@@ -26,17 +26,6 @@
 
 PG_MODULE_MAGIC;
 
-/* externally accessible functions */
-
-Datum		xml_is_well_formed(PG_FUNCTION_ARGS);
-Datum		xml_encode_special_chars(PG_FUNCTION_ARGS);
-Datum		xpath_nodeset(PG_FUNCTION_ARGS);
-Datum		xpath_string(PG_FUNCTION_ARGS);
-Datum		xpath_number(PG_FUNCTION_ARGS);
-Datum		xpath_bool(PG_FUNCTION_ARGS);
-Datum		xpath_list(PG_FUNCTION_ARGS);
-Datum		xpath_table(PG_FUNCTION_ARGS);
-
 /* exported for use by xslt_proc.c */
 
 PgXmlErrorContext *pgxml_parser_init(PgXmlStrictness strictness);
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 2f24b39..9f13787 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -32,10 +32,6 @@
 #endif   /* USE_LIBXSLT */
 
 
-/* externally accessible functions */
-
-Datum		xslt_process(PG_FUNCTION_ARGS);
-
 #ifdef USE_LIBXSLT
 
 /* declarations to come from xpath.c */
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 2e057b8..abd4afa 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -37,8 +37,6 @@
 
 PG_MODULE_MAGIC;
 
-void		_PG_init(void);
-
 /* Current connection to the primary, if any */
 static PGconn *streamConn = NULL;
 
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 455c089..56430be 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -348,6 +348,7 @@ 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); \
 const Pg_finfo_record * \
 CppConcat(pg_finfo_,funcname) (void) \
@@ -357,6 +358,9 @@ CppConcat(pg_finfo_,funcname) (void) \
 } \
 extern int no_such_variable
 
+void _PG_init(void);
+void _PG_fini(void);
+
 
 /*-------------------------------------------------------------------------
  *		Support for verifying backend compatibility of loaded modules
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index a81c185..5a97fbf 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -240,14 +240,6 @@
 /**********************************************************************
  * Forward declarations
  **********************************************************************/
-Datum		plperl_call_handler(PG_FUNCTION_ARGS);
-Datum		plperl_inline_handler(PG_FUNCTION_ARGS);
-Datum		plperl_validator(PG_FUNCTION_ARGS);
-Datum		plperlu_call_handler(PG_FUNCTION_ARGS);
-Datum		plperlu_inline_handler(PG_FUNCTION_ARGS);
-Datum		plperlu_validator(PG_FUNCTION_ARGS);
-void		_PG_init(void);
-
 static PerlInterpreter *plperl_init_interp(void);
 static void plperl_destroy_interp(PerlInterpreter **);
 static void plperl_fini(int code, Datum arg);
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index f3d1283..eb1d661 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -934,15 +934,6 @@ extern int	plpgsql_add_initdatums(int **varnos);
 extern void plpgsql_HashTableInit(void);
 
 /* ----------
- * Functions in pl_handler.c
- * ----------
- */
-extern void _PG_init(void);
-extern Datum plpgsql_call_handler(PG_FUNCTION_ARGS);
-extern Datum plpgsql_inline_handler(PG_FUNCTION_ARGS);
-extern Datum plpgsql_validator(PG_FUNCTION_ARGS);
-
-/* ----------
  * Functions in pl_exec.c
  * ----------
  */
diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
index 0dad843..5b2777f 100644
--- a/src/pl/plpython/plpy_main.c
+++ b/src/pl/plpython/plpy_main.c
@@ -39,18 +39,6 @@
 #define plpython_inline_handler plpython3_inline_handler
 #endif
 
-extern void _PG_init(void);
-extern Datum plpython_validator(PG_FUNCTION_ARGS);
-extern Datum plpython_call_handler(PG_FUNCTION_ARGS);
-extern Datum plpython_inline_handler(PG_FUNCTION_ARGS);
-
-#if PY_MAJOR_VERSION < 3
-/* Define aliases plpython2_call_handler etc */
-extern Datum plpython2_validator(PG_FUNCTION_ARGS);
-extern Datum plpython2_call_handler(PG_FUNCTION_ARGS);
-extern Datum plpython2_inline_handler(PG_FUNCTION_ARGS);
-#endif
-
 PG_MODULE_MAGIC;
 
 PG_FUNCTION_INFO_V1(plpython_validator);
@@ -58,6 +46,7 @@
 PG_FUNCTION_INFO_V1(plpython_inline_handler);
 
 #if PY_MAJOR_VERSION < 3
+/* Define aliases plpython2_call_handler etc */
 PG_FUNCTION_INFO_V1(plpython2_validator);
 PG_FUNCTION_INFO_V1(plpython2_call_handler);
 PG_FUNCTION_INFO_V1(plpython2_inline_handler);
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 0538038..ed68d3f 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -188,10 +188,6 @@
 /**********************************************************************
  * Forward declarations
  **********************************************************************/
-Datum		pltcl_call_handler(PG_FUNCTION_ARGS);
-Datum		pltclu_call_handler(PG_FUNCTION_ARGS);
-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);
 static void pltcl_init_load_unknown(Tcl_Interp *interp);
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index 4dbe314..c25bf6e 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -28,18 +28,10 @@
 #define RDELIM			')'
 #define DELIM			','
 
-extern Datum regress_dist_ptpath(PG_FUNCTION_ARGS);
-extern Datum regress_path_dist(PG_FUNCTION_ARGS);
 extern PATH *poly2path(POLYGON *poly);
-extern Datum interpt_pp(PG_FUNCTION_ARGS);
 extern void regress_lseg_construct(LSEG *lseg, Point *pt1, Point *pt2);
-extern Datum overpaid(PG_FUNCTION_ARGS);
-extern Datum boxarea(PG_FUNCTION_ARGS);
 extern char *reverse_name(char *string);
 extern int	oldstyle_length(int n, text *t);
-extern Datum int44in(PG_FUNCTION_ARGS);
-extern Datum int44out(PG_FUNCTION_ARGS);
-extern Datum make_tuple_indirect(PG_FUNCTION_ARGS);
 
 #ifdef PG_MODULE_MAGIC
 PG_MODULE_MAGIC;
@@ -236,7 +228,6 @@
 
 WIDGET	   *widget_in(char *str);
 char	   *widget_out(WIDGET * widget);
-extern Datum pt_in_widget(PG_FUNCTION_ARGS);
 
 #define NARGS	3
 
@@ -341,7 +332,6 @@
 static int	fd17a_level = 0;
 static bool fd17b_recursion = true;
 static bool fd17a_recursion = true;
-extern Datum funny_dup17(PG_FUNCTION_ARGS);
 
 PG_FUNCTION_INFO_V1(funny_dup17);
 
@@ -453,9 +443,6 @@
 	return PointerGetDatum(tuple);
 }
 
-extern Datum ttdummy(PG_FUNCTION_ARGS);
-extern Datum set_ttdummy(PG_FUNCTION_ARGS);
-
 #define TTDUMMY_INFINITY	999999
 
 static SPIPlanPtr splan = NULL;
-- 
1.8.5.1

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#1)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Peter Eisentraut <peter_e@gmx.net> writes:

This idea has appeared at least twice now, in
/messages/by-id/1386301050.2743.17.camel@vanquo.pezone.net and /messages/by-id/52D25AA2.50108@2ndquadrant.com . Even if it doesn't help with Windows issues, as discussed in the second thread, it still seems like a win for reducing boilerplate and accidental compiler warnings. So here is a patch for consideration.

Meh. I don't think that extension authors are really going to appreciate
changing from "thou shalt declare all thy functions" to "thou shalt
declare none of them". If the code were such that it wouldn't matter
whether a manual declaration were provided too, then that wouldn't be a
big deal --- but you seem to be ignoring the discussion in the one thread
cited above about PGDLLEXPORT.

Also, surely it is 100% bogus for fmgr.h to be declaring functions not
actually provided by fmgr.c. That will create about as many failure
modes as it removes, not to mention being conceptually wrong.

The latter point might possibly be worked around by putting the externs
for _PG_init and _PG_fini into the PG_MODULE_MAGIC macro, though I'm not
sure how well that works for multi-source-file extensions; the init
functions might be in some other file than the PG_MODULE_MAGIC call.

regards, tom lane

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

#3Andres Freund
andres@2ndquadrant.com
In reply to: Tom Lane (#2)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Hi,

On 2014-01-15 00:41:41 -0500, Tom Lane wrote:

Peter Eisentraut <peter_e@gmx.net> writes:

This idea has appeared at least twice now, in
/messages/by-id/1386301050.2743.17.camel@vanquo.pezone.net and /messages/by-id/52D25AA2.50108@2ndquadrant.com . Even if it doesn't help with Windows issues, as discussed in the second thread, it still seems like a win for reducing boilerplate and accidental compiler warnings. So here is a patch for consideration.

Meh. I don't think that extension authors are really going to appreciate
changing from "thou shalt declare all thy functions" to "thou shalt
declare none of them". If the code were such that it wouldn't matter
whether a manual declaration were provided too, then that wouldn't be a
big deal --- but you seem to be ignoring the discussion in the one thread
cited above about PGDLLEXPORT.

Also, surely it is 100% bogus for fmgr.h to be declaring functions not
actually provided by fmgr.c. That will create about as many failure
modes as it removes, not to mention being conceptually wrong.

The latter point might possibly be worked around by putting the externs
for _PG_init and _PG_fini into the PG_MODULE_MAGIC macro, though I'm not
sure how well that works for multi-source-file extensions; the init
functions might be in some other file than the PG_MODULE_MAGIC call.

Based on those comments and the lack of counter arguments after a month
I am going to mark the patch as rejected.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

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

#4Peter Eisentraut
peter_e@gmx.net
In reply to: Andres Freund (#3)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 2/15/14, 8:51 AM, Andres Freund wrote:

Based on those comments and the lack of counter arguments after a month
I am going to mark the patch as rejected.

Actually, I was waiting for that PGDLLIMPORT thread to sort itself out
before tackling this.

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

#5Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#2)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 1/15/14, 12:41 AM, Tom Lane wrote:

Meh. I don't think that extension authors are really going to appreciate
changing from "thou shalt declare all thy functions" to "thou shalt
declare none of them".

This patch does no such thing.

If the code were such that it wouldn't matter
whether a manual declaration were provided too, then that wouldn't be a
big deal --- but you seem to be ignoring the discussion in the one thread
cited above about PGDLLEXPORT.

In that thread, you argue that requiring PGDLLEXPORT is not acceptable,
so that makes this argument irrelevant.

Also, surely it is 100% bogus for fmgr.h to be declaring functions not
actually provided by fmgr.c.

That's the arrangement if you don't have dynamic loading. For dynamic
loading, the question isn't necessarily who provides them, but who
determines the interface for them. There has to be a way for the
postgres backend to say to extension module authors, I'm going to try to
load this function, and this is what it should look like. This case
wasn't envisioned when they designed C in 1970. If you have a better
idea, I'm listening.

That will create about as many failure
modes as it removes, not to mention being conceptually wrong.

What failure modes?

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

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#5)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Peter Eisentraut <peter_e@gmx.net> writes:

On 1/15/14, 12:41 AM, Tom Lane wrote:

Meh. I don't think that extension authors are really going to appreciate
changing from "thou shalt declare all thy functions" to "thou shalt
declare none of them".

This patch does no such thing.

Yes it does; people who fail to remove their manual externs will get
Windows-only build failures (or at least warnings; it's not very clear
which declaration will win).

regards, tom lane

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

#7Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#6)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 2/15/14, 10:22 AM, Tom Lane wrote:

Peter Eisentraut <peter_e@gmx.net> writes:

On 1/15/14, 12:41 AM, Tom Lane wrote:

Meh. I don't think that extension authors are really going to appreciate
changing from "thou shalt declare all thy functions" to "thou shalt
declare none of them".

This patch does no such thing.

Yes it does; people who fail to remove their manual externs will get
Windows-only build failures (or at least warnings; it's not very clear
which declaration will win).

The manual externs and the automatically provided ones are exactly the
same. Why would that fail?

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

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#7)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Peter Eisentraut <peter_e@gmx.net> writes:

On 2/15/14, 10:22 AM, Tom Lane wrote:

Yes it does; people who fail to remove their manual externs will get
Windows-only build failures (or at least warnings; it's not very clear
which declaration will win).

The manual externs and the automatically provided ones are exactly the
same. Why would that fail?

Maybe I'm remembering the wrong patch. I thought what this patch was
intending was to put PGDLLEXPORT into the automatically-provided externs.

regards, tom lane

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

#9Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#8)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Tom Lane wrote:

Peter Eisentraut <peter_e@gmx.net> writes:

On 2/15/14, 10:22 AM, Tom Lane wrote:

Yes it does; people who fail to remove their manual externs will get
Windows-only build failures (or at least warnings; it's not very clear
which declaration will win).

The manual externs and the automatically provided ones are exactly the
same. Why would that fail?

Maybe I'm remembering the wrong patch. I thought what this patch was
intending was to put PGDLLEXPORT into the automatically-provided externs.

This hunk is the essence of this patch:

#define PG_FUNCTION_INFO_V1(funcname) \
+Datum funcname(PG_FUNCTION_ARGS); \
extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \

Note that PGDLLEXPORT is already there. This patch is just about
additionally providing the prototype.

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

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

#10Andres Freund
andres@2ndquadrant.com
In reply to: Alvaro Herrera (#9)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 2014-02-17 10:30:16 -0300, Alvaro Herrera wrote:

Tom Lane wrote:

Peter Eisentraut <peter_e@gmx.net> writes:

On 2/15/14, 10:22 AM, Tom Lane wrote:

Yes it does; people who fail to remove their manual externs will get
Windows-only build failures (or at least warnings; it's not very clear
which declaration will win).

The manual externs and the automatically provided ones are exactly the
same. Why would that fail?

Maybe I'm remembering the wrong patch. I thought what this patch was
intending was to put PGDLLEXPORT into the automatically-provided externs.

This hunk is the essence of this patch:

#define PG_FUNCTION_INFO_V1(funcname) \
+Datum funcname(PG_FUNCTION_ARGS); \
extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \

Note that PGDLLEXPORT is already there. This patch is just about
additionally providing the prototype.

The PGDLLEXPORT is attached to the variable, no the function tho. If
somebody previously tried to do the correct thing and attached
PGDLLEXPORT to their own *function* prototoype, it would cause problems
now.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

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

#11Peter Eisentraut
peter_e@gmx.net
In reply to: Andres Freund (#10)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 4/4/14, 10:07 AM, Andres Freund wrote:

If
somebody previously tried to do the correct thing and attached
PGDLLEXPORT to their own *function* prototoype, it would cause problems
now.

What is the difference (on affected platforms) between

Datum funcname(PG_FUNCTION_ARGS);

and writing (effectively)

PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS);
Datum funcname(PG_FUNCTION_ARGS);

or for that matter

Datum funcname(PG_FUNCTION_ARGS);
PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS);

If there isn't a difference, then my patch is fine. Otherwise, it might
be good to document the issues for extension authors.

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

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#11)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Peter Eisentraut <peter_e@gmx.net> writes:

What is the difference (on affected platforms) between

Datum funcname(PG_FUNCTION_ARGS);

and writing (effectively)

PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS);
Datum funcname(PG_FUNCTION_ARGS);

or for that matter

Datum funcname(PG_FUNCTION_ARGS);
PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS);

According to
/messages/by-id/52D25AA2.50108@2ndquadrant.com

the latter fails outright. Which is problematic because that'd be the
more common case (particularly if you put manually-written externs in a
header file). So while we could do this, and it'd probably be an
improvement in the very long run, it'd definitely cause pain in the short
run. Not sure if it's worth it.

I still wish we could get rid of this problem by fixing the Windows build
recipes so that the PGDLLEXPORT marking wasn't needed. We proved to
ourselves recently that getting rid of PGDLLIMPORT on global variables
wouldn't work, but I'm not sure that the function end of it was really
investigated.

regards, tom lane

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

#13Craig Ringer
craig@2ndquadrant.com
In reply to: Tom Lane (#12)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 04/15/2014 03:39 AM, Tom Lane wrote:

I still wish we could get rid of this problem by fixing the Windows build
recipes so that the PGDLLEXPORT marking wasn't needed. We proved to
ourselves recently that getting rid of PGDLLIMPORT on global variables
wouldn't work, but I'm not sure that the function end of it was really
investigated.

My understanding is that we *can* drop PGDLLEXPORT on functions without
actively breaking anything. But we probably shouldn't.

If we omit PGDLLEXPORT, the linker of the DLL/executable that imports
the extern function will generate a thunk from the .LIB file for the
target DLL during linkage; this thunk within the DLL/EXE with the
undefined extern then jumps to the real address within the defining DLL/EXE.

Reference: http://msdn.microsoft.com/en-us/library/zw3za17w.aspx

So in other words, it makes calls across DLL boundaries less efficient
by adding a layer of indirection. (No idea how this works in the
presence of link time base address randomization either).

I actually think we should *add* a LIBPQEXPORT that handles this for
libpq, much like PGDLLEXPORT does for postgres(.exe). And in the
process, rename PGDLLEXPORT to POSTGRESEXPORT or PGSERVEREXPORT or
something.

PGDLLEXPORT is probably less important overall - it'll mainly impact
extensions (like hstore, intarray, etc) that call into the server.

I wonder if this thunking still really mattres with modern CPU
architecures' smart branch prediction, TLB caches, etc. I haven't found
much info on the real world impact.

It would probably be reasonable to add PGDLLEXPORT within postgres.exe
only on functions we've intentionally exposed for use by extensions,
where those functions are likely to get called a lot and don't have
bigget costs like disk I/O, network I/O, expensive memory allocations,
etc, that make call time overheads irrelevant.

--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

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

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Craig Ringer (#13)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Craig Ringer <craig@2ndquadrant.com> writes:

On 04/15/2014 03:39 AM, Tom Lane wrote:

I still wish we could get rid of this problem by fixing the Windows build
recipes so that the PGDLLEXPORT marking wasn't needed. We proved to
ourselves recently that getting rid of PGDLLIMPORT on global variables
wouldn't work, but I'm not sure that the function end of it was really
investigated.

My understanding is that we *can* drop PGDLLEXPORT on functions without
actively breaking anything. But we probably shouldn't.

If we omit PGDLLEXPORT, the linker of the DLL/executable that imports
the extern function will generate a thunk from the .LIB file for the
target DLL during linkage; this thunk within the DLL/EXE with the
undefined extern then jumps to the real address within the defining DLL/EXE.

TBH, if the only argument for this is a small efficiency difference,
then to my mind it barely requires discussion. I don't give one hoot
about micro-optimization for the Windows platform; I'm satisfied if
it works at all there. And I seriously doubt that a couple more cycles to
call any function implemented in a loadable module would matter anyway.

I actually think we should *add* a LIBPQEXPORT that handles this for
libpq, much like PGDLLEXPORT does for postgres(.exe). And in the
process, rename PGDLLEXPORT to POSTGRESEXPORT or PGSERVEREXPORT or
something.

My reaction to that is "not bloody likely". I remarked on this upthread
already, but there is absolutely no way that I want to clutter our source
code with platform-specific markings like that.

Perhaps somebody could try a Windows build with PGDLLEXPORT defined to
empty, and verify that it works, and if so do a pgbench comparison
against a build done the existing way?

regards, tom lane

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

#15Peter Eisentraut
peter_e@gmx.net
In reply to: Peter Eisentraut (#11)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 4/14/14, 3:28 PM, Peter Eisentraut wrote:

On 4/4/14, 10:07 AM, Andres Freund wrote:

If
somebody previously tried to do the correct thing and attached
PGDLLEXPORT to their own *function* prototoype, it would cause problems
now.

What is the difference (on affected platforms) between

Datum funcname(PG_FUNCTION_ARGS);

and writing (effectively)

PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS);
Datum funcname(PG_FUNCTION_ARGS);

or for that matter

Datum funcname(PG_FUNCTION_ARGS);
PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS);

If there isn't a difference, then my patch is fine. Otherwise, it might
be good to document the issues for extension authors.

Let me point out again that my patch doesn't actually do anything about
PGDLLEXPORT or the like. It just adds automatic prototypes into
PG_FUNCTION_INFO_V1, to reduce compiler warnings in extensions and
reduce some boilerplate in general.

If it turns out that this might help someone optimize the Windows build,
then great. But I gather it won't, so so what. Or maybe it can be made
to work, in which case extension authors will get compiler errors about
places they need to clean up. So it could still help that way, but who
knows, that's not the point.

If there are still concerns in this area, we could commit just the part
that adds the prototype to PG_FUNCTION_INFO_V1 and let that sit for a
while, and then remove the (now redundant) explicit prototypes in a
later release, so if there is a need to revert it, it won't be so big.

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

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#15)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

Peter Eisentraut <peter_e@gmx.net> writes:

Let me point out again that my patch doesn't actually do anything about
PGDLLEXPORT or the like. It just adds automatic prototypes into
PG_FUNCTION_INFO_V1, to reduce compiler warnings in extensions and
reduce some boilerplate in general.

Hmm ... for some reason I had gotten it in my head that you were adding
PGDLLEXPORT to the autogenerated extern declarations, but at least the
version of the patch in <1389762012.24046.2.camel@vanquo.pezone.net>
doesn't do that, so the point is moot.

I still object to the aspect of the patch that moves the externs for
_PG_init/_PG_fini into fmgr.h: that is conceptually wrong and will create
more confusion than the trivial code savings is worth. But I won't
complain if you commit the PG_FUNCTION_INFO_V1 changes.

regards, tom lane

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

#17Craig Ringer
craig@2ndquadrant.com
In reply to: Tom Lane (#14)
Re: Create function prototype as part of PG_FUNCTION_INFO_V1

On 04/15/2014 10:17 PM, Tom Lane wrote:

I actually think we should *add* a LIBPQEXPORT that handles this for
libpq, much like PGDLLEXPORT does for postgres(.exe). And in the
process, rename PGDLLEXPORT to POSTGRESEXPORT or PGSERVEREXPORT or
something.

My reaction to that is "not bloody likely". I remarked on this upthread
already, but there is absolutely no way that I want to clutter our source
code with platform-specific markings like that.

Perhaps somebody could try a Windows build with PGDLLEXPORT defined to
empty, and verify that it works, and if so do a pgbench comparison
against a build done the existing way?

Good idea.

Personally, I don't care about Windows enough. I want it to work, but
performance optimisation is beyond what I'm bothered with.

Another useful test would be to modify libpq as described above, so its
headers set __declspec(dllexport) on its exports during compilation and
its headers set __declspec(dllimport) when included while compiling
other binaries that will link to libpq. Then use *that* in pgbench too
and see if it makes any meaningful difference.

--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

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