1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
#ifndef __coverage_ah__
#define __coverage_ah__
#include <iostream>
using namespace std;
// Implementation of a generic coveragemonitor that does not only
// count how often a function is executed, but also which functions
// are not executed.
namespace coveragemonitor {
// data structure used to gather information about a joinpoint
struct Data {
unsigned _calls;
const char *(*_sig)();
};
// data structure used to link the joinpoint data elements
struct Chain {
static Chain *&first () { static Chain *chain = 0; return chain; }
Data *_data;
Chain *_next;
Chain (Data *data) : _data (data) {
Chain *head = first ();
first () = this;
_next = head;
}
};
// data structure used to combine data and chain elements
template <const char *(*SIG)()>
struct Collector {
static Data _data;
static Chain _chain;
};
template <const char *(*SIG)()> Data Collector<SIG>::_data = { 0, SIG };
template <const char *(*SIG)()> Chain Collector<SIG>::_chain (&_data);
}
aspect GenericCoverageAspect {
// Do not measure the coverage aspect's own methods
pointcut dontMeasure () = "% coveragemonitor::...::%(...)";
// Specify this joinpoint to define the functions you are
// interested in.
pointcut virtual coverage() = 0;
// Whenever one of the functions you are interested in is
// executed, save its name and count the number of invocations.
advice execution (coverage() && !dontMeasure()) : before() {
using namespace coveragemonitor;
typedef Collector<&JoinPoint::signature> Collector;
// As the compiler recognizes the access to the elements of
// Collector<JoinPoint::signature> it will create a template instance
// for all joinpoints - even for those that will never be
// visited.
// It is necessary to explicitly mention the _chain element
// here otherwise the compiler will not instantiate
// any Chain elements.
Collector::_chain._data->_calls++;
}
// Print the resulting information.
advice execution ("% main(...)") : after () {
std::cout << "*** Result of coverage monitoring ***" << std::endl;
for (coveragemonitor::Chain *curr = coveragemonitor::Chain::first();
curr; curr = curr->_next) {
std::cout << curr->_data->_sig() << " was executed "
<< curr->_data->_calls << " times." << std::endl;
}
}
};
#endif
|