~ubuntu-branches/ubuntu/maverick/aspectc++/maverick

« back to all changes in this revision

Viewing changes to AspectC++/CodeWeaver.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-04-10 17:40:52 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080410174052-xdnsm7oi8hauyyf1
Tags: 1.0pre4~svn.20080409+dfsg-3
Fix another missing include, this time in Ag++/StdSystem.cc

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
// MA  02111-1307  USA                                            
18
18
 
19
19
#include "CodeWeaver.h"
20
 
// #include "IntroductionInfo.h"
21
 
// #include "PointCutInfo.h"
22
20
#include "AspectInfo.h"
23
21
#include "AdviceInfo.h"
24
22
#include "JoinPointLoc.h"
25
23
#include "JoinPointPlan.h"
26
24
#include "JPAdvice.h"
27
 
// #include "ThisJoinPoint.h"
28
 
// #include "AspectDb.h"
29
25
#include "ACUnit.h"
30
 
// #include "JoinPoint.h"
31
26
#include "Naming.h"
32
27
#include "IntroductionUnit.h"
33
28
#include "NamespaceAC.h"
 
29
#include "ResultBuffer.h"
34
30
 
35
31
#include "Puma/ErrorSink.h"
36
32
#include "Puma/ACTree.h"
61
57
       << (result ? "true" : "false") << "; }"  << endl;
62
58
  if (in_class)
63
59
    code << "private:" << endl;
64
 
  code << ends;
65
60
  
66
61
  // paste the function after "{" of the class/struct/union definition
67
62
  Token *inspos = ((CT_ClassDef*)rec->Tree ())->Members ()->token ();
69
64
  paste (pos, code.str ());
70
65
}
71
66
 
72
 
void CodeWeaver::add_intro_include (JPL_Class *jpl, IntroductionInfo *ii) {
73
 
 
74
 
  assert (jpl && (jpl->type() == JoinPointLoc::Class ||
75
 
    jpl->type () == JoinPointLoc::Aspect));
76
 
 
77
 
  if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
78
 
      ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
79
 
    CObjectInfo *obj = ii->object (0);
80
 
    assert (obj && obj->Tree ());
81
 
    assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
82
 
    CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
83
 
    // first the includes for the class decl intros
84
 
    Unit *su = (Unit*)csd->token ()->belonging_to ();
85
 
    Unit *iu = jpl->unit ();
86
 
    if (IntroductionUnit::cast (iu) == 0) // TODO: no intros into intros
87
 
      _slice_includes.insert (iu, su);
88
 
    // now the intros for the non-inline slice members
89
 
    CClassDatabase *db = obj->ClassDB ();
90
 
    ACSliceInfo *acsi = db->SliceInfo (obj);
91
 
    assert (acsi);
92
 
    for (int m = 0; m < acsi->members (); m++) {
93
 
      CT_Intro *intro = acsi->member (m);
94
 
      CSourceInfo *si = jpl->class_info ()->SourceInfo ();
95
 
      bool in_header = (strcmp (si->FileName (),
96
 
                                si->FileInfo ()->Primary ()->name ()) != 0);
97
 
      if (in_header) {
98
 
        // check if there is a link-once code element in the class
99
 
        CObjectInfo *loo = jpl->link_once_object ();
100
 
        // return silently if this is only a declaration
101
 
        if (!loo || loo->Scope () == jpl->class_info ())
102
 
          continue;
103
 
      }
104
 
      iu = si->FileInfo ()->Primary ();
105
 
      su = (Unit*)intro->token ()->belonging_to ();
106
 
      if (IntroductionUnit::cast (iu) == 0) // TODO: no intros into intros
107
 
        _slice_includes.insert (iu, su);
108
 
    }
109
 
    return;
110
 
  }
111
 
  
112
 
  // old-style intros ...
113
 
  Unit *su = (Unit*)&ii->unit ();
114
 
  Unit *iu = jpl->unit ();
115
 
  
116
 
  // handle the case of non-inline introductions
117
 
  if (ii->prot () == CProtection::PROT_NONE) {
118
 
    CSourceInfo *si = jpl->class_info ()->SourceInfo ();
119
 
    bool in_header = (strcmp (si->FileName (),
120
 
                              si->FileInfo ()->Primary ()->name ()) != 0);
121
 
                              
122
 
    if (in_header) {
123
 
      // check if there is a link-once code element in the class
124
 
      CObjectInfo *loo = jpl->link_once_object ();
125
 
 
126
 
      // TODO: for now loo has to != 0, later we can exploit the proj. repo
127
 
      if (!loo) {
128
 
        // error handling in introduce ()
129
 
        return;
130
 
      }
131
 
      
132
 
      // return silently if this is only a declaration
133
 
      if (loo->Scope () == jpl->class_info ())
134
 
        return;
135
 
    }
136
 
    
137
 
    iu = si->FileInfo ()->Primary ();
138
 
  }
139
 
 
140
 
  // Introductions into introductions are not supported, yet
141
 
  if (IntroductionUnit::cast (iu) != 0)
142
 
    return;
143
 
  
144
 
  _slice_includes.insert (iu, su);
145
 
}
146
 
 
147
 
