44
48
#include "Puma/CTranslationUnit.h"
45
49
#include "Puma/CClassDatabase.h"
46
50
#include "Puma/ACAspectInfo.h"
51
#include "Puma/ACAdviceInfo.h"
47
52
#include "Puma/ACIntroductionInfo.h"
48
53
#include "Puma/ACPointcutInfo.h"
49
54
#include "Puma/ACTree.h"
50
55
#include "Puma/CPrintVisitor.h"
56
#include "Puma/SysCall.h"
54
60
using std::stringstream;
62
#include <stdlib.h> // for getenv
66
#include <unistd.h> // for access()!
58
70
void Transformer::work (Unit *unit, Token *primary_start, Token *primary_end) {
60
72
// set the start and end token of the unit
61
_primary_start = primary_start;
62
_primary_end = primary_end;
73
_code_weaver.init (primary_start, primary_end);
64
75
// determine back-end compiler problems and setup code weaver
65
76
BackEndProblems back_end_problems;
66
back_end_problems._local_class = _conf.problem_local_class ();
67
back_end_problems._spec_scope = _conf.problem_spec_scope ();
68
back_end_problems._size_type = _conf.size_type ();
69
back_end_problems._warn_macro = _conf.warn_macro();
70
back_end_problems._warn_deprecated = _conf.warn_deprecated();
77
back_end_problems._local_class = _conf.problem_local_class ();
78
back_end_problems._spec_scope = _conf.problem_spec_scope ();
79
back_end_problems._use_always_inline = !_conf.problem_force_inline ();
80
back_end_problems._size_type = _conf.size_type ();
81
back_end_problems._warn_macro = _conf.warn_macro();
82
back_end_problems._warn_deprecated = _conf.warn_deprecated();
71
83
_code_weaver.problems (back_end_problems);
73
85
// perform the transformation
74
86
CTranslationUnit *tunit1 = 0;
75
PointCutContext *context1 = 0;
87
ModelBuilder jpm (_vm, _err, _conf);
78
bool ok = (phase1 (unit, tunit1, context1, plan) &&
79
phase2 (unit, tunit1, *context1, plan));
89
bool ok = (phase1 (unit, tunit1, jpm) &&
90
phase2 (unit, tunit1, jpm));
85
94
_vm << "Aborting" << endvm;
88
97
bool Transformer::phase1 (Unit *unit, CTranslationUnit *&tunit,
89
PointCutContext *&context, Plan &plan) {
91
100
_vm << "Inserting namespace AC" << endvm;
92
101
// in front of start!
148
162
bool Transformer::phase2 (Unit *unit, CTranslationUnit *tunit1,
149
PointCutContext &context1, Plan &plan1) {
165
IncludeGraph ig (_project);
169
_vm << "Preparing introductions ..." << endvm;
170
Plan plan (_err, jpm);
172
// get all aspects from the plan (in some order)
173
const Plan::AspectContainer &aspects = plan.aspect_infos ();
174
for (Plan::AspectContainer::const_iterator i = aspects.begin ();
175
i != aspects.end (); ++i) {
177
JPL_Aspect &jpl_aspect = i->loc ();
179
// add introductions to plan
180
list<JPL_Introduction*> intros;
181
jpl_aspect.collect_intros (intros);
183
for (list<JPL_Introduction*>::iterator i = intros.begin ();
184
i != intros.end (); ++i) {
185
IntroductionInfo *ii = plan.addIntroduction (jpl_aspect, **i);
186
ii->analyze_expr (_err, jpm);
189
// add order advices to plan
190
list<JPL_Order*> orders;
191
jpl_aspect.collect_orders (orders);
193
for (list<JPL_Order*>::iterator i = orders.begin ();
194
i != orders.end (); ++i) {
195
OrderInfo *oi = plan.addOrder (jpl_aspect, **i);
196
oi->analyze_exprs (_err, jpm);
197
if (!getenv ("ACNEWREPO")) {
151
203
_vm << "Parsing again ..." << endvm;
153
205
// parse the translation unit, but ignore function bodies
154
Introducer introducer (_code_weaver, _parser, plan1);
206
Introducer introducer (plan, _code_weaver, _parser, jpm, ig);
155
207
_parser.introducer (&introducer);
156
208
CTranslationUnit *tunit = _parser.parse (*unit, _project);
157
209
_parser.introducer (0);
159
211
// do semantic analysis of expressions
160
212
_sem_visitor.run (tunit->tree ());
213
list<CTree*> &ah_trees = introducer.ah_trees ();
214
for (list<CTree*>::iterator i = ah_trees.begin (); i != ah_trees.end (); ++i)
216
_sem_visitor.run (*i);
162
218
if (_err.severity () >= sev_error) {
163
219
// TODO: delete takes too much time and has no real use for ac++
192
262
_repo.cleanup ();
193
264
return (_err.severity () < sev_error);
197
void Transformer::aspect_priviledges (CTranslationUnit &tunit) {
198
CClassDatabase &db = tunit.db ();
267
void Transformer::determine_aspect_includes (const IncludeGraph &ig) {
268
// find all files that are included by aspect headers
269
if (_conf.iterate_aspects ()) {
270
// collect the names of aspect header files,
271
// generate a unit with include statements for these files,
272
PathIterator ah_iter (".*\\.ah$");
273
while (_project.iterate (ah_iter))
274
_aspect_includes += aspect_include_cluster (ah_iter.file (), ig);
277
// Get the names from the configuration object (-a options)
278
for (int i = 0; i < _conf.aspect_headers (); i++)
279
_aspect_includes += aspect_include_cluster (_conf.aspect_header (i), ig);
283
string Transformer::aspect_include_cluster (const char* ah_file,
284
const IncludeGraph &ig) {
286
// find the corresponding unit object for the aspect header file name
287
const Unit *unit = _project.unitManager ().getUnit (ah_file, true);
288
if (!unit || !unit->isFile ()) {
289
_err << sev_fatal << "Unit for \"" << ah_file << "\" not found or no file."
294
// determine the aspect header cluster for this aspect header unit
295
set<const Unit*> cluster_units;
296
determine_aspect_cluster (unit, ig, cluster_units);
299
stringstream cluster;
300
cluster << "#ifdef __ac_need_";
301
Naming::mangle_file (cluster, (FileUnit*)unit);
304
for (set<const Unit*>::iterator i = cluster_units.begin ();
305
i != cluster_units.end (); ++i) {
306
const Unit *aspect_unit = *i;
307
Filename incname = _project.getInclString (aspect_unit->name ());
308
cluster << "#ifndef __ac_have_";
309
Naming::mangle_file (cluster, (FileUnit*)aspect_unit);
311
cluster << "#define __ac_have_";
312
Naming::mangle_file (cluster, (FileUnit*)aspect_unit);
314
cluster << "#include \"" << incname << "\"" << endl;
315
cluster << "#endif" << endl;
318
cluster << "#endif" << endl;
319
return cluster.str ();
322
void Transformer::determine_aspect_cluster (const Unit* ah_unit,
323
const IncludeGraph &ig, set<const Unit*> &cluster) {
325
// if the ah file is already a cluster member, we return immediately
326
if (cluster.find (ah_unit) != cluster.end ())
329
// otherwise the unit will be inserted
330
cluster.insert (ah_unit);
332
// find all header files that are included by this aspect header
333
set<const Unit*> inc_units;
334
ig.included_files (ah_unit, inc_units);
336
// include all aspect headers that affect join points in these headers
337
AspectIncludes &ais = _code_weaver.aspect_includes ();
338
for (set<const Unit*>::iterator i = inc_units.begin ();
339
i != inc_units.end (); ++i) {
340
Unit *inc_unit = (Unit*)*i;
341
AspectIncludes::const_iterator aii = ais.find (inc_unit);
342
if (aii != ais.end ()) {
343
const set<AspectRef> &aspect_refs = aii->second;
344
for (set<AspectRef>::const_iterator ari = aspect_refs.begin ();
345
ari != aspect_refs.end (); ++ari) {
346
JPL_Aspect &jpl_aspect = ari->_aspect->loc ();
347
Unit *aspect_unit = TI_Aspect::of (jpl_aspect)->unit ();
348
// recursively analyze the cluster of this aspect header unit
349
determine_aspect_cluster (aspect_unit, ig, cluster);
355
void Transformer::prepare_dynamic_weaving (ModelBuilder &jpm) {
357
// mark all operations that access introduced attributes
358
const list<AccessInfo> &access_infos = jpm.access_infos ();
359
for (list<AccessInfo>::const_iterator i = access_infos.begin ();
360
i != access_infos.end (); ++i) {
361
if (i->_info->isStatic () || i->_info->isAnonymous ())
363
Unit *unit = (Unit*)i->_info->Tree ()->token ()->belonging_to ();
364
while (unit->isMacroExp ())
365
unit = ((MacroUnit*)unit)->CallingUnit ();
366
if (IntroductionUnit::cast (unit)) {
367
Token *tok_before = i->_tree->token ();
368
const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE);
369
_code_weaver.paste (before, string ("/*** +access ") +
370
string (i->_info->QualName ()) + string (" ***/\n"));
371
Token *tok_after = i->_tree->end_token ();
372
const WeavePos &after = _code_weaver.weave_pos (tok_after, WeavePos::WP_AFTER);
373
_code_weaver.paste (after, string ("/*** -access ") +
374
string (i->_info->QualName ()) + string (" ***/\n"));
375
if (i->_tree->NodeName () == CT_MembPtrExpr::NodeId () ||
376
i->_tree->NodeName () == CT_MembRefExpr::NodeId ()) {
377
CTree *op = i->_tree->Son (1);
378
Token *tok_before = op->token ();
379
const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE);
380
_code_weaver.paste (before, string ("/*** op ") +
381
string (i->_info->QualName ()) + string (" ***/\n"));
386
// mark all classes that contain dynamically introduced attributes
387
JoinPointModel::Selection classes;
388
jpm.select ((JoinPointLoc::join_point_type)(JoinPointLoc::Class|
389
JoinPointLoc::Aspect), classes);
390
for (JoinPointModel::Selection::iterator i = classes.begin ();
391
i != classes.end (); ++i) {
392
JPL_Class *cls = (JPL_Class*)*i;
393
if (!cls->intro_target ())
395
bool mark_class = false;
396
const TI_Class *ti = TI_Class::of (*cls);
397
CClassInfo *ci = ti->class_info ();
398
for (unsigned i = 0; i < ci->Attributes (); i++) {
399
CAttributeInfo *attr = ci->Attribute (i);
400
if (attr->isStatic () || attr->isAnonymous ())
402
Unit *unit = (Unit*)attr->Tree ()->token ()->belonging_to ();
403
IntroductionUnit *iunit = IntroductionUnit::cast (unit);
406
JPL_Name *jpl_aspect = iunit->intro ()->parent ();
407
Token *tok_before = attr->Tree ()->ObjDecl ()->token ();
408
const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE);
409
_code_weaver.paste (before, string ("/*** +intro ") +
410
string (jpl_aspect->signature ()) + string (" ***/\n"));
412
Token *tok_after = attr->Tree ()->ObjDecl ()->end_token ();
413
const WeavePos &after = _code_weaver.weave_pos (tok_after, WeavePos::WP_AFTER);
414
_code_weaver.paste (after, string ("/*** -intro ") +
415
string (jpl_aspect->signature ()) + string (" ***/\n"));
419
Token *tok_before = ((CT_ClassDef*)ci->Tree ())->ObjDecl ()->token ();
420
const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE);
421
_code_weaver.paste (before, string ("/*** +class ") +
422
string (cls->signature ()) + string (" ***/\n"));
424
Token *tok_after = ((CT_ClassDef*)ci->Tree ())->Members ()->end_token ();
425
const WeavePos &after = _code_weaver.weave_pos (tok_after, WeavePos::WP_BEFORE);
426
_code_weaver.paste (after, string ("/*** -class ") +
427
string (cls->signature ()) + string (" ***/\n"));
433
void Transformer::update_intros_in_repo (ModelBuilder &jpm1) {
434
ModelBuilder::Selection intros;
435
jpm1.select (JoinPointLoc::Introduction, intros);
436
for (JoinPointModel::Selection::iterator i = intros.begin ();
437
i != intros.end (); ++i) {
438
JPL_Introduction &intro = *(JPL_Introduction*)*i;
439
_repo.consider (intro);
441
ModelBuilder::Selection classes;
442
jpm1.select ((JoinPointLoc::join_point_type)(JoinPointLoc::Class|
443
JoinPointLoc::Aspect), classes);
444
for (JoinPointModel::Selection::iterator i = classes.begin ();
445
i != classes.end (); ++i) {
446
JPL_Class &cls = *(JPL_Class*)*i;
447
// get the weaving plan of this intro
448
JPP_Class *plan = (JPP_Class*)cls.plan ();
449
// collect the intros into this class
451
set<JPL_Introduction*> intros;
452
for (int b = 0; b < plan->baseIntros (); b++)
453
intros.insert (plan->baseIntro (b));
454
for (int o = 0; o < plan->otherIntros (); o++)
455
intros.insert (plan->otherIntro (o));
456
// now update the repository with the intro information
457
for (set<JPL_Introduction*>::iterator intro_iter = intros.begin ();
458
intro_iter != intros.end (); ++intro_iter) {
459
_repo.update (**intro_iter, cls);
465
void Transformer::aspect_priviledges (ModelBuilder &jpm) {
466
// TODO: access to template classes
468
// get all aspects from the join point model
469
JoinPointModel::Selection all_aspects;
470
jpm.select (JoinPointLoc::Aspect, all_aspects);
472
// remember that these aspects should become friend of all classes
199
473
list<CClassInfo*> friends;
200
for (int a = 0; a < db.AspectInfos (); a++) {
201
CClassInfo *aspect_cls = db.AspectInfo (a)->ClassInfo ();
202
if (!aspect_cls->Tree () ||
203
!aspect_cls->ClassDB()->Project ()->
204
isBelow (aspect_cls->SourceInfo ()->SrcUnit ()))
206
friends.push_back (aspect_cls);
474
for (JoinPointModel::Selection::iterator iter = all_aspects.begin ();
475
iter != all_aspects.end (); ++iter) {
476
JPL_Aspect &jpl = (JPL_Aspect&)**iter;
477
friends.push_back (((TI_Aspect*)jpl.transform_info ())->ClassInfo());
208
480
if (!friends.empty ()) {
209
for (unsigned c = 0; c < db.ClassInfos (); c++) {
210
CClassInfo *cls = db.ClassInfo (c);
212
!cls->ClassDB()->Project ()->isBelow (cls->SourceInfo ()->SrcUnit ()))
481
// get all classes and aspects from the join point model
482
JoinPointModel::Selection all_classes;
483
jpm.select ((JoinPointLoc::join_point_type)
484
(JoinPointLoc::Aspect|JoinPointLoc::Class), all_classes);
486
// perform the transformation
487
for (JoinPointModel::Selection::iterator iter = all_classes.begin ();
488
iter != all_classes.end (); ++iter) {
489
JPL_Class &jpl = (JPL_Class&)**iter;
490
CClassInfo *cls = ((TI_Class*)jpl.transform_info ())->class_info();
492
// TODO: also ignore classes that do no belong to the project
493
if (!cls->isDefined ())
215
496
// Don't add friend declarations in the AC namespace definitions
216
497
CScopeInfo *scope = cls->Scope ();
217
498
while (!scope->GlobalScope ()) {
250
531
void Transformer::introductions (CTranslationUnit &tunit,
251
PointCutContext &context, Plan &plan) {
252
CClassDatabase &db = tunit.db ();
254
for (int a = 0; a < db.AspectInfos (); a++) {
255
ACAspectInfo *acai = db.AspectInfo (a);
257
if (acai->is_abstract ())
259
context.aspect_info (acai);
261
_vm << "intros for " << acai->name () << endvm;
262
// create a pointcut evaluator
263
PointCutEvaluator eva (_err, context);
265
// now handle the introductions of this aspect
266
AspectInfo *ai = plan.addAspect (acai);
268
// add all the introductions (including inherited ones) to the aspect
269
collect_intros (plan, db, ai, acai);
273
for (list<IntroductionInfo *>::iterator iter = ai->intro_infos ().begin ();
274
iter != ai->intro_infos ().end (); ++iter, ++i) {
275
IntroductionInfo *ii = (*iter);
276
ACIntroductionInfo *acii = ii->ac_info ();
277
CT_AdviceDecl *ad = acii->def_node ();
282
// check whether the slice is defined
283
if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
284
ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
285
ACSliceInfo *acsi = db.SliceInfo (ii->object(0));
287
if (!acsi->definition ()) {
288
_err << sev_error << ad->token ()->location ()
289
<< "undefined slice '" << ii->object (0)->QualName ()
290
<< "' used in advice" << endMessage;
293
if (acsi->type () == ACSliceInfo::SL_UNION) {
294
_err << sev_error << ad->token ()->location ()
295
<< "union slices are not supported by ac++, yet" << endMessage;
300
if (_conf.warn_deprecated ())
301
_err << sev_warning << ad->token ()->location ()
302
<< "deprecated introduction syntax, "
303
<< "use slice instead." << endMessage;
306
// evaluate the pointcut for this introduction
307
PointCut target_scopes;
309
eva.work (target_scopes, binding, ad->Pointcut (),
310
(JoinPointLoc::join_point_type)
311
(JoinPointLoc::Class | JoinPointLoc::Aspect));
312
assert (!binding._used);
313
if (_err.severity () >= sev_error)
316
// do the introduction into all classes refered by the pointcut
318
for (PointCut::iterator iter = target_scopes.begin ();
319
iter != target_scopes.end (); ++iter) {
320
const JoinPoint& jp = *iter;
322
assert (jp.type () == JoinPointLoc::Class ||
323
jp.type () == JoinPointLoc::Aspect);
325
CClassInfo *cls = ((JPL_Class*)jp.location ())->class_info ();
327
if (!cls->ClassDB()->Project ()->
328
isBelow (cls->SourceInfo ()->SrcUnit ()))
331
_vm << "into " << cls->Name () << endvm;
333
// consider the introduction in the big plan
334
plan.consider (jp.location (), ii);
336
// don't forget to include the aspect header, where some code is
338
_code_weaver.add_intro_include ((JPL_Class*)jp.location (), ii);
342
// update the project repository
343
_repo.update (*ii, target_scopes);
348
if (_err.severity () >= sev_error)
351
_vm << "Aspect ordering ..." << endvm;
352
orderings(tunit, plan, context, false);
354
// now do the final checks on the accumulated plan
355
_vm << "Final checks before weaving introductions" << endvm;
358
// Don't weave if there were errors in the planning phase
359
if (_err.severity () >= sev_error)
362
_vm << "Class Join Points" << endvm;
364
for (int i = 0; i < plan.class_jp_plans (); i++) {
365
JPP_Class &jp_plan = plan.class_jp_plan (i);
366
JPL_Class &jp_loc = plan.class_jp_loc (i);
368
_vm << jp_loc.signature () << endvm;
370
// introduce base classes
371
_code_weaver.baseclass (jp_loc, jp_plan);
373
// handle other intros
374
for (int i = 0; i < jp_plan.otherIntros (); i++) {
375
IntroductionInfo *ii = jp_plan.otherIntro (i);
377
if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
378
ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
379
ACSliceInfo *acsi = db.SliceInfo (ii->object(0))->definition ();
380
for (int m = 0; m < acsi->members (); m++)
381
_code_weaver.introduce (&jp_loc, acsi->member (m),
382
CProtection::PROT_NONE, _primary_end);
385
_code_weaver.introduce (&jp_loc, ii->tree ()->Decl (), ii->prot (),
534
// remove the introductions from the code
535
ModelBuilder::Selection intros;
536
jpm.select (JoinPointLoc::Introduction, intros);
537
for (JoinPointModel::Selection::iterator i = intros.begin ();
538
i != intros.end (); ++i) {
539
JPL_Introduction &intro = *(JPL_Introduction*)*i;
540
_code_weaver.kill (TI_Introduction::of (intro)->tree ());
392
543
// now delete all slice definitions
544
CClassDatabase &db = tunit.db ();
393
545
for (int s = 0; s < db.SliceInfos (); s++) {
394
546
ACSliceInfo *acsi = db.SliceInfo (s);
395
547
// first all members
401
553
if (!acsi->in_advice ())
402
554
_code_weaver.kill (acsi->def_node ());
405
// finally remove the introductions from the code
406
for (int i = 0; i < plan.intros (); i++)
407
_code_weaver.kill (plan.intro (i)->tree ());
412
558
void Transformer::orderings (CTranslationUnit &tunit, Plan& plan,
413
PointCutContext& context, bool purge) {
415
CClassDatabase &db = tunit.db ();
417
for (int a = 0; a < db.AspectInfos (); a++) {
419
ACAspectInfo *acai = db.AspectInfo (a);
420
if (acai->is_abstract ())
422
context.aspect_info (acai);
424
// create a pointcut evaluator
425
PointCutEvaluator eva (_err, context);
427
// collect all order statements of this aspect and its parents
428
Array<CT_AdviceDecl*> order_nodes;
429
collect_ordering (db, acai, order_nodes);
431
AspectInfo *ai = plan.getAspect (acai);
434
for (int i = 0; i < (int)order_nodes.length (); i++) {
435
CT_AdviceDecl *ad = order_nodes[i];
436
CT_OrderList *lst = ((CT_OrderDecl*)ad->Decl ())->OrderList ();
438
_vm << acai->name() << ":";
440
OrderInfo *order_info = plan.addOrder(ai, ad);
442
// resolve all pointcut expressions first
443
Array<ACAspectInfo*> *ais = new Array<ACAspectInfo*>[lst->Entries ()];
445
for (int n = 0; n < lst->Entries (); n++) {
450
// evaluate the current pointcut
452
Binding binding; // must be unused here
453
eva.work (pct, binding, lst->Entry (n), JoinPointLoc::Aspect);
454
assert (!binding._used);
456
// check all join points in this pointcut
457
for (PointCut::iterator iter = pct.begin ();
458
iter != pct.end (); ++iter) {
459
const JoinPoint &jp = *iter;
461
// get the AspectInfo object of this aspect
462
ACAspectInfo* ai = ((JPL_Aspect*)jp.location ())->aspect_info ();
464
// remember this aspect
467
_vm << " " << ai->name ();
472
// now collect pairs of order requirements
473
Array<ACAspectInfo*> oai_l; // aspect with lower precedence
474
Array<ACAspectInfo*> oai_h; // aspect with higher precedence
476
for (int n = 1; n < lst->Entries (); n++)
477
for (int h = 0; h < ais[n - 1].length (); h++)
478
for (int l = 0; l < ais[n].length (); l++) {
479
oai_h.append (ais[n - 1].lookup (h));
480
oai_l.append (ais[n].lookup (l));
485
// evaluate the pointcut for this ordering
488
eva.work (target, binding, ad->Pointcut (), JoinPointLoc::Any);
489
assert (!binding._used);
491
// remember the ordering in all JPP refered by the pointcut
492
for (PointCut::iterator iter = target.begin ();
493
iter != target.end (); ++iter) {
494
const JoinPoint &jp = *iter;
495
// remember the ordering in the big plan
496
for (int i = 0; i < oai_l.length (); i++)
497
plan.consider (jp.location (), *oai_h[i], *oai_l[i]);
500
if (purge) _code_weaver.kill (ad);
502
// update the project repository
503
_repo.update (*order_info);
559
ModelBuilder &jpm, bool purge) {
561
// let the plan object calculate the right order
564
// remove the introductions from the code
566
// Iterate through order advice declarations
567
ModelBuilder::Selection orders;
568
jpm.select (JoinPointLoc::Order, orders);
569
for (JoinPointModel::Selection::iterator i = orders.begin ();
570
i != orders.end (); ++i) {
571
JPL_Order &order = *(JPL_Order*)*i;
572
TI_Order &ti = *TI_Order::of (order);
573
_code_weaver.kill (ti.tree ());
556
void Transformer::collect_intros (Plan &plan, CClassDatabase &db,
557
AspectInfo *ai, ACAspectInfo *acai) {
558
for (int i = 0; i < acai->IntroNodes (); i++)
559
plan.addIntroduction (ai, acai->IntroNode (i));
561
for (unsigned b = 0; b < acai->ClassInfo ()->BaseClasses (); b++) {
562
CClassInfo *base = acai->ClassInfo ()->BaseClass (b)->Class ();
563
ACAspectInfo *base_aspect = db.AspectInfo (base);
565
collect_intros (plan, db, ai, base_aspect);
569
void Transformer::collect_advice (CClassDatabase &db, ACAspectInfo *ai,
570
Array<CT_AdviceDecl*> &advice_nodes) {
571
for (int i = 0; i < ai->AdviceNodes (); i++)
572
advice_nodes.append (ai->AdviceNode (i));
574
for (unsigned b = 0; b < ai->ClassInfo ()->BaseClasses (); b++) {
575
CClassInfo *base = ai->ClassInfo ()->BaseClass (b)->Class ();
576
ACAspectInfo *base_aspect = db.AspectInfo (base);
578
collect_advice (db, base_aspect, advice_nodes);
582
void Transformer::collect_ordering (CClassDatabase &db, ACAspectInfo *ai,
583
Array<CT_AdviceDecl*> &order_nodes) {
584
for (int i = 0; i < ai->OrderNodes (); i++)
585
order_nodes.append (ai->OrderNode (i));
587
for (unsigned b = 0; b < ai->ClassInfo ()->BaseClasses (); b++) {
588
CClassInfo *base = ai->ClassInfo ()->BaseClass (b)->Class ();
589
ACAspectInfo *base_aspect = db.AspectInfo (base);
591
collect_ordering (db, base_aspect, order_nodes);
595
625
void Transformer::join_points (CTranslationUnit &tunit,
596
PointCutContext &context) {
597
CClassDatabase &db = tunit.db ();
626
ModelBuilder &jpm, Plan &plan) {
602
629
_vm << "Advicecode manipulation" << endvm;
603
630
// Iterate through advice
604
for (int a = 0; a < db.AspectInfos (); a++) {
605
ACAspectInfo *acai = db.AspectInfo (a);
606
for (int i = 0; i < acai->AdviceNodes (); i++) {
607
CT_AdviceDecl *ad = acai->AdviceNode (i);
608
// register advice code in the big plan
609
AdviceCode *code = plan.addAdviceCode (ad);
610
// setup ThisJoinPoint object of this advice code
611
code->this_join_point ().setup (code->function ());
612
_code_weaver.provide_tjp (code->function (), code->this_join_point ());
631
ModelBuilder::Selection advice_codes;
632
jpm.select (JoinPointLoc::AdviceCode, advice_codes);
633
for (JoinPointModel::Selection::iterator i = advice_codes.begin ();
634
i != advice_codes.end (); ++i) {
635
JPL_AdviceCode &code = *(JPL_AdviceCode*)*i;
636
TI_AdviceCode &ti = *TI_AdviceCode::of (code);
637
// setup ThisJoinPoint object of this advice code
638
ti.this_join_point ().setup (ti.function ());
639
_code_weaver.provide_tjp (ti.function (), ti.this_join_point ());
616
642
_vm << "Collecting Advice" << endvm;
620
646
// Create a pointcut evaluator
647
PointCutContext context (jpm);
621
648
PointCutEvaluator eva (_err, context);
623
for (int a = 0; a < db.AspectInfos (); a++) {
624
ACAspectInfo *acai = db.AspectInfo (a);
626
// Don't weave advice of abstract aspects
627
if (acai->is_abstract ())
630
context.aspect_info (acai);
650
Plan::AspectContainer &aspects = plan.aspect_infos ();
651
for (Plan::AspectContainer::iterator i = aspects.begin ();
652
i != aspects.end (); ++i) {
653
AspectInfo &aspect_info = (AspectInfo&)*i;
654
JPL_Aspect &jpl_aspect = aspect_info.loc ();
656
context.concrete_aspect (jpl_aspect);
631
657
int index = 0; // CFlow index (each CFlow has a unique index per aspect)
633
AspectInfo *ai = plan.addAspect (acai);
635
659
// setup thisJoinPoint for aspectOf function, if there is one
636
if (ai->aspectof()) {
660
CFunctionInfo *aspect_of_func = TI_Aspect::of (jpl_aspect)->aspectof();
661
if (aspect_of_func) {
637
662
_vm << "Setting up thisJoinPoint for aspectof" << endvm;
638
ai->aspectof_this_join_point ().setup (ai->aspectof ());
663
aspect_info.aspectof_this_join_point ().setup (aspect_of_func);
639
664
_vm << "Supplying aspectof() with JoinPoint and tjp if needed" << endvm;
640
_code_weaver.provide_tjp (ai->aspectof (), ai->aspectof_this_join_point ());
665
_code_weaver.provide_tjp (aspect_of_func,
666
aspect_info.aspectof_this_join_point ());
643
// traverse inheritance tree and collect advice declarations
644
Array<CT_AdviceDecl*> advice_nodes;
645
collect_advice (db, acai, advice_nodes);
669
// handle the advice for the current aspect
670
list<AdviceInfo*> advices = aspect_info.advice_infos ();
648
for (int i = 0; i < (int)advice_nodes.length (); i++) {
649
CT_AdviceDecl *ad = advice_nodes[i];
650
AdviceInfo *advice_info = plan.addAdvice (ai, ad);
652
CFunctionInfo *adfunc = advice_info->code ().function ();
654
_vm << acai->name () << ": " << adfunc->Name () << endvm;
673
for (list<AdviceInfo*>::const_iterator i = advices.begin ();
674
i != advices.end (); ++i) {
675
AdviceInfo *advice_info = *i;
676
JPL_AdviceCode *code = &advice_info->code ();
677
CFunctionInfo *adfunc = TI_AdviceCode::of (*code)->function ();
679
_vm << jpl_aspect.signature () << ": " << adfunc->Name () << endvm;
657
682
// evaluate the pointcut, even inherited
658
683
_vm << "Evaluate Pointcut" << endvm;
659
684
PointCut &pc = advice_info->pointcut ();
660
Binding &binding = advice_info->code ().binding ();
685
Binding &binding = advice_info->binding ();
661
686
context.func (adfunc);
662
eva.work (pc, binding, ad->Pointcut (), JoinPointLoc::Code);
687
eva.work (pc, binding, code->expr (), JoinPointLoc::Code);
663
688
if (_err.severity () >= sev_error) {