From 01aad3b1d9fb9fcb8edbfed76241540d97da8586 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 3 Oct 2019 11:46:46 -0400
Subject: [PATCH 16/74] Add support for in-tree plugins

This patch adds support for "in-tree" plugins i.e. GCC plugins that live
in the GCC source tree and are shipped as part of the GCC tarball.

The patch adds Makefile/configure machinery for handling in-tree GCC
plugins, adapted from how we support frontends.

Each in-tree plugin should provide a Make-plugin.in and config-plugin.in,
analogous to the Make-lang.in and config-lang.in provided by a frontend;
they can also supply options via a plugin.opt, analogous to a frontend's
lang.opt.

The patch adds a --enable-plugins=[LIST OF PLUGIN NAMES] configure option,
analogous to --enable-languages.  The default is for no such plugins to be
enabled.

ChangeLog:
	* configure.ac: Handle --enable-plugins.

gcc/ChangeLog:
	* Makefile.in (CONFIG_PLUGINS): New.
	(SUBDIRS, subdirs): Generalize to cover plugins as well as
	languages.
	(plugin_opt_files): New.
	(ALL_OPT_FILES): Add plugin_opt_files.
	(ALL_HOST_PLUGIN_OBJS): New.
	(ALL_HOST_OBJS): Add ALL_HOST_PLUGIN_OBJS.
	(plugin_hooks): New.
	(PLUGIN_MAKEFRAGS): New; include them.
	(Makefile): Add dependency on PLUGIN_MAKEFRAGS.
	(all.cross): Add dependency on plugin.all.cross.
	(start.encap): Add plugin.start.encap.
	(rest.encap): Add plugin.rest.encap.
	(SELFTEST_TARGETS): Add selftest_plugins.
	(info): Add dependency on lang.info.
	(dvi): Add dependency on plugin.dvi.
	(pdf): Add dependency on plugin.pdf.
	(HTMLS_BUILD): Add plugin.html.
	(man): Add plugin.man.
	(mostlyclean): Add plugin.mostlyclean.
	(clean): Add plugin.clean.
	(distclean): Update for renaming of Make-hooks to Make-lang-hooks;
	add Make-plugin-hooks.  Add plugin.distclean dependency.
	(maintainer-clean): Add plugin.maintainer-clean.
	(install-plugin): Add plugin.install-plugin.
	(install-common): Add plugin.install-common.
	(install-info): Add plugin.install-info.
	(install-pdf): Add plugin.install-pdf.
	(install-html): Add plugin.install-html.
	(install-man): Add plugin.install-man.
	(uninstall): Add plugin.uninstall.
	(TAGS): Add plugin.tags.
	* configure.ac (Make-hooks): Rename to Make-lang-hooks.
	(plugin_opt_files): New.
	(plugin_specs_files): New.
	(plugin_tree_files): New.
	(all_plugins): New.
	(all_plugin_makefrags): New.
	(all_selected_plugins): New.
	(plugin_hooks): New.
	("Plugin hooks"): New section.  Iterate through config-plugin.in,
	analogously to config-lang.in.
	(check_plugins): New.
	(selftest_plugins): New.
	(Make-plugin-hooks): Emit.
	* doc/install.texi (--enable-plugins): New option.
---
 configure.ac         |   6 ++
 gcc/Makefile.in      |  98 ++++++++++++++++++++---------
 gcc/configure.ac     | 172 +++++++++++++++++++++++++++++++++++++++++++++++++--
 gcc/doc/install.texi |   9 +++
 4 files changed, 251 insertions(+), 34 deletions(-)

diff --git a/configure.ac b/configure.ac
index b8ce2ad..9b8b8ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2188,6 +2188,12 @@ Supported languages are: ${potential_languages}])
   ac_configure_args=`echo " $ac_configure_args" | sed -e "s/ '--enable-languages=[[^ ]]*'//g" -e "s/$/ '--enable-languages="$enable_languages"'/" `
 fi
 
