1
// This file is part of the AspectC++ compiler 'ac++'.
2
// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org)
4
// This program is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU General Public License as
6
// published by the Free Software Foundation; either version 2 of
7
// the License, or (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public
15
// License along with this program; if not, write to the Free
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
#ifndef __transform_info_h__
20
#define __transform_info_h__
22
#include "JoinPointLoc.h"
23
#include "ThisJoinPoint.h"
25
#include "Puma/CClassDatabase.h"
26
#include "Puma/CNamespaceInfo.h"
27
#include "Puma/DeducedArgument.h"
28
#include "Puma/CTemplateInstance.h"
29
#include "Puma/MacroUnit.h"
31
class TransformInfo : public ModelTransformInfo {
33
virtual JoinPointLoc &jpl () = 0;
34
virtual CTree *tree () const = 0;
35
virtual CObjectInfo *obj_info () const = 0;
36
// associated unique parser object (e.g. for name mangling)
37
virtual CObjectInfo *assoc_obj () const = 0;
39
return tree ()->token ()->location ().line ();
42
return tree ()->end_token ()->location ().line () - line () + 1;
44
// find the unit (non-macro) in which a join point is located
46
CTree *node = tree ();
49
Token *token = node->token ();
50
Unit *unit = (Unit*)token->belonging_to ();
51
while (unit && unit->isMacroExp ()) {
52
unit = ((MacroUnit*)unit)->CallingUnit ();
57
static inline const TransformInfo *of (const JoinPointLoc &loc);
58
static inline CTree *tree (const JoinPointLoc &loc);
59
static inline int line (const JoinPointLoc &loc);
60
static inline int lines (const JoinPointLoc &loc);
61
static inline Unit *unit (const JoinPointLoc &loc);
62
static inline Location location (const JoinPointLoc &loc);
66
inline const TransformInfo *TransformInfo::of (const JoinPointLoc &loc) {
67
return loc.transform_info () ? (TransformInfo*)loc.transform_info () : 0;
69
inline CTree *TransformInfo::tree (const JoinPointLoc &loc) {
70
return loc.transform_info () ?
71
((TransformInfo*)loc.transform_info ())->tree () : 0;
73
inline int TransformInfo::line (const JoinPointLoc &loc) {
74
return loc.transform_info () ?
75
((TransformInfo*)loc.transform_info ())->line () : -1;
77
inline int TransformInfo::lines (const JoinPointLoc &loc) {
78
return loc.transform_info () ?
79
((TransformInfo*)loc.transform_info ())->lines () : -1;
81
inline Unit *TransformInfo::unit (const JoinPointLoc &loc) {
82
return loc.transform_info () ?
83
((TransformInfo*)loc.transform_info ())->unit () : 0;
85
inline Location TransformInfo::location (const JoinPointLoc &loc) {
86
return loc.transform_info () ?
87
tree (loc)->token ()->location () : Location ();
90
class TI_Namespace : public TransformInfo {
91
// pointer to the Puma namespace object (for transformation)
92
CNamespaceInfo *_namespace_obj;
94
TI_Namespace () : _namespace_obj (0) {}
96
void namespace_info (CNamespaceInfo *n) { _namespace_obj = n; }
97
CNamespaceInfo *namespace_info () const { return _namespace_obj; }
98
virtual CObjectInfo *obj_info () const { return _namespace_obj; }
99
virtual CObjectInfo *assoc_obj () const { return _namespace_obj; }
100
virtual CTree *tree () const { return _namespace_obj->Tree (); }
102
static string name (CNamespaceInfo *n) {
103
if (n->GlobalScope ())
106
return n->QualName ();
110
class TI_Class : public TransformInfo {
111
CClassInfo *_class_obj;
114
TI_Class () : _class_obj (0), _phase (0) {}
116
void phase (int p) { _phase = p; }
117
int phase () const { return _phase; }
118
void class_info (CClassInfo *c) { _class_obj = c->DefObject (); }
119
CClassInfo *class_info () const { return _class_obj; }
121
virtual CObjectInfo *obj_info () const { return _class_obj; }
122
virtual CObjectInfo *assoc_obj () const { return _class_obj; }
123
virtual CTree *tree () const { return _class_obj->Tree (); }
125
static string name (CClassInfo *c) {
126
ostringstream class_name;
127
class_name << *c->TypeInfo ();
128
return class_name.str ();
131
static const TI_Class *of (const JPL_Class &loc) {
132
return (TI_Class*)loc.transform_info ();
136
class TI_Aspect : public TI_Class {
137
ACAspectInfo *_aspect_obj;
139
TI_Aspect () : _aspect_obj (0) {}
141
void aspect_info (ACAspectInfo *ai) {
143
class_info (ai->ClassInfo ());
145
ACAspectInfo *aspect_info () const { return _aspect_obj; }
146
CFunctionInfo *aspectof () const {
148
CFunctionInfo *aof = ClassInfo ()->Function ("aspectof");
150
aof = ClassInfo ()->Function ("aspectOf");
151
return aof ? aof->DefObject () : (CFunctionInfo*)0;
153
const char *name () const { return _aspect_obj->name (); }
154
ACAspectInfo *acnode () const { return _aspect_obj; }
155
CClassInfo *ClassInfo () const { return _aspect_obj->ClassInfo (); }
157
static string name (ACAspectInfo *ai) {
158
ostringstream class_name;
159
class_name << *ai->ClassInfo ()->TypeInfo ();
160
return class_name.str ();
163
static const TI_Aspect *of (const JPL_Aspect &loc) {
164
return (TI_Aspect*)loc.transform_info ();
169
class TI_Function : public TransformInfo {
170
CFunctionInfo *_func_obj;
173
TI_Function () : _func_obj (0), _phase (0) {}
175
void func_info (CFunctionInfo *fi) { _func_obj = fi->DefObject (); }
176
CFunctionInfo *func_info () const { return _func_obj; }
177
void phase (int p) { _phase = p; }
178
int phase () const { return _phase; }
179
virtual CObjectInfo *obj_info () const { return _func_obj; }
180
virtual CObjectInfo *assoc_obj () const { return _func_obj; }
181
virtual CTree *tree () const { return _func_obj->Tree (); }
183
static string name (CFunctionInfo *func_info) {
184
ostringstream sig, name;
185
if (func_info->isMethod () && !func_info->isStaticMethod ())
186
name << func_info->Name ();
188
name << func_info->QualName ();
190
// add the template arguments if it is a function template instance
191
CTemplateInstance *instance = func_info->TemplateInstance ();
194
for (unsigned a = 0; a < instance->DeducedArgs (); a++) {
195
if (a > 0) name << ",";
196
DeducedArgument *arg = instance->DeducedArg (a);
198
name << *arg->Type ();
199
else if (arg->Value ()) {
200
if (arg->Value ()->isSigned ())
201
name << arg->Value ()->convert_to_int ();
202
else if (arg->Value ()->isUnsigned ())
203
name << arg->Value ()->convert_to_uint ();
204
else if (arg->Value ()->isFloat ())
205
name << arg->Value ()->convert_to_float ();
208
name << "*invalid template arg*";
212
func_info->TypeInfo ()->TypeText (sig, name.str ().c_str ());
216
static const TI_Function *of (const JPL_Function &loc) {
217
return (TI_Function*)loc.transform_info ();
221
class TI_Type : public TransformInfo {
222
CTypeInfo *_type_info;
224
TI_Type () : _type_info (0) {}
226
void type_info (CTypeInfo *ti) { _type_info = ti; }
227
CTypeInfo *type_info () const { return _type_info; }
229
virtual CObjectInfo *obj_info () const { return 0; }
230
virtual CObjectInfo *assoc_obj () const { return 0; }
231
virtual CTree *tree () const { return 0; }
233
static string name (CTypeInfo *type_info) {
239
static const TI_Type *of (const JPL_Type &loc) {
240
return (TI_Type*)loc.transform_info ();
244
class TI_Code : public TransformInfo {
246
virtual CFunctionInfo *tjp_type() const = 0;
247
virtual CFunctionInfo *tjp_target() const = 0;
248
virtual CFunctionInfo *tjp_that() const = 0;
250
// that types (for the JoinPoint-API)
251
virtual CTypeInfo *that_type () const = 0;
253
// target type (for the JoinPoint-API)
254
virtual CTypeInfo *target_type () const = 0;
256
// interface needed to generate proper proceed code
257
virtual bool proceed_needs_that () const { return false; }
258
virtual bool proceed_needs_target () const { return false; }
259
virtual bool proceed_needs_fptr () const { return false; }
261
// helper functions for derived classes
262
static CTypeInfo *get_that_type (CObjectInfo *obj) {
263
CFunctionInfo *func = obj->FunctionInfo ();
265
CObjectInfo *this_obj = func->Attribute ("this");
267
CTypeInfo *type = this_obj->TypeInfo ();
268
// find the type which is referenced by 'this'
269
while (type && !type->isRecord ())
270
type = type->BaseType ();
275
if (obj->ClassScope ())
276
return obj->ClassScope ()->TypeInfo ();
280
// helper function: check if a function is a method (needs a 'this' pointer)
281
static bool needs_this (CFunctionInfo *func) {
282
if (func->isMethod () && !func->isStaticMethod ()) {
283
return !(func->isOperator () &&
284
(strcmp (func->Name (), "operator new") == 0 ||
285
strcmp (func->Name (), "operator new[]") == 0 ||
286
strcmp (func->Name (), "operator delete") == 0 ||
287
strcmp (func->Name (), "operator delete[]") == 0));
293
class TI_Method : public TI_Code {
294
CFunctionInfo *_func_info;
296
TI_Method () : _func_info (0) {}
298
void func_info (CFunctionInfo *f) { _func_info = f; }
299
virtual CObjectInfo *obj_info () const { return _func_info; }
300
virtual CObjectInfo *assoc_obj () const { return _func_info; }
301
virtual CTree *tree () const { return _func_info->Tree (); }
303
virtual CFunctionInfo *tjp_type() const {return _func_info;}
304
virtual CFunctionInfo *tjp_target() const {return _func_info;}
305
virtual CFunctionInfo *tjp_that() const {return _func_info;}
307
// that type (for the JoinPoint-API)
308
virtual CTypeInfo *that_type () const { return get_that_type (_func_info); }
310
// interface needed to generate proper proceed code
311
virtual bool proceed_needs_that () const { return needs_this (_func_info); }
313
// target type (for the JoinPoint-API)
314
virtual CTypeInfo *target_type () const {
315
CRecord *scope = _func_info->ClassScope ();
316
return scope ? scope->TypeInfo () : &CTYPE_VOID;
320
class TI_MethodCall : public TI_Code {
321
CFunctionInfo *called_func;
322
CObjectInfo *caller_obj;
325
TI_MethodCall () : called_func (0), caller_obj (0), node (0) {}
327
void called (CFunctionInfo *c) { called_func = c; }
328
CFunctionInfo *called () const { return called_func; }
329
void caller (CObjectInfo *c) { caller_obj = c; }
330
CFunctionInfo *caller () {
331
return caller_obj ? caller_obj->FunctionInfo () : 0;
333
void tree (CT_Call *n) { node = n; }
334
virtual CTree *tree () const { return node; }
335
virtual CObjectInfo *obj_info () const { return called_func; }
336
virtual CObjectInfo *assoc_obj () const { return caller_obj; }
338
virtual CFunctionInfo *tjp_type() const { return called_func;}
339
virtual CFunctionInfo *tjp_target() const { return called_func;}
340
virtual CFunctionInfo *tjp_that() const { return caller_obj->FunctionInfo ();}
342
// interface needed to generate proper proceed code
343
virtual bool proceed_needs_target () const { return needs_this (called_func); }
344
virtual bool proceed_needs_fptr () const { return needs_rights (); }
346
// that type (for the JoinPoint-API)
347
virtual CTypeInfo *that_type () const { return get_that_type (caller_obj); }
349
// target type (for the JoinPoint-API)
350
virtual CTypeInfo *target_type () const {
352
CTree *expr = target_expr (is_ptr);
354
CTypeInfo *type = expr->Type ();
355
// if this is a pointer or reference, take the base type
356
while (type && (type->TypeAddress () || !type->isRecord ()))
357
type = type->BaseType ();
361
else if (called_func->isMethod ()) {
362
if (called_func->isStaticMethod ()) {
363
return called_func->ClassScope ()->TypeInfo ();
366
if (caller_obj->FunctionInfo ()) {
367
assert (caller_obj->ClassScope ());
368
return caller_obj->ClassScope ()->TypeInfo ();
378
// the target object of the call or NULL
379
CT_Expression *target_expr (bool &is_ptr) const {
381
// check if this call has a target object
382
if (!(called_func->isMethod () && !called_func->isStaticMethod ()))
387
// what kind of node was used for the call?
388
const char *calltype = node->NodeName ();
390
// in most case we have no pointer
393
if (calltype == CT_CallExpr::NodeId ()) {
394
CTree *expr = ((CT_CallExpr*)node)->Expr ();
395
const char *fctcalltype = expr->NodeName ();
396
if (fctcalltype == CT_MembRefExpr::NodeId ()) {
398
result = expr->Son (0);
399
} else if (fctcalltype == CT_MembPtrExpr::NodeId ()) {
400
// <target-ptr>->method()
402
result = expr->Son (0);
405
is_ptr = true; // here 'this' is passed implicitly
408
else if (calltype == CT_BinaryExpr::NodeId ()) {
409
// <target> <op> <arg>
410
result = node->Son (0);
412
else if (calltype == CT_UnaryExpr::NodeId ()) {
414
result = node->Son (1);
416
else if (calltype == CT_PostfixExpr::NodeId ()) {
418
result = node->Son (0);
420
else if (calltype == CT_IndexExpr::NodeId ()) {
421
// <target> [ <index> ]
422
result = node->Son (0);
424
else if (calltype == CT_ImplicitCall::NodeId ()) {
426
result = node->Son (0);
429
cout << "unexpected node type " << node->NodeName () << " in "
430
<< "JPL_MethodCall::target_expr()" << endl;
432
return (CT_Expression*)result;
435
// the call expression node in the syntax tree
436
CT_Call *CallNode() const { return node;}
438
// checks if the original call uses a qualified target function name
439
bool is_qualified () const {
440
if (node->NodeName () != CT_CallExpr::NodeId ())
442
CTree *expr = ((CT_CallExpr*)node)->Expr ();
443
const char *nodename = expr->NodeName ();
444
if (nodename == CT_MembPtrExpr::NodeId () ||
445
nodename == CT_MembRefExpr::NodeId ()) {
446
expr = expr->Son (2); // some access function in PUMA missing!
447
nodename = expr->NodeName ();
449
return nodename == CT_QualName::NodeId () ||
450
nodename == CT_RootQualName::NodeId ();
453
// returns true if the call needs special access rights
454
bool needs_rights () const {
455
// get the target object type
456
CTypeInfo *type = target_type ()->UnqualType ();
458
// no member function => no accessibility problem
462
// static member => no problem only if public
463
if (called_func->isStaticMethod ())
464
return (called_func->Protection () != CProtection::PROT_PUBLIC);
466
// normal member function => look up the accessibility
467
if (type->ClassInfo () &&
468
type->ClassInfo ()->Accessibility (called_func) == CProtection::PROT_PUBLIC)
475
class TI_Construction : public TI_Code {
476
CFunctionInfo *_func_info;
478
TI_Construction () : _func_info (0) {}
480
void func_info (CFunctionInfo *f) { _func_info = f; }
481
virtual CObjectInfo *obj_info () const { return _func_info; }
482
virtual CObjectInfo *assoc_obj () const { return _func_info; }
483
virtual CTree *tree () const { return _func_info->ClassScope ()->Tree (); }
485
virtual CFunctionInfo *tjp_type() const {return _func_info;}
486
virtual CFunctionInfo *tjp_target() const {return _func_info;}
487
virtual CFunctionInfo *tjp_that() const {return _func_info;}
489
// that type (for the JoinPoint-API)
490
virtual CTypeInfo *that_type () const { return get_that_type (_func_info); }
492
// target type (for the JoinPoint-API)
493
virtual CTypeInfo *target_type () const {
494
CRecord *scope = _func_info->ClassScope ();
495
return scope ? scope->TypeInfo () : &CTYPE_VOID;
498
// interface needed to generate proper proceed code
499
virtual bool proceed_needs_that () const { return true; }
502
class TI_Destruction : public TI_Code {
503
CFunctionInfo *_func_info;
505
TI_Destruction () : _func_info (0) {}
507
void func_info (CFunctionInfo *f) { _func_info = f; }
508
virtual CObjectInfo *obj_info () const { return _func_info; }
509
virtual CObjectInfo *assoc_obj () const { return _func_info; }
510
virtual CTree *tree () const { return _func_info->ClassScope ()->Tree (); }
512
virtual CFunctionInfo *tjp_type() const {return _func_info;}
513
virtual CFunctionInfo *tjp_target() const {return _func_info;}
514
virtual CFunctionInfo *tjp_that() const {return _func_info;}
516
// that type (for the JoinPoint-API)
517
virtual CTypeInfo *that_type () const { return get_that_type (_func_info); }
519
// target type (for the JoinPoint-API)
520
virtual CTypeInfo *target_type () const {
521
CRecord *scope = _func_info->ClassScope ();
522
return scope ? scope->TypeInfo () : &CTYPE_VOID;
525
// interface needed to generate proper proceed code
526
virtual bool proceed_needs_that () const { return true; }
529
class TI_AdviceCode : public TransformInfo {
530
CT_AdviceDecl *_tree;
531
ThisJoinPoint _this_join_point;
535
TI_AdviceCode () : _tree (0), _phase (0) {}
537
void phase (int p) { _phase = p; }
538
int phase () const { return _phase; }
539
void tree (CT_AdviceDecl *ad) { _tree = ad; }
540
virtual CTree *tree () const { return _tree; }
542
virtual CObjectInfo *obj_info () const {
543
return ((CT_FctDef*)_tree->Decl ())->Object ();
545
virtual CObjectInfo *assoc_obj () const { return obj_info (); }
547
CScopeInfo *Scope () const {
548
return ((CT_FctDef*)_tree->Decl ())->Object ()->QualifiedScope ();
550
const char *name () const {
551
return ((CT_FctDef*)_tree->Decl ())->Object ()->Name ();
553
CFunctionInfo *function() const {
555
fname << "__" << (name () + 1);
556
return Scope ()->ClassInfo ()->Function (fname.str ().c_str ());
559
ThisJoinPoint &this_join_point () { return _this_join_point; }
560
const ThisJoinPoint &this_join_point () const { return _this_join_point; }
562
static string name (CT_AdviceDecl *ad) {
563
const char *name = ((CT_FctDef*)ad->Decl ())->Object ()->Name () + 1;
564
CScopeInfo *scope = ((CT_FctDef*)ad->Decl ())->Object ()->QualifiedScope ();
567
fname << scope->QualName () << "::__" << name;
571
static TI_AdviceCode *of (const JPL_AdviceCode &loc) {
572
return (TI_AdviceCode*)loc.transform_info ();
576
class TI_Introduction : public TransformInfo {
577
ACIntroductionInfo *_acii;
578
// the following elements are only needed for the *old* repository code
584
TI_Introduction () : _acii (0) {}
586
void intro_info (ACIntroductionInfo *acii) {
588
_loc = tree ()->token ()->location ();
589
_lines = tree ()->end_token ()->location ().line () - line () + 1;
590
_unit = (Unit*)tree ()->token ()->belonging_to ();
593
virtual CObjectInfo *obj_info () const { return 0; }
594
virtual CObjectInfo *assoc_obj () const { return obj_info (); }
595
virtual CT_AdviceDecl *tree () const { return _acii->def_node (); }
597
int line () const { return _loc.line (); }
598
int lines () const { return _lines; }
599
Unit *unit () const { return _unit; }
601
static TI_Introduction *of (const JPL_Introduction &loc) {
602
return (TI_Introduction*)loc.transform_info ();
606
class TI_Order : public TransformInfo {
607
CT_AdviceDecl *_tree;
609
TI_Order () : _tree (0) {}
610
void tree (CT_AdviceDecl *ad) { _tree = ad; }
611
virtual CObjectInfo *obj_info () const {
612
return ((CT_FctDef*)_tree->Decl ())->Object ();
614
virtual CObjectInfo *assoc_obj () const { return obj_info (); }
615
virtual CTree *tree () const { return _tree; }
617
static TI_Order *of (const JPL_Order &loc) {
618
return (TI_Order*)loc.transform_info ();
622
class TI_ClassSlice : public TransformInfo {
624
const Unit *_slice_unit;
627
TI_ClassSlice () : _obj (0), _slice_unit (0) {}
629
void obj_info (CObjectInfo *obj) { _obj = obj; }
630
virtual CObjectInfo *obj_info () const { return _obj; }
631
void slice_unit (const Unit *su) { _slice_unit = su; }
632
const Unit &slice_unit () const { return *_slice_unit; }
634
virtual CObjectInfo *assoc_obj () const { return obj_info (); }
635
// virtual CTree *tree () const { return _acsi->def_node (); }
636
virtual CTree *tree () const { return _obj->Tree (); }
639
static TI_ClassSlice *of (const JPL_ClassSlice &loc) {
640
return (TI_ClassSlice*)loc.transform_info ();
643
static string name (ACSliceInfo *acsi) {
644
return acsi->object ()->QualName ();
648
#endif // __transform_info_h__