[aspectc-user] class as argument of a method

Olaf Spinczyk os at aspectc.org
Wed Nov 19 13:24:38 CET 2008


Hi Leandro,

I cannot reproduce the problem. In order to do so, I extended the ac++ 
test program "CallAdvice" in the following way:

---
#include <stdio.h>

int f1 (int a) { return a + 1; }
int f2 (int a, int) { return a + 2; }
int f3 (int a, int, int) { return a + 2; }
void var_arg_fct (const char *fmt, ...) { }

class C {
  int _val;
public:
  C () : _val (4711) {}
  operator int () { return _val; }
  int val () const { return _val; }
  C &operator = (const C &obj) {
    return *this;
  }
  C dup () {
    C duplicate;
    duplicate = *this;
    return duplicate;
  }
  C operator ! () { return *this; }
  int operator + (int) { return 0; }
  void cnst () const { printf ("the const function\n"); }
  void cnst () { printf ("the non-const version\n"); };
  static void stat (int = 0) { printf ("in a static member\n"); }
  int stuff (C *pClass) { printf ("in function with class-ptr arg\n"); }
};

bool operator + (C, C) { return false; }
int operator ~ (C) { return 0; }

class B1 {
public:
  void f (int) {}
  virtual void g () { printf ("in the base function - OK\n"); }
};

class B2 : public B1 {
public:
  void f () { B1::f (0); }
  void g () { printf ("in the derived function - ERROR\n"); }
};

struct ABase {
  C c1;
  mutable C c2;
};

class A : public ABase {
public:
  void f () const { c1.cnst (); c2.cnst (); }
  void g () { c1.cnst (); c2.cnst (); }
};

class OpTester {
public:
  void run () {
    C c1, c2;
    c1 + c2;
    ~c1;
  }
};

struct GlobalPrinter {
  GlobalPrinter () {
    printf ("CallAdvice: code generation for all kinds of functions\n");
    printf 
("=============================================================\n");
    printf ("global initialization:\n");
  }
  ~GlobalPrinter () {
    printf 
("=============================================================\n");
  }
} gp;

int global () { printf ("in a global function\n"); return 42; }

int g = global ();
namespace XX {}
namespace XX { int g = global (); }
class G {
  static int g2;
public:
  static void f (int i = global ()) {}
};

int G::g2 = global ();

int main () {
//   struct Local {
//     static void f () { global (); } // call in local class => shall 
not match!
//   };
//   printf 
("-------------------------------------------------------------\n");
//   printf ("call to global function from local class => shall not 
match:\n");
//   Local::f ();
  printf 
("-------------------------------------------------------------\n");
  printf ("various kinds of functions:\n");
  C inst;
  C inst2 (inst.dup ());
  printf ("result is %d\n", f1 (f2 (3, 4)) + inst.dup ().dup ().val ());
  f3 (f1 (f2 (5, 6)), f2 (7, 8), 1);
  !!!!inst;
  inst + 0;
  inst + f1 (2);
  inst + inst;
  ~inst;
  inst.cnst ();
  inst.stuff (&inst);
  const C cc;
  cc.cnst ();
  printf 
("-------------------------------------------------------------\n");
  printf ("static member called:\n");
  C::stat ();
  printf 
("-------------------------------------------------------------\n");
  printf ("call in default arg:\n");
  G::f ();
  printf 
("-------------------------------------------------------------\n");
  printf ("static member called with object:\n");
  inst.stat (3);
  printf 
("-------------------------------------------------------------\n");
  printf ("function with variable argument list:\n");
  var_arg_fct ("bla %s %d %d", "a string", 4711, true);
  var_arg_fct ("bla %f", 3.14);
  printf 
("-------------------------------------------------------------\n");
  printf ("calls with fully qualified name:\n");
  B2 b2;
  b2.f ();
  b2.B1::g ();
  printf 
("-------------------------------------------------------------\n");
  printf ("calls in const member function:\n");
  A a;
  a.f ();
  a.g ();
  printf 
("-------------------------------------------------------------\n");
  printf ("operator calls from within non-static methods:\n");
  OpTester ot;
  ot.run ();
  printf 
("-------------------------------------------------------------\n");
  printf ("calls to conversion functions:\n");
  C c;
  int i;
  i = c;
  // i = (int)c; <-- this should also be affected by advice
  return 0;
}

aspect CallTracer {
  advice call ("% ...::%(...)") && !call ("% printf(...)") : around () {
    printf ("before %s", tjp->signature ());
    tjp->proceed ();
  }
};

aspect CallTracer2 {
  advice call ("% ...::%(...)") && !call ("% printf(...)") : before () {
    printf ("\n");
  }
};

aspect CallWithClassPtrTest {
  advice call ("% %::%(C *)") : before () {
    printf ("before %s\n", JoinPoint::signature ());
  }
};
---

As you can see, the class C has been extended by your "stuff" method and 
the aspect at the end implements the pointcut expression from your mail. 
The output of the test program is as expected. The advice matches. I 
tried this with ac++ 1.0pre3 (latest official release) as well as the 
current version from the subversion repository.

Could you send me a complete example for your problem?

Best regards,

Olaf


Leandro Costa wrote:
> Hi Guys!
>
> I have the following method:
>
> const int Class::stuff (Class *pClass);
>
> and the following pointcut:
>
> pointcut methods () = call ("% %::%(Class *)");
>
> but these expressions don't match.
>
> It seems I can match only methods with natural types as arguments 
> (int, char, float, ...).
> When I use classes as arguments, AspectC++ doesn't match. Why?
>
> -- 
> _____________________________________________
>
>                       Leandro Souza Costa
>
> "A vitória se encastela em jardins encantadores,
>  mas para se chegar a ela não há caminho de flores"
> _____________________________________________
> ------------------------------------------------------------------------
>
> _______________________________________________
> aspectc-user mailing list
> aspectc-user at aspectc.org
> http://www.aspectc.org/mailman/listinfo/aspectc-user
>   




More information about the aspectc-user mailing list