+# Look if the user specified --enable-plugins="..."
+if test -d ${srcdir}/gcc; then
+  enable_plugins=`echo "${enable_plugins}" | sed -e 's/[[ 	,]][[ 	,]]*/,/g' -e 's/,$//'`
+  ac_configure_args=`echo " $ac_configure_args" | sed -e "s/ '--enable-plugins=[[^ ]]*'//g" -e "s/$/ '--enable-plugins="$enable_plugins"'/" `
+fi
+
 # Handle --disable-<component> generically.
 for dir in $configdirs $build_configdirs $target_configdirs ; do
   dirname=`echo $dir | sed -e s/target-//g -e s/build-//g -e s/-/_/g`
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5feef6a..c0dfbde 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -132,7 +132,7 @@ CROSS=@CROSS@
 # Variables that exist for you to override.
 # See below for how to change them for certain systems.
 
-# List of language subdirectories.
+# List of language and plugin subdirectories.
 SUBDIRS =@subdirs@ build
 
 # Selection of languages to be made.
@@ -142,6 +142,8 @@ ifeq (@enable_gcov@,yes)
 LANGUAGES += gcov$(exeext) gcov-dump$(exeext) gcov-tool$(exeext)
 endif
 
+CONFIG_PLUGINS = @all_selected_plugins@
+
 # Default values for variables overridden in Makefile fragments.
 # CFLAGS is for the user to override to, e.g., do a cross build with -O2.
 # TCFLAGS is used for compilations with the GCC just built.
@@ -570,6 +572,7 @@ lang_checks_parallelized=
 lang_opt_files=@lang_opt_files@ $(srcdir)/c-family/c.opt $(srcdir)/common.opt
 lang_specs_files=@lang_specs_files@
 lang_tree_files=@lang_tree_files@
+plugin_opt_files=@plugin_opt_files@
 target_cpu_default=@target_cpu_default@
 OBJC_BOEHM_GC=@objc_boehm_gc@
 extra_modes_file=@extra_modes_file@
@@ -1186,7 +1189,7 @@ FLAGS_TO_PASS = \
 # Lists of files for various purposes.
 
 # All option source files
-ALL_OPT_FILES=$(lang_opt_files) $(extra_opt_files)
+ALL_OPT_FILES=$(lang_opt_files) $(plugin_opt_files) $(extra_opt_files)
 
 # Target specific, C specific object file
 C_TARGET_OBJS=@c_target_objs@
@@ -1639,6 +1642,8 @@ OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
 # This lists all host objects for the front ends.
 ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
 
+ALL_HOST_PLUGIN_OBJS = $(foreach v,$(CONFIG_PLUGINS),$($(v)_OBJS))
+
 ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) $(OBJS-libcommon) \
   $(OBJS-libcommon-target) main.o c-family/cppspec.o \
   $(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) \
@@ -1655,7 +1660,10 @@ endif
 
 # This lists all host object files, whether they are included in this
 # compilation or not.
-ALL_HOST_OBJS = $(ALL_HOST_FRONTEND_OBJS) $(ALL_HOST_BACKEND_OBJS)
+ALL_HOST_OBJS = \
+  $(ALL_HOST_FRONTEND_OBJS) \
+  $(ALL_HOST_PLUGIN_OBJS) \
+  $(ALL_HOST_BACKEND_OBJS)
 
 BACKEND = libbackend.a main.o libcommon-target.a libcommon.a \
 	$(CPPLIB) $(LIBDECNUMBER)
@@ -1752,6 +1760,32 @@ s-alltree: Makefile
 $(foreach file,$(ALL_HOST_FRONTEND_OBJS),$(eval CFLAGS-$(file) += -DIN_GCC_FRONTEND))
 
 #
+# Plugin makefile fragments.
+
+# The following targets define the interface between us and the
+# in-tree plugins.
+#
+# all.cross, start.encap, rest.encap,
+# install-common, install-info, install-man,
+# uninstall,
+# mostlyclean, clean, distclean, maintainer-clean,
+#
+# Each plugin is linked in with a series of hooks.  The name of each
+# hooked is "plugin.${target_name}" (eg: plugin.info).  Configure computes
+# and adds these here.  We use double-colon rules for some of the hooks;
+# double-colon rules should be preferred for any new hooks.
+
+# plugin hooks, generated by configure
+@plugin_hooks@
+
+# per-plugin makefile fragments
+PLUGIN_MAKEFRAGS = @all_plugin_makefrags@
+
+ifneq ($(PLUGIN_MAKEFRAGS),)
+include $(PLUGIN_MAKEFRAGS)
+endif
+
+#
 
 # -----------------------------
 # Rebuilding this configuration