void CodeWeaver::add_aspect_include (JoinPointLoc *jpl, AspectInfo *ai,
148
 
                                     ACAspectInfo *acai, AspectRef::Kind kind) {
 
67
void CodeWeaver::add_aspect_include (JoinPointLoc *jpl, AspectInfo &aspect_info,
 
68
  AspectRef::Kind kind) {
149
69
  Unit *iu;
150
70
 
151
71
  if (jpl && jpl->type () == JoinPointLoc::MethodCall &&
152
72
      ((JPL_Code*)jpl)->is_pseudo ())
153
73
    return;
154
74
 
 
75
  JPL_Aspect &jpl_aspect = aspect_info.loc ();
155
76
  // TODO: find out what this 'if' is good for ;-)
156
77
  if (!jpl)
157
 
    iu = acai->ClassInfo ()->SourceInfo ()->FileInfo ()->Primary ();
 
78
    // TODO: isn't there a _primary?
 
79
    iu = TI_Aspect::of (jpl_aspect)->ClassInfo ()->SourceInfo ()->FileInfo ()->Primary ();
158
80
  else {
159
 
    iu = jpl->unit ();
 
81
    iu = TransformInfo::unit (*jpl);
160
82
  }
161
83
 
162
84
  // if the 'insert unit' is an 'introduction unit', find the intro target unit
164
86
  while ((intro_unit = IntroductionUnit::cast (iu)) != 0)
165
87
    iu = intro_unit->target_unit ();
166
88
  
167
 
  _aspect_includes.insert (iu, ai, acai, kind);
 
89
  _aspect_includes.insert (iu, &aspect_info, kind);
168
90
}
169
91
 
170
 
void CodeWeaver::aspect_includes (CProject &project, Token *first) {
171
 
  Unit *primary = (Unit*)first->belonging_to ();
 
92
void CodeWeaver::aspect_includes (CProject &project) {
172
93
 
173
94
  // weave the aspect includes in all registered unit
174
95
  for (AspectIncludes::const_iterator iter = _aspect_includes.begin ();
176
97
 
177
98
    // determine the insertion position for the current unit
178
99
    Unit *unit = _aspect_includes.unit (iter);
179
 
    bool is_primary = (unit == primary);
180
 
    Token *inspos = is_primary ? first : (Token*)unit->first ();
181
100
 
182
101
    // generate the includes for the current unit
183
 
    string includes = _aspect_includes.generate (project, iter);
 
102
    string includes = _aspect_includes.generate (iter, problems ());
184
103
    
185
 
    // paste the includes (and optional guard head) at the beginning
186
 
    paste (weave_pos (inspos, WeavePos::WP_BEFORE), includes);
 
104
    // paste the includes (and optional guard head) at the beginning of the unit
 
105
    paste_first (unit, includes);
187
106
  }
188
107
}
189
108
 
212
131
    // generate the include guard prologue for the header file
213
132
    if (guard) {
214
133
      ostringstream guard_head;
215
 
      guard_head << "#ifndef ";
 
134
      guard_head << endl << "#ifndef ";
216
135
      Naming::guard (guard_head, (FileUnit*)unit);
217
136
      guard_head << endl << "#define ";
218
137
      Naming::guard (guard_head, (FileUnit*)unit);
219
 
      guard_head << endl << ends;
 
138
      guard_head << endl;
220
139
      includes += guard_head.str ();
221
140
    }
222
141
    
226
145
    // generate the #endif for the guard if needed
227
146
    if (guard) {
228
147
      ostringstream guard_tail;
229
 
      guard_tail << "#endif // ";
 
148
      guard_tail << endl << "#endif // ";
230
149
      Naming::guard (guard_tail, (FileUnit*)unit);
231
 
      guard_tail << endl << ends;
 
150
      guard_tail << endl;
232
151
      paste (weave_pos ((Token*)unit->last (), WeavePos::WP_AFTER),
233
152
        guard_tail.str ());
234
153
    }
253
172
}
254
173
 
255
174
 
256
 
void CodeWeaver::invocation_functions (ACAspectInfo *ai, Token *first,
 
175
void CodeWeaver::invocation_functions (ACAspectInfo *ai,
257
176
                                       const string &decls,
258
177
                                       const string &defs) {
259
178
        
290
209
  // create and insert the function name
291
210
  ostringstream func_decl;
292
211
  func_decl << " {}" << endl << "public: "
293
 
            << "void __" << (advice_func->Name () + 1) << " " << ends;
 
212
            << "void __" << (advice_func->Name () + 1) << " ";
294
213
  paste (after_args, func_decl.str ());
295
214
                    
296
215
  // set the protection
323
242
  // add all forward and friend declarations
324
243
  for (list<CClassInfo*>::iterator iter = friends.begin ();
325
244
       iter != friends.end (); ++iter) {
326
 
         
 
245
 
327
246
    // if this is the aspect itself, skip this one
328
247
    if (def == (*iter)->DefObject ())
329
248
      continue;
361
280
  }
362
281
 
363
282
  for (int i = namespaces.length () - 1; i >= 0; i--) {
364
 
    out << "namespace " << namespaces[i]->Name () << " {" << endl;
 
283
    if (namespaces[i]->isAnonymous ())
 
284
      out << "namespace {" << endl;
 
285
    else
 
286
      out << "namespace " << namespaces[i]->Name () << " {" << endl;
365
287
  }
366
288
}
367
289
 
373
295
  ostringstream ns_close;
374
296
  while (!obj->Scope ()->GlobalScope () && obj->Scope ()->NamespaceInfo ()) {
375
297
    obj = obj->Scope ();
376
 
    out << "} // closed " << obj->QualName () << endl;
377
 
  }
378
 
}
379
 
 
380
 
 
381
 
void CodeWeaver::introduce (JPL_Class *loc, CTree *decl,
382
 
                            CProtection::Type prot, Token *primary_end) {
383
 
  // name of the target class
384
 
  ostringstream target;
385
 
  target << " " << loc->class_info ()->QualName () << " " << ends;
386
 
 
387
 
  if (prot != CProtection::PROT_NONE) {
388
 
//    // An introduction inside the class
389
 
//    CClassInfo *cls = loc->class_info ();
390
 
//
391
 
//    // paste declaration before "}" of the class definition
392
 
//    Token *inspos = ((CT_ClassDef*)cls->DefObject ()->
393
 
//                    Tree ())->Members ()->end_token ();
394
 
//    const WeavePos &pos = weave_pos (inspos, WeavePos::WP_BEFORE);
395
 
//g++" -v -Dslice=_slice -I"../include" -O2 -Wall -D_REENTRANT -D_GNU_SOURCE -DPIC -fPIC -c -xc++ "os-unix.acc" -xnone -I"." -o "os-unix.pic.o"
396
 
//    // paste 'private:', 'protected', or 'public'      
397
 
//    paste (pos, protection_string (prot));
398
 
//
399
 
//    // copy the declaration
400
 
//    // replace all names of the aspect in the introduction with the name
401
 
//    // of the target class
402
 
//    CT_Intro *intro = (CT_Intro*)decl;
403
 
//    int start = 0;
404
 
//    for (int i = 0; i < intro->NameIndices (); i++) {
405
 
//      int index = intro->NameIndex (i);
406
 
//      if (index > start) {
407
 
//        copy (weave_pos (intro->Entry (start)->token (),
408
 
//                         WeavePos::WP_BEFORE),
409
 
//              weave_pos (intro->Entry (index - 1)->end_token (),
410
 
//                         WeavePos::WP_AFTER),
411
 
//              pos);
412
 
//      }
413
 
//      paste (pos, target.str ());
414
 
//      start = index + 1;
415
 
//    }
416
 
//    if (start < intro->Entries ()) {
417
 
//      copy (weave_pos (intro->Entry (start)->token (),
418
 
//                       WeavePos::WP_BEFORE),
419
 
//            weave_pos (intro->Entry (intro->Entries () - 1)->end_token (),
420
 
//                       WeavePos::WP_AFTER),
421
 
//            pos);
422
 
//    }
423
 
//
424
 
//    // paste 'private:' afterwards
425
 
//    paste (pos, protection_string (CProtection::PROT_PRIVATE));
426
 
  }
427
 
  else {
428
 
    // an external introduction
429
 
 
430
 
    CSourceInfo *si = loc->class_info ()->SourceInfo ();
431
 
    bool in_header = (strcmp (si->FileName (),
432
 
                              si->FileInfo ()->Primary ()->name ()) != 0);
433
 
                              
434
 
    if (in_header) {
435
 
      // check if there is a link-once code element in the class
436
 
      CObjectInfo *loo = loc->link_once_object ();
437
 
 
438
 
      // TODO: for now loo has to != 0, later we can exploit the proj. repo
439
 
      if (!loo) {
440
 
        _err << sev_warning << decl->token ()->location () 
441
 
             << "cannot introduce non-inline function or static attribute"
442
 
             << " into \"class " << loc->class_info ()->QualName ()
443
 
             << "\". It has to contain link-once code." << endMessage;
444
 
        return;
445
 
      }
446
 
      
447
 
      // return silently if this is only a declaration
448
 
      if (loo->Scope () == loc->class_info ())
449
 
        return;
450
 
    }
451
 
    
452
 
    // insert the copy of the declaration at the end of the translation unit
453
 
    const WeavePos &pos = weave_pos (primary_end, WeavePos::WP_AFTER);
454
 
 
455
 
    // TODO: this loop has to be executed in a different order than the loop
456
 
    //       for the introduction of inline members. The reason is the
457
 
    //       tranformation system: here we have an WP_AFTER position while
458
 
    //       the other loop has a WP_BEFORE position. That's ugly!
459
 
    
460
 
    // replace all names of the aspect in the introduction with the name
461
 
    // of the target class
462
 
    CT_Intro *intro = (CT_Intro*)decl;
463
 
    ostringstream target_qual, target_unqual;
464
 
    target_unqual << " " << loc->class_info ()->Name () << " " << ends;
465
 
    target_qual << " " << loc->class_info ()->QualName () << " " << ends;
466
 
    int start = intro->Entries () - 1;
467
 
    for (int i = intro->NameIndices () - 1; i >= 0; i--) {
468
 
      int index = intro->NameToIndex (i);
469
 
      if (index < start) {
470
 
        copy (weave_pos (intro->Entry (index + 1)->token (),
471
 
                         WeavePos::WP_BEFORE),
472
 
              weave_pos (intro->Entry (start)->end_token (),
473
 
                         WeavePos::WP_AFTER),
474
 
              pos);
475
 
      }
476
 
      if (intro->NameQual (i))
477
 
        paste (pos, target_qual.str ());
478
 
      else
479
 
        paste (pos, target_unqual.str ());
480
 
      start = intro->NameIndex (i) - 1;
481
 
    }
482
 
    if (start >= 0) {
483
 
      copy (weave_pos (intro->Entry (0)->token (),
484
 
                       WeavePos::WP_BEFORE),
485
 
            weave_pos (intro->Entry (start)->end_token (),
486
 
                       WeavePos::WP_AFTER),
487
 
            pos);
488
 
    }
489
 
  }
490
 
}
491
 
 
492
 
void CodeWeaver::baseclass (JPL_Class &loc, JPP_Class &plan) {
493
 
  CClassInfo *cls = loc.class_info ();
494
 
 
495
 
  // let the plan generate the baseclass list
496
 
  string bcl = plan.gen_baseclass_list ();
497
 
  if (bcl != "") {
498
 
    bcl = string (cls->BaseClasses () == 0 ? " :" : ",") + bcl;
499
 
    // paste the new base before "{" of the class definition's member list
500
 
    const WeavePos &pos = weave_pos (((CT_ClassDef*)cls->DefObject ()->
501
 
                                      Tree ())->Members ()->token (),
502
 
                                      WeavePos::WP_BEFORE);
503
 
    paste (pos, bcl);
504
 
  }
505
 
}
506
 
 
507
 
// void CodeWeaver::inherited (JPL_Class *loc, IntroductionInfo *intro)
508
 
//  {
509
 
//    TN_ClassInfo *cls = loc->class_info ();
510
 
 
511
 
//    const char *prot = intro->def_node ()->protection ();
512
 
 
513
 
//    for (unsigned f = 0; f < cls->Functions (); f++)
514
 
//     {
515
 
//       TN_FunctionInfo *func = cls->Function (f);
516
 
//       if (!func->isInherited () || func->isVirtual ())
517
 
//       continue;
518
 
      
519
 
//       if(!((strcmp (prot, "private") == 0  &&
520
 
//          func->Protection () == TN_ObjectInfo::PRIVATE) ||
521
 
//         (strcmp (prot, "protected") == 0  &&
522
 
//          func->Protection () == TN_ObjectInfo::PROTECTED) ||
523
 
//         (strcmp (prot, "public") == 0  &&
524
 
//          func->Protection () == TN_ObjectInfo::PUBLIC)))
525
 
//       continue;
526
 
 
527
 
//       // This check is too simple, it forgets the argument types
528
 
//       unsigned args = func->BaseObject ()->FunctionInfo ()->Arguments ();
529
 
//       int number = -1;
530
 
//       for (unsigned l = 0; l < cls->Functions (); l++)
531
 
//        {
532
 
//       TN_FunctionInfo *cmp = cls->Function (l);
533
 
//       if (cmp->isInherited ())
534
 
//          cmp = cmp->BaseObject ()->FunctionInfo ();
535
 
 
536
 
//       if (f != l &&
537
 
//           strcmp (func->Name (), cmp->Name ()) == 0 &&
538
 
//           args == cmp->Arguments ())
539
 
//        {
540
 
//          number = (int)l;
541
 
//          break;
542
 
//        }
543
 
//        }
544
 
 
545
 
//       if (number != -1)
546
 
//        {
547
 
//       _err << sev_warning << "Function " << func->Name ()
548
 
//            << " is inherited more than once by class "
549
 
//            << cls->Name () << ": "
550
 
//            << cls->Function (number)->BaseObject ()->QualName () 
551
 
//            << " and " << func->BaseObject ()->QualName ()
552
 
//            << endMessage;
553
 
//       continue;
554
 
//        }
555
 
      
556
 
//       CUnit *out = new_intro_unit (intro);
557
 
 
558
 
//       *out << prot << ":" << endl;
559
 
 
560
 
//       func = func->BaseObject ();
561
 
//       TN_TypeInfo *ftype = func->TypeInfo ();
562
 
 
563
 
//       *out << "inline ";
564
 
//       if (func->isVirtual ())
565
 
//       *out << "virtual ";
566
 
//       else if (func->defStatic ())
567
 
//       *out << "static ";
568
 
//       stringstream sig;
569
 
//       if (func->isOperator ())
570
 
//       sig << "operator ";
571
 
//       sig << func->Name ();
572
 
//       sig << " (";
573
 
//       replacement_fct_args (sig, func, true, true);
574
 
//       sig << ")";
575
 
//       if (ftype->isConst ())
576
 
//       sig << " const";
577
 
//       if (ftype->isVolatile ())
578
 
//       sig << " volatile";
579
 
//       sig << ends;
580
 
//       TN_TypeInfo *result_type = ftype->BaseType ();
581
 
//       result_type->TypeText (*out, sig.str ().data ());
582
 
      
583
 
//       // generate the function body
584
 
//       *out << endl;
585
 
//       *out << " {" << endl;
586
 
//       *out << "   ";
587
 
//       if (!result_type->isVoid ())
588
 
//       *out << "return ";
589
 
//       if (func->Scope ()->ClassInfo ())
590
 
//       *out << "::" << func->Scope ()->ClassInfo ()->QualName () << "::";
591
 
//       if (func->isOperator ())
592
 
//       *out << "operator ";
593
 
//       *out << func->Name () << "(";
594
 
//       for (unsigned a = 0; a < func->Arguments (); a++)
595
 
//        {
596
 
//       if (a > 0)
597
 
//          *out << ", ";
598
 
//       *out << "arg" << a;
599
 
//        }
600
 
//       *out << ");" << endl;
601
 
//       *out << " }" << endl;
602
 
//       *out << endu;
603
 
   
604
 
//       // paste the function behind "{" of the class definition
605
 
//       Token *inspos = cls->DefNode ()->son (2)->token ();
606
 
 
607
 
//       _commander.paste (inspos, out);
608
 
//     }
609
 
//  }
 
298
    out << "} // closed " << (obj->isAnonymous () ? "" : obj->QualName ()) << endl;
 
299
  }
 
