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,
22
using std::stringstream;
23
using std::ostringstream;
25
#include "JoinPointLoc.h"
26
#include "AdviceInfo.h"
27
#include "PointCutEvaluator.h"
29
#include "Puma/CTypeInfo.h"
30
#include "Puma/CTree.h"
32
JoinPointLoc::JoinPointLoc (RepoXMLNode jn, RepoXMLNode::iter &curr) :
33
_parent (0), _plan (0), _trans (0) {
35
id (jn.get_int_prop ("id"));
36
if (jn.has_prop ("sig"))
37
_sig = jn.get_str_prop ("sig");
38
// TODO: temporary hack:
39
if (jn.has_prop ("plan")) {
40
_plan = (JoinPointPlan*)1;
42
if (jn.has_prop ("tunits")) {
43
_tunits.from_string (jn.get_str_prop ("tunits"));
45
while (curr != jn.end_child () && (*curr).has_name ("src")) {
46
RepoXMLNode fn = *curr;
47
_source_locs.insert (SourceLoc (fn));
52
RepoXMLNode JoinPointLoc::make_xml (RepoXMLNode parent) const {
53
RepoXMLNode jpn = parent.make_child (type_str ());
54
jpn.set_int_prop ("id", id ());
55
// TODO: temporary hack:
57
jpn.set_int_prop ("plan", 1);
59
if (_tunits.size () > 0)
60
jpn.set_str_prop ("tunits", _tunits.to_string ().c_str ());
61
for (SSet::const_iterator iter = source_locs ().begin ();
62
iter != source_locs ().end (); ++iter)
63
(*iter).make_xml (jpn);
67
IdElementMap *JoinPointLoc::_map = 0;
69
JoinPointLoc *JoinPointLoc::create (RepoXMLNode node) {
70
RepoXMLNode::iter curr_child = node.first_child ();
71
if (node.has_name ("function"))
72
return new JPL_Function (node, curr_child);
73
if (node.has_name ("class"))
74
return new JPL_Class (node, curr_child);
75
if (node.has_name ("namespace"))
76
return new JPL_Namespace (node, curr_child);
77
if (node.has_name ("aspect"))
78
return new JPL_Aspect (node, curr_child);
79
if (node.has_name ("exec"))
80
return new JPL_Method (node, curr_child);
81
if (node.has_name ("call"))
82
return new JPL_MethodCall (node, curr_child);
83
if (node.has_name ("construction"))
84
return new JPL_Construction (node, curr_child);
85
if (node.has_name ("destruction"))
86
return new JPL_Destruction (node, curr_child);
87
if (node.has_name ("advice-before") ||
88
node.has_name ("advice-after") ||
89
node.has_name ("advice-around"))
90
return new JPL_AdviceCode (node, curr_child);
91
if (node.has_name ("intro"))
92
return new JPL_Introduction (node, curr_child);
93
if (node.has_name ("slice-dep-base") ||
94
node.has_name ("slice-dep-member") ||
95
node.has_name ("slice-class"))
96
return new JPL_ClassSlice (node, curr_child);
100
void JoinPointLoc::parent (JPL_Name *p) {
105
void JoinPointLoc::dump (int indent) const {
106
for (int i = 0; i < indent; i++) cout << " ";
107
cout << type_str () << " " << id () << " " << signature ();
108
if (_tunits.size () > 0)
109
cout << " tunits=" << _tunits.to_string () << endl;
111
for (SSet::const_iterator iter = source_locs ().begin ();
112
iter != source_locs ().end (); ++iter)
113
(*iter).print (indent + 1);
116
/// check whether this join point is seen by a specific tranlation unit
117
bool JoinPointLoc::is_known_in_tunit (File *tunit) {
118
int tunit_id = tunit->id ();
119
if (_tunits.size () > 0)
120
return _tunits.find (tunit_id) != _tunits.end ();
121
for (SSet::const_iterator iter = source_locs ().begin ();
122
iter != source_locs ().end (); ++iter) {
123
int src_file_id = iter->file_id ();
124
if (((File*)map (src_file_id))->is_known_in_tunit (tunit))
130
string JoinPointLoc::filename () const {
131
if (source_locs ().size () == 0)
134
SSet::const_iterator last;
135
for (SSet::const_iterator iter = source_locs ().begin ();
136
iter != source_locs ().end (); ++iter) {
138
if (iter->kind () == SLK_DEF)
141
return ((File*)map (last->file_id ()))->name ();
144
int JoinPointLoc::line () const {
145
if (source_locs ().size () == 0)
148
SSet::const_iterator last;
149
for (SSet::const_iterator iter = source_locs ().begin ();
150
iter != source_locs ().end (); ++iter) {
152
if (iter->kind () == SLK_DEF)
155
return last->line ();
158
void JPL_Name::dump (int indent) const {
159
JoinPointLoc::dump (indent);
160
if (type () == Aspect || type () == Class) {
161
JPL_Class *cls = (JPL_Class*)this;
163
const set<int> &bases = cls->base_class_ids ();
164
for (set<int>::const_iterator i = bases.begin (); i != bases.end (); ++i) {
165
JPL_Class *base = (JPL_Class*)map (*i);
166
for (int i = 0; i < (indent + 1); i++) cout << " ";
167
cout << " base class " << base->signature () << endl;
170
for (CList::const_iterator iter = children ().begin ();
171
iter != children ().end (); ++iter)
172
(*iter)->dump (indent + 1);
175
static void set_str (RepoXMLNode node, const char *a, const char *v) {
176
node.set_str_prop (a, v);
179
RepoXMLNode JPL_Name::make_xml (RepoXMLNode parent) const {
180
RepoXMLNode jpn = JoinPointLoc::make_xml (parent);
181
set_str (jpn, "sig", signature ());
183
jpn.set_int_prop("builtin", 1);
184
for (CList::const_iterator iter = children ().begin ();
185
iter != children ().end (); ++iter)
186
(*iter)->make_xml (jpn);
190
JPL_Name::JPL_Name (RepoXMLNode node, RepoXMLNode::iter &curr) :
191
JoinPointLoc (node, curr) {
192
_is_built_in = node.has_prop ("builtin");
193
while (curr != node.end_child ()) {
194
JoinPointLoc *jpl = create (*curr);
202
JPL_Namespace::JPL_Namespace (RepoXMLNode node, RepoXMLNode::iter &curr) :
203
JPL_Name (node, curr){
206
JPL_Class::JPL_Class (RepoXMLNode node, RepoXMLNode::iter &curr) :
207
JPL_Name (node, curr) {
208
while (curr != node.end_child () && (*curr).has_name ("base")) {
209
int base_id = (*curr).get_int_prop ("id");
210
_base_ids.insert (base_id);
215
RepoXMLNode JPL_Class::make_xml (RepoXMLNode parent) const {
216
RepoXMLNode jpn = JPL_Name::make_xml (parent);
217
for (set<int>::const_iterator iter = _base_ids.begin ();
218
iter != _base_ids.end (); ++iter) {
219
RepoXMLNode base_node = jpn.make_child ("base");
220
base_node.set_int_prop ("id", *iter);
225
JPL_Function::JPL_Function (RepoXMLNode node, RepoXMLNode::iter &curr) :
226
JPL_Name (node, curr) {
229
JPL_Function::~JPL_Function () {
230
for (vector<JPL_Type*>::iterator iter = _arg_types.begin ();
231
iter != _arg_types.end (); ++iter)
236
JPL_MethodCall::~JPL_MethodCall () {
237
for (vector<JPL_Type*>::iterator iter = _arg_types.begin ();
238
iter != _arg_types.end (); ++iter)
243
RepoXMLNode JPL_MethodCall::make_xml (RepoXMLNode parent) const {
244
RepoXMLNode jpn = JPL_Code::make_xml (parent);
245
jpn.set_int_prop ("target", _target_id);
249
bool JPL_Function::has_same_name_and_args (const JPL_Function &func) const {
250
if (!(arg_count () == func.arg_count () && name () == func.name ()))
252
for (int a = 0; a < arg_count (); a++)
253
if (strcmp (arg_type (a).signature (), func.arg_type (a).signature ()) != 0)
258
JPL_AdviceCode::JPL_AdviceCode (RepoXMLNode node, RepoXMLNode::iter &curr) :
259
JPL_Advice (0), JPL_Function (node, curr) {
260
if (node.has_name ("advice-before"))
261
_type = ADVICE_BEFORE;
262
else if (node.has_name ("advice-after"))
263
_type = ADVICE_AFTER;
265
_type = ADVICE_AROUND;
268
RepoXMLNode JPL_AdviceCode::make_xml (RepoXMLNode parent) const {
269
RepoXMLNode jpn = JPL_Name::make_xml (parent);
273
JPL_Introduction::JPL_Introduction (RepoXMLNode node, RepoXMLNode::iter &curr) :
274
JPL_Advice (0), JoinPointLoc (node, curr) {
275
_slice_id = node.get_int_prop ("slice");
278
RepoXMLNode JPL_Introduction::make_xml (RepoXMLNode parent) const {
279
RepoXMLNode jpn = JoinPointLoc::make_xml (parent);
280
jpn.set_int_prop ("slice", _slice_id);
284
JPL_ClassSlice::JPL_ClassSlice (RepoXMLNode node, RepoXMLNode::iter &curr) :
285
JPL_Name (node, curr) {
286
if (node.has_name ("slice-dep-base"))
288
else if (node.has_name ("slice-dep-member"))
289
_type = CS_OLD_OTHER;
294
RepoXMLNode JPL_ClassSlice::make_xml (RepoXMLNode parent) const {
295
RepoXMLNode jpn = JPL_Name::make_xml (parent);