@@ -1793,8 +1827,9 @@ $(foreach file,$(ALL_HOST_FRONTEND_OBJS),$(eval CFLAGS-$(file) += -DIN_GCC_FRONT
 # This is what is done in this makefile. Note that mkconfig.sh has a
 # move-if-change built-in
 
-Makefile: config.status $(srcdir)/Makefile.in $(LANG_MAKEFRAGS)
+Makefile: config.status $(srcdir)/Makefile.in $(LANG_MAKEFRAGS) $(PLUGIN_MAKEFRAGS)
 	LANGUAGES="$(CONFIG_LANGUAGES)" \
+	PLUGINS="$(CONFIG_PLUGINS)" \
 	CONFIG_HEADERS= \
 	CONFIG_SHELL="$(SHELL)" \
 	CONFIG_FILES=$@ $(SHELL) config.status
@@ -1924,12 +1959,13 @@ quickstrap: all
 all.internal: start.encap rest.encap doc selftest
 # This is what to compile if making a cross-compiler.
 all.cross: native gcc-cross$(exeext) cpp$(exeext) specs \
-	libgcc-support lang.all.cross doc selftest @GENINSRC@ srcextra
+	libgcc-support lang.all.cross plugin.all.cross doc \
+	selftest @GENINSRC@ srcextra
 # This is what must be made before installing GCC and converting libraries.
 start.encap: native xgcc$(exeext) cpp$(exeext) specs \
-	libgcc-support lang.start.encap @GENINSRC@ srcextra
+	libgcc-support lang.start.encap plugin.start.encap @GENINSRC@ srcextra
 # These can't be made until after GCC can run.
-rest.encap: lang.rest.encap
+rest.encap: lang.rest.encap plugin.rest.encap
 # This is what is made with the host's compiler
 # whether making a cross compiler or not.
 native: config.status auto-host.h build-@POSUB@ $(LANGUAGES) \
@@ -1967,11 +2003,12 @@ SELFTEST_DEPS = $(GCC_PASSES) stmp-int-hdrs $(srcdir)/testsuite/selftests
 # driver, frontend, or selftest data change.
 .PHONY: selftest
 
-# Potentially run all selftest-<LANG>.  The various <LANG>/Make-lang.in can
-# require the selftests to be run by defining their selftest-<LANG> as
-# s-selftest-<LANG>.  Otherwise, they should define it as empty.
+# Potentially run all selftest-<LANG> and selftest-<PLUGIN>.
+# The various <LANG>/Make-lang.in and <PLUGIN>/Make-plugin.in can
+# require the selftests to be run by defining their selftest-<NAME> as
+# s-selftest-<NAME>.  Otherwise, they should define it as empty.
 
-SELFTEST_TARGETS = @selftest_languages@
+SELFTEST_TARGETS = @selftest_languages@ @selftest_plugins@
 selftest: $(SELFTEST_TARGETS)
 
 # Recompile all the language-independent object files.
@@ -3157,7 +3194,8 @@ doc: $(BUILD_INFO) $(GENERATED_MANPAGES)
 INFOFILES = doc/cpp.info doc/gcc.info doc/gccint.info \
             doc/gccinstall.info doc/cppinternals.info
 
-info: $(INFOFILES) lang.info @GENINSRC@ srcinfo lang.srcinfo
+info: $(INFOFILES) lang.info plugin.info @GENINSRC@ srcinfo lang.srcinfo \
+	plugin.srcinfo
 
 srcinfo: $(INFOFILES)
 	-cp -p $^ $(srcdir)/doc
@@ -3244,7 +3282,7 @@ $(build_htmldir)/gccint/index.html: $(TEXI_GCCINT_FILES)
 $(build_htmldir)/cppinternals/index.html: $(TEXI_CPPINT_FILES)
 
 dvi:: doc/gcc.dvi doc/gccint.dvi doc/gccinstall.dvi doc/cpp.dvi \
-      doc/cppinternals.dvi lang.dvi
+      doc/cppinternals.dvi lang.dvi plugin.dvi
 
 doc/%.dvi: %.texi
 	$(TEXI2DVI) -I . -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
@@ -3256,7 +3294,7 @@ doc/gccinstall.dvi: $(TEXI_GCCINSTALL_FILES)
 PDFFILES = doc/gcc.pdf doc/gccint.pdf doc/gccinstall.pdf doc/cpp.pdf \
            doc/cppinternals.pdf
 
-pdf:: $(PDFFILES) lang.pdf
+pdf:: $(PDFFILES) lang.pdf plugin.pdf
 
 doc/%.pdf: %.texi
 	$(TEXI2PDF) -I . -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
@@ -3275,7 +3313,7 @@ HTMLS_INSTALL=$(build_htmldir)/cpp $(build_htmldir)/gcc \
 # List the html file targets.
 HTMLS_BUILD=$(build_htmldir)/cpp/index.html $(build_htmldir)/gcc/index.html \
        $(build_htmldir)/gccinstall/index.html $(build_htmldir)/gccint/index.html \
-       $(build_htmldir)/cppinternals/index.html lang.html
+       $(build_htmldir)/cppinternals/index.html lang.html plugin.html
 
 html:: $(HTMLS_BUILD)
 
@@ -3297,7 +3335,8 @@ MANFILES = doc/gcov.1 doc/cpp.1 doc/gcc.1 doc/gfdl.7 doc/gpl.7 \
 
 generated-manpages: man
 
-man: $(MANFILES) lang.man @GENINSRC@ srcman lang.srcman
+man: $(MANFILES) lang.man plugin.man @GENINSRC@ srcman lang.srcman \
+	plugin.srcman
 
 srcman: $(MANFILES)
 	-cp -p $^ $(srcdir)/doc
@@ -3351,7 +3390,7 @@ gpl.pod: gpl_v3.texi
 # We remove as much from the language subdirectories as we can
 # (less duplicated code).
 
-mostlyclean: lang.mostlyclean
+mostlyclean: lang.mostlyclean plugin.mostlyclean
 	-rm -f $(MOSTLYCLEANFILES)
 	-rm -f *$(objext) c-family/*$(objext)
 	-rm -f *$(coverageexts)
@@ -3388,7 +3427,7 @@ mostlyclean: lang.mostlyclean
 
 # Delete all files made by compilation
 # that don't exist in the distribution.
-clean: mostlyclean lang.clean
+clean: mostlyclean lang.clean plugin.clean
 	-rm -f libgcc.a libgcc_eh.a libgcov.a
 	-rm -f libgcc_s*
 	-rm -f libunwind*
@@ -3409,11 +3448,11 @@ clean: mostlyclean lang.clean
 
 # Delete all files that users would normally create
 # while building and installing GCC.
-distclean: clean lang.distclean
+distclean: clean lang.distclean plugin.distclean
 	-rm -f auto-host.h auto-build.h
 	-rm -f cstamp-h
 	-rm -f config.status config.run config.cache config.bak
-	-rm -f Make-lang Make-hooks Make-host Make-target
+	-rm -f Make-lang Make-lang-hooks Make-plugin-hooks Make-host Make-target
 	-rm -f Makefile *.oaux
 	-rm -f gthr-default.h
 	-rm -f TAGS */TAGS
@@ -3435,7 +3474,7 @@ distclean: clean lang.distclean
 maintainer-clean:
 	@echo 'This command is intended for maintainers to use; it'
 	@echo 'deletes files that may need special tools to rebuild.'
-	$(MAKE) lang.maintainer-clean distclean
+	$(MAKE) lang.maintainer-clean plugin.maintainer-clean distclean
 	-rm -f cpp.??s cpp.*aux
 	-rm -f gcc.??s gcc.*aux
 	-rm -f $(gcc_docdir)/*.info $(gcc_docdir)/*.1 $(gcc_docdir)/*.7 $(gcc_docdir)/*.dvi $(gcc_docdir)/*.pdf
@@ -3546,7 +3585,7 @@ install-gengtype: installdirs gengtype$(exeext) gtype.state
 	$(INSTALL_PROGRAM) gengtype$(exeext) $(DESTDIR)$(plugin_bindir)/gengtype$(exeext)
 
 # Install the headers needed to build a plugin.
-install-plugin: installdirs lang.install-plugin s-header-vars install-gengtype
+install-plugin: installdirs lang.install-plugin plugin.install-plugin s-header-vars install-gengtype
 # We keep the directory structure for files in config or c-family and .def
 # files. All other files are flattened to a single directory.
 	$(mkinstalldirs) $(DESTDIR)$(plugin_includedir)
@@ -3573,7 +3612,7 @@ install-plugin: installdirs lang.install-plugin s-header-vars install-gengtype
 	$(INSTALL_DATA) b-header-vars $(DESTDIR)$(plugin_includedir)/b-header-vars
 
 # Install the compiler executables built during cross compilation.
-install-common: native lang.install-common installdirs
+install-common: native lang.install-common plugin.install-common installdirs
 	for file in $(COMPILERS); do \
 	  if [ -f $$file ] ; then \
 	    rm -f $(DESTDIR)$(libexecsubdir)/$$file; \
@@ -3648,7 +3687,8 @@ install-info:: doc installdirs \
 	$(DESTDIR)$(infodir)/cppinternals.info \
 	$(DESTDIR)$(infodir)/gccinstall.info \
 	$(DESTDIR)$(infodir)/gccint.info \
-	lang.install-info
+	lang.install-info \
+	plugin.install-info
 
 $(DESTDIR)$(infodir)/%.info: doc/%.info installdirs
 	rm -f $@
@@ -3667,7 +3707,7 @@ $(DESTDIR)$(infodir)/%.info: doc/%.info installdirs
 
 pdf__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 
-install-pdf: $(PDFFILES) lang.install-pdf
+install-pdf: $(PDFFILES) lang.install-pdf plugin.install-pdf
 	@$(NORMAL_INSTALL)
 	test -z "$(pdfdir)/gcc" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)/gcc"
 	@list='$(PDFFILES)'; for p in $$list; do \
@@ -3679,7 +3719,7 @@ install-pdf: $(PDFFILES) lang.install-pdf
 
 html__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 
-install-html: $(HTMLS_BUILD) lang.install-html
+install-html: $(HTMLS_BUILD) lang.install-html plugin.install-html
 	@$(NORMAL_INSTALL)
 	test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
 	@list='$(HTMLS_INSTALL)'; for p in $$list; do \
@@ -3697,7 +3737,7 @@ install-html: $(HTMLS_BUILD) lang.install-html
 	done
 
 # Install the man pages.
-install-man: lang.install-man \
+install-man: lang.install-man plugin.install-man \
 	$(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext) \
 	$(DESTDIR)$(man1dir)/$(CPP_INSTALL_NAME)$(man1ext) \
 	$(DESTDIR)$(man1dir)/$(GCOV_INSTALL_NAME)$(man1ext) \
@@ -3857,7 +3897,7 @@ install-gcc-ar: installdirs gcc-ar$(exeext) gcc-nm$(exeext) gcc-ranlib$(exeext)
 	fi
 
 # Cancel installation by deleting the installed files.
-uninstall: lang.uninstall
+uninstall: lang.uninstall plugin.uninstall
 	-rm -rf $(DESTDIR)$(libsubdir)
 	-rm -rf $(DESTDIR)$(libexecsubdir)
 	-rm -rf $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext)
@@ -4164,7 +4204,7 @@ paranoia: paranoia.o real.o $(LIBIBERTY)
 # These exist for maintenance purposes.
 
 # Update the tags table.
-TAGS: lang.tags
+TAGS: lang.tags plugin.tags
 	(cd $(srcdir);					\
 	incs= ;						\
 	list='$(SUBDIRS)'; for dir in $$list; do	\
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 62f4b26..537d3d8 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -6300,7 +6300,7 @@ all_selected_languages=
 # The other mechanism is a set of hooks for each of the main targets
 # like `clean', `install', etc.
 
-language_hooks="Make-hooks"
+language_hooks="Make-lang-hooks"
 
 for lang in ${srcdir}/*/config-lang.in
 do
@@ -6409,8 +6409,8 @@ done
 # We link each language in with a set of hooks, reached indirectly via
 # lang.${target}.  Only do so for selected languages.
 
-rm -f Make-hooks
-touch Make-hooks
+rm -f Make-lang-hooks
+touch Make-lang-hooks
 target_list="all.cross start.encap rest.encap tags \
 	install-common install-man install-info install-pdf install-html dvi \
 	pdf html uninstall info man srcextra srcman srcinfo \
@@ -6423,7 +6423,160 @@ do
 	do
 		x="$x $lang.$t"
 	done
-	echo "lang.$t: $x" >> Make-hooks
+	echo "lang.$t: $x" >> Make-lang-hooks
+done
+
+# --------------
+# Plugin hooks
+# --------------
+
+# Make empty files to contain the specs and options for each plugin.
+# Then add #include lines to for a compiler that has specs and/or options.
+
+plugin_opt_files=
+plugin_specs_files=
+plugin_tree_files=
+# These (without "all_") are set in each config-plugin.in.
+# `plugin' must be a single word so is spelled singularly.
+all_plugins=
+# List of plugin makefile fragments.
+all_plugin_makefrags=
+
+# These are the plugins that are set in --enable-plugins,
+# and are available in the GCC tree.
+all_selected_plugins=
+
+# Add the plugin fragments.
+# Plugins are added via two mechanisms.  Some information must be
+# recorded in makefile variables, these are defined in config-plugin.in.
+# We accumulate them and plug them into the main Makefile.
+# The other mechanism is a set of hooks for each of the main targets
+# like `clean', `install', etc.
+
+plugin_hooks="Make-plugin-hooks"
+
+for plugin in ${srcdir}/*/config-plugin.in
+do
+changequote(,)dnl
+	test "$plugin" = "${srcdir}/*/config-plugin.in" && continue
+
+        plugin_alias=`sed -n -e 's,^plugin=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^plugin=\([^   ]*\).*$,\1,p' $plugin`
+        if test "x$plugin_alias" = x
+        then
+              echo "$plugin doesn't set \$plugin." 1>&2
+              exit 1
+        fi
+        subdir="`echo $plugin | sed -e 's,^.*/\([^/]*\)/config-plugin.in$,\1,'`"
+        subdirs="$subdirs $subdir"
+
+	# $gcc_subdir is where the gcc integration files are to be found
+	# for a plugin, both for internal compiler purposes (compiler
+	# sources implementing front-end to GCC tree converters), and for
+	# build infrastructure purposes (Make-plugin.in, etc.)
+	#
+	# This will be <subdir> (relative to $srcdir) if a line like 
+	# gcc_subdir="<subdir>" or gcc_subdir=<subdir>
+	# is found in <plugindir>/config-plugin.in, and will remain <plugindir>
+	# otherwise.
+	#
+	# Except for the plugin alias (fetched above), the regular
+	# "config-plugin.in" contents are always retrieved from $gcc_subdir,
+	# so a <plugindir>/config-plugin.in setting gcc_subdir typically sets
+	# only this and the plugin alias.
+
+        gcc_subdir=`sed -n -e 's,^gcc_subdir=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^gcc_subdir=\([^   ]*\).*$,\1,p' $plugin`
+        if [ "$gcc_subdir" = "" ]; then
+           gcc_subdir="$subdir"
+        fi
+
+        case ",$enable_plugins," in
+        *,$plugin_alias,*)
+            all_selected_plugins="$all_selected_plugins $plugin_alias"
+            if test -f $srcdir/$gcc_subdir/plugin-specs.h; then
+                plugin_specs_files="$plugin_specs_files $srcdir/$gcc_subdir/plugin-specs.h"
+	    fi
+	    ;;
+        esac
+changequote([,])dnl
+
+	plugin=
+	boot_plugin=
+	compilers=
+	outputs=
+	gtfiles=
+	subdir_requires=
+	. ${srcdir}/$gcc_subdir/config-plugin.in
+	if test "x$plugin" = x
+	then
+		echo "${srcdir}/$gcc_subdir/config-plugin.in doesn't set \$plugin." 1>&2
+		exit 1
+	fi
+
+	ok=:
+        case ",$enable_plugins," in
+        	*,$plugin_alias,*) ;;
+		*)
+			for i in $subdir_requires; do
+				test -f "${srcdir}/$i/config-plugin.in" && continue
+				ok=false
+				break
+			done
+		;;
+	esac
+	$ok || continue
+
+	all_plugin_makefrags="$all_plugin_makefrags \$(srcdir)/$gcc_subdir/Make-plugin.in"
+	if test -f $srcdir/$gcc_subdir/plugin.opt; then
+	    plugin_opt_files="$plugin_opt_files $srcdir/$gcc_subdir/plugin.opt"
+	    all_opt_files="$all_opt_files $srcdir/$gcc_subdir/plugin.opt"
+	fi
+	if test -f $srcdir/$gcc_subdir/$subdir-tree.def; then
+	    plugin_tree_files="$plugin_tree_files $srcdir/$gcc_subdir/$subdir-tree.def"
+	fi
+	all_plugins="$all_plugins $plugin"
+	all_compilers="$all_compilers $compilers"
+	all_outputs="$all_outputs $outputs"
+	all_gtfiles="$all_gtfiles [[$subdir]] $gtfiles"
+	case ",$enable_plugins," in
+		*,analyzer,*)
+		    AC_DEFINE(ENABLE_ANALYZER, 1, [Define to enable static analyzer.])
+		    enable_analyzer=yes
+		    AC_SUBST(enable_analyzer)
+		    ;;
+		*) ;;
+	esac
+done
+
+check_plugins=
+for plugin in $all_selected_plugins
+do
+	check_plugins="$check_plugins check-$plugin"
+done
+
+selftest_plugins=
+for plugin in $all_selected_plugins
+do
+	selftest_plugins="$selftest_plugins selftest-$plugin"
+done
+
+# We link each plugin in with a set of hooks, reached indirectly via
+# plugin.${target}.  Only do so for selected plugins.
+
+rm -f Make-plugin-hooks
+touch Make-plugin-hooks
+target_list="all.cross start.encap rest.encap tags \
+	install-common install-man install-info install-pdf install-html dvi \
+	pdf html uninstall info man srcextra srcman srcinfo \
+	mostlyclean clean distclean maintainer-clean install-plugin"
+
+for t in $target_list
+do
+	x=
+	for plugin in $all_selected_plugins
+	do
+		x="$x $plugin.$t"
+	done
+	echo "plugin.$t: $x" >> Make-plugin-hooks
 done
 
 # --------
