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. */
}
+/**
+ * Duplicate the current function's body so that there are two copies
+ * available for instrumentation. A function entry join point is
+ * required because the duplication process inserts an advice call at
+ * function entry which serves as a <i>distributor</i>.
+ *
+ * The distributor advice decides which copy to execute. A
+ * distributor advice function returns an int (unlike regular advice,
+ * which has void return type): a zero value will execute the original
+ * copy and a non-zero value will execute the new copy.
+ *
+ * Any arguments following func_name are arguments to be passed to the
+ * distributor advice function. (See the documentation for
+ * aop_insert_advice() for an explanation of passing arguments to
+ * advice.) #AOP_TERM_ARG must be the last argument to
+ * aop_duplicate(), even when not specifying any arguments for the
+ * advice function.
+ *
+ * \param jp The function entry join point for the current join point.
+ * The distributor advice will be inserted here. Function entry join
+ * points are obtained by joining on an aop_match_function_entry()
+ * pointcut.
+ * \param func_name The name of the distributor advice function.
+ * \param ... A list of arguments to pass to the advice function,
+ * terminated by #AOP_TERM_ARG.
+ */
void
aop_duplicate (struct aop_joinpoint *jp, const char *func_name, ...)
{
else if (jp->is_prepared)
fatal_error ("(InterAspect) Illegal to duplicate using a join point that"
" has already been used to insert advice.");
+ else if (is_current_func_duplicated())
+ fatal_error ("(InterAspect) Cannot duplicate a function more than once.");
va_start (argp, func_name);
func_call = build_gcc_call (func_name, integer_type_node, AOP_INSERT_BEFORE,