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

« back to all changes in this revision

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

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#include "Puma/CSemVisitor.h"
41
41
 
42
42
#include <climits>
43
 
#include <sstream>         /* istringstream */
44
43
#include "Puma/WChar.h"    /* wcslen() */
45
 
#include <ctype.h>         /* isdigit(); isxdigit() */
 
44
#include <ctype.h>         /* isdigit(), isxdigit() */
46
45
#include <string.h>
 
46
#include <stdlib.h>        /* strtod() */
47
47
 
48
48
using namespace std;
49
49
 
108
108
  CTypeInfo *result = expr->Type ();
109
109
 
110
110
  // ensure not to evaluate twice
111
 
  if (! result || result == &CTYPE_UNDEFINED || 
 
111
  if (! result || *result == CTYPE_UNDEFINED || 
112
112
     expr->IsSimpleName () ||
113
113
     expr->NodeName () == CT_BracedExpr::NodeId ()) {
114
114
    // call the node type specific resolve function
148
148
  U_LONG_LONG v;
149
149
  
150
150
  v = (strcmp (node->token ()->text (), "true") == 0) ? 1 : 0;
151
 
  result = &CTYPE_BOOL;
 
151
  result = &CTYPE_C_BOOL;
152
152
 
153
153
  node->setValue (new CConstant (v, result));
154
154
  node->setTypeRef (result);
483
483
  lng = (s[ln-1] == 'l' || s[ln-1] == 'L');
484
484
  flt = (s[ln-1] == 'f' || s[ln-1] == 'F');
485
485
 
486
 
  std::istringstream iss (s);
487
 
  iss >> v;
 
486
  v = strtod(s, NULL);
488
487
 
489
488
  if (lng) 
490
489
    result = &CTYPE_LONG_DOUBLE;
514
513
  // find semantic object to name
515
514
  info = lookup (node, NON_TAG, true);
516
515
  if (! info || info->TypedefInfo ()) {
517
 
    SEM_ERROR__undeclared (node);
 
516
    // typedef name or not a implicitely declared function
 
517
    if (info || base->NodeName () != CT_CallExpr::NodeId ()) {
 
518
      SEM_ERROR__undeclared (node);
 
519
    }
518
520
    node->setTypeRef (&CTYPE_UNDEFINED);
519
521
    return &CTYPE_UNDEFINED;
520
522
  }
541
543
 
542
544
 
543
545
CTypeInfo *CSemExpr::resolve (CT_BracedExpr *node, CTree *base) {
544
 
  return resolveExpr (node->Expr (), node);
 
546
  CTypeInfo* result = resolveExpr (node->Expr (), node);
 
547
 
 
548
  // handle constants
 
549
  passOnConstant (node->Expr (), node, result);
 
550
  
 
551
  node->setTypeRef (result);
 
552
  return result;
545
553
}
546
554
 
547
555
 
718
726
  if (t1->isArithmetic () && t2->isArithmetic ()) {
719
727
    t1 = apply_binary_op (node, oper);
720
728
    v1 = node->Value () ? node->Value ()->Constant () : 0;
721
 
    if (v1 && t1 != &CTYPE_INT) // must have type `int'
 
729
    if (v1 && *t1 != CTYPE_INT) // must have type `int'
722
730
      node->setValue (v1->cast_to (&CTYPE_INT));
723
731
  } else if (! (t1->isPointer () && t2->isPointer () && 
724
732
                compatibleBase (t1, t2))) 
743
751
  if (t1->isArithmetic () && t2->isArithmetic ()) {
744
752
    t1 = apply_binary_op (node, oper);
745
753
    v1 = node->Value () ? node->Value ()->Constant () : 0;
746
 
    if (v1 && t1 != &CTYPE_INT) // must have type `int'
 
754
    if (v1 && *t1 != CTYPE_INT) // must have type `int'
747
755
      node->setValue (v1->cast_to (&CTYPE_INT));
748
756
  } else if ((t1->isInteger () && t2->isPointer ()) ||
749
757
             (t2->isInteger () && t1->isPointer ())) {
805
813
  } else if (t1->isArithmetic () && t2->isArithmetic ()) {
806
814
    t1 = apply_binary_op (node, oper);
807
815
    v1 = node->Value () ? node->Value ()->Constant () : 0;
808
 
    if (v1 && t1 != &CTYPE_INT) // must have type `int'
 
816
    if (v1 && *t1 != CTYPE_INT) // must have type `int'
809
817
      node->setValue (v1->cast_to (&CTYPE_INT)); 
810
818
  }
811
819
  return &CTYPE_INT;
974
982
    } else {
975
983
      if (v1) {
976
984
        node->setValue (v1->compute (oper));
977
 
        if (t1 != &CTYPE_INT) // must have type `int'
 
985
        if (*t1 != CTYPE_INT) // must have type `int'
978
986
          node->setValue (v1->cast_to (&CTYPE_INT)); 
979
987
      }
980
988
      result = &CTYPE_INT;
1145
1153
 
1146
1154
CTypeInfo *CSemExpr::resolve (CT_SizeofExpr *node, CTree *base) {
1147
1155
  CTypeInfo *result, *t1;
1148
 
  unsigned long pos;
1149
1156
  CObjectInfo *info;
1150
1157
  U_LONG_LONG size;
1151
 
  
1152
 
  result = &CTYPE_UNDEFINED;
1153
 
  pos = node->token_node ()->Number ();
1154
 
  
 
1158
 
 
1159
  result = CTypeInfo::CTYPE_SIZE_T; // size_t
 
1160
 
1155
1161
  // resolve operand; can be either expression or named type
1156
1162
  if (node->TypeName ()) { // named type
1157
1163
    info = node->TypeName ()->Object ();
1158
 
    t1 = info->TypeInfo ();
 
1164
    t1 = info ? info->TypeInfo () : 0;
1159
1165
  } else {
1160
1166
    // do not convert array/function type to pointer type
1161
1167
    conv_to_ptr = 0;
1162
 
    t1 = resolveExpr (node->Expr (), node); 
 
1168
    t1 = resolveExpr (node->Expr (), node);
1163
1169
    info = findObject (node->Expr ());
1164
1170
  }
1165
 
  
 
1171
 
1166
1172
  // sizeof op1; sizeof ( op1 )
1167
 
  if (t1->isFunction () || (info ? info->TypeInfo ()->TypeBitField () : false)) { 
 
1173
  if (! t1 || t1->isFunction () || (info && info->TypeInfo ()->TypeBitField ())) {
1168
1174
    SEM_ERROR__invalid_op (node, "unary", "sizeof");
1169
1175
  } else {
1170
 
    result = CTypeInfo::CTYPE_SIZE_T; // size_t
1171
1176
    size = t1->Size (); // size in bits
1172
1177
    if (size / 8) {
1173
1178
      node->setValue (new CConstant (size / 8, result));
1181
1186
 
1182
1187
 
1183
1188
///////////////////////////////////////////////////////
 
1189
// alignof expression //////////////////////////////////
 
1190
///////////////////////////////////////////////////////
 
1191
 
 
1192
 
 
1193
 
 
1194
CTypeInfo *CSemExpr::resolve (CT_AlignofExpr *node, CTree *base) {
 
1195
  CTypeInfo *result, *t1;
 
1196
  CObjectInfo *info;
 
1197
  U_LONG_LONG align;
 
1198
 
 
1199
  result = CTypeInfo::CTYPE_SIZE_T; // size_t
 
1200
 
 
1201
  // resolve operand; can be either expression or named type
 
1202
  if (node->TypeName ()) { // named type
 
1203
    info = node->TypeName ()->Object ();
 
1204
    t1 = info ? info->TypeInfo () : 0;
 
1205
  } else {
 
1206
    // do not convert array/function type to pointer type
 
1207
    conv_to_ptr = 0;
 
1208
    t1 = resolveExpr (node->Expr (), node);
 
1209
    //info = findObject (node->Expr ());
 
1210
  }
 
1211
 
 
1212
  // alignof op1; alignof ( op1 )
 
1213
  if (! t1) {
 
1214
    SEM_ERROR__invalid_op (node, "unary", "alignof");
 
1215
  } else {
 
1216
    align = t1->Align (); // alignment in bytes
 
1217
    if (align) {
 
1218
      node->setValue (new CConstant (align, result));
 
1219
    }
 
1220
  }
 
1221
 
 
1222
  node->setTypeRef (result);
 
1223
  return result;
 
1224
}
 
1225
 
 
1226
 
 
1227
 
 
1228
///////////////////////////////////////////////////////
 
1229
// offsetof expression ////////////////////////////////
 
1230
///////////////////////////////////////////////////////
 
1231
 
 
1232
 
 
1233
 
 
1234
CTypeInfo *CSemExpr::resolve (CT_OffsetofExpr *node, CTree *base) {
 
1235
  CTypeInfo *result;
 
1236
  U_LONG_LONG offset;
 
1237
  
 
1238
  // TODO: calculate the offset in bytes of the given member
 
1239
  offset = 0;
 
1240
  result = CTypeInfo::CTYPE_SIZE_T; // size_t
 
1241
  
 
1242
  node->setValue (new CConstant (offset, result));
 
1243
  node->setTypeRef (result);
 
1244
  return result;
 
1245
}
 
1246
 
 
1247
 
 
1248
 
 
1249
///////////////////////////////////////////////////////
1184
1250
// if-then expression /////////////////////////////////
1185
1251
///////////////////////////////////////////////////////
1186
1252
 
1236
1302
    if (! compatibleBase (t2, t3)) {
1237
1303
      SEM_ERROR__type_mismatch (node, "conditional expression");
1238
1304
    } else if (t2->isConst () != t3->isConst () ||
1239
 
             t2->isVolatile () != t3->isVolatile () ||
1240
 
             t2->isRestrict () != t3->isRestrict ())
 
1305
               t2->isVolatile () != t3->isVolatile () ||
 
1306
               t2->isRestrict () != t3->isRestrict ()) {
1241
1307
      result = new CTypeQualified (t2->VirtualType ()->BaseType ()->Duplicate (), 
1242
1308
        t2->isConst () || t3->isConst (),
1243
1309
        t2->isVolatile () || t3->isVolatile (),
1244
1310
        t2->isRestrict () || t3->isRestrict ());
1245
 
    else
 
1311
    } else if (t2->PtrToFct () && t3->PtrToFct ()) {
 
1312
      result = t2->PtrToFct ()->ArgTypes ()->Entries () ? t2 : t3;
 
1313
    } else {
1246
1314
      result = t2;
 
1315
    }
1247
1316
  } else if (t2->isArithmetic () && t3->isArithmetic ()) {
1248
1317
    // apply arithmetic conversions if needed
1249
1318
    if (*t2 > *t3) {
1250
 
      cast_to (t2, op3, node);
 
1319
      result = cast_to (t2, op3, node);
1251
1320
      op3 = node->Son (4);
1252
1321
    } else if (*t2 < *t3) {
1253
1322
      result = cast_to (t3, op2, node);
1254
1323
      op2 = node->Son (2);
1255
 
    }
1256
 
    result = t2;
 
1324
    } else
 
1325
      result = t2;
1257
1326
  } else
1258
1327
    SEM_ERROR__invalid_op (node, "conditional", "?:");
1259
1328
 
1269
1338
    }
1270
1339
  }
1271
1340
  
1272
 
  if (result == t2 || result == t3 || *result == CTYPE_UNDEFINED)
 
1341
  if (!result || result == t2 || result == t3 || *result == CTYPE_UNDEFINED)
1273
1342
    node->setTypeRef (result);
1274
1343
  else
1275
1344
    node->setType (result);
1300
1369
  if (! (t1 && ((t1->isScalar () && t2->isScalar ()) || t1->isVoid ()))) { 
1301
1370
    SEM_ERROR (node, "invalid cast");
1302
1371
  } else {
1303
 
    if (*t1 != *t2) {
1304
 
      // cast constant value if any
1305
 
      value = node->Expr ()->Value ();
1306
 
      if (value) {
1307
 
        if (value->Constant ()) {
1308
 
          value = value->Constant ()->cast_to (t1);
1309
 
          node->setValue (value);
1310
 
        } else
1311
 
          node->setValueRef (value);
1312
 
      }
 
1372
    // cast constant value if any
 
1373
    value = node->Expr ()->Value ();
 
1374
    if (value) {
 
1375
      if (value->Constant () && *t1 != *t2) {
 
1376
        value = value->Constant ()->cast_to (t1);
 
1377
        node->setValue (value);
 
1378
      } else
 
1379
        node->setValueRef (value);
1313
1380
    }
1314
1381
    result = t1;
1315
1382
  }
1439
1506
  conv_to_ptr = ctp_old;
1440
1507
  
1441
1508
  // function call: op1 ( op2 , .. )
1442
 
  if (! (t1->isPointer () && t1->VirtualType ()->BaseType ()->isFunction ())) {
1443
 
    SEM_ERROR (node, "called object is not a function");
1444
 
  } else {
 
1509
  if (t1->isPointer () && t1->VirtualType ()->BaseType ()->isFunction ()) {
1445
1510
    ftype = t1->VirtualType ()->BaseType ()->VirtualType ()->TypeFunction ();
1446
1511
    result = ftype->ReturnType ();
1447
1512
    ptypes = ftype->ArgTypes ();
1509
1574
        }
1510
1575
      }
1511
1576
    }
 
1577
  } else if (t1->is_undefined ()) {
 
1578
    // object not resolved, so it is an implicitely
 
1579
    // declared function; the return type defaults
 
1580
    // to int
 
1581
    result = &CTYPE_INT;
 
1582
  } else {
 
1583
    // object could be resolved but is not a function,
 
1584
    SEM_ERROR (node, "called object is not a function");
1512
1585
  }
