* Get a dynval representing a function call's return value. Note
* that you must filter with aop_filter_call_pc_by_return_type() in
* order to capture the return value using aop_capture_return_value().
+ *
+ * Note that it is illegal to pass the resulting aop_dynval to
+ * aop_insert_advice() with #AOP_INSERT_BEFORE, as that would require
+ * the function's return value to be known before it exectues.
* \param jp A function call join point. Function call join points
* are obtained by joining on an aop_match_function_call() pointcut.
* \return A dynval with its type determined by
#include <tm.h>
#include <tree.h>
#include <gimple.h>
+#include <toplev.h>
#include "aop.h"
#include "aop-dynval.h"
#include "aop-pointcut.h"
+/* Throw a fatal error if a dynval is not allowed in a before-advice
+ call. */
+static void
+verify_legal_in_before_advice (struct aop_dynval *dv)
+{
+ switch (dv->kind)
+ {
+ case ADV_FUN_RETVAL:
+ fatal_error("(InterAspect) Attempt to capture return value in"
+ " before advice (see aop_capture_return_value()"
+ " documentation).");
+ default:
+ break; /* Permitted. */
+ }
+}
+
static tree
build_string_ptr (const char *string)
{
The new nodes get stored in arglist. */
static gimple
-build_gcc_call (const char *func_name, tree return_type, va_list argp)
+build_gcc_call (const char *func_name, tree return_type,
+ enum aop_insert_location location, va_list argp)
{
enum aop_argkind kind;
VEC(tree, heap) *arg_list;
break;
case ATA_DYNVAL:
dv = va_arg (argp, struct aop_dynval *);
+
+ /* Some dynvals aren't permitted in before advice. */
+ if (location == AOP_INSERT_BEFORE)
+ verify_legal_in_before_advice (dv);
+
new_arg = build_dynval (dv);
VEC_safe_push (tree, heap, arg_list, new_arg);
break;
}
va_start (argp, location);
- func_call = build_gcc_call (func_name, void_type_node, argp);
+ func_call = build_gcc_call (func_name, void_type_node, location, argp);
va_end (argp);
if(location == AOP_INSERT_BEFORE)