~ubuntu-branches/ubuntu/maverick/aspectc++/maverick

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-04-10 17:40:52 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080410174052-xdnsm7oi8hauyyf1
Tags: 1.0pre4~svn.20080409+dfsg-3
Fix another missing include, this time in Ag++/StdSystem.cc

Show diffs side-by-side

added added

removed removed

Lines of Context:
110
110
}
111
111
 
112
112
 
113
 
// �14.8.2 deduce template arguments (if necessary)
 
113
// §14.8.2 deduce template arguments (if necessary)
114
114
bool InstantiationCandidate::deduceArguments (bool real_inst) {
115
115
  CTemplateParamInfo *param;
116
116
  CT_TemplateArgList *args;
141
141
  else if (obj_info->FunctionInfo ())
142
142
    tpl_info = obj_info->FunctionInfo ()->TemplateInfo ();
143
143
  else if (obj_info->TemplateParamInfo ())
144
 
    tpl_info = obj_info->TemplateParamInfo ()->TemplateInfo ();
 
144
    tpl_info = obj_info->TemplateParamInfo ()->TemplateTemplate ();
145
145
  if (! tpl_info) {
146
146
// TEMPORARY HACK --->
147
147
    if (real_inst) {
188
188
      // ommited arguments must be deducible from the function call
189
189
      // argument list
190
190
      } else 
191
 
        return deduceArguments (i);
 
191
        return deduceArgumentsFromFctCall (i);
192
192
    } else
193
193
      arg = args->Entry (i);
194
194
    
291
291
}
292
292
 
293
293
 
294
 
// �14.8.2 deduce template arguments from function call
295
 
