~ubuntu-branches/ubuntu/wily/aspectc++/wily

« back to all changes in this revision

Viewing changes to Puma/gen-release/step1/src/CCInstantiation.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2009-06-15 10:17:02 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090615101702-qsr30iptwbxylmo2
Tags: 1.0pre4~svn.20090615-1
* New upstream release.
* don't ignore errors in the postrm script
* avoid spurious creation of empty dir ./usr/sbin/
* improve short descriptions of libpuma-doc and libpuma-dev
* bump Standards-Version to 3.8.1
* bump debhelper compat level to level 7 (latest in stable)

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include "Puma/CFileInfo.h"
40
40
#include "Puma/CSourceInfo.h"
41
41
#include "Puma/CCConversions.h"
 
42
#include "Puma/TemplateInstanceUnit.h"
42
43
 
43
44
#include <stdio.h>      /* sprintf() */
44
 
#include <sstream>  /* ostringstream */
 
45
#include <stdlib.h>     /* strtol() */
 
46
#include <sstream>      /* ostringstream */
45
47
using namespace std;
46
48
 
47
49
namespace Puma {
48
50
 
49
51
 
50
52
/*DEBUG*/int TRACE_INSTANCE_CODE = 0;
 
53
/*DEBUG*/int TRACE_PARSE_INSTANCE = 0;
51
54
 
52
55
 
53
56
#define SEM_ERROR(loc__,mesg__) \
56
59
        << mesg__ << endMessage;}}
57
60
 
58
61
 
59
 
// maximal instantiation depth
60
 
const unsigned CCInstantiation::MAX_DEPTH = 50;
61
 
 
62
 
unsigned int CCInstantiation::m_ScopeNameCounter = 0;
63
 
 
64
 
 
65
62
CCInstantiation::CCInstantiation (ErrorSink &e, bool rep) : err (e) {
66
63
  instance      = 0;
67
64
  last_instance = 0;
71
68
 
72
69
  base_candidate = new InstantiationCandidate;
73
70
  candidates[0] = base_candidate;
74
 
  First ().initialize (rep ? &e : (ErrorSink*)0);
 
71
  base_candidate->initialize (rep ? &e : (ErrorSink*)0);
75
72
}
76
73
 
77
74
 
88
85
 
89
86
 
90
87
// start instantiation process
91
 
CObjectInfo *CCInstantiation::instantiate (CTree *node, 
92
 
 CObjectInfo *binfo, const CCOverloading &ovl) {
93
 
  // function call arguments
94
 
  unsigned args = ovl.Arguments ();
95
 
  for (unsigned i = 0; i < args; i++)
96
 
    First ().addArgument (ovl.Argument (i));
97
 
 
98
 
  return instantiate (node, binfo, true);
99
 
}
100
 
 
101
 
 
102
 
// start instantiation process
103
 