300
}
 
301
 
610
302
 
611
303
void CodeWeaver::singleton (ACAspectInfo *ai) {
612
304
  if (ai->aspect_of ()) {
638
330
      << "  static " << ai->name () << " *aspectOf () {" << endl
639
331
      << "    return aspectof ();" << endl
640
332
      << "  }" << endl
641
 
      << "private:" << endl << ends;
 
333
      << "private:" << endl;
642
334
    
643
335
    paste (pos, func.str ());
644
336
  }
649
341
void CodeWeaver::make_proceed_code (ostream &out, JoinPointLoc *badly_typed_loc,
650
342
                                    bool action, int max_depth) {
651
343
  JPL_Code *loc = (JPL_Code*)badly_typed_loc;
 
344
  TI_Code *ti = (TI_Code*)TransformInfo::of (*loc);
 
345
  
652
346
  // set flags that describe the kind of join point
653
347
  bool is_exec = false, is_call = false, is_cons = false, is_dest = false;  
654
348
  if (loc->type () == JoinPointLoc::Method)
662
356
  else
663
357
    return; // should not happen!
664
358
 
665
 
  // find out which function has to be called 
666
 
  CFunctionInfo *dstfunc = (is_exec ? ((JPL_Method*)loc)->func_info () :
667
 
                           (is_call ? ((JPL_MethodCall*)loc)->called ():
668
 
                           (is_cons ? ((JPL_Construction*)loc)->func_info () :
669
 
                           (is_dest ? ((JPL_Destruction*)loc)->func_info () :
670
 
                           0))));
 
359
  // find out which function has to be called by proceed
 
360
  JPL_Function *func = 0;
 
361
  if (is_call)
 
362
    func = ((JPL_MethodCall*)loc)->target_function ();
 
363
  else if (is_exec || is_cons || is_dest)
 
364
    func = (JPL_Function*)loc->parent ();
 
365
  CFunctionInfo *dstfunc = ((TI_Function*)func->transform_info())->func_info ();
671
366
  bool obj_needed = needs_this (dstfunc);
672
367
  
673
 
  bool local_class = (is_call && !_problems._local_class &&
674
 
                      !((JPL_MethodCall*)loc)->in_member_init () &&
675
 
                      ((JPL_MethodCall*)loc)->needs_rights ());
676
 
  bool havefuncptr = (is_call && ((JPL_MethodCall*)loc)->needs_rights () &&
 
368
//  bool local_class = (is_call && !_problems._local_class &&
 
369
//                      !((JPL_MethodCall*)loc)->in_member_init () &&
 
370
//                      ((JPL_MethodCall*)loc)->needs_rights ());
 
371
  bool local_class = false;
 
372
  bool havefuncptr = (ti->proceed_needs_fptr () &&
677
373
                      (!local_class || max_depth > 0));
678
374
                      
679
375
  // nothing is done to proceed implicitly defined special member fcts
687
383
    cflows.gen_trigger_obj (out);
688
384
  }
689
385
 
690
 
  // generate the 'result =' code
691
 
  CTypeInfo *result_type = 
692
 
    dstfunc->isConversion () ? dstfunc->ConversionType () :
693
 
    dstfunc->TypeInfo ()->BaseType ();
694
 
    
695
 
  if (action)
696
 
    make_action_result_assignment(out, result_type);
697
 
  else
698
 
    make_result_assignment(out, result_type);
 
386
  // generate the expression that calculates the result
 
387
  stringstream res;
699
388
  
700
389
  // if we call the function with a function pointer there must be one more br.
701
390
  if (havefuncptr)
702
 
    out << "(";
 
391
    res << "(";
703
392
      
704
393
  // if an object is needed for the call, issue 'obj->'
705
394
  if (obj_needed) {
706
395
    if (is_call) {
707
 
      if (action) {
708
 
        out << "((";
709
 
        Naming::tjp_struct (out, loc, 0);
710
 
        out << "::Target*)_target)->";
711
 
      }
 
396
      if (action)
 
397
        res << "__TJP::target ()->";
712
398
      else {
713
 
        out << "dstthis->";
 
399
        res << "dstthis->";
714
400
      }
715
401
    }
716
402
    else if (is_exec || is_cons || is_dest) {
717
 
      if (action) {
718
 
        out << "((";
719
 
        Naming::tjp_struct (out, loc, 0);
720
 
        out << "::That*)_that)->";
721
 
      }
722
 
      else {
723
 
        out << "this->";
724
 
      }
 
403
      if (action)
 
404
        res << "__TJP::that ()->";
 
405
      else
 
406
        res << "this->";
725
407
    }
726
408
  }
727
409
  
728
410
  // generate the function name
729
411
  if (is_exec || (!dstfunc->isBuiltin () && (is_cons || is_dest))) {
730
412
    if (!obj_needed && nscope (dstfunc))
731
 
      out << "::" << nscope (dstfunc)->QualName () << "::";
 
413
      res << "::" << nscope (dstfunc)->QualName () << "::";
732
414
    // use __old_<name> for execution join points
733
 
    Naming::exec_inner (out, loc);
 
415
    Naming::exec_inner (res, loc);
734
416
  } else if (is_call) {
735
417
    if (havefuncptr) {
736
418
      if (action) {
737
 
        out << "**(";
738
 
//        if (dstfunc->isMethod () && !dstfunc->isStaticMethod ()) 
739
 
//          CTypeMemberPointer (dstfunc->TypeInfo (),
740
 
//                              dstfunc->Record ()).TypeText (out, "*",
741
 
//                                                            true, true);
742
 
//        else
743
 
//          CTypePointer (dstfunc->TypeInfo ()).TypeText (out, "*", true, true);
744
 
        if (dstfunc->isMethod ()) 
745
 
          CTypePointer (dstfunc->TypeInfo ()).TypeText (out, "*", false, true);
746
 
        out << ")_fptr";
 
419
        res << "**(";
 
420
        CObjectInfo *srcobj = TransformInfo::of (*loc)->assoc_obj();
 
421
        CFunctionInfo *srcfunc = srcobj->FunctionInfo ();
 
422
        CClassInfo *srccls = cscope (srcfunc);
 
423
        CClassInfo *dstcls = cscope (dstfunc);
 
424
        bool in_derived =
 
425
          (srccls && dstcls && dstcls->isDerivedClass (srccls, true));
 
426
        if (in_derived)
 
427
          CTypePointer (srcfunc->TypeInfo ()).TypeText (res, "*", true, true);
 
428
        else
 
429
          CTypePointer (dstfunc->TypeInfo ()).TypeText (res, "*", true, true);
 
430
        res << ")_fptr";
747
431
      } else {
748
 
        out << "*fptr";
 
432
        res << "*fptr";
749
433
      }
750
434
    }
751
435
    else {
752
436
      // destination function name
753
 
      if (((JPL_MethodCall*)loc)->is_qualified () ||
754
 
          dstfunc->isStaticMethod () || !dstfunc->isMethod ()) {
755
 
        out << "::";
756
 
        if (nscope (dstfunc))
757
 
          out << nscope (dstfunc)->QualName () << "::";
758
 
      }
759
 
  
760
 
      out << dstfunc->Name ();
 
437
      if (((TI_MethodCall*)TransformInfo::of (*loc))->is_qualified () ||
 
438
          dstfunc->isStaticMethod () || !dstfunc->isMethod ())
 
439
        res << dstfunc->QualName (true, true);
 
440
                else
 
441
              res << dstfunc->Name ();
 
442
      
 
443
            // add the template arguments if it is a function template instance
 
444
            CTemplateInstance *instance = dstfunc->TemplateInstance ();
 
445
            if (instance) {
 
446
              res << "< ";
 
447
              for (unsigned a = 0; a < instance->DeducedArgs (); a++) {
 
448
                if (a > 0) res << ",";
 
449
                DeducedArgument *arg = instance->DeducedArg (a);
 
450
                if (arg->Type ())
 
451
                  arg->Type ()->TypeText (res, "", true, true);
 
452
                else if (arg->Value ()) {
 
453
                  if (arg->Value ()->isSigned ())
 
454
                    res << arg->Value ()->convert_to_int ();
 
455
                  else if (arg->Value ()->isUnsigned ())
 
456
                    res << arg->Value ()->convert_to_uint ();
 
457
                  else if (arg->Value ()->isFloat ())
 
458
                    res << arg->Value ()->convert_to_float ();
 
459
                }
 
460
                else
 
461
                  res << "*invalid template arg*";
 
462
              }
 
463
              res << " >";
 
464
            }
 
465
      
761
466
    }
762
467
  }
763
468
 
764
469
  // if this was a call via pointer we need a closing bracket
765
470
  if (havefuncptr)
766
 
    out << ")";
 
471
    res << ")";
767
472
    
768
473
  // destination function arguments
769
 
  out << "(";
 
474
  res << "(";
770
475
  for (int a = 0 ; a < loc->arg_count (); a++) {
771
 
    if (a > 0) out << ", ";
 
476
    if (a > 0) res << ", ";
772
477
    if (action) {
773
478
      // make sure that if the argument type was a reference we use the
774
479
      // referred type here
775
 
      out << "*((";
776
 
      Naming::tjp_struct (out, loc, 0);
777
 
      out << "::Arg<" << a << ">::ReferredType*)_args[" << a << "])";
 
480
      res << "*(typename __TJP::template Arg<" << a 
 
481
          << ">::ReferredType*)__TJP::arg(" << a << ")";
778
482
    }
779
483
    else
780
 
      out << "arg" << a;
 
484
      res << "arg" << a;
781
485
  }
782
 
  out << ")";
783
 
  // new: bracket if we have a result assignment
784
 
  if (!(result_type->isVoid () || result_type->isUndefined ()))
785
 
    out << ")";
 
486
  res << ")";
 
487
  
 
488
  // generate the 'result =' code
 
489
  CTypeInfo *result_type = 
 
490
    dstfunc->isConversion () ? dstfunc->ConversionType () :
 
491
    dstfunc->TypeInfo ()->BaseType ();
 
492
    
 
493
  ResultBuffer result_buffer (result_type);
 
494
  out << "    ";
 
495
  if (action)
 
496
    out << result_buffer.action_result_assignment(res.str ());
 
497
  else
 
498
    out << result_buffer.result_assignment(res.str ());
786
499
    
787
500
  out << ";" << endl;
788
501
    
795
508
                                     JPAdvice *jpa) {
796
509
  // generate the action function, which is used to obtain an action object
797
510
  impl << "  AC::Action &action() {" << endl;
798
 
  impl << "    _wrapper = &";
 
511
  impl << "    this->__TJP::_wrapper = &";
799
512
  Naming::action_wrapper (impl, loc, jpa->depth ());
800
513
  impl << ";" << endl;
801
514
  impl << "    return *this;" << endl;
806
519
  Naming::action_wrapper (impl, loc, jpa->depth ());
807
520
  impl << " (AC::Action &action) {" << endl;
808
521
  // convert the action object ref into a TJP_... object ref and call proceed
809
 
  impl << "    ((";
810
 
  Naming::tjp_struct (impl, loc, jpa->depth ());
811
 
  impl << "&)action).proceed ();" << endl;
 
522
  impl << "    ((__TJP&)action).proceed ();" << endl;
812
523
 
813
524
  impl << "  }" << endl;
814
525
}
824
535
    make_proceed_code (impl, loc, true, jpa->max_depth ());
825
536
  }
