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

« back to all changes in this revision

Viewing changes to Puma/src/aspects/ExtAC.ah

  • 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:
19
19
#ifndef __ext_ac_ah__
20
20
#define __ext_ac_ah__
21
21
 
 
22
#include <string.h>
 
23
 
22
24
#include "Puma/ACTree.h"
23
25
#include "Puma/CTokens.h"
24
26
#include "Puma/ACClassDatabase.h"
40
42
 
41
43
#include <string.h>
42
44
 
43
 
using namespace Puma;
44
45
 
45
46
aspect ExtAC {
46
47
  // used to enable and disable this extension at runtime
55
56
  pointcut parser () = "Puma::Parser";
56
57
  advice derived (parser ()) && !parser (): slice class {
57
58
  public:
58
 
    void introducer (ACIntroducer *i) { semantic ()._introducer = i; }
59
 
    ACIntroducer *introducer () const { return semantic ()._introducer; }
 
59
    void introducer (Puma::ACIntroducer *i) { semantic ()._introducer = i; }
 
60
    Puma::ACIntroducer *introducer () const { return semantic ()._introducer; }
60
61
  };
61
62
 
62
63
  // *****************
65
66
 
66
67
  // introduce AC extensions
67
68
  pointcut cclassdb ()  = "Puma::CClassDatabase";
68
 
  advice cclassdb () : slice class : public ACClassDatabase;
 
69
  advice cclassdb () : slice class : public Puma::ACClassDatabase;
69
70
  
70
71
  // add behavioral extensions
71
72
  advice within (cclassdb ()) && execution ("% ...::Dump(%,int)") : before () {
72
 
    tjp->that ()->ACClassDatabase::Dump (*tjp->arg<0>(), *tjp->arg<1>());
 
73
    tjp->that ()->Puma::ACClassDatabase::Dump (*tjp->arg<0>(), *tjp->arg<1>());
73
74
  }
74
75
 
75
76
  // ***************************
78
79
 
79
80
  pointcut csemantic () = "Puma::CSemantic";
80
81
 
81
 
  advice csemantic () : slice class ACSemantic {
 
82
  advice csemantic () : slice class Puma::ACSemantic {
82
83
  public:
83
 
    ACIntroducer *_introducer;
 
84
    Puma::ACIntroducer *_introducer;
84
85
  private:
85
86
    bool _in_advice_decl;
86
87
    bool _in_pointcut_decl;
87
 
    Syntax::State _at_end_of_advice_decl;
88
 
    CStructure *_saved_scope;
 
88
    Puma::Syntax::State _at_end_of_advice_decl;
 
89
    Puma::CStructure *_saved_scope;
89
90
 
90
91
    // post processing of introduce function
91
 
    void introduce_function_post (CObjectInfo *, CTree *);
92
 
    void introduce_class_post (CT_ClassDef *cd);
93
 
    void add_base_classes_post (CTree *cs);
 
92
    void introduce_function_post (Puma::CObjectInfo *, Puma::CTree *);
 
93
    virtual void introduce_class_post (Puma::CT_ClassDef *cd);
 
94
    void add_base_classes_post (Puma::CT_ClassDef *cs);
94
95
  
95
96
  public:
96
97
    // new introduce functions (called from Syntax)
97
 
    virtual CTree *introduce_pointcut ();
98
 
    virtual CTree *introduce_class_slice ();
99
 
    virtual CTree *introduce_class_slice_member ();
100
 
    virtual CTree *introduce_member_advice ();
101
 
    virtual CTree *introduce_advice () { return introduce_member_advice (); }
 
98
    virtual Puma::CTree *introduce_pointcut ();
 
99
    virtual Puma::CTree *introduce_class_slice ();
 
100
    virtual Puma::CTree *introduce_class_slice_member ();
 
101
    virtual Puma::CTree *introduce_member_advice ();
 
102
    virtual Puma::CTree *introduce_advice () { return introduce_member_advice (); }
102
103
 
103
104
    // check an introduction if it makes sense
104
 
    void check_intro (CT_ObjDecl *od);
 
105
    void check_intro (Puma::CT_ObjDecl *od);
105
106
 
106
107
    // change or get semantic state information
107
108
    void enter_advice_decl () { _in_advice_decl = true; }
112
113
    void leave_pointcut_expr ();
113
114
  };
114
115
 
 
116
  pointcut ccsemantic () = "Puma::CCSemantic";
 
117
 
 
118
  advice ccsemantic () : slice class Puma::ACCSemantic {
 
119
  private:
 
120
    virtual void introduce_class_post (Puma::CT_ClassDef *cd);
 
121
  };
 
122
  
115
123
  // initialize introduced attributes
116
124
  advice construction (csemantic ()) : after () {
117
125
    tjp->that ()->_in_advice_decl   = false;
124
132
    execution ("Puma::CTree * ...::introduce_function ()") : around () {
125
133
     
126
134
    // first save the current function
127
 
    CObjectInfo *func = tjp->that ()->current_fct;
 
135
    Puma::CObjectInfo *func = tjp->that ()->current_fct;
128
136
    
129
137
    // now do the original stuff
130
138
    tjp->proceed ();
131
 
    CTree *node = *tjp->result ();
 
139
    Puma::CTree *node = *tjp->result ();
132
140
    if (!node)
133
141
      return;
134
142
 
148
156
  // extend member handling
149
157
  advice within (derived (csemantic ())) &&
150
158
    execution ("% ...::introduce_member(...)") : after () {
151
 
    CTree *node = *tjp->result ();
152
 
    if (!node || node->NodeName () != CT_InitDeclarator::NodeId ())
 
159
    Puma::CTree *node = *tjp->result ();
 
160
    if (!node || node->NodeName () != Puma::CT_InitDeclarator::NodeId ())
153
161
      return;
154
162
 
155
 
    CObjectInfo *object = ((CT_InitDeclarator *)node)->Object ();
 
163
    Puma::CObjectInfo *object = ((Puma::CT_InitDeclarator *)node)->Object ();
156
164
    if (tjp->that ()->_in_pointcut_decl && object->FunctionInfo ()) {
157
165
      // setup the scope for the following pointcut expression
158
166
      tjp->that ()->current_scope = object->FunctionInfo ();
174
182
  // extend object handling
175
183
  advice within (derived (csemantic ())) &&
176
184
    execution ("% ...::introduce_object(...)") : after () {
177
 
    CTree *node = *tjp->result ();
178
 
    if (! node || node->NodeName () != CT_InitDeclarator::NodeId ()) 
 
185
    Puma::CTree *node = *tjp->result ();
 
186
    if (! node || node->NodeName () != Puma::CT_InitDeclarator::NodeId ()) 
179
187
      return;
180
188
 
181
 
    CObjectInfo *object = ((CT_InitDeclarator *)node)->Object ();
 
189
    Puma::CObjectInfo *object = ((Puma::CT_InitDeclarator *)node)->Object ();
182
190
    if (tjp->that ()->_in_pointcut_decl && object->FunctionInfo ()) {
183
191
      // setup the scope for the following pointcut expression
184
192
// TEMPORARY
202
210
  // extend the class handling  
203
211
  advice within (derived (csemantic ())) &&
204
212
    execution ("% ...::introduce_class(...)") : after () {
205
 
    CT_ClassDef *cd = (CT_ClassDef*)*tjp->result ();
 
213
    Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)*tjp->result ();
206
214
    if (!cd)
207
215
      return;
208
216
    tjp->that ()->introduce_class_post (cd);
209
 
 
210
 
    if (tjp->that ()->_introducer) {
211
 
      // handle introductions before a class, they shall be parsed in global scope
212
 
      CStructure *saved_scope = tjp->that ()->current_scope;
213
 
      tjp->that ()->current_scope = tjp->that ()->_db->FileInfo (0);
214
 
//    _protection.push (CProtection::PROT_NONE);
215
 
//    _in_extern_decl.push (0);
216
 
      tjp->that ()->_introducer->class_before (cd);
217
 
//    _in_extern_decl.pop ();
218
 
//    _protection.pop ();
219
 
      tjp->that ()->current_scope = saved_scope;
220
 
    }
221
217
  }
222
218
 
223
219
  // extend the class handling  
224
 
  advice within (derived (csemantic ())) &&
225
 
    execution ("% ...::class_spec(...)") : before () {
 
220
//  advice within (derived (csemantic ())) &&
 
221
//    execution ("% ...::class_spec(...)") : before () {
 
222
//    if (tjp->that ()->_introducer) {
 
223
//      Puma::CT_ClassDef *cd =
 
224
//        (Puma::CT_ClassDef*)tjp->that ()->current_scope->Structure ()->Tree ();
 
225
//      Puma::Builder &builder = tjp->that ()->builder ();
 
226
//      tjp->that ()->_introducer->class_end (cd,
 
227
//        builder.get_node (builder.nodes () - 1));
 
228
//    }
 
229
//  }
 
230
  advice call ("% ...::leave_class_def()") &&
 
231
    within ("Puma::CTree *Puma::CCSemantic::class_spec()") : before () {
226
232
    if (tjp->that ()->_introducer) {
227
 
      CT_ClassDef *cd =
228
 
        (CT_ClassDef*)tjp->that ()->current_scope->Structure ()->Tree ();
229
 
      Builder &builder = tjp->that ()->builder ();
230
 
      tjp->that ()->_introducer->class_end (cd,
231
 
        builder.get_node (builder.nodes () - 1));
 
233
      Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)
 
234
        tjp->that ()->current_scope->Structure ()->Tree ();
 
235
      tjp->that ()->_introducer->class_end (cd);
232
236
    }
233
237
  }
234
 
 
 
238
  
235
239
  // perform an additional check on base classes with aspects
236
240
  advice within (derived (csemantic ())) &&
237
241
    execution ("% ...::add_base_classes(...)") : after () {
238
242
 
239
243
    // obtain the first argument
240
 
    CTree *cs = *tjp->arg<0>();
 
244
    Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)*tjp->arg<0>();
241
245
    
 
246
    // if necessary introduce base classes here
 
247
    if (tjp->that ()->_introducer) {
 
248
      tjp->that ()->_introducer->base_clause_end (cd,
 
249
        tjp->that ()->syntax ().provider ()->current ());
 
250
    }
 
251
 
 
252
    // semantically handle introduced base classes
 
253
    Puma::CT_BaseSpecList *bl = (Puma::CT_BaseSpecList*)cd->BaseIntros ();
 
254
    if (cd->Object () && bl) {
 
255
      int num = bl->Entries ();
 
256
      for (int i = 0; i < num; i++)
 
257
        tjp->that ()->addBaseClass (cd->Object ()->ClassInfo (),
 
258
          (Puma::CT_BaseSpec*)bl->Entry (i));
 
259
    }
 
260
 
242
261
    // handle it
243
 
    tjp->that ()->add_base_classes_post (cs);
244
 
  }
 
262
    tjp->that ()->add_base_classes_post (cd);
 
263
  }
 
264
 
 
265
  // extend the translation unit handling -> finalization
 
266
  advice within (derived (csemantic ())) &&
 
267
    execution ("% ...::trans_unit(...)") : after () {
 
268
    if (tjp->that ()->_introducer) {
 
269
      tjp->that ()->_introducer->trans_unit_end ((Puma::CT_Program*)*tjp->result ());
 
270
    }
 
271
  }
 
272
 
245
273
};
246
274
 
247
275
 
250
278
// ***************************
251
279
 
252
280
slice void ExtAC::ACSemantic::introduce_function_post (
253
 
  CObjectInfo *func, CTree *node) {
 
281
  Puma::CObjectInfo *func, Puma::CTree *node) {
254
282
    
255
283
  // check for an advice definition
256
 
  if (_in_advice_decl && node->NodeName () == CT_FctDeclarator::NodeId ()) {
 
284
  if (_in_advice_decl && node->NodeName () == Puma::CT_FctDeclarator::NodeId ()) {
257
285
    bool is_advice = (strcmp (func->Name (), "before") == 0 ||
258
286
                      strcmp (func->Name (), "after")  == 0 ||
259
287
                      strcmp (func->Name (), "around") == 0);
260
288
    if (is_advice) {
261
 
      CClassInfo   *ci = func->Scope ()->ClassInfo ();
262
 
      ACAspectInfo *ai = ((ACClassDatabase*)_db)->AspectInfo (ci);
 
289
      Puma::CClassInfo   *ci = func->Scope ()->ClassInfo ();
 
290
      Puma::ACAspectInfo *ai = ((Puma::ACClassDatabase*)_db)->AspectInfo (ci);
263
291
      if (ai) {
264
292
        std::ostringstream new_name;
265
 
        new_name << "%a" << ai->AdviceCount () << "_" << func->Name ()
266
 
                 << std::ends;
 
293
        new_name << "%a" << ai->AdviceCount () << "_" << func->Name ();
267
294
        func->Name (new_name.str ().c_str ());
268
295
      }
269
296
    }
273
300
  if (func->FunctionInfo () && func->Scope ()->ClassInfo () && 
274
301
      (strcmp (func->Name (), "aspectOf") == 0 ||
275
302
       strcmp (func->Name (), "aspectof") == 0)) {
276
 
    CFunctionInfo *aofunc = (CFunctionInfo*)func;
277
 
    ACAspectInfo *ai = _db->AspectInfo (aofunc->Scope ()->ClassInfo ());
278
 
    if (ai->aspect_of () &&
279
 
        strcmp (ai->aspect_of ()->Name (), func->Name ()) == 0)
280
 
      SEM_ERROR (node, "too many aspectof functions");
281
 
    if (aofunc->Arguments () != 0 || !aofunc->isStaticMethod ())
282
 
      SEM_ERROR (node, "invalid signature of aspectof");
283
 
    ai->aspect_of (aofunc);
284
 
  }
285
 
}
286
 
 
287
 
slice void ExtAC::ACSemantic::introduce_class_post (
288
 
  CT_ClassDef *cd) {
 
303
    Puma::CFunctionInfo *aofunc = (Puma::CFunctionInfo*)func;
 
304
    Puma::ACAspectInfo *ai = _db->AspectInfo (aofunc->Scope ()->ClassInfo ());
 
305
    if (ai) {
 
306
      if (ai->aspect_of () &&
 
307
          strcmp (ai->aspect_of ()->Name (), func->Name ()) == 0)
 
308
        SEM_ERROR (node, "too many aspectof functions");
 
309
      if (aofunc->Arguments () != 0 || !aofunc->isStaticMethod ())
 
310
        SEM_ERROR (node, "invalid signature of aspectof");
 
311
      ai->aspect_of (aofunc);
 
312
    }
 
313
  }
 
314
}
 
315
 
 
316
slice void ExtAC::ACSemantic::introduce_class_post (Puma::CT_ClassDef *cd) {
 
317
 
 
318
  if (_introducer) {
 
319
    // handle introductions before a class, they shall be parsed in global scope
 
320
    Puma::CStructure *saved_scope = current_scope;
 
321
    current_scope = _db->FileInfo (0);
 
322
    _introducer->class_before (cd);
 
323
    current_scope = saved_scope;
 
324
  }
 
325
 
 
326
  if (cd->token ()->type () == Puma::TOK_ASPECT) {
 
327
    Puma::CClassInfo *ci = cd->Object ()->ClassInfo ();
 
328
 
 
329
    _db->new_aspect (ci);
 
330
 
 
331
    if (! ci->Scope ()->ScopeInfo ()->GlobalScope ())
 
332
      SEM_ERROR (cd, "aspects must be in global scope");
 
333
  }
 
334
}
 
335
 
 
336
slice void ExtAC::ACCSemantic::introduce_class_post (CT_ClassDef *cd) {
289
337
   
290
 
  if (cd->token ()->type () == TOK_ASPECT) {
291
 
    CClassInfo *ci = cd->Object ()->ClassInfo ();
 
338
  if (_introducer) {
 
339
    // handle introductions before a class, they shall be parsed in global scope
 
340
    Puma::CStructure *saved_scope = current_scope;
 
341
    current_scope = _db->FileInfo (0);
 
342
    _protection.push (Puma::CProtection::PROT_NONE);
 
343
    _in_extern_decl.push (0);
 
344
    _in_class_def.push (false);
 
345
    _introducer->class_before (cd);
 
346
    _in_class_def.pop ();
 
347
    _in_extern_decl.pop ();
 
348
    _protection.pop ();
 
349
    current_scope = saved_scope;
 
350
  }
 
351
 
 
352
  if (cd->token ()->type () == Puma::TOK_ASPECT) {
 
353
    Puma::CClassInfo *ci = cd->Object ()->ClassInfo ();
292
354
 
293
355
    _db->new_aspect (ci);
294
356
 
297
359
  }
298
360
}
299
361
 
300
 
slice void ExtAC::ACSemantic::add_base_classes_post (CTree *cs) {
 
362
slice void ExtAC::ACSemantic::add_base_classes_post (Puma::CT_ClassDef *cs) {
301
363
 
302
 
  if (cs && cs->token ()->type () == TOK_ASPECT && cs->SemObject () && 
 
364
  // check base classes of aspects
 
365
  if (cs && cs->token ()->type () == Puma::TOK_ASPECT && cs->SemObject () && 
303
366
      cs->SemObject ()->Object ()) {
304
 
    CClassInfo *ci = cs->SemObject ()->Object ()->ClassInfo ();
 
367
    Puma::CClassInfo *ci = cs->SemObject ()->Object ()->ClassInfo ();
305
368
    if (! ci) // ???
306
369
      return;
307
370
    
308
371
    for (unsigned int b = 0; b < ci->BaseClasses (); b++) {
309
 
      CClassInfo *bci = ci->BaseClass (b)->Class ();
 
372
      Puma::CClassInfo *bci = ci->BaseClass (b)->Class ();
310
373
 
311
374
      // check if the base class is an aspect
312
 
      ACAspectInfo *bai = ((ACClassDatabase*)_db)->AspectInfo (bci);
 
375
      Puma::ACAspectInfo *bai = ((Puma::ACClassDatabase*)_db)->AspectInfo (bci);
313
376
      // normal classes are ignored here
314
377
      if (! bai) continue;
315
378
 
316
379
      // it is an error if the base aspect is not abstract
317
380
      if (! bai->is_abstract ()) {
318
 
        *_err << sev_error << cs->token ()->location ()
 
381
        *_err << Puma::sev_error << cs->token ()->location ()
319
382
                     << "base aspect '" << bai->name () << "' is not abstract"
320
 
              << endMessage;
 
383
              << Puma::endMessage;
321
384
        continue;
322
385
      }
323
386
    }
324
387
  }
325
388
}
326
389
 
327
 
slice CTree *ExtAC::ACSemantic::introduce_pointcut () {
328
 
  CT_PointcutDecl *pcd = (CT_PointcutDecl*) builder ().pointcut_decl ();
 
390
slice Puma::CTree *ExtAC::ACSemantic::introduce_pointcut () {
 
391
  Puma::CT_PointcutDecl *pcd = (Puma::CT_PointcutDecl*) builder ().pointcut_decl ();
329
392
  
330
393
  // handle pointcuts only if there is a valid ObjDecl node
331
394
  if (pcd && pcd->Decl () && 
332
 
      pcd->Decl ()->NodeName () == CT_ObjDecl::NodeId () &&
 
395
      pcd->Decl ()->NodeName () == Puma::CT_ObjDecl::NodeId () &&
333
396
      pcd->Decl ()->Son (0) &&
334
 
      pcd->Decl ()->Son (0)->NodeName () == CT_DeclSpecSeq::NodeId () &&
 
397
      pcd->Decl ()->Son (0)->NodeName () == Puma::CT_DeclSpecSeq::NodeId () &&
335
398
      pcd->Decl ()->Son (1) &&
336
 
      pcd->Decl ()->Son (1)->NodeName () == CT_DeclaratorList::NodeId ()) {
 
399
      pcd->Decl ()->Son (1)->NodeName () == Puma::CT_DeclaratorList::NodeId ()) {
337
400
    // handle the declaration specifier list. This must be 'virtual' or empty.
338
401
    // Empty is represented by an implicit INT node (no token).
339
 
    CT_DeclSpecSeq *dss = ((CT_ObjDecl*)pcd->Decl ())->DeclSpecs ();
 
402
    Puma::CT_DeclSpecSeq *dss = ((Puma::CT_ObjDecl*)pcd->Decl ())->DeclSpecs ();
340
403
    if (dss->Entries () > 0) {
341
404
      if (!(dss->Entries () == 1 &&
342
 
            dss->Entry (0)->NodeName () == CT_PrimDeclSpec::NodeId () &&
343
 
            (((CT_PrimDeclSpec*)dss->Entry (0))->SpecType () ==
344
 
             CT_PrimDeclSpec::PDS_VIRTUAL ||
 
405
            dss->Entry (0)->NodeName () == Puma::CT_PrimDeclSpec::NodeId () &&
 
406
            (((Puma::CT_PrimDeclSpec*)dss->Entry (0))->SpecType () ==
 
407
             Puma::CT_PrimDeclSpec::PDS_VIRTUAL ||
345
408
             !dss->Entry (0)->token ()))) {
346
409
        SEM_ERROR (dss, "only the 'virtual' specifier is allowed for a pointcut");
347
410
        return pcd;
349
412
    }
350
413
 
351
414
    // handle the declarator and introduce pointcut into ACClassDatabase
352
 
    CT_DeclaratorList *dl = ((CT_ObjDecl*)pcd->Decl ())->Declarators ();
 
415
    Puma::CT_DeclaratorList *dl = ((Puma::CT_ObjDecl*)pcd->Decl ())->Declarators ();
353
416
    for (int d = 0; d < dl->Entries (); d++) {
354
 
      CT_InitDeclarator *id = (CT_InitDeclarator*)dl->Entry (d);
355
 
      CFunctionInfo *pcdfunc = id->Object ()->FunctionInfo ();
 
417
      Puma::CT_InitDeclarator *id = (Puma::CT_InitDeclarator*)dl->Entry (d);
 
418
      Puma::CFunctionInfo *pcdfunc = id->Object ()->FunctionInfo ();
356
419
 
357
420
      if (!pcdfunc) {
358
421
        SEM_ERROR (id, "invalid pointcut definition");
362
425
      // handle pointcuts with undefined result type:
363
426
      //   must be changed to INT to avoid problems with semantic analysis
364
427
      //   of operator calls
365
 
      CTypeInfo *old_ret_type = pcdfunc->TypeInfo ()->ReturnType ();
 
428
      Puma::CTypeInfo *old_ret_type = pcdfunc->TypeInfo ()->ReturnType ();
366
429
      if (old_ret_type->is_undefined ()) {
367
 
        pcdfunc->TypeInfo ()->BaseType (&CTYPE_INT);
368
 
        CTypeInfo::Destroy (old_ret_type);
 
430
        pcdfunc->TypeInfo ()->BaseType (&Puma::CTYPE_INT);
 
431
        Puma::CTypeInfo::Destroy (old_ret_type);
369
432
      }
370
433
 
371
 
      ACPointcutInfo *pi = ((ACClassDatabase*)_db)->new_pointcut (pcdfunc);
 
434
      Puma::ACPointcutInfo *pi = ((Puma::ACClassDatabase*)_db)->new_pointcut (pcdfunc);
372
435
      pi->def_node (pcd);
373
 
      CClassInfo *ci = pcdfunc->Scope ()->ClassInfo ();
 
436
      Puma::CClassInfo *ci = pcdfunc->Scope ()->ClassInfo ();
374
437
      if (ci) {
375
 
        ACAspectInfo *ai = ((ACClassDatabase*)_db)->AspectInfo (ci);
 
438
        Puma::ACAspectInfo *ai = ((Puma::ACClassDatabase*)_db)->AspectInfo (ci);
376
439
        if (ai) {
377
440
          pi->Aspect (ai);
378
441
          ai->add (pi);
384
447
}
385
448
 
386
449
 
387
 
slice CTree *ExtAC::ACSemantic::introduce_class_slice () {
 
450
slice Puma::CTree *ExtAC::ACSemantic::introduce_class_slice () {
388
451
  // check if this is a slice member
389
 
  CTree *name = builder ().get_node (2);
390
 
  if (name->NodeName () == CT_QualName::NodeId () ||
391
 
      name->NodeName () == CT_RootQualName::NodeId ()) {
392
 
    CT_QualName *qn = (CT_QualName*)name;
 
452
  Puma::CTree *name = builder ().get_node (2);
 
453
  if (name->NodeName () == Puma::CT_QualName::NodeId () ||
 
454
      name->NodeName () == Puma::CT_RootQualName::NodeId ()) {
 
455
    Puma::CT_QualName *qn = (Puma::CT_QualName*)name;
393
456
    for (int n = 0; n < qn->Entries () - 1; n++) {
394
 
      assert (qn->Entry (n)->NodeName () == CT_SimpleName::NodeId ());
395
 
      CT_SimpleName *sn = (CT_SimpleName*)qn->Entry (n);
 
457
      assert (qn->Entry (n)->NodeName () == Puma::CT_SimpleName::NodeId ());
 
458
      Puma::CT_SimpleName *sn = (Puma::CT_SimpleName*)qn->Entry (n);
396
459
      if (!sn->Object ()) {
397
 
        *_err << sev_error << name->token ()->location ()
 
460
        *_err << Puma::sev_error << name->token ()->location ()
398
461
              << "unknown scope '" << sn->Text ()
399
 
              << "' in slice or slice member declaration" << endMessage;
400
 
        return (CTree*)0;
 
462
              << "' in slice or slice member declaration" << Puma::endMessage;
 
463
        return (Puma::CTree*)0;
401
464
      }
402
465
      if (_db->SliceInfo (sn->Object ())) {
403
466
        // this is a slice member definition
404
 
        return (CTree*)0;
 
467
        return (Puma::CTree*)0;
405
468
      }
406
469
    }
407
470
  }
408
471
 
409
472
  // build the ClassSliceDecl node
410
 
  CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)builder ().class_slice_decl ();
 
473
  Puma::CT_ClassSliceDecl *csd = (Puma::CT_ClassSliceDecl*)builder ().class_slice_decl ();
411
474
  if (!csd) return csd;
412
 
  assert (csd->NodeName () == CT_ClassSliceDecl::NodeId ());
 
475
  assert (csd->NodeName () == Puma::CT_ClassSliceDecl::NodeId ());
413
476
  
414
477
  // lookup name
415
478
  bool error = true;
416
 
  CObjectInfo *info = 0;
417
 
  CCNameLookup nl (*_err);
 
479
  Puma::CObjectInfo *info = 0;
 
480
  Puma::CCNameLookup nl (*_err);
418
481
  nl.lookupType (csd->name (), current_scope);
419
482
  if (nl.Objects ()) {
420
483
    info = nl.Object ();
421
484
    // slice already defined in lookup scope
422
 
    ACSliceInfo *acsi = _db->SliceInfo (info);
 
485
    Puma::ACSliceInfo *acsi = _db->SliceInfo (info);
423
486
    if (!acsi) {
424
 
      *_err << sev_error << csd->token ()->location ()
 
487
      *_err << Puma::sev_error << csd->token ()->location ()
425
488
            << "slice '" << csd->name ()->Name ()->Text ()
426
 
            << "' already defined" << endMessage;
427
 
      *_err << sev_error << info->Tree ()->token ()->location ()
428
 
            << "previous defininition here" << endMessage;
 
489
            << "' already defined" << Puma::endMessage;
 
490
      *_err << Puma::sev_error << info->Tree ()->token ()->location ()
 
491
            << "previous defininition here" << Puma::endMessage;
429
492
    }
430
493
    else if (acsi->definition () && (csd->base_clause () || csd->members ())) {
431
 
      *_err << sev_error << csd->token ()->location ()
 
494
      *_err << Puma::sev_error << csd->token ()->location ()
432
495
            << "redefinition of slice '" << csd->name ()->Name ()->Text ()
433
 
            << "'" << endMessage;
434
 
      *_err << sev_error
 
496
            << "'" << Puma::endMessage;
 
497
      *_err << Puma::sev_error
435
498
            << acsi->definition ()->def_node ()->token ()->location ()
436
 
            << "previous defininition here" << endMessage;
 
499
            << "previous defininition here" << Puma::endMessage;
437
500
    }
438
501
    else if (acsi->def_node ()->key ()->token ()->type () !=
439
502
      csd->key ()->token ()->type ()) {
440
 
      *_err << sev_error << csd->token ()->location ()
 
503
      *_err << Puma::sev_error << csd->token ()->location ()
441
504
            << "slice '" << csd->name ()->Name ()->Text ()
442
 
            << "' already defined with different class key" << endMessage;
443
 
      *_err << sev_error << info->Tree ()->token ()->location ()
444
 
            << "previous defininition here" << endMessage;
 
505
            << "' already defined with different class key" << Puma::endMessage;
 
506
      *_err << Puma::sev_error << info->Tree ()->token ()->location ()
 
507
            << "previous defininition here" << Puma::endMessage;
445
508
    }
446
509
    else
447
510
      error = false;
453
516
    info = current_scope->newClass();
454
517
    info->Name (csd->name ()->Text ());
455
518
    info->Tree (csd);
456
 
    ACSliceInfo *si = _db->new_slice (info);
 
519
    Puma::ACSliceInfo *si = _db->new_slice (info);
457
520
    si->def_node (csd);
458
521
    si->in_advice (_in_advice_decl);
459
522
    csd->Object (info);
463
526
      nl.Object ()->NextObject (info);
464
527
    
465
528
    // analyze the members
466
 
    ACIntroAnalyzer anal(_db, info->ClassInfo ());
467
 
    CT_List *members = csd->members ();
 
529
    Puma::ACIntroAnalyzer anal(_db, info->ClassInfo ());
 
530
    Puma::CT_List *members = csd->members ();
468
531
    if (members) {
469
532
      for (int i = 0; i < members->Entries (); i++) {
470
 
        CT_Intro *intro = (CT_Intro*)members->Entry (i);
 
533
        Puma::CT_Intro *intro = (Puma::CT_Intro*)members->Entry (i);
471
534
        anal.analyze_intro_member (intro);
472
535
        if (anal.error ())
473
536
          SEM_ERROR (intro, anal.error_msg ());
477
540
  return csd;  
478
541
}
479
542
 
480
 
slice CTree *ExtAC::ACSemantic::introduce_class_slice_member () {
481
 
  CT_Intro *i = (CT_Intro*)builder ().class_slice_member_decl ();
 
543
slice Puma::CTree *ExtAC::ACSemantic::introduce_class_slice_member () {
 
544
  Puma::CT_Intro *i = (Puma::CT_Intro*)builder ().class_slice_member_decl ();
482
545
  if (!i) return i;
483
546
  
484
547
  // analyse the code
485
 
  ACIntroAnalyzer anal(_db, current_scope);
 
548
  Puma::ACIntroAnalyzer anal(_db, current_scope);
486
549
  anal.analyze_intro (i);
487
 
  if (anal.error ())
 
550
  if (anal.error ()) {
488
551
    SEM_ERROR (i, anal.error_msg ());
489
 
  else {
490
 
    ACSliceInfo *acsi = _db->SliceInfo (i->Scope ());
 
552
  } else {
 
553
    Puma::ACSliceInfo *acsi = _db->SliceInfo (i->Scope ());
491
554
    assert (acsi);
492
555
    acsi = acsi->definition ();
493
556
    if (!acsi) {
494
 
      *_err << sev_error << i->token ()->location ()
 
557
      *_err << Puma::sev_error << i->token ()->location ()
495
558
            << "slice '" << i->Scope ()->QualName ()
496
 
            << "' is incomplete" << endMessage;
 
559
            << "' is incomplete" << Puma::endMessage;
497
560
    }
498
561
    else
499
562
      acsi->add_member (i);
501
564
  return i;
502
565
}
503
566
 
504
 
slice CTree *ExtAC::ACSemantic::introduce_member_advice () {
505
 
  CT_AdviceDecl *ad = (CT_AdviceDecl*) builder ().advice_decl ();
 
567
slice Puma::CTree *ExtAC::ACSemantic::introduce_member_advice () {
 
568
  Puma::CT_AdviceDecl *ad = (Puma::CT_AdviceDecl*) builder ().advice_decl ();
506
569
  if (! ad)
507
570
    return ad;
508
571
 
509
572
  const char *nodename = ad->Decl ()->NodeName ();
510
 
  ACAspectInfo *ai = 0;
511
 
  if (nodename == CT_Intro::NodeId ()) {
 
573
  Puma::ACAspectInfo *ai = 0;
 
574
  if (nodename == Puma::CT_Intro::NodeId ()) {
512
575
 
513
576
    // find out if we are in an aspect body
514
577
    if (current_scope->ClassInfo ())
515
578
      ai = _db->AspectInfo (current_scope->ClassInfo ());
516
579
    
517
580
    // analyse the introduction code
518
 
    CT_Intro *intro = (CT_Intro*)ad->Decl ();
519
 
    ACIntroAnalyzer anal(_db, current_scope);
 
581
    Puma::CT_Intro *intro = (Puma::CT_Intro*)ad->Decl ();
 
582
    Puma::ACIntroAnalyzer anal(_db, current_scope);
520
583
    if (ai)
521
584
      anal.analyze_intro_member (intro);
522
585
    else
523
586
      anal.analyze_intro (intro);
524
 
    if (anal.error ())
 
587
    if (anal.error ()) {
525
588
      SEM_ERROR (intro, anal.error_msg ());
526
 
    else if (!ai)
 
589
    } else if (!ai)
527
590
      ai = _db->AspectInfo (intro->Scope ()->ClassInfo ());
528
591
      
529
592
    // if we found out to which aspect this intro belong, add it
532
595
    else
533
596
      SEM_ERROR (intro, "introduction not in aspect scope");
534
597
  }
535
 
  else if (nodename == CT_FctDef::NodeId ()) {
536
 
    CT_FctDef *fd = (CT_FctDef*)ad->Decl ();
537
 
    CClassInfo *ci = fd->Object ()->QualifiedScope ()->ClassInfo ();
 
598
  else if (nodename == Puma::CT_FctDef::NodeId ()) {
 
599
    Puma::CT_FctDef *fd = (Puma::CT_FctDef*)ad->Decl ();
 
600
    Puma::CClassInfo *ci = fd->Object ()->QualifiedScope ()->ClassInfo ();
538
601
    if (ci && (ai = ((ACClassDatabase*)_db)->AspectInfo (ci)))
539
602
      ai->addAdviceNode (ad);
540
603
    else
541
604
      SEM_ERROR (fd, "advice/introduction not in aspect scope");
542
605
  }
543
 
  else if (nodename == CT_ObjDecl::NodeId ()) {
544
 
    CClassInfo *ci = current_scope->ClassInfo ();
 
606
  else if (nodename == Puma::CT_ObjDecl::NodeId ()) {
 
607
    Puma::CClassInfo *ci = current_scope->ClassInfo ();
545
608
    if (! ci) {
546
 
      CT_DeclaratorList *dl = ((CT_ObjDecl*)ad->Decl ())->Declarators ();
 
609
      Puma::CT_DeclaratorList *dl = ((Puma::CT_ObjDecl*)ad->Decl ())->Declarators ();
547
610
      if (dl->Entries ()) {
548
 
        CT_InitDeclarator *id = (CT_InitDeclarator*)dl->Entry (0);
 
611
        Puma::CT_InitDeclarator *id = (Puma::CT_InitDeclarator*)dl->Entry (0);
549
612
        ci = id->Object ()->QualifiedScope ()->ClassInfo ();
550
613
      }
551
614
    }
552
615
    if (ci && (ai = ((ACClassDatabase*)_db)->AspectInfo (ci))) {
553
616
      // check if this is semantically correct
554
 
      check_intro ((CT_ObjDecl*)ad->Decl ());
 
617
      check_intro ((Puma::CT_ObjDecl*)ad->Decl ());
555
618
      // add the introduction to the aspect
556
619
      ai->addIntroNode (ad, protection ());
557
620
    }
558
621
  }
559
 
  else if (nodename == CT_OrderDecl::NodeId ()) {
560
 
    CClassInfo *ci = current_scope->ClassInfo ();
561
 
    if (ci && (ai = ((ACClassDatabase*)_db)->AspectInfo (ci))) {
562
 
      CT_OrderList *lst = ((CT_OrderDecl*)ad->Decl ())->OrderList ();
563
 
      if (lst->Entries () <= 1)
 
622
  else if (nodename == Puma::CT_OrderDecl::NodeId ()) {
 
623
    Puma::CClassInfo *ci = current_scope->ClassInfo ();
 
624
    if (ci && (ai = ((Puma::ACClassDatabase*)_db)->AspectInfo (ci))) {
 
625
      Puma::CT_OrderList *lst = ((Puma::CT_OrderDecl*)ad->Decl ())->OrderList ();
 
626
      if (lst->Entries () <= 1) {
564
627
        SEM_ERROR (ad, "order list must have at least two entries");
565
 
      else
 
628
      } else
566
629
        ai->addOrderNode (ad);
567
630
    }
568
631
    else
569
632
      SEM_ERROR (ad, "order advice not in aspect scope");
570
633
  }
571
 
  else if (nodename == CT_SliceRef::NodeId ()) {
572
 
    CClassInfo *ci = current_scope->ClassInfo ();
573
 
    if (ci && (ai = ((ACClassDatabase*)_db)->AspectInfo (ci))) {
574
 
      CT_SliceRef *sr = (CT_SliceRef*)ad->Decl ();
 
634
  else if (nodename == Puma::CT_SliceRef::NodeId ()) {
 
635
    Puma::CClassInfo *ci = current_scope->ClassInfo ();
 
636
    if (ci && (ai = ((Puma::ACClassDatabase*)_db)->AspectInfo (ci))) {
 
637
      Puma::CT_SliceRef *sr = (Puma::CT_SliceRef*)ad->Decl ();
575
638
      // lookup name
576
 
      CObjectInfo *info = sr->name ()->Name ()->Object ();
 
639
      Puma::CObjectInfo *info = sr->name ()->Name ()->Object ();
577
640
      if (!info) {
578
641
        // Object not resolved => identifier in C mode => lookup here
579
 
        CCNameLookup nl (*_err);
 
642
        Puma::CCNameLookup nl (*_err);
580
643
        nl.lookupType (sr->name (), current_scope);
581
644
        if (nl.Objects ()) {
582
645
          info = nl.Object ();
598
661
      SEM_ERROR (ad, "introduction not in aspect scope");
599
662
    }
600
663
  }
601
 
  else if (nodename == CT_ClassSliceDecl::NodeId ()) {
602
 
    CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)ad->Decl ();
603
 
    CClassInfo *ci = current_scope->ClassInfo ();
604
 
    if (ci && (ai = ((ACClassDatabase*)_db)->AspectInfo (ci)) && csd->Object ())
 
664
  else if (nodename == Puma::CT_ClassSliceDecl::NodeId ()) {
 
665
    Puma::CT_ClassSliceDecl *csd = (Puma::CT_ClassSliceDecl*)ad->Decl ();
 
666
    Puma::CClassInfo *ci = current_scope->ClassInfo ();
 
667
    if (ci && (ai = ((Puma::ACClassDatabase*)_db)->AspectInfo (ci)) && csd->Object ())
605
668
      ai->addIntroNode (ad, protection ());
606
669
  }
607
670
  
608
671
  return ad;
609
672
}
610
673
 
611
 
slice void ExtAC::ACSemantic::check_intro (CT_ObjDecl *od) {
612
 
  CT_DeclaratorList *dl = od->Declarators();
 
674
slice void ExtAC::ACSemantic::check_intro (Puma::CT_ObjDecl *od) {
 
675
  Puma::CT_DeclaratorList *dl = od->Declarators();
613
676
  bool baseclass = false;
614
677
  for (int i = 0; i < dl->Entries (); i++)
615
 
    if (strcmp (((CT_InitDeclarator*)dl->Entry (i))->Object ()->Name (),
 
678
    if (strcmp (((Puma::CT_InitDeclarator*)dl->Entry (i))->Object ()->Name (),
616
679
                "baseclass") == 0)
617
680
      baseclass = true;
618
681
  if (baseclass) {
619
 
    CFunctionInfo *obj = ((CT_InitDeclarator*)dl->Entry (0))->
 
682
    Puma::CFunctionInfo *obj = ((Puma::CT_InitDeclarator*)dl->Entry (0))->
620
683
      Object ()->FunctionInfo ();
621
 
    if (dl->Entries () != 1 || !obj)
 
684
    if (dl->Entries () != 1 || !obj) {
622
685
      SEM_ERROR (od, "invalid baseclass introduction");
623
 
    else if (od->DeclSpecs ()->Entries () > 1 ||
 
686
    } else if (od->DeclSpecs ()->Entries () > 1 ||
624
687
             (od->DeclSpecs ()->Entries () == 1 &&
625
 
              od->DeclSpecs ()->token ()->type () != TOK_VIRTUAL))
 
688
              od->DeclSpecs ()->token ()->type () != Puma::TOK_VIRTUAL)) {
626
689
      SEM_ERROR (od, "baseclasses can only be virtual");
627
 
    else if (obj->Arguments () != 1)
 
690
    } else if (obj->Arguments () != 1) {
628
691
      SEM_ERROR (od, "provide exactly 1 name in a baseclass introduction");
629
 
    else if (!obj->Argument (0u)->TypeInfo ()->isClass ())
 
692
    } else if (!obj->Argument (0u)->TypeInfo ()->isClass ()) {
630
693
      SEM_ERROR (od, "baseclass argument is not a class");
631
 
    else if (obj->Protection () == CProtection::PROT_NONE)
 
694
    } else if (obj->Protection () == Puma::CProtection::PROT_NONE) {
632
695
      SEM_ERROR (od, "baseclass introduction must be in aspect scope");
 
696
    }
633
697
  }
634
698
}
635
699
 
637
701
  _at_end_of_advice_decl = syntax ().token_provider->get_state ();
638
702
  _saved_scope = current_scope;
639
703
  if (builder ().nodes () > 2) { // block intro decls have only 2 nodes!
640
 
    CTree *node = builder ().get_node (2);
641
 
    if (node->NodeName () == CT_FctDef::NodeId ())
642
 
      current_scope = ((CT_FctDef*)node)->Object ()->FunctionInfo ();
 
704
    Puma::CTree *node = builder ().get_node (2);
 
705
    if (node->NodeName () == Puma::CT_FctDef::NodeId ())
 
706
      current_scope = ((Puma::CT_FctDef*)node)->Object ()->FunctionInfo ();
643
707
  }
644
708
}
645
709