~ubuntu-branches/ubuntu/utopic/aspectc++/utopic

« back to all changes in this revision

Viewing changes to AspectC++/JoinPointPlan.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2006-04-07 11:56:35 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060407115635-e8wfgmetasrf2p27
Tags: 0.99+1.0pre3-1
* new upstream release
* Apply patch from Martin Michlmayr for g++-4.1 (Closes: #357901)
* further (simple) patches in Puma/ and AspectC++ for g++-4.1
* note that Puma needs to be rewoven so that it can be compiled
  with g++-4.1. This will be done we switch the default compiler
  version.
* Patch JoinPointRepo.cc so that it doesn't loop endlessly anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "IntroductionUnit.h"
23
23
#include "AspectInfo.h"
24
24
#include "WeaverBase.h"
 
25
#include "LineDirectiveMgr.h"
25
26
 
26
27
#include "Puma/CProtection.h"
27
28
#include "Puma/ErrorSink.h"
84
85
  case IntroductionInfo::INTRO_OTHER:
85
86
    _other.append (ii);
86
87
    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);
 
91
    assert (obj && obj->Tree ());
 
92
    assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
 
93
    CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
 
94
    if (csd->base_clause ())
 
95
      _base.append (ii);
 
96
    if (csd->members () && csd->members ()->Entries ())
 
97
      _other.append (ii);
 
98
    }
 
99
    break;
87
100
  case IntroductionInfo::INTRO_INHERITED:
88
101
    break;
89
102
  case IntroductionInfo::INTRO_ERROR:
95
108
bool JPP_Class::consider (IntroductionInfo *ii) {
96
109
  switch (ii->type ()) {
97
110
  case IntroductionInfo::INTRO_BASECLASS:
98
 
    break;
99
111
  case IntroductionInfo::INTRO_INHERITED:
100
 
    break;
101
112
  case IntroductionInfo::INTRO_OTHER:
102
 
    break;
 
113
  case IntroductionInfo::INTRO_SLICE_REF:
 
114
  case IntroductionInfo::INTRO_SLICE_DECL:
 
115
    _unsorted.append (ii);
 
116
    return true;
103
117
  default:
104
118
    return false;
105
119
  }
106
 
  _unsorted.append(ii);
107
 
  return true;
108
120
}
109
121
 
110
122
bool JPP_Class::check(ErrorSink &err) {
138
150
  // fill the unit with a baseclass list
139
151
  for (int i = 0; i < _base.length (); i++) {
140
152
    IntroductionInfo *ii = _base.lookup (i);
141
 
 
142
 
    // get all the needed information
143
 
    CProtection::Type prot = ii->object (0)->Protection ();
144
 
    bool virt = ii->object (0)->isVirtual ();
145
 
    CTypeInfo *type = ii->object (0)->FunctionInfo ()->
146
 
      Argument (0u)->TypeInfo ();
147
153
    
148
154
    // generate the code for this entry
149
155
    if (i > 0) result << ", ";
150
 
    if (virt) result << "virtual ";
151
 
    switch (prot) {
152
 
      case CProtection::PROT_PRIVATE:   result << "private "; break;
153
 
      case CProtection::PROT_PROTECTED: result << "protected "; break;
154
 
      case CProtection::PROT_PUBLIC:    result << "public "; break;
155
 
      default:
156
 
        assert (false);
157
 
    }
158
 
    result << *type;
 
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
    }
159
186
  }
160
187
  result << ends;
161
188
  return result.str ();
162
189
}
163
190
 
164
 
