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;
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>());
75
76
// ***************************
79
80
pointcut csemantic () = "Puma::CSemantic";
81
advice csemantic () : slice class ACSemantic {
82
advice csemantic () : slice class Puma::ACSemantic {
83
ACIntroducer *_introducer;
84
Puma::ACIntroducer *_introducer;
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;
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);
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 (); }
103
104
// check an introduction if it makes sense
104
void check_intro (CT_ObjDecl *od);
105
void check_intro (Puma::CT_ObjDecl *od);
106
107
// change or get semantic state information
107
108
void enter_advice_decl () { _in_advice_decl = true; }
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 ())
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 ())
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
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 ();
208
216
tjp->that ()->introduce_class_post (cd);
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;
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));
230
advice call ("% ...::leave_class_def()") &&
231
within ("Puma::CTree *Puma::CCSemantic::class_spec()") : before () {
226
232
if (tjp->that ()->_introducer) {
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);
235
239
// perform an additional check on base classes with aspects
236
240
advice within (derived (csemantic ())) &&
237
241
execution ("% ...::add_base_classes(...)") : after () {
239
243
// obtain the first argument
240
CTree *cs = *tjp->arg<0>();
244
Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)*tjp->arg<0>();
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 ());
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));
243
tjp->that ()->add_base_classes_post (cs);
262
tjp->that ()->add_base_classes_post (cd);
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 ());
250
278
// ***************************
252
280
slice void ExtAC::ACSemantic::introduce_function_post (
253
CObjectInfo *func, CTree *node) {
281
Puma::CObjectInfo *func, Puma::CTree *node) {
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);
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);
264
292
std::ostringstream new_name;
265
new_name << "%a" << ai->AdviceCount () << "_" << func->Name ()
293
new_name << "%a" << ai->AdviceCount () << "_" << func->Name ();
267
294
func->Name (new_name.str ().c_str ());
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);
287
slice void ExtAC::ACSemantic::introduce_class_post (
303
Puma::CFunctionInfo *aofunc = (Puma::CFunctionInfo*)func;
304
Puma::ACAspectInfo *ai = _db->AspectInfo (aofunc->Scope ()->ClassInfo ());
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);
316
slice void ExtAC::ACSemantic::introduce_class_post (Puma::CT_ClassDef *cd) {
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;
326
if (cd->token ()->type () == Puma::TOK_ASPECT) {
327
Puma::CClassInfo *ci = cd->Object ()->ClassInfo ();
329
_db->new_aspect (ci);
331
if (! ci->Scope ()->ScopeInfo ()->GlobalScope ())
332
SEM_ERROR (cd, "aspects must be in global scope");
336
slice void ExtAC::ACCSemantic::introduce_class_post (CT_ClassDef *cd) {
290
if (cd->token ()->type () == TOK_ASPECT) {
291
CClassInfo *ci = cd->Object ()->ClassInfo ();
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 ();
349
current_scope = saved_scope;
352
if (cd->token ()->type () == Puma::TOK_ASPECT) {
353
Puma::CClassInfo *ci = cd->Object ()->ClassInfo ();
293
355
_db->new_aspect (ci);
300
slice void ExtAC::ACSemantic::add_base_classes_post (CTree *cs) {
362
slice void ExtAC::ACSemantic::add_base_classes_post (Puma::CT_ClassDef *cs) {
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 ();
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 ();
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;
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"
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 ();
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");
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 ();
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);
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 ();
375
ACAspectInfo *ai = ((ACClassDatabase*)_db)->AspectInfo (ci);
438
Puma::ACAspectInfo *ai = ((Puma::ACClassDatabase*)_db)->AspectInfo (ci);
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;
462
<< "' in slice or slice member declaration" << Puma::endMessage;
463
return (Puma::CTree*)0;
402
465
if (_db->SliceInfo (sn->Object ())) {
403
466
// this is a slice member definition
467
return (Puma::CTree*)0;
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 ());
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);
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;
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;
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;
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;
463
526
nl.Object ()->NextObject (info);
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 ();
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 ());
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;
484
547
// analyse the code
485
ACIntroAnalyzer anal(_db, current_scope);
548
Puma::ACIntroAnalyzer anal(_db, current_scope);
486
549
anal.analyze_intro (i);
488
551
SEM_ERROR (i, anal.error_msg ());
490
ACSliceInfo *acsi = _db->SliceInfo (i->Scope ());
553
Puma::ACSliceInfo *acsi = _db->SliceInfo (i->Scope ());
492
555
acsi = acsi->definition ();
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;
499
562
acsi->add_member (i);
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 ();
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 ()) {
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 ());
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);
521
584
anal.analyze_intro_member (intro);
523
586
anal.analyze_intro (intro);
525
588
SEM_ERROR (intro, anal.error_msg ());
527
590
ai = _db->AspectInfo (intro->Scope ()->ClassInfo ());
529
592
// if we found out to which aspect this intro belong, add it
533
596
SEM_ERROR (intro, "introduction not in aspect scope");
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);
541
604
SEM_ERROR (fd, "advice/introduction not in aspect scope");
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 ();
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 ();
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 ());
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");
566
629
ai->addOrderNode (ad);
569
632
SEM_ERROR (ad, "order advice not in aspect scope");
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 ();
576
CObjectInfo *info = sr->name ()->Name ()->Object ();
639
Puma::CObjectInfo *info = sr->name ()->Name ()->Object ();
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");
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 ());
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;
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");