826
537
  else {
 
538
    // generate __TJP type (for the next level)
 
539
    impl << "    typedef ";
 
540
    Naming::tjp_struct (impl, (JPL_Code*)loc, jpa->depth () - 1);
 
541
    impl << "<TResult, TThat, TTarget, TArgs> __TJP;" << endl;
827
542
    // generate advice calls
828
543
    make_advice_calls (impl, jpa->next (), loc, true);
829
544
  }
830
545
  impl << "  }" << endl;
831
546
}
832
547
 
 
548
// generate the name of the joinpoint-specific TJP type
 
549
void CodeWeaver::make_tjp_typename (ostream &out, JPL_Code *loc, int depth) {
 
550
  TI_Code *ti = (TI_Code*)TransformInfo::of (*loc);
 
551
  Naming::tjp_struct (out, loc, depth);
 
552
  out << "< " << ThisJoinPoint::gen_result_type (loc) << ", ";
 
553
  ti->that_type ()->TypeText (out, "", true, true);
 
554
  out << ", ";
 
555
  ti->target_type ()->TypeText (out, "", true, true);
 
556
  // argument types
 
557
  unsigned arg_count = loc->arg_count ();
 
558
  out << ", ";
 
559
  for (unsigned a = 0; a < arg_count; a++) {
 
560
    CTypeInfo *argtype = TI_Type::of (loc->arg_type (a))->type_info ();
 
561
    out << " AC::TL< ";
 
562
    argtype->TypeText (out, "", true, true);
 
563
    out << ",";
 
564
  }
 
565
  out << " AC::TLE";  
 
566
  for (unsigned a = 0; a < arg_count; a++)
 
567
    out << " >";
 
568
  out << " >";
 
569
 }
 
570
 
833
571
// insert TJP class definition before join point
834
 
