138
150
// fill the unit with a baseclass list
139
151
for (int i = 0; i < _base.length (); i++) {
140
152
IntroductionInfo *ii = _base.lookup (i);
142
// get all the needed information
143
CProtection::Type prot = ii->object (0)->Protection ();
144
bool virt = ii->object (0)->isVirtual ();
145
CTypeInfo *type = ii->object (0)->FunctionInfo ()->
146
Argument (0u)->TypeInfo ();
148
154
// generate the code for this entry
149
155
if (i > 0) result << ", ";
150
if (virt) result << "virtual ";
152
case CProtection::PROT_PRIVATE: result << "private "; break;
153
case CProtection::PROT_PROTECTED: result << "protected "; break;
154
case CProtection::PROT_PUBLIC: result << "public "; break;
157
if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
158
ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
159
// slice-based base class intro
160
CObjectInfo *obj = ii->object (0);
161
assert (obj && obj->Tree ());
162
assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
163
CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
164
CT_Intro *base = csd->base_clause ();
165
for (int e = 1; e < base->Entries (); e++) // skip entry(0) -- the ':'
166
result << base->Entry (e)->token ()->text () << " ";
169
// old-style base class intro with 'baseclass(virtual Bla)'
170
// get all the needed information
171
CProtection::Type prot = ii->object (0)->Protection ();
172
bool virt = ii->object (0)->isVirtual ();
173
CTypeInfo *type = ii->object (0)->FunctionInfo ()->
174
Argument (0u)->TypeInfo ();
176
if (virt) result << "virtual ";
178
case CProtection::PROT_PRIVATE: result << "private "; break;
179
case CProtection::PROT_PROTECTED: result << "protected "; break;
180
case CProtection::PROT_PUBLIC: result << "public "; break;
161
188
return result.str ();
164
Unit *JPP_Class::gen_intro (ErrorStream &err, CStructure *target) const {
191
Unit *JPP_Class::gen_intro (ErrorStream &err, CStructure *target,
192
LineDirectiveMgr &lmgr) const {
166
194
// create the new unit
167
195
IntroductionUnit *unit =
187
213
if (ii->prot () == CProtection::PROT_NONE)
190
// add privat/public/protected
192
prot << WeaverBase::protection_string (ii->prot ()) << " " << endu;
193
unit->move ((Token*)unit->last (), prot);
195
// obtain the pattern for this intro
196
const Unit &pattern = ii->pattern ();
198
CT_Intro *intro = (CT_Intro*)ii->tree ()->Decl ();
200
// create a formatted unit and replace the advice name with the target name
201
for (Token *curr = (Token*)pattern.first (); curr;
202
curr = (Token*)pattern.next (curr), e++) {
204
if (i < intro->NameIndices () && e == intro->NameIndex (i)) {
205
// target class name is used instead of intro token
206
tok = (Token*)target_name.first ();
209
unit->append (*tok->duplicate ());
210
if (tok->type () == TOK_OPEN_CURLY || tok->type () == TOK_SEMI_COLON)
211
unit->append (*((Token*)nl.first ())->duplicate ());
216
// TODO: member intros from slices are ignored here!
217
if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
218
ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
219
CObjectInfo *obj = ii->object (0);
220
assert (obj && obj->Tree ());
221
assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
222
CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
224
ACUnit slice_start (err);
225
if (ii->prot () == CProtection::PROT_PRIVATE)
226
slice_start << " private:" << endl;
213
unit->append (*((Token*)ws.first ())->duplicate ());
228
slice_start << " public:" << endl;
229
// add " typedef <target-name> <slice-name>;\n"
230
if (!obj->isAnonymous ()) {
231
slice_start << " typedef " << target->Name () << " "
232
<< obj->Name () << ";" << endl;
235
unit->move ((Token*)unit->last (), slice_start);
236
// generate the intro itself from the stored pattern
237
Token *curr = (Token*)ii->pattern ().first ();
238
Location loc = curr->location ();
240
lmgr.directive (dir, (Unit*)&ii->pattern (), curr);
243
unit->move ((Token*)unit->last (), dir);
244
for (int m = 0; m < csd->members ()->Entries (); m++) {
246
tmp_pattern.name (ii->pattern ().name ());
247
CT_Intro *intro = (CT_Intro*)csd->members ()->Entry (m);
248
for (int i = 0; i < intro->Entries (); i++) {
249
tmp_pattern.append (*curr->duplicate ());
250
curr = (Token*)ii->pattern ().next (curr);
252
instantiate_intro (err, unit, intro, tmp_pattern, target_name, loc);
256
// add privat/public/protected
258
prot << WeaverBase::protection_string (ii->prot ()) << " " << endu;
259
unit->move ((Token*)unit->last (), prot);
261
// obtain the pattern for this intro
262
const Unit &pattern = ii->pattern ();
264
CT_Intro *intro = (CT_Intro*)ii->tree ()->Decl ();
265
Token *curr = (Token*)ii->pattern ().first ();
267
lmgr.directive (dir, (Unit*)&pattern, curr);
270
unit->move ((Token*)unit->last (), dir);
271
Location loc = ((Token*)pattern.first ())->location ();
272
instantiate_intro (err, unit, intro, pattern, target_name, loc);
278
void JPP_Class::instantiate_intro (ErrorStream &err, Unit *unit,
279
CT_Intro *intro, const Unit &pattern, Unit &target_name,
280
Location &loc) const {
282
// ... some units for formatting
289
// create a formatted unit and replace the advice name with the target name
290
for (Token *curr = (Token*)pattern.first (); curr;
291
curr = (Token*)pattern.next (curr), e++) {
293
if (curr->location ().line () != loc.line ()) {
294
for (int l = loc.line (); l < curr->location ().line (); l++)
295
unit->append (*((Token*)nl.first ())->duplicate ());
296
loc = curr->location ();
299
unit->append (*((Token*)ws.first ())->duplicate ());
300
if (i < intro->NameIndices () && e == intro->NameIndex (i)) {
301
// target class name is used instead of intro token
302
tok = (Token*)target_name.first ();
305
unit->append (*tok->duplicate ());