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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2009-09-18 10:46:03 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090918104603-fjfrjm7cze5w2kz5
Tags: 1.0pre4~svn.20090918-1
* New snapshot
* include patch from "Michael Bienia" <geser@ubuntu.com> to fix FTBFS
  with g++-4.4. Thanks! (Closes: #546175)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "Puma/CConstant.h"
30
30
#include "Puma/CCConversions.h"
31
31
#include "Puma/CUnit.h"
 
32
#include "Puma/TemplateInstanceUnit.h"
32
33
#include "Puma/CCParser.h"
33
34
#include "Puma/TokenStream.h"
34
35
#include "Puma/UnitManager.h"
39
40
#include "Puma/CFileInfo.h"
40
41
#include "Puma/CSourceInfo.h"
41
42
#include "Puma/CCConversions.h"
 
43
#include "Puma/CCSemExpr.h"
 
44
#include "Puma/CAttributeInfo.h"
42
45
 
43
46
namespace Puma {
44
47
 
52
55
  }
53
56
 
54
57
 
 
58
extern int TRACE_INSTANCE_CODE;
 
59
extern int TRACE_PARSE_INSTANCE;
 
60
 
 
61
 
55
62
InstantiationCandidate::InstantiationCandidate () {
56
 
  obj_info = 0;
57
 
  tpl_info = 0;
58
 
  poi      = 0;
59
 
  err      = 0;
 
63
  obj_info   = 0;
 
64
  tpl_info   = 0;
 
65
  poi        = 0;
 
66
  err        = 0;
 
67
  trans_unit = 0;
 
68
  inst_scope = 0;
60
69
}
61
70
 
62
71
 
65
74
//  for (long i = 0; i < darguments.length (); i++)
66
75
//    if (darguments[i])
67
76
//      delete darguments[i];
 
77
//  if (trans_unit)
 
78
//    delete trans_unit;
68
79
}
69
80
 
70
81
 
71
82
void InstantiationCandidate::reset () {
72
 
  obj_info = 0;
73
 
  tpl_info = 0;
74
 
  poi      = 0;
75
 
  err      = 0;
 
83
  obj_info   = 0;
 
84
  tpl_info   = 0;
 
85
  poi        = 0;
 
86
  err        = 0;
 
87
  inst_scope = 0;
 
88
 
 
89
// TEMPORARY HACK
 
90
//  if (trans_unit)
 
91
//    delete trans_unit;
 
92
  trans_unit = 0;
76
93
 
77
94
  for (long i = 0; i < darguments.length (); i++)
78
95
    if (darguments[i])
110
127
}
111
128
 
112
129
 
 
130
CTemplateParamInfo* InstantiationCandidate::getMatchingParameter (CTemplateParamInfo *param) {
 
131
  if (tpl_info && param && param->TemplateInfo () != tpl_info)
 
132
    param = tpl_info->Parameter (param->getPosition ());
 
133
  return param;
 
134
}
 
135
 
 
136
 
 
137
bool InstantiationCandidate::canBeInstantiated () {
 
138
  // template instantiation disabled?
 
139
  if (! obj_info->SemDB()->Project()->config().Option("--real-instances"))
 
140
    return false;
 
141
  // point of instantiation depends on template parameter?
 
142
  if (CCSemExpr::isDependent(poi))
 
143
    return false;
 
144
  // everything OK
 
145
  return true;
 
146
}
 
147
 
 
148
 
113
149
// §14.8.2 deduce template arguments (if necessary)
114
150
bool InstantiationCandidate::deduceArguments (bool real_inst) {
115
 
  CTemplateParamInfo *param;
116
 
  CT_TemplateArgList *args;
117
 
  //CTypeInfo *ptype, *atype;
118
 
  CObjectInfo *oinfo = 0;
119
 
  unsigned numargs;
120
 
  bool default_arg;
121
 
  CTree *arg, *sn, *name;
122
 
  
 
151
  // check if template really can be instantiated
 
152
  if (real_inst && ! canBeInstantiated())
 
153
    real_inst = false;
 
154
 
 
155
  CTree* name = poi;
 
156
  if (name->NodeName () == CT_QualName::NodeId () ||
 
157
      name->NodeName () == CT_RootQualName::NodeId ())
 
158
    name = ((CT_QualName*)name)->Name ();
 
159
 
123
160
  // template arguments
124
 
  name = poi;
125
 
  if (name->NodeName () == CT_QualName::NodeId () ||
126
 
      name->NodeName () == CT_RootQualName::NodeId ())
127
 
    name = ((CT_QualName*)name)->Name ();
 
161
  CT_TemplateArgList *args;
 
162
  unsigned numargs;
128
163
  if (name->NodeName () == CT_TemplateName::NodeId ()) {
129
164
    args = ((CT_TemplateName*)name)->Arguments ();
130
165
    numargs = args->Entries ();
132
167
    args = 0;
133
168
    numargs = 0;
134
169
  }
135
 
  
 
170
 
136
171
  // get template parameter list information
137
172
  if (obj_info->ClassInfo ())
138
173
    tpl_info = obj_info->ClassInfo ()->TemplateInfo ();
146
181
    if (real_inst) {
147
182
      SEM_ERROR (poi, "fatal error: missing template parameter information");
148
183
      return false;
149
 
    } else
150
 
      return true;
 
184
    }
 
185
    return true;
151
186
  }
152
 
  
 
187
 
153
188
  // check number of template arguments for function templates
154
189
  if (obj_info->FunctionInfo () && numargs > tpl_info->Parameters ()) {
155
190
    if (real_inst) {
156
 
      SEM_ERROR (poi, "wrong number of template arguments (" 
 
191
      SEM_ERROR (poi, "wrong number of template arguments ("
157
192
        << numargs << ", should be " << tpl_info->Parameters () << ")");
158
193
      return false;
159
 
    } else
160
 
      return true;
 
194
    }
 
195
    return true;
161
196
  }
162
 
    
163
 
  // compare type of arguments with type of parameters
