147
182
SEM_ERROR (poi, "fatal error: missing template parameter information");
153
188
// check number of template arguments for function templates
154
189
if (obj_info->FunctionInfo () && numargs > tpl_info->Parameters ()) {
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 () << ")");
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);
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
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
173
SEM_ERROR (poi, "missing default argument for parameter " << i+1);
211
SEM_ERROR(poi, "missing default argument for parameter " << pos+1);
178
arg = param->DefaultArgument ()->Entry (0);
181
// function template parameters cannot have default arguments;
182
// ommited arguments must be deducible from the function call
185
return deduceArgumentsFromFctCall (i);
217
// function template parameters do not have default arguments,
218
// ommited arguments must be deduced from the function call
225
// deduce the direct and default arguments
226
if (! (real_inst ? parseDirectArguments(pos, numargs, args) :
227
matchDirectArguments(pos, numargs, args))) {
231
if (pos < tpl_info->Parameters()) {
232
// deduce remaining arguments from function call
233
return deduceArgumentsFromFctCall(pos);
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;
247
if (is_default_arg) {
248
// default template argument
249
arg = param->DefaultArgument ()->Entry (0);
251
// direct template argument
187
252
arg = args->Entry (i);
189
255
// template template parameter: expect name of class base template
190
256
if (param->isTemplate ()) {
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);
205
darguments.append (new DeducedArgument (param,
206
oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
208
if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ())
209
darguments.append (new DeducedArgument (param,
210
oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
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));
212
261
// template type parameter: expect type-id
213
} else if (param->isTypeParam ()) {
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);
220
darguments.append (new DeducedArgument (param,
221
oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
223
if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ())
224
darguments.append (new DeducedArgument (param,
225
oinfo->TypeInfo ()->VirtualType (), arg, default_arg));
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));
227
267
// template non-type parameter: expect constant expression
230
// not a non-type argument
231
if (arg->NodeName () == CT_NamedType::NodeId ()) {
232
SEM_ERROR (arg, "expected a constant as argument " << i+1);
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));
241
// need value of constant
242
if (! arg->Value () || ! arg->Value ()->Constant ()) {
243
SEM_ERROR (arg, "expected a constant as argument " << i+1);
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);
256
atype = arg->Value ()->Type ();
259
} else if (ptype->isPointer () && arg->Value ()->Constant ()->isNull ()) {
260
SEM_ERROR (arg, "could not convert template argument '0' to '" << *ptype << "'");
263
// integral conversions
264
CCConvSeq *seq = cvs.implicitConversions (ptype, atype, arg, 0);
266
SEM_ERROR (arg, "could not convert template argument '" << *atype << "' to '" << *ptype << "'");
271
darguments.append (new DeducedArgument (param,
272
arg->Value ()->Constant (), arg, default_arg));
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));
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));
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));
1263
1301
// setup the preprocessor
1264
1302
TokenStream stream;
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
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
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());
1281
TokenProvider provider (cpp);
1282
tu->tree (p.syntax ().run (provider));
1283
tu->cpp_tree (cpp.syntaxTree ());
1318
TokenProvider provider(cpp);
1319
trans_unit->tree(p.syntax().run(provider));
1320
trans_unit->cpp_tree(cpp.syntaxTree());
1285
1322
// decrease instantiation depth
1286
TemplateInfo ()->decreaseDepth ();
1288
// report errors and clean up
1289
if (((ErrorCollector&)p.builder ().err ()).severity () > sev_warning) {
1292
err << getPoiToken()->location ()
1293
<< "In instantiation of `" << scope->Name ().c_str ()+1
1294
<< "':" << endMessage;
1295
p.builder ().errors (err);
1297
//delete trans_unit;
1300
// no errors detected
1303
//instance->TemplateInstance ()->canDelete ();
1305
//delete trans_unit;
1311
First ().forgetDeducedArgs ();
1323
tpl_info->decreaseDepth ();
1325
// if not failed, deduce from the parsed arguments
1326
if (((ErrorCollector&)p.builder().err()).severity() < sev_error) {
1327
return deduceFromParsedArguments(pos, numargs, args);
1329
// failed due to parse errors
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");
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);
1347
if (is_default_arg) {
1348
// default template argument
1349
arg = param->DefaultArgument()->Entry(0);
1351
// direct template argument
1352
arg = args->Entry(i);
1355
// get the name of the parameter
1356
const char* name = getParameterName(param);
1358
// get the corresponding object in the instance unit
1359
CObjectInfo* oinfo = arg_scope->Object(name);
1360
if (! oinfo || ! oinfo->TypeInfo()) {
1364
// template template parameter: class base template
1365
if (param->isTemplate()) {
1366
// template<...> struct [name] {
1367
// typedef [arg]<...> __puma_redirect;
1369
oinfo = ((CStructure*)oinfo)->Object("__puma_redirect")->TypeInfo()->ClassInfo();
1370
if (! oinfo || ! oinfo->isTemplateInstance()) {
1373
oinfo = oinfo->TemplateInstance()->Template();
1374
darguments.append(new DeducedArgument(param,
1375
oinfo->TypeInfo(), arg, is_default_arg, !is_default_arg));
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));
1383
// template non-type parameter: expect constant expression
1385
// static [type] [name] = [arg];
1386
CTree* init = ((CAttributeInfo*)oinfo)->Init();
1387
if (! init || ! init->Value() || ! init->Value()->Constant()) {
1390
darguments.append(new DeducedArgument(param,
1391
init->Value()->Constant(), arg, is_default_arg, !is_default_arg));
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);
1406
if (is_default_arg) {
1407
// default template argument
1408
arg = param->DefaultArgument()->Entry(0);
1410
// direct template argument
1411
arg = args->Entry(i);
1414
// get the name of the parameter, generate one
1415
// if the parameter is anonymous
1416
const char* name = getParameterName(param);
1418
if (param->isTemplate()) {
1419
// template-template parameter
1420
CTypeInfo* type = 0;
1421
if (! is_default_arg) {
1422
// get the template type
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);
1436
type = oinfo->TypeInfo()->VirtualType();
1438
if (! insertTemplateTemplateArgument(param, arg, type, name, unit))
1441
else if (param->isTypeParam()) {
1442
// template type parameter
1443
CTypeInfo* type = 0;
1444
if (! is_default_arg) {
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);
1453
type = oinfo->TypeInfo()->VirtualType();
1455
if (! insertTypeTemplateArgument(param, arg, type, name, unit))
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);
1467
// need value of constant
1468
if (! arg->Value() || ! arg->Value()->Constant()) {
1469
SEM_ERROR(arg, "expected a constant as argument " << i+1);
1472
value = arg->Value()->Constant();
1474
if (! insertNonTypeTemplateArgument(param, arg, value, name, unit))
1479
// finish and scan the code
1480
unit << "}\n" << endu;
1482
// dump code to stdout if tracing enabled
1483
//if (TRACE_INSTANCE_CODE) {
1484
// dumpInstanceCode(unit);
1490
bool InstantiationCandidate::insertNonTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CConstant* value, const char* name, CUnit& unit) {
1491
// static [type] [name] = [arg];
1493
CT_NonTypeParamDecl* decl = (CT_NonTypeParamDecl*)param->Tree();
1494
copyTree(unit, decl->DeclSpecs(), 0, 0, name);
1496
copyTree(unit, decl->Declarator(), 0, findName(decl->Declarator()),
1497
name, param->ValueType() && ! param->ValueType()->isConst());
1502
copyTree(unit, tree, tree->end_token());
1511
bool InstantiationCandidate::insertTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type, const char* name, CUnit& unit) {
1512
// typedef [arg] [name];
1515
type->TypeText(unit, name, true);
1517
copyTree(unit, tree, 0, findPrivateName(tree), name);
1526
bool InstantiationCandidate::insertTemplateTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type, const char* name, CUnit& unit) {
1527
// template<...> struct [name] {
1528
// typedef [arg]<...> __puma_redirect;
1530
CTemplateInfo* ti = param->TemplateTemplate();
1531
unit << "template< ";
1532
listParameters(unit, ti);
1533
unit << " > struct " << name << " {\n typedef ";
1535
type->TypeText(unit, 0, true);
1537
copyTree(unit, tree, tree->end_token());
1542
listParameterNames(unit, ti);
1543
unit << "> __puma_redirect;\n};\n";
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 ());
1556
// get the name of the parameter, generate one
1557
// if the parameter is anonymous
1558
const char* name = getParameterName(param);
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";
1569
if (param->isTemplate ()) {
1570
// deduced template-template argument
1571
if (! insertTemplateTemplateArgument(param, 0, arg->Type(), name, unit))
1573
} else if (param->isTypeParam ()) {
1574
// deduced type argument
1575
if (! insertTypeTemplateArgument(param, 0, arg->Type(), name, unit))
1578
// deduced non-type argument
1579
if (! insertNonTypeTemplateArgument(param, 0, arg->Value(), name, unit))
1584
// check for a template parameter in the class name -> desturbs
1585
Array<CTree*> desturbing;
1586
calculateDesturbing (desturbing);
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);
1594
unit << "\n" << endu;
1596
if (TRACE_INSTANCE_CODE) {
1597
dumpInstanceCode(unit);
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 ());
1624
void InstantiationCandidate::dumpInstanceCode(CUnit& unit) {
1626
if (PointOfInstantiation()) {
1627
std::cout << getPointOfInstantiationToken()->location() << ": ";
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;
1637
std::cout << "-------------------" << std::endl;
1638
unit.print(std::cout);
1639
std::cout << "-------------------\n" << std::endl;
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
1647
for (int i = 0; i < desturbing->length (); i++)
1648
if (desturbing->lookup (i) == tree)
1649
return; // prune here
1652
// replace name with name of the current template parameter
1656
if (sn->NodeName() == CT_PrivateName::NodeId())
1657
unit << name << " ";
1659
else if (tree->NodeName() == CT_Token::NodeId()) {
1661
Token* t = tree->token();
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() : " ");
1675
if (tree->NodeName() == CT_FctDef::NodeId()) {
1676
body = ((CT_FctDef*)tree)->Body();
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 ';'
1686
// don't instantiate function body, instantiated on demand
1691
copyTree(unit, tree->Son(i), end_token, sn, name, make_const);
1694
if (tree->NodeName() == CT_TemplateName::NodeId()) {
1695
extendTemplateName(unit, (CT_TemplateName*)tree);
1697
else if (tree->NodeName() == CT_SimpleName::NodeId()) {
1698
extendClassName(unit, (CT_SimpleName*)tree);
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()) {
1711
listParameterNames(unit, TemplateInfo());
1718
void InstantiationCandidate::extendTemplateName(CUnit &unit, CT_TemplateName *name) {
1719
CObjectInfo *info = name->TemplateName()->Object();
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 ";
1734
void InstantiationCandidate::listParameters(CUnit &unit, CTemplateInfo *ti) {
1735
CTemplateParamInfo *tp;
1736
CT_TypeParamDecl *tpd;
1737
CT_NonTypeParamDecl *ntpd;
1740
for (unsigned i = 0; i < ti->Parameters(); ++i) {
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);
1750
ntpd = (CT_NonTypeParamDecl*)tp->Tree();
1751
copyTree(unit, ntpd, 0, findPrivateName(ntpd->Declarator()), name);
1757
void InstantiationCandidate::listParameterNames(CUnit &unit, CTemplateInfo *ti) {
1758
for (unsigned j = 0; j < ti->Parameters(); ++j) {
1762
CTemplateParamInfo *tp = ti->Parameter(j);
1763
if (*tp->Name() != '%') {
1766
unit << "__puma_" << tp->Name()+1;
1772
const char* InstantiationCandidate::getParameterName(CTemplateParamInfo* param) {
1773
const char* name = param->Name();
1775
sprintf(anon_name_buf, "__puma_%s", name+1);
1776
name = anon_name_buf;
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;
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;
1317
1834
} // namespace Puma