@@ -6481,7 +6634,10 @@ AC_SUBST(all_compilers)
 AC_SUBST(all_gtfiles)
 AC_SUBST(all_lang_makefrags)
 AC_SUBST(all_languages)
+AC_SUBST(all_plugin_makefrags)
 AC_SUBST(all_selected_languages)
+AC_SUBST(all_plugins)
+AC_SUBST(all_selected_plugins)
 AC_SUBST(build_exeext)
 AC_SUBST(build_install_headers_dir)
 AC_SUBST(build_xm_file_list)
@@ -6490,6 +6646,8 @@ AC_SUBST(build_xm_defines)
 AC_SUBST(build_file_translate)
 AC_SUBST(check_languages)
 AC_SUBST(selftest_languages)
+AC_SUBST(check_plugins)
+AC_SUBST(selftest_plugins)
 AC_SUBST(cpp_install_dir)
 AC_SUBST(xmake_file)
 AC_SUBST(tmake_file)
@@ -6515,6 +6673,9 @@ AC_SUBST(install)
 AC_SUBST(lang_opt_files)
 AC_SUBST(lang_specs_files)
 AC_SUBST(lang_tree_files)
+AC_SUBST(plugin_opt_files)
+AC_SUBST(plugin_specs_files)
+AC_SUBST(plugin_tree_files)
 AC_SUBST(local_prefix)
 AC_SUBST(md_file)
 AC_SUBST(objc_boehm_gc)
