--- /dev/null
+/* 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/>.
+*/
+
+
+/* Whether we want them or not (we don't), Autoconf _insists_ on
+ defining these. Since GCC's config.h (which we must include) also
+ defines them, we have to undef them here. */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <stdarg.h>
+
+#include <config.h>
+#include <system.h>
+#include <coretypes.h>
+#include <tm.h>
+#include <tree.h>
+#include <gimple.h>
+
+#include "aop.h"
+#include "aop-pointcut.h"
+
+static tree
+build_string_ptr (const char *string)
+{
+ size_t string_len;
+ tree string_tree;
+
+ tree string_ref;
+ tree ret;
+
+ string_len = strlen (string) + 1;
+
+ string_tree = build_string (string_len, string);
+ TREE_TYPE (string_tree) =
+ build_array_type (char_type_node, build_index_type (size_int (string_len)));
+
+ string_ref = build4(ARRAY_REF,
+ char_type_node,
+ string_tree,
+ build_int_cst (TYPE_DOMAIN (TREE_TYPE (string_tree)), 0),
+ NULL,
+ NULL);
+
+ ret = build1(ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (string_ref)),
+ string_ref);
+
+ return ret;
+}
+
+/* Weaving functions all take varags parameters that represent the
+ arguments to pass to the new advice function. This function
+ iterates through those arguments and creates GIMPLE tree nodes for
+ each of them.
+
+ The new nodes get stored in arglist. */
+static gimple
+build_gcc_call (const char *func_name, tree return_type, va_list argp)
+{
+ enum aop_argkind kind;
+ VEC(tree, heap) *arg_list;
+ tree argtype_list;
+
+ tree func_type;
+ tree func_decl;
+ gimple func_call;
+
+ arg_list = VEC_alloc (tree, heap, 2);
+ argtype_list = void_list_node;
+
+ while ((kind = va_arg (argp, enum aop_argkind)) != AOP_TERM_ARG)
+ {
+ tree new_arg;
+ const char *str_cst;
+
+ switch (kind)
+ {
+ case ATA_STR_CST:
+ str_cst = va_arg (argp, const char *);
+ new_arg = build_string_ptr (str_cst);
+ VEC_safe_push (tree, heap, arg_list, new_arg);
+ break;
+ default:
+ aop_assert (0);
+ }
+
+ argtype_list = tree_cons (NULL_TREE, TREE_TYPE (new_arg), argtype_list);
+ }
+
+ /* Using tree_cons builds the list backwards! Un-backwards it. */
+ argtype_list = nreverse (argtype_list);
+
+ func_type = build_function_type (return_type, argtype_list);
+ func_decl = build_fn_decl (func_name, func_type);
+ func_call = gimple_build_call_vec (func_decl, arg_list);
+
+ VEC_free (tree, heap, arg_list);
+
+ return func_call;
+}
+
+void
+aop_do_weave (struct aop_joinpoint *jp, const char *func_name, ...)
+{
+ va_list argp;
+ gimple func_call;
+
+ va_start (argp, func_name);
+ func_call = build_gcc_call (func_name, void_type_node, argp);
+ va_end (argp);
+
+ gsi_insert_before (jp->gsi, func_call, GSI_SAME_STMT);
+}
extern const char *aop_capture_lhs_name (struct aop_joinpoint *jp);
+extern void aop_do_weave (struct aop_joinpoint *jp, const char *name, ...);
+
extern void aop_register_pass (const char *pass_name, pass_callback callback);
extern void aop_join_on (struct aop_pointcut *pc, join_callback callback);
extern void aop_main ();
extern void aop_abort (const char *filename, int lineno, const char *function)
__attribute__((noreturn));
+/* Fancy macro magic used for the varargs component of do_weave
+ functions. */
+
+enum aop_argkind {
+ ATA_STR_CST,
+ ATA_DYNVAL,
+ AOP_TERM_ARG,
+};
+
+#define AOP_STR_CST(VAL) ATA_STR_CST, VAL
+#define AOP_DYNVAL(VAL) ATA_DYNVAL, VAL
+
#endif