~ubuntu-branches/ubuntu/wily/aspectc++/wily

« back to all changes in this revision

Viewing changes to Puma/src/parser/acparser/ACIntroAnalyzer.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:
18
18
 
19
19
#include "Puma/ACIntroAnalyzer.h"
20
20
#include "Puma/CClassDatabase.h"
 
21
#include "Puma/CCNameLookup.h"
21
22
#include "Puma/CScopeInfo.h"
22
23
#include "Puma/CTokens.h"
23
24
#include <string.h>
24
25
 
25
26
namespace Puma {
26
27
 
27
 
CClassDatabase *_db;
28
 
CScopeInfo *_current_scope;
29
 
CT_Intro *_intro;
30
 
 
31
 
int ttype(int pos) {
 
28
int ACIntroAnalyzer::ttype(int pos) {
32
29
  return _intro->Entry (pos)->token ()->type ();
33
30
}
34
31
 
35
 
bool is_in (int tok, int *set) {
 
32
bool ACIntroAnalyzer::is_in (int tok, int *set) {
36
33
  while (*set) {
37
34
    if (*set == tok)
38
35
      return true;
41
38
  return false;
42
39
}
43
40
 
44
 
bool block (int &outer_pos, int open, int close) {
 
41
bool ACIntroAnalyzer::block (int &outer_pos, int open, int close) {
45
42
  if (ttype (outer_pos) != open)
46
43
    return false;
47
44
    
64
61
  return true;
65
62
}
66
63
 
67
 
bool skip (int &outer_pos, int *term) {
 
64
bool ACIntroAnalyzer::skip (int &outer_pos, int *term) {
68
65
  // save the current position
69
66
  int pos = outer_pos;
70
67
  int entries = _intro->Entries ();
88
85
}
89
86
 
90
87
 
91
 
bool constructor_args (int &outer_pos) {
 
88
bool ACIntroAnalyzer::constructor_args (int &outer_pos) {
92
89
  int pos = outer_pos;
93
90
  bool result = false;
94
91
  if (block (pos, TOK_OPEN_ROUND, TOK_CLOSE_ROUND) &&
108
105
}
109
106
 
110
107
 
111
 
bool nested_name (int &outer_pos, bool &is_declarator, bool is_decl_name = false) {
 
108
bool ACIntroAnalyzer::nested_name (int &outer_pos, bool &is_declarator,
 
109
  bool is_decl_name) {
 
110
 
112
111
  // save the current position
113
112
  int pos = outer_pos;
114
113
 
115
114
  // by default this name is not necessarily part of the declarator
116
115
  is_declarator = false;
117
116
  
 
117
  // scope is 0 at the beginning
 
118
  CScopeInfo *last_scope = 0;
 
119
  
118
120
  // root qualified name ("::" is optional)?
119
121
  bool root = false;
 
122
  CScopeInfo *lookup_scope = _current_scope;
 
123
  CScopeInfo *relevant_scope = 0;
120
124
  if (ttype (pos) == TOK_COLON_COLON) {
121
125
    pos++;
122
126
    root = true;
 
127
    while (!lookup_scope->GlobalScope ())
 
128
      lookup_scope = lookup_scope->Parent ();
 
129
    last_scope = lookup_scope;
123
130
  }
124
131
 
125
132
  int names = 0;
 
133
  int relevant_name_index = -1;
126
134
  bool is_destructor = false;
127
 
  bool is_in_aspect  = false;
128
135
  bool done;
129
136
  do {
130
137
    done = true;
142
149
      is_destructor = true;
143
150
    }
144
151
    else if (tok == TOK_ID) {
 
152
      ErrorStream err;
 
153
      CCNameLookup nl (err);
 
154
      nl.lookup (_intro->Entry (pos)->token ()->text (),
 
155
        lookup_scope->Structure (), !last_scope);
 
156
      CObjectInfo *obj = nl.Objects () ? nl.Object (0) : (CObjectInfo*)0;
 
157
      if (obj && obj->ScopeInfo ()) {
 
158
        if (!relevant_scope && ((_is_slice && _db->SliceInfo (obj)) ||
 
159
            (!_is_slice && is_decl_name && obj->ClassInfo () &&
 
160
            _db->AspectInfo (obj->ClassInfo ())))) {
 
161
          relevant_scope = obj->ScopeInfo ();
 
162
          relevant_name_index = pos;
 
163
        }
 
164
      }
145
165
      names++;
146
166
      pos++;
147
167
      tok = ttype (pos);
148
168
      if (tok == TOK_COLON_COLON) {
149
 
        if (names == 1 && is_decl_name &&
150
 
            _db->AspectInfo (_intro->Entry (pos - 1)->token ()->text ())) {
151
 
          _intro->AddNameIndex (pos - 1);
152
 
          is_in_aspect = true;
 
169
        if (obj && obj->ScopeInfo ()) {
 
170
          lookup_scope = obj->ScopeInfo ();
 
171
          last_scope = lookup_scope;
153
172
        }
154
173
        done = false;
155
174
        pos++;
165
184
      return true;
166
185
    }
167
186
  } while (!done && pos < _intro->Entries ());
168
 
  
169
 
  if (!root && pos >= 1 && names == 1 && _current_scope->ClassInfo () &&
170
 
    strcmp (_current_scope->Name (),
171
 
            _intro->Entry (pos - 1)->token ()->text ()) == 0) {
172
 
    int name_pos = pos - 1;
173
 
    if (constructor_args (pos)) {
174
 
      is_declarator = true;
175
 
      // store the detected name in the CT_Intro object
176
 
      if (is_decl_name) {
177
 
        _intro->AddNameIndex (name_pos);
178
 
      }
179
 
    }
180
 
  }   
181
 
  // qualified constructor name?
182
 
  else if (pos >= 3 && names >= 2 && !_current_scope->ClassInfo () &&
183
 
           strcmp (_intro->Entry (pos - 1)->token ()->text (),
184
 
                   _intro->Entry (pos - 3)->token ()->text ()) == 0) {
185
 
    is_declarator = true;
186
 
    // store the detected name in the CT_Intro object
187
 
    if (is_decl_name && names == 2) {
188
 
      _intro->AddNameIndex (pos - 1);
189
 
    }
190
 
  }
191
 
  // qualified destructor name?
192
 
  else if (pos >= 4 && names >= 2 && !_current_scope->ClassInfo () &&
193
 
           is_destructor &&
194
 
           strcmp (_intro->Entry (pos - 1)->token ()->text (),
195
 
                   _intro->Entry (pos - 4)->token ()->text ()) == 0) {
196
 
    is_declarator = true;
197
 
    // store the detected name in the CT_Intro object
198
 
    if (is_decl_name && names == 2) {
199
 
      _intro->AddNameIndex (pos - 1);
200
 
    }
201
 
  }
202
 
  else
203
 
    is_declarator = false;
204
187
 
 
188
  if (relevant_name_index >= 0) {  
 
189
    _intro->AddNameIndex (outer_pos, relevant_name_index);
 
190
  }
 
191
  
 
192
  // a special name?
 
193
  if (names >= 2) {
 
194
    // qualified constructor name?
 
195
    const DString &last_name = _intro->Entry (pos - 1)->token ()->text ();
 
196
    if (last_name == _intro->Entry (pos - 3)->token ()->text ()) {
 
197
      is_declarator = true;
 
198
    }
 
199
    // qualified destructor name?
 
200
    else if (is_destructor &&
 
201
             last_name == _intro->Entry (pos - 4)->token ()->text ()) {
 
202
      is_declarator = true;
 
203
    }
 
204
    if (is_declarator && is_decl_name &&
 
205
      relevant_scope && last_name == relevant_scope->Name ()) {
 
206
        // store the detected name in the CT_Intro object
 
207
        _intro->AddNameIndex (pos - 1);
 
208
    }
 
209
  }
 
210
  
205
211
  if (is_destructor)
206
212
    is_declarator = true;
207
213
    
208
 
  if (names && !(!is_decl_name && is_declarator))
 
214
  if (names && !(!is_decl_name && is_declarator)) {
 
215
    if (relevant_scope) {
 
216
      if (_intro->Scope () && relevant_scope != _intro->Scope ())
 
217
        return false;
 
218
      _intro->Scope (relevant_scope->Structure ());
 
219
    }
 
220
    
209
221
    outer_pos = pos;
 
222
  }
210
223
  return (names > 0);
211
224
}
212
225
 
213
226
 
214
 
bool ptr_operator (int &outer_pos) {
 
227
bool ACIntroAnalyzer::ptr_operator (int &outer_pos) {
215
228
  // save the current position
216
229
  int pos = outer_pos;
217
230
 
253
266
  return true;
254
267
}
255
268
 
256
 
bool declarator (int &outer_pos) {
 
269
bool ACIntroAnalyzer::declarator (int &outer_pos) {
257
270
  int term[] = { TOK_COMMA, TOK_ASSIGN, TOK_OPEN_CURLY, TOK_SEMI_COLON,
258
271
                 TOK_CLOSE_ROUND, 0 };
259
272
  // save the current position
285
298
  return true;
286
299
}
287
300
 
288
 
bool init_declarator (int &outer_pos) {
 
301
bool ACIntroAnalyzer::init_declarator (int &outer_pos) {
289
302
  // save the current position
290
303
  int pos = outer_pos;
291
304
 
302
315
  return true;
303
316
}
304
317
 
305
 
void ACIntroAnalyzer::analyze (CClassDatabase *db, CScopeInfo *current_scope,
306
 
  CT_Intro *intro) {
 
318
const char *ACIntroAnalyzer::error_msg () const {
 
319
  switch (_state) {
 
320
    case IA_OK:              return "no error in introduction";
 
321
    case IA_UNDEFINED:       return "introduction not analyzed";
 
322
    case IA_INVALID:         return "invalid introduction";
 
323
    case IA_INV_SCOPE:       return "introduction definition not in aspect scope";
 
324
    case IA_INV_SLICE:       return "invalid slice declaration";
 
325
    case IA_INV_DESTR:       return "invalid destructor name";
 
326
    case IA_SLICE_IN_SLICE:  return "slice in slice definition";
 
327
    case IA_ASPECT_IN_SLICE: return "aspect in slice definition";
 
328
    case IA_ADVICE_IN_SLICE: return "advice in slice definition";
 
329
    case IA_PCT_IN_SLICE:    return "pointcut in slice definition";
 
330
  }
 
331
  return 0;
 
332
}
 
333
 
 
334
 
 
335
void ACIntroAnalyzer::analyze_intro_member (CT_Intro *intro) {
 
336
  _intro = intro;
 
337
  
 
338
  int pos;
 
339
  _state = IA_OK;
 
340
  
 
341
  // check for constructor
 
342
  pos = 0;
 
343
  if (ttype (pos) == TOK_EXPLICIT)
 
344
    pos++;
 
345
  if (ttype (pos) == TOK_ID &&
 
346
    _intro->Entry (pos)->token ()->text () == _current_scope->Name ()) {
 
347
     int name_pos = pos;
 
348
     pos++;
 
349
     if (constructor_args (pos)) {
 
350
       _intro->AddNameIndex (name_pos);
 
351
     }
 
352
  }
 
353
 
 
354
  // check for destructor
 
355
  pos = 0;
 
356
  if (ttype (pos) == TOK_VIRTUAL)
 
357
    pos++;
 
358
  if (ttype (pos) == TOK_TILDE) {
 
359
    pos++;
 
360
    if (ttype (pos) == TOK_ID &&
 
361
      _intro->Entry (pos)->token ()->text () == _current_scope->Name ()) {
 
362
      int name_pos = pos;
 
363
      pos++;
 
364
      if (ttype (pos) == TOK_OPEN_ROUND && ttype (pos + 1) == TOK_CLOSE_ROUND) {
 
365
        _intro->AddNameIndex (name_pos);
 
366
      }
 
367
    }
 
368
    else {
 
369
      _state = IA_INV_DESTR;
 
370
    }
 
371
  }
 
372
  
 
373
  // check for errors
 
374
  for (pos = 0; pos < _intro->Entries () && _state == IA_OK; pos++) {
 
375
    int tok = ttype (pos);
 
376
    if (tok == TOK_SLICE)
 
377
      _state = IA_SLICE_IN_SLICE;
 
378
    else if (tok == TOK_ASPECT)
 
379
      _state = IA_ASPECT_IN_SLICE;
 
380
    else if (tok == TOK_ADVICE)
 
381
      _state = IA_ADVICE_IN_SLICE;
 
382
    else if (tok == TOK_POINTCUT)
 
383
      _state = IA_PCT_IN_SLICE;
 
384
  }
 
385
}
 
386
 
 
387
void ACIntroAnalyzer::analyze_intro (CT_Intro *intro) {
307
388
 
308
389
  // should become attributes
309
 
  _db = db;
310
 
  _current_scope = current_scope;
311
390
  _intro = intro;
312
 
  
 
391
  _is_slice = (intro->token ()->type () == TOK_SLICE);
 
392
 
313
393
  _state = IA_INVALID;
314
 
  _scope = 0;
315
 
  
 
394
  _intro->Scope (0);
 
395
 
316
396
  // skip the declaration specifier sequence
317
397
  int pos = 0;
318
398
  bool have_type = false;
324
404
      // if we already have a type, this name belongs to the declarator
325
405
      if (have_type || special) {
326
406
        pos = saved_pos;
 
407
        intro->RollbackNameIndex (pos);
327
408
        break;
328
409
      }
329
410
      have_type = true;
391
472
    return;
392
473
  }
393
474
 
394
 
  // first case: we are in an aspect body
395
 
  if (current_scope->ClassInfo ()) {
396
 
    _scope = db->AspectInfo (current_scope->ClassInfo ());
397
 
  }
398
 
  else if (current_scope->GlobalScope () &&
399
 
           _intro->NameIndices () > 0) {
400
 
    // second case: a non-inline introduction defined in global scope
401
 
    int index = _intro->NameIndex (0);
402
 
    _scope = _db->AspectInfo (_intro->Entry (index)->token ()->text ());
403
 
  }
404
 
 
405
475
  //if we were able to determine the scope, the result is valid
406
 
  if (_scope) {
407
 
//    cout << "INTRO" << endl;
 
476
//  cout << "slice: " << _intro->token ()->location () << endl;
 
477
  if (_intro->Scope ()) {
 
478
//    cout << "  ";
408
479
//    for (int e = 0; e < _intro->Entries (); e++)
409
480
//      cout << _intro->Entry (e)->token ()->text () << " ";
410
481
//    cout << endl;
411
 
//    for (int i = 0; i < _intro->NameIndices (); i++)
412
 
//      cout << _intro->NameIndex (i) << " ";
 
482
//    cout << "  => indices: ";
 
483
//    for (int i = 0; i < _intro->NameIndices (); i++) {
 
484
//      cout << "(" << _intro->NameIndex (i) << "," << _intro->NameToIndex (i);
 
485
//      if (_intro->NameQual (i))
 
486
//        cout << " qual";
 
487
//      cout << ") ";
 
488
//    }
413
489
//    cout << endl;
 
490
//    cout << "  => scope: " << _intro->Scope ()->QualName () << endl;
414
491
    _state = IA_OK;
415
492
  }
416
493
  else