@@ -6540,6 +6701,7 @@ AC_SUBST(d_target_objs)
 AC_SUBST(target_cpu_default)
 
 AC_SUBST_FILE(language_hooks)
+AC_SUBST_FILE(plugin_hooks)
 
 # Echo link setup.
 if test x${build} = x${host} ; then
@@ -6742,7 +6904,7 @@ AC_MSG_RESULT($ld_pushpopstate_support)
 # AC_CONFIG_SUBDIRS($subdirs)
 
 # Create the Makefile
-# and configure language subdirectories
+# and configure language and plugin subdirectories
 AC_CONFIG_FILES($all_outputs)
 
 AC_CONFIG_COMMANDS([default],
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index dd36a1e..c27807f 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1707,6 +1707,15 @@ specified languages with the stage-1 compiler by using @command{make
 stage1-bubble all-target}, or run the testsuite on the stage-1 compiler
 for the specified languages using @command{make stage1-start check-gcc}.
 
+@item --enable-plugins=@var{plugin1},@var{plugin2},@dots{}
+Specify that a particular subset of in-tree plugins should be built.
+For a list of valid values for @var{pluginN} you can issue the following
+command in the @file{gcc} directory of your GCC source tree:@*
+@smallexample
+grep ^plugin= */config-plugin.in
+@end smallexample
+If you do not pass this flag, then no in-tree plugins will be built.
+
 @item --disable-libada
 Specify that the run-time libraries and tools used by GNAT should not
 be built.  This can be useful for debugging, or for compatibility with
-- 
1.8.5.3