bool InstantiationCandidate::deduceArguments (unsigned skip) {
 
294
// §14.8.2 deduce template arguments from function call
 
295
bool InstantiationCandidate::deduceArgumentsFromFctCall (unsigned skip) {
296
296
  DeducedArgumentList dargs (tpl_info->Parameters ()-skip);
297
297
  CFunctionInfo *finfo;
298
298
  CTypeList *fargs;
301
301
  bool succeeded;
302
302
  CTree *arg;
303
303
 
 
304
  //copied = false;
304
305
  succeeded = true;
305
306
  finfo = obj_info->FunctionInfo ();
306
307
  fargs = finfo->TypeInfo ()->ArgTypes ();
332
333
    } else
333
334
      arg = Argument (i);
334
335
    
335
 
    // �14.3.2.5 implicit argument type conversions
336
 
    type = arg->Type ()->VirtualType ();
 
336
    // §14.3.2.5 implicit argument type conversions
 
337
    type = arg->Type () ? arg->Type () : arg->SemObject ()->Object ()->TypeInfo ();
 
338
    type = type->VirtualType ();
337
339
    // array-to-pointer and function-to-pointer conversions
338
 
    if (type->isArray () || type->isFunction ()) {
339
 
      type = type->isArray () ? type->VirtualType ()->BaseType () : type;
340
 
      type = new CTypePointer (type->Duplicate ());
341
 
    } else {
342
 
      // qualification conversion
343
 
      if (type->TypeQualified ())
344
 
        type = type->UnqualType ()->Duplicate ();
345
 
      // integral promotion and conversion
346
 
      if (type->isInteger ()) {
347
 
        CCConversions cvs (*err);
348
 
        type = cvs.integralPromotion (type)->Duplicate ();
 
340
    if (! fargs->Entry (i)->isAddress ()) {
 
341
      if (type->isArray () || type->isFunction ()) {
 
342
        type = type->isArray () ? type->VirtualType ()->BaseType () : type;
 
343
        type = new CTypePointer (type->Duplicate ());
349
344
      }
 
345
    } 
 
346
    
 
347
    if (deduceArguments (fargs->Entry (i)->VirtualType (), type, dargs) != 0) {
 
348
      succeeded = false;
350
349
    }
351
 
        
352
 
    succeeded = deduceArguments (fargs->Entry (i)->VirtualType (), type, dargs);
353
 
 
354
 
    if (type != arg->Type ()->VirtualType ())
355
 
      CTypeInfo::Destroy (type);
356
350
  }
357
351
 
358
352
  for (unsigned i = 0; i < (unsigned)dargs.length () && succeeded; i++) {
367
361
}
368
362
 
369
363
 
370
 
bool InstantiationCandidate::deduceArguments (CTypeInfo *ftype, CTypeInfo *atype, 
371
 
 DeducedArgumentList &dargs) {
372
 
  CTemplateInstance *fui, *aui, *fci, *aci;
373
 
  CObjectInfo *finfo, *ainfo;
374
 
  CTemplateParamInfo *param;
375
 
  CTypeList *ftl, *atl;
376
 
  CTypeInfo *type;
377
 
  int pos;
378
 
 
379
 
  ftype = ftype->UnqualType ();
380
 
  atype = atype->UnqualType ();
381
 
  
 
364
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
 
365
int InstantiationCandidate::deduceArguments (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
 
366
  int ret;
 
367
  
 
368
  // ignore qualifiers if exact match is not required
 
369
  if (! exact_match) {
 
370
    ftype = ftype->UnqualType ();
 
371
  }
 
372
  
 
373
  // template parameter
382
374
  if (ftype->TypeTemplateParam ()) {
383
 
    param = ftype->TypeTemplateParam ()->TemplateParamInfo ();
384
 
    pos = getPosition (param);
385
 
    if (pos != -1) {
386
 
      if (param->isTemplate ()) {
387
 
        if (atype->TypeRecord () && 
388
 
            (ainfo = atype->TypeRecord ()->Record ()) &&
389
 
            ainfo->isTemplateInstance ()) {
390
 
          if (ainfo->UnionInstance ())
391
 
            dargs[pos] = new DeducedArgument (param, 
392
 
              ainfo->TemplateInstance ()->Template ()->ObjectInfo ()->TypeInfo ());
393
 
          else if (ainfo->ClassInstance ())
394
 
            dargs[pos] = new DeducedArgument (param, 
395
 
              ainfo->TemplateInstance ()->Template ()->ObjectInfo ()->TypeInfo ());
396
 
        }
397
 
      } else if (param->isTypeParam ()) 
398
 
        dargs[pos] = new DeducedArgument (param, atype);
399
 
    }
400
 
    return true;
401
 
  } 
402
 
  
403
 
  if (ftype->Id () != atype->Id () ||
404
 
      ftype->TypeEmpty () || ftype->TypePrimitive ()) {
405
 
    return true;
406
 
  } 
407
 
  
 
375
    return deduceTemplateParam (ftype, atype, dargs, exact_match);
 
376
  }
 
377
  
 
378
  // types must be equal to deduce template arguments
 
379
  if (ftype->Id () != atype->Id ()) { 
 
380
    return exact_match ? 2 : 0;
 
381
  }
 
382
  
 
383
  // nothing to deduce
 
384
  if (ftype->TypeEmpty () || ftype->TypePrimitive ()) {
 
385
    return 0;
 
386
  }
 
387
  
 
388
  // deduce from pointer to class member
408
389
  if (ftype->TypeMemberPointer ()) {
409
 
    param = ftype->TypeMemberPointer ()->TemplateParam ();
410
 
    if (param) {
411
 
      pos = getPosition (param);
412
 
      if (pos != -1 && param->isTypeParam () && atype->TypeMemberPointer ()->Record ()) 
413
 
        dargs[pos] = new DeducedArgument (param, 
414
 
          atype->TypeMemberPointer ()->Record ()->TypeInfo ());
415
 
    }
 
390
    return deduceFromMemberPointer (ftype, atype, dargs, exact_match);
 
391
 
 
392
  // deduce from class or union type
416
393
  } else if (ftype->TypeRecord ()) {
417
 
    finfo = ftype->TypeRecord ()->Record ();
418
 
    ainfo = atype->TypeRecord ()->Record ();
419
 
    if (finfo && ainfo && finfo->isTemplateInstance () &&
420
 
        ainfo->isTemplateInstance ()) {
421
 
      fui = finfo->UnionInstance () ? finfo->TemplateInstance () : 0; 
422
 
      aui = ainfo->UnionInstance () ? ainfo->TemplateInstance () : 0; 
423
 
      if (fui && aui && fui->DeducedArgs () == aui->DeducedArgs ()) {
424
 
        for (unsigned i = 0; i < fui->DeducedArgs (); i++)
425
 
          if ((type = fui->DeducedArg (i)->Type ())) {
426
 
            if (aui->DeducedArg (i)->Type ()) {
427
 
              if (! deduceArguments (type, aui->DeducedArg (i)->Type (), dargs))
428
 
                return false;
429
 
            } else if (type->TypeTemplateParam () &&
430
 
                     ! type->TypeTemplateParam ()->isTypeParam ()) {
431
 
              param = type->TypeTemplateParam ()->TemplateParamInfo ();
432
 
              if (param) {
433
 
                pos = getPosition (param);
434
 
                if (pos != -1) 
435
 
                  dargs[pos] = new DeducedArgument (param, aui->DeducedArg (i)->Value ());
436
 
              }
437
 
            }
438
 
          }
439
 
      }
440
 
      fci = finfo->ClassInstance () ? finfo->TemplateInstance () : 0; 
441
 
      aci = ainfo->ClassInstance () ? ainfo->TemplateInstance () : 0; 
442
 
      if (fci && aci && fci->DeducedArgs () == aci->DeducedArgs ()) {
443
 
        for (unsigned i = 0; i < fci->DeducedArgs (); i++)
444
 
          if ((type = fci->DeducedArg (i)->Type ())) {
445
 
            if (aci->DeducedArg (i)->Type ()) {
446
 
              if (! deduceArguments (type, aci->DeducedArg (i)->Type (), dargs))
447
 
                return false;
448
 
            } else if (type->TypeTemplateParam () &&
449
 
                     ! type->TypeTemplateParam ()->isTypeParam ()) {
450
 
              param = type->TypeTemplateParam ()->TemplateParamInfo ();
451
 
              if (param) {
452
 
                pos = getPosition (param);
453
 
                if (pos != -1) 
454
 
                  dargs[pos] = new DeducedArgument (param, aci->DeducedArg (i)->Value ());
455
 
              }
456
 
            }
457
 
          }
458
 
      }
459
 
    }
460
 
    return true;
 
394
    return deduceFromRecord (ftype, atype, dargs, exact_match);
 
395
 
 
396
  // deduce from array type
461
397
  } else if (ftype->TypeArray ()) {
462
 
    if (ftype->TypeArray ()->DepDim ()) {
463
 
      param = ftype->TypeArray ()->DepDim ()->TemplateParamInfo ();
464
 
      if (param) {
465
 
        pos = getPosition (param);
466
 
        if (pos != -1 && ! param->isTypeParam () && atype->TypeArray ()->Dimension ())
467
 
          dargs[pos] = new DeducedArgument (param, atype->TypeArray ()->Dimension ());
468
 
      }
 
398
    if ((ret = deduceFromArray (ftype, atype, dargs, exact_match)) != 0) { 
 
399
      return ret;
469
400
    }
 
401
 
 
402
  // deduce from function type
470
403
  } else if (ftype->TypeFunction ()) {
471
 
    if (ftype->TypeFunction ()->ArgTypes ()->Entries () == 
472
 
        atype->TypeFunction ()->ArgTypes ()->Entries ()) {
473
 
      ftl = ftype->TypeFunction ()->ArgTypes ();
474
 
      atl = atype->TypeFunction ()->ArgTypes ();
475
 
      for (unsigned i = 0; i < ftl->Entries (); i++) {
476
 
        if (! deduceArguments (ftl->Entry (i), atl->Entry (i), dargs)) 
477
 
          return false;
478
 
      }
479
 
    }
480
 
  }
481
 
  
482
 
  return deduceArguments (ftype->BaseType (), atype->BaseType (), dargs);
483
 
}
484
 
 
485
 
 
486
 
// �14.5.4.1.2 try to match a partial specialization 
 
404
    if ((ret = deduceFromFunction (ftype, atype, dargs, exact_match)) != 0) { 
 
405
      return ret;
 
406
    }
 
407
  }
 
408
  
 
409
  // deduce from the base types, types must match exactly
 
410
  return deduceArguments (ftype->BaseType (), atype->BaseType (), dargs, exact_match);
 
411
}
 
412
 
 
413
 
 
414
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
 
415
int InstantiationCandidate::deduceFromFunction (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
 
416
  CTypeFunction *fft = ftype->TypeFunction ();
 
417
  CTypeFunction *aft = atype->TypeFunction ();
 
418
  
 
419
  // number of function parameters must be equal
 
420
  if (fft->ArgTypes ()->Entries () == aft->ArgTypes ()->Entries ()) {
 
421
    CTypeList *ftl = fft->ArgTypes ();
 
422
    CTypeList *atl = aft->ArgTypes ();
 
423
    
 
424
    bool matching_args = true;
 
425
    bool ambiguous_type = false;
 
426
    DeducedArgumentList curr_dargs;
 
427
        
 
428
    // prepare temporary deduced argument container
 
429
    for (unsigned i = 0; i < tpl_info->Parameters (); i++) {
 
430
      curr_dargs.append (0);
 
431
    }
 
432
    
 
433
    // deduce from the function parameters
 
434
    for (unsigned i = 0; i < ftl->Entries () && matching_args && ! ambiguous_type; i++) {
 
435
      switch (deduceArguments (ftl->Entry (i), atl->Entry (i), dargs, true)) {
 
436
        case 2: matching_args = false; break;
 
437
        case 1: ambiguous_type = true; break;
 
438
        default: break;
 
439
      }
 
440
    }
 
441
    
 
442
    // join the deduced template arguments if possible
 
443
    if (! joinDeducedArguments (dargs, curr_dargs, matching_args, ambiguous_type)) {
 
444
      return matching_args && ambiguous_type ? 1 : 
 
445
             exact_match && ! matching_args ? 2 : 0;
 
446
    }
 
447
 
 
448
  // different number of function parameters
 
449
  } else if (exact_match) {
 
450
    return 2;
 
451
  }
 
452
 
 
453
  return 0; 
 
454
}
 
455
 
 
456
 
 
457
bool InstantiationCandidate::joinDeducedArguments (DeducedArgumentList &dargs, DeducedArgumentList &curr_dargs, bool &matching_args, bool &ambiguous_type) {
 
458
  // check if the current deduced template arguments are valid
 
459
  if (! matching_args || ambiguous_type) {
 
460
    // discard the deduced template arguments
 
461
    for (long i = 0; i < curr_dargs.length (); i++) {
 
462
      DeducedArgument *darg = curr_dargs.fetch (i);
 
463
      if (darg) delete darg;
 
464
    }
 
465
  } 
 
466
  // if not ambiguous, add the deduced arguments to dargs
 
467
  if (matching_args) {
 
468
    // join the deduced template arguments
 
469
    if (! ambiguous_type) {
 
470
      for (long i = 0; i < curr_dargs.length (); i++) {
 
471
        DeducedArgument *darg = curr_dargs.fetch (i);
 
472
        if (darg && ! setDeducedArgument (dargs, i, darg)) {
 
473
          ambiguous_type = true;
 
474
        }
 
475
      }
 
476
    }
 
477
  }
 
478
  return matching_args && ! ambiguous_type;
 
479
}
 
480
 
 
481
 
 
482
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
 
483
int InstantiationCandidate::deduceFromArray (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
 
484
  CTypeArray *array = ftype->TypeArray ();
 
485
  
 
486
  // array size depends on a template parameter
 
487
  if (array->DepDim ()) {
 
488
    CTemplateParamInfo *param = array->DepDim ()->TemplateParamInfo ();
 
489
    
 
490
    if (param) {
 
491
      int pos = getPosition (param);
 
492
      
 
493
      // non-type template parameter
 
494
      if (pos != -1 && ! param->isTypeParam ()) {
 
495
        array = atype->TypeArray ();
 
496
        
 
497
        // array has dimension
 
498
        if (array->Dimension ()) { 
 
499
          if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, array->Dimension ()))) {
 
500
            return 1;
 
501
          }
 
502
        
 
503
        // match non-type template parameter for partial ordering of function templates
 
504
        } else if (array->DepDim ()) {     
 
505
          CTemplateParamInfo *aparam = array->DepDim ()->TemplateParamInfo ();
 
506
          if (aparam && 
 
507
              ! aparam->isTypeParam () && 
 
508
              ! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
 
509
            return 1;
 
510
          }
 
511
        }
 
512
      }
 
513
    }
 
