~ubuntu-branches/ubuntu/quantal/aspectc++/quantal

« back to all changes in this revision

Viewing changes to Puma/gen-release/step1/src/CCSemExpr.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:
35
35
#include "Puma/CTemplateInfo.h"
36
36
#include "Puma/CNamespaceInfo.h"
37
37
#include "Puma/CTemplateParamInfo.h"
 
38
#include "Puma/CTemplateInstance.h"
38
39
#include "Puma/CWStrLiteral.h"
39
40
#include "Puma/CStrLiteral.h"
40
41
 
42
43
// the include cycle problem
43
44
#include "Puma/CCSemVisitor.h"
44
45
 
 
46
#include <climits>
45
47
#include <string>
46
48
#include <sstream>         /* istringstream */
47
49
#include "Puma/WChar.h"    /* wcslen() */
48
50
#include <ctype.h>         /* isdigit(); isxdigit() */
49
51
#include <stdio.h>         /* sprintf() */
 
52
#include <string.h>
50
53
using namespace std;
51
54
 
52
55
namespace Puma {
55
58
// print semantic error messages
56
59
 
57
60
#define SEM_MSG(node__,mesg__) \
58
 
  err << node__->token ()->location () << mesg__ << endMessage
 
61
  {if (node__->token ()) err << node__->token ()->location (); err << mesg__ << endMessage;}
59
62
  
60
63
#define SEM_ERROR(node__, mesg__) \
61
64
  SEM_MSG (node__, sev_error << mesg__)
175
178
  if (id == CT_SimpleName::NodeId ()) {
176
179
    info = ((CT_SimpleName*)expr)->Name ()->Object ();
177
180
    if (info)
178
 
      return (type->isFunction () || info->AttributeInfo () ||
179
 
              info->ArgumentInfo ());
 
181
      return (type->isFunction () || info->ArgumentInfo () ||
 
182
              info->AttributeInfo ());
180
183
    return false;
181
184
  } 
182
185
  if (id == CT_BracedExpr::NodeId ())
376
379
  if (result->is_char () || result->is_short () || 
377
380
      result->is_signed_char () || result->is_unsigned_char () || 
378
381
      result->is_unsigned_short () || result->is_wchar_t () || 
379
 
      result->isEnum () || result->is_bool ()) {
 
382
      result->is_bool ()) {
380
383
    result = castToType (&CTYPE_INT, expr, base, true);
 
384
  } else if (result->isEnum ()) { 
 
385
    result = castToType (result->VirtualType ()->TypeEnum ()->UnderlyingType (), expr, base, true);
381
386
  } else if (result->TypeBitField ()) {
382
387
    if (result->BaseType ()->isEnum () ||
383
388
        (result->BaseType ()->isInteger () && 
447
452
  // resolve expression
448
453
  result = resolve (node, base);
449
454
  // apply lvalue-to-rvalue conversions
450
 
  if (base)
 
455
  if (result && result != &CTYPE_UNDEFINED && base)
451
456
    result = convLvalueToRvalue (node, base);
452
457
 
453
458
  return result;
483
488
 
484
489
  // call the node type specific resolve function
485
490
  if (!(result = node->resolve (*this, base))) {
486
 
    cout << "NodeName: " << node->NodeName () << endl;
487
491
    SEM_ERROR (node, "expression expected");
488
492
    result = &CTYPE_UNDEFINED;
489
493
    if (node->SemValue ())
677
681
    }
678
682
 
679
683
    t1 = node->Son (0)->Type ();
680
 
    if (! (t1->isPointer () && t1->VirtualType ()->BaseType ()->isRecord ())) 
 
684
    if (! (t1->isPointer () && t1->VirtualType ()->BaseType ()->isRecord ())) { 
681
685
      SEM_ERROR__left_op (node, op, "not pointer to class object");
682
 
    else {
 
686
    } else {
683
687
      obj_type = t1->VirtualType ()->BaseType ();
684
688
      t2 = obj_type->VirtualType ();
685
689
    }
686
690
  // op1 . op2
687
691
  } else {
688
 
    if (! t1->isRecord ()) 
 
692
    if (! t1->isRecord ()) {
689
693
      SEM_ERROR__left_op (node, op, "not a class object");
690
 
    else {
 
694
    } else {
691
695
      obj_type = t1;
692
696
      t2 = t1->VirtualType ();
693
697
    }
696
700
  // get the class info 
697
701
  if (t2) {
698
702
    pos = node->Son (1)->token_node ()->Number ();
699
 
    if (! t2->isComplete (pos))
 
703
    if (! t2->isComplete (pos)) {
700
704
      SEM_ERROR__left_op (node, op, "not a complete object type");
701
 
    else
 
705
    } else {
702
706
      sinfo = t2->TypeRecord ()->Record ();
 
707
    }
703
708
  }
704
709
  
705
710
  // lookup the class member
743
748
      } else if (checkDeclsFound (node, nl)) {
744
749
        // possibly overloaded function; resolve it
745
750
        if (nl.Object (0)->FunctionInfo ()) {
746
 
          if (! fct_call_args)
 
751
          if (! fct_call_args) {
747
752
            SEM_WARNING (node, "cannot resolve possibly overloaded function");
748
 
          else if (dep_args) 
 
753
          } else if (dep_args) {
749
754
            dependent = true;
750
 
          else {
 
755
          } else {
751
756
            CCOverloading ovl (err);
752
757
            ovl.ObjectType (obj_type); 
753
758
            ovl.addCandidates (nl);
916
921
      // collect scopes associated with the function call arguments
917
922
      CCAssocScopes scopes (fct_call->Arguments ());
918
923
      
919
 
      if (! scopes.Namespaces ())
 
924
      if (! scopes.Namespaces ()) {
920
925
        SEM_ERROR__undeclared (node);
921
 
      else {
 
926
      } else {
922
927
        arg_dep_lookup = true;
923
928
        
924
929
        // lookup name in associated namespaces as if 
927
932
          nl.lookupInAssNs (node, scopes.Namespace (i));
928
933
        
929
934
        // name is definitely not known here
930
 
        if (! nl.Objects ())
 
935
        if (! nl.Objects ()) {
931
936
          SEM_ERROR__undeclared (node);
932
 
        else {
 
937
        } else {
933
938
          if (nl.Objects () == 1 && ! nl.Object (0)->FunctionInfo ())
934
939
            nl.reset ();
935
940
          else
1147
1152
    result = binary_ass (node, base);
1148
1153
 
1149
1154
  node->setTypeRef (result);
 
1155
  
 
1156
  // transform the expression into a call expression with a built-in operator
 
1157
  // as the target function
 
1158
  CTypeInfo *t1 = node->Son (0)->Type (); 
 
1159
  CTypeInfo *t2 = node->Son (2)->Type ();
 
1160
  builtinOpExpr (node, base, op, oper, result, t1, t2);
 
1161
  
1150
1162
  return result;
1151
1163
}
1152
1164
 
1166
1178
 
1167
1179
  // error diagnostics not yet complete!
1168
1180
 
1169
 
  if (! isLvalue (node->Son (0))) 
 
1181
  if (! isLvalue (node->Son (0))) {
1170
1182
    SEM_ERROR (node, "non-lvalue in assignment");
1171
 
  else {
 
1183
  } else {
1172
1184
    if (! isModifiable (t1, pos))
1173
1185
      SEM_WARNING (node, "assignment of unmodifiable location");
1174
1186
    if (! t1->isRecord ())
1186
1198
  
1187
1199
    v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0;
1188
1200
    if (v2) {
1189
 
      if ((oper == TOK_MOD_EQ || oper == TOK_DIV_EQ) && v2->isNull ())
1190
 
        SEM_ERROR (node, "division by zero");
1191
 
      else if ((oper == TOK_RSH_EQ || oper == TOK_LSH_EQ) && v2->isNegative ())
 
1201
      if ((oper == TOK_MOD_EQ || oper == TOK_DIV_EQ) && v2->isNull ()) {
 
1202
        SEM_WARNING (node, "division by zero");
 
1203
      } else if ((oper == TOK_RSH_EQ || oper == TOK_LSH_EQ) && v2->isNegative ()) {
1192
1204
        SEM_WARNING (node, "negative shift count");
 
1205
      }
1193
1206
    }
1194
1207
  }
1195
1208
  
1217
1230
 
1218
1231
  // error diagnostics not yet complete!
1219
1232
 
1220
 
  if (! (t1->isScalar () && t2->isScalar ()))
 
1233
  if (! (t1->isScalar () && t2->isScalar ())) {
1221
1234
    SEM_ERROR__invalid_op (node, "binary", op);
1222
 
  else {
 
1235
  } else {
1223
1236
    if (! t1->VirtualType ()->is_bool ())
1224
1237
      castToType (&CTYPE_BOOL, node->Son (0), node, true);
1225
1238
    if (! t2->VirtualType ()->is_bool ())
1248
1261
 
1249
1262
  // error diagnostics not yet complete!
1250
1263
 
1251
 
  if (! (t1->isInteger () && t2->isInteger ()))
 
1264
  if (! (t1->isInteger () && t2->isInteger ())) {
1252
1265
    SEM_ERROR__invalid_op (node, "binary", op);
1253
 
  else {
 
1266
  } else {
1254
1267
    // apply usual arithmetic conversions
1255
1268
    result = usualArithmeticConv (node->Son (0), node->Son (2), node);
1256
1269
    apply_binary_op (node, oper);
1330
1343
 
1331
1344
  // error diagnostics not yet complete!
1332
1345
 
1333
 
  if (! (t1->isInteger () && t2->isInteger ()))
 
1346
  if (! (t1->isInteger () && t2->isInteger ())) {
1334
1347
    SEM_ERROR__invalid_op (node, "binary", op);
1335
 
  else {
 
1348
  } else {
1336
1349
    // apply integral promotions on both operands
1337
1350
    t1 = intPromotion (node->Son (0), node); 
1338
1351
    t2 = intPromotion (node->Son (2), node);
1366
1379
    result = usualArithmeticConv (node->Son (0), node->Son (2), node);
1367
1380
  } else if (oper == TOK_PLUS) {
1368
1381
    if (! (t1->isArithmetic () && t2->isPointer ()) &&
1369
 
        ! (t2->isArithmetic () && t1->isPointer ()))
 
1382
        ! (t2->isArithmetic () && t1->isPointer ())) {
1370
1383
      SEM_ERROR__invalid_op (node, "binary", "+");
1371
 
    else
 
1384
    } else {
1372
1385
      result = t1->isPointer () ? t1 : t2;
 
1386
    }
1373
1387
  } else { // oper == TOK_MINUS
1374
1388
    if (! (t1->isPointer () && t2->isInteger ()) &&
1375
 
        ! (t1->isPointer () && t2->isPointer () && sameUnqualBaseType (t1, t2))) 
 
1389
        ! (t1->isPointer () && t2->isPointer () && sameUnqualBaseType (t1, t2))) {
1376
1390
      SEM_ERROR__invalid_op (node, "binary", "-");
1377
 
    else                        /* ptrdiff_t */
 
1391
    } else {                       /* ptrdiff_t */
1378
1392
      result = t2->isPointer () ? CTypeInfo::CTYPE_PTRDIFF_T : t1;
 
1393
    }
1379
1394
  }
1380
1395
  
1381
1396
  apply_binary_op (node, oper);
1407
1422
 
1408
1423
    v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0;
1409
1424
    if ((oper == TOK_MODULO || oper == TOK_DIV) && v2 && v2->isNull ()) 
1410
 
      SEM_ERROR (node, "division by zero");
1411
 
    else
1412
 
      apply_binary_op (node, oper);
 
1425
      SEM_WARNING (node, "division by zero");
 
1426
    apply_binary_op (node, oper);
1413
1427
  }
1414
1428
  
1415
1429
  return result;
1434
1448
 
1435
1449
  // error diagnostics not yet complete!
1436
1450
 
1437
 
  if (! t2->TypeMemberPointer ())
 
1451
  if (! t2->TypeMemberPointer ()) {
1438
1452
    SEM_ERROR__right_op (node, op, "not pointer to member");
1439
 
  else if (oper == TOK_DOT_STAR && ! t1->isRecord ())
 
1453
  } else if (oper == TOK_DOT_STAR && ! t1->isRecord ()) {
1440
1454
    SEM_ERROR__left_op (node, op, "not of class type");
1441
 
  else if (oper == TOK_PTS_STAR && ! (t1->isPointer () && 
1442
 
            t1->VirtualType ()->BaseType ()->isRecord ()))
 
1455
  } else if (oper == TOK_PTS_STAR && ! (t1->isPointer () && 
 
1456
            t1->VirtualType ()->BaseType ()->isRecord ())) {
1443
1457
    SEM_ERROR__left_op (node, op, "not pointer to class type");
1444
 
  else {
 
1458
  } else {
1445
1459
    pclass = t2->TypeMemberPointer ()->Record ();
1446
1460
    if (oper == TOK_DOT_STAR)
1447
1461
      oclass = t1->VirtualType ()->TypeRecord ()->Record ();
1509
1523
 
1510
1524
  // prefix in-/decrement: ++ op1; -- op1
1511
1525
  if (oper == TOK_DECR || oper == TOK_INCR) {
1512
 
    if (! isLvalue (node->Son (1))) 
 
1526
    if (! isLvalue (node->Son (1))) { 
1513
1527
      SEM_ERROR (node, "non-lvalue in prefix increment/decrement");
1514
 
    else {
1515
 
      if (! isModifiable (t1, pos))
1516
 
        if (oper == TOK_DECR)
 
1528
    } else {
 
1529
      if (! isModifiable (t1, pos)) {
 
1530
        if (oper == TOK_DECR) {
1517
1531
          SEM_WARNING (node, "decrement of unmodifiable location");
1518
 
        else
 
1532
        } else {
1519
1533
          SEM_WARNING (node, "increment of unmodifiable location");
 
1534
        }
 
1535
      }
1520
1536
      if (! t1->isScalar () ||
1521
 
          (oper == TOK_DECR && t1->VirtualType ()->is_bool ()))
 
1537
          (oper == TOK_DECR && t1->VirtualType ()->is_bool ())) {
1522
1538
        SEM_ERROR__invalid_op (node, "unary", op);
 
1539
      }
1523
1540
    }
1524
1541
    result = t1->UnqualType ();
1525
1542
  // + op1; - op1; ~ op1
1532
1549
      v1 = node->Son (1)->Value () ? node->Son (1)->Value ()->Constant () : 0;
1533
1550
      if (v1 && ! t1->isPointer ()) 
1534
1551
        node->setValue (v1->compute (oper));
1535
 
    } else
 
1552
    } else {
1536
1553
      SEM_ERROR__invalid_op (node, "unary", op);
 
1554
    }
1537
1555
    result = t1;
1538
1556
  // ! op1
1539
1557
  } else if (oper == TOK_NOT) {
1540
 
    if (! t1->isScalar ())
 
1558
    if (! t1->isScalar ()) {
1541
1559
      SEM_ERROR__invalid_op (node, "unary", op);
1542
 
    else {
 
1560
    } else {
1543
1561
      if (! t1->VirtualType ()->is_bool ())
1544
1562
        t1 = castToType (&CTYPE_BOOL, node->Son (1), node, true);
1545
1563
      v1 = node->Son (1)->Value () ? node->Son (1)->Value ()->Constant () : 0;
1550
1568
  }
1551
1569
 
1552
1570
  node->setTypeRef (result);
 
1571
  
 
1572
  // transform the expression into a call expression with a built-in operator
 
1573
  // as the target function
 
1574
  t1 = node->Son (1)->Type (); 
 
1575
  builtinOpExpr (node, base, op, oper, result, t1);
 
1576
  
1553
1577
  return result;
1554
1578
}
1555
1579
 
1589
1613
    dep_base = resetDependent ();
1590
1614
    overloaded = overloadedOperator (node, base, op, oper, node->Son (0), second);
1591
1615
    delete second;
 
1616
    // restore parent pointer
 
1617
    node->ReplaceSon (node->Son (1), node->Son (1));
1592
1618
    if (isDependent (node, dep_base))
1593
1619
      return &CTYPE_UNDEFINED;
1594
1620
    else if (overloaded)
1598
1624
  }
1599
1625
  
1600
1626
  // postfix in-/decrement: op1 ++; op1 --
1601
 
  if (! isLvalue (node->Son (0))) 
 
1627
  if (! isLvalue (node->Son (0))) { 
1602
1628
    SEM_ERROR (node, "non-lvalue in postfix increment/decrement");
1603
 
  else {
1604
 
    if (! isModifiable (t1, pos))
1605
 
      if (oper == TOK_DECR)
 
1629
  } else {
 
1630
    if (! isModifiable (t1, pos)) {
 
1631
      if (oper == TOK_DECR) {
1606
1632
        SEM_WARNING (node, "decrement of unmodifiable location");
1607
 
      else
 
1633
      } else {
1608
1634
        SEM_WARNING (node, "increment of unmodifiable location");
 
1635
      }
 
1636
    }
1609
1637
    if (! t1->isScalar () ||
1610
 
        (oper == TOK_DECR && t1->VirtualType ()->is_bool ()))
 
1638
        (oper == TOK_DECR && t1->VirtualType ()->is_bool ())) {
1611
1639
      SEM_ERROR__invalid_op (node, "unary", op);
 
1640
    }
1612
1641
  }
1613
1642
 
1614
1643
  result = t1->UnqualType ();
1615
1644
  node->setTypeRef (result);
 
1645
 
 
1646
  // transform the expression into a call expression with a built-in operator
 
1647
  // as the target function
 
1648
  builtinOpExpr (node, base, op, oper, result, t1);
 
1649
 
1616
1650
  return result;
1617
1651
}
1618
1652
 
1900
1934
 
1901
1935
  // error diagnostics not yet complete!
1902
1936
 
 
1937
  bool error = true;
1903
1938
  if (! t1->isPointer ()) {
1904
1939
    SEM_ERROR__invalid_op (node, "unary", "*");
1905
1940
    result = &CTYPE_UNDEFINED;
1906
1941
  } else {
1907
 
    if (t1->VirtualType ()->BaseType ()->isVoid ())
 
1942
    if (t1->VirtualType ()->BaseType ()->isVoid ()) {
1908
1943
      SEM_ERROR (node, "dereferencing pointer to void");
1909
 
    result = t1->VirtualType ()->BaseType ();
 
1944
      result = &CTYPE_UNDEFINED;
 
1945
    }
 
1946
    else
 
1947
      error = false;
1910
1948
  }
1911
1949
 
1912
 
  node->setTypeRef (result);
 
1950
  if (error)
 
1951
    node->setTypeRef (result);
 
1952
  else {
 
1953
    result = new CTypeAddress (t1->VirtualType ()->BaseType ()->Duplicate ());
 
1954
    node->setType (result);
 
1955
    // transform the expression into a call expression with a built-in operator
 
1956
    // as the target function
 
1957
    t1 = node->Son (1)->Type (); 
 
1958
    builtinOpExpr (node, base, "*", node->token ()->type (), result, t1);
 
1959
  }
1913
1960
  return result;
1914
1961
}
1915
1962
 
1947
1994
  // error diagnostics not yet complete!
1948
1995
 
1949
1996
  // address of class member
 
1997
  bool error = false;
1950
1998
  if ((op1->NodeName () == CT_QualName::NodeId () ||
1951
1999
       op1->NodeName () == CT_RootQualName::NodeId ()) &&
1952
2000
      (info = ((CT_QualName*)op1)->Name ()->Object ()) &&
1971
2019
    SEM_ERROR__invalid_op (node, "unary", "&");
1972
2020
    result = &CTYPE_UNDEFINED;
1973
2021
    node->setTypeRef (result);
 
2022
    error = true;
 
2023
  }
 
2024
 
 
2025
  if (!error) {
 
2026
    // transform the expression into a call expression with a built-in operator
 
2027
    // as the target function
 
2028
    builtinOpExpr (node, base, "&", node->token ()->type (), result, t1);
1974
2029
  }
1975
2030
 
1976
2031
  return result;
2284
2339
  // evaluation not yet complete!
2285
2340
  
2286
2341
  // sizeof op1; sizeof ( op1 )
2287
 
  if (t1->isFunction ()/* || ! t1->isComplete (pos)*/) 
 
2342
  if (t1->isFunction ()/* || ! t1->isComplete (pos)*/) {
2288
2343
    SEM_ERROR__invalid_op (node, "unary", "sizeof");
2289
 
  else
 
2344
  } else
2290
2345
    size = t1->Size (); // size in bits
2291
2346
 
2292
2347
  // NOT CORRECT! TO BE FIXED!
2332
2387
  }
2333
2388
    
2334
2389
  // subscripting: op1 [ op2 ]
 
2390
  bool error = true;
2335
2391
  if (! t1->isPointer () || ! t2->isInteger ()) {
2336
2392
    SEM_ERROR__invalid_op (node, "array subscript", "[]");
2337
2393
    result = &CTYPE_UNDEFINED;
2338
2394
  } else 
2339
 
    result = t1->VirtualType ()->BaseType ();
 
2395
    error = false;
2340
2396
 
2341
 
  node->setTypeRef (result);
 
2397
  if (error)
 
2398
    node->setTypeRef (result);
 
2399
  else {
 
2400
    result = new CTypeAddress (t1->VirtualType ()->BaseType ()->Duplicate ());
 
2401
    node->setType (result);
 
2402
    // transform the expression into a call expression with a built-in operator
 
2403
    // as the target function
 
2404
    t1 = node->Son (1)->Type (); 
 
2405
    builtinOpExpr (node, base, "[]", oper, result, t1, t2);
 
2406
  }
2342
2407
  return result;
2343
2408
}
2344
2409
 
2390
2455
    result = &CTYPE_CHAR;
2391
2456
    v = (char)v;
2392
2457
  } else {                         // integer character constant
2393
 
    if (chars > 4)
 
2458
    if (chars > 4) {
2394
2459
      SEM_ERROR (node, "integer character constant too long");
2395
 
    else
 
2460
    } else {
2396
2461
      SEM_WARNING (node, "multi-character character constant");
 
2462
    }
2397
2463
    result = &CTYPE_INT; 
2398
2464
    v = (int)v;
2399
2465
  }
2415
2481
    result = &CTYPE_WCHAR_T;
2416
2482
    v = (wchar_t)v;
2417
2483
  } else {
2418
 
    if (chars > 4)
 
2484
    if (chars > 4) {
2419
2485
      SEM_ERROR (node, "integer character constant too long");
2420
 
    else 
 
2486
    } else {
2421
2487
      SEM_WARNING (node, "multi-character character constant");
 
2488
    }
2422
2489
    result = &CTYPE_INT;
2423
2490
    v = (int)v;
2424
2491
  }
2757
2824
  CTypeInfo *t0, *t1 = 0, *type = 0;
2758
2825
  CCandidateInfo *cand;
2759
2826
  CFunctionInfo *finfo;
2760
 
  CT_CallExpr *call;
2761
2827
  CRecord *cinfo;
2762
2828
  char opname[1000]; // enough space for every possible operator name
2763
2829
 
2823
2889
          if (t0->isEnum ()) {
2824
2890
            type = finfo->Argument ((unsigned)0)->TypeInfo ();
2825
2891
            if (*type->VirtualType () == *t0->VirtualType ())
2826
 
              ovl.addCandidate (new CCandidateInfo (finfo));
 
2892
              ovl.addCandidate (finfo);
2827
2893
          } else if (t1 && t1->isEnum () && finfo->Arguments () > 1) {
2828
2894
            type = finfo->Argument ((unsigned)1)->TypeInfo ();
2829
2895
            if (*type->VirtualType () == *t1->VirtualType ())
2830
 
              ovl.addCandidate (new CCandidateInfo (finfo));
 
2896
              ovl.addCandidate (finfo);
2831
2897
          }
2832
2898
        }
2833
2899
      }
2836
2902
  }
2837
2903
 
2838
2904
  // create and add built-in candidates
2839
 
  ovl.createBuiltinOperators (opname, oper, arg0, arg1);
 
2905
  CClassDatabase *db = current_scope->ClassDB ();
 
2906
  ovl.createBuiltinOperators (db, opname, oper, arg0, arg1);
2840
2907
 
2841
2908
  // let overload resolution know the qualification
2842
2909
  // of the object the operator is called on
2864
2931
      // if not resolved to a built-in operator, transform
2865
2932
      // the expression into a call-expression
2866
2933
      if (! finfo->isBuiltin ()) {
2867
 
        if (base) {
2868
 
          call = new CT_CallExpr (node);
 
2934
        CT_Call *call = node->IsCall ();
 
2935
        if (call)
2869
2936
          call->Object (finfo);
2870
 
          call->setTypeRef (type);
2871
 
          base->ReplaceSon (node, call);
2872
 
        }
2873
2937
        if (node->SemValue ())
2874
2938
          node->SemValue ()->setTypeRef (/*finfo->TypeInfo ()*/type);
2875
2939
        return type;
3145
3209
// check result of function overload resolution
3146
3210
bool CCSemExpr::validOvlFctSet (CTree *node, const char *what, 
3147
3211
 const char *name, CCOverloading &ovl) {
 
3212
  CTemplateInstance *inst;
3148
3213
  CObjectInfo *info;
3149
3214
  CTree *arg;
3150
3215
 
3161
3226
      if (i+1 < ovl.Arguments ())
3162
3227
        fname << ",";
3163
3228
    }
3164
 
    fname << ")" << std::ends;
 
3229
    fname << ")";
3165
3230
    
3166
3231
    SEM_ERROR (node, "call to " << what << " `" << fname.str ().c_str () << "' is ambiguous");
3167
3232
 
3168
3233
    for (unsigned i = 0; i < ovl.Candidates (); i++) {
3169
3234
      info = ovl.Candidate (i)->Function ();
 
3235
      inst = info->TemplateInstance ();
 
3236
      if (inst) {
 
3237
        info = inst->Template ()->ObjectInfo ();
 
3238
      }
3170
3239
      if (info->Tree () && info->Tree ()->token ())
3171
3240
        err << info->Tree ()->token ()->location ();
3172
3241
      if (i == 0)
3173
 
        err << "candidates are ";
 
3242
        err << "candidates are: ";
3174
3243
      else
3175
 
        err << "               ";
 
3244
        err << "                ";
3176
3245
      std::ostringstream sig;
3177
3246
      info->TypeInfo ()->TypeText (sig, info->Name ());
3178
 
      sig << std::ends;
3179
 
      err << "`" << sig.str ().c_str () << "'" << endMessage;
 
3247
      if (inst) {
 
3248
        sig << " [with ";
 
3249
        for (unsigned j = 0; j < inst->DeducedArgs (); j++) {
 
3250
          DeducedArgument *darg = inst->DeducedArg (j);
 
3251
          if (j != 0) 
 
3252
            sig << ", ";
 
3253
          if (darg->Type ()) 
 
3254
            darg->TemplateParam ()->TypeInfo ()->TypeText (sig);
 
3255
          else 
 
3256
            darg->TemplateParam ()->TypeInfo ()->TypeText (sig, darg->TemplateParam ()->Name ());
 
3257
          sig << " = ";
 
3258
          if (darg->Type ())
 
3259
            darg->Type ()->TypeText (sig);
 
3260
          else if (arg->Value ())
 
3261
            darg->Value ()->print (sig);
 
3262
        }
 
3263
        sig << "]";
 
3264
      } 
 
3265
      err << sig.str ().c_str () << endMessage;
3180
3266
    }
3181
3267
    return false;
3182
3268
  // no matching function 
3285
3371
}
3286
3372
 
3287
3373
 
 
3374
// transform the expression into a call expression with a built-in operator
 
3375
// as the target function
 
3376
void CCSemExpr::builtinOpExpr (CTree *node, CTree *base,
 
3377
  const char *op, int oper, CTypeInfo *result,
 
3378
  CTypeInfo *t1, CTypeInfo *t2) const {
 
3379
  CT_Call *call = node->IsCall ();
 
3380
  if (!call) {
 
3381
    cout << node->NodeName ()
 
3382
         << " is no CT_Call node, but builtin operator!" << endl;
 
3383
  }
 
3384
  else if (result == &CTYPE_UNDEFINED || t1 == &CTYPE_UNDEFINED ||
 
3385
    t2 == &CTYPE_UNDEFINED) {
 
3386
    cout << "undefined type: " << node->token ()->location () << endl;
 
3387
  }
 
3388
  else {
 
3389
    char name[1000];
 
3390
    sprintf (name, "operator %s", op);
 
3391
    CFunctionInfo *fi = current_scope->ClassDB ()->BuiltinOperator (name, oper,
 
3392
      result->Duplicate (), t1->Duplicate (), t2 ? t2->Duplicate () : 0);
 
3393
    call->Object (fi);
 
3394
  }
 
3395
}
 
3396
 
3288
3397
} // namespace Puma