164
 
  for (unsigned i = 0; i < tpl_info->Parameters (); i++) {
165
 
    param = tpl_info->Parameter (i);
166
 
    default_arg = false;
167
197
 
168
 
    if (i >= numargs) {
169
 
      // consider default template arguments for non-function templates
170
 
      if (! obj_info->FunctionInfo ()) {
171
 
        if (! param->DefaultArgument ()) {
 
198
  // calculate index of first parameter for which no direct template
 
199
  // argument or default template argument is given
 
200
  unsigned pos = 0;
 
201
  for (; pos < tpl_info->Parameters(); pos++) {
 
202
    CTemplateParamInfo *param = tpl_info->Parameter(pos);
 
203
    if (pos >= numargs) {
 
204
      // no direct template argument for the current parameter,
 
205
      // check default template arguments for non-function templates
 
206
      if (! obj_info->FunctionInfo()) {
 
207
        // not a function template, check default argument
 
208
        if (! param->DefaultArgument()) {
 
209
          // no default argument
172
210
          if (real_inst) {
173
 
            SEM_ERROR (poi, "missing default argument for parameter " << i+1);
 
211
            SEM_ERROR(poi, "missing default argument for parameter " << pos+1);
174
212
            return false;
175
 
          } else
176
 
            return true;
177
 
        } else {
178
 
          arg = param->DefaultArgument ()->Entry (0);
179
 
          default_arg = true;
 
213
          }
 
214
          return true;
180
215
        }
181
 
      // function template parameters cannot have default arguments;
182
 
      // ommited arguments must be deducible from the function call
183
 
      // argument list
184
 
      } else 
185
 
        return deduceArgumentsFromFctCall (i);
186
 
    } else
 
216
      } else {
 
217
        // function template parameters do not have default arguments,
 
218
        // ommited arguments must be deduced from the function call
 
219
        // argument list
 
220
        break;
 
221
      }
 
222
    }
 
223
  }
 
224
 
 
225
  // deduce the direct and default arguments
 
226
  if (! (real_inst ? parseDirectArguments(pos, numargs, args) :
 
227
                     matchDirectArguments(pos, numargs, args))) {
 
228
    return false;
 
229
  }
 
230
 
 
231
  if (pos < tpl_info->Parameters()) {
 
232
    // deduce remaining arguments from function call
 
233
    return deduceArgumentsFromFctCall(pos);
 
234
  }
 
235
  return true;
 
236
}
 
237
 
 
238
 
 
239
bool InstantiationCandidate::matchDirectArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args) {
 
240
  // match direct and default template arguments
 
241
  for (unsigned i = 0; i < pos; i++) {
 
242
    CTemplateParamInfo *param = tpl_info->Parameter (i);
 
243
    bool is_default_arg = (i >= numargs);
 
244
    CObjectInfo* oinfo = 0;
 
245
    CTree *arg;
 
246
 
 
247
    if (is_default_arg) {
 
248
      // default template argument
 
249
      arg = param->DefaultArgument ()->Entry (0);
 
250
    } else {
 
251
      // direct template argument
187
252
      arg = args->Entry (i);
188
 
    
 
253
    }
 
254
 
189
255
    // template template parameter: expect name of class base template
190
256
    if (param->isTemplate ()) {
191
 
      if (real_inst) {
192
 
        sn = arg;
193
 
        if (sn->NodeName () == CT_NamedType::NodeId ())
194
 
          sn = sn->Son (0)->Son (0);
195
 
        if (! (sn->NodeName () == CT_SimpleName::NodeId () ||
196
 
               sn->NodeName () == CT_RootQualName::NodeId () ||
197
 
               sn->NodeName () == CT_QualName::NodeId ()) ||
198
 
            ! sn->SemObject () || 
199
 
            ! (oinfo = sn->SemObject ()->Object ()) ||
200
 
            ! ((oinfo->TemplateParamInfo () && oinfo->TemplateParamInfo ()->isTemplate ()) ||
201
 
               (oinfo->Record () && oinfo->Record ()->isTemplate ()))) {
202
 
          SEM_ERROR (arg, "expected a class template as argument " << i+1);
203
 
          return false;
204
 
        }
205
 
        darguments.append (new DeducedArgument (param, 
206
 
          oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
207
 
      } else {
208
 
        if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ())
209
 
          darguments.append (new DeducedArgument (param, 
210
 
            oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
211
 
      }
 
257
      if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ())
 
258
        darguments.append (new DeducedArgument (param,
 
259
          oinfo->TypeInfo ()->VirtualType (), arg, is_default_arg, !is_default_arg));
 
260
    }
212
261
    // template type parameter: expect type-id
213
 
    } else if (param->isTypeParam ()) {
214
 
      if (real_inst) {
215
 
        if (! (arg->NodeName () == CT_NamedType::NodeId ()) || ! arg->SemObject () || 
216
 
            ! (oinfo = arg->SemObject ()->Object ())) {
217
 
          SEM_ERROR (arg, "expected a type as argument " << i+1);
218
 
          return false;
219
 
        }
220
 
        darguments.append (new DeducedArgument (param, 
221
 
          oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
222
 
      } else {
223
 
        if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ())
224
 
          darguments.append (new DeducedArgument (param, 
225
 
            oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
226
 
      }
 
262
    else if (param->isTypeParam ()) {
 
263
      if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ())
 
264
        darguments.append (new DeducedArgument (param,
 
265
          oinfo->TypeInfo ()->VirtualType (), arg, is_default_arg, !is_default_arg));
 
266
    }
227
267
    // template non-type parameter: expect constant expression
228
 
    } else {
229
 
      if (real_inst) {
230
 
        // not a non-type argument
231
 
        if (arg->NodeName () == CT_NamedType::NodeId ()) {
232
 
          SEM_ERROR (arg, "expected a constant as argument " << i+1);
233
 
          return false;
234
 
        }
235
 
        // consider template non-type parameter as argument
236
 
        if (arg->Type () && arg->Type ()->TypeTemplateParam () &&
237
 
            arg->Type ()->TypeTemplateParam ()->isNonType ()) {
238
 
          darguments.append (new DeducedArgument (param, arg->Type (), arg, default_arg));
239
 
          continue;
240
 
        }
241
 
        // need value of constant
242
 
        if (! arg->Value () || ! arg->Value ()->Constant ()) {
243
 
          SEM_ERROR (arg, "expected a constant as argument " << i+1);
244
 
          return false;
245
 
        }
246
 
        /* TEMPORARY COMMENTED OUT
247
 
        // check and if necessary convert the template argument
248
 
        CCConversions cvs (*err);
249
 
        ptype = param->ValueType ();
250
 
        atype = arg->Value ()->Type ();
251
 
        if (ptype->isInteger ()) {
252
 
          // integral promotions
253
 
          if (*ptype != *atype) {
254
 
            atype = cvs.integralPromotion (atype);
255
 
            if (! atype) {
256
 
              atype = arg->Value ()->Type ();
257
 
            }
258
 
          }
259
 
        } else if (ptype->isPointer () && arg->Value ()->Constant ()->isNull ()) {
260
 
          SEM_ERROR (arg, "could not convert template argument '0' to '" << *ptype << "'");
261
 
          return false;
262
 
        }
263
 
        // integral conversions
264
 
        CCConvSeq *seq = cvs.implicitConversions (ptype, atype, arg, 0);
265
 
        if (! seq) {
266
 
          SEM_ERROR (arg, "could not convert template argument '" << *atype << "' to '" << *ptype << "'");
267
 
          return false;
268
 
        } else {
269
 
          delete seq;
270
 
        }*/
271
 
        darguments.append (new DeducedArgument (param, 
272
 
          arg->Value ()->Constant (), arg, default_arg));
273
 
      } else {
274
 
        // consider template non-type parameter as argument
275
 
        if (arg->Type () && arg->Type ()->TypeTemplateParam () &&
276
 
            arg->Type ()->TypeTemplateParam ()->isNonType ()) {
277
 
          darguments.append (new DeducedArgument (param, 
278
 
            arg->Type (), arg, default_arg));
279
 
        } else if (arg->Value () && arg->Value ()->Constant ()) {
280
 
          darguments.append (new DeducedArgument (param, 
281
 
            arg->Value ()->Constant (), arg, default_arg));
282
 
        }
 
268
    else {
 
269
      if (arg->Type () && arg->Type ()->TypeTemplateParam () &&
 
270
          arg->Type ()->TypeTemplateParam ()->isNonType ()) {
 
271
        // template non-type parameter as argument
 
272
        darguments.append (new DeducedArgument (param,
 
273
          arg->Type (), arg, is_default_arg, !is_default_arg));
 
274
      }
 
275
      else if (arg->Value () && arg->Value ()->Constant ()) {
 
276
        darguments.append (new DeducedArgument (param,
 
277
          arg->Value ()->Constant (), arg, is_default_arg, !is_default_arg));
283
278
      }
284
279
    }
285
280
  }
301
296
  finfo = obj_info->FunctionInfo ();
302
297
  fargs = finfo->TypeInfo ()->ArgTypes ();
303
298
  numargs = Arguments ();
304
 
  
 
299
 
305
300
  // compare number of function arguments and parameters
306
301
  if (fargs->Entries () > numargs) {
307
302
    numargs = fargs->Entries ();
327
322
      }
328
323
    } else
329
324
      arg = Argument (i);
330
 
    
 
325
 
331
326
    // §14.3.2.5 implicit argument type conversions
332
327
    type = arg->Type () ? arg->Type () : arg->SemObject ()->Object ()->TypeInfo ();
333
328
    type = type->VirtualType ();
337
332
        type = type->isArray () ? type->VirtualType ()->BaseType () : type;
338
333
        type = new CTypePointer (type->Duplicate ());
339
334
      }
340
 
    } 
341
 
    
 
335
    }
 
336
 
342
337
    if (deduceArguments (fargs->Entry (i)->VirtualType (), type, dargs, exact_match) == 1) {
343
338
      succeeded = false; // ambiguous type for parameter
344
339
    }
348
343
    if (! dargs[i]) {
349
344
      SEM_ERROR (poi, "could not deduce argument for parameter " << i+1);
350
345
      succeeded = false;
351
 
    } else 
 
346
    } else
352
347
      darguments.append (dargs[i]);
353
348
  }
