Let GDB reuse GCC's parser.
2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Tom Tromey <tromey@redhat.com> * aclocal.m4: New file. * callbacks.cc: New file. * callbacks.hh: New file. * cc1plugin-config.h.in: New file. * configure: New file. * configure.ac: New file. * connection.cc: New file. * connection.hh: New file. * findcomp.cc: New file. * findcomp.hh: New file. * libcc1.cc: New file. * libcc1plugin.sym: New file. * libcc1.sym: New file. * Makefile.am: New file. * Makefile.in: New file. * marshall.cc: New file. * marshall.hh: New file. * names.cc: New file. * names.hh: New file. * plugin.cc: New file. * rpc.hh: New file. * status.hh: New file. 2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Tom Tromey <tromey@redhat.com> * gcc-c-fe.def: New file. * gcc-c-interface.h: New file. * gcc-interface.h: New file. 2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Tom Tromey <tromey@redhat.com> * c-tree.h (enum c_oracle_request): New. (c_binding_oracle_function): New typedef. (c_binding_oracle, c_pushtag, c_bind): Declare. * c-decl.c (c_binding_oracle): New global. (I_SYMBOL_CHECKED): New macro. (i_symbol_binding): New function. (I_SYMBOL_BINDING, I_SYMBOL_DECL): Redefine. (I_TAG_CHECKED): New macro. (i_tag_binding): New function. (I_TAG_BINDING, I_TAG_DECL): Redefine. (I_LABEL_CHECKED): New macro. (i_label_binding): New function. (I_LABEL_BINDING, I_LABEL_DECL): Redefine. (c_print_identifier): Save and restore c_binding_oracle. (c_pushtag, c_bind): New functions. 2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Tom Tromey <tromey@redhat.com> * aclocal.m4, configure: Rebuild. * Makefile.in (aclocal_deps): Add gcc-plugin.m4. * configure.ac: Use GCC_ENABLE_PLUGINS. * stor-layout.c (finish_bitfield_layout): Now public. Change argument type to 'tree'. (finish_record_layout): Update. * stor-layout.h (finish_bitfield_layout): Declare. 2014-10-27 Tom Tromey <tromey@redhat.com> * gcc-plugin.m4: New file. 2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Tom Tromey <tromey@redhat.com> * Makefile.def: Add libcc1 to host_modules. * configure.ac (host_tools): Add libcc1. * Makefile.in, configure: Rebuild. From-SVN: r216748
This commit is contained in:
parent
50a504654d
commit
ddc8de034a
44 changed files with 23919 additions and 300 deletions
|
@ -1,3 +1,10 @@
|
|||
2014-10-27 Phil Muldoon <pmuldoon@redhat.com>
|
||||
Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* Makefile.def: Add libcc1 to host_modules.
|
||||
* configure.ac (host_tools): Add libcc1.
|
||||
* Makefile.in, configure: Rebuild.
|
||||
|
||||
2014-10-24 Hans-Peter Nilsson <hp@axis.com>
|
||||
|
||||
* configure.ac (build_configargs): Don't share config.cache between
|
||||
|
|
|
@ -123,6 +123,8 @@ host_modules= { module= gnattools; };
|
|||
host_modules= { module= lto-plugin; bootstrap=true;
|
||||
extra_configure_flags='--enable-shared @extra_linker_plugin_flags@ @extra_linker_plugin_configure_flags@';
|
||||
extra_make_flags='@extra_linker_plugin_flags@'; };
|
||||
host_modules= { module= libcc1; bootstrap=true;
|
||||
extra_configure_flags=--enable-shared; };
|
||||
|
||||
target_modules = { module= libstdc++-v3;
|
||||
bootstrap=true;
|
||||
|
@ -356,6 +358,9 @@ dependencies = { module=all-gnattools; on=all-target-libstdc++-v3; };
|
|||
dependencies = { module=all-lto-plugin; on=all-libiberty; };
|
||||
dependencies = { module=all-lto-plugin; on=all-libiberty-linker-plugin; };
|
||||
|
||||
dependencies = { module=configure-libcc1; on=configure-gcc; };
|
||||
dependencies = { module=all-libcc1; on=all-gcc; };
|
||||
|
||||
dependencies = { module=all-utils; on=all-libiberty; };
|
||||
|
||||
dependencies = { module=configure-mpfr; on=all-gmp; };
|
||||
|
|
997
Makefile.in
997
Makefile.in
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,7 @@
|
|||
2014-10-27 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gcc-plugin.m4: New file.
|
||||
|
||||
2014-09-01 Andi Kleen <ak@linux.intel.com>
|
||||
|
||||
* bootstrap-lto.mk: Implement slim bootstrap.
|
||||
|
|
113
config/gcc-plugin.m4
Normal file
113
config/gcc-plugin.m4
Normal file
|
@ -0,0 +1,113 @@
|
|||
# gcc-plugin.m4 -*- Autoconf -*-
|
||||
# Check whether GCC is able to be built with plugin support.
|
||||
|
||||
dnl Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
dnl This file is free software, distributed under the terms of the GNU
|
||||
dnl General Public License. As a special exception to the GNU General
|
||||
dnl Public License, this file may be distributed as part of a program
|
||||
dnl that contains a configuration script generated by Autoconf, under
|
||||
dnl the same distribution terms as the rest of that program.
|
||||
|
||||
# Check for plugin support.
|
||||
# Respects --enable-plugin.
|
||||
# Sets the shell variables enable_plugin and pluginlibs.
|
||||
AC_DEFUN([GCC_ENABLE_PLUGINS],
|
||||
[# Check for plugin support
|
||||
AC_ARG_ENABLE(plugin,
|
||||
[AS_HELP_STRING([--enable-plugin], [enable plugin support])],
|
||||
enable_plugin=$enableval,
|
||||
enable_plugin=yes; default_plugin=yes)
|
||||
|
||||
pluginlibs=
|
||||
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="nm${exeext} -g"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_nm -g"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="objdump${exeext} -T"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_objdump -T"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$enable_plugin" = x"yes"; then
|
||||
|
||||
AC_MSG_CHECKING([for exported symbols])
|
||||
if test "x$export_sym_check" != x; then
|
||||
echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
|
||||
${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
: # No need to use a flag
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_MSG_CHECKING([for -rdynamic])
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
plugin_rdynamic=yes
|
||||
pluginlibs="-rdynamic"
|
||||
else
|
||||
plugin_rdynamic=no
|
||||
enable_plugin=no
|
||||
fi
|
||||
AC_MSG_RESULT([$plugin_rdynamic])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([unable to check])
|
||||
fi
|
||||
|
||||
# Check -ldl
|
||||
saved_LIBS="$LIBS"
|
||||
AC_SEARCH_LIBS([dlopen], [dl])
|
||||
if test x"$ac_cv_search_dlopen" = x"-ldl"; then
|
||||
pluginlibs="$pluginlibs -ldl"
|
||||
fi
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
# Check that we can build shared objects with -fPIC -shared
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CFLAGS=`echo $CFLAGS | sed s/-mdynamic-no-pic//g`
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -shared -undefined dynamic_lookup"
|
||||
;;
|
||||
*)
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -fPIC -shared"
|
||||
;;
|
||||
esac
|
||||
AC_MSG_CHECKING([for -fPIC -shared])
|
||||
AC_TRY_LINK(
|
||||
[extern int X;],[return X == 0;],
|
||||
[AC_MSG_RESULT([yes]); have_pic_shared=yes],
|
||||
[AC_MSG_RESULT([no]); have_pic_shared=no])
|
||||
if test x"$have_pic_shared" != x"yes" -o x"$ac_cv_search_dlopen" = x"no"; then
|
||||
pluginlibs=
|
||||
enable_plugin=no
|
||||
fi
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
|
||||
# If plugin support had been requested but not available, fail.
|
||||
if test x"$enable_plugin" = x"no" ; then
|
||||
if test x"$default_plugin" != x"yes"; then
|
||||
AC_MSG_ERROR([
|
||||
Building GCC with plugin support requires a host that supports
|
||||
-fPIC, -shared, -ldl and -rdynamic.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
2
configure
vendored
2
configure
vendored
|
@ -2728,7 +2728,7 @@ host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktr
|
|||
# binutils, gas and ld appear in that order because it makes sense to run
|
||||
# "make check" in that particular order.
|
||||
# If --enable-gold is used, "gold" may replace "ld".
|
||||
host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools"
|
||||
host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools libcc1"
|
||||
|
||||
# libgcj represents the runtime libraries only used by gcj.
|
||||
libgcj="target-libffi \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
# 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
# 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
|
@ -141,7 +141,7 @@ host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktr
|
|||
# binutils, gas and ld appear in that order because it makes sense to run
|
||||
# "make check" in that particular order.
|
||||
# If --enable-gold is used, "gold" may replace "ld".
|
||||
host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools"
|
||||
host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools libcc1"
|
||||
|
||||
# libgcj represents the runtime libraries only used by gcj.
|
||||
libgcj="target-libffi \
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2014-10-27 Phil Muldoon <pmuldoon@redhat.com>
|
||||
Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* aclocal.m4, configure: Rebuild.
|
||||
* Makefile.in (aclocal_deps): Add gcc-plugin.m4.
|
||||
* configure.ac: Use GCC_ENABLE_PLUGINS.
|
||||
* stor-layout.c (finish_bitfield_layout): Now public. Change
|
||||
argument type to 'tree'.
|
||||
(finish_record_layout): Update.
|
||||
* stor-layout.h (finish_bitfield_layout): Declare.
|
||||
|
||||
2014-10-27 Alan Lawrence <alan.lawrence@arm.com>
|
||||
|
||||
* config/aarch64/aarch64.c (TARGET_GIMPLE_FOLD_BUILTIN): Define again.
|
||||
|
|
|
@ -1673,6 +1673,7 @@ aclocal_deps = \
|
|||
$(srcdir)/../config/codeset.m4 \
|
||||
$(srcdir)/../config/extensions.m4 \
|
||||
$(srcdir)/../config/gettext-sister.m4 \
|
||||
$(srcdir)/../config/gcc-plugin.m4 \
|
||||
$(srcdir)/../config/iconv.m4 \
|
||||
$(srcdir)/../config/lcmessage.m4 \
|
||||
$(srcdir)/../config/lib-ld.m4 \
|
||||
|
|
89
gcc/aclocal.m4
vendored
89
gcc/aclocal.m4
vendored
|
@ -11,94 +11,6 @@
|
|||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is `.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[dnl Rely on autoconf to set up CDPATH properly.
|
||||
AC_PREREQ([2.50])dnl
|
||||
# expand $ac_aux_dir to an absolute path
|
||||
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||
])
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 6
|
||||
|
||||
# AM_PROG_CC_C_O
|
||||
# --------------
|
||||
# Like AC_PROG_CC_C_O, but changed for automake.
|
||||
AC_DEFUN([AM_PROG_CC_C_O],
|
||||
[AC_REQUIRE([AC_PROG_CC_C_O])dnl
|
||||
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([compile])dnl
|
||||
# FIXME: we rely on the cache variable name because
|
||||
# there is no other way.
|
||||
set dummy $CC
|
||||
am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
|
||||
eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
|
||||
if test "$am_t" != yes; then
|
||||
# Losing compiler, so override with the script.
|
||||
# FIXME: It is wrong to rewrite CC.
|
||||
# But if we don't then we get into trouble of one sort or another.
|
||||
# A longer-term fix would be to have automake use am__CC in this case,
|
||||
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||
CC="$am_aux_dir/compile $CC"
|
||||
fi
|
||||
dnl Make sure AC_PROG_CC is never called again, or it will override our
|
||||
dnl setting of CC.
|
||||
m4_define([AC_PROG_CC],
|
||||
[m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
|
||||
])
|
||||
|
||||
m4_include([../libtool.m4])
|
||||
m4_include([../ltoptions.m4])
|
||||
m4_include([../ltsugar.m4])
|
||||
|
@ -108,6 +20,7 @@ m4_include([../config/acx.m4])
|
|||
m4_include([../config/codeset.m4])
|
||||
m4_include([../config/depstand.m4])
|
||||
m4_include([../config/dfp.m4])
|
||||
m4_include([../config/gcc-plugin.m4])
|
||||
m4_include([../config/gettext-sister.m4])
|
||||
m4_include([../config/iconv.m4])
|
||||
m4_include([../config/lcmessage.m4])
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
2014-10-27 Phil Muldoon <pmuldoon@redhat.com>
|
||||
Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* c-tree.h (enum c_oracle_request): New.
|
||||
(c_binding_oracle_function): New typedef.
|
||||
(c_binding_oracle, c_pushtag, c_bind): Declare.
|
||||
* c-decl.c (c_binding_oracle): New global.
|
||||
(I_SYMBOL_CHECKED): New macro.
|
||||
(i_symbol_binding): New function.
|
||||
(I_SYMBOL_BINDING, I_SYMBOL_DECL): Redefine.
|
||||
(I_TAG_CHECKED): New macro.
|
||||
(i_tag_binding): New function.
|
||||
(I_TAG_BINDING, I_TAG_DECL): Redefine.
|
||||
(I_LABEL_CHECKED): New macro.
|
||||
(i_label_binding): New function.
|
||||
(I_LABEL_BINDING, I_LABEL_DECL): Redefine.
|
||||
(c_print_identifier): Save and restore c_binding_oracle.
|
||||
(c_pushtag, c_bind): New functions.
|
||||
|
||||
2014-10-27 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* c-typeck.c: Adjust include files.
|
||||
|
|
164
gcc/c/c-decl.c
164
gcc/c/c-decl.c
|
@ -220,21 +220,6 @@ struct GTY((chain_next ("%h.prev"))) c_binding {
|
|||
#define B_IN_FILE_SCOPE(b) ((b)->depth == 1 /*file_scope->depth*/)
|
||||
#define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
|
||||
|
||||
#define I_SYMBOL_BINDING(node) \
|
||||
(((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->symbol_binding)
|
||||
#define I_SYMBOL_DECL(node) \
|
||||
(I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
|
||||
|
||||
#define I_TAG_BINDING(node) \
|
||||
(((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->tag_binding)
|
||||
#define I_TAG_DECL(node) \
|
||||
(I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
|
||||
|
||||
#define I_LABEL_BINDING(node) \
|
||||
(((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->label_binding)
|
||||
#define I_LABEL_DECL(node) \
|
||||
(I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
|
||||
|
||||
/* Each C symbol points to three linked lists of c_binding structures.
|
||||
These describe the values of the identifier in the three different
|
||||
namespaces defined by the language. */
|
||||
|
@ -250,6 +235,96 @@ struct GTY(()) lang_identifier {
|
|||
extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
|
||||
[(sizeof(struct lang_identifier) == C_SIZEOF_STRUCT_LANG_IDENTIFIER) ? 1 : -1];
|
||||
|
||||
/* The binding oracle; see c-tree.h. */
|
||||
void (*c_binding_oracle) (enum c_oracle_request, tree identifier);
|
||||
|
||||
/* This flag is set on an identifier if we have previously asked the
|
||||
binding oracle for this identifier's symbol binding. */
|
||||
#define I_SYMBOL_CHECKED(node) \
|
||||
(TREE_LANG_FLAG_4 (IDENTIFIER_NODE_CHECK (node)))
|
||||
|
||||
static inline struct c_binding* *
|
||||
i_symbol_binding (tree node)
|
||||
{
|
||||
struct lang_identifier *lid
|
||||
= (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
|
||||
|
||||
if (lid->symbol_binding == NULL
|
||||
&& c_binding_oracle != NULL
|
||||
&& !I_SYMBOL_CHECKED (node))
|
||||
{
|
||||
/* Set the "checked" flag first, to avoid infinite recursion
|
||||
when the binding oracle calls back into gcc. */
|
||||
I_SYMBOL_CHECKED (node) = 1;
|
||||
c_binding_oracle (C_ORACLE_SYMBOL, node);
|
||||
}
|
||||
|
||||
return &lid->symbol_binding;
|
||||
}
|
||||
|
||||
#define I_SYMBOL_BINDING(node) (*i_symbol_binding (node))
|
||||
|
||||
#define I_SYMBOL_DECL(node) \
|
||||
(I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
|
||||
|
||||
/* This flag is set on an identifier if we have previously asked the
|
||||
binding oracle for this identifier's tag binding. */
|
||||
#define I_TAG_CHECKED(node) \
|
||||
(TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (node)))
|
||||
|
||||
static inline struct c_binding **
|
||||
i_tag_binding (tree node)
|
||||
{
|
||||
struct lang_identifier *lid
|
||||
= (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
|
||||
|
||||
if (lid->tag_binding == NULL
|
||||
&& c_binding_oracle != NULL
|
||||
&& !I_TAG_CHECKED (node))
|
||||
{
|
||||
/* Set the "checked" flag first, to avoid infinite recursion
|
||||
when the binding oracle calls back into gcc. */
|
||||
I_TAG_CHECKED (node) = 1;
|
||||
c_binding_oracle (C_ORACLE_TAG, node);
|
||||
}
|
||||
|
||||
return &lid->tag_binding;
|
||||
}
|
||||
|
||||
#define I_TAG_BINDING(node) (*i_tag_binding (node))
|
||||
|
||||
#define I_TAG_DECL(node) \
|
||||
(I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
|
||||
|
||||
/* This flag is set on an identifier if we have previously asked the
|
||||
binding oracle for this identifier's label binding. */
|
||||
#define I_LABEL_CHECKED(node) \
|
||||
(TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (node)))
|
||||
|
||||
static inline struct c_binding **
|
||||
i_label_binding (tree node)
|
||||
{
|
||||
struct lang_identifier *lid
|
||||
= (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
|
||||
|
||||
if (lid->label_binding == NULL
|
||||
&& c_binding_oracle != NULL
|
||||
&& !I_LABEL_CHECKED (node))
|
||||
{
|
||||
/* Set the "checked" flag first, to avoid infinite recursion
|
||||
when the binding oracle calls back into gcc. */
|
||||
I_LABEL_CHECKED (node) = 1;
|
||||
c_binding_oracle (C_ORACLE_LABEL, node);
|
||||
}
|
||||
|
||||
return &lid->label_binding;
|
||||
}
|
||||
|
||||
#define I_LABEL_BINDING(node) (*i_label_binding (node))
|
||||
|
||||
#define I_LABEL_DECL(node) \
|
||||
(I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
|
||||
|
||||
/* The resulting tree type. */
|
||||
|
||||
union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
|
||||
|
@ -618,6 +693,15 @@ decl_jump_unsafe (tree decl)
|
|||
void
|
||||
c_print_identifier (FILE *file, tree node, int indent)
|
||||
{
|
||||
void (*save) (enum c_oracle_request, tree identifier);
|
||||
|
||||
/* Temporarily hide any binding oracle. Without this, calls to
|
||||
debug_tree from the debugger will end up calling into the oracle,
|
||||
making for a confusing debug session. As the oracle isn't needed
|
||||
here for normal operation, it's simplest to suppress it. */
|
||||
save = c_binding_oracle;
|
||||
c_binding_oracle = NULL;
|
||||
|
||||
print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
|
||||
print_node (file, "tag", I_TAG_DECL (node), indent + 4);
|
||||
print_node (file, "label", I_LABEL_DECL (node), indent + 4);
|
||||
|
@ -628,6 +712,8 @@ c_print_identifier (FILE *file, tree node, int indent)
|
|||
fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
|
||||
(void *) rid, IDENTIFIER_POINTER (rid));
|
||||
}
|
||||
|
||||
c_binding_oracle = save;
|
||||
}
|
||||
|
||||
/* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
|
||||
|
@ -1494,6 +1580,54 @@ pushtag (location_t loc, tree name, tree type)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* An exported interface to pushtag. This is used by the gdb plugin's
|
||||
binding oracle to introduce a new tag binding. */
|
||||
|
||||
void
|
||||
c_pushtag (location_t loc, tree name, tree type)
|
||||
{
|
||||
pushtag (loc, name, type);
|
||||
}
|
||||
|
||||
/* An exported interface to bind a declaration. LOC is the location
|
||||
to use. DECL is the declaration to bind. The decl's name is used
|
||||
to determine how it is bound. If DECL is a VAR_DECL, then
|
||||
IS_GLOBAL determines whether the decl is put into the global (file
|
||||
and external) scope or the current function's scope; if DECL is not
|
||||
a VAR_DECL then it is always put into the file scope. */
|
||||
|
||||
void
|
||||
c_bind (location_t loc, tree decl, bool is_global)
|
||||
{
|
||||
struct c_scope *scope;
|
||||
bool nested = false;
|
||||
|
||||
if (TREE_CODE (decl) != VAR_DECL || current_function_scope == NULL)
|
||||
{
|
||||
/* Types and functions are always considered to be global. */
|
||||
scope = file_scope;
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
}
|
||||
else if (is_global)
|
||||
{
|
||||
/* Also bind it into the external scope. */
|
||||
bind (DECL_NAME (decl), decl, external_scope, true, false, loc);
|
||||
nested = true;
|
||||
scope = file_scope;
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DECL_CONTEXT (decl) = current_function_decl;
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
scope = current_function_scope;
|
||||
}
|
||||
|
||||
bind (DECL_NAME (decl), decl, scope, false, nested, loc);
|
||||
}
|
||||
|
||||
/* Subroutine of compare_decls. Allow harmless mismatches in return
|
||||
and argument types provided that the type modes match. This function
|
||||
|
|
|
@ -673,12 +673,36 @@ extern int current_function_returns_abnormally;
|
|||
extern enum machine_mode c_default_pointer_mode;
|
||||
|
||||
/* In c-decl.c */
|
||||
|
||||
/* Tell the binding oracle what kind of binding we are looking for. */
|
||||
|
||||
enum c_oracle_request
|
||||
{
|
||||
C_ORACLE_SYMBOL,
|
||||
C_ORACLE_TAG,
|
||||
C_ORACLE_LABEL
|
||||
};
|
||||
|
||||
/* If this is non-NULL, then it is a "binding oracle" which can lazily
|
||||
create bindings when needed by the C compiler. The oracle is told
|
||||
the name and type of the binding to create. It can call pushdecl
|
||||
or the like to ensure the binding is visible; or do nothing,
|
||||
leaving the binding untouched. c-decl.c takes note of when the
|
||||
oracle has been called and will not call it again if it fails to
|
||||
create a given binding. */
|
||||
|
||||
typedef void c_binding_oracle_function (enum c_oracle_request, tree identifier);
|
||||
|
||||
extern c_binding_oracle_function *c_binding_oracle;
|
||||
|
||||
extern void c_finish_incomplete_decl (tree);
|
||||
extern void c_write_global_declarations (void);
|
||||
extern tree c_omp_reduction_id (enum tree_code, tree);
|
||||
extern tree c_omp_reduction_decl (tree);
|
||||
extern tree c_omp_reduction_lookup (tree, tree);
|
||||
extern tree c_check_omp_declare_reduction_r (tree *, int *, void *);
|
||||
extern void c_pushtag (location_t, tree, tree);
|
||||
extern void c_bind (location_t, tree, bool);
|
||||
|
||||
/* In c-errors.c */
|
||||
extern void pedwarn_c90 (location_t, int opt, const char *, ...)
|
||||
|
|
168
gcc/configure
vendored
168
gcc/configure
vendored
|
@ -27931,7 +27931,7 @@ $as_echo "#define HAVE_cloog 1" >>confdefs.h
|
|||
fi
|
||||
|
||||
# Check for plugin support
|
||||
# Check whether --enable-plugin was given.
|
||||
# Check whether --enable-plugin was given.
|
||||
if test "${enable_plugin+set}" = set; then :
|
||||
enableval=$enable_plugin; enable_plugin=$enableval
|
||||
else
|
||||
|
@ -27939,64 +27939,64 @@ else
|
|||
fi
|
||||
|
||||
|
||||
pluginlibs=
|
||||
pluginlibs=
|
||||
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="nm${exeext} -g"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_nm -g"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="objdump${exeext} -T"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_objdump -T"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="nm${exeext} -g"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_nm -g"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="objdump${exeext} -T"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_objdump -T"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$enable_plugin" = x"yes"; then
|
||||
if test x"$enable_plugin" = x"yes"; then
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exported symbols" >&5
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exported symbols" >&5
|
||||
$as_echo_n "checking for exported symbols... " >&6; }
|
||||
if test "x$export_sym_check" != x; then
|
||||
echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
|
||||
${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
: # No need to use a flag
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
if test "x$export_sym_check" != x; then
|
||||
echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
|
||||
${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
: # No need to use a flag
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -rdynamic" >&5
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -rdynamic" >&5
|
||||
$as_echo_n "checking for -rdynamic... " >&6; }
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
plugin_rdynamic=yes
|
||||
pluginlibs="-rdynamic"
|
||||
else
|
||||
plugin_rdynamic=no
|
||||
enable_plugin=no
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_rdynamic" >&5
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
plugin_rdynamic=yes
|
||||
pluginlibs="-rdynamic"
|
||||
else
|
||||
plugin_rdynamic=no
|
||||
enable_plugin=no
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_rdynamic" >&5
|
||||
$as_echo "$plugin_rdynamic" >&6; }
|
||||
fi
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to check" >&5
|
||||
fi
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to check" >&5
|
||||
$as_echo "unable to check" >&6; }
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check -ldl
|
||||
saved_LIBS="$LIBS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
|
||||
# Check -ldl
|
||||
saved_LIBS="$LIBS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
|
||||
$as_echo_n "checking for library containing dlopen... " >&6; }
|
||||
if test "${ac_cv_search_dlopen+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
|
@ -28052,28 +28052,28 @@ if test "$ac_res" != no; then :
|
|||
|
||||
fi
|
||||
|
||||
if test x"$ac_cv_search_dlopen" = x"-ldl"; then
|
||||
pluginlibs="$pluginlibs -ldl"
|
||||
fi
|
||||
LIBS="$saved_LIBS"
|
||||
if test x"$ac_cv_search_dlopen" = x"-ldl"; then
|
||||
pluginlibs="$pluginlibs -ldl"
|
||||
fi
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
# Check that we can build shared objects with -fPIC -shared
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CFLAGS=`echo $CFLAGS | sed s/-mdynamic-no-pic//g`
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -shared -undefined dynamic_lookup"
|
||||
;;
|
||||
*)
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -fPIC -shared"
|
||||
;;
|
||||
esac
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fPIC -shared" >&5
|
||||
# Check that we can build shared objects with -fPIC -shared
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CFLAGS=`echo $CFLAGS | sed s/-mdynamic-no-pic//g`
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -shared -undefined dynamic_lookup"
|
||||
;;
|
||||
*)
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -fPIC -shared"
|
||||
;;
|
||||
esac
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fPIC -shared" >&5
|
||||
$as_echo_n "checking for -fPIC -shared... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
extern int X;
|
||||
int
|
||||
|
@ -28093,22 +28093,22 @@ $as_echo "no" >&6; }; have_pic_shared=no
|
|||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
if test x"$have_pic_shared" != x"yes" -o x"$ac_cv_search_dlopen" = x"no"; then
|
||||
pluginlibs=
|
||||
enable_plugin=no
|
||||
fi
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
if test x"$have_pic_shared" != x"yes" -o x"$ac_cv_search_dlopen" = x"no"; then
|
||||
pluginlibs=
|
||||
enable_plugin=no
|
||||
fi
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
|
||||
# If plugin support had been requested but not available, fail.
|
||||
if test x"$enable_plugin" = x"no" ; then
|
||||
if test x"$default_plugin" != x"yes"; then
|
||||
as_fn_error "
|
||||
Building GCC with plugin support requires a host that supports
|
||||
-fPIC, -shared, -ldl and -rdynamic." "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# If plugin support had been requested but not available, fail.
|
||||
if test x"$enable_plugin" = x"no" ; then
|
||||
if test x"$default_plugin" != x"yes"; then
|
||||
as_fn_error "
|
||||
Building GCC with plugin support requires a host that supports
|
||||
-fPIC, -shared, -ldl and -rdynamic." "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
|
100
gcc/configure.ac
100
gcc/configure.ac
|
@ -5548,105 +5548,7 @@ if test "x${CLOOGLIBS}" != "x" ; then
|
|||
AC_DEFINE(HAVE_cloog, 1, [Define if cloog is in use.])
|
||||
fi
|
||||
|
||||
# Check for plugin support
|
||||
AC_ARG_ENABLE(plugin,
|
||||
[AS_HELP_STRING([--enable-plugin], [enable plugin support])],
|
||||
enable_plugin=$enableval,
|
||||
enable_plugin=yes; default_plugin=yes)
|
||||
|
||||
pluginlibs=
|
||||
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="nm${exeext} -g"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_nm -g"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if test x$build = x$host; then
|
||||
export_sym_check="objdump${exeext} -T"
|
||||
elif test x$host = x$target; then
|
||||
export_sym_check="$gcc_cv_objdump -T"
|
||||
else
|
||||
export_sym_check=
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$enable_plugin" = x"yes"; then
|
||||
|
||||
AC_MSG_CHECKING([for exported symbols])
|
||||
if test "x$export_sym_check" != x; then
|
||||
echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
|
||||
${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
: # No need to use a flag
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_MSG_CHECKING([for -rdynamic])
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest$ac_exeext > /dev/null 2>&1
|
||||
if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
|
||||
plugin_rdynamic=yes
|
||||
pluginlibs="-rdynamic"
|
||||
else
|
||||
plugin_rdynamic=no
|
||||
enable_plugin=no
|
||||
fi
|
||||
AC_MSG_RESULT([$plugin_rdynamic])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([unable to check])
|
||||
fi
|
||||
|
||||
# Check -ldl
|
||||
saved_LIBS="$LIBS"
|
||||
AC_SEARCH_LIBS([dlopen], [dl])
|
||||
if test x"$ac_cv_search_dlopen" = x"-ldl"; then
|
||||
pluginlibs="$pluginlibs -ldl"
|
||||
fi
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
# Check that we can build shared objects with -fPIC -shared
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CFLAGS=`echo $CFLAGS | sed s/-mdynamic-no-pic//g`
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -shared -undefined dynamic_lookup"
|
||||
;;
|
||||
*)
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
LDFLAGS="$LDFLAGS -fPIC -shared"
|
||||
;;
|
||||
esac
|
||||
AC_MSG_CHECKING([for -fPIC -shared])
|
||||
AC_TRY_LINK(
|
||||
[extern int X;],[return X == 0;],
|
||||
[AC_MSG_RESULT([yes]); have_pic_shared=yes],
|
||||
[AC_MSG_RESULT([no]); have_pic_shared=no])
|
||||
if test x"$have_pic_shared" != x"yes" -o x"$ac_cv_search_dlopen" = x"no"; then
|
||||
pluginlibs=
|
||||
enable_plugin=no
|
||||
fi
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
|
||||
# If plugin support had been requested but not available, fail.
|
||||
if test x"$enable_plugin" = x"no" ; then
|
||||
if test x"$default_plugin" != x"yes"; then
|
||||
AC_MSG_ERROR([
|
||||
Building GCC with plugin support requires a host that supports
|
||||
-fPIC, -shared, -ldl and -rdynamic.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
GCC_ENABLE_PLUGINS
|
||||
AC_SUBST(pluginlibs)
|
||||
AC_SUBST(enable_plugin)
|
||||
if test x"$enable_plugin" = x"yes"; then
|
||||
|
|
|
@ -1959,10 +1959,10 @@ finish_bitfield_representative (tree repr, tree field)
|
|||
}
|
||||
|
||||
/* Compute and set FIELD_DECLs for the underlying objects we should
|
||||
use for bitfield access for the structure laid out with RLI. */
|
||||
use for bitfield access for the structure T. */
|
||||
|
||||
static void
|
||||
finish_bitfield_layout (record_layout_info rli)
|
||||
void
|
||||
finish_bitfield_layout (tree t)
|
||||
{
|
||||
tree field, prev;
|
||||
tree repr = NULL_TREE;
|
||||
|
@ -1971,10 +1971,10 @@ finish_bitfield_layout (record_layout_info rli)
|
|||
we could use the underlying type as hint for the representative
|
||||
if the bitfield would fit and the representative would not exceed
|
||||
the union in size. */
|
||||
if (TREE_CODE (rli->t) != RECORD_TYPE)
|
||||
if (TREE_CODE (t) != RECORD_TYPE)
|
||||
return;
|
||||
|
||||
for (prev = NULL_TREE, field = TYPE_FIELDS (rli->t);
|
||||
for (prev = NULL_TREE, field = TYPE_FIELDS (t);
|
||||
field; field = DECL_CHAIN (field))
|
||||
{
|
||||
if (TREE_CODE (field) != FIELD_DECL)
|
||||
|
@ -2061,7 +2061,7 @@ finish_record_layout (record_layout_info rli, int free_p)
|
|||
finalize_type_size (rli->t);
|
||||
|
||||
/* Compute bitfield representatives. */
|
||||
finish_bitfield_layout (rli);
|
||||
finish_bitfield_layout (rli->t);
|
||||
|
||||
/* Propagate TYPE_PACKED to variants. With C++ templates,
|
||||
handle_packed_attribute is too early to do this. */
|
||||
|
|
|
@ -35,6 +35,7 @@ extern tree rli_size_so_far (record_layout_info);
|
|||
extern void normalize_rli (record_layout_info);
|
||||
extern void place_field (record_layout_info, tree);
|
||||
extern void compute_record_mode (tree);
|
||||
extern void finish_bitfield_layout (tree);
|
||||
extern void finish_record_layout (record_layout_info, int);
|
||||
extern unsigned int element_precision (const_tree);
|
||||
extern void finalize_size_functions (void);
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2014-10-27 Phil Muldoon <pmuldoon@redhat.com>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gcc-c-fe.def: New file.
|
||||
* gcc-c-interface.h: New file.
|
||||
* gcc-interface.h: New file.
|
||||
|
||||
2014-10-15 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* libiberty.h (choose_tmpdir): New prototype.
|
||||
|
|
197
include/gcc-c-fe.def
Normal file
197
include/gcc-c-fe.def
Normal file
|
@ -0,0 +1,197 @@
|
|||
/* Interface between GCC C FE and GDB -*- c -*-
|
||||
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
|
||||
/* Create a new "decl" in GCC. A decl is a declaration, basically a
|
||||
kind of symbol.
|
||||
|
||||
NAME is the name of the new symbol. SYM_KIND is the kind of
|
||||
symbol being requested. SYM_TYPE is the new symbol's C type;
|
||||
except for labels, where this is not meaningful and should be
|
||||
zero. If SUBSTITUTION_NAME is not NULL, then a reference to this
|
||||
decl in the source will later be substituted with a dereference
|
||||
of a variable of the given name. Otherwise, for symbols having
|
||||
an address (e.g., functions), ADDRESS is the address. FILENAME
|
||||
and LINE_NUMBER refer to the symbol's source location. If this
|
||||
is not known, FILENAME can be NULL and LINE_NUMBER can be 0.
|
||||
This function returns the new decl. */
|
||||
|
||||
GCC_METHOD7 (gcc_decl, build_decl,
|
||||
const char *, /* Argument NAME. */
|
||||
enum gcc_c_symbol_kind, /* Argument SYM_KIND. */
|
||||
gcc_type, /* Argument SYM_TYPE. */
|
||||
const char *, /* Argument SUBSTITUTION_NAME. */
|
||||
gcc_address, /* Argument ADDRESS. */
|
||||
const char *, /* Argument FILENAME. */
|
||||
unsigned int) /* Argument LINE_NUMBER. */
|
||||
|
||||
/* Insert a GCC decl into the symbol table. DECL is the decl to
|
||||
insert. IS_GLOBAL is true if this is an outermost binding, and
|
||||
false if it is a possibly-shadowing binding. */
|
||||
|
||||
GCC_METHOD2 (int /* bool */, bind,
|
||||
gcc_decl, /* Argument DECL. */
|
||||
int /* bool */) /* Argument IS_GLOBAL. */
|
||||
|
||||
/* Insert a tagged type into the symbol table. NAME is the tag name
|
||||
of the type and TAGGED_TYPE is the type itself. TAGGED_TYPE must
|
||||
be either a struct, union, or enum type, as these are the only
|
||||
types that have tags. FILENAME and LINE_NUMBER refer to the type's
|
||||
source location. If this is not known, FILENAME can be NULL and
|
||||
LINE_NUMBER can be 0. */
|
||||
|
||||
GCC_METHOD4 (int /* bool */, tagbind,
|
||||
const char *, /* Argument NAME. */
|
||||
gcc_type, /* Argument TAGGED_TYPE. */
|
||||
const char *, /* Argument FILENAME. */
|
||||
unsigned int) /* Argument LINE_NUMBER. */
|
||||
|
||||
/* Return the type of a pointer to a given base type. */
|
||||
|
||||
GCC_METHOD1 (gcc_type, build_pointer_type,
|
||||
gcc_type) /* Argument BASE_TYPE. */
|
||||
|
||||
/* Create a new 'struct' type. Initially it has no fields. */
|
||||
|
||||
GCC_METHOD0 (gcc_type, build_record_type)
|
||||
|
||||
/* Create a new 'union' type. Initially it has no fields. */
|
||||
|
||||
GCC_METHOD0 (gcc_type, build_union_type)
|
||||
|
||||
/* Add a field to a struct or union type. FIELD_NAME is the field's
|
||||
name. FIELD_TYPE is the type of the field. BITSIZE and BITPOS
|
||||
indicate where in the struct the field occurs. */
|
||||
|
||||
GCC_METHOD5 (int /* bool */, build_add_field,
|
||||
gcc_type, /* Argument RECORD_OR_UNION_TYPE. */
|
||||
const char *, /* Argument FIELD_NAME. */
|
||||
gcc_type, /* Argument FIELD_TYPE. */
|
||||
unsigned long, /* Argument BITSIZE. */
|
||||
unsigned long) /* Argument BITPOS. */
|
||||
|
||||
/* After all the fields have been added to a struct or union, the
|
||||
struct or union type must be "finished". This does some final
|
||||
cleanups in GCC. */
|
||||
|
||||
GCC_METHOD2 (int /* bool */, finish_record_or_union,
|
||||
gcc_type, /* Argument RECORD_OR_UNION_TYPE. */
|
||||
unsigned long) /* Argument SIZE_IN_BYTES. */
|
||||
|
||||
/* Create a new 'enum' type. The new type initially has no
|
||||
associated constants. */
|
||||
|
||||
GCC_METHOD1 (gcc_type, build_enum_type,
|
||||
gcc_type) /* Argument UNDERLYING_INT_TYPE. */
|
||||
|
||||
/* Add a new constant to an enum type. NAME is the constant's
|
||||
name and VALUE is its value. */
|
||||
|
||||
GCC_METHOD3 (int /* bool */, build_add_enum_constant,
|
||||
gcc_type, /* Argument ENUM_TYPE. */
|
||||
const char *, /* Argument NAME. */
|
||||
unsigned long) /* Argument VALUE. */
|
||||
|
||||
/* After all the constants have been added to an enum, the type must
|
||||
be "finished". This does some final cleanups in GCC. */
|
||||
|
||||
GCC_METHOD1 (int /* bool */, finish_enum_type,
|
||||
gcc_type) /* Argument ENUM_TYPE. */
|
||||
|
||||
/* Create a new function type. RETURN_TYPE is the type returned by
|
||||
the function, and ARGUMENT_TYPES is a vector, of length NARGS, of
|
||||
the argument types. IS_VARARGS is true if the function is
|
||||
varargs. */
|
||||
|
||||
GCC_METHOD3 (gcc_type, build_function_type,
|
||||
gcc_type, /* Argument RETURN_TYPE. */
|
||||
const struct gcc_type_array *, /* Argument ARGUMENT_TYPES. */
|
||||
int /* bool */) /* Argument IS_VARARGS. */
|
||||
|
||||
/* Return an integer type with the given properties. */
|
||||
|
||||
GCC_METHOD2 (gcc_type, int_type,
|
||||
int /* bool */, /* Argument IS_UNSIGNED. */
|
||||
unsigned long) /* Argument SIZE_IN_BYTES. */
|
||||
|
||||
/* Return a floating point type with the given properties. */
|
||||
|
||||
GCC_METHOD1 (gcc_type, float_type,
|
||||
unsigned long) /* Argument SIZE_IN_BYTES. */
|
||||
|
||||
/* Return the 'void' type. */
|
||||
|
||||
GCC_METHOD0 (gcc_type, void_type)
|
||||
|
||||
/* Return the 'bool' type. */
|
||||
|
||||
GCC_METHOD0 (gcc_type, bool_type)
|
||||
|
||||
/* Create a new array type. If NUM_ELEMENTS is -1, then the array
|
||||
is assumed to have an unknown length. */
|
||||
|
||||
GCC_METHOD2 (gcc_type, build_array_type,
|
||||
gcc_type, /* Argument ELEMENT_TYPE. */
|
||||
int) /* Argument NUM_ELEMENTS. */
|
||||
|
||||
/* Create a new variably-sized array type. UPPER_BOUND_NAME is the
|
||||
name of a local variable that holds the upper bound of the array;
|
||||
it is one less than the array size. */
|
||||
|
||||
GCC_METHOD2 (gcc_type, build_vla_array_type,
|
||||
gcc_type, /* Argument ELEMENT_TYPE. */
|
||||
const char *) /* Argument UPPER_BOUND_NAME. */
|
||||
|
||||
/* Return a qualified variant of a given base type. QUALIFIERS says
|
||||
which qualifiers to use; it is composed of or'd together
|
||||
constants from 'enum gcc_qualifiers'. */
|
||||
|
||||
GCC_METHOD2 (gcc_type, build_qualified_type,
|
||||
gcc_type, /* Argument UNQUALIFIED_TYPE. */
|
||||
enum gcc_qualifiers) /* Argument QUALIFIERS. */
|
||||
|
||||
/* Build a complex type given its element type. */
|
||||
|
||||
GCC_METHOD1 (gcc_type, build_complex_type,
|
||||
gcc_type) /* Argument ELEMENT_TYPE. */
|
||||
|
||||
/* Build a vector type given its element type and number of
|
||||
elements. */
|
||||
|
||||
GCC_METHOD2 (gcc_type, build_vector_type,
|
||||
gcc_type, /* Argument ELEMENT_TYPE. */
|
||||
int) /* Argument NUM_ELEMENTS. */
|
||||
|
||||
/* Build a constant. NAME is the constant's name and VALUE is its
|
||||
value. FILENAME and LINE_NUMBER refer to the type's source
|
||||
location. If this is not known, FILENAME can be NULL and
|
||||
LINE_NUMBER can be 0. */
|
||||
|
||||
GCC_METHOD5 (int /* bool */, build_constant,
|
||||
gcc_type, /* Argument TYPE. */
|
||||
const char *, /* Argument NAME. */
|
||||
unsigned long, /* Argument VALUE. */
|
||||
const char *, /* Argument FILENAME. */
|
||||
unsigned int) /* Argument LINE_NUMBER. */
|
||||
|
||||
/* Emit an error and return an error type object. */
|
||||
|
||||
GCC_METHOD1 (gcc_type, error,
|
||||
const char *) /* Argument MESSAGE. */
|
220
include/gcc-c-interface.h
Normal file
220
include/gcc-c-interface.h
Normal file
|
@ -0,0 +1,220 @@
|
|||
/* Interface between GCC C FE and GDB
|
||||
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_C_INTERFACE_H
|
||||
#define GCC_C_INTERFACE_H
|
||||
|
||||
#include "gcc-interface.h"
|
||||
|
||||
/* This header defines the interface to the GCC API. It must be both
|
||||
valid C and valid C++, because it is included by both programs. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Forward declaration. */
|
||||
|
||||
struct gcc_c_context;
|
||||
|
||||
/*
|
||||
* Definitions and declarations for the C front end.
|
||||
*/
|
||||
|
||||
/* Defined versions of the C front-end API. */
|
||||
|
||||
enum gcc_c_api_version
|
||||
{
|
||||
GCC_C_FE_VERSION_0 = 0
|
||||
};
|
||||
|
||||
/* Qualifiers. */
|
||||
|
||||
enum gcc_qualifiers
|
||||
{
|
||||
GCC_QUALIFIER_CONST = 1,
|
||||
GCC_QUALIFIER_VOLATILE = 2,
|
||||
GCC_QUALIFIER_RESTRICT = 4
|
||||
};
|
||||
|
||||
/* This enumerates the kinds of decls that GDB can create. */
|
||||
|
||||
enum gcc_c_symbol_kind
|
||||
{
|
||||
/* A function. */
|
||||
|
||||
GCC_C_SYMBOL_FUNCTION,
|
||||
|
||||
/* A variable. */
|
||||
|
||||
GCC_C_SYMBOL_VARIABLE,
|
||||
|
||||
/* A typedef. */
|
||||
|
||||
GCC_C_SYMBOL_TYPEDEF,
|
||||
|
||||
/* A label. */
|
||||
|
||||
GCC_C_SYMBOL_LABEL
|
||||
};
|
||||
|
||||
/* This enumerates the types of symbols that GCC might request from
|
||||
GDB. */
|
||||
|
||||
enum gcc_c_oracle_request
|
||||
{
|
||||
/* An ordinary symbol -- a variable, function, typedef, or enum
|
||||
constant. */
|
||||
|
||||
GCC_C_ORACLE_SYMBOL,
|
||||
|
||||
/* A struct, union, or enum tag. */
|
||||
|
||||
GCC_C_ORACLE_TAG,
|
||||
|
||||
/* A label. */
|
||||
|
||||
GCC_C_ORACLE_LABEL
|
||||
};
|
||||
|
||||
/* The type of the function called by GCC to ask GDB for a symbol's
|
||||
definition. DATUM is an arbitrary value supplied when the oracle
|
||||
function is registered. CONTEXT is the GCC context in which the
|
||||
request is being made. REQUEST specifies what sort of symbol is
|
||||
being requested, and IDENTIFIER is the name of the symbol. */
|
||||
|
||||
typedef void gcc_c_oracle_function (void *datum,
|
||||
struct gcc_c_context *context,
|
||||
enum gcc_c_oracle_request request,
|
||||
const char *identifier);
|
||||
|
||||
/* The type of the function called by GCC to ask GDB for a symbol's
|
||||
address. This should return 0 if the address is not known. */
|
||||
|
||||
typedef gcc_address gcc_c_symbol_address_function (void *datum,
|
||||
struct gcc_c_context *ctxt,
|
||||
const char *identifier);
|
||||
|
||||
/* An array of types used for creating a function type. */
|
||||
|
||||
struct gcc_type_array
|
||||
{
|
||||
/* Number of elements. */
|
||||
|
||||
int n_elements;
|
||||
|
||||
/* The elements. */
|
||||
|
||||
gcc_type *elements;
|
||||
};
|
||||
|
||||
/* The vtable used by the C front end. */
|
||||
|
||||
struct gcc_c_fe_vtable
|
||||
{
|
||||
/* The version of the C interface. The value is one of the
|
||||
gcc_c_api_version constants. */
|
||||
|
||||
unsigned int c_version;
|
||||
|
||||
/* Set the callbacks for this context.
|
||||
|
||||
The binding oracle is called whenever the C parser needs to look
|
||||
up a symbol. This gives the caller a chance to lazily
|
||||
instantiate symbols using other parts of the gcc_c_fe_interface
|
||||
API.
|
||||
|
||||
The address oracle is called whenever the C parser needs to look
|
||||
up a symbol. This is only called for symbols not provided by the
|
||||
symbol oracle -- that is, just built-in functions where GCC
|
||||
provides the declaration.
|
||||
|
||||
DATUM is an arbitrary piece of data that is passed back verbatim
|
||||
to the callbakcs in requests. */
|
||||
|
||||
void (*set_callbacks) (struct gcc_c_context *self,
|
||||
gcc_c_oracle_function *binding_oracle,
|
||||
gcc_c_symbol_address_function *address_oracle,
|
||||
void *datum);
|
||||
|
||||
#define GCC_METHOD0(R, N) \
|
||||
R (*N) (struct gcc_c_context *);
|
||||
#define GCC_METHOD1(R, N, A) \
|
||||
R (*N) (struct gcc_c_context *, A);
|
||||
#define GCC_METHOD2(R, N, A, B) \
|
||||
R (*N) (struct gcc_c_context *, A, B);
|
||||
#define GCC_METHOD3(R, N, A, B, C) \
|
||||
R (*N) (struct gcc_c_context *, A, B, C);
|
||||
#define GCC_METHOD4(R, N, A, B, C, D) \
|
||||
R (*N) (struct gcc_c_context *, A, B, C, D);
|
||||
#define GCC_METHOD5(R, N, A, B, C, D, E) \
|
||||
R (*N) (struct gcc_c_context *, A, B, C, D, E);
|
||||
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
|
||||
R (*N) (struct gcc_c_context *, A, B, C, D, E, F, G);
|
||||
|
||||
#include "gcc-c-fe.def"
|
||||
|
||||
#undef GCC_METHOD0
|
||||
#undef GCC_METHOD1
|
||||
#undef GCC_METHOD2
|
||||
#undef GCC_METHOD3
|
||||
#undef GCC_METHOD4
|
||||
#undef GCC_METHOD5
|
||||
#undef GCC_METHOD7
|
||||
|
||||
};
|
||||
|
||||
/* The C front end object. */
|
||||
|
||||
struct gcc_c_context
|
||||
{
|
||||
/* Base class. */
|
||||
|
||||
struct gcc_base_context base;
|
||||
|
||||
/* Our vtable. This is a separate field because this is simpler
|
||||
than implementing a vtable inheritance scheme in C. */
|
||||
|
||||
const struct gcc_c_fe_vtable *c_ops;
|
||||
};
|
||||
|
||||
/* The name of the .so that the compiler builds. We dlopen this
|
||||
later. */
|
||||
|
||||
#define GCC_C_FE_LIBCC libcc1.so
|
||||
|
||||
/* The compiler exports a single initialization function. This macro
|
||||
holds its name as a symbol. */
|
||||
|
||||
#define GCC_C_FE_CONTEXT gcc_c_fe_context
|
||||
|
||||
/* The type of the initialization function. The caller passes in the
|
||||
desired base version and desired C-specific version. If the
|
||||
request can be satisfied, a compatible gcc_context object will be
|
||||
returned. Otherwise, the function returns NULL. */
|
||||
|
||||
typedef struct gcc_c_context *gcc_c_fe_context_function
|
||||
(enum gcc_base_api_version,
|
||||
enum gcc_c_api_version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GCC_C_INTERFACE_H */
|
127
include/gcc-interface.h
Normal file
127
include/gcc-interface.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* Generic interface between GCC and GDB
|
||||
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_INTERFACE_H
|
||||
#define GCC_INTERFACE_H
|
||||
|
||||
/* This header defines the interface to the GCC API. It must be both
|
||||
valid C and valid C++, because it is included by both programs. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Opaque typedefs for objects passed through the interface. */
|
||||
|
||||
typedef unsigned long long gcc_type;
|
||||
typedef unsigned long long gcc_decl;
|
||||
|
||||
/* An address in the inferior. */
|
||||
|
||||
typedef unsigned long long gcc_address;
|
||||
|
||||
/* Forward declaration. */
|
||||
|
||||
struct gcc_base_context;
|
||||
|
||||
/* Defined versions of the generic API. */
|
||||
|
||||
enum gcc_base_api_version
|
||||
{
|
||||
GCC_FE_VERSION_0 = 0
|
||||
};
|
||||
|
||||
/* The operations defined by the GCC base API. This is the vtable for
|
||||
the real context structure which is passed around.
|
||||
|
||||
The "base" API is concerned with basics shared by all compiler
|
||||
front ends: setting command-line arguments, the file names, etc.
|
||||
|
||||
Front-end-specific interfaces inherit from this one. */
|
||||
|
||||
struct gcc_base_vtable
|
||||
{
|
||||
/* The actual version implemented in this interface. This field can
|
||||
be relied on not to move, so users can always check it if they
|
||||
desire. The value is one of the gcc_base_api_version constants.
|
||||
*/
|
||||
|
||||
unsigned int version;
|
||||
|
||||
/* Set the compiler's command-line options for the next compilation.
|
||||
TRIPLET_REGEXP is a regular expression that is used to match the
|
||||
configury triplet prefix to the compiler.
|
||||
The arguments are copied by GCC. ARGV need not be
|
||||
NULL-terminated. The arguments must be set separately for each
|
||||
compilation; that is, after a compile is requested, the
|
||||
previously-set arguments cannot be reused.
|
||||
|
||||
This returns NULL on success. On failure, returns a malloc()d
|
||||
error message. The caller is responsible for freeing it. */
|
||||
|
||||
char *(*set_arguments) (struct gcc_base_context *self,
|
||||
const char *triplet_regexp,
|
||||
int argc, char **argv);
|
||||
|
||||
/* Set the file name of the program to compile. The string is
|
||||
copied by the method implementation, but the caller must
|
||||
guarantee that the file exists through the compilation. */
|
||||
|
||||
void (*set_source_file) (struct gcc_base_context *self, const char *file);
|
||||
|
||||
/* Set a callback to use for printing error messages. DATUM is
|
||||
passed through to the callback unchanged. */
|
||||
|
||||
void (*set_print_callback) (struct gcc_base_context *self,
|
||||
void (*print_function) (void *datum,
|
||||
const char *message),
|
||||
void *datum);
|
||||
|
||||
/* Perform the compilation. FILENAME is the name of the resulting
|
||||
object file. VERBOSE can be set to cause GCC to print some
|
||||
information as it works. Returns true on success, false on
|
||||
error. */
|
||||
|
||||
int /* bool */ (*compile) (struct gcc_base_context *self,
|
||||
const char *filename,
|
||||
int /* bool */ verbose);
|
||||
|
||||
/* Destroy this object. */
|
||||
|
||||
void (*destroy) (struct gcc_base_context *self);
|
||||
};
|
||||
|
||||
/* The GCC object. */
|
||||
|
||||
struct gcc_base_context
|
||||
{
|
||||
/* The virtual table. */
|
||||
|
||||
const struct gcc_base_vtable *ops;
|
||||
};
|
||||
|
||||
/* The name of the dummy wrapper function generated by gdb. */
|
||||
|
||||
#define GCC_FE_WRAPPER_FUNCTION "_gdb_expr"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GCC_INTERFACE_H */
|
26
libcc1/ChangeLog
Normal file
26
libcc1/ChangeLog
Normal file
|
@ -0,0 +1,26 @@
|
|||
2014-10-27 Phil Muldoon <pmuldoon@redhat.com>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* aclocal.m4: New file.
|
||||
* callbacks.cc: New file.
|
||||
* callbacks.hh: New file.
|
||||
* cc1plugin-config.h.in: New file.
|
||||
* configure: New file.
|
||||
* configure.ac: New file.
|
||||
* connection.cc: New file.
|
||||
* connection.hh: New file.
|
||||
* findcomp.cc: New file.
|
||||
* findcomp.hh: New file.
|
||||
* libcc1.cc: New file.
|
||||
* libcc1plugin.sym: New file.
|
||||
* libcc1.sym: New file.
|
||||
* Makefile.am: New file.
|
||||
* Makefile.in: New file.
|
||||
* marshall.cc: New file.
|
||||
* marshall.hh: New file.
|
||||
* names.cc: New file.
|
||||
* names.hh: New file.
|
||||
* plugin.cc: New file.
|
||||
* rpc.hh: New file.
|
||||
* status.hh: New file.
|
55
libcc1/Makefile.am
Normal file
55
libcc1/Makefile.am
Normal file
|
@ -0,0 +1,55 @@
|
|||
## Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
## This file is part of GCC.
|
||||
|
||||
## GCC is free software; you can redistribute it and/or modify it under
|
||||
## the terms of the GNU General Public License as published by the Free
|
||||
## Software Foundation; either version 3, or (at your option) any later
|
||||
## version.
|
||||
|
||||
## GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
## for more details.
|
||||
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with GCC; see the file COPYING3. If not see
|
||||
## <http://www.gnu.org/licenses/>.
|
||||
|
||||
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||
gcc_build_dir = ../$(host_subdir)/gcc
|
||||
AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
|
||||
-I $(gcc_build_dir) -I$(srcdir)/../gcc \
|
||||
-I $(srcdir)/../gcc/c -I $(srcdir)/../gcc/c-family \
|
||||
-I $(srcdir)/../libcpp/include
|
||||
WERROR_FLAG = -Werror
|
||||
AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR_FLAG) $(visibility)
|
||||
libiberty = ../libiberty/pic/libiberty.a
|
||||
|
||||
|
||||
plugindir = $(libdir)/gcc/$(target_noncanonical)/$(gcc_version)/plugin
|
||||
cc1libdir = $(libdir)/$(libsuffix)
|
||||
|
||||
if ENABLE_PLUGIN
|
||||
plugin_LTLIBRARIES = libcc1plugin.la
|
||||
cc1lib_LTLIBRARIES = libcc1.la
|
||||
endif
|
||||
|
||||
BUILT_SOURCES = compiler-name.h
|
||||
|
||||
# Put this in a header so we don't run sed for each compilation. This
|
||||
# is also simpler to debug as one can easily see the constant.
|
||||
compiler-name.h: Makefile
|
||||
echo "#define COMPILER_NAME \"`echo gcc | sed '$(transform)'`\"" > compiler-name.h
|
||||
|
||||
|
||||
shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \
|
||||
marshall.cc marshall.hh rpc.hh status.hh
|
||||
|
||||
libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
|
||||
libcc1plugin_la_SOURCES = plugin.cc $(shared_source)
|
||||
libcc1plugin_la_LIBADD = $(libiberty)
|
||||
|
||||
libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym
|
||||
libcc1_la_SOURCES = findcomp.cc libcc1.cc names.cc names.hh $(shared_source)
|
||||
libcc1_la_LIBADD = $(libiberty)
|
630
libcc1/Makefile.in
Normal file
630
libcc1/Makefile.in
Normal file
|
@ -0,0 +1,630 @@
|
|||
# Makefile.in generated by automake 1.11.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = .
|
||||
DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
||||
$(top_srcdir)/configure $(am__configure_deps) \
|
||||
$(srcdir)/cc1plugin-config.h.in $(srcdir)/../mkinstalldirs \
|
||||
$(srcdir)/../depcomp
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
|
||||
$(top_srcdir)/../config/depstand.m4 \
|
||||
$(top_srcdir)/../config/gcc-plugin.m4 \
|
||||
$(top_srcdir)/../config/lead-dot.m4 \
|
||||
$(top_srcdir)/../config/override.m4 \
|
||||
$(top_srcdir)/../config/warnings.m4 \
|
||||
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
|
||||
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
|
||||
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno config.status.lineno
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
|
||||
CONFIG_HEADER = cc1plugin-config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(cc1libdir)" "$(DESTDIR)$(plugindir)"
|
||||
LTLIBRARIES = $(cc1lib_LTLIBRARIES) $(plugin_LTLIBRARIES)
|
||||
libcc1_la_DEPENDENCIES = $(libiberty)
|
||||
am__objects_1 = callbacks.lo connection.lo marshall.lo
|
||||
am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo names.lo $(am__objects_1)
|
||||
libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS)
|
||||
libcc1_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||
$(CXXFLAGS) $(libcc1_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
@ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir)
|
||||
libcc1plugin_la_DEPENDENCIES = $(libiberty)
|
||||
am_libcc1plugin_la_OBJECTS = plugin.lo $(am__objects_1)
|
||||
libcc1plugin_la_OBJECTS = $(am_libcc1plugin_la_OBJECTS)
|
||||
libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||
$(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
@ENABLE_PLUGIN_TRUE@am_libcc1plugin_la_rpath = -rpath $(plugindir)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(libcc1_la_SOURCES) $(libcc1plugin_la_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
WARN_FLAGS = @WARN_FLAGS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_libsubdir = @build_libsubdir@
|
||||
build_os = @build_os@
|
||||
build_subdir = @build_subdir@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
gcc_version = @gcc_version@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_subdir = @host_subdir@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
libsuffix = @libsuffix@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_noncanonical = @target_noncanonical@
|
||||
target_os = @target_os@
|
||||
target_subdir = @target_subdir@
|
||||
target_vendor = @target_vendor@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
visibility = @visibility@
|
||||
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||
gcc_build_dir = ../$(host_subdir)/gcc
|
||||
AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
|
||||
-I $(gcc_build_dir) -I$(srcdir)/../gcc \
|
||||
-I $(srcdir)/../gcc/c -I $(srcdir)/../gcc/c-family \
|
||||
-I $(srcdir)/../libcpp/include
|
||||
|
||||
WERROR_FLAG = -Werror
|
||||
AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR_FLAG) $(visibility)
|
||||
libiberty = ../libiberty/pic/libiberty.a
|
||||
plugindir = $(libdir)/gcc/$(target_noncanonical)/$(gcc_version)/plugin
|
||||
cc1libdir = $(libdir)/$(libsuffix)
|
||||
@ENABLE_PLUGIN_TRUE@plugin_LTLIBRARIES = libcc1plugin.la
|
||||
@ENABLE_PLUGIN_TRUE@cc1lib_LTLIBRARIES = libcc1.la
|
||||
BUILT_SOURCES = compiler-name.h
|
||||
shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \
|
||||
marshall.cc marshall.hh rpc.hh status.hh
|
||||
|
||||
libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
|
||||
libcc1plugin_la_SOURCES = plugin.cc $(shared_source)
|
||||
libcc1plugin_la_LIBADD = $(libiberty)
|
||||
libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym
|
||||
libcc1_la_SOURCES = findcomp.cc libcc1.cc names.cc names.hh $(shared_source)
|
||||
libcc1_la_LIBADD = $(libiberty)
|
||||
all: $(BUILT_SOURCES) cc1plugin-config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cc .lo .o .obj
|
||||
am--refresh:
|
||||
@:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
|
||||
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
echo ' $(SHELL) ./config.status'; \
|
||||
$(SHELL) ./config.status;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
$(am__cd) $(srcdir) && $(AUTOCONF)
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
cc1plugin-config.h: stamp-h1
|
||||
@if test ! -f $@; then \
|
||||
rm -f stamp-h1; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
|
||||
else :; fi
|
||||
|
||||
stamp-h1: $(srcdir)/cc1plugin-config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status cc1plugin-config.h
|
||||
$(srcdir)/cc1plugin-config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
||||
rm -f stamp-h1
|
||||
touch $@
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f cc1plugin-config.h stamp-h1
|
||||
install-cc1libLTLIBRARIES: $(cc1lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(cc1libdir)" || $(MKDIR_P) "$(DESTDIR)$(cc1libdir)"
|
||||
@list='$(cc1lib_LTLIBRARIES)'; test -n "$(cc1libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(cc1libdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(cc1libdir)"; \
|
||||
}
|
||||
|
||||
uninstall-cc1libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(cc1lib_LTLIBRARIES)'; test -n "$(cc1libdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(cc1libdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(cc1libdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-cc1libLTLIBRARIES:
|
||||
-test -z "$(cc1lib_LTLIBRARIES)" || rm -f $(cc1lib_LTLIBRARIES)
|
||||
@list='$(cc1lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
|
||||
@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
|
||||
}
|
||||
|
||||
uninstall-pluginLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-pluginLTLIBRARIES:
|
||||
-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
|
||||
@list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libcc1.la: $(libcc1_la_OBJECTS) $(libcc1_la_DEPENDENCIES)
|
||||
$(libcc1_la_LINK) $(am_libcc1_la_rpath) $(libcc1_la_OBJECTS) $(libcc1_la_LIBADD) $(LIBS)
|
||||
libcc1plugin.la: $(libcc1plugin_la_OBJECTS) $(libcc1plugin_la_DEPENDENCIES)
|
||||
$(libcc1plugin_la_LINK) $(am_libcc1plugin_la_rpath) $(libcc1plugin_la_OBJECTS) $(libcc1plugin_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findcomp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marshall.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@
|
||||
|
||||
.cc.o:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cc.obj:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.cc.lo:
|
||||
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool config.lt
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) cc1plugin-config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) cc1plugin-config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) cc1plugin-config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) cc1plugin-config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
check-am: all-am
|
||||
check: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) check-am
|
||||
all-am: Makefile $(LTLIBRARIES) cc1plugin-config.h
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(cc1libdir)" "$(DESTDIR)$(plugindir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-cc1libLTLIBRARIES clean-generic clean-libtool \
|
||||
clean-pluginLTLIBRARIES mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-cc1libLTLIBRARIES install-pluginLTLIBRARIES
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-cc1libLTLIBRARIES uninstall-pluginLTLIBRARIES
|
||||
|
||||
.MAKE: all check install install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
|
||||
clean-cc1libLTLIBRARIES clean-generic clean-libtool \
|
||||
clean-pluginLTLIBRARIES ctags distclean distclean-compile \
|
||||
distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-tags dvi dvi-am html html-am info info-am install \
|
||||
install-am install-cc1libLTLIBRARIES install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-pluginLTLIBRARIES install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
pdf pdf-am ps ps-am tags uninstall uninstall-am \
|
||||
uninstall-cc1libLTLIBRARIES uninstall-pluginLTLIBRARIES
|
||||
|
||||
|
||||
# Put this in a header so we don't run sed for each compilation. This
|
||||
# is also simpler to debug as one can easily see the constant.
|
||||
compiler-name.h: Makefile
|
||||
echo "#define COMPILER_NAME \"`echo gcc | sed '$(transform)'`\"" > compiler-name.h
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
981
libcc1/aclocal.m4
vendored
Normal file
981
libcc1/aclocal.m4
vendored
Normal file
|
@ -0,0 +1,981 @@
|
|||
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
|
||||
[m4_warning([this file was generated for autoconf 2.64.
|
||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically `autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
# (This private macro should not be called outside this file.)
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.11'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.11.1], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
# _AM_AUTOCONF_VERSION(VERSION)
|
||||
# -----------------------------
|
||||
# aclocal traces this macro to find the Autoconf version.
|
||||
# This is a private macro too. Using m4_define simplifies
|
||||
# the logic in aclocal, which can simply ignore this definition.
|
||||
m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.11.1])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is `.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[dnl Rely on autoconf to set up CDPATH properly.
|
||||
AC_PREREQ([2.50])dnl
|
||||
# expand $ac_aux_dir to an absolute path
|
||||
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||
])
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 9
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ(2.52)dnl
|
||||
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 10
|
||||
|
||||
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
||||
# written in clear, in which case automake, when reading aclocal.m4,
|
||||
# will think it sees a *use*, and therefore will trigger all it's
|
||||
# C support machinery. Also note that it means that autoscan, seeing
|
||||
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
||||
|
||||
|
||||
# _AM_DEPENDENCIES(NAME)
|
||||
# ----------------------
|
||||
# See how the compiler implements dependency checking.
|
||||
# NAME is "CC", "CXX", "GCJ", or "OBJC".
|
||||
# We try a few techniques and use that to set a single cache variable.
|
||||
#
|
||||
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
|
||||
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
|
||||
# dependency, and given that the user is not expected to run this macro,
|
||||
# just rely on AC_PROG_CC.
|
||||
AC_DEFUN([_AM_DEPENDENCIES],
|
||||
[AC_REQUIRE([AM_SET_DEPDIR])dnl
|
||||
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
|
||||
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
|
||||
AC_REQUIRE([AM_DEP_TRACK])dnl
|
||||
|
||||
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
|
||||
[$1], CXX, [depcc="$CXX" am_compiler_list=],
|
||||
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
|
||||
[$1], UPC, [depcc="$UPC" am_compiler_list=],
|
||||
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
||||
[depcc="$$1" am_compiler_list=])
|
||||
|
||||
AC_CACHE_CHECK([dependency style of $depcc],
|
||||
[am_cv_$1_dependencies_compiler_type],
|
||||
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
|
||||
# We make a subdir and do the tests there. Otherwise we can end up
|
||||
# making bogus files that we don't know about and never remove. For
|
||||
# instance it was reported that on HP-UX the gcc test will end up
|
||||
# making a dummy file named `D' -- because `-MD' means `put the output
|
||||
# in D'.
|
||||
mkdir conftest.dir
|
||||
# Copy depcomp to subdir because otherwise we won't find it if we're
|
||||
# using a relative directory.
|
||||
cp "$am_depcomp" conftest.dir
|
||||
cd conftest.dir
|
||||
# We will build objects and dependencies in a subdirectory because
|
||||
# it helps to detect inapplicable dependency modes. For instance
|
||||
# both Tru64's cc and ICC support -MD to output dependencies as a
|
||||
# side effect of compilation, but ICC will put the dependencies in
|
||||
# the current directory while Tru64 will put them in the object
|
||||
# directory.
|
||||
mkdir sub
|
||||
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
if test "$am_compiler_list" = ""; then
|
||||
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
|
||||
fi
|
||||
am__universal=false
|
||||
m4_case([$1], [CC],
|
||||
[case " $depcc " in #(
|
||||
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||
esac],
|
||||
[CXX],
|
||||
[case " $depcc " in #(
|
||||
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||
esac])
|
||||
|
||||
for depmode in $am_compiler_list; do
|
||||
# Setup a source with many dependencies, because some compilers
|
||||
# like to wrap large dependency lists on column 80 (with \), and
|
||||
# we should not choose a depcomp mode which is confused by this.
|
||||
#
|
||||
# We need to recreate these files for each test, as the compiler may
|
||||
# overwrite some of them when testing with obscure command lines.
|
||||
# This happens at least with the AIX C compiler.
|
||||
: > sub/conftest.c
|
||||
for i in 1 2 3 4 5 6; do
|
||||
echo '#include "conftst'$i'.h"' >> sub/conftest.c
|
||||
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
|
||||
# Solaris 8's {/usr,}/bin/sh.
|
||||
touch sub/conftst$i.h
|
||||
done
|
||||
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
|
||||
|
||||
# We check with `-c' and `-o' for the sake of the "dashmstdout"
|
||||
# mode. It turns out that the SunPro C++ compiler does not properly
|
||||
# handle `-M -o', and we need to detect this. Also, some Intel
|
||||
# versions had trouble with output in subdirs
|
||||
am__obj=sub/conftest.${OBJEXT-o}
|
||||
am__minus_obj="-o $am__obj"
|
||||
case $depmode in
|
||||
gcc)
|
||||
# This depmode causes a compiler race in universal mode.
|
||||
test "$am__universal" = false || continue
|
||||
;;
|
||||
nosideeffect)
|
||||
# after this tag, mechanisms are not by side-effect, so they'll
|
||||
# only be used when explicitly requested
|
||||
if test "x$enable_dependency_tracking" = xyes; then
|
||||
continue
|
||||
else
|
||||
break
|
||||
fi
|
||||
;;
|
||||
msvisualcpp | msvcmsys)
|
||||
# This compiler won't grok `-c -o', but also, the minuso test has
|
||||
# not run yet. These depmodes are late enough in the game, and
|
||||
# so weak that their functioning should not be impacted.
|
||||
am__obj=conftest.${OBJEXT-o}
|
||||
am__minus_obj=
|
||||
;;
|
||||
none) break ;;
|
||||
esac
|
||||
if depmode=$depmode \
|
||||
source=sub/conftest.c object=$am__obj \
|
||||
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
|
||||
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
|
||||
>/dev/null 2>conftest.err &&
|
||||
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||
grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
|
||||
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
|
||||
# icc doesn't choke on unknown options, it will just issue warnings
|
||||
# or remarks (even with -Werror). So we grep stderr for any message
|
||||
# that says an option was ignored or not supported.
|
||||
# When given -MP, icc 7.0 and 7.1 complain thusly:
|
||||
# icc: Command line warning: ignoring option '-M'; no argument required
|
||||
# The diagnosis changed in icc 8.0:
|
||||
# icc: Command line remark: option '-MP' not supported
|
||||
if (grep 'ignoring option' conftest.err ||
|
||||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
|
||||
am_cv_$1_dependencies_compiler_type=$depmode
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd ..
|
||||
rm -rf conftest.dir
|
||||
else
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
fi
|
||||
])
|
||||
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
|
||||
AM_CONDITIONAL([am__fastdep$1], [
|
||||
test "x$enable_dependency_tracking" != xno \
|
||||
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
|
||||
])
|
||||
|
||||
|
||||
# AM_SET_DEPDIR
|
||||
# -------------
|
||||
# Choose a directory name for dependency files.
|
||||
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
|
||||
AC_DEFUN([AM_SET_DEPDIR],
|
||||
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
|
||||
])
|
||||
|
||||
|
||||
# AM_DEP_TRACK
|
||||
# ------------
|
||||
AC_DEFUN([AM_DEP_TRACK],
|
||||
[AC_ARG_ENABLE(dependency-tracking,
|
||||
[ --disable-dependency-tracking speeds up one-time build
|
||||
--enable-dependency-tracking do not reject slow dependency extractors])
|
||||
if test "x$enable_dependency_tracking" != xno; then
|
||||
am_depcomp="$ac_aux_dir/depcomp"
|
||||
AMDEPBACKSLASH='\'
|
||||
fi
|
||||
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
||||
AC_SUBST([AMDEPBACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
#serial 5
|
||||
|
||||
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# ------------------------------
|
||||
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[{
|
||||
# Autoconf 2.62 quotes --file arguments for eval, but not when files
|
||||
# are listed without --file. Let's play safe and only enable the eval
|
||||
# if we detect the quoting.
|
||||
case $CONFIG_FILES in
|
||||
*\'*) eval set x "$CONFIG_FILES" ;;
|
||||
*) set x $CONFIG_FILES ;;
|
||||
esac
|
||||
shift
|
||||
for mf
|
||||
do
|
||||
# Strip MF so we end up with the name of the file.
|
||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile or not.
|
||||
# We used to match only the files named `Makefile.in', but
|
||||
# some people rename them; so instead we look at the file content.
|
||||
# Grep'ing the first line is not enough: some people post-process
|
||||
# each Makefile.in and add a new line on top of each file to say so.
|
||||
# Grep'ing the whole file is not good either: AIX grep has a line
|
||||
# limit of 2048, but all sed's we know have understand at least 4000.
|
||||
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
|
||||
dirpart=`AS_DIRNAME("$mf")`
|
||||
else
|
||||
continue
|
||||
fi
|
||||
# Extract the definition of DEPDIR, am__include, and am__quote
|
||||
# from the Makefile without running `make'.
|
||||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
||||
test -z "$DEPDIR" && continue
|
||||
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
||||
test -z "am__include" && continue
|
||||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
||||
# When using ansi2knr, U may be empty or an underscore; expand it
|
||||
U=`sed -n 's/^U = //p' < "$mf"`
|
||||
# Find all dependency output files, they are included files with
|
||||
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
||||
# simplest approach to changing $(DEPDIR) to its actual value in the
|
||||
# expansion.
|
||||
for file in `sed -n "
|
||||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
||||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
|
||||
# Make sure the directory exists.
|
||||
test -f "$dirpart/$file" && continue
|
||||
fdir=`AS_DIRNAME(["$file"])`
|
||||
AS_MKDIR_P([$dirpart/$fdir])
|
||||
# echo "creating $dirpart/$file"
|
||||
echo '# dummy' > "$dirpart/$file"
|
||||
done
|
||||
done
|
||||
}
|
||||
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
|
||||
|
||||
# AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# -----------------------------
|
||||
# This macro should only be invoked once -- use via AC_REQUIRE.
|
||||
#
|
||||
# This code is only required when automatic dependency tracking
|
||||
# is enabled. FIXME. This creates each `.P' file that we will
|
||||
# need in order to bootstrap the dependency handling code.
|
||||
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AC_CONFIG_COMMANDS([depfiles],
|
||||
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
|
||||
])
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 16
|
||||
|
||||
# This macro actually does too much. Some checks are only needed if
|
||||
# your package does certain things. But this isn't really a big deal.
|
||||
|
||||
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
# -----------------------------------------------
|
||||
# The call with PACKAGE and VERSION arguments is the old style
|
||||
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||
# and VERSION should now be passed to AC_INIT and removed from
|
||||
# the call to AM_INIT_AUTOMAKE.
|
||||
# We support both call styles for the transition. After
|
||||
# the next Automake release, Autoconf can make the AC_INIT
|
||||
# arguments mandatory, and then we can depend on a new Autoconf
|
||||
# release and drop the old call support.
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_PREREQ([2.62])dnl
|
||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||
dnl the ones we care about.
|
||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`"; then
|
||||
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
|
||||
# is not polluted with repeated "-I."
|
||||
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
|
||||
# test to see if srcdir already configured
|
||||
if test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
fi
|
||||
|
||||
# test whether we have cygpath
|
||||
if test -z "$CYGPATH_W"; then
|
||||
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||
CYGPATH_W='cygpath -w'
|
||||
else
|
||||
CYGPATH_W=echo
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CYGPATH_W])
|
||||
|
||||
# Define the identity of the package.
|
||||
dnl Distinguish between old-style and new-style calls.
|
||||
m4_ifval([$2],
|
||||
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
AC_SUBST([PACKAGE], [$1])dnl
|
||||
AC_SUBST([VERSION], [$2])],
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
|
||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||
|
||||
_AM_IF_OPTION([no-define],,
|
||||
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
|
||||
|
||||
# Some tools Automake needs.
|
||||
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo)
|
||||
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
|
||||
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
|
||||
# We need awk for the "check" target. The system "awk" is bad on
|
||||
# some platforms.
|
||||
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||
[_AM_PROG_TAR([v7])])])
|
||||
_AM_IF_OPTION([no-dependencies],,
|
||||
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||
[_AM_DEPENDENCIES(CC)],
|
||||
[define([AC_PROG_CC],
|
||||
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||
[_AM_DEPENDENCIES(CXX)],
|
||||
[define([AC_PROG_CXX],
|
||||
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
|
||||
[_AM_DEPENDENCIES(OBJC)],
|
||||
[define([AC_PROG_OBJC],
|
||||
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
|
||||
])
|
||||
_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
|
||||
dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
|
||||
dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
|
||||
dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
|
||||
AC_CONFIG_COMMANDS_PRE(dnl
|
||||
[m4_provide_if([_AM_COMPILER_EXEEXT],
|
||||
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
|
||||
])
|
||||
|
||||
dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
|
||||
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
|
||||
dnl mangled by Autoconf and run in a shell conditional statement.
|
||||
m4_define([_AC_COMPILER_EXEEXT],
|
||||
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
|
||||
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp files are numbered to have different names.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[# Compute $1's index in $config_headers.
|
||||
_am_arg=$1
|
||||
_am_stamp_count=1
|
||||
for _am_header in $config_headers :; do
|
||||
case $_am_header in
|
||||
$_am_arg | $_am_arg:* )
|
||||
break ;;
|
||||
* )
|
||||
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||
esac
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_SH
|
||||
# ------------------
|
||||
# Define $install_sh.
|
||||
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
if test x"${install_sh}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
|
||||
*)
|
||||
install_sh="\${SHELL} $am_aux_dir/install-sh"
|
||||
esac
|
||||
fi
|
||||
AC_SUBST(install_sh)])
|
||||
|
||||
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||
# From Jim Meyering
|
||||
|
||||
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 5
|
||||
|
||||
# AM_MAINTAINER_MODE([DEFAULT-MODE])
|
||||
# ----------------------------------
|
||||
# Control maintainer-specific portions of Makefiles.
|
||||
# Default is to disable them, unless `enable' is passed literally.
|
||||
# For symmetry, `disable' may be passed as well. Anyway, the user
|
||||
# can override the default with the --enable/--disable switch.
|
||||
AC_DEFUN([AM_MAINTAINER_MODE],
|
||||
[m4_case(m4_default([$1], [disable]),
|
||||
[enable], [m4_define([am_maintainer_other], [disable])],
|
||||
[disable], [m4_define([am_maintainer_other], [enable])],
|
||||
[m4_define([am_maintainer_other], [enable])
|
||||
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
|
||||
AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
|
||||
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
|
||||
AC_ARG_ENABLE([maintainer-mode],
|
||||
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer],
|
||||
[USE_MAINTAINER_MODE=$enableval],
|
||||
[USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
|
||||
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
|
||||
AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
|
||||
MAINT=$MAINTAINER_MODE_TRUE
|
||||
AC_SUBST([MAINT])dnl
|
||||
]
|
||||
)
|
||||
|
||||
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
|
||||
|
||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 4
|
||||
|
||||
# AM_MAKE_INCLUDE()
|
||||
# -----------------
|
||||
# Check to see how make treats includes.
|
||||
AC_DEFUN([AM_MAKE_INCLUDE],
|
||||
[am_make=${MAKE-make}
|
||||
cat > confinc << 'END'
|
||||
am__doit:
|
||||
@echo this is the am__doit target
|
||||
.PHONY: am__doit
|
||||
END
|
||||
# If we don't find an include directive, just comment out the code.
|
||||
AC_MSG_CHECKING([for style of include used by $am_make])
|
||||
am__include="#"
|
||||
am__quote=
|
||||
_am_result=none
|
||||
# First try GNU make style include.
|
||||
echo "include confinc" > confmf
|
||||
# Ignore all kinds of additional output from `make'.
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=include
|
||||
am__quote=
|
||||
_am_result=GNU
|
||||
;;
|
||||
esac
|
||||
# Now try BSD make style include.
|
||||
if test "$am__include" = "#"; then
|
||||
echo '.include "confinc"' > confmf
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=.include
|
||||
am__quote="\""
|
||||
_am_result=BSD
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([am__include])
|
||||
AC_SUBST([am__quote])
|
||||
AC_MSG_RESULT([$_am_result])
|
||||
rm -f confinc confmf
|
||||
])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 6
|
||||
|
||||
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||
# ------------------------------
|
||||
AC_DEFUN([AM_MISSING_PROG],
|
||||
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||
$1=${$1-"${am_missing_run}$2"}
|
||||
AC_SUBST($1)])
|
||||
|
||||
|
||||
# AM_MISSING_HAS_RUN
|
||||
# ------------------
|
||||
# Define MISSING if not defined so far and test if it supports --run.
|
||||
# If it does, set am_missing_run to use it, otherwise, to nothing.
|
||||
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --run true"; then
|
||||
am_missing_run="$MISSING --run "
|
||||
else
|
||||
am_missing_run=
|
||||
AC_MSG_WARN([`missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_MKDIR_P
|
||||
# ---------------
|
||||
# Check for `mkdir -p'.
|
||||
AC_DEFUN([AM_PROG_MKDIR_P],
|
||||
[AC_PREREQ([2.60])dnl
|
||||
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
|
||||
dnl while keeping a definition of mkdir_p for backward compatibility.
|
||||
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
|
||||
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
|
||||
dnl Makefile.ins that do not define MKDIR_P, so we do our own
|
||||
dnl adjustment using top_builddir (which is defined more often than
|
||||
dnl MKDIR_P).
|
||||
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
|
||||
case $mkdir_p in
|
||||
[[\\/$]]* | ?:[[\\/]]*) ;;
|
||||
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
|
||||
esac
|
||||
])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 4
|
||||
|
||||
# _AM_MANGLE_OPTION(NAME)
|
||||
# -----------------------
|
||||
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
# _AM_SET_OPTION(NAME)
|
||||
# ------------------------------
|
||||
# Set option NAME. Presently that only means defining a flag for this option.
|
||||
AC_DEFUN([_AM_SET_OPTION],
|
||||
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
|
||||
|
||||
# _AM_SET_OPTIONS(OPTIONS)
|
||||
# ----------------------------------
|
||||
# OPTIONS is a space-separated list of Automake options.
|
||||
AC_DEFUN([_AM_SET_OPTIONS],
|
||||
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||
|
||||
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||
# -------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 5
|
||||
|
||||
# AM_SANITY_CHECK
|
||||
# ---------------
|
||||
AC_DEFUN([AM_SANITY_CHECK],
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftest.file
|
||||
# Reject unsafe characters in $srcdir or the absolute working directory
|
||||
# name. Accept space and tab only in the latter.
|
||||
am_lf='
|
||||
'
|
||||
case `pwd` in
|
||||
*[[\\\"\#\$\&\'\`$am_lf]]*)
|
||||
AC_MSG_ERROR([unsafe absolute working directory name]);;
|
||||
esac
|
||||
case $srcdir in
|
||||
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
|
||||
AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
|
||||
esac
|
||||
|
||||
# Do `set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
|
||||
if test "$[*]" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t "$srcdir/configure" conftest.file`
|
||||
fi
|
||||
rm -f conftest.file
|
||||
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
|
||||
test "$[2]" = conftest.file
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)])
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_STRIP
|
||||
# ---------------------
|
||||
# One issue with vendor `install' (even GNU) is that you can't
|
||||
# specify the program used to strip binaries. This is especially
|
||||
# annoying in cross-compiling environments, where the build's strip
|
||||
# is unlikely to handle the host's binaries.
|
||||
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||
# always use install-sh in `make install-strip', and initialize
|
||||
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
# Installed binaries are usually stripped using `strip' when the user
|
||||
# run `make install-strip'. However `strip' might not be the right
|
||||
# tool to use in cross-compilation environments, therefore Automake
|
||||
# will honor the `STRIP' environment variable to overrule this program.
|
||||
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
|
||||
if test "$cross_compiling" != no; then
|
||||
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||
fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 2
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 2
|
||||
|
||||
# _AM_PROG_TAR(FORMAT)
|
||||
# --------------------
|
||||
# Check how to create a tarball in format FORMAT.
|
||||
# FORMAT should be one of `v7', `ustar', or `pax'.
|
||||
#
|
||||
# Substitute a variable $(am__tar) that is a command
|
||||
# writing to stdout a FORMAT-tarball containing the directory
|
||||
# $tardir.
|
||||
# tardir=directory && $(am__tar) > result.tar
|
||||
#
|
||||
# Substitute a variable $(am__untar) that extract such
|
||||
# a tarball read from stdin.
|
||||
# $(am__untar) < result.tar
|
||||
AC_DEFUN([_AM_PROG_TAR],
|
||||
[# Always define AMTAR for backward compatibility.
|
||||
AM_MISSING_PROG([AMTAR], [tar])
|
||||
m4_if([$1], [v7],
|
||||
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
|
||||
[m4_case([$1], [ustar],, [pax],,
|
||||
[m4_fatal([Unknown tar format])])
|
||||
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||
# Loop over all known methods to create a tar archive until one works.
|
||||
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||
# Do not fold the above two line into one, because Tru64 sh and
|
||||
# Solaris sh will not grok spaces in the rhs of `-'.
|
||||
for _am_tool in $_am_tools
|
||||
do
|
||||
case $_am_tool in
|
||||
gnutar)
|
||||
for _am_tar in tar gnutar gtar;
|
||||
do
|
||||
AM_RUN_LOG([$_am_tar --version]) && break
|
||||
done
|
||||
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||
am__untar="$_am_tar -xf -"
|
||||
;;
|
||||
plaintar)
|
||||
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||
# ustar tarball either.
|
||||
(tar --version) >/dev/null 2>&1 && continue
|
||||
am__tar='tar chf - "$$tardir"'
|
||||
am__tar_='tar chf - "$tardir"'
|
||||
am__untar='tar xf -'
|
||||
;;
|
||||
pax)
|
||||
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||
am__untar='pax -r'
|
||||
;;
|
||||
cpio)
|
||||
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||
am__untar='cpio -i -H $1 -d'
|
||||
;;
|
||||
none)
|
||||
am__tar=false
|
||||
am__tar_=false
|
||||
am__untar=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the value was cached, stop now. We just wanted to have am__tar
|
||||
# and am__untar set.
|
||||
test -n "${am_cv_prog_tar_$1}" && break
|
||||
|
||||
# tar/untar a dummy directory, and stop if the command works
|
||||
rm -rf conftest.dir
|
||||
mkdir conftest.dir
|
||||
echo GrepMe > conftest.dir/file
|
||||
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||
rm -rf conftest.dir
|
||||
if test -s conftest.tar; then
|
||||
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||
fi
|
||||
done
|
||||
rm -rf conftest.dir
|
||||
|
||||
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||
AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([../config/acx.m4])
|
||||
m4_include([../config/depstand.m4])
|
||||
m4_include([../config/gcc-plugin.m4])
|
||||
m4_include([../config/lead-dot.m4])
|
||||
m4_include([../config/override.m4])
|
||||
m4_include([../config/warnings.m4])
|
||||
m4_include([../libtool.m4])
|
||||
m4_include([../ltoptions.m4])
|
||||
m4_include([../ltsugar.m4])
|
||||
m4_include([../ltversion.m4])
|
||||
m4_include([../lt~obsolete.m4])
|
90
libcc1/callbacks.cc
Normal file
90
libcc1/callbacks.cc
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* Callback management.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <cc1plugin-config.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "callbacks.hh"
|
||||
#include "libiberty.h"
|
||||
|
||||
// An entry in the hash table.
|
||||
struct method
|
||||
{
|
||||
const char *name;
|
||||
cc1_plugin::callback_ftype *func;
|
||||
};
|
||||
|
||||
// Hash function for struct method.
|
||||
static hashval_t
|
||||
hash_method (const void *a)
|
||||
{
|
||||
const struct method *m = (const struct method *) a;
|
||||
|
||||
return htab_hash_string (m->name);
|
||||
}
|
||||
|
||||
// Equality function for struct method.
|
||||
static int
|
||||
eq_method (const void *a, const void *b)
|
||||
{
|
||||
const struct method *ma = (const struct method *) a;
|
||||
const struct method *mb = (const struct method *) b;
|
||||
|
||||
return strcmp (ma->name, mb->name) == 0;
|
||||
}
|
||||
|
||||
cc1_plugin::callbacks::callbacks ()
|
||||
: m_registry (htab_create_alloc (10, hash_method, eq_method,
|
||||
free, xcalloc, free))
|
||||
{
|
||||
}
|
||||
|
||||
cc1_plugin::callbacks::~callbacks ()
|
||||
{
|
||||
htab_delete (m_registry);
|
||||
}
|
||||
|
||||
void
|
||||
cc1_plugin::callbacks::add_callback (const char *name,
|
||||
cc1_plugin::callback_ftype *func)
|
||||
{
|
||||
method m;
|
||||
method **slot;
|
||||
|
||||
m.name = name;
|
||||
m.func = func;
|
||||
|
||||
slot = (method **) htab_find_slot (m_registry, &m, INSERT);
|
||||
*slot = XNEW (method);
|
||||
**slot = m;
|
||||
}
|
||||
|
||||
cc1_plugin::callback_ftype *
|
||||
cc1_plugin::callbacks::find_callback (const char *name)
|
||||
{
|
||||
method m, *found;
|
||||
|
||||
m.name = name;
|
||||
|
||||
found = (method *) htab_find (m_registry, &m);
|
||||
if (found == NULL)
|
||||
return NULL;
|
||||
|
||||
return found->func;
|
||||
}
|
64
libcc1/callbacks.hh
Normal file
64
libcc1/callbacks.hh
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Callback management
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_CALLBACKS_HH
|
||||
#define CC1_PLUGIN_CALLBACKS_HH
|
||||
|
||||
#include "status.hh"
|
||||
#include "hashtab.h"
|
||||
|
||||
namespace cc1_plugin
|
||||
{
|
||||
class connection;
|
||||
|
||||
// The type of a callback method.
|
||||
typedef status callback_ftype (connection *);
|
||||
|
||||
// This class manages callback functions. A callback has a name and
|
||||
// an underlying function. When a query packet arrives, the name is
|
||||
// inspected and the corresponding function is called. A callback
|
||||
// function has to know how to decode its own arguments, but
|
||||
// wrappers are provided elsewhere to automate this.
|
||||
class callbacks
|
||||
{
|
||||
public:
|
||||
|
||||
callbacks ();
|
||||
~callbacks ();
|
||||
|
||||
// Add a callback named NAME. FUNC is the function to call when
|
||||
// this method is invoked.
|
||||
void add_callback (const char *name, callback_ftype *func);
|
||||
|
||||
// Look up a callback by name. Returns NULL if the method is not
|
||||
// found.
|
||||
callback_ftype *find_callback (const char *name);
|
||||
|
||||
private:
|
||||
|
||||
// Declared but not defined to avoid use.
|
||||
callbacks (const callbacks &);
|
||||
callbacks &operator= (const callbacks &);
|
||||
|
||||
// The mapping.
|
||||
htab_t m_registry;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // CC1_PLUGIN_CALLBACKS_HH
|
92
libcc1/cc1plugin-config.h.in
Normal file
92
libcc1/cc1plugin-config.h.in
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* cc1plugin-config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the declaration of `basename', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_BASENAME
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
17176
libcc1/configure
vendored
Normal file
17176
libcc1/configure
vendored
Normal file
File diff suppressed because it is too large
Load diff
73
libcc1/configure.ac
Normal file
73
libcc1/configure.ac
Normal file
|
@ -0,0 +1,73 @@
|
|||
dnl Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
dnl
|
||||
dnl This file is part of GCC.
|
||||
dnl
|
||||
dnl GCC is free software; you can redistribute it and/or modify it under
|
||||
dnl the terms of the GNU General Public License as published by the Free
|
||||
dnl Software Foundation; either version 3, or (at your option) any later
|
||||
dnl version.
|
||||
dnl
|
||||
dnl GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
dnl WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
dnl for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with GCC; see the file COPYING3. If not see
|
||||
dnl <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_PREREQ(2.64)
|
||||
AC_INIT([libcc1], [version-unused])
|
||||
AC_CONFIG_SRCDIR([libcc1.cc])
|
||||
AC_CONFIG_HEADER(cc1plugin-config.h)
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
# Determine the noncanonical target name, for directory use.
|
||||
ACX_NONCANONICAL_TARGET
|
||||
GCC_TOPLEV_SUBDIRS
|
||||
|
||||
# 1.11.1: Require that version of automake.
|
||||
# foreign: Don't require README, INSTALL, NEWS, etc.
|
||||
# no-define: Don't define PACKAGE and VERSION.
|
||||
# -Wall: Issue all automake warnings.
|
||||
# -Wno-portability: Don't warn about constructs supported by GNU make.
|
||||
# (because GCC requires GNU make anyhow).
|
||||
AM_INIT_AUTOMAKE([1.11.1 foreign no-dist no-define -Wall -Wno-portability])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
LT_INIT([disable-static])
|
||||
AM_PROG_LIBTOOL
|
||||
AC_PROG_CXX
|
||||
|
||||
visibility=
|
||||
if test "$GXX" = yes; then
|
||||
visibility=-fvisibility=hidden
|
||||
fi
|
||||
AC_SUBST(visibility)
|
||||
|
||||
AC_CHECK_DECLS([basename])
|
||||
|
||||
gcc_version=`cat $srcdir/../gcc/BASE-VER`
|
||||
AC_SUBST(gcc_version)
|
||||
|
||||
ACX_PROG_CC_WARNING_OPTS([-W -Wall], [WARN_FLAGS])
|
||||
WARN_FLAGS="$WARN_FLAGS -Werror"
|
||||
AC_SUBST(WARN_FLAGS)
|
||||
|
||||
libsuffix=
|
||||
if test "$GXX" = yes; then
|
||||
libsuffix=`$CXX -print-multi-os-directory`
|
||||
fi
|
||||
AC_SUBST(libsuffix)
|
||||
|
||||
# If any of these functions are missing, simply don't bother building
|
||||
# this plugin.
|
||||
GCC_ENABLE_PLUGINS
|
||||
AC_CHECK_FUNC(socketpair, , enable_plugin=no)
|
||||
AC_CHECK_FUNC(select, , enable_plugin=no)
|
||||
AC_CHECK_FUNC(fork, , enable_plugin=no)
|
||||
AM_CONDITIONAL(ENABLE_PLUGIN, test $enable_plugin = yes)
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
153
libcc1/connection.cc
Normal file
153
libcc1/connection.cc
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* Connect implementation
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <cc1plugin-config.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include "marshall.hh"
|
||||
#include "connection.hh"
|
||||
#include "rpc.hh"
|
||||
|
||||
cc1_plugin::connection::~connection ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
cc1_plugin::connection::print (const char *)
|
||||
{
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::connection::send (char c)
|
||||
{
|
||||
if (write (m_fd, &c, 1) != 1)
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::connection::send (const void *buf, int len)
|
||||
{
|
||||
if (write (m_fd, buf, len) != len)
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::connection::require (char c)
|
||||
{
|
||||
char result;
|
||||
|
||||
if (read (m_fd, &result, 1) != 1
|
||||
|| result != c)
|
||||
return FAIL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::connection::get (void *buf, int len)
|
||||
{
|
||||
if (read (m_fd, buf, len) != len)
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::connection::do_wait (bool want_result)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
char result;
|
||||
fd_set read_set;
|
||||
|
||||
FD_ZERO (&read_set);
|
||||
FD_SET (m_fd, &read_set);
|
||||
if (m_aux_fd != -1)
|
||||
FD_SET (m_aux_fd, &read_set);
|
||||
|
||||
int nfds = select (FD_SETSIZE, &read_set, NULL, NULL, NULL);
|
||||
if (nfds == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// We have to check the stderr fd first, to avoid a possible
|
||||
// blocking scenario when do_wait is called reentrantly. In
|
||||
// such a call, if we handle the primary fd first, then we may
|
||||
// re-enter this function, read from gcc's stderr, causing the
|
||||
// outer invocation of this function to block when trying to
|
||||
// read.
|
||||
if (m_aux_fd != -1 && FD_ISSET (m_aux_fd, &read_set))
|
||||
{
|
||||
char buf[1024];
|
||||
int n = read (m_aux_fd, buf, sizeof (buf) - 1);
|
||||
if (n < 0)
|
||||
return FAIL;
|
||||
if (n > 0)
|
||||
{
|
||||
buf[n] = '\0';
|
||||
print (buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET (m_fd, &read_set))
|
||||
{
|
||||
int n = read (m_fd, &result, 1);
|
||||
if (n == 0)
|
||||
return want_result ? FAIL : OK;
|
||||
if (n != 1)
|
||||
return FAIL;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case 'R':
|
||||
// The reply is ready; the caller will unmarshall it.
|
||||
return want_result ? OK : FAIL;
|
||||
|
||||
case 'Q':
|
||||
// While waiting for a reply, the other side made a method
|
||||
// call.
|
||||
{
|
||||
// Use an argument_wrapper here to simplify management
|
||||
// of the string's lifetime.
|
||||
argument_wrapper<char *> method_name;
|
||||
|
||||
if (!method_name.unmarshall (this))
|
||||
return FAIL;
|
||||
|
||||
callback_ftype *callback
|
||||
= m_callbacks.find_callback (method_name);
|
||||
// The call to CALLBACK is where we may end up in a
|
||||
// reentrant call.
|
||||
if (callback == NULL || !callback (this))
|
||||
return FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
114
libcc1/connection.hh
Normal file
114
libcc1/connection.hh
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* Plugin connection declarations
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_CONNECTION_HH
|
||||
#define CC1_PLUGIN_CONNECTION_HH
|
||||
|
||||
#include "status.hh"
|
||||
#include "callbacks.hh"
|
||||
|
||||
namespace cc1_plugin
|
||||
{
|
||||
// The connection class represents one side of the connection
|
||||
// between the gdb-side library and the gcc plugin. It handles the
|
||||
// low-level details of reading and writing data.
|
||||
class connection
|
||||
{
|
||||
public:
|
||||
|
||||
connection (int fd)
|
||||
: m_fd (fd),
|
||||
m_aux_fd (-1),
|
||||
m_callbacks ()
|
||||
{
|
||||
}
|
||||
|
||||
connection (int fd, int aux_fd)
|
||||
: m_fd (fd),
|
||||
m_aux_fd (aux_fd),
|
||||
m_callbacks ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~connection ();
|
||||
|
||||
// Send a single character. This is used to introduce various
|
||||
// higher-level protocol elements.
|
||||
status send (char c);
|
||||
|
||||
// Send data in bulk.
|
||||
status send (const void *buf, int len);
|
||||
|
||||
// Read a single byte from the connection and verify that it
|
||||
// matches the argument C.
|
||||
status require (char c);
|
||||
|
||||
// Read data in bulk.
|
||||
status get (void *buf, int len);
|
||||
|
||||
// This is called after a query (remote function call) has been
|
||||
// sent to the remote. It waits for a response packet. The
|
||||
// response character is read before returning. Any query packets
|
||||
// sent from the remote while waiting for a response are handled
|
||||
// by this function.
|
||||
status wait_for_result ()
|
||||
{
|
||||
return do_wait (true);
|
||||
}
|
||||
|
||||
// Read and respond to query packets sent by the remote. This
|
||||
// function returns when the connection is closed.
|
||||
status wait_for_query ()
|
||||
{
|
||||
return do_wait (false);
|
||||
}
|
||||
|
||||
// Register a callback with this connection. NAME is the name of
|
||||
// the method being registered. FUNC is the function. It must
|
||||
// know how to decode its own arguments. When a query packet is
|
||||
// received by one of the wait_* methods, the corresponding
|
||||
// callback is invoked.
|
||||
void add_callback (const char *name, callback_ftype *func)
|
||||
{
|
||||
m_callbacks.add_callback (name, func);
|
||||
}
|
||||
|
||||
virtual void print (const char *);
|
||||
|
||||
private:
|
||||
|
||||
// Declared but not defined, to prevent use.
|
||||
connection (const connection &);
|
||||
connection &operator= (const connection &);
|
||||
|
||||
// Helper function for the wait_* methods.
|
||||
status do_wait (bool);
|
||||
|
||||
// The file descriptor.
|
||||
int m_fd;
|
||||
|
||||
// An auxiliary file descriptor, or -1 if none.
|
||||
int m_aux_fd;
|
||||
|
||||
// Callbacks associated with this connection.
|
||||
callbacks m_callbacks;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CC1_PLUGIN_CONNECTION_HH
|
139
libcc1/findcomp.cc
Normal file
139
libcc1/findcomp.cc
Normal file
|
@ -0,0 +1,139 @@
|
|||
/* Find the correct compiler.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <string>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libiberty.h"
|
||||
#include "xregex.h"
|
||||
#include "findcomp.hh"
|
||||
|
||||
class scanner
|
||||
{
|
||||
public:
|
||||
|
||||
scanner (const std::string &dir)
|
||||
{
|
||||
m_dir = opendir (dir.c_str ());
|
||||
}
|
||||
|
||||
~scanner ()
|
||||
{
|
||||
if (m_dir != NULL)
|
||||
closedir (m_dir);
|
||||
}
|
||||
|
||||
const char *next ()
|
||||
{
|
||||
if (m_dir == NULL)
|
||||
return NULL;
|
||||
|
||||
struct dirent *entry = readdir (m_dir);
|
||||
if (entry == NULL)
|
||||
return NULL;
|
||||
|
||||
return entry->d_name;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
DIR *m_dir;
|
||||
};
|
||||
|
||||
static bool
|
||||
search_dir (const regex_t ®exp, const std::string &dir, std::string *result)
|
||||
{
|
||||
scanner scan (dir);
|
||||
const char *filename;
|
||||
|
||||
while ((filename = scan.next ()) != NULL)
|
||||
{
|
||||
if (regexec (®exp, filename, 0, NULL, 0) == 0)
|
||||
{
|
||||
*result = filename;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class tokenizer
|
||||
{
|
||||
public:
|
||||
|
||||
tokenizer (const char *str)
|
||||
: m_str (str),
|
||||
m_pos (0)
|
||||
{
|
||||
}
|
||||
|
||||
bool done () const
|
||||
{
|
||||
return m_pos == std::string::npos;
|
||||
}
|
||||
|
||||
std::string next ()
|
||||
{
|
||||
std::string::size_type last_pos = m_pos;
|
||||
std::string::size_type colon = m_str.find(':', last_pos);
|
||||
|
||||
std::string result;
|
||||
if (colon == std::string::npos)
|
||||
{
|
||||
m_pos = colon;
|
||||
result = m_str.substr(last_pos, colon);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pos = colon + 1;
|
||||
result = m_str.substr(last_pos, colon - last_pos);
|
||||
}
|
||||
if (result == "")
|
||||
result = ".";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::string m_str;
|
||||
std::string::size_type m_pos;
|
||||
};
|
||||
|
||||
bool
|
||||
find_compiler (const regex_t ®exp, std::string *result)
|
||||
{
|
||||
const char *cpath = getenv ("PATH");
|
||||
|
||||
if (cpath == NULL)
|
||||
return false;
|
||||
|
||||
tokenizer dirs (cpath);
|
||||
while (!dirs.done ())
|
||||
{
|
||||
std::string dir = dirs.next ();
|
||||
if (search_dir (regexp, dir, result))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
25
libcc1/findcomp.hh
Normal file
25
libcc1/findcomp.hh
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* Find the correct compiler.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_FINDCOMP_HH
|
||||
#define CC1_PLUGIN_FINDCOMP_HH
|
||||
|
||||
extern bool find_compiler (const regex_t ®exp, std::string *result);
|
||||
|
||||
#endif // CC1_PLUGIN_FINDCOMP_HH
|
530
libcc1/libcc1.cc
Normal file
530
libcc1/libcc1.cc
Normal file
|
@ -0,0 +1,530 @@
|
|||
/* The library used by gdb.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <cc1plugin-config.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include "rpc.hh"
|
||||
#include "connection.hh"
|
||||
#include "names.hh"
|
||||
#include "callbacks.hh"
|
||||
#include "gcc-interface.h"
|
||||
#include "libiberty.h"
|
||||
#include "xregex.h"
|
||||
#include "findcomp.hh"
|
||||
#include "compiler-name.h"
|
||||
|
||||
struct libcc1;
|
||||
|
||||
class libcc1_connection;
|
||||
|
||||
// The C compiler context that we hand back to our caller.
|
||||
struct libcc1 : public gcc_c_context
|
||||
{
|
||||
libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
|
||||
~libcc1 ();
|
||||
|
||||
// A convenience function to print something.
|
||||
void print (const char *str)
|
||||
{
|
||||
this->print_function (this->print_datum, str);
|
||||
}
|
||||
|
||||
libcc1_connection *connection;
|
||||
|
||||
gcc_c_oracle_function *binding_oracle;
|
||||
gcc_c_symbol_address_function *address_oracle;
|
||||
void *oracle_datum;
|
||||
|
||||
void (*print_function) (void *datum, const char *message);
|
||||
void *print_datum;
|
||||
|
||||
std::vector<std::string> args;
|
||||
std::string source_file;
|
||||
};
|
||||
|
||||
// A local subclass of connection that holds a back-pointer to the
|
||||
// gcc_c_context object that we provide to our caller.
|
||||
class libcc1_connection : public cc1_plugin::connection
|
||||
{
|
||||
public:
|
||||
|
||||
libcc1_connection (int fd, int aux_fd, libcc1 *b)
|
||||
: connection (fd, aux_fd),
|
||||
back_ptr (b)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void print (const char *buf)
|
||||
{
|
||||
back_ptr->print (buf);
|
||||
}
|
||||
|
||||
libcc1 *back_ptr;
|
||||
};
|
||||
|
||||
libcc1::libcc1 (const gcc_base_vtable *v,
|
||||
const gcc_c_fe_vtable *cv)
|
||||
: connection (NULL),
|
||||
binding_oracle (NULL),
|
||||
address_oracle (NULL),
|
||||
oracle_datum (NULL),
|
||||
print_function (NULL),
|
||||
print_datum (NULL),
|
||||
args (),
|
||||
source_file ()
|
||||
{
|
||||
base.ops = v;
|
||||
c_ops = cv;
|
||||
}
|
||||
|
||||
libcc1::~libcc1 ()
|
||||
{
|
||||
delete connection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This is a wrapper function that is called by the RPC system and
|
||||
// that then forwards the call to the library user. Note that the
|
||||
// return value is not used; the type cannot be 'void' due to
|
||||
// limitations in our simple RPC.
|
||||
int
|
||||
call_binding_oracle (cc1_plugin::connection *conn,
|
||||
enum gcc_c_oracle_request request,
|
||||
const char *identifier)
|
||||
{
|
||||
libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
|
||||
|
||||
self->binding_oracle (self->oracle_datum, self, request, identifier);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This is a wrapper function that is called by the RPC system and
|
||||
// that then forwards the call to the library user.
|
||||
gcc_address
|
||||
call_symbol_address (cc1_plugin::connection *conn, const char *identifier)
|
||||
{
|
||||
libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
|
||||
|
||||
return self->address_oracle (self->oracle_datum, self, identifier);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
set_callbacks (struct gcc_c_context *s,
|
||||
gcc_c_oracle_function *binding_oracle,
|
||||
gcc_c_symbol_address_function *address_oracle,
|
||||
void *datum)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
|
||||
self->binding_oracle = binding_oracle;
|
||||
self->address_oracle = address_oracle;
|
||||
self->oracle_datum = datum;
|
||||
}
|
||||
|
||||
// Instances of these rpc<> template functions are installed into the
|
||||
// "c_vtable". These functions are parameterized by type and method
|
||||
// name and forward the call via the connection.
|
||||
|
||||
template<typename R, const char *&NAME>
|
||||
R rpc (struct gcc_c_context *s)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
R result;
|
||||
|
||||
if (!cc1_plugin::call (self->connection, NAME, &result))
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename R, const char *&NAME, typename A>
|
||||
R rpc (struct gcc_c_context *s, A arg)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
R result;
|
||||
|
||||
if (!cc1_plugin::call (self->connection, NAME, &result, arg))
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename R, const char *&NAME, typename A1, typename A2>
|
||||
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
R result;
|
||||
|
||||
if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename R, const char *&NAME, typename A1, typename A2, typename A3>
|
||||
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
R result;
|
||||
|
||||
if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
|
||||
typename A4>
|
||||
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
R result;
|
||||
|
||||
if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
|
||||
arg4))
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
|
||||
typename A4, typename A5>
|
||||
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
R result;
|
||||
|
||||
if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
|
||||
arg4, arg5))
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
|
||||
typename A4, typename A5, typename A6, typename A7>
|
||||
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
|
||||
A6 arg6, A7 arg7)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
R result;
|
||||
|
||||
if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
|
||||
arg4, arg5, arg6, arg7))
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct gcc_c_fe_vtable c_vtable =
|
||||
{
|
||||
GCC_C_FE_VERSION_0,
|
||||
set_callbacks,
|
||||
|
||||
#define GCC_METHOD0(R, N) \
|
||||
rpc<R, cc1_plugin::N>,
|
||||
#define GCC_METHOD1(R, N, A) \
|
||||
rpc<R, cc1_plugin::N, A>,
|
||||
#define GCC_METHOD2(R, N, A, B) \
|
||||
rpc<R, cc1_plugin::N, A, B>,
|
||||
#define GCC_METHOD3(R, N, A, B, C) \
|
||||
rpc<R, cc1_plugin::N, A, B, C>,
|
||||
#define GCC_METHOD4(R, N, A, B, C, D) \
|
||||
rpc<R, cc1_plugin::N, A, B, C, D>,
|
||||
#define GCC_METHOD5(R, N, A, B, C, D, E) \
|
||||
rpc<R, cc1_plugin::N, A, B, C, D, E>,
|
||||
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
|
||||
rpc<R, cc1_plugin::N, A, B, C, D, E, F, G>,
|
||||
|
||||
#include "gcc-c-fe.def"
|
||||
|
||||
#undef GCC_METHOD0
|
||||
#undef GCC_METHOD1
|
||||
#undef GCC_METHOD2
|
||||
#undef GCC_METHOD3
|
||||
#undef GCC_METHOD4
|
||||
#undef GCC_METHOD5
|
||||
#undef GCC_METHOD7
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Construct an appropriate regexp to match the compiler name.
|
||||
static std::string
|
||||
make_regexp (const char *triplet_regexp, const char *compiler)
|
||||
{
|
||||
std::stringstream buf;
|
||||
|
||||
buf << "^" << triplet_regexp << "-";
|
||||
|
||||
// Quote the compiler name in case it has something funny in it.
|
||||
for (const char *p = compiler; *p; ++p)
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case '.':
|
||||
case '^':
|
||||
case '$':
|
||||
case '*':
|
||||
case '+':
|
||||
case '?':
|
||||
case '(':
|
||||
case ')':
|
||||
case '[':
|
||||
case '{':
|
||||
case '\\':
|
||||
case '|':
|
||||
buf << '\\';
|
||||
break;
|
||||
}
|
||||
buf << *p;
|
||||
}
|
||||
buf << "$";
|
||||
|
||||
return buf.str ();
|
||||
}
|
||||
|
||||
static char *
|
||||
libcc1_set_arguments (struct gcc_base_context *s,
|
||||
const char *triplet_regexp,
|
||||
int argc, char **argv)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
regex_t triplet;
|
||||
int code;
|
||||
|
||||
std::string rx = make_regexp (triplet_regexp, COMPILER_NAME);
|
||||
code = regcomp (&triplet, rx.c_str (), REG_EXTENDED | REG_NOSUB);
|
||||
if (code != 0)
|
||||
{
|
||||
size_t len = regerror (code, &triplet, NULL, 0);
|
||||
char err[len];
|
||||
|
||||
regerror (code, &triplet, err, len);
|
||||
|
||||
return concat ("Could not compile regexp \"",
|
||||
rx.c_str (),
|
||||
"\": ",
|
||||
err,
|
||||
(char *) NULL);
|
||||
}
|
||||
|
||||
std::string compiler;
|
||||
if (!find_compiler (triplet, &compiler))
|
||||
{
|
||||
regfree (&triplet);
|
||||
return concat ("Could not find a compiler matching \"",
|
||||
rx.c_str (),
|
||||
"\"",
|
||||
(char *) NULL);
|
||||
}
|
||||
regfree (&triplet);
|
||||
|
||||
self->args.push_back (compiler);
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
self->args.push_back (argv[i]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
libcc1_set_source_file (struct gcc_base_context *s,
|
||||
const char *file)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
|
||||
self->source_file = file;
|
||||
}
|
||||
|
||||
static void
|
||||
libcc1_set_print_callback (struct gcc_base_context *s,
|
||||
void (*print_function) (void *datum,
|
||||
const char *message),
|
||||
void *datum)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
|
||||
self->print_function = print_function;
|
||||
self->print_datum = datum;
|
||||
}
|
||||
|
||||
static int
|
||||
fork_exec (libcc1 *self, char **argv, int spair_fds[2], int stderr_fds[2])
|
||||
{
|
||||
pid_t child_pid = fork ();
|
||||
|
||||
if (child_pid == -1)
|
||||
{
|
||||
close (spair_fds[0]);
|
||||
close (spair_fds[1]);
|
||||
close (stderr_fds[0]);
|
||||
close (stderr_fds[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (child_pid == 0)
|
||||
{
|
||||
// Child.
|
||||
dup2 (stderr_fds[1], 1);
|
||||
dup2 (stderr_fds[1], 2);
|
||||
close (stderr_fds[0]);
|
||||
close (stderr_fds[1]);
|
||||
close (spair_fds[0]);
|
||||
|
||||
execvp (argv[0], argv);
|
||||
_exit (127);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parent.
|
||||
close (spair_fds[1]);
|
||||
close (stderr_fds[1]);
|
||||
|
||||
cc1_plugin::status result = cc1_plugin::FAIL;
|
||||
if (self->connection->send ('H')
|
||||
&& ::cc1_plugin::marshall (self->connection, GCC_C_FE_VERSION_0))
|
||||
result = self->connection->wait_for_query ();
|
||||
|
||||
close (spair_fds[0]);
|
||||
close (stderr_fds[0]);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (waitpid (child_pid, &status, 0) == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
libcc1_compile (struct gcc_base_context *s,
|
||||
const char *filename,
|
||||
int verbose)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
|
||||
int fds[2];
|
||||
if (socketpair (AF_LOCAL, SOCK_STREAM, 0, fds) != 0)
|
||||
{
|
||||
self->print ("could not create socketpair\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stderr_fds[2];
|
||||
if (pipe (stderr_fds) != 0)
|
||||
{
|
||||
self->print ("could not create pipe\n");
|
||||
close (fds[0]);
|
||||
close (fds[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
self->args.push_back ("-fplugin=libcc1plugin");
|
||||
char buf[100];
|
||||
if (snprintf (buf, sizeof (buf), "-fplugin-arg-libcc1plugin-fd=%d", fds[1])
|
||||
>= (long) sizeof (buf))
|
||||
abort ();
|
||||
self->args.push_back (buf);
|
||||
|
||||
self->args.push_back (self->source_file);
|
||||
self->args.push_back ("-c");
|
||||
self->args.push_back ("-o");
|
||||
self->args.push_back (filename);
|
||||
if (verbose)
|
||||
self->args.push_back ("-v");
|
||||
|
||||
self->connection = new libcc1_connection (fds[0], stderr_fds[0], self);
|
||||
|
||||
cc1_plugin::callback_ftype *fun
|
||||
= cc1_plugin::callback<int,
|
||||
enum gcc_c_oracle_request,
|
||||
const char *,
|
||||
call_binding_oracle>;
|
||||
self->connection->add_callback ("binding_oracle", fun);
|
||||
|
||||
fun = cc1_plugin::callback<gcc_address,
|
||||
const char *,
|
||||
call_symbol_address>;
|
||||
self->connection->add_callback ("address_oracle", fun);
|
||||
|
||||
char **argv = new (std::nothrow) char *[self->args.size () + 1];
|
||||
if (argv == NULL)
|
||||
return 0;
|
||||
|
||||
for (unsigned int i = 0; i < self->args.size (); ++i)
|
||||
argv[i] = const_cast<char *> (self->args[i].c_str ());
|
||||
argv[self->args.size ()] = NULL;
|
||||
|
||||
return fork_exec (self, argv, fds, stderr_fds);
|
||||
}
|
||||
|
||||
static void
|
||||
libcc1_destroy (struct gcc_base_context *s)
|
||||
{
|
||||
libcc1 *self = (libcc1 *) s;
|
||||
|
||||
delete self;
|
||||
}
|
||||
|
||||
static const struct gcc_base_vtable vtable =
|
||||
{
|
||||
GCC_FE_VERSION_0,
|
||||
libcc1_set_arguments,
|
||||
libcc1_set_source_file,
|
||||
libcc1_set_print_callback,
|
||||
libcc1_compile,
|
||||
libcc1_destroy
|
||||
};
|
||||
|
||||
extern "C" gcc_c_fe_context_function gcc_c_fe_context;
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
struct gcc_c_context *
|
||||
gcc_c_fe_context (enum gcc_base_api_version base_version,
|
||||
enum gcc_c_api_version c_version)
|
||||
{
|
||||
if (base_version != GCC_FE_VERSION_0 || c_version != GCC_C_FE_VERSION_0)
|
||||
return NULL;
|
||||
|
||||
return new libcc1 (&vtable, &c_vtable);
|
||||
}
|
1
libcc1/libcc1.sym
Normal file
1
libcc1/libcc1.sym
Normal file
|
@ -0,0 +1 @@
|
|||
gcc_c_fe_context
|
2
libcc1/libcc1plugin.sym
Normal file
2
libcc1/libcc1plugin.sym
Normal file
|
@ -0,0 +1,2 @@
|
|||
plugin_init
|
||||
plugin_is_GPL_compatible
|
166
libcc1/marshall.cc
Normal file
166
libcc1/marshall.cc
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* Marshalling and unmarshalling.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <cc1plugin-config.h>
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
#include "marshall.hh"
|
||||
#include "connection.hh"
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::unmarshall_check (connection *conn, unsigned long long check)
|
||||
{
|
||||
unsigned long long r;
|
||||
|
||||
if (!unmarshall (conn, &r))
|
||||
return FAIL;
|
||||
return check == r ? OK : FAIL;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::marshall_intlike (connection *conn, unsigned long long val)
|
||||
{
|
||||
if (!conn->send ('i'))
|
||||
return FAIL;
|
||||
return conn->send (&val, sizeof (val));
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::unmarshall_intlike (connection *conn, unsigned long long *result)
|
||||
{
|
||||
if (!conn->require ('i'))
|
||||
return FAIL;
|
||||
return conn->get (result, sizeof (*result));
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::unmarshall (connection *conn, enum gcc_c_symbol_kind *result)
|
||||
{
|
||||
protocol_int p;
|
||||
if (!unmarshall_intlike (conn, &p))
|
||||
return FAIL;
|
||||
*result = (enum gcc_c_symbol_kind) p;
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::unmarshall (connection *conn, enum gcc_c_oracle_request *result)
|
||||
{
|
||||
protocol_int p;
|
||||
if (!unmarshall_intlike (conn, &p))
|
||||
return FAIL;
|
||||
*result = (enum gcc_c_oracle_request) p;
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::unmarshall (connection *conn, enum gcc_qualifiers *result)
|
||||
{
|
||||
protocol_int p;
|
||||
if (!unmarshall_intlike (conn, &p))
|
||||
return FAIL;
|
||||
*result = (enum gcc_qualifiers) p;
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::marshall (connection *conn, const char *str)
|
||||
{
|
||||
if (!conn->send ('s'))
|
||||
return FAIL;
|
||||
|
||||
unsigned long long len = str == NULL ? -1ULL : strlen (str);
|
||||
if (!conn->send (&len, sizeof (len)))
|
||||
return FAIL;
|
||||
|
||||
if (str == NULL)
|
||||
return OK;
|
||||
|
||||
return conn->send (str, len);
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::unmarshall (connection *conn, char **result)
|
||||
{
|
||||
unsigned long long len;
|
||||
|
||||
if (!conn->require ('s'))
|
||||
return FAIL;
|
||||
if (!conn->get (&len, sizeof (len)))
|
||||
return FAIL;
|
||||
|
||||
if (len == -1ULL)
|
||||
{
|
||||
*result = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
char *str = new (std::nothrow) char[len + 1];
|
||||
if (str == NULL)
|
||||
return FAIL;
|
||||
|
||||
if (!conn->get (str, len))
|
||||
{
|
||||
delete[] str;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
str[len] = '\0';
|
||||
*result = str;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::marshall (connection *conn, const gcc_type_array *a)
|
||||
{
|
||||
if (!conn->send ('a'))
|
||||
return FAIL;
|
||||
|
||||
unsigned long long r = a->n_elements;
|
||||
if (!conn->send (&r, sizeof (r)))
|
||||
return FAIL;
|
||||
|
||||
return conn->send (a->elements, r * sizeof (a->elements[0]));
|
||||
}
|
||||
|
||||
cc1_plugin::status
|
||||
cc1_plugin::unmarshall (connection *conn, gcc_type_array **result)
|
||||
{
|
||||
unsigned long long len;
|
||||
|
||||
if (!conn->require ('a'))
|
||||
return FAIL;
|
||||
if (!conn->get (&len, sizeof (len)))
|
||||
return FAIL;
|
||||
|
||||
*result = new gcc_type_array;
|
||||
|
||||
(*result)->n_elements = len;
|
||||
(*result)->elements = new gcc_type[len];
|
||||
|
||||
if (!conn->get ((*result)->elements, len * sizeof ((*result)->elements[0])))
|
||||
{
|
||||
delete[] (*result)->elements;
|
||||
delete *result;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
93
libcc1/marshall.hh
Normal file
93
libcc1/marshall.hh
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* Marshalling and unmarshalling.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_MARSHALL_HH
|
||||
#define CC1_PLUGIN_MARSHALL_HH
|
||||
|
||||
#include "status.hh"
|
||||
#include "gcc-c-interface.h"
|
||||
|
||||
namespace cc1_plugin
|
||||
{
|
||||
class connection;
|
||||
|
||||
// Only a single kind of integer is ever sent over the wire, and
|
||||
// this is it.
|
||||
typedef unsigned long long protocol_int;
|
||||
|
||||
// Read an integer from the connection and verify that it has the
|
||||
// value V.
|
||||
status unmarshall_check (connection *, protocol_int v);
|
||||
|
||||
// Write an integer, prefixed with the integer type marker, to the
|
||||
// connection.
|
||||
status marshall_intlike (connection *, protocol_int);
|
||||
|
||||
// Read a type marker from the connection and verify that it is an
|
||||
// integer type marker. If not, return FAIL. If so, read an
|
||||
// integer store it in the out argument.
|
||||
status unmarshall_intlike (connection *, protocol_int *);
|
||||
|
||||
// A template function that can handle marshalling various integer
|
||||
// objects to the connection.
|
||||
template<typename T>
|
||||
status marshall (connection *conn, T scalar)
|
||||
{
|
||||
return marshall_intlike (conn, scalar);
|
||||
}
|
||||
|
||||
// A template function that can handle unmarshalling various integer
|
||||
// objects from the connection. Note that this can't be
|
||||
// instantiated for enum types. Note also that there's no way at
|
||||
// the protocol level to distinguish different int types.
|
||||
template<typename T>
|
||||
status unmarshall (connection *conn, T *scalar)
|
||||
{
|
||||
protocol_int result;
|
||||
|
||||
if (!unmarshall_intlike (conn, &result))
|
||||
return FAIL;
|
||||
*scalar = result;
|
||||
return OK;
|
||||
}
|
||||
|
||||
// Unmarshallers for some specific enum types. With C++11 we
|
||||
// wouldn't need these, as we could add type traits to the scalar
|
||||
// unmarshaller.
|
||||
status unmarshall (connection *, enum gcc_c_symbol_kind *);
|
||||
status unmarshall (connection *, enum gcc_qualifiers *);
|
||||
status unmarshall (connection *, enum gcc_c_oracle_request *);
|
||||
|
||||
// Send a string type marker followed by a string.
|
||||
status marshall (connection *, const char *);
|
||||
|
||||
// Read a string type marker followed by a string. The caller is
|
||||
// responsible for freeing the resulting string using 'delete[]'.
|
||||
status unmarshall (connection *, char **);
|
||||
|
||||
// Send a gcc_type_array marker followed by the array.
|
||||
status marshall (connection *, const gcc_type_array *);
|
||||
|
||||
// Read a gcc_type_array marker, followed by a gcc_type_array. The
|
||||
// resulting array must be freed by the caller, using 'delete[]' on
|
||||
// the elements, and 'delete' on the array object itself.
|
||||
status unmarshall (connection *, struct gcc_type_array **);
|
||||
};
|
||||
|
||||
#endif // CC1_PLUGIN_MARSHALL_HH
|
46
libcc1/names.cc
Normal file
46
libcc1/names.cc
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* String definitions.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <cc1plugin-config.h>
|
||||
#include "names.hh"
|
||||
|
||||
#define GCC_METHOD0(R, N) \
|
||||
const char *cc1_plugin::N = # N;
|
||||
#define GCC_METHOD1(R, N, A) \
|
||||
const char *cc1_plugin::N = # N;
|
||||
#define GCC_METHOD2(R, N, A, B) \
|
||||
const char *cc1_plugin::N = # N;
|
||||
#define GCC_METHOD3(R, N, A, B, C) \
|
||||
const char *cc1_plugin::N = # N;
|
||||
#define GCC_METHOD4(R, N, A, B, C, D) \
|
||||
const char *cc1_plugin::N = # N;
|
||||
#define GCC_METHOD5(R, N, A, B, C, D, E) \
|
||||
const char *cc1_plugin::N = # N;
|
||||
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
|
||||
const char *cc1_plugin::N = # N;
|
||||
|
||||
#include "gcc-c-fe.def"
|
||||
|
||||
#undef GCC_METHOD0
|
||||
#undef GCC_METHOD1
|
||||
#undef GCC_METHOD2
|
||||
#undef GCC_METHOD3
|
||||
#undef GCC_METHOD4
|
||||
#undef GCC_METHOD5
|
||||
#undef GCC_METHOD7
|
55
libcc1/names.hh
Normal file
55
libcc1/names.hh
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* String declarations.
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_NAMES_HH
|
||||
#define CC1_PLUGIN_NAMES_HH
|
||||
|
||||
namespace cc1_plugin
|
||||
{
|
||||
// This code defines global string constants, one for each method in
|
||||
// gcc-c-fe.def. This is needed so that they can be used as
|
||||
// template arguments elsewhere.
|
||||
|
||||
#define GCC_METHOD0(R, N) \
|
||||
extern const char *N;
|
||||
#define GCC_METHOD1(R, N, A) \
|
||||
extern const char *N;
|
||||
#define GCC_METHOD2(R, N, A, B) \
|
||||
extern const char *N;
|
||||
#define GCC_METHOD3(R, N, A, B, C) \
|
||||
extern const char *N;
|
||||
#define GCC_METHOD4(R, N, A, B, C, D) \
|
||||
extern const char *N;
|
||||
#define GCC_METHOD5(R, N, A, B, C, D, E) \
|
||||
extern const char *N;
|
||||
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
|
||||
extern const char *N;
|
||||
|
||||
#include "gcc-c-fe.def"
|
||||
|
||||
#undef GCC_METHOD0
|
||||
#undef GCC_METHOD1
|
||||
#undef GCC_METHOD2
|
||||
#undef GCC_METHOD3
|
||||
#undef GCC_METHOD4
|
||||
#undef GCC_METHOD5
|
||||
#undef GCC_METHOD7
|
||||
};
|
||||
|
||||
#endif // CC1_PLUGIN_NAMES_HH
|
916
libcc1/plugin.cc
Normal file
916
libcc1/plugin.cc
Normal file
|
@ -0,0 +1,916 @@
|
|||
/* Library interface to C front end
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <cc1plugin-config.h>
|
||||
|
||||
#undef PACKAGE_NAME
|
||||
#undef PACKAGE_STRING
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
#include "../gcc/config.h"
|
||||
|
||||
#undef PACKAGE_NAME
|
||||
#undef PACKAGE_STRING
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
#include "gcc-plugin.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "stringpool.h"
|
||||
|
||||
#include "gcc-interface.h"
|
||||
#include "tree-core.h"
|
||||
#include "wide-int.h"
|
||||
#include "stor-layout.h"
|
||||
#include "c-tree.h"
|
||||
#include "toplev.h"
|
||||
#include "timevar.h"
|
||||
#include "hash-table.h"
|
||||
#include "tm.h"
|
||||
#include "c-family/c-pragma.h"
|
||||
#include "c-lang.h"
|
||||
#include "diagnostic.h"
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
|
||||
#include "callbacks.hh"
|
||||
#include "connection.hh"
|
||||
#include "rpc.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
int plugin_is_GPL_compatible;
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// This is put into the lang hooks when the plugin starts.
|
||||
|
||||
static void
|
||||
plugin_print_error_function (diagnostic_context *context, const char *file,
|
||||
diagnostic_info *diagnostic)
|
||||
{
|
||||
if (current_function_decl != NULL_TREE
|
||||
&& DECL_NAME (current_function_decl) != NULL_TREE
|
||||
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
|
||||
GCC_FE_WRAPPER_FUNCTION) == 0)
|
||||
return;
|
||||
lhd_print_error_function (context, file, diagnostic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned long long
|
||||
convert_out (tree t)
|
||||
{
|
||||
return (unsigned long long) (uintptr_t) t;
|
||||
}
|
||||
|
||||
static tree
|
||||
convert_in (unsigned long long v)
|
||||
{
|
||||
return (tree) (uintptr_t) v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct decl_addr_value
|
||||
{
|
||||
tree decl;
|
||||
tree address;
|
||||
};
|
||||
|
||||
struct decl_addr_hasher : typed_free_remove<decl_addr_value>
|
||||
{
|
||||
typedef decl_addr_value value_type;
|
||||
typedef decl_addr_value compare_type;
|
||||
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
decl_addr_hasher::hash (const value_type *e)
|
||||
{
|
||||
return IDENTIFIER_HASH_VALUE (DECL_NAME (e->decl));
|
||||
}
|
||||
|
||||
inline bool
|
||||
decl_addr_hasher::equal (const value_type *p1, const compare_type *p2)
|
||||
{
|
||||
return p1->decl == p2->decl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct string_hasher : typed_noop_remove<char>
|
||||
{
|
||||
typedef char value_type;
|
||||
typedef char compare_type;
|
||||
|
||||
static inline hashval_t hash (const value_type *s)
|
||||
{
|
||||
return htab_hash_string (s);
|
||||
}
|
||||
|
||||
static inline bool equal (const value_type *p1, const value_type *p2)
|
||||
{
|
||||
return strcmp (p1, p2) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// A wrapper for pushdecl that doesn't let gdb have a chance to
|
||||
// instantiate a symbol.
|
||||
|
||||
static void
|
||||
pushdecl_safe (tree decl)
|
||||
{
|
||||
void (*save) (enum c_oracle_request, tree identifier);
|
||||
|
||||
save = c_binding_oracle;
|
||||
c_binding_oracle = NULL;
|
||||
pushdecl (decl);
|
||||
c_binding_oracle = save;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct plugin_context : public cc1_plugin::connection
|
||||
{
|
||||
plugin_context (int fd);
|
||||
|
||||
// Map decls to addresses.
|
||||
hash_table<decl_addr_hasher> address_map;
|
||||
|
||||
// A collection of trees that are preserved for the GC.
|
||||
hash_table< pointer_hash<tree_node> > preserved;
|
||||
|
||||
// File name cache.
|
||||
hash_table<string_hasher> file_names;
|
||||
|
||||
// Perform GC marking.
|
||||
void mark ();
|
||||
|
||||
// Preserve a tree during the plugin's operation.
|
||||
tree preserve (tree t)
|
||||
{
|
||||
tree_node **slot = preserved.find_slot (t, INSERT);
|
||||
*slot = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
source_location get_source_location (const char *filename,
|
||||
unsigned int line_number)
|
||||
{
|
||||
if (filename == NULL)
|
||||
return UNKNOWN_LOCATION;
|
||||
|
||||
filename = intern_filename (filename);
|
||||
linemap_add (line_table, LC_ENTER, false, filename, line_number);
|
||||
source_location loc = linemap_line_start (line_table, line_number, 0);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
return loc;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Add a file name to FILE_NAMES and return the canonical copy.
|
||||
const char *intern_filename (const char *filename)
|
||||
{
|
||||
char **slot = file_names.find_slot (filename, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
/* The file name must live as long as the line map, which
|
||||
effectively means as long as this compilation. So, we copy
|
||||
the string here but never free it. */
|
||||
*slot = xstrdup (filename);
|
||||
}
|
||||
return *slot;
|
||||
}
|
||||
};
|
||||
|
||||
static plugin_context *current_context;
|
||||
|
||||
|
||||
|
||||
plugin_context::plugin_context (int fd)
|
||||
: cc1_plugin::connection (fd),
|
||||
address_map (30),
|
||||
preserved (30),
|
||||
file_names (30)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
plugin_context::mark ()
|
||||
{
|
||||
for (hash_table<decl_addr_hasher>::iterator it = address_map.begin ();
|
||||
it != address_map.end ();
|
||||
++it)
|
||||
{
|
||||
ggc_mark ((*it)->decl);
|
||||
ggc_mark ((*it)->address);
|
||||
}
|
||||
|
||||
for (hash_table< pointer_hash<tree_node> >::iterator it = preserved.begin ();
|
||||
it != preserved.end ();
|
||||
++it)
|
||||
ggc_mark (&*it);
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_binding_oracle (enum c_oracle_request kind, tree identifier)
|
||||
{
|
||||
enum gcc_c_oracle_request request;
|
||||
|
||||
gcc_assert (current_context != NULL);
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case C_ORACLE_SYMBOL:
|
||||
request = GCC_C_ORACLE_SYMBOL;
|
||||
break;
|
||||
case C_ORACLE_TAG:
|
||||
request = GCC_C_ORACLE_TAG;
|
||||
break;
|
||||
case C_ORACLE_LABEL:
|
||||
request = GCC_C_ORACLE_LABEL;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
int ignore;
|
||||
cc1_plugin::call (current_context, "binding_oracle", &ignore,
|
||||
request, IDENTIFIER_POINTER (identifier));
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_pragma_user_expression (cpp_reader *)
|
||||
{
|
||||
c_binding_oracle = plugin_binding_oracle;
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_init_extra_pragmas (void *, void *)
|
||||
{
|
||||
c_register_pragma ("GCC", "user_expression", plugin_pragma_user_expression);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Maybe rewrite a decl to its address.
|
||||
static tree
|
||||
address_rewriter (tree *in, int *walk_subtrees, void *arg)
|
||||
{
|
||||
plugin_context *ctx = (plugin_context *) arg;
|
||||
|
||||
if (!DECL_P (*in) || DECL_NAME (*in) == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
|
||||
decl_addr_value value;
|
||||
value.decl = *in;
|
||||
decl_addr_value *found_value = ctx->address_map.find (&value);
|
||||
if (found_value != NULL)
|
||||
{
|
||||
// At this point we don't need VLA sizes for gdb-supplied
|
||||
// variables, and having them here confuses later passes, so we
|
||||
// drop them.
|
||||
if (C_TYPE_VARIABLE_SIZE (TREE_TYPE (*in)))
|
||||
{
|
||||
TREE_TYPE (*in)
|
||||
= build_array_type_nelts (TREE_TYPE (TREE_TYPE (*in)), 1);
|
||||
DECL_SIZE (*in) = TYPE_SIZE (TREE_TYPE (*in));
|
||||
DECL_SIZE_UNIT (*in) = TYPE_SIZE_UNIT (TREE_TYPE (*in));
|
||||
}
|
||||
}
|
||||
else if (DECL_IS_BUILTIN (*in))
|
||||
{
|
||||
gcc_address address;
|
||||
|
||||
if (!cc1_plugin::call (ctx, "address_oracle", &address,
|
||||
IDENTIFIER_POINTER (DECL_NAME (*in))))
|
||||
return NULL_TREE;
|
||||
if (address == 0)
|
||||
return NULL_TREE;
|
||||
|
||||
// Insert the decl into the address map in case it is referenced
|
||||
// again.
|
||||
value.address = build_int_cst_type (ptr_type_node, address);
|
||||
decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
|
||||
gcc_assert (*slot == NULL);
|
||||
*slot
|
||||
= static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
|
||||
**slot = value;
|
||||
found_value = *slot;
|
||||
}
|
||||
else
|
||||
return NULL_TREE;
|
||||
|
||||
if (found_value->address != error_mark_node)
|
||||
{
|
||||
// We have an address for the decl, so rewrite the tree.
|
||||
tree ptr_type = build_pointer_type (TREE_TYPE (*in));
|
||||
*in = fold_build1 (INDIRECT_REF, TREE_TYPE (*in),
|
||||
fold_build1 (CONVERT_EXPR, ptr_type,
|
||||
found_value->address));
|
||||
}
|
||||
|
||||
*walk_subtrees = 0;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
// When generating code for gdb, we want to be able to use absolute
|
||||
// addresses to refer to otherwise external objects that gdb knows
|
||||
// about. gdb passes in these addresses when building decls, and then
|
||||
// before gimplification we go through the trees, rewriting uses to
|
||||
// the equivalent of "*(TYPE *) ADDR".
|
||||
static void
|
||||
rewrite_decls_to_addresses (void *function_in, void *)
|
||||
{
|
||||
tree function = (tree) function_in;
|
||||
|
||||
// Do nothing if we're not in gdb.
|
||||
if (current_context == NULL)
|
||||
return;
|
||||
|
||||
walk_tree (&DECL_SAVED_TREE (function), address_rewriter, current_context,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
gcc_decl
|
||||
plugin_build_decl (cc1_plugin::connection *self,
|
||||
const char *name,
|
||||
enum gcc_c_symbol_kind sym_kind,
|
||||
gcc_type sym_type_in,
|
||||
const char *substitution_name,
|
||||
gcc_address address,
|
||||
const char *filename,
|
||||
unsigned int line_number)
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
tree identifier = get_identifier (name);
|
||||
enum tree_code code;
|
||||
tree decl;
|
||||
tree sym_type = convert_in (sym_type_in);
|
||||
|
||||
switch (sym_kind)
|
||||
{
|
||||
case GCC_C_SYMBOL_FUNCTION:
|
||||
code = FUNCTION_DECL;
|
||||
break;
|
||||
|
||||
case GCC_C_SYMBOL_VARIABLE:
|
||||
code = VAR_DECL;
|
||||
break;
|
||||
|
||||
case GCC_C_SYMBOL_TYPEDEF:
|
||||
code = TYPE_DECL;
|
||||
break;
|
||||
|
||||
case GCC_C_SYMBOL_LABEL:
|
||||
// FIXME: we aren't ready to handle labels yet.
|
||||
// It isn't clear how to translate them properly
|
||||
// and in any case a "goto" isn't likely to work.
|
||||
return convert_out (error_mark_node);
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
source_location loc = ctx->get_source_location (filename, line_number);
|
||||
|
||||
decl = build_decl (loc, code, identifier, sym_type);
|
||||
TREE_USED (decl) = 1;
|
||||
TREE_ADDRESSABLE (decl) = 1;
|
||||
|
||||
if (sym_kind != GCC_C_SYMBOL_TYPEDEF)
|
||||
{
|
||||
decl_addr_value value;
|
||||
|
||||
value.decl = decl;
|
||||
if (substitution_name != NULL)
|
||||
{
|
||||
// If the translator gave us a name without a binding,
|
||||
// we can just substitute error_mark_node, since we know the
|
||||
// translator will be reporting an error anyhow.
|
||||
value.address
|
||||
= lookup_name (get_identifier (substitution_name));
|
||||
if (value.address == NULL_TREE)
|
||||
value.address = error_mark_node;
|
||||
}
|
||||
else
|
||||
value.address = build_int_cst_type (ptr_type_node, address);
|
||||
decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
|
||||
gcc_assert (*slot == NULL);
|
||||
*slot
|
||||
= static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
|
||||
**slot = value;
|
||||
}
|
||||
|
||||
return convert_out (ctx->preserve (decl));
|
||||
}
|
||||
|
||||
int
|
||||
plugin_bind (cc1_plugin::connection *,
|
||||
gcc_decl decl_in, int is_global)
|
||||
{
|
||||
tree decl = convert_in (decl_in);
|
||||
c_bind (DECL_SOURCE_LOCATION (decl), decl, is_global);
|
||||
rest_of_decl_compilation (decl, is_global, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_tagbind (cc1_plugin::connection *self,
|
||||
const char *name, gcc_type tagged_type,
|
||||
const char *filename, unsigned int line_number)
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
c_pushtag (ctx->get_source_location (filename, line_number),
|
||||
get_identifier (name), convert_in (tagged_type));
|
||||
return 1;
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_pointer_type (cc1_plugin::connection *,
|
||||
gcc_type base_type)
|
||||
{
|
||||
// No need to preserve a pointer type as the base type is preserved.
|
||||
return convert_out (build_pointer_type (convert_in (base_type)));
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_record_type (cc1_plugin::connection *self)
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (make_node (RECORD_TYPE)));
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_union_type (cc1_plugin::connection *self)
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (make_node (UNION_TYPE)));
|
||||
}
|
||||
|
||||
int
|
||||
plugin_build_add_field (cc1_plugin::connection *,
|
||||
gcc_type record_or_union_type_in,
|
||||
const char *field_name,
|
||||
gcc_type field_type_in,
|
||||
unsigned long bitsize,
|
||||
unsigned long bitpos)
|
||||
{
|
||||
tree record_or_union_type = convert_in (record_or_union_type_in);
|
||||
tree field_type = convert_in (field_type_in);
|
||||
|
||||
gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
|
||||
|| TREE_CODE (record_or_union_type) == UNION_TYPE);
|
||||
|
||||
/* Note that gdb does not preserve the location of field decls, so
|
||||
we can't provide a decent location here. */
|
||||
tree decl = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
get_identifier (field_name), field_type);
|
||||
DECL_FIELD_CONTEXT (decl) = record_or_union_type;
|
||||
|
||||
if (TREE_CODE (field_type) == INTEGER_TYPE
|
||||
&& TYPE_PRECISION (field_type) != bitsize)
|
||||
{
|
||||
DECL_BIT_FIELD_TYPE (decl) = field_type;
|
||||
TREE_TYPE (decl)
|
||||
= c_build_bitfield_integer_type (bitsize, TYPE_UNSIGNED (field_type));
|
||||
}
|
||||
|
||||
DECL_MODE (decl) = TYPE_MODE (TREE_TYPE (decl));
|
||||
|
||||
// There's no way to recover this from DWARF.
|
||||
SET_DECL_OFFSET_ALIGN (decl, TYPE_PRECISION (pointer_sized_int_node));
|
||||
|
||||
tree pos = bitsize_int (bitpos);
|
||||
pos_from_bit (&DECL_FIELD_OFFSET (decl), &DECL_FIELD_BIT_OFFSET (decl),
|
||||
DECL_OFFSET_ALIGN (decl), pos);
|
||||
|
||||
DECL_SIZE (decl) = bitsize_int (bitsize);
|
||||
DECL_SIZE_UNIT (decl) = size_int ((bitsize + BITS_PER_UNIT - 1)
|
||||
/ BITS_PER_UNIT);
|
||||
|
||||
DECL_CHAIN (decl) = TYPE_FIELDS (record_or_union_type);
|
||||
TYPE_FIELDS (record_or_union_type) = decl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_finish_record_or_union (cc1_plugin::connection *,
|
||||
gcc_type record_or_union_type_in,
|
||||
unsigned long size_in_bytes)
|
||||
{
|
||||
tree record_or_union_type = convert_in (record_or_union_type_in);
|
||||
|
||||
gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
|
||||
|| TREE_CODE (record_or_union_type) == UNION_TYPE);
|
||||
|
||||
/* We built the field list in reverse order, so fix it now. */
|
||||
TYPE_FIELDS (record_or_union_type)
|
||||
= nreverse (TYPE_FIELDS (record_or_union_type));
|
||||
|
||||
if (TREE_CODE (record_or_union_type) == UNION_TYPE)
|
||||
{
|
||||
/* Unions can just be handled by the generic code. */
|
||||
layout_type (record_or_union_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME there's no way to get this from DWARF,
|
||||
// or even, it seems, a particularly good way to deduce it.
|
||||
TYPE_ALIGN (record_or_union_type)
|
||||
= TYPE_PRECISION (pointer_sized_int_node);
|
||||
|
||||
TYPE_SIZE (record_or_union_type) = bitsize_int (size_in_bytes
|
||||
* BITS_PER_UNIT);
|
||||
TYPE_SIZE_UNIT (record_or_union_type) = size_int (size_in_bytes);
|
||||
|
||||
compute_record_mode (record_or_union_type);
|
||||
finish_bitfield_layout (record_or_union_type);
|
||||
// FIXME we have no idea about TYPE_PACKED
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_enum_type (cc1_plugin::connection *self,
|
||||
gcc_type underlying_int_type_in)
|
||||
{
|
||||
tree underlying_int_type = convert_in (underlying_int_type_in);
|
||||
|
||||
if (underlying_int_type == error_mark_node)
|
||||
return convert_out (error_mark_node);
|
||||
|
||||
tree result = make_node (ENUMERAL_TYPE);
|
||||
|
||||
TYPE_PRECISION (result) = TYPE_PRECISION (underlying_int_type);
|
||||
TYPE_UNSIGNED (result) = TYPE_UNSIGNED (underlying_int_type);
|
||||
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (result));
|
||||
}
|
||||
|
||||
int
|
||||
plugin_build_add_enum_constant (cc1_plugin::connection *,
|
||||
gcc_type enum_type_in,
|
||||
const char *name,
|
||||
unsigned long value)
|
||||
{
|
||||
tree cst, decl, cons;
|
||||
tree enum_type = convert_in (enum_type_in);
|
||||
|
||||
gcc_assert (TREE_CODE (enum_type) == ENUMERAL_TYPE);
|
||||
|
||||
cst = build_int_cst (enum_type, value);
|
||||
/* Note that gdb does not preserve the location of enum constants,
|
||||
so we can't provide a decent location here. */
|
||||
decl = build_decl (BUILTINS_LOCATION, CONST_DECL,
|
||||
get_identifier (name), enum_type);
|
||||
DECL_INITIAL (decl) = cst;
|
||||
pushdecl_safe (decl);
|
||||
|
||||
cons = tree_cons (DECL_NAME (decl), cst, TYPE_VALUES (enum_type));
|
||||
TYPE_VALUES (enum_type) = cons;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_finish_enum_type (cc1_plugin::connection *,
|
||||
gcc_type enum_type_in)
|
||||
{
|
||||
tree enum_type = convert_in (enum_type_in);
|
||||
tree minnode, maxnode, iter;
|
||||
|
||||
iter = TYPE_VALUES (enum_type);
|
||||
minnode = maxnode = TREE_VALUE (iter);
|
||||
for (iter = TREE_CHAIN (iter);
|
||||
iter != NULL_TREE;
|
||||
iter = TREE_CHAIN (iter))
|
||||
{
|
||||
tree value = TREE_VALUE (iter);
|
||||
if (tree_int_cst_lt (maxnode, value))
|
||||
maxnode = value;
|
||||
if (tree_int_cst_lt (value, minnode))
|
||||
minnode = value;
|
||||
}
|
||||
TYPE_MIN_VALUE (enum_type) = minnode;
|
||||
TYPE_MAX_VALUE (enum_type) = maxnode;
|
||||
|
||||
layout_type (enum_type);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_function_type (cc1_plugin::connection *self,
|
||||
gcc_type return_type_in,
|
||||
const struct gcc_type_array *argument_types_in,
|
||||
int is_varargs)
|
||||
{
|
||||
tree *argument_types;
|
||||
tree return_type = convert_in (return_type_in);
|
||||
tree result;
|
||||
|
||||
argument_types = new tree[argument_types_in->n_elements];
|
||||
for (int i = 0; i < argument_types_in->n_elements; ++i)
|
||||
argument_types[i] = convert_in (argument_types_in->elements[i]);
|
||||
|
||||
if (is_varargs)
|
||||
result = build_varargs_function_type_array (return_type,
|
||||
argument_types_in->n_elements,
|
||||
argument_types);
|
||||
else
|
||||
result = build_function_type_array (return_type,
|
||||
argument_types_in->n_elements,
|
||||
argument_types);
|
||||
|
||||
delete[] argument_types;
|
||||
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (result));
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_int_type (cc1_plugin::connection *self,
|
||||
int is_unsigned, unsigned long size_in_bytes)
|
||||
{
|
||||
tree result = c_common_type_for_size (BITS_PER_UNIT * size_in_bytes,
|
||||
is_unsigned);
|
||||
if (result == NULL_TREE)
|
||||
result = error_mark_node;
|
||||
else
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
ctx->preserve (result);
|
||||
}
|
||||
return convert_out (result);
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_float_type (cc1_plugin::connection *,
|
||||
unsigned long size_in_bytes)
|
||||
{
|
||||
if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (float_type_node))
|
||||
return convert_out (float_type_node);
|
||||
if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (double_type_node))
|
||||
return convert_out (double_type_node);
|
||||
if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (long_double_type_node))
|
||||
return convert_out (long_double_type_node);
|
||||
return convert_out (error_mark_node);
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_void_type (cc1_plugin::connection *)
|
||||
{
|
||||
return convert_out (void_type_node);
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_bool_type (cc1_plugin::connection *)
|
||||
{
|
||||
return convert_out (boolean_type_node);
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_array_type (cc1_plugin::connection *self,
|
||||
gcc_type element_type_in, int num_elements)
|
||||
{
|
||||
tree element_type = convert_in (element_type_in);
|
||||
tree result;
|
||||
|
||||
if (num_elements == -1)
|
||||
result = build_array_type (element_type, NULL_TREE);
|
||||
else
|
||||
result = build_array_type_nelts (element_type, num_elements);
|
||||
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (result));
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_vla_array_type (cc1_plugin::connection *self,
|
||||
gcc_type element_type_in,
|
||||
const char *upper_bound_name)
|
||||
{
|
||||
tree element_type = convert_in (element_type_in);
|
||||
tree upper_bound = lookup_name (get_identifier (upper_bound_name));
|
||||
tree range = build_index_type (upper_bound);
|
||||
|
||||
tree result = build_array_type (element_type, range);
|
||||
C_TYPE_VARIABLE_SIZE (result) = 1;
|
||||
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (result));
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_qualified_type (cc1_plugin::connection *,
|
||||
gcc_type unqualified_type_in,
|
||||
enum gcc_qualifiers qualifiers)
|
||||
{
|
||||
tree unqualified_type = convert_in (unqualified_type_in);
|
||||
int quals = 0;
|
||||
|
||||
if ((qualifiers & GCC_QUALIFIER_CONST) != 0)
|
||||
quals |= TYPE_QUAL_CONST;
|
||||
if ((qualifiers & GCC_QUALIFIER_VOLATILE) != 0)
|
||||
quals |= TYPE_QUAL_VOLATILE;
|
||||
if ((qualifiers & GCC_QUALIFIER_RESTRICT) != 0)
|
||||
quals |= TYPE_QUAL_RESTRICT;
|
||||
|
||||
return convert_out (build_qualified_type (unqualified_type, quals));
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_complex_type (cc1_plugin::connection *self,
|
||||
gcc_type base_type)
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (build_complex_type (convert_in (base_type))));
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_build_vector_type (cc1_plugin::connection *self,
|
||||
gcc_type base_type, int nunits)
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
return convert_out (ctx->preserve (build_vector_type (convert_in (base_type),
|
||||
nunits)));
|
||||
}
|
||||
|
||||
int
|
||||
plugin_build_constant (cc1_plugin::connection *self, gcc_type type_in,
|
||||
const char *name, unsigned long value,
|
||||
const char *filename, unsigned int line_number)
|
||||
{
|
||||
plugin_context *ctx = static_cast<plugin_context *> (self);
|
||||
tree cst, decl;
|
||||
tree type = convert_in (type_in);
|
||||
|
||||
cst = build_int_cst (type, value);
|
||||
decl = build_decl (ctx->get_source_location (filename, line_number),
|
||||
CONST_DECL, get_identifier (name), type);
|
||||
DECL_INITIAL (decl) = cst;
|
||||
pushdecl_safe (decl);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
gcc_type
|
||||
plugin_error (cc1_plugin::connection *,
|
||||
const char *message)
|
||||
{
|
||||
error ("%s", message);
|
||||
return convert_out (error_mark_node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Perform GC marking.
|
||||
|
||||
static void
|
||||
gc_mark (void *, void *)
|
||||
{
|
||||
if (current_context != NULL)
|
||||
current_context->mark ();
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
|
||||
int
|
||||
plugin_init (struct plugin_name_args *plugin_info,
|
||||
struct plugin_gcc_version *)
|
||||
{
|
||||
long fd = -1;
|
||||
for (int i = 0; i < plugin_info->argc; ++i)
|
||||
{
|
||||
if (strcmp (plugin_info->argv[i].key, "fd") == 0)
|
||||
{
|
||||
char *tail;
|
||||
errno = 0;
|
||||
fd = strtol (plugin_info->argv[i].value, &tail, 0);
|
||||
if (*tail != '\0' || errno != 0)
|
||||
fatal_error ("%s: invalid file descriptor argument to plugin",
|
||||
plugin_info->base_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd == -1)
|
||||
fatal_error ("%s: required plugin argument %<fd%> is missing",
|
||||
plugin_info->base_name);
|
||||
|
||||
current_context = new plugin_context (fd);
|
||||
|
||||
// Handshake.
|
||||
cc1_plugin::protocol_int version;
|
||||
if (!current_context->require ('H')
|
||||
|| ! ::cc1_plugin::unmarshall (current_context, &version))
|
||||
fatal_error ("%s: handshake failed", plugin_info->base_name);
|
||||
if (version != GCC_C_FE_VERSION_0)
|
||||
fatal_error ("%s: unknown version in handshake", plugin_info->base_name);
|
||||
|
||||
register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
|
||||
plugin_init_extra_pragmas, NULL);
|
||||
register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
|
||||
rewrite_decls_to_addresses, NULL);
|
||||
register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
|
||||
gc_mark, NULL);
|
||||
|
||||
lang_hooks.print_error_function = plugin_print_error_function;
|
||||
|
||||
#define GCC_METHOD0(R, N) \
|
||||
{ \
|
||||
cc1_plugin::callback_ftype *fun \
|
||||
= cc1_plugin::callback<R, plugin_ ## N>; \
|
||||
current_context->add_callback (# N, fun); \
|
||||
}
|
||||
#define GCC_METHOD1(R, N, A) \
|
||||
{ \
|
||||
cc1_plugin::callback_ftype *fun \
|
||||
= cc1_plugin::callback<R, A, plugin_ ## N>; \
|
||||
current_context->add_callback (# N, fun); \
|
||||
}
|
||||
#define GCC_METHOD2(R, N, A, B) \
|
||||
{ \
|
||||
cc1_plugin::callback_ftype *fun \
|
||||
= cc1_plugin::callback<R, A, B, plugin_ ## N>; \
|
||||
current_context->add_callback (# N, fun); \
|
||||
}
|
||||
#define GCC_METHOD3(R, N, A, B, C) \
|
||||
{ \
|
||||
cc1_plugin::callback_ftype *fun \
|
||||
= cc1_plugin::callback<R, A, B, C, plugin_ ## N>; \
|
||||
current_context->add_callback (# N, fun); \
|
||||
}
|
||||
#define GCC_METHOD4(R, N, A, B, C, D) \
|
||||
{ \
|
||||
cc1_plugin::callback_ftype *fun \
|
||||
= cc1_plugin::callback<R, A, B, C, D, \
|
||||
plugin_ ## N>; \
|
||||
current_context->add_callback (# N, fun); \
|
||||
}
|
||||
#define GCC_METHOD5(R, N, A, B, C, D, E) \
|
||||
{ \
|
||||
cc1_plugin::callback_ftype *fun \
|
||||
= cc1_plugin::callback<R, A, B, C, D, E, \
|
||||
plugin_ ## N>; \
|
||||
current_context->add_callback (# N, fun); \
|
||||
}
|
||||
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
|
||||
{ \
|
||||
cc1_plugin::callback_ftype *fun \
|
||||
= cc1_plugin::callback<R, A, B, C, D, E, F, G, \
|
||||
plugin_ ## N>; \
|
||||
current_context->add_callback (# N, fun); \
|
||||
}
|
||||
|
||||
#include "gcc-c-fe.def"
|
||||
|
||||
#undef GCC_METHOD0
|
||||
#undef GCC_METHOD1
|
||||
#undef GCC_METHOD2
|
||||
#undef GCC_METHOD3
|
||||
#undef GCC_METHOD4
|
||||
#undef GCC_METHOD5
|
||||
#undef GCC_METHOD7
|
||||
|
||||
return 0;
|
||||
}
|
486
libcc1/rpc.hh
Normal file
486
libcc1/rpc.hh
Normal file
|
@ -0,0 +1,486 @@
|
|||
/* RPC call and callback templates
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_RPC_HH
|
||||
#define CC1_PLUGIN_RPC_HH
|
||||
|
||||
#include "status.hh"
|
||||
#include "marshall.hh"
|
||||
#include "connection.hh"
|
||||
|
||||
namespace cc1_plugin
|
||||
{
|
||||
// The plugin API may contain some "const" method parameters.
|
||||
// However, when unmarshalling we cannot unmarshall into a const
|
||||
// object; and furthermore we want to be able to deallocate pointers
|
||||
// when finished with them. This wrapper class lets us properly
|
||||
// remove the "const" and handle deallocation from pointer types.
|
||||
|
||||
template<typename T>
|
||||
class argument_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
argument_wrapper () { }
|
||||
~argument_wrapper () { }
|
||||
|
||||
operator T () const { return m_object; }
|
||||
|
||||
status unmarshall (connection *conn)
|
||||
{
|
||||
return ::cc1_plugin::unmarshall (conn, &m_object);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T m_object;
|
||||
|
||||
// No copying or assignment allowed.
|
||||
argument_wrapper (const argument_wrapper &);
|
||||
argument_wrapper &operator= (const argument_wrapper &);
|
||||
};
|
||||
|
||||
// Specialization for any kind of pointer. This is declared but not
|
||||
// defined to avoid bugs if a new pointer type is introduced into
|
||||
// the API. Instead you will just get a compilation error.
|
||||
template<typename T>
|
||||
class argument_wrapper<const T *>;
|
||||
|
||||
// Specialization for string types.
|
||||
template<>
|
||||
class argument_wrapper<const char *>
|
||||
{
|
||||
public:
|
||||
argument_wrapper () : m_object (NULL) { }
|
||||
~argument_wrapper ()
|
||||
{
|
||||
delete[] m_object;
|
||||
}
|
||||
|
||||
operator const char * () const
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
status unmarshall (connection *conn)
|
||||
{
|
||||
return ::cc1_plugin::unmarshall (conn, &m_object);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char *m_object;
|
||||
|
||||
// No copying or assignment allowed.
|
||||
argument_wrapper (const argument_wrapper &);
|
||||
argument_wrapper &operator= (const argument_wrapper &);
|
||||
};
|
||||
|
||||
// Specialization for gcc_type_array.
|
||||
template<>
|
||||
class argument_wrapper<const gcc_type_array *>
|
||||
{
|
||||
public:
|
||||
argument_wrapper () : m_object (NULL) { }
|
||||
~argument_wrapper ()
|
||||
{
|
||||
// It would be nicer if gcc_type_array could have a destructor.
|
||||
// But, it is in code shared with gdb and cannot.
|
||||
if (m_object != NULL)
|
||||
delete[] m_object->elements;
|
||||
delete m_object;
|
||||
}
|
||||
|
||||
operator const gcc_type_array * () const
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
status unmarshall (connection *conn)
|
||||
{
|
||||
return ::cc1_plugin::unmarshall (conn, &m_object);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
gcc_type_array *m_object;
|
||||
|
||||
// No copying or assignment allowed.
|
||||
argument_wrapper (const argument_wrapper &);
|
||||
argument_wrapper &operator= (const argument_wrapper &);
|
||||
};
|
||||
|
||||
// There are two kinds of template functions here: "call" and
|
||||
// "callback". They are each repeated multiple times to handle
|
||||
// different numbers of arguments. (This would be improved with
|
||||
// C++11, though applying a call is still tricky until C++14 can be
|
||||
// used.)
|
||||
|
||||
// The "call" template is used for making a remote procedure call.
|
||||
// It starts a query ('Q') packet, marshalls its arguments, waits
|
||||
// for a result, and finally reads and returns the result via an
|
||||
// "out" parameter.
|
||||
|
||||
// The "callback" template is used when receiving a remote procedure
|
||||
// call. This template function is suitable for use with the
|
||||
// "callbacks" and "connection" classes. It decodes incoming
|
||||
// arguments, passes them to the wrapped function, and finally
|
||||
// marshalls a reply packet.
|
||||
|
||||
template<typename R>
|
||||
status
|
||||
call (connection *conn, const char *method, R *result)
|
||||
{
|
||||
if (!conn->send ('Q'))
|
||||
return FAIL;
|
||||
if (!marshall (conn, method))
|
||||
return FAIL;
|
||||
if (!marshall (conn, 0))
|
||||
return FAIL;
|
||||
if (!conn->wait_for_result ())
|
||||
return FAIL;
|
||||
if (!unmarshall (conn, result))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
template<typename R, R (*func) (connection *)>
|
||||
status
|
||||
callback (connection *conn)
|
||||
{
|
||||
R result;
|
||||
|
||||
if (!unmarshall_check (conn, 0))
|
||||
return FAIL;
|
||||
result = func (conn);
|
||||
if (!conn->send ('R'))
|
||||
return FAIL;
|
||||
return marshall (conn, result);
|
||||
}
|
||||
|
||||
template<typename R, typename A>
|
||||
status
|
||||
call (connection *conn, const char *method, R *result, A arg)
|
||||
{
|
||||
if (!conn->send ('Q'))
|
||||
return FAIL;
|
||||
if (!marshall (conn, method))
|
||||
return FAIL;
|
||||
if (!marshall (conn, 1))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg))
|
||||
return FAIL;
|
||||
if (!conn->wait_for_result ())
|
||||
return FAIL;
|
||||
if (!unmarshall (conn, result))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
template<typename R, typename A, R (*func) (connection *, A)>
|
||||
status
|
||||
callback (connection *conn)
|
||||
{
|
||||
argument_wrapper<A> arg;
|
||||
R result;
|
||||
|
||||
if (!unmarshall_check (conn, 1))
|
||||
return FAIL;
|
||||
if (!arg.unmarshall (conn))
|
||||
return FAIL;
|
||||
result = func (conn, arg);
|
||||
if (!conn->send ('R'))
|
||||
return FAIL;
|
||||
return marshall (conn, result);
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2>
|
||||
status
|
||||
call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2)
|
||||
{
|
||||
if (!conn->send ('Q'))
|
||||
return FAIL;
|
||||
if (!marshall (conn, method))
|
||||
return FAIL;
|
||||
if (!marshall (conn, 2))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg1))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg2))
|
||||
return FAIL;
|
||||
if (!conn->wait_for_result ())
|
||||
return FAIL;
|
||||
if (!unmarshall (conn, result))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, R (*func) (connection *,
|
||||
A1, A2)>
|
||||
status
|
||||
callback (connection *conn)
|
||||
{
|
||||
argument_wrapper<A1> arg1;
|
||||
argument_wrapper<A2> arg2;
|
||||
R result;
|
||||
|
||||
if (!unmarshall_check (conn, 2))
|
||||
return FAIL;
|
||||
if (!arg1.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg2.unmarshall (conn))
|
||||
return FAIL;
|
||||
result = func (conn, arg1, arg2);
|
||||
if (!conn->send ('R'))
|
||||
return FAIL;
|
||||
return marshall (conn, result);
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3>
|
||||
status
|
||||
call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
|
||||
A3 arg3)
|
||||
{
|
||||
if (!conn->send ('Q'))
|
||||
return FAIL;
|
||||
if (!marshall (conn, method))
|
||||
return FAIL;
|
||||
if (!marshall (conn, 3))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg1))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg2))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg3))
|
||||
return FAIL;
|
||||
if (!conn->wait_for_result ())
|
||||
return FAIL;
|
||||
if (!unmarshall (conn, result))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3,
|
||||
R (*func) (connection *, A1, A2, A3)>
|
||||
status
|
||||
callback (connection *conn)
|
||||
{
|
||||
argument_wrapper<A1> arg1;
|
||||
argument_wrapper<A2> arg2;
|
||||
argument_wrapper<A3> arg3;
|
||||
R result;
|
||||
|
||||
if (!unmarshall_check (conn, 3))
|
||||
return FAIL;
|
||||
if (!arg1.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg2.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg3.unmarshall (conn))
|
||||
return FAIL;
|
||||
result = func (conn, arg1, arg2, arg3);
|
||||
if (!conn->send ('R'))
|
||||
return FAIL;
|
||||
return marshall (conn, result);
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
status
|
||||
call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
|
||||
A3 arg3, A4 arg4)
|
||||
{
|
||||
if (!conn->send ('Q'))
|
||||
return FAIL;
|
||||
if (!marshall (conn, method))
|
||||
return FAIL;
|
||||
if (!marshall (conn, 4))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg1))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg2))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg3))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg4))
|
||||
return FAIL;
|
||||
if (!conn->wait_for_result ())
|
||||
return FAIL;
|
||||
if (!unmarshall (conn, result))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
R (*func) (connection *, A1, A2, A3, A4)>
|
||||
status
|
||||
callback (connection *conn)
|
||||
{
|
||||
argument_wrapper<A1> arg1;
|
||||
argument_wrapper<A2> arg2;
|
||||
argument_wrapper<A3> arg3;
|
||||
argument_wrapper<A4> arg4;
|
||||
R result;
|
||||
|
||||
if (!unmarshall_check (conn, 4))
|
||||
return FAIL;
|
||||
if (!arg1.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg2.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg3.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg4.unmarshall (conn))
|
||||
return FAIL;
|
||||
result = func (conn, arg1, arg2, arg3, arg4);
|
||||
if (!conn->send ('R'))
|
||||
return FAIL;
|
||||
return marshall (conn, result);
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
status
|
||||
call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
|
||||
A3 arg3, A4 arg4, A5 arg5)
|
||||
{
|
||||
if (!conn->send ('Q'))
|
||||
return FAIL;
|
||||
if (!marshall (conn, method))
|
||||
return FAIL;
|
||||
if (!marshall (conn, 5))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg1))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg2))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg3))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg4))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg5))
|
||||
return FAIL;
|
||||
if (!conn->wait_for_result ())
|
||||
return FAIL;
|
||||
if (!unmarshall (conn, result))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, R (*func) (connection *, A1, A2, A3, A4, A5)>
|
||||
status
|
||||
callback (connection *conn)
|
||||
{
|
||||
argument_wrapper<A1> arg1;
|
||||
argument_wrapper<A2> arg2;
|
||||
argument_wrapper<A3> arg3;
|
||||
argument_wrapper<A4> arg4;
|
||||
argument_wrapper<A5> arg5;
|
||||
R result;
|
||||
|
||||
if (!unmarshall_check (conn, 5))
|
||||
return FAIL;
|
||||
if (!arg1.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg2.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg3.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg4.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg5.unmarshall (conn))
|
||||
return FAIL;
|
||||
result = func (conn, arg1, arg2, arg3, arg4, arg5);
|
||||
if (!conn->send ('R'))
|
||||
return FAIL;
|
||||
return marshall (conn, result);
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
status
|
||||
call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
|
||||
A3 arg3, A4 arg4, A5 arg5, A6 arg6, A7 arg7)
|
||||
{
|
||||
if (!conn->send ('Q'))
|
||||
return FAIL;
|
||||
if (!marshall (conn, method))
|
||||
return FAIL;
|
||||
if (!marshall (conn, 7))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg1))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg2))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg3))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg4))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg5))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg6))
|
||||
return FAIL;
|
||||
if (!marshall (conn, arg7))
|
||||
return FAIL;
|
||||
if (!conn->wait_for_result ())
|
||||
return FAIL;
|
||||
if (!unmarshall (conn, result))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
template<typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7,
|
||||
R (*func) (connection *, A1, A2, A3, A4, A5, A6, A7)>
|
||||
status
|
||||
callback (connection *conn)
|
||||
{
|
||||
argument_wrapper<A1> arg1;
|
||||
argument_wrapper<A2> arg2;
|
||||
argument_wrapper<A3> arg3;
|
||||
argument_wrapper<A4> arg4;
|
||||
argument_wrapper<A5> arg5;
|
||||
argument_wrapper<A6> arg6;
|
||||
argument_wrapper<A7> arg7;
|
||||
R result;
|
||||
|
||||
if (!unmarshall_check (conn, 7))
|
||||
return FAIL;
|
||||
if (!arg1.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg2.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg3.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg4.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg5.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg6.unmarshall (conn))
|
||||
return FAIL;
|
||||
if (!arg7.unmarshall (conn))
|
||||
return FAIL;
|
||||
result = func (conn, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
if (!conn->send ('R'))
|
||||
return FAIL;
|
||||
return marshall (conn, result);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CC1_PLUGIN_RPC_HH
|
33
libcc1/status.hh
Normal file
33
libcc1/status.hh
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* status type definition
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_STATUS_HH
|
||||
#define CC1_PLUGIN_STATUS_HH
|
||||
|
||||
namespace cc1_plugin
|
||||
{
|
||||
// The status returned by various connection functions.
|
||||
enum status
|
||||
{
|
||||
FAIL = 0,
|
||||
OK = 1
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CC1_PLUGIN_STATUS_HH
|
Loading…
Add table
Reference in a new issue