143
string JPP_Class::gen_baseclass_list () const {
145
// do nothing if there are no base classes to add
146
if (_base.length () == 0)
149
ostringstream result;
150
// fill the unit with a baseclass list
151
for (int i = 0; i < _base.length (); i++) {
152
IntroductionInfo *ii = _base.lookup (i);
154
// generate the code for this entry
155
if (i > 0) result << ", ";
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;
188
return result.str ();
191
Unit *JPP_Class::gen_intro (ErrorStream &err, CStructure *target,
192
LineDirectiveMgr &lmgr) const {
194
// create the new unit
195
IntroductionUnit *unit =
196
new IntroductionUnit ((Unit*)target->Tree ()->token ()->belonging_to ());
198
// create a unit with the target class name
199
ACUnit target_name (err);
200
target_name << target->Name () << endu;
140
void JPP_Class::gen_intros (list<Unit*> &units, ErrorStream &err,
141
CStructure *target, LineDirectiveMgr &lmgr, bool non_inline) const {
201
143
// ... some unit for formatting
203
145
ws << " " << endu;
205
// at least on token is needed in the unit for 'move' (see below)
206
unit->append (*((Token*)ws.first ())->duplicate ());
208
147
// handle all intros
209
148
for (int i = 0; i < otherIntros (); i++) {
210
IntroductionInfo *ii = otherIntro (i);
149
JPL_Introduction *ii = otherIntro (i);
212
// ignore non-inline introductions here (for now)
213
if (ii->prot () == CProtection::PROT_NONE)
151
// create the new unit
152
IntroductionUnit *unit =
153
new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ());
156
// at least on token is needed in the unit for 'move' (see below)
157
unit->append (*((Token*)ws.first ())->duplicate ());
216
159
// 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);
160
if (ii->introduced ()->slice_type () == JPL_ClassSlice::CS_NORMAL) {
161
CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
220
162
assert (obj && obj->Tree ());
221
163
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;
164
ACSliceInfo *acsi = obj->ClassDB ()->SliceInfo (obj)->definition ();
166
gen_intro_non_inline (unit, ii, acsi, err, lmgr, target);
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);
168
gen_intro_inline (unit, ii, acsi, err, lmgr, target);
256
// add privat/public/protected
258
prot << WeaverBase::protection_string (ii->prot ()) << " " << endu;
259
unit->move ((Token*)unit->last (), prot);
170
else if ((ii->introduced ()->prot () == CProtection::PROT_NONE && non_inline) ||
171
(ii->introduced ()->prot () != CProtection::PROT_NONE && !non_inline)) {
173
// add privat/public/protected
175
prot << WeaverBase::protection_string (ii->introduced ()->prot ()) << " " << endu;
176
unit->move ((Token*)unit->last (), prot);
261
179
// obtain the pattern for this intro
262
const Unit &pattern = ii->pattern ();
180
const Unit &pattern = ii->introduced ()->pattern ();
264
CT_Intro *intro = (CT_Intro*)ii->tree ()->Decl ();
265
Token *curr = (Token*)ii->pattern ().first ();
182
CT_Intro *intro = (CT_Intro*)TI_Introduction::of (*ii)->tree ()->Decl ();
183
Token *curr = (Token*)ii->introduced ()->pattern ().first ();
266
184
ACUnit dir (err);
267
185
lmgr.directive (dir, (Unit*)&pattern, curr);
269
187
if (!dir.empty ())
270
188
unit->move ((Token*)unit->last (), dir);
271
189
Location loc = ((Token*)pattern.first ())->location ();
272
instantiate_intro (err, unit, intro, pattern, target_name, loc);
190
instantiate_intro (err, unit, intro, pattern, target, loc);
193
// if there was no introduction return 0
194
if (unit->first () == unit->last ())
197
units.push_back (unit);
202
void JPP_Class::gen_intro_inline (Unit *unit, JPL_Introduction *ii,
203
ACSliceInfo *acsi, ErrorStream &err, LineDirectiveMgr &lmgr,
204
CStructure *target) const {
206
CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
207
CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
210
ACUnit slice_start (err);
211
if (ii->introduced ()->prot () == CProtection::PROT_PRIVATE)
212
slice_start << " private:" << endl;
214
slice_start << " public:" << endl;
215
// add " typedef <target-name> <slice-name>;\n"
216
if (!obj->isAnonymous ()) {
217
slice_start << " typedef " << target->Name () << " "
218
<< obj->Name () << ";" << endl;
221
unit->move ((Token*)unit->last (), slice_start);
222
// generate the intro itself from the stored pattern
223
const Unit &pattern = *acsi->pattern ();
224
Token *curr = (Token*)pattern.first ();
225
Location loc = curr->location ();
227
lmgr.directive (dir, (Unit*)&pattern, curr);
230
unit->move ((Token*)unit->last (), dir);
231
for (int m = 0; m < csd->members ()->Entries (); m++) {
233
tmp_pattern.name (pattern.name ());
234
CT_Intro *intro = (CT_Intro*)csd->members ()->Entry (m);
235
for (int i = 0; i < intro->Entries (); i++) {
236
tmp_pattern.append (*curr->duplicate ());
237
curr = (Token*)pattern.next (curr);
239
instantiate_intro (err, unit, intro, tmp_pattern, target, loc);
243
void JPP_Class::gen_intro_non_inline (Unit *unit, JPL_Introduction *ii,
244
ACSliceInfo *acsi, ErrorStream &err, LineDirectiveMgr &lmgr,
245
CStructure *target) const {
247
// generate the intros from the stored non-inline member patterns
248
for (int m = 0; m < acsi->members (); m++) {
249
CT_Intro *intro = acsi->member (m);
250
const Unit &pattern = *acsi->member_pattern (m);
251
Token *curr = (Token*)pattern.first ();
252
Location loc = curr->location ();
254
lmgr.directive (dir, (Unit*)&pattern, curr);
257
unit->move ((Token*)unit->last (), dir);
258
instantiate_intro (err, unit, intro, pattern, target, loc);
263
void JPP_Class::gen_base_intro (IntroductionUnit &intro_unit,
264
JPL_Introduction *ii, bool first) const {
266
// generate the code for this entry
267
intro_unit << (first ? ": " : ", ");
269
if (ii->introduced ()->slice_type () == JPL_ClassSlice::CS_NORMAL) {
270
// slice-based base class intro
271
CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
272
assert (obj && obj->Tree ());
273
assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
274
ACSliceInfo *acsi = obj->ClassDB ()->SliceInfo (obj)->definition ();
275
const Unit &base = *acsi->base_pattern ();
276
for (Token *curr = (Token*)base.first (); curr;
277
curr = (Token*)base.next (curr)) {
278
intro_unit << *curr << " ";
282
// old-style base class intro with 'baseclass(virtual Bla)'
283
// get all the needed information
284
CObjectInfo *obj = TI_ClassSlice::of (*ii->introduced ())->assoc_obj ();
285
CProtection::Type prot = obj->Protection ();
286
bool virt = obj->isVirtual ();
287
CTypeInfo *type = obj->FunctionInfo ()->Argument (0u)->TypeInfo ();
289
if (virt) intro_unit << "virtual ";
291
case CProtection::PROT_PRIVATE: intro_unit << "private "; break;
292
case CProtection::PROT_PROTECTED: intro_unit << "protected "; break;
293
case CProtection::PROT_PUBLIC: intro_unit << "public "; break;
303
void JPP_Class::gen_base_intros (list<Unit*> &units, ErrorStream &err,
304
CClassInfo *target, LineDirectiveMgr &lmgr) const {
306
for (int i = 0; i < _base.length (); i++) {
307
// get the current introduction
308
JPL_Introduction *ii = _base.lookup (i);
310
// create the new unit
311
IntroductionUnit *unit =
312
new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ());
315
// generate the code for this base class introduction
316
gen_base_intro (*unit, ii, (i == 0));
318
// store the result for the caller
319
units.push_back (unit);
278
323
void JPP_Class::instantiate_intro (ErrorStream &err, Unit *unit,
279
CT_Intro *intro, const Unit &pattern, Unit &target_name,
324
CT_Intro *intro, const Unit &pattern, CStructure *target,
280
325
Location &loc) const {
327
// create a unit with the target class name
328
ACUnit target_name (err);
329
target_name << target->Name () << endu;
330
ACUnit target_qual_name (err);
331
target_qual_name << target->QualName () << endu;
282
333
// ... some units for formatting
284
335
nl << endl << endu;