354
 
  
 
349
 
355
350
  return succeeded;
356
351
}
357
352
 
681
676
  if (param) {
682
677
    int pos = getPosition (param);
683
678
    if (pos != -1 && param->isTypeParam ()) {
684
 
      
 
679
 
685
680
      CRecord *record = atype->TypeMemberPointer ()->Record ();
686
 
      
 
681
 
687
682
      // argument type is class or union, can be deduced
688
683
      if (record) {
689
684
        if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, record->TypeInfo ()))) {
690
685
          return 1;
691
686
        }
692
 
      
 
687
 
693
688
      // argument member pointer type contains template parameter, handled as unique type for 
694
689
      // partial ordering of function templates
695
690
      } else {
726
721
      // deduce template arguments from the type arguments of the template instances,
727
722
      // the template used to instantiate finfo must be equal to the template used
728
723
      // to instantiate ainfo or one of its base classes
729
 
      
 
724
 
730
725
      CTemplateInstance *fi = finfo->TemplateInstance (); 
731
726
      Array<CTemplateInstance*> instances;
732
727
      getTemplateInstances (ainfo, instances); // search the class hierarchy of ainfo
733
 
    
 
728
 
734
729
      bool at_least_one_match = false;
735
730
      for (long j = 0; j < instances.length (); j++) {
736
731
        CTemplateInstance *ai = instances.fetch (j);
737
 
      
 
732
 
738
733
        // same template and same number of template arguments
739
734
        CTemplateInfo *ft = fi->Template ()->BaseTemplate () ? fi->Template ()->BaseTemplate () : fi->Template ();
740
735
        CTemplateInfo *at = ai->Template ()->BaseTemplate () ? ai->Template ()->BaseTemplate () : ai->Template ();
749
744
        }
750
745
        at_least_one_match = at_least_one_match || (ret == 0);
751
746
      }
752
 
      
 
747
 
753
748
      // require exact match
754
749
      if (! at_least_one_match) {
755
750
        return 2;
756
751
      }
757
 
     
 
752
 
758
753
    // ordinary types must match, if not the top level types
759
754
    } else if (exact_match && (*finfo != *ainfo)) {
760
755
      return 2;
761
756
    }
762
757
  }
763
 
    
 
758
 
764
759
  return 0; 
765
760
}
766
761
 
770
765
  bool matching_args = true;
771
766
  bool ambiguous_type = false;
772
767
  DeducedArgumentList curr_dargs;
773
 
        
 
768
 
774
769
  // number of template arguments must match
775
770
  if (fi->InstantiationArgs () != ai->InstantiationArgs ()) {
776
771
    return 2;
788
783
    CTypeInfo *adtype = ai->InstantiationArg (i)->Type ();
789
784
    CConstant *fvalue = fi->InstantiationArg (i)->Value ();
790
785
    CConstant *avalue = ai->InstantiationArg (i)->Value ();
791
 
          
 
786
 
792
787
    if (fdtype) {
793
788
      // type template arguments
794
789
      if (adtype) {
809
804
            ambiguous_type = true;
810
805
          }
811
806
        }
812
 
              
 
807
 
813
808
      } else {
814
809
        matching_args = false;
815
810
      }
816
 
          
 
811
 
817
812
    // non-type template arguments
818
813
    } else if (fvalue && (! avalue || (*fvalue != *avalue))) {
819
814
      matching_args = false;
820
815
    }
821
816
  }
822
 
        
 
817
 
823
818
  // check if deduced template arguments are valid
824
819
  if (! matching_args || ambiguous_type) {
825
820
    // discard the deduced template arguments
1197
1192
}
1198
1193
 
1199
1194
 
1200
 