void CodeWeaver::make_tjp_struct(ostream &out, JoinPointLoc *loc,
 
572
void CodeWeaver::make_tjp_struct(ostream &out, JoinPointLoc *ploc,
835
573
                                 JPAdvice *jpa) {
836
 
 
 
574
  JPL_Code *loc = (JPL_Code*)ploc;
 
575
  
837
576
  // recursively call the function for the previous TJP classes
838
577
  if (jpa->depth () > 0) {
839
578
    make_tjp_struct (out, loc, jpa->next ());
845
584
  tjp.gen_tjp_struct (out, (JPL_Code*)loc, _problems, jpa->depth ());
846
585
  
847
586
  // generate the proceed function for the current structure
848
 
  if (jpa->around () &&
849
 
      (jpa->around ()->code ().this_join_point ().proceed () ||
850
 
       jpa->around ()->code ().this_join_point ().action() ||
851
 
       !jpa->around ()->pointcut ().cflow_triggers ().empty ()))
852
 
    make_proceed_func (out, loc, jpa);
853
 
  
854
 
  // generate action wrapper if needed
855
 
  if (jpa->around () && jpa->around ()->code ().this_join_point ().action())
856
 
    make_action_wrapper (out, loc, jpa);
857
 
  
858
 
  // closing bracket of the TJP class! Opened in gen_tjp_struct.
859
 
  out << "};" << endl;
 
587
  if (jpa->around ()) {
 
588
    const ThisJoinPoint &curr_tjp =
 
589
      TI_AdviceCode::of (jpa->around ()->code ())->this_join_point ();
 
590
    if (curr_tjp.proceed () || curr_tjp.action() ||
 
591
        !jpa->around ()->pointcut ().cflow_triggers ().empty ())
 
592
      make_proceed_func (out, loc, jpa);
 
593
  
 
594
    // generate action wrapper if needed
 
595
    if (curr_tjp.action())
 
596
      make_action_wrapper (out, loc, jpa);
 
597
  }
860
598
  
861
599
  if (jpa->depth () == 0) {
862
600
    stringstream jpname;
863
 
    Naming::tjp_struct (jpname, loc, 0);
864
 
    jpname << ends;
 
601
    Naming::tjp_struct(jpname, loc, 0);
865
602
    jpa->root ()->gen_binding_templates (out, jpname.str ().data (), _problems);
866
603
  }
867
604
  
 
605
  // closing bracket of the TJP class! Opened in gen_tjp_struct.
 
606
  out << "};" << endl;
 
607
  
868
608
  out << endl;
869
609
}
870
610
 
871
611
void CodeWeaver::make_tjp_common_init(ostream &code, JoinPointLoc *badly_typed_loc,
872
612
                                      JPAdvice *jpa) {
873
 
  JPL_Code *loc = (JPL_Code*)badly_typed_loc;
874
 
  const ThisJoinPoint &tjp = jpa->tjp ();
875
 
  JoinPointLoc::join_point_type jptype = loc->type ();
876
 
 
877
 
  bool local_class = false, havefuncptr = false;
878
 
  // determine the weaving parameters
879
 
  if (jptype == JoinPointLoc::MethodCall) {
880
 
    local_class = (!_problems._local_class &&
881
 
                   !((JPL_MethodCall*)loc)->in_member_init () &&
882
 
                   ((JPL_MethodCall*)loc)->needs_rights ());
883
 
    havefuncptr = (((JPL_MethodCall*)loc)->needs_rights () &&
884
 
                   (!local_class || jpa->depth () > 0));
885
 
  }
886
 
 
887
 
  if (tjp.pointer_needed ()) {    
888
 
 
889
 
    int args = ((JPL_Code*)loc)->arg_count ();
890
 
    if (tjp.arg() || tjp.useAction() ||
891
 
        (tjp.proceed () && loc->proceed_needs_args ())) {
892
 
      if (args) {
893
 
        code << "  void *";
894
 
        Naming::tjp_args_array(code, loc);
895
 
        code << "[] = { ";
896
 
        for (int i = 0; i < args; i++) {
897
 
          if (i > 0) code << ", ";
898
 
          code << "(void*)&arg" << i;
899
 
        }
900
 
        code << " };" << endl;
901
 
      }
902
 
    }
903
 
    
904
 
    code << "  ";
905
 
    Naming::tjp_struct(code, loc, jpa->depth ());
906
 
    code << " ";
907
 
    Naming::tjp_instance(code, loc);
908
 
    code << ";" << endl;
909
 
 
910
 
    if (tjp.arg() || tjp.useAction() ||
911
 
        (tjp.proceed () && loc->proceed_needs_args ())) {
912
 
      code << "  ";
913
 
      Naming::tjp_instance(code, loc);
914
 
      code << "._args = ";
915
 
      if (args)
916
 
        Naming::tjp_args_array(code, loc);
917
 
      else
918
 
        code << "0";
919
 
      code << ";" << endl;
920
 
    }
921
 
    
922
 
    if (tjp.result() || tjp.useAction() ||
923
 
        (tjp.proceed () && loc->proceed_needs_result ())) {
924
 
      code << "  ";
925
 
      Naming::tjp_instance(code, loc);
926
 
      code << "._result = ";
927
 
      CTypeInfo *rtype = ((JPL_Code*)loc)->result_type ().type_info ();
928
 
      if (!(rtype->isVoid() || rtype->isUndefined ())) {
929
 
        if (tjp.useAction ())
930
 
          code << "(void*)";
931
 
        code << "&(";
932
 
        Naming::tjp_struct (code, loc, jpa->depth ());
933
 
        code << "::Result&)result";
934
 
      } else {
935
 
        code << "0";
936
 
      }
937
 
      code << ";" << endl;
938
 
    }
939
 
    
940
 
    if (tjp.target() || tjp.useAction() ||
941
 
        (tjp.proceed () && loc->proceed_needs_target ())) {
942
 
      code << "  ";
943
 
      Naming::tjp_instance(code, loc);
944
 
      code << "._target = ";
945
 
      if (loc->tjp_target () && needs_this (loc->tjp_target())) {
946
 
        code << " (";
947
 
        if (tjp.useAction ())
948
 
          code << "void*)";
949
 
        else {
950
 
          Naming::tjp_struct(code, loc, jpa->depth ());
951
 
          code << "::Target*)";
952
 
        }
953
 
        switch (jptype) {
954
 
          case JoinPointLoc::Construction:
955
 
          case JoinPointLoc::Destruction:
956
 
          case JoinPointLoc::Method:
957
 
            code << "this";
958
 
            break;
959
 
          case JoinPointLoc::MethodCall:
960
 
            code << "dstthis";
961
 
            break;
962
 
          default:
963
 
            code << " 0";
964
 
          }
965
 
      } else {
966
 
        code << " 0";
967
 
      }
968
 
      code << ";" << endl;
969
 
    }
970
 
 
971
 
    if (tjp.that() || tjp.useAction() ||
972
 
        (tjp.proceed () && loc->proceed_needs_that ())) {
973
 
      code << "  ";
974
 
      Naming::tjp_instance(code, loc);
975
 
      code << "._that = ";
976
 
      if (loc->tjp_that () && needs_this (loc->tjp_that())) {
977
 
        code << " (";
978
 
        if (tjp.useAction ())
979
 
          code << "void*)";
980
 
        else {
981
 
          Naming::tjp_struct(code, loc, jpa->depth ());
982
 
          code << "::That*)";
983
 
        }
984
 
        switch (jptype) {
985
 
          case JoinPointLoc::Construction:
986
 
          case JoinPointLoc::Destruction:
987
 
          case JoinPointLoc::Method:
988
 
            code << "this";
989
 
            break;
990
 
          case JoinPointLoc::MethodCall:
991
 
            code << "srcthis";
992
 
            break;
993
 
          default:
994
 
            code << " 0";
995
 
        }
996
 
      } else {
997
 
        code << " 0";
998
 
      }
999
 
      code << ";" << endl;
1000
 
    }
1001
 
    
1002
 
    if (tjp.useAction () ||
1003
 
        (tjp.proceed () && loc->proceed_needs_fptr ())) {
1004
 
      code << "  ";
1005
 
      Naming::tjp_instance(code, loc);
1006
 
      code << "._fptr = ";
1007
 
      if (havefuncptr)
1008
 
        code << "&fptr";
1009
 
      else  
1010
 
        code << "0";
1011
 
      code << ";" << endl;
1012
 
    }
1013
 
  }
1014
 
}
1015
 
 
1016
 
void CodeWeaver::make_result_type (ostream &out, CTypeInfo *type,
1017
 
  bool reference) {
1018
 
  if (type->isVoid () || type->isUndefined ())
1019
 
    out << "void";
1020
 
  else if (type->isAddress ())
1021
 
    type->BaseType ()->TypeText (out, reference ? "*&" : "*", true, true);
1022
 
  else
1023
 
    type->TypeText (out, reference ? "&" : "", true, true);
1024
 
}
1025
 
 
1026
 
void CodeWeaver::make_result_declaration(ostream &out, CTypeInfo *type) {
1027
 
  if (!(type->isVoid () || type->isUndefined ())) {
1028
 
    out << "  AC::ResultBuffer< ";
1029
 
    make_result_type (out, type, false);
1030
 
    out << " > result;" << endl;
1031
 
  }
1032
 
}
1033
 
 
1034
 
void CodeWeaver::make_result_assignment(ostream &out, CTypeInfo *type) {
1035
 
  if (!(type->isVoid() || type->isUndefined ()))  {
1036
 
    out << "  ::new (&result) ";
1037
 
    make_result_type (out, type->UnqualType (), false);
1038
 
    out << " (";
1039
 
    if (type->isAddress ())
1040
 
      out << "&";
1041
 
  }
1042
 
}
1043
 
 
1044
 
void CodeWeaver::make_action_result_assignment(ostream &out, CTypeInfo *type) {
1045
 
  if (!(type->isVoid() || type->isUndefined ()))  {
1046
 
    out << "  ::new ((AC::ResultBuffer< ";
1047
 
    make_result_type (out, type, false);
1048
 
    out << " >*)_result) ";
1049
 
    make_result_type (out, type, false);
1050
 
    out << " (";
1051
 
    if (type->isAddress ())
1052
 
      out << "&";
1053
 
  }  
1054
 
}
1055
 
 
1056
 
void CodeWeaver::make_result_return(ostream &out, CTypeInfo *type) {
1057
 
  if (!(type->isVoid () || type->isUndefined ())) {
1058
 
    out << "  return ";
1059
 
    if (type->isAddress ())
1060
 
      out << "*";
1061
 
    out << "(";
1062
 
    make_result_type (out, type, true);
1063
 
    out << ")result;" << endl;
1064
 
  }
 
613
  jpa->tjp ().gen_tjp_init(code, (JPL_Code*)badly_typed_loc,
 
614
    _problems, jpa->depth ());
 
615
}
 
616
 
 
617
// generates the signature of a wrapper function for exec/cons/dest join pts
 
618
string CodeWeaver::wrapper_function_signature (JPL_Code *loc,
 
619
  CFunctionInfo *func, bool def) {
 
620
  assert (func);
 
621
  
 
622
  stringstream name_args;
 
623
  if (func->CObjectInfo::QualifiedScope () &&
 
624
      func->Scope () != func->CObjectInfo::QualifiedScope ())
 
625
    name_args << func->CObjectInfo::QualifiedScope ()->QualName () << "::";
 
626
  Naming::exec_inner (name_args, loc);
 
627
  name_args << "(";
 
628
  for (unsigned a = 0; a < func->Arguments (); a++) {
 
629
    CArgumentInfo *arg = func->Argument (a);
 
630
    if (arg->TypeInfo ()->is_void ())
 
631
      break;
 
632
    if (a > 0) name_args << ",";
 
633
      arg->TypeInfo ()->TypeText (name_args,
 
634
                                  arg->isAnonymous () ? "" : arg->Name (),
 
635
                                  true, true);
 
636
  }
 
637
  name_args << ")";
 
638
 
 
639
  ostringstream wrapped;
 
640
 
 
641
  if (_problems._use_always_inline) // GNU extension
 
642
    wrapped << "__attribute__((always_inline)) ";
 
643
  wrapped << "inline "; // the wrapped function should always be inlined
 
644
  if (func->isStaticMethod () && func->ClassScope () == func->Scope ())
 
645
    wrapped << "static ";
 
646
 
 
647
  if (func->isConstructor () || func->isDestructor ())
 
648
    wrapped << "void " << name_args.str ().c_str ();
 
649
  else {
 
650
    CTypeInfo *type = func->isConversion () ? func->ConversionType () :
 
651
                                              func->TypeInfo ()->BaseType ();
 
652
      type->TypeText (wrapped, name_args.str ().c_str (), true, true);
 
653
    if (func->TypeInfo ()->isConst ())
 
654
      wrapped << " const";
 
655
    if (func->TypeInfo ()->isVolatile ())
 
656
      wrapped << " volatile";
 
657
  }
 
658
  
 
659
  return wrapped.str ();
1065
660
}
1066
661
 
1067
662
void CodeWeaver::cons_join_point (JPL_Construction *loc, JPP_Code &plan) {
1068
 
  if (loc->assoc_obj ()->FunctionInfo ()->isBuiltin ())
 
663
  if (loc->function ()->is_built_in())
1069
664
    gen_special_member_function (loc, plan);
1070
665
  else
1071
666
    wrap_function (loc, plan);
1072
667
}
1073
668
  
1074
669
void CodeWeaver::dest_join_point (JPL_Destruction *loc, JPP_Code &plan) {
1075
 
  if (loc->assoc_obj ()->FunctionInfo ()->isBuiltin ())
 
670
  if (loc->function ()->is_built_in())
1076
671
    gen_special_member_function (loc, plan);
1077
672
  else
1078
673
    wrap_function (loc, plan);
1110
705
 
1111
706
  ostringstream code;
1112
707
  JPAdvice *ejpa = plan.jp_advice ();
1113
 
  CFunctionInfo *func = loc->assoc_obj ()->FunctionInfo ();
 
708
  CFunctionInfo *func = TransformInfo::of (*loc)->assoc_obj ()->FunctionInfo ();
1114
709
  assert (func && func->ClassScope ());
1115
710
  CClassInfo *cls = func->ClassScope ()->ClassInfo ();
1116
711
 
1126
721
  if (ejpa->tjp ().type_needed ()) {
1127
722
    ostringstream wrappers;
1128
723
    make_tjp_struct(wrappers, loc, ejpa);
1129
 
    wrappers << ends;
1130
724
    paste (weave_pos (inspos, WeavePos::WP_BEFORE), wrappers.str ());
1131
725
  }
1132
726
 
1214
808
    }
1215
809
  }
1216
810
 
 
811
  // generate __TJP type (for this level)
 
812
  if (ejpa->tjp ().type_needed ()) {
 
813
    code << "  typedef ";
 
814
    make_tjp_typename (code, (JPL_Code*)loc, ejpa->depth ());
 
815
    code << " __TJP;" << endl;
 
816
  }
 
817
 
1217
818
  // generate common JoinPoint initialization
1218
819
  make_tjp_common_init(code, loc, ejpa);
1219
820
    
1220
821
  // generate calls to advice code or original function
1221
822
  make_advice_calls(code, ejpa, loc);
1222
823
 
1223
 
  code << endl << "}" << endl << ends;
 
824
  code << endl << "}" << endl;
1224
825
 
1225
826
  // insert the definition
1226
827
  paste (weave_pos (inspos, WeavePos::WP_BEFORE), code.str ());
1323
924
      << "{ return _data[i]; } // for VC++ 2003" << endl;
1324
925
  out << "    template <typename I> const E& operator [] (I i) const "
1325
926
      << "{ return _data[i]; } // for VC++ 2003" << endl;
1326
 
  out << "  } " << obj->Name () << ends;
 
927
  out << "  } " << obj->Name ();
1327
928
}
1328
929
 
