Trigger build.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
20 #include "SemanticAnalysis.h"
23 #include "TypeManager.h"
25 #include "NameBinding.h"
32 IsPrimitiveType(Type *type, PrimitiveType primitive)
37 if (!type->isPrimitive())
40 return primitive == type->primitive();
44 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
49 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
53 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
62 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
64 switch (expression->kind()) {
65 case AstNode::kBinaryExpression:
69 BinaryExpression *b = expression->toBinaryExpression();
70 if (!EvaluateForConstant(b->left(), &left) ||
71 !EvaluateForConstant(b->right(), &right))
75 return EvaluateBinaryOperation(b->token(), left, right, out);
78 case AstNode::kNameProxy:
80 NameProxy *proxy = expression->toNameProxy();
81 if (proxy->binding()->kind() != BoundName::CONSTANT)
84 NamedConstant *c = proxy->binding()->toNamedConstant();
85 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
92 case AstNode::kIntegerLiteral:
93 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
101 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
111 SemanticAnalysis::analyze()
116 scope_ = tree_->scope();
118 for (size_t i = 0; i < tree_->statements()->length(); i++) {
119 Statement *statement = tree_->statements()->at(i);
120 if (statement->isFunctionStatement()) {
121 FunctionStatement *funstmt = statement->toFunctionStatement();
122 if (!preanalyze(funstmt))
127 for (size_t i = 0; i < tree_->statements()->length(); i++) {
128 Statement *statement = tree_->statements()->at(i);
129 statement->accept(this);
132 return !cc_.failures();
136 SemanticAnalysis::visitAndApplyType(Expression *expression)
138 expression->accept(this);
139 return expression->type();
143 SemanticAnalysis::visitForLoad(Expression *expression)
145 Local<Type> type(zone_, visitAndApplyType(expression));
149 if (type->isReference()) {
150 expression->setType(type->contained());
151 } else if (expression->isIndexExpression()) {
153 expression->setType(type->contained());
154 } else if (expression->isCallExpression()) {
155 if (type->isVoid()) {
156 CallExpression *call = expression->toCallExpression();
157 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
162 return expression->type();
165 // :TODO: this leaks an interior pointer.
166 static inline const char *
167 GetTypeName(Type *type)
171 if (type->isFunction())
173 if (type->isReference())
174 type = type->contained();
176 return type->tag()->chars();
181 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
183 const char *op = TokenNames[token];
184 const char *name = GetTypeName(type);
186 cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
190 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
192 const char *op = TokenNames[token];
193 const char *leftName = GetTypeName(left);
194 const char *rightName = GetTypeName(right);
196 cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
200 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
202 if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
203 (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
205 // If either side is a float, the other side must be a float or int.
206 if (left->isFloat() || right->isFloat()) {
207 Type *floatType = left->isFloat() ? left : right;
208 Type *other = left->isFloat() ? right : left;
209 if (other->isFloat() || (other->isInt32() && !other->tag()))
214 if (token == TOK_OR || token == TOK_AND) {
215 if (!canTest(node, left) || !canTest(node, right))
217 return zone_->types()->getPrimitive(PrimitiveType_Int32);
220 if (token >= TOK_EQUALS && token <= TOK_GE) {
221 if ((left->isFloat() || (left->isInt32() && !left->tag())) &&
222 (right->isFloat() || (right->isInt32() && !right->tag())))
224 return zone_->types()->getPrimitive(PrimitiveType_Int32);
226 binaryTypeError(node, token, left, right);
230 if ((!left->isInt32() || left->tag()) ||
231 (!right->isInt32() || right->tag()))
233 binaryTypeError(node, token, left, right);
241 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
243 if (type->isArray() || (type->isInt32() && type->tag())) {
244 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
251 SemanticAnalysis::visitForLValue(Expression *expression)
253 if (expression->isIndexExpression()) {
254 Type *type = visitAndApplyType(expression);
258 if (type->isConst()) {
259 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
263 return type->contained();
266 if (!expression->isNameProxy()) {
267 cc_.reportError(expression->pos(), Message_ExpectedLValue);
271 NameProxy *proxy = expression->toNameProxy();
272 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
273 cc_.reportError(expression->pos(), Message_ExpectedLValue);
277 Variable *var = proxy->binding()->toVariable();
281 if (var->type()->isReference()) {
282 if (var->type()->isConst()) {
283 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
286 return var->type()->contained();
291 SemanticAnalysis::ControlStatus
292 SemanticAnalysis::visitForControl(Statement *statement)
294 ControlScope scope(&control_);
295 statement->accept(this);
296 return scope.status();
300 SemanticAnalysis::visit(NameProxy *name)
302 name->setType(name->binding()->type());
306 SemanticAnalysis::visit(Assignment *node)
308 Local<Type> exprType(zone_, visitForLoad(node->expression()));
312 Local<Type> type(zone_, visitForLValue(node->lvalue()));
316 if (node->token() != TOK_ASSIGN) {
317 if (!typeCheckBinary(node, node->token(), type, exprType))
321 if (!typeCheckAssignment(node, exprType, type, true))
328 SemanticAnalysis::visit(IncDecExpression *node)
330 Local<Type> type(zone_, visitForLValue(node->expression()));
334 assert(!type->isReference());
336 if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
337 unaryTypeError(node, node->token(), type);
345 SemanticAnalysis::visit(UnaryExpression *node)
347 Local<Type> type(zone_, visitForLoad(node->expression()));
351 switch (node->token())
354 if (!canTest(node->expression(), type))
356 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
363 if (!type->isFloat() && (!type->isInt32() || type->tag())) {
364 unaryTypeError(node, node->token(), type);
371 assert(node->token() == TOK_TILDE);
372 if (!type->isInt32() || type->tag()) {
373 unaryTypeError(node, node->token(), type);
382 SemanticAnalysis::visit(TernaryExpression *node)
384 Local<Type> type(zone_, visitForLoad(node->condition()));
388 if (!canTest(node->condition(), type))
391 Local<Type> left(zone_, visitForLoad(node->left()));
392 Local<Type> right(zone_, visitForLoad(node->right()));
397 binaryTypeError(node, TOK_QMARK, left, right);
403 SemanticAnalysis::visit(BinaryExpression *node)
405 Local<Type> left(zone_, visitForLoad(node->left()));
406 Local<Type> right(zone_, visitForLoad(node->right()));
410 Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
414 node->setType(result);
418 SemanticAnalysis::visit(ReturnStatement *node)
420 // Set this early, so if we error we don't get more errors.
421 control_->returns(Returns_Always);
423 if (!node->expression()) {
424 if (!function_->returnType()->isVoid())
425 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
429 Local<Type> type(zone_, visitForLoad(node->expression()));
433 Local<Type> returnType(zone_, function_->returnType());
434 if (!typeCheckAssignment(node, type, returnType, true))
439 SemanticAnalysis::visit(ForStatement *node)
441 LoopScope loop(&loop_);
444 scope_ = node->scope();
446 if (node->initialization())
447 node->initialization()->accept(this);
449 if (node->condition()) {
450 Local<Type> type(zone_, visitForLoad(node->condition()));
451 if (!type || !canTest(node->condition(), type)) {
457 node->update()->accept(this);
459 ControlStatus status = visitForControl(node->body());
461 // If there is a condition, we treat this like a while loop. Otherwise,
462 // join point is only reachable if the loop contains a break. The
463 // termination status doesn't tell us anything yet.
464 if (node->condition() || loop.breaks())
465 control_->merge(status, ControlStatus(false, Returns_Never));
467 control_->terminate(status.returns());
470 scope_ = scope_->enclosing();
474 SemanticAnalysis::visit(WhileStatement *node)
476 LoopScope loop(&loop_);
478 Local<Type> type(zone_, visitForLoad(node->condition()));
479 if (!type || !canTest(node->condition(), type)) {
483 ControlStatus status = visitForControl(node->body());
485 // Detect loops that will always have a fork in the control-flow graph.
486 // This will be a |while| loop, or a |do-while| loop whose body does
489 // For now, we treat these as an |if| regardless of the direction the
490 // branch can take. That means the control-flow is always conditional.
491 if (node->token() == TOK_WHILE ||
492 !status.terminates() ||
495 control_->merge(status, ControlStatus(false, Returns_Never));
497 // At this point, we've got a do-while loop with a |return| or
498 // |continue|, meaning that the rest of the block is unreachable.
499 control_->terminate(status.returns());
504 SemanticAnalysis::visit(BlockStatement *node)
507 scope_ = node->scope();
508 for (size_t i = 0; i < node->statements()->length(); i++) {
509 Statement *statement = node->statements()->at(i);
510 statement->accept(this);
513 scope_ = scope_->enclosing();
517 SemanticAnalysis::visit(VariableDeclaration *node)
519 Local<String> tag(zone_, node->tag());
520 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
524 if (node->postDimensions()) {
525 Local<Type> init(zone_);
526 if (node->initialization()) {
527 if ((init = visitForLoad(node->initialization())) == NULL)
531 if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
532 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
536 // If we have an initializer, make sure it's the same type.
537 if (init && node->postDimensions()->length() != init->levels()) {
538 cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
542 Local<Type> check(zone_, init);
543 for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
544 Expression *expr = node->postDimensions()->at(i);
548 Local<Type> exprType(zone_, visitForLoad(expr));
552 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
553 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
558 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
561 cc_.reportError(expr->pos(), Message_BadArraySize);
564 if (size >= int(INT_MAX / sizeof(int))) {
565 cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
570 if (check->elements() == -1) {
571 cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
575 if (check->isCharArray()) {
576 if (check->elements() > size) {
577 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
580 } else if (check->elements() != size) {
581 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
587 cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
591 // here until we get dynamic array support.
592 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
596 // Infer the size from the initializer.
598 cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
601 if (init->elements() == -1) {
602 cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
605 size = init->elements();
608 type = zone_->types()->unsafeArray(type, size, false);
613 check = check->contained();
616 // If this variable is stack allocated, we could use the LIFO heap
617 // to allocate it. If that's the case, make sure to reserve a slot
618 // so we can unwind the LIFO heap at the end of this scope.
619 if (!node->variable()->needsHeapAllocation())
620 scope_->setUsesLifoHeap();
622 if (node->initialization()) {
623 Local<Type> right(zone_, visitForLoad(node->initialization()));
626 if (!typeCheckAssignment(node, type, right, true))
629 if (type->primitive() == PrimitiveType_Char) {
630 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
635 node->variable()->setType(type);
639 SemanticAnalysis::visit(IntegerLiteral *node)
641 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
645 SemanticAnalysis::visit(ExpressionStatement *node)
647 visitAndApplyType(node->expression());
651 SemanticAnalysis::preanalyze(FunctionStatement *node)
653 Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
657 // Apply types to arguments.
658 for (size_t i = 0; i < node->parameters()->length(); i++) {
659 Parameter *parameter = node->parameters()->at(i);
661 Local<String> tag(zone_, parameter->tag());
662 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
666 if (parameter->reference()) {
667 if (parameter->dimensions()) {
668 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
672 type = zone_->types()->getReference(type, parameter->isConst());
675 } else if (parameter->dimensions()) {
676 if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
677 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
681 if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
682 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
686 for (size_t i = parameter->dimensions()->length() - 1;
687 i < parameter->dimensions()->length();
690 int size = Type::UNKNOWN_SIZE;
691 if (Expression *expr = parameter->dimensions()->at(i)) {
693 if (!EvaluateForConstant(expr, &box)) {
694 cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
700 type = zone_->types()->unsafeArray(type, size, parameter->isConst());
706 if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) ||
707 (type->isReference() && type->contained()->primitive() == PrimitiveType_Char))
709 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
713 args->set(zone_, i, type);
714 parameter->variable()->setType(type);
717 Local<Type> returnType(zone_);
718 if (node->hasExplicitReturn() || node->fun()->isNative())
719 returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
721 returnType = zone_->types()->getVoid();
725 Local<Type> funtype(zone_);
726 if (node->fun()->isNative())
727 funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic());
729 funtype = zone_->types()->newFunction(returnType, args);
733 // If the function already has a type, it was forward declared before, and
734 // now this is our chance to type check the second declaration.
735 if (node->fun()->type()) {
736 Local<Type> forward(zone_, node->fun()->type());
737 if (!Type::Compare(funtype, forward)) {
738 cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
741 node->fun()->setForwardType(forward);
744 node->fun()->setType(funtype);
750 SemanticAnalysis::visit(FunctionStatement *node)
752 function_ = node->fun()->type();
753 scope_ = node->scope();
755 ControlScope control(&control_);
757 node->body()->accept(this);
759 ControlStatus status = control.status();
760 if (status.returns() == Returns_Sometimes) {
761 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
762 } else if (status.returns() == Returns_Never) {
763 if (!function_->returnType()->isVoid())
764 cc_.reportError(node->pos(), Message_MissingReturnValue);
773 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
775 Local<Type> actual(zone_, argActual);
776 Local<Type> given(zone_, argGiven);
778 if (!given->isArray()) {
779 cc_.reportError(node->pos(), Message_ExpectedArray);
782 if (given->levels() != actual->levels()) {
783 cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
788 while (given->isArray()) {
789 if (actual->elements() != -1) {
791 if (given->elements() == -1 || actual->elements() == -1) {
792 cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
796 if (actual->isCharArray()) {
797 // String assignment can have a truncated |given|.
798 if (given->elements() > actual->elements()) {
799 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
803 if (given->elements() != actual->elements()) {
804 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
809 if (actual->elements() != -1 && given->elements() != actual->elements()) {
810 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
815 given = given->contained();
816 actual = actual->contained();
819 if (given->primitive() != actual->primitive()) {
820 // :TODO: leaks an interior pointer.
821 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
822 const char *actualTag = given->tag() ? given->tag()->chars() : "_";
823 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
831 SemanticAnalysis::typeCheckAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
833 Local<Type> actual(zone_, argActual);
834 Local<Type> given(zone_, argGiven);
836 if (actual->isArray())
837 return typeCheckArrayAssignment(node, given, actual, forAssign);
839 if (given->isArray()) {
840 cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
844 // The given type may not have been dereferenced.
845 if (given->isReference())
846 given = given->contained();
847 if (actual->isReference())
848 actual = actual->contained();
850 if (!given->isPrimitive() || !actual->isPrimitive()) {
851 cc_.reportError(node->pos(), Message_UnsupportedType);
855 if (given->primitive() != actual->primitive()) {
856 // :TODO: leaks an interior pointer
857 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
858 const char *actualTag = actual->tag() ? actual->tag()->chars() : "_";
859 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
867 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
869 return typeCheckAssignment(node, given, actual, false);
873 SemanticAnalysis::visit(CallExpression *node)
875 Local<Type> type(zone_, visitForLoad(node->callee()));
879 if (!type->isFunction()) {
880 cc_.reportError(node->pos(), Message_CalleeNotFunction);
883 if (node->arguments()->length() != type->parameters()->length()) {
884 if (!type->isNative() ||
885 !type->isNativeVariadic() ||
886 node->arguments()->length() < type->parameters()->length())
888 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
893 // Currently, only calls from a NameProxy are possible.
894 NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
895 if (fun->isForward()) {
896 cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
900 for (unsigned i = 0; i < node->arguments()->length(); i++) {
901 // Note: we don't compute references unless the callee needs a
903 Expression *expression = node->arguments()->at(i);
904 Local<Type> given(zone_, visitAndApplyType(expression));
908 // Since we skip a load, check for a call expression that returns void.
909 if (given->isVoid()) {
910 assert(expression->isCallExpression());
911 CallExpression *call = expression->toCallExpression();
912 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
916 // If it's an IndexExpression, we special case the ability to compute
918 if (expression->isIndexExpression())
919 given = given->contained();
921 bool mustComputeReference;
922 if (i >= type->parameters()->length()) {
923 // Special handling for natives. Arguments past the formal must
924 // always have references computed. However, arrays are already
925 // references for natives.
926 assert(type->isNative() && type->isNativeVariadic());
927 mustComputeReference = !given->isReference() && !given->isArray();
929 Local<Type> actual(zone_, type->parameterAt(i));
930 if (!typeCheckParameter(expression, given, actual))
932 mustComputeReference = actual->isReference() && !given->isReference();
935 // If the actual is a reference, and the given is not, we'll need to
936 // compute a reference, which may be allocated on the stack.
937 if (mustComputeReference)
938 scope_->setUsesLifoHeap();
941 node->setType(fun->type()->returnType());
945 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
947 // If both sides terminate in a return, we consider this a return as well.
948 if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
949 terminate(Returns_Always);
953 ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
957 if (left.terminates() && right.terminates())
964 SemanticAnalysis::visit(IfStatement *node)
966 Local<Type> type(zone_, visitForLoad(node->condition()));
970 if (!canTest(node, type))
973 ControlStatus trueBranch = visitForControl(node->ifTrue());
974 ControlStatus falseBranch = ControlStatus(false, Returns_Never);
977 falseBranch = visitForControl(node->ifFalse());
979 control_->merge(trueBranch, falseBranch);
983 SemanticAnalysis::visit(IndexExpression *node)
985 Local<Type> left(zone_, visitForLoad(node->left()));
986 Local<Type> right(zone_, visitForLoad(node->right()));
991 if (!right->isInt32()) {
992 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
995 if (!left->isArray()) {
996 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
1003 SemanticAnalysis::visit(EnumStatement *node)
1005 // Forbid the blessed types.
1006 Local<String> tag(zone_, node->name());
1007 if (!strcmp(tag->chars(), "Float") ||
1008 !strcmp(tag->chars(), "String") ||
1009 !strcmp(tag->chars(), "any") ||
1010 !strcmp(tag->chars(), "bool"))
1012 cc_.reportError(node->pos(), Message_InvalidEnumName);
1016 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
1021 for (size_t i = 0; i < node->entries()->length(); i++) {
1022 EnumStatement::Entry &entry = node->entries()->at(i);
1024 BoxedPrimitive box = BoxedPrimitive::Int(value);
1026 entry.expr->accept(this);
1027 if (!EvaluateForConstant(entry.expr, &box)) {
1028 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
1032 assert(box.type() == PrimitiveType_Int32);
1033 value = box.toInt();
1036 entry.name->set(type, box);
1042 SemanticAnalysis::visit(StringLiteral *node)
1044 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
1048 type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
1052 node->setType(type);
1056 SemanticAnalysis::visit(FloatLiteral *node)
1058 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
1062 node->setType(type);
1066 SemanticAnalysis::visit(BreakStatement *node)
1069 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
1073 // Note: ignore breaks that occur in unreachable control-flow.
1074 if (!control_->status().terminates())
1077 control_->terminate(Returns_Never);
1081 SemanticAnalysis::visit(ContinueStatement *node)
1084 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
1088 // Note: ignore continues that occur in unreachable control-flow.
1089 if (!control_->status().terminates())
1090 loop_->addContinue();
1092 control_->terminate(Returns_Never);