void InstantiationCandidate::printArgumentList (std::ostream &out) const {
 
1195
void InstantiationCandidate::printArgumentList (std::ostream &out, bool print_default_args) const {
1201
1196
  out << "<";
1202
1197
  for (unsigned i = 0; i < DeducedArgs (); i++) {
1203
1198
    DeducedArgument *arg = DeducedArg (i);
1204
 
    
 
1199
 
1205
1200
    // do not list default arguments
1206
 
    if (arg->isDefaultArg ())
 
1201
    if (! print_default_args && arg->isDefaultArg ())
1207
1202
      break;
1208
1203
 
1209
1204
    if (i) out << ",";
1213
1208
}
1214
1209
 
1215
1210
 
1216
 
Token* InstantiationCandidate::getPointOfInstantiationToken() const {
 
1211
Token* InstantiationCandidate::getPointOfInstantiationToken(CTree* p) const {
1217
1212
  Token* token = 0;
1218
 
  CTree* point = poi;
 
1213
  CTree* point = p ? p : poi;
1219
1214
  if (point) {
1220
1215
    do {
1221
1216
      token = point->token();
1225
1220
}
1226
1221
 
1227
1222
 
1228
 
/*
1229
 
bool InstantiationCandidate::parseArguments () {
1230
 
  CStructure *scope;
1231
 
  CProject *project;
1232
 
  bool fct_inst;
1233
 
  CUnit *unit;
1234
 
 
 
1223
bool InstantiationCandidate::maxInstDepthReached () {
 
1224
  // ISO says not more than 17
 
1225
  unsigned max_depth = 17;
 
1226
  // maximum set by user?
 
1227
  const ConfOption *opt = tpl_info->SemDB ()->Project ()->config ().Option ("--template-depth");
 
1228
  if (opt && opt->Arguments () > 0) {
 
1229
    max_depth = strtol (opt->Argument (0), NULL, 10);
 
1230
  }
 
1231
  if (tpl_info->Depth () > max_depth) {
 
1232
    CTemplateInstance* topinst = 0;
 
1233
    Unit* unit = getPointOfInstantiationToken()->unit ();
 
1234
    while (unit->isTemplateInstance ()) {
 
1235
      TemplateInstanceUnit* tiunit = (TemplateInstanceUnit*)unit;
 
1236
      topinst = tiunit->TemplateInstance ();
 
1237
      unit = tiunit->ContainingUnit ();
 
1238
    }
 
1239
    if (topinst && topinst->Object()) {
 
1240
      *err << getPointOfInstantiationToken(topinst->PointOfInstantiation())->location ()
 
1241
           << "In instantiation of `" << *topinst->Object()->TypeInfo()
 
1242
           << "':" << endMessage;
 
1243
    }
 
1244
    *err << sev_error << getPointOfInstantiationToken()->location ()
 
1245
         << "maximum instantiation depth ("
 
1246
         << max_depth << ") reached" << endMessage;
 
1247
    return true;
 
1248
  }
 
1249
  return false;
 
1250
}
 
1251
 
 
1252
 
 
1253
CStructure *InstantiationCandidate::createInstanceScope() {
 
1254
  CStructure *scope = tpl_info->Parent()->newNamespace();
 
1255
  scope->NamespaceInfo()->aroundInstantiation(true);
 
1256
  scope->Name("%<anonymous>");
 
1257
  scope->TypeInfo(&CTYPE_UNDEFINED);
 
1258
  scope->SemDB(obj_info->SemDB());
 
1259
  scope->SourceInfo()->FileInfo(obj_info->SourceInfo()->FileInfo());
 
1260
  scope->SourceInfo()->StartToken(PointOfInstantiation()->token_node());
 
1261
  return scope;
 
1262
}
 
1263
 
 
1264
 
 
1265
bool InstantiationCandidate::parseDirectArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args) {
1235
1266
  // check maximal instantiation depth
1236
 
#  if (maxInstDepthReached ()) {
 
1267
  if (maxInstDepthReached()) {
1237
1268
    return false;
1238
1269
  }
1239
1270
 
1240
1271
  // increase instantiation depth
1241
 
  tpl_info->increaseDepth ();
1242
 
 
1243
 
#  scope = makeScope ();
1244
 
  fct_inst = obj_info->FunctionInfo ();
1245
 
  project = obj_info->SemDB ()->Project ();
1246
 
  unit = new TemplateInstanceUnit (err, getPointOfInstantiationToken()->unit(), 0);
1247
 
  unit->scanner ().configure (project->config ());
1248
 
  unit->name (scope->Name ());
1249
 
 
1250
 
  // create code for the template instance
1251
 
  fillUnit (*unit);
1252
 
 
1253
 
  // setup new parser for the instantiated code
1254
 
#  trans_unit = new CTranslationUnit (*unit, *project);
 
1272
  tpl_info->increaseDepth();
 
1273
 
 
1274
  // create new template instance scope
 
1275
  inst_scope = createInstanceScope();
 
1276
  // get the current project
 
1277
  CProject* project = obj_info->SemDB()->Project();
 
1278
 
 
1279
  // create a new token unit for the template arguments
 
1280
  CUnit* unit = new TemplateInstanceUnit(*err, getPointOfInstantiationToken()->unit(), 0);
 
1281
  unit->scanner().configure(project->config());
 
1282
  unit->name(inst_scope->Name());
 
1283
 
 
1284
  // create a new translation unit
 
1285
  trans_unit = new CTranslationUnit(*unit, *project);
 
1286
 
 
1287
  // create code for the template parameters
 
1288
  if (! insertCodeForArguments(pos, numargs, args, *unit)) {
 
1289
    return false;
 
1290
  }
 
1291
 
 
1292
  // setup new parser
1255
1293
  CCParser p;
1256
 
  p.configure (project->config ());
 
1294
  p.configure(project->config());
1257
1295
  if (TRACE_PARSE_INSTANCE) {
1258
1296
#ifdef __PUMA_TRACING__
1259
1297
    p.trace(std::cout);
1262
1300
 
1263
1301
  // setup the preprocessor
1264
1302
  TokenStream stream;
1265
 
  stream.push (unit); 
1266
 
  project->unitManager ().init ();
1267
 
  PreprocessorParser cpp (&project->err (), 
1268
 
    &project->unitManager (), &tu->local_units ());
1269
 
  cpp.macroManager ()->init (unit->name ());
1270
 
  cpp.stream (&stream);
1271
 
  cpp.configure (project->config (), false); // do not process --include option
 
1303
  stream.push(unit);
 
1304
  project->unitManager().init();
 
1305
  PreprocessorParser cpp(&project->err(), &project->unitManager(), &trans_unit->local_units());
 
1306
  cpp.macroManager()->init(unit->name());
 
1307
  cpp.stream(&stream);
 
1308
  cpp.configure(project->config(), false); // do not process --include option
1272
1309
 
1273
1310
  // initialize semantic analyzer
1274
 
  p.semantic ().init (*ObjectInfo ()->SemDB (),
1275
 
    *ObjectInfo ()->SourceInfo ()->FileInfo ()->Primary (), 
1276
 
    scope, fct_inst, ! fct_inst, this);   
1277
 
  ((ErrorCollector&)p.builder ().err ()).index (0);
1278
 
  p.semantic ().error_sink (p.builder ().err ());
 
1311
  bool is_fct = obj_info->FunctionInfo();
 
1312
  Unit* primary = obj_info->SourceInfo()->FileInfo()->Primary();
 
1313
  p.semantic().init(*obj_info->SemDB(), *primary, inst_scope, is_fct, !is_fct, 0);
 
1314
  ((ErrorCollector&)p.builder().err()).index(0);
 
1315
  p.semantic().error_sink(p.builder().err());
1279
1316
 
1280
 
  // start parsing 
1281
 
  TokenProvider provider (cpp);
1282
 
  tu->tree (p.syntax ().run (provider)); 
1283
 
  tu->cpp_tree (cpp.syntaxTree ());
 
1317
  // parse the code
 
1318
  TokenProvider provider(cpp);
 
1319
  trans_unit->tree(p.syntax().run(provider));
 
1320
  trans_unit->cpp_tree(cpp.syntaxTree());
1284
1321
 
1285
1322
  // decrease instantiation depth
1286
 
  TemplateInfo ()->decreaseDepth ();
1287
 
 
1288
 
  // report errors and clean up
1289
 
  if (((ErrorCollector&)p.builder ().err ()).severity () > sev_warning) {
1290
 
    removeInstance ();
1291
 
    if (report) {
1292
 
      err << getPoiToken()->location ()
1293
 
          << "In instantiation of `" << scope->Name ().c_str ()+1 
1294
 
          << "':" << endMessage;
1295
 
      p.builder ().errors (err);
1296
 
    }
1297
 
    //delete trans_unit;
1298
 
    //trans_unit = 0;
1299
 
    //delete unit;
1300
 
  // no errors detected
1301
 
  } else {
1302
 
    if (instance) {
1303
 
      //instance->TemplateInstance ()->canDelete ();
1304
 
    } else {
1305
 
      //delete trans_unit;
1306
 
      //trans_unit = 0;
1307
 
      //delete unit;
1308
 
    }
1309
 
  }
1310
 
 
1311
 
  First ().forgetDeducedArgs ();
1312
 
  return instance;
1313
 
}
1314
 
*/
 
1323
  tpl_info->decreaseDepth ();
 
1324
 
 
1325
  // if not failed, deduce from the parsed arguments
 
1326
  if (((ErrorCollector&)p.builder().err()).severity() < sev_error) {
 
1327
    return deduceFromParsedArguments(pos, numargs, args);
 
1328
  }
 
1329
  // failed due to parse errors
 
1330
  return false;
 
1331
}
 
1332
 
 
1333
 
 
1334
bool InstantiationCandidate::deduceFromParsedArguments(unsigned pos, unsigned numargs, CT_TemplateArgList *args) {
 
1335
  // get the argument declaration scope
 
1336
  CStructure* arg_scope = inst_scope->Namespace("__puma_dargs");
 
1337
  if (! arg_scope) {
 
1338
    return false;
 
1339
  }
 
1340
 
 
1341
  // deduce arguments from parsed direct and default arguments
 
1342
  for (unsigned i = 0; i < pos; i++) {
 
1343
    CTemplateParamInfo *param = tpl_info->Parameter(i);
 
1344
    bool is_default_arg = (i >= numargs);
 
1345
    CTree *arg;
 
1346
 
 
1347
    if (is_default_arg) {
 
1348
      // default template argument
 
1349
      arg = param->DefaultArgument()->Entry(0);
 
1350
    } else {
 
1351
      // direct template argument
 
1352
      arg = args->Entry(i);
 
1353
    }
 
1354
 
 
1355
    // get the name of the parameter
 
1356
    const char* name = getParameterName(param);
 
1357
 
 
1358
    // get the corresponding object in the instance unit
 
1359
    CObjectInfo* oinfo = arg_scope->Object(name);
 
1360
    if (! oinfo || ! oinfo->TypeInfo()) {
 
1361
      return false;
 
1362
    }
 
1363
 
 
1364
    // template template parameter: class base template
 
1365
    if (param->isTemplate()) {
 
1366
      // template<...> struct [name] {
 
1367
      //   typedef [arg]<...> __puma_redirect;
 
1368
      // };
 
1369
      oinfo = ((CStructure*)oinfo)->Object("__puma_redirect")->TypeInfo()->ClassInfo();
 
1370
      if (! oinfo || ! oinfo->isTemplateInstance()) {
 
1371
        return false;
 
1372
      }
 
1373
      oinfo = oinfo->TemplateInstance()->Template();
 
1374
      darguments.append(new DeducedArgument(param,
 
1375
        oinfo->TypeInfo(), arg, is_default_arg, !is_default_arg));
 
1376
    }
 
1377
    // template type parameter: expect type-id
 
1378
    else if (param->isTypeParam()) {
 
1379
      // typedef [arg] [name];
 
1380
      darguments.append(new DeducedArgument(param,
 
1381
        oinfo->TypeInfo()->VirtualType(), arg, is_default_arg, !is_default_arg));
 
1382
    }
 
1383
    // template non-type parameter: expect constant expression
 
1384
    else {
 
1385
      // static [type] [name] = [arg];
 
1386
      CTree* init = ((CAttributeInfo*)oinfo)->Init();
 
1387
      if (! init || ! init->Value() || ! init->Value()->Constant()) {
 
1388
        return false;
 
1389
      }
 
1390
      darguments.append(new DeducedArgument(param,
 
1391
        init->Value()->Constant(), arg, is_default_arg, !is_default_arg));
 
1392
    }
 
1393
  }
 
1394
  return true;
 
1395
}
 
1396
 
 
1397
 
 
1398
bool InstantiationCandidate::insertCodeForArguments(unsigned pos, unsigned numargs, CT_TemplateArgList *args, CUnit& unit) {
 
1399
  // insert code for each direct or default argument
 
1400
  unit << "namespace __puma_dargs {\n" << endu;
 
1401
  for (unsigned i = 0; i < pos; i++) {
 
1402
    CTemplateParamInfo *param = tpl_info->Parameter(i);
 
1403
    bool is_default_arg = (i >= numargs);
 
1404
    CTree *arg;
 
1405
 
 
1406
    if (is_default_arg) {
 
1407
      // default template argument
 
1408
      arg = param->DefaultArgument()->Entry(0);
 
1409
    } else {
 
1410
      // direct template argument
 
1411
      arg = args->Entry(i);
 
1412
    }
 
1413
 
 
1414
    // get the name of the parameter, generate one
 
1415
    // if the parameter is anonymous
 
1416
    const char* name = getParameterName(param);
 
1417
 
 
1418
    if (param->isTemplate()) {
 
1419
      // template-template parameter
 
1420
      CTypeInfo* type = 0;
 
1421
      if (! is_default_arg) {
 
1422
        // get the template type
 
1423
        CObjectInfo* oinfo;
 
1424
        CTree* sn = arg;
 
1425
        if (sn->NodeName() == CT_NamedType::NodeId())
 
1426
          sn = sn->Son(0)->Son(0);
 
1427
        if (! (sn->NodeName() == CT_SimpleName::NodeId() ||
 
1428
               sn->NodeName() == CT_RootQualName::NodeId() ||
 
1429
               sn->NodeName() == CT_QualName::NodeId()) ||
 
1430
            ! sn->SemObject() ||
 
1431
            ! (oinfo = sn->SemObject()->Object()) ||
 
1432
            ! (oinfo->Record() && oinfo->Record()->isTemplate())) {
 
1433
          SEM_ERROR(arg, "expected a class template as argument " << i+1);
 
1434
          return false;
 
1435
        }
 
1436
        type = oinfo->TypeInfo()->VirtualType();
 
1437
      }
 
1438
      if (! insertTemplateTemplateArgument(param, arg, type, name, unit))
 
1439
        return false;
 
1440
    }
 
1441
    else if (param->isTypeParam()) {
 
1442
      // template type parameter
 
1443
      CTypeInfo* type = 0;
 
1444
      if (! is_default_arg) {
 
1445
        // get the type
 
1446
        CObjectInfo* oinfo;
 
1447
        if (! (arg->NodeName() == CT_NamedType::NodeId()) ||
 
1448
            ! arg->SemObject() ||
 
1449
            ! (oinfo = arg->SemObject()->Object())) {
 
1450
          SEM_ERROR(arg, "expected a type as argument " << i+1);
 
1451
          return false;
 
1452
        }
 
1453
        type = oinfo->TypeInfo()->VirtualType();
 
1454
      }
 
1455
      if (! insertTypeTemplateArgument(param, arg, type, name, unit))
 
1456
        return false;
 
1457
    }
 
1458
    else {
 
1459
      // template non-type parameter
 
1460
      CConstant* value = 0;
 
1461
      if (! is_default_arg) {
 
1462
        // not a non-type argument
 
1463
        if (arg->NodeName() == CT_NamedType::NodeId()) {
 
1464
          SEM_ERROR(arg, "expected a constant as argument " << i+1);
 
1465
          return false;
 
1466
        }
 
1467
        // need value of constant
 
1468
        if (! arg->Value() || ! arg->Value()->Constant()) {
 
1469
          SEM_ERROR(arg, "expected a constant as argument " << i+1);
 
1470
          return false;
 
1471
        }
 
1472
        value = arg->Value()->Constant();
 
1473
      }
 
1474
      if (! insertNonTypeTemplateArgument(param, arg, value, name, unit))
 
1475
        return false;
 
1476
    }
 
1477
  }
 
1478
 
 
1479
  // finish and scan the code
 
1480
  unit << "}\n" << endu;
 
1481
 
 
1482
  // dump code to stdout if tracing enabled
 
1483
  //if (TRACE_INSTANCE_CODE) {
 
1484
  //  dumpInstanceCode(unit);
 
1485
  //}
 
1486
  return true;
 
1487
}
 
1488
 
 
1489
 
 
1490
bool InstantiationCandidate::insertNonTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CConstant* value, const char* name, CUnit& unit) {
 
1491
  // static [type] [name] = [arg];
 
1492
  unit << "static ";
 
1493
  CT_NonTypeParamDecl* decl = (CT_NonTypeParamDecl*)param->Tree();
 
1494
  copyTree(unit, decl->DeclSpecs(), 0, 0, name);
 
1495
  unit << " ";
 
1496
  copyTree(unit, decl->Declarator(), 0, findName(decl->Declarator()),
 
1497
    name, param->ValueType() && ! param->ValueType()->isConst());
 
1498
  unit << " = ";
 
1499
  if (value) {
 
1500
    unit << *value;
 
1501
  } else if (tree) {
 
1502
    copyTree(unit, tree, tree->end_token());
 
1503
  } else {
 
1504
    return false;
 
1505
  }
 
1506
  unit << ";\n";
 
1507
  return true;
 
1508
}
 
1509
 
 
1510
 
 
1511
bool InstantiationCandidate::insertTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type, const char* name, CUnit& unit) {
 
1512
  // typedef [arg] [name];
 
1513
  unit << "typedef ";
 
1514
  if (type) {
 
1515
    type->TypeText(unit, name, true);
 
1516
  } else if (tree) {
 
1517
    copyTree(unit, tree, 0, findPrivateName(tree), name);
 
1518
  } else {
 
1519
    return false;
 
1520
  }
 
1521
  unit << ";\n";
 
1522
  return true;
 
1523
}
 
1524
 
 
1525
 
 
1526
bool InstantiationCandidate::insertTemplateTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type, const char* name, CUnit& unit) {
 
1527
  // template<...> struct [name] {
 
1528
  //   typedef [arg]<...> __puma_redirect;
 
1529
  // };
 
1530
  CTemplateInfo* ti = param->TemplateTemplate();
 
1531
  unit << "template< ";
 
1532
  listParameters(unit, ti);
 
1533
  unit << " > struct " << name << " {\n  typedef ";
 
1534
  if (type) {
 
1535
    type->TypeText(unit, 0, true);
 
1536
  } else if (tree) {
 
1537
    copyTree(unit, tree, tree->end_token());
 
1538
  } else {
 
1539
    return false;
 
1540
  }
 
1541
  unit << "<";
 
1542
  listParameterNames(unit, ti);
 
1543
  unit << "> __puma_redirect;\n};\n";
 
1544
  return true;
 
1545
}
 
1546
 
 
1547
 
 
1548
bool InstantiationCandidate::insertCodeForInstance (CUnit &unit) {
 
1549
  // add all non-direct non-default arguments
 
1550
  for (unsigned i = 0; i < DeducedArgs (); i++) {
 
1551
    DeducedArgument *arg = DeducedArg (i);
 
1552
    CTemplateParamInfo *param = getMatchingParameter(arg->TemplateParam ());
 
1553
    if (! param)
 
1554
      continue;
 
1555
 
 
1556
    // get the name of the parameter, generate one
 
1557
    // if the parameter is anonymous
 
1558
    const char* name = getParameterName(param);
 
1559
 
 
1560
    // direct or default argument
 
1561
    if ((arg->isDefaultArg() || arg->isDirectArg()) &&
 
1562
        arg->TemplateParam()->Template() == tpl_info) {
 
1563
      // code already inserted, only introduce the name
 
1564
      // of the parameter into the instance scope
 
1565
      unit << "using __puma_dargs::" << name << ";\n";
 
1566
      continue;
 
1567
    }
 
1568
 
 
1569
    if (param->isTemplate ()) {
 
1570
      // deduced template-template argument
 
1571
      if (! insertTemplateTemplateArgument(param, 0, arg->Type(), name, unit))
 
1572
        return false;
 
1573
    } else if (param->isTypeParam ()) {
 
1574
      // deduced type argument
 
1575
      if (! insertTypeTemplateArgument(param, 0, arg->Type(), name, unit))
 
1576
        return false;
 
1577
    } else {
 
1578
      // deduced non-type argument
 
1579
      if (! insertNonTypeTemplateArgument(param, 0, arg->Value(), name, unit))
 
1580
        return false;
 
1581
    }
 
1582
  }
 
1583
 
 
1584
  // check for a template parameter in the class name -> desturbs
 
1585
  Array<CTree*> desturbing;
 
1586
  calculateDesturbing (desturbing);
 
1587
 
 
1588
  // copy the object declaration without the template header
 
1589
  if (TemplateInfo ()->Tree ()) {
 
1590
    CTree* decl = TemplateInfo ()->Tree ()->Declaration ();
 
1591
    copyTree (unit, decl, decl->end_token(), 0, 0, false, &desturbing);
 
1592
  }
 
1593
 
 
1594
  unit << "\n" << endu;
 
1595
 
 
1596
  if (TRACE_INSTANCE_CODE) {
 
1597
    dumpInstanceCode(unit);
 
1598
  }
 
1599
  return true;
 
1600
}
 
1601
 
 
1602
 
 
1603
void InstantiationCandidate::calculateDesturbing (Array<CTree*>& desturbing) {
 
1604
  // check for a template parameter in the class name -> desturbs
 
1605
  if (ObjectInfo ()->Tree ()->NodeName () == CT_ClassDef::NodeId ()) {
 
1606
    CT_ClassDef *clsdef = (CT_ClassDef*)ObjectInfo ()->Tree ();
 
1607
    if (clsdef->Name ()->NodeName () == CT_TemplateName::NodeId ())
 
1608
      desturbing.append (((CT_TemplateName*)clsdef->Name ())->Arguments ());
 
1609
    CT_MembList *members = clsdef->Members ();
 
1610
    if (members) { // normally true, but in case of parse errors (?) ...
 
1611
      for (int i = 0; i < members->Entries (); i++) {
 
1612
        if (members->Entry (i)->NodeName () == CT_FctDef::NodeId ()) {
 
1613
          CT_FctDef *fctdef = (CT_FctDef*)members->Entry (i);
 
1614
          CT_SimpleName *nm =((CT_Declarator*)fctdef->Declarator ())->Name ();
 
1615
          if (nm->NodeName () == CT_TemplateName::NodeId ())
 
1616
            desturbing.append (((CT_TemplateName*)nm)->Arguments ());
 
1617
        }
 
1618
      }
 
1619
    }
 
1620
  }
 
1621
}
 
1622
 
 
1623
 
 
1624
void InstantiationCandidate::dumpInstanceCode(CUnit& unit) {
 
1625
  std::cout << endl;
 
1626
  if (PointOfInstantiation()) {
 
1627
    std::cout << getPointOfInstantiationToken()->location() << ": ";
 
1628
  }
 
1629
  std::cout << obj_info->Name();
 
1630
  printArgumentList(std::cout);
 
1631
  std::cout << ": instantiated here" << std::endl;
 
1632
  if (tpl_info->Tree() && tpl_info->Tree()->token() && tpl_info->ObjectInfo()) {
 
1633
    std::cout << tpl_info->Tree()->token()->location()
 
1634
              << ": instantiation of template "
 
1635
              << tpl_info->ObjectInfo()->QualName(true) << std::endl;
 
1636
  }
 
1637
  std::cout << "-------------------" << std::endl;
 
1638
  unit.print(std::cout);
 
1639
  std::cout << "-------------------\n" << std::endl;
 
1640
}
 
1641
 
 
1642
 
 
1643
void InstantiationCandidate::copyTree(CUnit &unit, CTree *tree, Token* end_token, CTree *sn, const char *name, bool make_const, Array<CTree*> *desturbing) {
 
1644
  // first check if this subtree is disturbing and should
 
1645
  // be omitted in the generated unit
 
1646
  if (desturbing)
 
1647
    for (int i = 0; i < desturbing->length (); i++)
 
1648
      if (desturbing->lookup (i) == tree)
 
1649
        return; // prune here
 
1650
 
 
1651
  if (tree == sn) {
 
1652
    // replace name with name of the current template parameter
 
1653
    unit << " ";
 
1654
    if (make_const)
 
1655
      unit << "const ";
 
1656
    if (sn->NodeName() == CT_PrivateName::NodeId())
 
1657
      unit << name << " ";
 
1658
  }
 
1659
  else if (tree->NodeName() == CT_Token::NodeId()) {
 
1660
    // copy the rest
 
1661
    Token* t = tree->token();
 
1662
    if (t) {
 
1663
      unit << t->text();
 
1664
      if (t != end_token) {
 
1665
        Token* next = t->unit()->next(t);
 
1666
        if (next && (next->is_whitespace() || next->is_comment()))
 
1667
          unit << (next->is_whitespace() ? next->text() : " ");
 
1668
        else if (! next)
 
1669
          unit << " ";
 
1670
      }
 
1671
    }
 
1672
  }
 
1673
 
 
1674
  CTree* body = 0;
 
1675
  if (tree->NodeName() == CT_FctDef::NodeId()) {
 
1676
    body = ((CT_FctDef*)tree)->Body();
 
1677
  }
 
1678
 
 
1679
  for (unsigned i = 0; i < (unsigned)tree->Sons(); i++) {
 
1680
    CTree* son = tree->Son(i);
 
1681
    if (body && body == son) {
 
1682
      if (body->NodeName() == CT_Error::NodeId()) {
 
1683
        // if function body is error node => replace by ';'
 
1684
        unit << ";\n";
 
1685
      } else {
 
1686
        // don't instantiate function body, instantiated on demand
 
1687
        unit << "{}\n";
 
1688
      }
 
1689
      continue;
 
1690
    }
 
1691
    copyTree(unit, tree->Son(i), end_token, sn, name, make_const);
 
1692
  }
 
1693
 
 
1694
  if (tree->NodeName() == CT_TemplateName::NodeId()) {
 
1695
    extendTemplateName(unit, (CT_TemplateName*)tree);
 
1696
  }
 
1697
  else if (tree->NodeName() == CT_SimpleName::NodeId()) {
 
1698
    extendClassName(unit, (CT_SimpleName*)tree);
 
1699
  }
 
1700
}
 
1701
 
 
1702
 
 
1703
void InstantiationCandidate::extendClassName(CUnit &unit, CT_SimpleName *name) {
 
1704
  CObjectInfo *info = name->Object();
 
1705
  if (info && info == ObjectInfo()) {
 
1706
    // change X to X<T> if X is the instantiated class template
 
1707
    // do not extend X in the class head
 
1708
    CTree* parent = name->Parent()->IsSimpleName() ? name->Parent()->Parent() : name->Parent();
 
1709
    if (parent->NodeName() != CT_ClassDef::NodeId()) { 
 
1710
      unit << "<";
 
1711
      listParameterNames(unit, TemplateInfo());
 
1712
      unit << "> ";
 
1713
    }
 
1714
  }
 
1715
}
 
1716
 
 
1717
 
 
1718
void InstantiationCandidate::extendTemplateName(CUnit &unit, CT_TemplateName *name) {
 
1719
  CObjectInfo *info = name->TemplateName()->Object();
 
1720
  if (info) {
 
1721
    // is template template parameter?
 
1722
    CTemplateParamInfo *pinfo = info->TemplateParamInfo();
 
1723
    if (pinfo && pinfo->isTemplate()) {
 
1724
      // which template parameter is it?
 
1725
      if (getPosition(pinfo) != -1) {
 
1726
        // extend the template name
 
1727
        unit << "::__puma_redirect ";
 
1728
      }
 
1729
    }
 
1730
  }
 
1731
}
 
1732
 
 
1733
 
 
1734
void InstantiationCandidate::listParameters(CUnit &unit, CTemplateInfo *ti) {
 
1735
  CTemplateParamInfo *tp;
 
1736
  CT_TypeParamDecl *tpd;
 
1737
  CT_NonTypeParamDecl *ntpd;
 
1738
  const char* name;
 
1739
 
 
1740
  for (unsigned i = 0; i < ti->Parameters(); ++i) {
 
1741
    if (i > 0) {
 
1742
      unit << ",";
 
1743
    }
 
1744
    tp = ti->Parameter(i);
 
1745
    name = getParameterName(tp);
 
1746
    if (tp->isTypeParam()) {
 
1747
      tpd = (CT_TypeParamDecl*)tp->Tree();
 
1748
      copyTree(unit, tpd, 0, findPrivateName(tpd->Name()), name);
 
1749
    } else {
 
1750
      ntpd = (CT_NonTypeParamDecl*)tp->Tree();
 
1751
      copyTree(unit, ntpd, 0, findPrivateName(ntpd->Declarator()), name);
 
1752
    }
 
1753
  }
 
1754
}
 
1755
 
 
1756
 
 
1757
void InstantiationCandidate::listParameterNames(CUnit &unit, CTemplateInfo *ti) {
 
1758
  for (unsigned j = 0; j < ti->Parameters(); ++j) {
 
1759
    if (j > 0) {
 
1760
      unit << ",";
 
1761
    }
 
1762
    CTemplateParamInfo *tp = ti->Parameter(j);
 
1763
    if (*tp->Name() != '%') {
 
1764
      unit << tp->Name();
 
1765
    } else {
 
1766
      unit << "__puma_" << tp->Name()+1;
 
1767
    }
 
1768
  }
 
1769
}
 
1770
 
 
1771
 
 
1772
const char* InstantiationCandidate::getParameterName(CTemplateParamInfo* param) {
 
1773
  const char* name = param->Name();
 
1774
  if (*name == '%') {
 
1775
    sprintf(anon_name_buf, "__puma_%s", name+1);
 
1776
    name = anon_name_buf;
 
1777
  }
 
1778
  return name;
 
1779
}
 
1780
 
 
1781
 
 
1782
CT_SimpleName *InstantiationCandidate::findPrivateName (CTree *node) {
 
1783
  const char *id = node->NodeName ();
 
1784
  if (id == CT_PrivateName::NodeId ())
 
1785
    return (CT_SimpleName*)node;
 
1786
  else if (id == CT_NamedType::NodeId ())
 
1787
    return findPrivateName (((CT_NamedType*)node)->Declarator ());
 
1788
  else if (id == CT_FctDeclarator::NodeId ())
 
1789
    return findPrivateName (((CT_FctDeclarator*)node)->Declarator ());
 
1790
  else if (id == CT_ArrayDeclarator::NodeId ())
 
1791
    return findPrivateName (((CT_ArrayDeclarator*)node)->Declarator ());
 
1792
  else if (id == CT_PtrDeclarator::NodeId ())
 
1793
    return findPrivateName (((CT_PtrDeclarator*)node)->Declarator ());
 
1794
  else if (id == CT_MembPtrDeclarator::NodeId ())
 
1795
    return findPrivateName (((CT_MembPtrDeclarator*)node)->Declarator ());
 
1796
  else if (id == CT_BracedDeclarator::NodeId ())
 
1797
    return findPrivateName (((CT_BracedDeclarator*)node)->Declarator ());
 
1798
  else if (id == CT_BitFieldDeclarator::NodeId ())
 
1799
    return findPrivateName (((CT_BitFieldDeclarator*)node)->Declarator ());
 
1800
  else if (id == CT_RefDeclarator::NodeId ())
 
1801
    return findPrivateName (((CT_RefDeclarator*)node)->Declarator ());
 
1802
  else if (id == CT_InitDeclarator::NodeId ())
 
1803
    return findPrivateName (((CT_InitDeclarator*)node)->Declarator ());
 
1804
  return (CT_SimpleName*)0;
 
1805
}
 
1806
 
 
1807
 
 
1808
CT_SimpleName *InstantiationCandidate::findName (CTree *node) {
 
1809
  const char *id = node->NodeName ();
 
1810
  if (node->IsSimpleName ())
 
1811
    return (CT_SimpleName*)node;
 
1812
  else if (id == CT_NamedType::NodeId ())
 
1813
    return findName (((CT_NamedType*)node)->Declarator ());
 
1814
  else if (id == CT_FctDeclarator::NodeId ())
 
1815
    return findName (((CT_FctDeclarator*)node)->Declarator ());
 
1816
  else if (id == CT_ArrayDeclarator::NodeId ())
 
1817
    return findName (((CT_ArrayDeclarator*)node)->Declarator ());
 
1818
  else if (id == CT_PtrDeclarator::NodeId ())
 
1819
    return findName (((CT_PtrDeclarator*)node)->Declarator ());
 
1820
  else if (id == CT_MembPtrDeclarator::NodeId ())
 
1821
    return findName (((CT_MembPtrDeclarator*)node)->Declarator ());
 
1822
  else if (id == CT_BracedDeclarator::NodeId ())
 
1823
    return findName (((CT_BracedDeclarator*)node)->Declarator ());
 
1824
  else if (id == CT_BitFieldDeclarator::NodeId ())
 
1825
    return findName (((CT_BitFieldDeclarator*)node)->Declarator ());
 
1826
  else if (id == CT_RefDeclarator::NodeId ())
 
1827
    return findName (((CT_RefDeclarator*)node)->Declarator ());
 
1828
  else if (id == CT_InitDeclarator::NodeId ())
 
1829
    return findName (((CT_InitDeclarator*)node)->Declarator ());
 
1830
  return (CT_SimpleName*)0;
 
1831
}
1315
1832
 
1316
1833
 
1317
1834
} // namespace Puma