~ubuntu-branches/ubuntu/quantal/aspectc++/quantal

« back to all changes in this revision

Viewing changes to AspectC++/JoinPointPlan.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:
18
18
 
19
19
#include "JoinPointPlan.h"
20
20
#include "ACUnit.h"
21
 
#include "IntroductionInfo.h"
22
21
#include "IntroductionUnit.h"
23
22
#include "AspectInfo.h"
24
23
#include "WeaverBase.h"
29
28
#include "Puma/ManipCommander.h"
30
29
#include "Puma/CFunctionInfo.h"
31
30
#include "Puma/CArgumentInfo.h"
 
31
#include "Puma/ACSliceInfo.h"
 
32
#include "Puma/CClassDatabase.h"
32
33
 
33
34
// issue an advice in the plan for this code join point
34
35
void JPP_Code::issue (int index) {
35
36
  AdviceInfo *ai = _unsorted[index];
36
37
  const Condition &cond = *_conds[index];
37
38
  switch (ai->type()) {
38
 
  case ADVICE_BEFORE:
 
39
  case JPL_AdviceCode::ADVICE_BEFORE:
39
40
    _jpa.do_before (ai, cond);
40
41
    break;
41
 
  case ADVICE_AROUND:
 
42
  case JPL_AdviceCode::ADVICE_AROUND:
42
43
    _jpa.do_around (ai, cond);
43
44
    break;
44
 
  case ADVICE_AFTER:
 
45
  case JPL_AdviceCode::ADVICE_AFTER:
45
46
    _jpa.do_after (ai, cond);
46
47
    break;
47
48
  }
63
64
    ACAspectInfo* ai = &item (i);
64
65
    for (int j = 0; j < _unsorted.length(); j++) {
65
66
      AdviceInfo* a = _unsorted[j];
66
 
      if (a && (a->aspect()->acnode() == ai)) {
 
67
      if (a && (TI_Aspect::of (a->aspect())->acnode() == ai)) {
67
68
        issue(j);
68
69
        _unsorted[j] = 0;
69
70
      }
77
78
}
78
79
 
79
80
// issue an introduction in the plan for this class join point
80
 
void JPP_Class::issue (IntroductionInfo *ii) {
81
 
  switch (ii->type ()) {
82
 
  case IntroductionInfo::INTRO_BASECLASS:
 
81
void JPP_Class::issue (JPL_Introduction *ii) {
 
82
  switch (ii->introduced ()->slice_type ()) {
 
83
  case JPL_ClassSlice::CS_OLD_BASE:
83
84
    _base.append (ii);
84
85
    break;
85
 
  case IntroductionInfo::INTRO_OTHER:
 
86
  case JPL_ClassSlice::CS_OLD_OTHER:
86
87
    _other.append (ii);
87
88
    break;
88
 
  case IntroductionInfo::INTRO_SLICE_REF: // slices might contribute new
89
 
  case IntroductionInfo::INTRO_SLICE_DECL: {// members and base classes
90
 
    CObjectInfo *obj = ii->object (0);
 
89
  case JPL_ClassSlice::CS_NORMAL: { // slices might contribute new members and base classes
 
90
    CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
91
91
    assert (obj && obj->Tree ());
92
92
    assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
93
93
    CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
97
97
      _other.append (ii);
98
98
    }
99
99
    break;
100
 
  case IntroductionInfo::INTRO_INHERITED:
101
 
    break;
102
 
  case IntroductionInfo::INTRO_ERROR:
 
100
  case JPL_ClassSlice::CS_ERROR:
103
101
    break;
104
102
  }
105
103
}
106
104
 
107
105
// consider an introduction in the plan for this class join point
108
 
bool JPP_Class::consider (IntroductionInfo *ii) {
109
 
  switch (ii->type ()) {
110
 
  case IntroductionInfo::INTRO_BASECLASS:
111
 
  case IntroductionInfo::INTRO_INHERITED:
112
 
  case IntroductionInfo::INTRO_OTHER:
113
 
  case IntroductionInfo::INTRO_SLICE_REF:
114
 
  case IntroductionInfo::INTRO_SLICE_DECL:
 
106
bool JPP_Class::consider (JPL_Introduction *ii) {
 
107
  switch (ii->introduced ()->slice_type ()) {
 
108
  case JPL_ClassSlice::CS_OLD_BASE:
 
109
  case JPL_ClassSlice::CS_OLD_OTHER:
 
110
  case JPL_ClassSlice::CS_NORMAL:
115
111
    _unsorted.append (ii);
116
112
    return true;
117
113
  default:
127
123
  for (int i = 0; i < items (); i++) {
128
124
    ACAspectInfo* ai = &item (i);
129
125
    for (int j = 0; j < _unsorted.length(); j++) {
130
 
      if (_unsorted[j] && (_unsorted[j]->aspect()->acnode() == ai)) {
 
126
      if (_unsorted[j] && (((TI_Aspect*)_unsorted[j]->parent()->transform_info ())->acnode() == ai)) {
131
127
        issue(_unsorted[j]);
132
128
        _unsorted[j] = 0;
133
129
      }
140
136
  return true;
141
137
}
142
138
 
143
 
string JPP_Class::gen_baseclass_list () const {
144
 
 
145
 
  // do nothing if there are no base classes to add
146
 
  if (_base.length () == 0)
147
 
    return "";
148
 
 
149
 
  ostringstream result;
150
 
  // fill the unit with a baseclass list
151
 
  for (int i = 0; i < _base.length (); i++) {
152
 
    IntroductionInfo *ii = _base.lookup (i);
153
 
    
154
 
    // generate the code for this entry
155
 
    if (i > 0) result << ", ";
156
 
 
157
 
    if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
158
 
        ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
159
 
      // slice-based base class intro
160
 
      CObjectInfo *obj = ii->object (0);
161
 
      assert (obj && obj->Tree ());
162
 
      assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
163
 
      CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
164
 
      CT_Intro *base = csd->base_clause ();
165
 
      for (int e = 1; e < base->Entries (); e++) // skip entry(0) -- the ':'
166
 
        result << base->Entry (e)->token ()->text () << " ";
167
 
    }
168
 
    else {
169
 
      // old-style base class intro with 'baseclass(virtual Bla)'
170
 
      // get all the needed information
171
 
      CProtection::Type prot = ii->object (0)->Protection ();
172
 
      bool virt = ii->object (0)->isVirtual ();
173
 
      CTypeInfo *type = ii->object (0)->FunctionInfo ()->
174
 
        Argument (0u)->TypeInfo ();
175
 
      
176
 
      if (virt) result << "virtual ";
177
 
      switch (prot) {
178
 
        case CProtection::PROT_PRIVATE:   result << "private "; break;
179
 
        case CProtection::PROT_PROTECTED: result << "protected "; break;
180
 
        case CProtection::PROT_PUBLIC:    result << "public "; break;
181
 
        default:
182
 
          assert (false);
183
 
      }
184
 
      result << *type;
185
 
    }
186
 
  }
187
 
  result << ends;
188
 
  return result.str ();
189
 
}
190
 
 
191
 
Unit *JPP_Class::gen_intro (ErrorStream &err, CStructure *target,
192
 
  LineDirectiveMgr &lmgr) const {
193
 
 
194
 
  // create the new unit
195
 
  IntroductionUnit *unit = 
196
 
    new IntroductionUnit ((Unit*)target->Tree ()->token ()->belonging_to ());
197
 
 
198
 
  // create a unit with the target class name
199
 
  ACUnit target_name (err);
200
 
  target_name << target->Name () << endu;
 
139
 
 
140
void JPP_Class::gen_intros (list<Unit*> &units, ErrorStream &err,
 
141
  CStructure *target, LineDirectiveMgr &lmgr, bool non_inline) const {
 
142
 
201
143
  // ... some unit for formatting
202
144
  ACUnit ws (err);
203
145
  ws << " " << endu;
204
146
    
205
 
  // at least on token is needed in the unit for 'move' (see below)
206
 
  unit->append (*((Token*)ws.first ())->duplicate ());
207
 
 
208
147
  // handle all intros
209
148
  for (int i = 0; i < otherIntros (); i++) {
210
 
    IntroductionInfo *ii = otherIntro (i);
 
149
    JPL_Introduction *ii = otherIntro (i);
211
150
    
212
 
    // ignore non-inline introductions here (for now)
213
 
    if (ii->prot () == CProtection::PROT_NONE)
214
 
      continue;
 
151
    // create the new unit
 
152
    IntroductionUnit *unit = 
 
153
      new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ());
 
154
    unit->intro (ii);
 
155
 
 
156
    // at least on token is needed in the unit for 'move' (see below)
 
157
    unit->append (*((Token*)ws.first ())->duplicate ());
215
158
 
216
159
    // TODO: member intros from slices are ignored here!
217
 
    if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
218
 
        ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
219
 
      CObjectInfo *obj = ii->object (0);
 
160
    if (ii->introduced ()->slice_type () == JPL_ClassSlice::CS_NORMAL) {
 
161
      CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
220
162
      assert (obj && obj->Tree ());
221
163
      assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
222
 
      CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
223
 
      // add "private:\n"
224
 
      ACUnit slice_start (err);
225
 
      if (ii->prot () == CProtection::PROT_PRIVATE)
226
 
        slice_start << "  private:" << endl;
 
164
      ACSliceInfo *acsi = obj->ClassDB ()->SliceInfo (obj)->definition ();
 
165
      if (non_inline)
 
166
        gen_intro_non_inline (unit, ii, acsi, err, lmgr, target);
227
167
      else
228
 
        slice_start << "  public:" << endl;
229
 
      // add "  typedef <target-name> <slice-name>;\n"
230
 
      if (!obj->isAnonymous ()) {
231
 
        slice_start << "  typedef " << target->Name () << " "
232
 
                    << obj->Name () << ";" << endl;
233
 
      }
234
 
      slice_start << endu;
235
 
      unit->move ((Token*)unit->last (), slice_start);
236
 
      // generate the intro itself from the stored pattern
237
 
      Token *curr = (Token*)ii->pattern ().first ();
238
 
      Location loc = curr->location ();
239
 
      ACUnit dir (err);
240
 
      lmgr.directive (dir, (Unit*)&ii->pattern (), curr);
241
 
      dir << endu;
242
 
      if (!dir.empty ())
243
 
        unit->move ((Token*)unit->last (), dir);
244
 
      for (int m = 0; m < csd->members ()->Entries (); m++) {
245
 
        Unit tmp_pattern;
246
 
        tmp_pattern.name (ii->pattern ().name ());
247
 
        CT_Intro *intro = (CT_Intro*)csd->members ()->Entry (m);
248
 
        for (int i = 0; i < intro->Entries (); i++) {
249
 
          tmp_pattern.append (*curr->duplicate ());
250
 
          curr = (Token*)ii->pattern ().next (curr);
251
 
        }
252
 
        instantiate_intro (err, unit, intro, tmp_pattern, target_name, loc);
253
 
      }
 
168
        gen_intro_inline (unit, ii, acsi, err, lmgr, target);
254
169
    }
255
 
    else {
256
 
      // add privat/public/protected
257
 
      ACUnit prot (err);
258
 
      prot << WeaverBase::protection_string (ii->prot ()) << "  " << endu;
259
 
      unit->move ((Token*)unit->last (), prot);
 
170
    else if ((ii->introduced ()->prot () == CProtection::PROT_NONE && non_inline) ||
 
171
              (ii->introduced ()->prot () != CProtection::PROT_NONE && !non_inline)) {
 
172
      if (!non_inline) {
 
173
        // add privat/public/protected
 
174
        ACUnit prot (err);
 
175
        prot << WeaverBase::protection_string (ii->introduced ()->prot ()) << "  " << endu;
 
176
        unit->move ((Token*)unit->last (), prot);
 
177
      }
260
178
      
261
179
      // obtain the pattern for this intro
262
 
      const Unit &pattern = ii->pattern ();
 
180
      const Unit &pattern = ii->introduced ()->pattern ();
263
181
  
264
 
      CT_Intro *intro = (CT_Intro*)ii->tree ()->Decl ();
265
 
      Token *curr = (Token*)ii->pattern ().first ();
 
182
      CT_Intro *intro = (CT_Intro*)TI_Introduction::of (*ii)->tree ()->Decl ();
 
183
      Token *curr = (Token*)ii->introduced ()->pattern ().first ();
266
184
      ACUnit dir (err);
267
185
      lmgr.directive (dir, (Unit*)&pattern, curr);
268
186
      dir << endu;
269
187
      if (!dir.empty ())
270
188
        unit->move ((Token*)unit->last (), dir);
271
189
      Location loc = ((Token*)pattern.first ())->location ();
272
 
      instantiate_intro (err, unit, intro, pattern, target_name, loc);
273
 
    }
274
 
  }
275
 
  return unit;
 
190
      instantiate_intro (err, unit, intro, pattern, target, loc);
 
191
    }
 
192
 
 
193
    // if there was no introduction return 0
 
194
    if (unit->first () == unit->last ())
 
195
      delete unit;
 
196
    else
 
197
      units.push_back (unit);
 
198
  }
 
199
}
 
200
 
 
201
 
 
202
void JPP_Class::gen_intro_inline (Unit *unit, JPL_Introduction *ii,
 
203
  ACSliceInfo *acsi, ErrorStream &err, LineDirectiveMgr &lmgr,
 
204
  CStructure *target) const {
 
205
  
 
206
  CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
 
207
  CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
 
208
  
 
209
  // add "private:\n"
 
210
  ACUnit slice_start (err);
 
211
  if (ii->introduced ()->prot () == CProtection::PROT_PRIVATE)
 
212
    slice_start << "  private:" << endl;
 
213
  else
 
214
    slice_start << "  public:" << endl;
 
215
  // add "  typedef <target-name> <slice-name>;\n"
 
216
  if (!obj->isAnonymous ()) {
 
217
    slice_start << "  typedef " << target->Name () << " "
 
218
                << obj->Name () << ";" << endl;
 
219
  }
 
220
  slice_start << endu;
 
221
  unit->move ((Token*)unit->last (), slice_start);
 
222
  // generate the intro itself from the stored pattern
 
223
  const Unit &pattern = *acsi->pattern ();
 
224
  Token *curr = (Token*)pattern.first ();
 
225
  Location loc = curr->location ();
 
226
  ACUnit dir (err);
 
227
  lmgr.directive (dir, (Unit*)&pattern, curr);
 
228
  dir << endu;
 
229
  if (!dir.empty ())
 
230
    unit->move ((Token*)unit->last (), dir);
 
231
  for (int m = 0; m < csd->members ()->Entries (); m++) {
 
232
    Unit tmp_pattern;
 
233
    tmp_pattern.name (pattern.name ());
 
234
    CT_Intro *intro = (CT_Intro*)csd->members ()->Entry (m);
 
235
    for (int i = 0; i < intro->Entries (); i++) {
 
236
      tmp_pattern.append (*curr->duplicate ());
 
237
      curr = (Token*)pattern.next (curr);
 
238
    }
 
239
    instantiate_intro (err, unit, intro, tmp_pattern, target, loc);
 
240
  }
 
241
}
 
242
 
 
243
void JPP_Class::gen_intro_non_inline (Unit *unit, JPL_Introduction *ii,
 
244
  ACSliceInfo *acsi, ErrorStream &err, LineDirectiveMgr &lmgr,
 
245
  CStructure *target) const {
 
246
  
 
247
  // generate the intros from the stored non-inline member patterns
 
248
  for (int m = 0; m < acsi->members (); m++) {
 
249
    CT_Intro *intro = acsi->member (m);
 
250
    const Unit &pattern = *acsi->member_pattern (m);
 
251
    Token *curr = (Token*)pattern.first ();
 
252
    Location loc = curr->location ();
 
253
    ACUnit dir (err);
 
254
    lmgr.directive (dir, (Unit*)&pattern, curr);
 
255
    dir << endu;
 
256
    if (!dir.empty ())
 
257
      unit->move ((Token*)unit->last (), dir);
 
258
    instantiate_intro (err, unit, intro, pattern, target, loc);
 
259
  }
 
260
}
 
261
 
 
262
 
 
263
void JPP_Class::gen_base_intro (IntroductionUnit &intro_unit,
 
264
  JPL_Introduction *ii, bool first) const {
 
265
 
 
266
  // generate the code for this entry
 
267
  intro_unit << (first ? ": " : ", ");
 
268
 
 
269
  if (ii->introduced ()->slice_type () == JPL_ClassSlice::CS_NORMAL) {
 
270
    // slice-based base class intro
 
271
    CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
 
272
    assert (obj && obj->Tree ());
 
273
    assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
 
274
    ACSliceInfo *acsi = obj->ClassDB ()->SliceInfo (obj)->definition ();
 
275
    const Unit &base = *acsi->base_pattern ();
 
276
    for (Token *curr = (Token*)base.first (); curr;
 
277
      curr = (Token*)base.next (curr)) {
 
278
      intro_unit << *curr << " ";
 
279
    }
 
280
  }
 
281
  else {
 
282
    // old-style base class intro with 'baseclass(virtual Bla)'
 
283
    // get all the needed information
 
284
    CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
 
285
    CProtection::Type prot = obj->Protection ();
 
286
    bool virt = obj->isVirtual ();
 
287
    CTypeInfo *type = obj->FunctionInfo ()->Argument (0u)->TypeInfo ();
 
288
      
 
289
    if (virt) intro_unit << "virtual ";
 
290
    switch (prot) {
 
291
      case CProtection::PROT_PRIVATE:   intro_unit << "private "; break;
 
292
      case CProtection::PROT_PROTECTED: intro_unit << "protected "; break;
 
293
      case CProtection::PROT_PUBLIC:    intro_unit << "public "; break;
 
294
      default:
 
295
        assert (false);
 
296
    }
 
297
    intro_unit << *type;
 
298
  }
 
299
  intro_unit << endu;
 
300
}
 
301
 
 
302
 
 
303
void JPP_Class::gen_base_intros (list<Unit*> &units, ErrorStream &err,
 
304
  CClassInfo *target, LineDirectiveMgr &lmgr) const {
 
305
 
 
306
  for (int i = 0; i < _base.length (); i++) {
 
307
    // get the current introduction
 
308
    JPL_Introduction *ii = _base.lookup (i);
 
309
 
 
310
    // create the new unit
 
311
    IntroductionUnit *unit = 
 
312
      new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ());
 
313
    unit->intro (ii);
 
314
 
 
315
    // generate the code for this base class introduction
 
316
    gen_base_intro (*unit, ii, (i == 0));
 
317
 
 
318
    // store the result for the caller
 
319
    units.push_back (unit);
 
320
  }
276
321
}
277
322
 
278
323
void JPP_Class::instantiate_intro (ErrorStream &err, Unit *unit,
279
 
  CT_Intro *intro, const Unit &pattern, Unit &target_name,
 
324
  CT_Intro *intro, const Unit &pattern, CStructure *target,
280
325
  Location &loc) const {
281
326
    
 
327
  // create a unit with the target class name
 
328
  ACUnit target_name (err);
 
329
  target_name << target->Name () << endu;
 
330
  ACUnit target_qual_name (err);
 
331
  target_qual_name << target->QualName () << endu;
 
332
 
282
333
  // ... some units for formatting
283
334
  ACUnit nl (err);
284
335
  nl << endl << endu;
299
350
      unit->append (*((Token*)ws.first ())->duplicate ());
300
351
    if (i < intro->NameIndices () && e == intro->NameIndex (i)) {
301
352
      // target class name is used instead of intro token
302
 
      tok = (Token*)target_name.first ();
 
353
      if (intro->NameQual (i))
 
354
        *unit += target_qual_name;
 
355
      else
 
356
        *unit += target_name;
 
357
      while (e < intro->NameToIndex (i)) {
 
358
        e++;
 
359
        curr = (Token*)pattern.next (curr);
 
360
      }
303
361
      i++;
304
362
    }
305
 
    unit->append (*tok->duplicate ());
 
363
    else
 
364
      unit->append (*tok->duplicate ());
306
365
  }
307
366
}