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:
Phil Muldoon 2014-10-27 17:21:42 +00:00
parent 50a504654d
commit ddc8de034a
44 changed files with 23919 additions and 300 deletions

View File

@ -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

View File

@ -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; };

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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
View File

@ -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 \

View File

@ -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 \

View File

@ -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.

View File

@ -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
View File

@ -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])

View File

@ -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.

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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. */

View File

@ -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);

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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

File diff suppressed because it is too large Load Diff

73
libcc1/configure.ac Normal file
View 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
View 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
View 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
View 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 &regexp, const std::string &dir, std::string *result)
{
scanner scan (dir);
const char *filename;
while ((filename = scan.next ()) != NULL)
{
if (regexec (&regexp, 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 &regexp, 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
View 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 &regexp, std::string *result);
#endif // CC1_PLUGIN_FINDCOMP_HH

530
libcc1/libcc1.cc Normal file
View 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
View File

@ -0,0 +1 @@
gcc_c_fe_context

2
libcc1/libcc1plugin.sym Normal file
View File

@ -0,0 +1,2 @@
plugin_init
plugin_is_GPL_compatible

166
libcc1/marshall.cc Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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