514
    
 
515
  // ordinary types must be an exact match
 
516
  } else if (exact_match && (*ftype != *atype)) {
 
517
    return 2;
 
518
  }
 
519
  
 
520
  return 0;
 
521
}
 
522
 
 
523
 
 
524
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
 
525
int InstantiationCandidate::deduceTemplateParam (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
 
526
  CTemplateParamInfo *param = ftype->TypeTemplateParam ()->TemplateParamInfo ();
 
527
  int ret, pos = getPosition (param);
 
528
  
 
529
  if (pos != -1) {
 
530
    // template template parameter
 
531
    if (param->isTemplate ()) {
 
532
      CObjectInfo *ainfo = atype->TypeRecord () ? (CObjectInfo*)atype->TypeRecord ()->Record () : 
 
533
                           atype->TypeTemplateParam () ? (CObjectInfo*)atype->TypeTemplateParam ()->TemplateParamInfo () : 0;
 
534
 
 
535
      // template parameter list must match
 
536
      if (! matchingTemplateParameters (param, ainfo)) {
 
537
        return exact_match ? 2 : 0;
 
538
      }
 
539
      
 
540
      // get the template instance info of the argument, if it is an template instance
 
541
      CTemplateInstance *ti = ainfo->Record () ? ainfo->TemplateInstance () : ainfo->TemplateParamInfo ()->TemplateInstance ();  
 
542
      CTemplateInfo *tpl = getTemplateInfo (ainfo);
 
543
 
 
544
      // match template instance
 
545
      if (param->TemplateInstance ()) {
 
546
        if (! ti) {
 
547
          // not a template instance
 
548
          return exact_match ? 2 : 0;
 
549
        }
 
550
 
 
551
        // deduce from the argument list
 
552
        ret = deduceArgumentsFromTemplateArgList (param->TemplateInstance (), ti, dargs);
 
553
        if (ret != 0) {
 
554
          return ret;
 
555
        }
 
556
        
 
557
        // matches the template itself
 
558
        if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, tpl->ObjectInfo ()->TypeInfo ()))) {
 
559
          return 1;
 
560
        } 
 
561
      
 
562
      // template template parameter does not match template instances
 
563
      } else if (ti) {
 
564
        return exact_match ? 2 : 0;
 
565
 
 
566
      // match template itself (template name)
 
567
      } else {
 
568
        if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, tpl->ObjectInfo ()->TypeInfo ()))) {
 
569
          return 1;
 
570
        }
 
