40
40
#include "Puma/CSemVisitor.h"
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() */
48
48
using namespace std;
108
108
CTypeInfo *result = expr->Type ();
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
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);
518
520
node->setTypeRef (&CTYPE_UNDEFINED);
519
521
return &CTYPE_UNDEFINED;
543
545
CTypeInfo *CSemExpr::resolve (CT_BracedExpr *node, CTree *base) {
544
return resolveExpr (node->Expr (), node);
546
CTypeInfo* result = resolveExpr (node->Expr (), node);
549
passOnConstant (node->Expr (), node, result);
551
node->setTypeRef (result);
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));
811
819
return &CTYPE_INT;
1146
1154
CTypeInfo *CSemExpr::resolve (CT_SizeofExpr *node, CTree *base) {
1147
1155
CTypeInfo *result, *t1;
1149
1156
CObjectInfo *info;
1150
1157
U_LONG_LONG size;
1152
result = &CTYPE_UNDEFINED;
1153
pos = node->token_node ()->Number ();
1159
result = CTypeInfo::CTYPE_SIZE_T; // size_t
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;
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 ());
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");
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));
1183
1188
///////////////////////////////////////////////////////
1189
// alignof expression //////////////////////////////////
1190
///////////////////////////////////////////////////////
1194
CTypeInfo *CSemExpr::resolve (CT_AlignofExpr *node, CTree *base) {
1195
CTypeInfo *result, *t1;
1199
result = CTypeInfo::CTYPE_SIZE_T; // size_t
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;
1206
// do not convert array/function type to pointer type
1208
t1 = resolveExpr (node->Expr (), node);
1209
//info = findObject (node->Expr ());
1212
// alignof op1; alignof ( op1 )
1214
SEM_ERROR__invalid_op (node, "unary", "alignof");
1216
align = t1->Align (); // alignment in bytes
1218
node->setValue (new CConstant (align, result));
1222
node->setTypeRef (result);
1228
///////////////////////////////////////////////////////
1229
// offsetof expression ////////////////////////////////
1230
///////////////////////////////////////////////////////
1234
CTypeInfo *CSemExpr::resolve (CT_OffsetofExpr *node, CTree *base) {
1238
// TODO: calculate the offset in bytes of the given member
1240
result = CTypeInfo::CTYPE_SIZE_T; // size_t
1242
node->setValue (new CConstant (offset, result));
1243
node->setTypeRef (result);
1249
///////////////////////////////////////////////////////
1184
1250
// if-then expression /////////////////////////////////
1185
1251
///////////////////////////////////////////////////////
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 ());
1311
} else if (t2->PtrToFct () && t3->PtrToFct ()) {
1312
result = t2->PtrToFct ()->ArgTypes ()->Entries () ? t2 : t3;
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);
1258
1327
SEM_ERROR__invalid_op (node, "conditional", "?:");
1300
1369
if (! (t1 && ((t1->isScalar () && t2->isScalar ()) || t1->isVoid ()))) {
1301
1370
SEM_ERROR (node, "invalid cast");
1304
// cast constant value if any
1305
value = node->Expr ()->Value ();
1307
if (value->Constant ()) {
1308
value = value->Constant ()->cast_to (t1);
1309
node->setValue (value);
1311
node->setValueRef (value);
1372
// cast constant value if any
1373
value = node->Expr ()->Value ();
1375
if (value->Constant () && *t1 != *t2) {
1376
value = value->Constant ()->cast_to (t1);
1377
node->setValue (value);
1379
node->setValueRef (value);
1439
1506
conv_to_ptr = ctp_old;
1441
1508
// function call: op1 ( op2 , .. )
1442
if (! (t1->isPointer () && t1->VirtualType ()->BaseType ()->isFunction ())) {
1443
SEM_ERROR (node, "called object is not a function");
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 ();
1577
} else if (t1->is_undefined ()) {
1578
// object not resolved, so it is an implicitely
1579
// declared function; the return type defaults
1581
result = &CTYPE_INT;
1583
// object could be resolved but is not a function,
1584
SEM_ERROR (node, "called object is not a function");
1514
1587
node->setTypeRef (result);
1987
2060
if (! isLvalue (ae->Expr ()))
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 () ||
2054
2130
// other pointer types are compatible to pointer to void
2055
if (t1->BaseType ()->isVoid ()) {
2131
if (t1->BaseType ()->isVoid () || t2->BaseType ()->isVoid ()) {
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);
2071
2147
if (*t1 == *t2) {
2072
2148
// types are equal
2187
void CSemExpr::passOnConstant (CTree *node, CTree *base, CTypeInfo *t1) {
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);
2198
base->SemValue ()->setValueRef (value);
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 () ||