1513
1586
 
1514
1587
  node->setTypeRef (result);
1987
2060
    if (! isLvalue (ae->Expr ()))
1988
2061
      return false;
1989
2062
    CObjectInfo *info = findObject (ae->Expr ());
1990
 
    return info && info->Storage () == CStorage::CLASS_STATIC;
 
2063
    return info && (info->Storage () == CStorage::CLASS_STATIC ||
 
2064
                    info->Storage () == CStorage::CLASS_THREAD);
1991
2065
  } else if (id == CT_SimpleName::NodeId ()) {
1992
2066
    CT_SimpleName *name = (CT_SimpleName*)node;
1993
2067
    return ((name->Object () && name->Object ()->EnumeratorInfo ()) ||
1994
2068
            (! integer && node->Type ()->isPointer () &&
1995
2069
             (node->Type ()->VirtualType ()->BaseType ()->isFunction () ||
1996
2070
              node->Type ()->VirtualType ()->BaseType ()->isArray ())));
1997
 
  } else if (id == CT_SizeofExpr::NodeId ()) {
 
2071
  } else if (id == CT_SizeofExpr::NodeId () ||
 
2072
             id == CT_AlignofExpr::NodeId () ||
 
2073
             id == CT_OffsetofExpr::NodeId ()) {
1998
2074
    return node->Value ();
1999
2075
  } else if (id == CT_Bool::NodeId () ||
2000
2076
             id == CT_Character::NodeId () ||
2052
2128
      return true;
2053
2129
    }