571
      }
 
572
 
 
573
    // type template parameter, matches any type
 
574
    } else if (param->isTypeParam ()) {
 
575
      if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
 
576
        return 1;
 
577
      }
 
578
 
 
579
    // non-type template parameter, matches any value or non-type template parameter,
 
580
    // for partial ordering of function templates
 
581
    } else if (! param->isTypeParam ()) {
 
582
      if (atype->TypeTemplateParam ()) {
 
583
        CTemplateParamInfo *aparam = atype->TypeTemplateParam ()->TemplateParamInfo ();
 
584
        if (aparam && 
 
585
            ! aparam->isTypeParam () && 
 
586
            ! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
 
587
          return 1;
 
588
        }
 
589
      }
 
590
    }
 
591
  }
 
592
  
 
593
  return 0;
 
594
}
 
595
 
 
596
 
 
597
bool InstantiationCandidate::matchingTemplateParameters (CTemplateParamInfo *param, CObjectInfo *ainfo) {
 
598
  if (! ainfo)
 
599
    return false;
 
600
    
 
601
  CTemplateInfo *atpl = getTemplateInfo (ainfo);
 
602
  CTemplateInfo *ftpl = param->TemplateTemplate ();
 
603
    
 
604
  if (! ftpl && ! atpl)
 
605
    return true;
 
606
  if (! ftpl || ! atpl || ftpl->Parameters () != atpl->Parameters ())
 
607
    return false;
 
608
    
 
609
  for (unsigned i = 0; i < ftpl->Parameters (); i++) {
 
610
    CTemplateParamInfo *fparam = ftpl->Parameter (i);  
 
611
    CTemplateParamInfo *aparam = atpl->Parameter (i);
 
612
    
 
613
    if (*fparam->TypeInfo () != *aparam->TypeInfo ()) 
 
614
      return false;
 
615
  }
 
616
 
 
617
  return true;
 
618
}
 