Unit *JPP_Class::gen_intro (ErrorStream &err, CStructure *target) const {
 
191
Unit *JPP_Class::gen_intro (ErrorStream &err, CStructure *target,
 
192
  LineDirectiveMgr &lmgr) const {
165
193
 
166
194
  // create the new unit
167
195
  IntroductionUnit *unit = 
171
199
  ACUnit target_name (err);
172
200
  target_name << target->Name () << endu;
173
201
  // ... some unit for formatting
174
 
  ACUnit nl (err);
175
 
  nl << endl << endu;
176
202
  ACUnit ws (err);
177
203
  ws << " " << endu;
178
204
    
187
213
    if (ii->prot () == CProtection::PROT_NONE)
188
214
      continue;
189
215
 
190
 
    // add privat/public/protected
191
 
    ACUnit prot (err);
192
 
    prot << WeaverBase::protection_string (ii->prot ()) << "  " << endu;
193
 
    unit->move ((Token*)unit->last (), prot);
194
 
    
195
 
    // obtain the pattern for this intro
196
 
    const Unit &pattern = ii->pattern ();
197
 
 
198
 
    CT_Intro *intro = (CT_Intro*)ii->tree ()->Decl ();
199
 
    int i = 0, e = 0;
200
 
    // create a formatted unit and replace the advice name with the target name
201
 
    for (Token *curr = (Token*)pattern.first (); curr;
202
 
         curr = (Token*)pattern.next (curr), e++) {
203
 
      Token *tok = curr;
204
 
      if (i < intro->NameIndices () && e == intro->NameIndex (i)) {
205
 
        // target class name is used instead of intro token
206
 
        tok = (Token*)target_name.first ();
207
 
        i++;
208
 
      }
209
 
      unit->append (*tok->duplicate ());
210
 
      if (tok->type () == TOK_OPEN_CURLY || tok->type () == TOK_SEMI_COLON)
211
 
        unit->append (*((Token*)nl.first ())->duplicate ());
 
216
    // 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);
 
220
      assert (obj && obj->Tree ());
 
221
      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;
212
227
      else
213
 
        unit->append (*((Token*)ws.first ())->duplicate ());
 
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
      }
 
254
    }
 
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);
 
260
      
 
261
      // obtain the pattern for this intro
 
262
      const Unit &pattern = ii->pattern ();
 
263
  
 
264
      CT_Intro *intro = (CT_Intro*)ii->tree ()->Decl ();
 
265
      Token *curr = (Token*)ii->pattern ().first ();
 
266
      ACUnit dir (err);
 
267
      lmgr.directive (dir, (Unit*)&pattern, curr);
 
268
      dir << endu;
 
269
      if (!dir.empty ())
 
270
        unit->move ((Token*)unit->last (), dir);
 
271
      Location loc = ((Token*)pattern.first ())->location ();
 
272
      instantiate_intro (err, unit, intro, pattern, target_name, loc);
214
273
    }
215
274
  }
216
275
  return unit;
217
276
}
218
277
 
 
278
void JPP_Class::instantiate_intro (ErrorStream &err, Unit *unit,
 
279
  CT_Intro *intro, const Unit &pattern, Unit &target_name,
 
280
  Location &loc) const {
 
281
    
 
282
  // ... some units for formatting
 
283
  ACUnit nl (err);
 
284
  nl << endl << endu;
 
285
  ACUnit ws (err);
 
286
  ws << " " << endu;
 
287
  
 
288
  int i = 0, e = 0;
 
289
  // create a formatted unit and replace the advice name with the target name
 
290
  for (Token *curr = (Token*)pattern.first (); curr;
 
291
       curr = (Token*)pattern.next (curr), e++) {
 
292
    Token *tok = curr;
 
293
    if (curr->location ().line () != loc.line ()) {
 
294
      for (int l = loc.line (); l < curr->location ().line (); l++)
 
295
        unit->append (*((Token*)nl.first ())->duplicate ());
 
296
      loc = curr->location ();
 
297
    }
 
298
    else
 
299
      unit->append (*((Token*)ws.first ())->duplicate ());
 
300
    if (i < intro->NameIndices () && e == intro->NameIndex (i)) {
 
301
      // target class name is used instead of intro token
 
302
      tok = (Token*)target_name.first ();
 
303
      i++;
 
304
    }
 
305
    unit->append (*tok->duplicate ());
 
306
  }
 
307
}