2054
2130
    // other pointer types are compatible to pointer to void
2055
 
    if (t1->BaseType ()->isVoid ()) {
 
2131
    if (t1->BaseType ()->isVoid () || t2->BaseType ()->isVoid ()) {
2056
2132
      return true;
2057
2133
    }
2058
2134
    // base types and qualifier have to be compatible
2064
2140
  if (t1->isFunction () && t2->isFunction ()) {
2065
2141
    // return type and parameter list have to be compatible
2066
2142
    // NO FUNCTION PARAMETER PROMOTION AT THE MOMENT
2067
 
    return compatibleBase (t1, t2) &&
2068
 
      t1->TypeFunction ()->ArgTypes ()->Entries () ==
2069
 
      t2->TypeFunction ()->ArgTypes ()->Entries ();
 
2143
    unsigned nargs1 = t1->TypeFunction ()->ArgTypes ()->Entries ();
 
2144
    unsigned nargs2 = t2->TypeFunction ()->ArgTypes ()->Entries ();
 
2145
    return compatibleBase (t1, t2) && (nargs1 == 0 || nargs2 == 0 || nargs1 == nargs2);
2070
2146
  }
2071
2147
  if (*t1 == *t2) {
2072
2148
    // types are equal
2108
2184
 
2109
2185
 
2110
2186
 
 
2187
void CSemExpr::passOnConstant (CTree *node, CTree *base, CTypeInfo *t1) {
 
2188
  CTypeInfo *t2;
 
2189
  CConstant *value;
 
2190
  
 
2191
  t2 = node->Type ();
 
2192
  value = node->Value () ? node->Value ()->Constant () : 0;
 
2193
  if (value && base->SemValue ()) {
 
2194
    if (t1 && t2 && *t1 != *t2) {
 
2195
      value = value->cast_to (t1);
 
2196
      base->SemValue ()->setValue (value);
 
2197
    } else
 
2198
      base->SemValue ()->setValueRef (value);
 
2199
  }
 
2200
}
 
2201
 
 
2202
 
 
2203
 
2111
2204
CTypeInfo *CSemExpr::cast_to (CTypeInfo *type, CTree *node, CTree *base, bool ref) {
2112
2205
  CT_ImplicitCast *cast;
2113
2206
  CExprValue *value;
2192
2285
//             id == CT_CastExpr::NodeId () ||
2193
2286
//             id == CT_IfThenExpr::NodeId () ||
2194
2287
//             id == CT_SizeofExpr::NodeId () ||
 
2288
//             id == CT_AlignofExpr::NodeId () ||
 
2289
//             id == CT_OffsetofExpr::NodeId () ||
2195
2290
//             id == CT_Integer::NodeId () ||
2196
2291
//             id == CT_Character::NodeId () ||
2197
2292
//             id == CT_WideCharacter::NodeId () ||