619
 
 
620
 
 
621
CTemplateInfo *InstantiationCandidate::getTemplateInfo (CObjectInfo *info) {
 
622
  CTemplateInfo *tpl = 0;
 
623
  if (info->TemplateInstance ())
 
624
    tpl = info->TemplateInstance ()->Template ();
 
625
  else if (info->Record ())
 
626
    tpl = info->Record ()->TemplateInfo ();
 
627
  else if (info->TemplateParamInfo ())
 
628
    tpl = info->TemplateParamInfo ()->TemplateTemplate ();
 
629
  return tpl;
 
630
}
 
631
 
 
632
 
 
633
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
 
634
int InstantiationCandidate::deduceFromMemberPointer (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
 
635
  CTemplateParamInfo *param = ftype->TypeMemberPointer ()->TemplateParam ();
 
636
 
 
637
  // member pointer of form T::member where T is a type template parameter
 
638
  if (param) {
 
639
    int pos = getPosition (param);
 
640
    if (pos != -1 && param->isTypeParam ()) {
 
641
      
 
642
      CRecord *record = atype->TypeMemberPointer ()->Record ();
 
643
      
 
644
      // argument type is class or union, can be deduced
 
645
      if (record) {
 
646
        if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, record->TypeInfo ()))) {
 
647
          return 1;
 
648
        }
 
649
      
 
650
      // argument member pointer type contains template parameter, handled as unique type for 
 
651
      // partial ordering of function templates
 
652
      } else {
 
653
        CTemplateParamInfo *tp = atype->TypeMemberPointer ()->TemplateParam ();
 
654
        if (tp && tp->isTypeParam () && ! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
 
655
          return 1;
 
656
        }
 
657
      }
 