1329
930
void CodeWeaver::exec_join_point (JPL_Method *loc, JPP_Code &plan) {
1333
934
void CodeWeaver::wrap_function (JPL_Code *loc, JPP_Code &plan) {
1334
935
  _code_plan = &plan;
1335
936
  
1336
 
  CFunctionInfo *func = loc->assoc_obj ()->DefObject ()->FunctionInfo ();
 
937
  CFunctionInfo *func = TransformInfo::of (*loc)->assoc_obj ()->DefObject ()->FunctionInfo ();
1337
938
  assert (func);
1338
939
 
1339
940
  // handle each declaration and the optional definition separately
1372
973
  // not necessary for methods and if there is a declaration anyway
1373
974
  if (!func->isMethod () && !wrapped_decl) {
1374
975
    have_pre_sig = true;
1375
 
    pre_sig << loc->wrapper_function_signature (func, true) << ";" << endl;
 
976
    pre_sig << wrapper_function_signature (loc, func, true) << ";" << endl;
1376
977
  }
1377
978
  
1378
979
  // generate the JoinPoint class
1399
1000
  CTypeFunction *ftype = func->TypeInfo ()->TypeFunction ();
1400
1001
  CTypeInfo *result_type = func->isConversion () ?
1401
1002
    func->ConversionType () : ftype->BaseType ();
1402
 
 
 
1003
  ResultBuffer result_buffer (result_type);
 
1004
  
1403
1005
  pre_body << "{" << endl;
 
1006
 
 
1007
  // generate __TJP type (for this level)
 
1008
  if (ejpa->tjp ().type_needed ()) {
 
1009
    pre_body << "  typedef ";
 
1010
    make_tjp_typename (pre_body, loc, ejpa->depth ());
 
1011
    pre_body << " __TJP;" << endl;
 
1012
  }
1404
1013
  
1405
1014
  // declare the result object
1406
 
  make_result_declaration(pre_body, result_type);
 
1015
  pre_body << "  " << result_buffer.result_declaration ();
1407
1016
 
1408
1017
  // generate common JoinPoint initialization
1409
 
  make_tjp_common_init(pre_body, loc, ejpa);
 
1018
  make_tjp_common_init (pre_body, loc, ejpa);
1410
1019
  
1411
1020
  // generate calls to advice code or original function
1412
 
  make_advice_calls(pre_body, ejpa, loc);
 
1021
  make_advice_calls (pre_body, ejpa, loc);
1413
1022
 
1414
 
  make_result_return(pre_body, result_type);
 
1023
  pre_body << "  " << result_buffer.result_return ();
1415
1024
  pre_body << endl << "}" << endl;
1416
1025
 
1417
1026
  // generate the signature of the inner function (the original)
1419
1028
  if (func->isMethod () && !func->isStaticMethod () && !needs_this (func))
1420
1029
    pre_body << "static ";
1421
1030
  // add a wrapper function declaration
1422
 
  pre_body << loc->wrapper_function_signature (func, true);
 
1031
  pre_body << wrapper_function_signature (loc, func, true);
1423
1032
 
1424
1033
  // insert the new body and new signature in front of the old body
1425
1034
  paste (weave_pos (fctdef->Body ()->token (), WeavePos::WP_BEFORE),
1447
1056
  if (func->isMethod () && !func->isStaticMethod () && !needs_this (func))
1448
1057
    inner_decl += "static ";
1449
1058
  // add the wrapper function declaration
1450
 
  inner_decl += loc->wrapper_function_signature (func->FunctionInfo (), false);
 
1059
  inner_decl += wrapper_function_signature (loc, func->FunctionInfo (), false);
1451
1060
  inner_decl += ";";
1452
1061
  // switch to the right protection if needed
1453
1062
  if (func->Protection () != CProtection::PROT_NONE &&
1501
1110
            strcmp (field_text, "Result") == 0) {
1502
1111
          stringstream field_unit;
1503
1112
          Naming::tjp_typedef (field_unit, field_text);
1504
 
          field_unit << ends;
1505
1113
          const WeavePos &qname_start =
1506
1114
            weave_pos (node->token (), WeavePos::WP_BEFORE);
1507
1115
          const WeavePos &qname_end =
1545
1153
    typedefs << "  typedef typename JoinPoint::Result ";
1546
1154
    Naming::tjp_typedef (typedefs, "Result");
1547
1155
    typedefs << ";" << endl;
1548
 
    typedefs << ends;
1549
1156
    paste (weave_pos (fctdef->Body ()->token (), WeavePos::WP_AFTER),
1550
1157
           typedefs.str ());
1551
1158
  }
1559
1166
    args << "JoinPoint *tjp";
1560
1167
    if (func->Arguments () > 0)
1561
1168
      args << ", ";
1562
 
    args << ends;
1563
1169
    paste (weave_pos (arg_tree->token (), WeavePos::WP_AFTER), args.str ());
1564
1170
  }
1565
1171
  
1577
1183
void CodeWeaver::make_advice_call(ostream &out, JoinPointLoc *loc, 
1578
1184
                                                          AdviceInfo *ai, bool inter, int depth) {
1579
1185
 
1580
 
  CFunctionInfo *srcfunc, *dstfunc;
 
1186
  CFunctionInfo *srcfunc;
1581
1187
  const char *srcthis_name = "srcthis";
1582
1188
  
1583
1189
  if (loc->type () == JoinPointLoc::Method ||
1584
1190
      loc->type () == JoinPointLoc::Construction ||
1585
1191
      loc->type () == JoinPointLoc::Destruction) {
1586
 
    srcfunc = loc->assoc_obj ()->DefObject ()->FunctionInfo ();
1587
 
    dstfunc = 0;
 
1192
    srcfunc = TransformInfo::of (*loc)->assoc_obj ()->DefObject ()->FunctionInfo ();
1588
1193
    if (!inter)
1589
1194
      srcthis_name = "this";
1590
1195
  }
1591
1196
  else if (loc->type () == JoinPointLoc::MethodCall) {
1592
 
    srcfunc = ((JPL_MethodCall*)loc)->caller ();
1593
 
    dstfunc = ((JPL_MethodCall*)loc)->called ();
 
1197
    srcfunc = ((TI_MethodCall*)TransformInfo::of (*loc))->caller ();
1594
1198
  }
1595
1199
  else {
1596
1200
    out << "// invalid join point type in make_advice_call" << endl;
1610
1214
 
1611
1215
  // make the advice call itself
1612
1216
  stringstream tjp_tp;
1613
 
  Naming::tjp_struct (tjp_tp, jp.location (), depth);
1614
 
  tjp_tp << ends;
 
1217
//  make_tjp_typename (tjp_tp, (JPL_Code*)jp.location (), depth);
 
1218
//  tjp_tp << " ";
 
1219
  tjp_tp << "__TJP";
1615
1220
   
1616
1221
  stringstream tjp_obj;
1617
1222
  if (inter)
1620
1225
    tjp_obj << "&";
1621
1226
    Naming::tjp_instance (tjp_obj, jp.location ());
1622
1227
  }
1623
 
  tjp_obj << ends;
1624
1228
   
1625
1229
  out << "  ";
1626
1230
  ai->gen_invocation_func_call (out, tjp_tp.str ().data (),
1629
1233
 
1630
1234
  if (jp.condition ()) {
1631
1235
    out << "  }" << endl;
1632
 
    if (ai->type () == ADVICE_AROUND) {
 
1236
    if (ai->type () == JPL_AdviceCode::ADVICE_AROUND) {
1633
1237
      out << "  else {" << endl << "    ";
1634
1238
      if (inter)
1635
1239
        out << tjp_tp.str ().data () << "::";
1662
1266
// at a call join point
1663
1267
void CodeWeaver::call_join_point (JPL_MethodCall *loc, JPP_Code &plan) {
1664
1268
  // determine the weaving parameters
1665
 
  bool local_class = (!_problems._local_class && !loc->in_member_init () &&
1666
 
                      loc->needs_rights ());
 
1269
//  bool local_class = (!_problems._local_class && !loc->in_member_init () &&
 
1270
//                      loc->needs_rights ());
 
1271
  bool local_class = false;
1667
1272
  
1668
1273
  _code_plan = &plan;
1669
 
  
 
1274
 
 
1275
  TI_MethodCall &ti = *(TI_MethodCall*)TransformInfo::of (*loc);
1670
1276
  JPAdvice *cjpa = plan.jp_advice ();
1671
 
  CObjectInfo *srcobj = loc->assoc_obj();
 
1277
  CObjectInfo *srcobj = TransformInfo::of (*loc)->assoc_obj();
1672
1278
  CFunctionInfo *srcfunc = srcobj->FunctionInfo ();
1673
 
  CFunctionInfo *dstfunc = loc->called();
 
1279
  CFunctionInfo *dstfunc = ti.called ();
1674
1280
  CTypeInfo *tdstfunc = dstfunc->TypeInfo()->TypeFunction();
1675
1281
 
 
1282
  // determine the weaving position for wrapper code
 
1283
  const WeavePos *pos = 0;
 
1284
  bool extern_c_block = false;
 
1285
  if (local_class) {
 
1286
    // opening "{"
 
1287
    Token *inspos = ((CT_FctDef*)srcfunc->Tree ())->Body ()->token ();
 
1288
     pos = &weave_pos (inspos, WeavePos::WP_AFTER);
 
1289
  }
 
1290
  else {
 
1291
    CTree *tree;
 
1292
    if (srcfunc) {
 
1293
      CT_FctDef *fctdef = (CT_FctDef*)srcfunc->Tree ();
 
1294
      tree = linkage_adjust (fctdef);
 
1295
      if (fctdef->Linkage () && fctdef->Linkage ()->isList ())
 
1296
        extern_c_block = true;
 
1297
    }
 
1298
    else
 
1299
      tree = ((CT_InitDeclarator*)srcobj->Tree ())->ObjDecl ();
 
1300
    pos = &weave_pos (tree->token (), WeavePos::WP_BEFORE);
 
1301
  }
 
1302
  
1676
1303
  // generate and insert a forward declaration for the target function if needed
1677
1304
  if (srcfunc && srcfunc == dstfunc && !dstfunc->isMethod () &&
1678
1305
      dstfunc->NextObject () == dstfunc) {
1685
1312
  cjpa->mergeTJPFlags();
1686
1313
  if (cjpa->tjp ().type_needed ()) {
1687
1314
    ostringstream tjp;
 
1315
    if (extern_c_block)
 
1316
      tjp << "}" << endl;
1688
1317
    make_tjp_struct (tjp, loc, cjpa);
1689
 
    tjp << ends;
 
1318
    if (extern_c_block)
 
1319
      tjp << "extern \"C\" {" << endl;
1690
1320
    // insert the definition
1691
 
    const WeavePos &pos =
1692
 
      weave_pos(loc->insertloc_tjp_struct (), WeavePos::WP_BEFORE);
1693
 
    paste (pos, tjp.str ());
 
1321
    paste (*pos, tjp.str ());
1694
1322
  }
1695
1323
  
1696
1324
  // generate replacement function for dstfunc
1710
1338
  // has to be preceded by a 'static' keyword to avoid an implicit 'this'.
1711
1339
  if (local_class || srcobj->Scope ()->ClassInfo ())
1712
1340
      code << "static ";
 
1341
  if (_problems._use_always_inline) // GNU extension
 
1342
    code << "__attribute__((always_inline)) ";
1713
1343
  code << "inline ";
1714
1344
 
1715
1345
  stringstream sig;
1730
1360
  unsigned argnum = 0;
1731
1361
  bool havesrcthis = srcfunc && needs_this (srcfunc);
1732
1362
  bool havedstthis = needs_this (dstfunc);
1733
 
  bool havefuncptr = (loc->needs_rights () &&
 
1363
  bool havefuncptr = (ti.proceed_needs_fptr () &&
1734
1364
                     (!local_class || cjpa->depth () > 0));  
1735
1365
 
1736
 
  const char *calltype = loc->CallExprNode ()->Son(0)->NodeName ();
 
1366
  const char *calltype = ti.CallNode ()->NodeName ();
1737
1367
 
1738
1368
  // source and destination this pointer arguments (if needed)
1739
1369
  if (havesrcthis) {
1770
1400
  
1771
1401
  // analyse the target object of this call
1772
1402
  bool target_is_ptr;
1773
 
  CT_Expression *target_expr = loc->target_expr (target_is_ptr);
 
1403
  CT_Expression *target_expr = ti.target_expr (target_is_ptr);
1774
1404
 
1775
1405
  if (havedstthis) {
1776
1406
    if (argnum) {
1808
1438
    if (argnum > 0)
1809
1439
    sig << ", ";
1810
1440
    stringstream arg_name;
1811
 
    arg_name << "arg" << a << ends;
1812
 
    CTypeInfo *type = loc->arg_type (a).type_info ();
 
1441
    arg_name << "arg" << a;
 
1442
    CTypeInfo *type = TI_Type::of (loc->arg_type (a))->type_info ();
1813
1443
    type->TypeText (sig, arg_name.str ().data (), true, true);
1814
1444
    argnum++;
1815
1445
  }
1816
1446
//  replacement_fct_args (sig, dstfunc, true, true);
1817
1447
 
1818
 
  sig << ")" << ends;
1819
 
  new_call << ends;
 
1448
  sig << ")";
1820
1449
  
1821
1450
  // add result type
1822
1451
  CTypeInfo *result_type = dstfunc->isConversion () ? 
1823
1452
    dstfunc->ConversionType () : tdstfunc->BaseType ();
1824
1453
  result_type->TypeText(code, sig.str ().data (), true, true);
 
1454
  ResultBuffer result_buffer (result_type);
1825
1455
 
1826
1456
  // replacement function body
1827
1457
  code << "{" << endl;
1828
1458
 
 
1459
  // generate __TJP type (for the next level)
 
1460
  if (cjpa->tjp ().type_needed ()) {
 
1461
    code << "  typedef ";
 
1462
    make_tjp_typename (code, loc, cjpa->depth ());
 
1463
    code << " __TJP;" << endl;
 
1464
  }
 
1465
 
1829
1466
  // declare the result store
1830
 
  make_result_declaration(code, result_type);
 
1467
  code << "  " << result_buffer.result_declaration();
1831
1468
 
1832
1469
  // generate common JoinPoint initialization
1833
1470
  make_tjp_common_init(code, loc, cjpa);
1835
1472
  // add calls to advice code
1836
1473
  make_advice_calls(code, cjpa, loc);
1837
1474
 
1838
 
  make_result_return(code, result_type);
 
1475
  code << "  " << result_buffer.result_return();
1839
1476
 
1840
1477
  code << " }" << endl;
1841
1478
 
1843
1480
    code << "};" << endl;
1844
1481
  }
1845
1482
 
1846
 
  code << ends;
1847
 
 
1848
1483
  // now we perform the code manipulation
1849
1484
 
1850
1485
  // insert the call wrapper body
1851
 
  if (local_class) {
1852
 
    // opening "{"
1853
 
    Token *inspos = ((CT_FctDef*)srcfunc->Tree ())->Body ()->token ();
1854
 
    paste (weave_pos (inspos, WeavePos::WP_AFTER), code.str ());
1855
 
  }
1856
 
  else {
1857
 
    CTree *pos;
1858
 
    if (srcfunc) {
1859
 
      CT_FctDef *fctdef = (CT_FctDef*)srcfunc->Tree ();
1860
 
      pos = linkage_adjust (fctdef);
1861
 
    }
1862
 
    else
1863
 
      pos = ((CT_InitDeclarator*)srcobj->Tree ())->ObjDecl ();
1864
 
    paste (weave_pos (pos->token (), WeavePos::WP_BEFORE), code.str ());
1865
 
  }
 
1486
  paste (*pos, code.str ());
1866
1487
 
1867
1488
  // replace call with call to replacement function
1868
1489
 
1869
1490
  // paste the first (generated) part of the call (in front)
1870
 
  paste (weave_pos (loc->CallExprNode ()->token (), WeavePos::WP_BEFORE),
 
1491
  paste (weave_pos (ti.CallNode ()->token (), WeavePos::WP_BEFORE),
1871
1492
         new_call.str ());
1872
1493
  
1873
1494
  // paste a closing bracket behind the call
1874
 
  paste (weave_pos (loc->CallExprNode ()->end_token (), WeavePos::WP_AFTER),
 
1495
  paste (weave_pos (ti.CallNode ()->end_token (), WeavePos::WP_AFTER),
1875
1496
         ")");
1876
1497
  
1877
1498
  // provide the other arguments
1878
1499
 
1879
1500
  CTree *node;
1880
 
  // the destination function is a conversion function
1881
 
  if (dstfunc->isConversion ()) {
1882
 
    node = target_expr;
1883
 
    assert (node);
1884
 
    paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1885
 
  }
1886
1501
  // call was a binary operator call
1887
 
  else if (calltype == CT_BinaryExpr::NodeId ()) {
1888
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (0);
 
1502
  if (calltype == CT_BinaryExpr::NodeId ()) {
 
1503
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (0);
1889
1504
    if (target_expr) {
1890
1505
      if (!target_is_ptr)
1891
1506
        paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1892
1507
    }
1893
1508
    else if ((havesrcthis || havefuncptr) && !havedstthis)
1894
1509
      paste (weave_pos (node->token (), WeavePos::WP_BEFORE), ",");
1895
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (1);
 
1510
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1);
1896
1511
    paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ",");
1897
1512
    kill (node);
1898
1513
  }
1899
1514
  // call was a unary operator call
1900
1515
  else if (calltype == CT_UnaryExpr::NodeId ()) {
1901
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (0);
 
1516
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (0);
1902
1517
    kill (node);
1903
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (1);
 
1518
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1);
1904
1519
    if (target_expr) {
1905
1520
      if (!target_is_ptr)
1906
1521
        paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1910
1525
  }
1911
1526
  // call was a postfix operator call
1912
1527
  else if (calltype == CT_PostfixExpr::NodeId ()) {
1913
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (1);
 
1528
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1);
1914
1529
    kill (node);
1915
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (0);
 
1530
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (0);
1916
1531
    if (strcmp (dstfunc->Name (), "operator ++") == 0 ||
1917
1532
        strcmp (dstfunc->Name (), "operator --") == 0)
1918
1533
      paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ", 0");
1921
1536
  }
1922
1537
  // call was an index operator call
1923
1538
  else if (calltype == CT_IndexExpr::NodeId ()) {
1924
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (0);
 
1539
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (0);
1925
1540
    if (target_expr && !target_is_ptr)
1926
1541
      paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1927
1542
    // replace the opening '[' with ','
1928
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (1);
 
1543
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1);
1929
1544
    paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ",");
1930
1545
    kill (node);
1931
1546
    // delete the closing ']'
1932
 
    node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (3);
 
1547
    node = ((CT_BinaryExpr*)ti.CallNode ())->Son (3);
1933
1548
    kill (node);
1934
1549
  }
 
1550
  // the destination function is a conversion function
 
1551
  else if (calltype == CT_ImplicitCall::NodeId ()) {
 
1552
    node = target_expr;
 
1553
    assert (node);
 
1554
    paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
 
1555
  }
1935
1556
  // call was an ordinary function call
1936
 
  else {    
 
1557
  else {
 
1558
    const char *fctnodetype = ti.CallNode()->Son (0)->NodeName ();
1937
1559
    if ((target_expr && !target_is_ptr) &&
1938
 
         (calltype == CT_MembRefExpr::NodeId () ||
1939
 
          calltype == CT_MembPtrExpr::NodeId ())) {
1940
 
      node = loc->CallExprNode ()->Son (0);
 
1560
         (fctnodetype == CT_MembRefExpr::NodeId () ||
 
1561
          fctnodetype == CT_MembPtrExpr::NodeId ())) {
 
1562
      node = ti.CallNode ()->Son (0);
1941
1563
      paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1942
1564
    }
1943
 
    if (calltype == CT_MembRefExpr::NodeId () && havedstthis) {
1944
 
      kill (((CT_MembRefExpr*)loc->CallExprNode ()->Son (0))->Son (1));
1945
 
      kill (((CT_MembRefExpr*)loc->CallExprNode ()->Son (0))->Son (2));
 
1565
    if (fctnodetype == CT_MembRefExpr::NodeId () && havedstthis) {
 
1566
      kill (((CT_MembRefExpr*)ti.CallNode ()->Son (0))->Son (1));
 
1567
      kill (((CT_MembRefExpr*)ti.CallNode ()->Son (0))->Son (2));
1946
1568
    }
1947
 
    else if (calltype == CT_MembPtrExpr::NodeId () && havedstthis) {
1948
 
      kill (((CT_MembPtrExpr*)loc->CallExprNode ()->Son (0))->Son (1));
1949
 
      kill (((CT_MembPtrExpr*)loc->CallExprNode ()->Son (0))->Son (2));
 
1569
    else if (fctnodetype == CT_MembPtrExpr::NodeId () && havedstthis) {
 
1570
      kill (((CT_MembPtrExpr*)ti.CallNode ()->Son (0))->Son (1));
 
1571
      kill (((CT_MembPtrExpr*)ti.CallNode ()->Son (0))->Son (2));
1950
1572
    }
1951
1573
    else
1952
 
      kill (loc->CallExprNode ()->Son (0));
1953
 
    CT_ExprList *args = loc->CallExprNode ()->Arguments ();
 
1574
      kill (ti.CallNode ()->Son (0));
 
1575
    CT_ExprList *args = ((CT_CallExpr*)ti.CallNode ())->Arguments ();
1954
1576
    if (!args) {
1955
 
      _err << sev_warning << loc->CallExprNode ()->token ()->location ()
 
1577
      _err << sev_warning << ti.CallNode ()->token ()->location ()
1956
1578
           << "unsupported kind of call, cannot weave advice code"
1957
1579
           << endMessage;
1958
1580
      return;