CObjectInfo *CCInstantiation::instantiate (CTree *node, 
104
 
 CObjectInfo *binfo, bool real_inst, CStructure *cs) {
 
88
CObjectInfo *CCInstantiation::instantiate (CTree *node,
 
89
 CObjectInfo *binfo, bool real_inst, CStructure *cs, bool inst_immediately) {
105
90
  // don't call twice
106
91
  if (instance || ! binfo || ! node)
107
92
    return instance;
108
93
 
109
94
  First ().initialize (node, binfo);
110
95
  current_scope = cs;
111
 
  
112
 
// TEMPORARY HACK --->
113
 
  if (! ObjectInfo ()->SemDB ()->Project ()->config ().Option ("--real-instances")) 
 
96
 
 
97
  if (! ObjectInfo ()->SemDB ()->Project ()->config ().Option ("--real-instances"))
114
98
    real_inst = false;
115
 
// TEMPORARY HACK <---
116
99
 
117
100
  // §14.8.2 deduce template arguments
118
101
  if (! First ().deduceArguments (real_inst))
119
102
    return instance;
120
 
  
 
103
 
121
104
  // choose the appropriate template specialization (if any)
122
105
  if (! chooseSpecialization ()) {
123
106
    return instance;
125
108
 
126
109
  // instantiate template if not already done before
127
110
  if (! alreadyInstantiated (real_inst)) {
128
 
    // check maximal instantiation depth
129
 
    if (TemplateInfo ()->Depth () >= MAX_DEPTH) {
130
 
      err << sev_fatal << PointOfInstantiation ()->token ()->location () 
131
 
          << "maximal instantiation depth ("
132
 
          << MAX_DEPTH << ") reached" << endMessage;
133
 
      return instance;
134
 
    }
135
 
 
136
111
    // create an instance of the template
137
 
    if (real_inst)
138
 
      createInstance ();
139
 
    else
140
 
      createPseudoInstance ();
141
 
    
142
 
    // do not delete the deduced arguments
 
112
    createPseudoInstance ();
 
113
 
143
114
    if (instance) {
 
115
      // do not delete the deduced arguments
144
116
      First ().forgetDeducedArgs ();
145
117
      if (base_candidate != &First ())
146
118
        base_candidate->forgetDeducedArgs ();
 
119
 
 
120
      instance->TemplateInstance ()->canInstantiate (real_inst);
 
121
 
 
122
      if (real_inst && inst_immediately) {
 
123
        instance = instance->TemplateInstance ()->instantiate (cs) ? instance : 0;
 
124
      }
147
125
    }
148
 
  }    
149
 
    
 
126
  }
 
127
 
150
128
  return instance;
151
129
}
152
130
 
161
139
  CT_TemplateArgList *args;
162
140
 
163
141
  // only class templates can be partially specialized
164
 
  if (ObjectInfo ()->FunctionInfo ()) 
 
142
  if (ObjectInfo ()->FunctionInfo ())
165
143
    return true;
166
144
 
167
145
  // iterate specializations
180
158
    // create new instantiation candidate
181
159
    InstantiationCandidate *cand = new InstantiationCandidate;
182
160
    cand->initialize (PointOfInstantiation (), info, tinfo, report ? &err : (ErrorSink*)0);
183
 
    
 
161
 
184
162
    // add the template arguments of the partial specialization
185
163
    entries = args->Entries ();
186
164
    for (unsigned j = 0; j < entries; j++)
189
167
    no_default = false;
190
168
    for (unsigned j = entries; j < TemplateInfo ()->Parameters (); j++) {
191
169
      // no default argument? this is an error
192
 
      if (! TemplateInfo ()->Parameter (i)->DefaultArgument ()) {
 
170
      if (! TemplateInfo ()->Parameter (j)->DefaultArgument ()) {
193
171
        no_default = true;
194
172
        cand->reset ();
195
173
        delete cand;
196
174
        break;
197
175
      }
198
 
      cand->addArgument (TemplateInfo ()->Parameter (i)->DefaultArgument ());
 
176
      cand->addArgument (TemplateInfo ()->Parameter (j)->DefaultArgument ());
199
177
    }
200
178
    if (no_default)
201
179
      continue;
290
268
  if (report) {
291
269
    std::ostringstream name;
292
270
    name << ObjectInfo ()->Name ();
293
 
    listArguments (*base_candidate, name);
294
 
    err << sev_error << PointOfInstantiation ()->token ()->location () 
295
 
        << "Instantiation of `" << name.str ().c_str () 
 
271
    base_candidate->printArgumentList (name);
 
272
    err << sev_error << getPoiToken()->location ()
 
273
        << "Instantiation of `" << name.str ().c_str ()
296
274
        << "' is ambiguous" << endMessage;
297
275
    for (int i = 1; i < candidates.length (); i++) {
298
276
      InstantiationCandidate *cand = candidates[i];
311
289
 
312
290
 
313
291
bool CCInstantiation::alreadyInstantiated (bool real_inst) {
314
 
  CObjectInfo *ti;
315
 
  bool cont;
316
 
 
317
292
  last_instance = 0;
318
293
  for (unsigned i = 0; i < TemplateInfo ()->Instances (); i++) {
319
 
    ti = TemplateInfo ()->Instance (i);
320
 
    cont = false;
321
 
// TEMPORARY HACK --->
322
 
    if ((TemplateInfo ()->isBaseTemplate () == 
323
 
         ti->TemplateInstance ()->Template ()->isBaseTemplate ()) && 
 
294
    CObjectInfo *ti = TemplateInfo ()->Instance (i);
 
295
    bool cont = false;
 
296
 
 
297
    if ((TemplateInfo ()->isBaseTemplate () ==
 
298
         ti->TemplateInstance ()->Template ()->isBaseTemplate ()) &&
324
299
        (DeducedArgs () == ti->TemplateInstance ()->DeducedArgs ())) {
325
300
      for (unsigned j = 0; j < ti->TemplateInstance ()->DeducedArgs (); j++)
326
 
        if (! (*DeducedArg (j) == *ti->TemplateInstance ()->DeducedArg (j)))
 
301
        if (*DeducedArg (j) != *ti->TemplateInstance ()->DeducedArg (j))
327
302
          cont = true;
328
303
    } else
329
304
      cont = true;
330
 
// TEMPORARY HACK <---
 
305
 
331
306
    if (! cont) {
332
307
      instance = ti;
333
308
      if ((ti->FunctionInfo () && ti->FunctionInfo ()->isFctDef ()) ||
338
313
        last_instance = ti;
339
314
    }
340
315
  }
341
 
  
 
316
 
342
317
  instance = 0;
343
 
  if (last_instance) { 
 
318
  if (last_instance) {
344
319
    if (real_inst &&
345
320
        ((ObjectInfo ()->FunctionInfo () && ObjectInfo ()->FunctionInfo ()->isFctDef ()) ||
346
321
         (ObjectInfo ()->Record () && ObjectInfo ()->Record ()->isDefined ())))
347
322
      return false;
348
323
    instance = last_instance;
349
324
    last_instance = 0;
350
 
    return true;    
351
 
  } 
 
325
    return true;
 
326
  }
352
327
  return false;
353
328
}
354
329
 
380
355
  instance->SourceInfo ()->FileInfo (ObjectInfo ()->SourceInfo ()->FileInfo ());
381
356
  instance->SourceInfo ()->StartToken (PointOfInstantiation ()->token_node ());
382
357
  instance->TypeInfo (ObjectInfo ()->TypeInfo ()->Duplicate ());
383
 
  ti->PointOfInstantiation (getSimpleName (), current_scope);
 
358
  ti->PointOfInstantiation (PointOfInstantiation (), current_scope);
384
359
  ti->Template (TemplateInfo ());
 
360
  ti->Object (instance);
385
361
  ti->isPseudoInstance (true);
386
362
  if (instance->FunctionInfo ())
387
363
    instance->TypeInfo ()->TypeFunction ()->FunctionInfo (instance->FunctionInfo ());
393
369
    ti->addDeducedArg (DeducedArg (i));
394
370
  for (unsigned i = 0; i < base_candidate->DeducedArgs (); i++)
395
371
    ti->addInstantiationArg (base_candidate->DeducedArg (i));
396
 
  if (! instance->TemplateParamInfo ()) {
397
 
    TemplateInfo ()->addPseudoInstance (instance);
398
 
  }
399
 
}
400
 
 
401
 
 
402
 
void CCInstantiation::createInstance () {
 
372
  TemplateInfo ()->addInstance (instance);
 
373
}
 
374
 
 
375
 
 
376
void CCInstantiation::setupFromPseudoInstance (CTemplateInstance* instinfo, CStructure* scope) {
 
377
  instance = instinfo->Object ();
 
378
  current_scope = (scope && scope == instance) ? scope->Parent ()->Structure () : scope;
 
379
  CObjectInfo* defobj = instinfo->Template ()->ObjectInfo ()->DefObject ();
 
380
  base_candidate->initialize (instinfo->PointOfInstantiation (), defobj, defobj->Template ());
 
381
  for (unsigned i = 0; i < instinfo->DeducedArgs (); i++)
 
382
    base_candidate->addDeducedArg (instinfo->DeducedArg (i));
 
383
}
 
384
 
 
385
 
 
386
bool CCInstantiation::instantiate (CTemplateInstance* instinfo, CStructure* instscope) {
403
387
  CTranslationUnit *tu;
404
388
  CStructure *scope;
405
389
  CProject *project;
406
390
  bool fct_inst;
407
391
  CUnit *unit;
408
392
 
 
393
  // setup from the pseudo instance information to
 
394
  // reset the correct instantiation information
 
395
  setupFromPseudoInstance (instinfo, instscope);
 
396
 
 
397
  // check maximal instantiation depth
 
398
  if (maxInstDepthReached ()) {
 
399
    First ().forgetDeducedArgs ();
 
400
    removeInstance ();
 
401
    return false;
 
402
  }
 
403
 
409
404
  // increase instantiation depth
410
405
  TemplateInfo ()->increaseDepth ();
411
406
 
412
 
  scope = makeScope ();
 
407
  scope = instance->TemplateParamInfo () ? makeScope () : instance->Scope ()->Structure ();
413
408
  fct_inst = (ObjectInfo ()->FunctionInfo ());
414
409
  project = ObjectInfo ()->SemDB ()->Project ();
415
 
  unit = new CUnit (err);
 
410
  unit = new TemplateInstanceUnit (err, getPoiToken()->unit(), instinfo);
 
411
  unit->scanner ().configure (project->config ());
416
412
  unit->name (scope->Name ());
417
413
 
418
414
  // create code for the template instance
421
417
  // setup new parser for the instantiated code
422
418
  trans_unit = tu = new CTranslationUnit (*unit, *project);
423
419
  CCParser p;
424
 
  p.syntax ().configure (project->config ());
425
 
  p.semantic ().configure (project->config ());
 
420
  p.configure (project->config ());
 
421
  if (TRACE_PARSE_INSTANCE) {
 
422
#ifdef __PUMA_TRACING__
 
423
    p.trace(std::cout);
 
424
#endif
 
425
  }
 
426
 
426
427
  // setup the preprocessor
427
428
  TokenStream stream;
428
429
  stream.push (unit); 
 
430
  project->unitManager ().init ();
429
431
  PreprocessorParser cpp (&project->err (), 
430
432
    &project->unitManager (), &tu->local_units ());
431
433
  cpp.macroManager ()->init (unit->name ());
432
434
  cpp.stream (&stream);
433
435
  cpp.configure (project->config (), false); // do not process --include option
 
436
 
434
437
  // initialize semantic analyzer
435
438
  p.semantic ().init (*ObjectInfo ()->SemDB (),
436
439
    *ObjectInfo ()->SourceInfo ()->FileInfo ()->Primary (), 
437
440
    scope, fct_inst, ! fct_inst, this);   
438
441
  ((ErrorCollector&)p.builder ().err ()).index (0);
439
442
  p.semantic ().error_sink (p.builder ().err ());
 
443
 
 
444
  // start parsing 
440
445
  TokenProvider provider (cpp);
441
 
  // start parsing 
442
446
  tu->tree (p.syntax ().run (provider)); 
443
447
  tu->cpp_tree (cpp.syntaxTree ());
444
448
 
449
453
  if (((ErrorCollector&)p.builder ().err ()).severity () > sev_warning) {
450
454
    removeInstance ();
451
455
    if (report) {
452
 
      err << PointOfInstantiation ()->token ()->location () 
 
456
      err << getPoiToken()->location ()
453
457
          << "In instantiation of `" << scope->Name ().c_str ()+1 
454
458
          << "':" << endMessage;
455
459
      p.builder ().errors (err);
467
471
      //delete unit;
468
472
    }
469
473
  }
 
474
 
 
475
  First ().forgetDeducedArgs ();
 
476
  return instance;
 
477
}
 
478
 
 
479
 
 
480
bool CCInstantiation::maxInstDepthReached () {
 
481
  // ISO says not more than 17
 
482
  unsigned max_depth = 17;
 
483
  // maximum set by user?
 
484
  const ConfOption *opt = TemplateInfo ()->SemDB ()->Project ()->config ().Option ("--template-depth");
 
485
  if (opt && opt->Arguments () > 0) {
 
486
    max_depth = strtol (opt->Argument (0), NULL, 10);
 
487
  }
 
488
  if (TemplateInfo ()->Depth () > max_depth) {
 
489
    CTemplateInstance* topinst = 0;
 
490
    Unit* unit = getPoiToken()->unit ();
 
491
    while (unit->isTemplateInstance ()) {
 
492
      TemplateInstanceUnit* tiunit = (TemplateInstanceUnit*)unit;
 
493
      topinst = tiunit->TemplateInstance ();
 
494
      unit = tiunit->ContainingUnit ();
 
495
    }
 
496
    if (topinst && topinst->Object()) {
 
497
      err << getPoiToken(topinst)->location ()
 
498
          << "In instantiation of `" << *topinst->Object()->TypeInfo()
 
499
          << "':" << endMessage;
 
500
    }
 
501
    err << sev_error << getPoiToken()->location ()
 
502
        << "maximum instantiation depth ("
 
503
        << max_depth << ") reached" << endMessage;
 
504
    return true;
 
505
  }
 
506
  return false;
 
507
}
 
508
 
 
509
 
 
510
Token* CCInstantiation::getPoiToken(CTemplateInstance* ti) {
 
511
  Token* tok = 0;
 
512
  if (ti) {
 
513
    CTree* poi = ti->PointOfInstantiation();
 
514
    do {
 
515
      tok = poi->token();
 
516
    } while (! tok && (poi = poi->Parent()));
 
517
  } 
 
518
  else {
 
519
    tok = First().getPointOfInstantiationToken();
 
520
  }
 
521
  return tok;
470
522
}
471
523
 
472
524
 
473
525
void CCInstantiation::insertInstance (CObjectInfo *info) {
474
 
  if (! info || ! info->TemplateInstance ())
475
 
    return;
476
 
 
477
 
  instance = info;
478
 
  for (unsigned i = 0; i < DeducedArgs (); i++)
479
 
    instance->TemplateInstance ()->addDeducedArg (DeducedArg (i));
480
 
  for (unsigned i = 0; i < base_candidate->DeducedArgs (); i++)
481
 
    instance->TemplateInstance ()->addInstantiationArg (base_candidate->DeducedArg (i));
482
 
  if (last_instance && last_instance != instance)
483
 
    instance->NextObject (last_instance);
484
 
  instance->TemplateInstance ()->PointOfInstantiation (getSimpleName (),
485
 
    current_scope);
486
 
  instance->TemplateInstance ()->Template (TemplateInfo ());
487
 
  instance->TemplateInstance ()->TranslationUnit (trans_unit);
488
 
  TemplateInfo ()->addInstance (instance);
489
 
}    
 
526
  if (info && info->TemplateInstance ()) {
 
527
    instance = info;
 
528
    if (last_instance && last_instance != instance)
 
529
      instance->NextObject (last_instance);
 
530
    instance->TemplateInstance ()->TranslationUnit (trans_unit);
 
531
  }
 
532
}
490
533
 
491
534
 
492
535
void CCInstantiation::removeInstance () {
493
 
  if (! instance)
494
 
    return;
495
 
 
496
 
  TemplateInfo ()->removeInstance (instance);
497
 
  instance->TemplateInstance ()->clearDeducedArgs ();
498
 
  instance->TemplateInstance ()->PointOfInstantiation (0, 0);
499
 
  instance->TemplateInstance ()->TranslationUnit (0);
500
536
  instance = 0;
501
 
}    
 
537
}
 
538
 
 
539
 
 
540
CStructure *CCInstantiation::makeScope () {
 
541
  CStructure *scope;
 
542
 
 
543
  // create namespace name
 
544
  std::ostringstream sname;
 
545
  sname << "%" << ObjectInfo ()->Name ();
 
546
  base_candidate->printArgumentList (sname);
 
547
 
 
548
  scope = TemplateInfo ()->Parent ()->newNamespace ();
 
549
  scope->NamespaceInfo ()->aroundInstantiation (true);
 
550
  scope->Name (sname.str ().c_str ());
 
551
  scope->TypeInfo (&CTYPE_UNDEFINED);
 
552
  scope->SemDB (ObjectInfo ()->SemDB ());
 
553
  scope->SourceInfo ()->FileInfo (ObjectInfo ()->SourceInfo ()->FileInfo ());
 
554
  scope->SourceInfo ()->StartToken (PointOfInstantiation ()->token_node ());
 
555
  return scope;
 
556
}
 
557
 
 
558
 
 
559
void CCInstantiation::listParameters (CUnit &unit, CTemplateInfo *ti) {
 
560
  CTemplateParamInfo *tp;
 
561
  CT_TypeParamDecl *tpd;
 
562
  CT_NonTypeParamDecl *ntpd;
 
563
  const char* name;
 
564
 
 
565
  for (unsigned i = 0; i < ti->Parameters (); ++i) {
 
566
    if (i > 0) {
 
567
      unit << ",";
 
568
    }
 
569
    tp = ti->Parameter (i);
 
570
    char anonymous[100];
 
571
    name = tp->Name ();
 
572
    if (*tp->Name () == '%') {
 
573
      sprintf(anonymous, "__puma_%s", name+1);
 
574
      name = anonymous;
 
575
    }
 
576
    if (tp->isTypeParam ()) {
 
577
      tpd = (CT_TypeParamDecl*)tp->Tree ();
 
578
      copyTree (unit, tpd, findPrivateName (tpd->Name ()), name);
 
579
    } else {
 
580
      ntpd = (CT_NonTypeParamDecl*)tp->Tree ();
 
581
      copyTree (unit, ntpd, findPrivateName (ntpd->Declarator ()), name);
 
582
    }
 
583
  }
 
584
}
502
585
 
503
586
 
504
587
void CCInstantiation::fillUnit (CUnit &unit) {
 
588
  CTemplateParamInfo *param, *tp;
505
589
  DeducedArgument *arg;
506
 
  CTemplateParamInfo *param;
507
590
  CTree *default_arg;
508
 
  CTypeInfo *type;
509
 
  std::ostringstream psname;
510
 
  
511
 
  psname << "__puma_" << m_ScopeNameCounter;
512
 
  m_ScopeNameCounter++;
 
591
  CTemplateInfo *ti;
 
592
 
513
593
  for (unsigned i = 0; i < DeducedArgs (); i++) {
514
594
    arg = DeducedArg (i);
515
595
    param = arg->TemplateParam ();
516
 
    // unnamed and template template parameters are special, 
517
 
    // nothing needs to be generated
518
 
    if (! param || param->isTemplate () || ! param->Name () || 
519
 
        *param->Name () == '%')
 
596
    if (! param)
520
597
      continue;
521
 
      
 
598
 
 
599
    // get the name of the parameter, generate one
 
600
    // if the parameter is anonymous
 
601
    char anonymous[100];
 
602
    const char* name = param->Name ();
 
603
    if (*name == '%') {
 
604
      sprintf(anonymous, "__puma_%s", name+1);
 
605
      name = anonymous;
 
606
    }
 
607
 
 
608
    // deduced template-template argument
 
609
    if (param->isTemplate ()) {
 
610
      ti = param->TemplateTemplate ();
 
611
      unit << "template< ";
 
612
      listParameters(unit, param->TemplateTemplate ());
 
613
      unit << " > struct " << name;
 
614
      unit << " {\n  typedef ";
 
615
      if (arg->isDefaultArg () && arg->TemplateArg ()) {
 
616
        copyTree (unit, arg->TemplateArg (), arg->TemplateArg ()->end_token ());
 
617
      } else if (arg->Type ()) {
 
618
        arg->Type ()->TypeText (unit, 0, true);
 
619
      }
 
620
      unit << "<";
 
621
      for (unsigned j = 0; j < ti->Parameters (); ++j) {
 
622
        if (j > 0) {
 
623
          unit << ",";
 
624
        }
 
625
        tp = ti->Parameter (j);
 
626
        if (*tp->Name () != '%') {
 
627
          unit << tp->Name ();
 
628
        } else {
 
629
          unit << "__puma_" << tp->Name ()+1;
 
630
        }
 
631
      }
 
632
      unit << "> __puma_redirect;\n};\n" << endu;
522
633
    // deduced type argument
523
 
    if (param->isTypeParam ()) {
 
634
    } else if (param->isTypeParam ()) {
524
635
      // default template argument
525
 
      if (arg->isDefaultArg ()) {
 
636
      if (arg->isDefaultArg () && arg->TemplateArg ()) {
526
637
        unit << "typedef ";
527
638
        default_arg = arg->TemplateArg ();
528
 
        genArgType (unit, default_arg, findPrivateName (default_arg), param->Name ());
 
639
        copyTree (unit, default_arg, findPrivateName (default_arg), name);
529
640
        unit << ";\n" << endu;
530
641
      } else if (arg->Type ()) {
531
 
        unit << "namespace " << psname.str () << " {\n";
532
642
        unit << "typedef ";
533
 
        arg->Type ()->TypeText (unit, param->Name (), true);
534
 
        unit << ";\n}\n" << "using " << psname.str () << "::" 
535
 
             << param->Name () << ";\n" << endu;
 
643
        arg->Type ()->TypeText (unit, name, true);
 
644
        unit << ";\n" << endu;
536
645
      }
537
646
    // deduced non-type argument
538
647
    } else {
539
648
      unit << "static ";
540
 
      type = param->ValueType ();
541
 
      if (! type->isConst ()) {
542
 
        // turn it into a const type
543
 
        type = new CTypeQualified (type->Duplicate (), true, false, false);
544
 
        type->TypeText (unit, param->Name (), true);
545
 
        delete type;
546
 
      } else {
547
 
        type->TypeText (unit, param->Name (), true);
548
 
      }
 
649
      CT_NonTypeParamDecl* decl = (CT_NonTypeParamDecl*)param->Tree ();
 
650
      copyTree (unit, decl->DeclSpecs (), 0, name);
 
651
      unit << " ";
 
652
      copyTree (unit, decl->Declarator (), findName (decl->Declarator ()), name,
 
653
        param->ValueType () && ! param->ValueType ()->isConst ());
549
654
      // default template argument
550
 
      if (arg->isDefaultArg ()) {
 
655
      if (arg->isDefaultArg () && arg->TemplateArg ()) {
551
656
        unit << " = ";
552
 
        copyTree (unit, arg->TemplateArg ());
 
657
        copyTree (unit, arg->TemplateArg (), arg->TemplateArg ()->end_token ());
553
658
      } else if (arg->Value ()) {
554
659
        unit << " = " << *(arg->Value ());
555
660
      }
556
661
      unit << ";\n" << endu;
557
662
    }
558
663
  }
559
 
  
 
664
 
560
665
  // check for a template parameter in the class name -> desturbs
561
666
  Array<CTree*> desturbing;
562
667
  if (ObjectInfo ()->Tree ()->NodeName () == CT_ClassDef::NodeId ()) {
566
671
    CT_MembList *members = clsdef->Members ();
567
672
    if (members) { // normally true, but in case of parse errors (?) ...
568
673
      for (int i = 0; i < members->Entries (); i++) {
569
 
        if (members->Entry (i)->NodeName () == CT_FctDef::NodeId ()) {
570
 
          CT_FctDef *fctdef = (CT_FctDef*)members->Entry (i);
571
 
          CT_SimpleName *nm =((CT_Declarator*)fctdef->Declarator ())->Name ();
572
 
          if (nm->NodeName () == CT_TemplateName::NodeId ())
573
 
            desturbing.append (((CT_TemplateName*)nm)->Arguments ());
574
 
        }
 
674
        if (members->Entry (i)->NodeName () == CT_FctDef::NodeId ()) {
 
675
          CT_FctDef *fctdef = (CT_FctDef*)members->Entry (i);
 
676
          CT_SimpleName *nm =((CT_Declarator*)fctdef->Declarator ())->Name ();
 
677
          if (nm->NodeName () == CT_TemplateName::NodeId ())
 
678
            desturbing.append (((CT_TemplateName*)nm)->Arguments ());
 
679
        }
575
680
      }
576
681
    }
577
682
  }
578
 
  
 
683
 
579
684
  // copy the object declaration without the template header
580
685
  if (TemplateInfo ()->Tree ()) {
581
 
    copyTree (unit, TemplateInfo ()->Tree ()->Declaration (), false, &desturbing);
 
686
    CTree* decl = TemplateInfo ()->Tree ()->Declaration ();
 
687
    copyTree (unit, decl, decl->end_token(), &desturbing);
582
688
  }
583
 
  
 
689
 
584
690
  unit << "\n" << endu;
585
691
 
586
692
  if (TRACE_INSTANCE_CODE) {
587
 
    cout << "\ninstantiation unit: " << unit.name () << endl;
 
693
    cout << endl;
 
694
    if (PointOfInstantiation ()) {
 
695
      cout << getPoiToken()->location () << ": ";
 
696
    }
 
697
    cout << unit.name ();
 
698
    if (instance && instance->Scope () && instance->Scope ()->Scope ()) {
 
699
      cout << ": instantiated in scope " << instance->Scope ()->Scope ()->QualName (true);
 
700
    }
 
701
    cout << endl;
 
702
    if (TemplateInfo ()->Tree () && TemplateInfo ()->Tree ()->token () && TemplateInfo ()->ObjectInfo ()) {
 
703
      cout << TemplateInfo ()->Tree ()->token ()->location () << ": instantiation of template " 
 
704
           << TemplateInfo ()->ObjectInfo ()->QualName (true) << endl;
 
705
    }
588
706
    cout << "-------------------" << endl;
589
707
    unit.print (cout);
590
 
    cout << "\n-------------------\n" << endl;
 
708
    cout << "-------------------\n" << endl;
591
709
  }
592
710
}
593
711
 
594
712
 
595
 
void CCInstantiation::genArgType (CUnit &unit, CTree *tree, CTree *pname, const char *name) {
596
 
  // replace private name with name of the current template parameter
597
 
  if (tree == pname) {
598
 
    unit << name << " ";
 
713
void CCInstantiation::copyTree (CUnit &unit, CTree *tree, CTree *sn, const char *name, bool make_const) {
 
714
  // replace name with name of the current template parameter
 
715
  if (tree == sn) {
 
716
    unit << " ";
 
717
    if (make_const) 
 
718
      unit << "const ";
 
719
    if (sn->NodeName () == CT_PrivateName::NodeId ())
 
720
      unit << name << " ";
599
721
  // replace template template parameter by its deduced value
600
722
  } else if (tree->NodeName () == CT_SimpleName::NodeId ()) {
601
 
    replaceName (unit, (CT_SimpleName*)tree, true);
 
723
    replaceName (unit, (CT_SimpleName*)tree, 0);
602
724
    return;
603
725
  // copy the rest
604
726
  } else if (tree->NodeName () == CT_Token::NodeId ()) {
605
 
    if (tree->token ())
606
 
      unit << tree->token ()->text () << " ";
607
 
  } 
608
 
  
 
727
    Token* t = tree->token ();
 
728
    if (t) {
 
729
      unit << t->text ();
 
730
      Token* next = t->unit()->next(t);
 
731
      if (next && (next->is_whitespace() || next->is_comment()))
 
732
        unit << (next->is_whitespace() ? next->text() : " ");
 
733
      else if (! next)
 
734
        unit << " ";
 
735
    }
 
736
  }
 
737
 
609
738
  for (unsigned i = 0; i < (unsigned)tree->Sons (); i++) {
610
 
    genArgType (unit, tree->Son (i), pname, name);
 
739
    copyTree (unit, tree->Son (i), sn, name, make_const);
 
740
  }
 
741
 
 
742
  if (tree->NodeName () == CT_TemplateName::NodeId ()) {
 
743
    extendTemplateName (unit, (CT_TemplateName*)tree);
611
744
  }
612
745
}
613
746
 
614
747
 
615
 
void CCInstantiation::copyTree (CUnit &unit, CTree *tree, bool gen_spaces, 
616
 
 Array<CTree*> *desturbing) {
617
 
  // first check if this subtree is desturbing and should 
 
748
void CCInstantiation::copyTree (CUnit &unit, CTree *tree, Token* end_token, Array<CTree*> *desturbing) {
 
749
  // first check if this subtree is disturbing and should
618
750
  // be omitted in the generated unit
619
 
  if (desturbing) 
 
751
  if (desturbing)
620
752
    for (int i = 0; i < desturbing->length (); i++)
621
753
      if (desturbing->lookup (i) == tree)
622
754
        return; // prune here
623
 
      
 
755
 
624
756
  // replace template template parameter by its deduced value
625
757
  if (tree->NodeName () == CT_SimpleName::NodeId ()) {
626
 
    replaceName (unit, (CT_SimpleName*)tree, gen_spaces);
 
758
    replaceName (unit, (CT_SimpleName*)tree, end_token);
627
759
    return;
628
760
  // copy the rest
629
761
  } else if (tree->NodeName () == CT_Token::NodeId ()) {
630
 
    if (tree->token ()) {
631
 
      unit << tree->token ()->text () << " ";
 
762
    Token* t = tree->token ();
 
763
    if (t) {
 
764
      unit << t->text ();
 
765
      if (t != end_token) {
 
766
        Token* next = t->unit()->next(t);
 
767
        if (next && (next->is_whitespace() || next->is_comment()))
 
768
          unit << (next->is_whitespace() ? next->text() : " ");
 
769
        else if (! next)
 
770
          unit << " ";
 
771
      }
632
772
    }
633
773
  }
634
 
  
635
 
  for (unsigned i = 0; i < (unsigned)tree->Sons (); i++)
636
 
    copyTree (unit, tree->Son (i), gen_spaces, desturbing);
637
 
    
638
 
  // function bodies might be error nodes, because they were skipped
639
 
  // ==> replace by ';'
 
774
 
 
775
  CTree* body = 0;
640
776
  if (tree->NodeName () == CT_FctDef::NodeId ()) {
641
 
    if (((CT_FctDef*)tree)->Body ()->NodeName () == CT_Error::NodeId ()) {
642
 
      unit << ";";
643
 
    }
644
 
  }
645
 
}
646
 
 
647
 
 
648
 
void CCInstantiation::replaceName (CUnit &unit, CT_SimpleName *name, bool gen_spaces) {
 
777
    body = ((CT_FctDef*)tree)->Body ();
 
778
  }
 
779
 
 
780
  for (unsigned i = 0; i < (unsigned)tree->Sons (); i++) {
 
781
    CTree* son = tree->Son (i);
 
782
    if (body && body == son) {
 
783
      if (body->NodeName () == CT_Error::NodeId ()) {
 
784
        // if function body is error node => replace by ';'
 
785
        unit << ";\n";
 
786
      } else {
 
787
        // don't instantiate function body, instantiated on demand
 
788
        unit << "{}\n";
 
789
      }
 
790
      continue;
 
791
    }
 
792
    copyTree (unit, tree->Son (i), end_token, desturbing);
 
793
  }
 
794
 
 
795
  if (tree->NodeName () == CT_TemplateName::NodeId ()) {
 
796
    extendTemplateName (unit, (CT_TemplateName*)tree);
 
797
  }
 
798
}
 
799
 
 
800
 
 
801
void CCInstantiation::extendTemplateName (CUnit &unit, CT_TemplateName *name) {
 
802
  CObjectInfo *info = name->TemplateName ()->Object ();
 
803
  if (info) {
 
804
    // is template template parameter?
 
805
    CTemplateParamInfo *pinfo = info->TemplateParamInfo ();
 
806
    if (pinfo && pinfo->isTemplate ()) {
 
807
      // which template parameter is it?
 
808
      int pos = First ().getPosition (pinfo);
 
809
      if (pos != -1) {
 
810
        // extend the template name
 
811
        unit << "::__puma_redirect ";
 
812
      }
 
813
    }
 
814
  }
 
815
}
 
816
 
 
817
 
 
818
void CCInstantiation::replaceName (CUnit &unit, CT_SimpleName *name, Token *end_token) {
649
819
  bool replaced = false;
650
820
  
651
821
  CObjectInfo *info = name->Object ();
655
825
    if (pinfo && pinfo->isTemplate ()) {
656
826
      // which template parameter is it?
657
827
      int pos = First ().getPosition (pinfo);
658
 
      if (pos != -1) {
 
828
      if (pos != -1 && name->Parent ()->NodeName () != CT_TemplateName::NodeId ()) {
659
829
        // get deduced argument for this parameter and insert it here
660
830
        DeducedArgument *darg = DeducedArg (pos);
661
831
        if (darg->TemplateArg ()) {
662
 
          copyTree (unit, darg->TemplateArg (), gen_spaces);
 
832
          copyTree (unit, darg->TemplateArg (), end_token);
663
833
          replaced = true;
664
834
        } else {
665
 
          replaced = dumpDeducedArg (darg, unit);
 
835
          replaced = darg->Type() || darg->Value();
 
836
          unit << *darg << " ";
666
837
        }
667
838
      }
668
839
    }
669
840
  }
670
841
  // not replaced, so copy it as it is
671
842
  if (! replaced) {
672
 
    copyTree (unit, name->token_node (), gen_spaces);
673
 
  }
674
 
}
675
 
 
676
 
 
677
 
CStructure *CCInstantiation::makeScope () {
678
 
  CStructure *scope;
679
 
  
680
 
  // create namespace name
681
 
  std::ostringstream sname;
682
 
  sname << "%" << ObjectInfo ()->Name ();
683
 
  listArguments (*base_candidate, sname);
684
 
 
685
 
//  if (current_scope)
686
 
//    scope = current_scope->newNamespace ();    
687
 
//  else
688
 
  scope = TemplateInfo ()->Parent ()->newNamespace ();    
689
 
  scope->NamespaceInfo ()->aroundInstantiation (true);
690
 
  scope->Name (sname.str ().c_str ());
691
 
  scope->TypeInfo (&CTYPE_UNDEFINED);
692
 
  scope->SemDB (ObjectInfo ()->SemDB ());
693
 
  scope->SourceInfo ()->FileInfo (ObjectInfo ()->SourceInfo ()->FileInfo ());
694
 
  scope->SourceInfo ()->StartToken (PointOfInstantiation ()->token_node ());
695
 
  return scope;
696
 
}
697
 
 
698
 
 
699
 
void CCInstantiation::listArguments (InstantiationCandidate &cand, std::ostringstream &out) {
700
 
  out << "<";
701
 
  for (unsigned i = 0; i < cand.DeducedArgs (); i++) {
702
 
    DeducedArgument *arg = cand.DeducedArg (i);
703
 
    // do not list default arguments
704
 
    if (arg->isDefaultArg ())
705
 
      break;
706
 
 
707
 
    if (i) out << ",";
708
 
    dumpDeducedArg (arg, out);
709
 
  }
710
 
  out << ">";
711
 
}
712
 
 
713
 
 
714
 
bool CCInstantiation::dumpDeducedArg (DeducedArgument *arg, std::ostringstream &out) {
715
 
  if (arg->Type ()) {
716
 
    arg->Type ()->TypeText (out);
717
 
  } else if (arg->Value ()) {
718
 
    out << *(arg->Value ());
719
 
  } else {
720
 
    return false;
721
 
  }
722
 
  return true;
723
 
}
724
 
 
725
 
 
726
 
CT_SimpleName *CCInstantiation::getSimpleName () {
727
 
  if (PointOfInstantiation ()->NodeName () == CT_SimpleName::NodeId () ||
728
 
      PointOfInstantiation ()->NodeName () == CT_QualName::NodeId () ||
729
 
      PointOfInstantiation ()->NodeName () == CT_RootQualName::NodeId () ||
730
 
      PointOfInstantiation ()->NodeName () == CT_TemplateName::NodeId () ||
731
 
      PointOfInstantiation ()->NodeName () == CT_OperatorName::NodeId () ||
732
 
      PointOfInstantiation ()->NodeName () == CT_SpecialName::NodeId () ||
733
 
      PointOfInstantiation ()->NodeName () == CT_PrivateName::NodeId () ||
734
 
      PointOfInstantiation ()->NodeName () == CT_DestructorName::NodeId () ||
735
 
      PointOfInstantiation ()->NodeName () == CT_ConversionName::NodeId ())
736
 
    return (CT_SimpleName*)PointOfInstantiation ();
737
 
  return (CT_SimpleName*)0;
 
843
    for (unsigned i = 0; i < (unsigned)name->Sons (); i++) {
 
844
      copyTree (unit, name->Son (i), end_token);
 
845
    }
 
846
  }
738
847
}
739
848
 
740
849
 
764
873
}
765
874
 
766
875
 
 
876
CT_SimpleName *CCInstantiation::findName (CTree *node) const {
 
877
  const char *id = node->NodeName ();
 
878
  if (node->IsSimpleName ())
 
879
    return (CT_SimpleName*)node;
 
880
  else if (id == CT_NamedType::NodeId ())
 
881
    return findName (((CT_NamedType*)node)->Declarator ());
 
882
  else if (id == CT_FctDeclarator::NodeId ())
 
883
    return findName (((CT_FctDeclarator*)node)->Declarator ());
 
884
  else if (id == CT_ArrayDeclarator::NodeId ())
 
885
    return findName (((CT_ArrayDeclarator*)node)->Declarator ());
 
886
  else if (id == CT_PtrDeclarator::NodeId ())
 
887
    return findName (((CT_PtrDeclarator*)node)->Declarator ());
 
888
  else if (id == CT_MembPtrDeclarator::NodeId ())
 
889
    return findName (((CT_MembPtrDeclarator*)node)->Declarator ());
 
890
  else if (id == CT_BracedDeclarator::NodeId ())
 
891
    return findName (((CT_BracedDeclarator*)node)->Declarator ());
 
892
  else if (id == CT_BitFieldDeclarator::NodeId ())
 
893
    return findName (((CT_BitFieldDeclarator*)node)->Declarator ());
 
894
  else if (id == CT_RefDeclarator::NodeId ())
 
895
    return findName (((CT_RefDeclarator*)node)->Declarator ());
 
896
  else if (id == CT_InitDeclarator::NodeId ())
 
897
    return findName (((CT_InitDeclarator*)node)->Declarator ());
 
898
  return (CT_SimpleName*)0;
 
899
}
 
900
 
 
901
 
767
902
} // namespace Puma