658
    }
 
659
  
 
660
  // ordinary types must match, if not the top level types
 
661
  } else if (exact_match && (*ftype != *atype)) {
 
662
    return 2;
 
663
  }
 
664
  
 
665
  return 0; 
 
666
}
 
667
 
 
668
 
 
669
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
 
670
int InstantiationCandidate::deduceFromRecord (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
 
671
  CRecord *finfo = ftype->TypeRecord ()->Record ();
 
672
  CRecord *ainfo = atype->TypeRecord ()->Record ();
 
673
  
 
674
  if (finfo && ainfo) {
 
675
    // types must have same record type, i.e. either class or union 
 
676
    if ((finfo->ClassInfo () && ! ainfo->ClassInfo ()) ||
 
677
        (finfo->UnionInfo () && ! ainfo->UnionInfo ())) {
 
678
      return exact_match ? 2 : 0;
 
679
    }
 
680
  
 
681
    // parameter type is template instance
 
682
    if (finfo->isTemplateInstance ()) {
 
683
      // deduce template arguments from the type arguments of the template instances,
 
684
      // the template used to instantiate finfo must be equal to the template used
 
685
      // to instantiate ainfo or one of its base classes
 
686
      
 
687
      CTemplateInstance *fi = finfo->TemplateInstance (); 
 
688
      Array<CTemplateInstance*> instances;
 
689
      getTemplateInstances (ainfo, instances); // search the class hierarchy of ainfo
 
690
    
 
691
      bool at_least_one_match = false;
 
692
      for (long j = 0; j < instances.length (); j++) {
 
693
        CTemplateInstance *ai = instances.fetch (j);
 
694
      
 
695
        // same template and same number of template arguments
 
696
        CTemplateInfo *ft = fi->Template ()->BaseTemplate () ? fi->Template ()->BaseTemplate () : fi->Template ();
 
697
        CTemplateInfo *at = ai->Template ()->BaseTemplate () ? ai->Template ()->BaseTemplate () : ai->Template ();
 
698
        if (*ft != *at || fi->InstantiationArgs () != ai->InstantiationArgs ()) {
 
699
          continue;
 
700
        }
 
701
 
 
702
        // deduce from the template arguments
 
703
        int ret = deduceArgumentsFromTemplateArgList (fi, ai, dargs);
 
704
        if (ret == 1) {
 
705
          return 1;
 
706
        }
 
707
        at_least_one_match = at_least_one_match || (ret == 0);
 
708
      }
 
709
      
 
710
      // require exact match
 
711
      if (! at_least_one_match) {
 
712
        return 2;
 
713
      }
 
714
     
 
715
    // ordinary types must match, if not the top level types
 
716
    } else if (exact_match && (*finfo != *ainfo)) {
 
717
      return 2;
 
718
    }
 
719
  }
 
720
    
 
721
  return 0; 
 
722
}
 
