jitcraft/SemanticAnalysis.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jul 02 01:24:57 2012 -0700 (2012-07-02)
changeset 25 23e8b3d8e4e6
parent 23 8a31742781c1
child 28 a9665857cfd5
permissions -rw-r--r--
Scanning, parsing, and static analysis now report errors properly.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #include "SemanticAnalysis.h"
    19 #include "Types.h"
    20 #include "Zone.h"
    21 #include "TypeManager.h"
    22 #include "Scopes.h"
    23 
    24 using namespace jc;
    25 
    26 static inline bool
    27 IsPrimitiveType(Type *type, PrimitiveType primitive)
    28 {
    29     if (!type)
    30         return false;
    31 
    32     if (!type->isPrimitive())
    33         return false;
    34 
    35     return primitive == type->primitive();
    36 }
    37 
    38 static inline bool
    39 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
    40                         BoxedPrimitive *out)
    41 {
    42     switch (kind) {
    43       case TOK_PLUS:
    44         *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
    45         return true;
    46 
    47       case TOK_SHL:
    48         *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
    49         return true;
    50     }
    51 
    52     return true;
    53 }
    54 
    55 static bool
    56 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
    57 {
    58     switch (expression->kind()) {
    59       case AstNode::kBinaryExpression:
    60       {
    61         BoxedPrimitive left;
    62         BoxedPrimitive right;
    63         BinaryExpression *b = expression->toBinaryExpression();
    64         if (!EvaluateForConstant(b->left(), &left) ||
    65             !EvaluateForConstant(b->right(), &right))
    66         {
    67             return false;
    68         }
    69         return EvaluateBinaryOperation(b->token(), left, right, out);
    70       }
    71 
    72       case AstNode::kNameProxy:
    73       {
    74         NameProxy *proxy = expression->toNameProxy();
    75         if (proxy->binding()->kind() != BoundName::CONSTANT)
    76             return false;
    77 
    78         NamedConstant *c = proxy->binding()->toNamedConstant();
    79         if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
    80             return false;
    81 
    82         *out = c->value();
    83         return true;
    84       }
    85 
    86       case AstNode::kIntegerLiteral:
    87         *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
    88         return true;
    89 
    90       default:
    91         return false;
    92     }
    93 }
    94 
    95 SemanticAnalysis::SemanticAnalysis(CompileContext &cc, ParseTree *tree)
    96   : cc_(cc),
    97     tree_(tree),
    98     loopDepth_(0),
    99     scope_(NULL)
   100 {
   101 }
   102 
   103 bool
   104 SemanticAnalysis::analyze()
   105 {
   106     if (cc_.failures())
   107         return false;
   108 
   109     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   110         Statement *statement = tree_->statements()->at(i);
   111         if (statement->isFunctionStatement()) {
   112             FunctionStatement *funstmt = statement->toFunctionStatement();
   113             if (!preanalyze(funstmt))
   114                 return false;
   115         }
   116     }
   117 
   118     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   119         Statement *statement = tree_->statements()->at(i);
   120         statement->accept(this);
   121     }
   122 
   123     return !cc_.failures();
   124 }
   125 
   126 Type *
   127 SemanticAnalysis::visitAndApplyType(Expression *expression)
   128 {
   129     expression->accept(this);
   130     return expression->type();
   131 }
   132 
   133 Type *
   134 SemanticAnalysis::visitForLoad(Expression *expression)
   135 {
   136     // :TODO: use Local
   137     Type *type = visitAndApplyType(expression);
   138     if (!type)
   139         return NULL;
   140 
   141     if (type->isReference()) {
   142         expression->setType(type->contained());
   143     } else if (expression->isIndexExpression()) {
   144         if (type->isArray())
   145             expression->setType(type->contained());
   146     }
   147 
   148     return expression->type();
   149 }
   150 
   151 Type *
   152 SemanticAnalysis::visitForRef(Expression *expression)
   153 {
   154     expression->accept(this);
   155     return expression->type();
   156 }
   157 
   158 static inline const char *
   159 GetTypeName(Type *type)
   160 {
   161     if (type->isArray())
   162         return "array";
   163     if (type->isFunction())
   164         return "function";
   165     if (type->isReference())
   166         type = type->contained();
   167     if (type->tag())
   168         return type->tag();
   169     return "int";
   170 }
   171 
   172 void
   173 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Type *type)
   174 {
   175     const char *op = TokenNames[token];
   176     const char *name = GetTypeName(type);
   177 
   178     cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
   179 }
   180 
   181 void
   182 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Type *left, Type *right)
   183 {
   184     const char *op = TokenNames[token];
   185     const char *leftName = GetTypeName(left);
   186     const char *rightName = GetTypeName(right);
   187 
   188     cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
   189 }
   190 
   191 Type *
   192 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Type *left, Type *right)
   193 {
   194     if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
   195         (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
   196     {
   197         // If either side is a float, the other side must be a float or int.
   198         if (left->isFloat() || right->isFloat()) {
   199             Type *floatType = left->isFloat() ? left : right;
   200             Type *other = left->isFloat() ? right : left;
   201             if (other->isFloat() || (other->isInt32() && !other->tag()))
   202                 return other;
   203         }
   204     }
   205 
   206     if ((!left->isInt32() || left->tag()) ||
   207         (!right->isInt32() || right->tag()))
   208     {
   209         binaryTypeError(node, token, left, right);
   210         return NULL;
   211     }
   212 
   213     return left;
   214 }
   215 
   216 bool
   217 SemanticAnalysis::canTest(AstNode *node, Type *type)
   218 {
   219     if (type->isArray()) {
   220         cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
   221         return false;
   222     }
   223     return true;
   224 }
   225 
   226 Type *
   227 SemanticAnalysis::visitForLValue(Expression *expression)
   228 {
   229     if (expression->isIndexExpression()) {
   230         Type *type = visitAndApplyType(expression);
   231         if (!type)
   232             return NULL;
   233 
   234         return type->contained();
   235     }
   236 
   237     if (!expression->isNameProxy()) {
   238         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   239         return NULL;
   240     }
   241 
   242     NameProxy *proxy = expression->toNameProxy();
   243     if (!proxy->binding()->kind() == BoundName::VARIABLE) {
   244         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   245         return NULL;
   246     }
   247 
   248     Variable *var = proxy->binding()->toVariable();
   249     if (!var->type())
   250         return NULL;
   251 
   252     if  (var->type()->isReference())
   253         return var->type()->contained();
   254     return var->type();
   255 }
   256 
   257 void
   258 SemanticAnalysis::visit(NameProxy *name)
   259 {
   260     name->setType(name->binding()->type());
   261 }
   262 
   263 void
   264 SemanticAnalysis::visit(Assignment *node)
   265 {
   266     Type *exprType = visitForLoad(node->expression());
   267     if (!exprType)
   268         return ;
   269 
   270     // :TODO: use Local
   271     Type *type = visitForLValue(node->lvalue());
   272     if (!type)
   273         return;
   274 
   275     if (node->token() != TOK_ASSIGN) {
   276         if (!typeCheckBinary(node, node->token(), type, exprType))
   277             return;
   278     }
   279 
   280     if (!typeCheckAssignment(node, exprType, type, true))
   281         return;
   282 
   283     node->setType(type);
   284 }
   285 
   286 void
   287 SemanticAnalysis::visit(IncDecExpression *node)
   288 {
   289     // :TODO: use Local
   290     Type *type = visitForLValue(node->expression());
   291     if (!type)
   292         return;
   293 
   294     assert(!type->isReference());
   295 
   296     if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
   297         unaryTypeError(node, node->token(), type);
   298         return;
   299     }
   300 
   301     node->setType(type);
   302 }
   303 
   304 void
   305 SemanticAnalysis::visit(BinaryExpression *node)
   306 {
   307     // :TODO: use Local
   308     Type *left = visitForLoad(node->left());
   309     Type *right = visitForLoad(node->right());
   310     if (!left || !right)
   311         return;
   312 
   313     Type *result = typeCheckBinary(node, node->token(), left, right);
   314     if (!result)
   315         return;
   316 
   317     node->setType(result);
   318 }
   319 
   320 void
   321 SemanticAnalysis::visit(ReturnStatement *node)
   322 {
   323     Type *type = visitForLoad(node->expression());
   324     if (!type)
   325         return;
   326 
   327     if (!typeCheckAssignment(node, type, function_->returnType(), true))
   328         return;
   329 }
   330 
   331 void
   332 SemanticAnalysis::visit(ForStatement *node)
   333 {
   334     loopDepth_++;
   335     if (node->scope())
   336         scope_ = node->scope();
   337 
   338     if (node->initialization())
   339         node->initialization()->accept(this);
   340 
   341     if (node->condition()) {
   342         Type *type = visitForLoad(node->condition());
   343         if (!type || !canTest(node->condition(), type)) {
   344             loopDepth_--;
   345             return;
   346         }
   347     }
   348 
   349     if (node->update())
   350         node->update()->accept(this);
   351 
   352     node->body()->accept(this);
   353 
   354     if (node->scope())
   355         scope_ = scope_->enclosing();
   356     loopDepth_--;
   357 }
   358 
   359 void 
   360 SemanticAnalysis::visit(WhileStatement *node)
   361 {
   362     loopDepth_++;
   363 
   364     Type *type = visitForLoad(node->condition());
   365     if (!type || !canTest(node->condition(), type)) {
   366         loopDepth_--;
   367         return;
   368     }
   369 
   370     node->body()->accept(this);
   371     loopDepth_--;
   372 }
   373 
   374 void
   375 SemanticAnalysis::visit(BlockStatement *node)
   376 {
   377     if (node->scope())
   378         scope_ = node->scope();
   379     for (size_t i = 0; i < node->statements()->length(); i++) {
   380         Statement *statement = node->statements()->at(i);
   381         statement->accept(this);
   382     }
   383     if (node->scope())
   384         scope_ = scope_->enclosing();
   385 }
   386 
   387 void
   388 SemanticAnalysis::visit(VariableDeclaration *node)
   389 {
   390     // :TODO: use locals
   391     Type *type = ZONE()->types()->getPrimitiveForTag(node->tag());
   392     if (!type)
   393         return;
   394 
   395     if (node->postDimensions()) {
   396         Type *init = NULL;
   397         if (node->initialization()) {
   398             if ((init = visitAndApplyType(node->initialization())) == NULL)
   399                 return;
   400         }
   401 
   402         if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
   403             cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   404             return;
   405         }
   406 
   407         // If we have an initializer, make sure it's the same type.
   408         if (init && node->postDimensions()->size() != init->levels()) {
   409             cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
   410             return;
   411         }
   412 
   413         Type *check = init;
   414         for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
   415             Expression *expr = node->postDimensions()->at(i);
   416             int size = -1;
   417 
   418             if (expr) {
   419                 Type *exprType = visitForLoad(expr);
   420                 if (!exprType)
   421                     return;
   422 
   423                 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   424                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   425                     return;
   426                 }
   427 
   428                 BoxedPrimitive box;
   429                 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   430                     size = box.toInt();
   431                     if (size <= 0) {
   432                         cc_.reportError(expr->pos(), Message_BadArraySize);
   433                         return;
   434                     }
   435                     if (size >= INT_MAX / sizeof(int)) {
   436                         cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
   437                         return;
   438                     }
   439 
   440                     if (check) {
   441                         if (check->elements() == -1) {
   442                             cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
   443                             return;
   444                         }
   445 
   446                         if (check->isCharArray()) {
   447                             if (check->elements() > size) {
   448                                 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   449                                 return;
   450                             }
   451                         } else if (check->elements() != size) {
   452                             cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
   453                             return;
   454                         }
   455                     }
   456                 } else {
   457                     if (init) {
   458                         cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
   459                         return;
   460                     }
   461 
   462                     // here until we get dynamic array support.
   463                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   464                     return;
   465                 }
   466             } else {
   467                 // Infer the size from the initializer.
   468                 if (!init) {
   469                     cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
   470                     return;
   471                 }
   472                 if (init->elements() == -1) {
   473                     cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
   474                     return;
   475                 }
   476                 size = init->elements();
   477             }
   478 
   479             type = ZONE()->types()->unsafeArray(type, size);
   480             if (!type)
   481                 return;
   482 
   483             if (check)
   484                 check = check->contained();
   485         }
   486 
   487         // Right now, any array is allowed on the LIFO heap. In case the
   488         // runtime actually decides to use the LIFO heap, we must reserve
   489         // a slot so we can unwind the heap when the current scope leaves.
   490         scope_->setUsesLifoHeap();
   491     } else {
   492         if (node->initialization()) {
   493             Type *right = visitForLoad(node->initialization());
   494             if (!right)
   495                 return;
   496             if (!typeCheckAssignment(node, type, right, true))
   497                 return;
   498         }
   499         if (type->primitive() == PrimitiveType_Char) {
   500             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   501             return;
   502         }
   503     }
   504 
   505     node->variable()->setType(type);
   506 }
   507 
   508 void
   509 SemanticAnalysis::visit(IntegerLiteral *node)
   510 {
   511     node->setType(ZONE()->types()->getPrimitive(PrimitiveType_Int32));
   512 }
   513 
   514 void
   515 SemanticAnalysis::visit(ExpressionStatement *node)
   516 {
   517     node->expression()->accept(this);
   518 }
   519 
   520 bool
   521 SemanticAnalysis::preanalyze(FunctionStatement *node)
   522 {
   523     // :TODO: use Local
   524 
   525     FixedArray *args = FixedArray::New(ZONE(), node->parameters()->size(), Heap::Tenure_Old);
   526     if (!args)
   527         return false;
   528 
   529     // Apply types to arguments.
   530     for (size_t i = 0; i < node->parameters()->size(); i++) {
   531         Parameter *parameter = node->parameters()->at(i);
   532         
   533         Type *type = ZONE()->types()->getPrimitiveForTag(parameter->tag());
   534         if (!type)
   535             return false;
   536 
   537         if (type->primitive() == PrimitiveType_Char) {
   538             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   539             return false;
   540         }
   541 
   542         if (parameter->reference()) {
   543             type = ZONE()->types()->getReference(type);
   544             if (!type)
   545                 return false;
   546         }
   547 
   548         args->set(ZONE(), i, type);
   549         parameter->variable()->setType(type);
   550     }
   551 
   552     Type *returnType = ZONE()->types()->getPrimitive(PrimitiveType_Int32);
   553     if (!returnType)
   554         return false;
   555 
   556     Type *funtype = ZONE()->types()->newFunction(returnType, args);
   557     if (!funtype)
   558         return false;
   559 
   560     node->fun()->setType(funtype);
   561     return true;
   562 }
   563 
   564 void
   565 SemanticAnalysis::visit(FunctionStatement *node)
   566 {
   567     function_ = node->fun()->type();
   568     scope_ = node->scope();
   569     node->body()->accept(this);
   570     scope_ = NULL;
   571     function_ = NULL;
   572 }
   573 
   574 bool
   575 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
   576 {
   577     if (!given->isArray()) {
   578         cc_.reportError(node->pos(), Message_ExpectedArray);
   579         return false;
   580     }
   581     if (given->levels() != actual->levels()) {
   582         cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
   583         return false;
   584     }
   585 
   586     unsigned level = 0;
   587     while (given->isArray()) {
   588         if (actual->elements() != -1) {
   589             if (forAssign) {
   590                 if (given->elements() == -1 || actual->elements() == -1) {
   591                     cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
   592                     return false;
   593                 }
   594 
   595                 if (actual->isCharArray()) {
   596                     // String assignment can have a truncated |given|.
   597                     if (given->elements() > actual->elements()) {
   598                         cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   599                         return false;
   600                     }
   601                 } else {
   602                     if (given->elements() != actual->elements()) {
   603                         cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   604                         return false;
   605                     }
   606                 }
   607             } else {
   608                 if (actual->elements() != -1 && given->elements() != actual->elements()) {
   609                     cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   610                     return false;
   611                 }
   612             }
   613         }
   614         given = given->contained();
   615         actual = actual->contained();
   616     }
   617 
   618     if (given->primitive() != actual->primitive()) {
   619         const char *givenTag = given->tag() ? given->tag() : "_";
   620         const char *actualTag = given->tag() ? given->tag() : "_";
   621         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   622         return false;
   623     }
   624 
   625     return true;
   626 }
   627 
   628 bool
   629 SemanticAnalysis::typeCheckAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
   630 {
   631     if (actual->isArray())
   632         return typeCheckArrayAssignment(node, given, actual, forAssign);
   633 
   634     if (given->isArray()) {
   635         cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
   636         return false;
   637     }
   638 
   639     if (!given->isPrimitive() || !actual->primitive()) {
   640         cc_.reportError(node->pos(), Message_UnsupportedType);
   641         return false;
   642     }
   643     
   644     // The given type may not have been dereferenced.
   645     if (given->isReference())
   646         given = given->contained();
   647     if (actual->isReference())
   648         actual = given->contained();
   649 
   650     if (given->primitive() != actual->primitive()) {
   651         const char *givenTag = given->tag() ? given->tag() : "_";
   652         const char *actualTag = given->tag() ? given->tag() : "_";
   653         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   654         return false;
   655     }
   656 
   657     return true;
   658 }
   659 
   660 bool
   661 SemanticAnalysis::typeCheckParameter(AstNode *node, Type *given, Type *actual)
   662 {
   663     return typeCheckAssignment(node, given, actual, false);
   664 }
   665 
   666 void
   667 SemanticAnalysis::visit(CallExpression *node)
   668 {
   669     Type *type = visitForLoad(node->callee());
   670     if (!type)
   671         return;
   672 
   673     if (!type->isFunction()) {
   674         cc_.reportError(node->pos(), Message_CalleeNotFunction);
   675         return;
   676     }
   677     if (node->arguments()->size() != type->parameters()->length()) {
   678         cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
   679         return;
   680     }
   681 
   682     for (unsigned i = 0; i < node->arguments()->size(); i++) {
   683         // Note: we don't compute references unless the callee needs a
   684         // reference type.
   685         Expression *expression = node->arguments()->at(i);
   686         Type *given = visitAndApplyType(expression);
   687         if (!given)
   688             return;
   689 
   690         // If it's an IndexExpression, we special case the ability to compute
   691         // a reference.
   692         if (expression->isIndexExpression())
   693             given = given->contained();
   694 
   695         Type *actual = type->parameterAt(i);
   696         if (!typeCheckParameter(expression, given, actual))
   697             return;
   698 
   699         // If the actual is a reference, and the given is not, we'll need to
   700         // compute a reference, which may be allocated on the stack.
   701         if (actual->isReference() && !given->isReference())
   702             scope_->setUsesLifoHeap();
   703     }
   704 }
   705 
   706 void
   707 SemanticAnalysis::visit(IfStatement *node)
   708 {
   709     Type *type = visitForLoad(node->condition());
   710     if (!type)
   711         return;
   712 
   713     if (!canTest(node, type))
   714         return;
   715 
   716     node->ifTrue()->accept(this);
   717     if (node->ifFalse())
   718         node->ifFalse()->accept(this);
   719 }
   720 
   721 void
   722 SemanticAnalysis::visit(IndexExpression *node)
   723 {
   724     // :TODO: use locals
   725     Type *left = visitForRef(node->left());
   726     Type *right = visitForLoad(node->right());
   727 
   728     if (!left || !right)
   729         return;
   730 
   731     if (!right->isInt32()) {
   732         cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
   733         return;
   734     }
   735     if (!left->isArray()) {
   736         cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
   737         return;
   738     }
   739     node->setType(left);
   740 }
   741 
   742 void
   743 SemanticAnalysis::visit(EnumStatement *node)
   744 {
   745     // Forbid the blessed types.
   746     Name *tag = node->name();
   747     if (!strcmp(tag, "Float") ||
   748         !strcmp(tag, "String") ||
   749         !strcmp(tag, "any") ||
   750         !strcmp(tag, "bool"))
   751     {
   752         cc_.reportError(node->pos(), Message_InvalidEnumName);
   753         return;
   754     }
   755 
   756     Type *type = ZONE()->types()->getPrimitiveForTag(tag);
   757     if (!type)
   758         return;
   759 
   760     int value = 0;
   761     for (size_t i = 0; i < node->entries()->size(); i++) {
   762         EnumStatement::Entry &entry = node->entries()->at(i);
   763 
   764         BoxedPrimitive box = BoxedPrimitive::Int(value);
   765         if (entry.expr) {
   766             entry.expr->accept(this);
   767             if (!EvaluateForConstant(entry.expr, &box)) {
   768                 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
   769                 return;
   770             }
   771 
   772             assert(box.type() == PrimitiveType_Int32);
   773             value = box.toInt();
   774         }
   775 
   776         entry.name->set(type, box);
   777         value++;
   778     }
   779 }
   780 
   781 void
   782 SemanticAnalysis::visit(StringLiteral *node)
   783 {
   784     Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Char);
   785     if (!type)
   786         return;
   787 
   788     type = Type::NewArray(ZONE(), type, node->string()->length() + 1, true);
   789     if (!type)
   790         return;
   791 
   792     node->setType(type);
   793 }
   794 
   795 void
   796 SemanticAnalysis::visit(FloatLiteral *node)
   797 {
   798     Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Float);
   799     if (!type)
   800         return;
   801 
   802     node->setType(type);
   803 }
   804 
   805 void
   806 SemanticAnalysis::visit(BreakStatement *node)
   807 {
   808     if (loopDepth_ == 0)
   809         cc_.reportError(node->pos(), Message_BreakOutsideLoop);
   810 }
   811 
   812 void
   813 SemanticAnalysis::visit(ContinueStatement *node)
   814 {
   815     if (loopDepth_ == 0)
   816         cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
   817 }