723
 
 
724
 
 
725
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
 
726
int InstantiationCandidate::deduceArgumentsFromTemplateArgList (CTemplateInstance *fi, CTemplateInstance *ai, DeducedArgumentList &dargs) {
 
727
  bool matching_args = true;
 
728
  bool ambiguous_type = false;
 
729
  DeducedArgumentList curr_dargs;
 
730
        
 
731
  // number of template arguments must match
 
732
  if (fi->InstantiationArgs () != ai->InstantiationArgs ()) {
 
733
    return 2;
 
734
  }
 
735
  
 
736
  // prepare temporary deduced argument container
 
737
  for (unsigned i = 0; i < tpl_info->Parameters (); i++) {
 
738
    curr_dargs.append (0);
 
739
  }
 
740
 
 
741
  // now try to deduce from the template arguments, must match exactly 
 
742
  // for a successful deduction
 
743
  for (unsigned i = 0; i < fi->InstantiationArgs () && matching_args && ! ambiguous_type; i++) {
 
744
    CTypeInfo *fdtype = fi->InstantiationArg (i)->Type ();
 
745
    CTypeInfo *adtype = ai->InstantiationArg (i)->Type ();
 
746
    CConstant *fvalue = fi->InstantiationArg (i)->Value ();
 
747
    CConstant *avalue = ai->InstantiationArg (i)->Value ();
 
748
          
 
749
    if (fdtype) {
 
750
      // type template arguments
 
751
      if (adtype) {
 
752
        switch (deduceArguments (fdtype, adtype, curr_dargs, true)) {
 
753
          case 2: matching_args = false; break;
 
754
          case 1: ambiguous_type = true; break;
 
755
          default: break;
 
756
        }
 
757
 
 
758
      // non-type template arguments
 
759
      } else if (avalue && 
 
760
                 fdtype->TypeTemplateParam () && 
 
761
                 ! fdtype->TypeTemplateParam ()->isTypeParam ()) {
 
762
        CTemplateParamInfo *param = fdtype->TypeTemplateParam ()->TemplateParamInfo ();
 
763
        if (param) {
 
764
          int pos = getPosition (param);
 
765
          if (pos != -1 && ! setDeducedArgument (curr_dargs, pos, new DeducedArgument (param, avalue))) {
 
766
            ambiguous_type = true;
 
767
          }
 
768
        }
 
769
              
 
770
      } else {
 
771
        matching_args = false;
 
772
      }
 
773
          
 
774
    // non-type template arguments
 
775
    } else if (fvalue && (! avalue || (*fvalue != *avalue))) {
 
776
      matching_args = false;
 
777
    }
 
778
  }
 
779
        
 
780
  // check if deduced template arguments are valid
 
781
  if (! matching_args || ambiguous_type) {
 
782
    // discard the deduced template arguments
 
783
    for (long i = 0; i < curr_dargs.length (); i++) {
 
784
      DeducedArgument *darg = curr_dargs.fetch (i);
 
785
      if (darg) delete darg;
 
786
    }
 
787
  } 
 
788
  // if not ambiguous, add the deduced arguments to dargs
 
789
  if (matching_args) {
 
790
    // add the deduced template arguments
 
791
    if (! ambiguous_type) {
 
792
      for (long i = 0; i < curr_dargs.length (); i++) {
 
793
        DeducedArgument *darg = curr_dargs.fetch (i);
 
794
        if (darg && ! setDeducedArgument (dargs, i, darg)) {
 
795
          ambiguous_type = true;
 
796
        }
 
797
      }
 
798
    }
 
799
    if (ambiguous_type) {
 
800
      return 1;
 
801
    }
 
802
    return 0;
 
803
  }
 
804
  return 2;
 
805
}
 
806
 
 
807
 
 
808
void InstantiationCandidate::getTemplateInstances(CRecord* c, Array<CTemplateInstance*>& instances) {
 
809
  if (c->isTemplateInstance ()) {
 
810
    instances.append (c->TemplateInstance ());
 
811
  }
 
812
  CClassInfo *cl = c->ClassInfo ();
 
813
  if (cl) {
 
814
    for (unsigned i = 0; i < cl->BaseClasses (); i++) {
 
815
      getTemplateInstances (cl->BaseClass (i)->Class (), instances);
 
816
    }
 
817
  }
 
818
}
 
819
 
 
820
 
 
821
// §14.5.4.1.2 try to match a partial specialization 
487
822
// against a given template argument list
488
823
bool InstantiationCandidate::match () {
489
824
  CT_TemplateArgList *args;
772
1107
}
773
1108
 
774
1109
 
775
 
// �14.5.5.2 partial ordering rules
 
1110
// §14.5.5.2 partial ordering rules
776
1111
// return 0 if equal, 1 if more, and -1 if less specialized than other
777
1112
int InstantiationCandidate::compare (InstantiationCandidate &other) {
778
1113
  InstantiationCandidate cand1;
803
1138
}
804
1139
 
805
1140
 
 
1141
bool InstantiationCandidate::setDeducedArgument (DeducedArgumentList &args, int pos, DeducedArgument *arg) {
 
1142
  bool res = true;
 
1143
  DeducedArgument *old = args[pos];
 
1144
  if (! old) {
 
1145
    args[pos] = arg;
 
1146
  } else {
 
1147
    res = (*arg == *old);
 
1148
    delete arg;
 
1149
  }
 
1150
  return res;
 
1151
}
 
1152
 
 
1153
 
806
1154
} // namespace Puma