Added support for negate operator.
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/.
19 #include "SemanticAnalysis.h"
22 #include "TypeManager.h"
30 IsPrimitiveType(Type *type, PrimitiveType primitive)
35 if (!type->isPrimitive())
38 return primitive == type->primitive();
42 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
47 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
51 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
60 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
62 switch (expression->kind()) {
63 case AstNode::kBinaryExpression:
67 BinaryExpression *b = expression->toBinaryExpression();
68 if (!EvaluateForConstant(b->left(), &left) ||
69 !EvaluateForConstant(b->right(), &right))
73 return EvaluateBinaryOperation(b->token(), left, right, out);
76 case AstNode::kNameProxy:
78 NameProxy *proxy = expression->toNameProxy();
79 if (proxy->binding()->kind() != BoundName::CONSTANT)
82 NamedConstant *c = proxy->binding()->toNamedConstant();
83 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
90 case AstNode::kIntegerLiteral:
91 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
99 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
109 SemanticAnalysis::analyze()
114 for (size_t i = 0; i < tree_->statements()->length(); i++) {
115 Statement *statement = tree_->statements()->at(i);
116 if (statement->isFunctionStatement()) {
117 FunctionStatement *funstmt = statement->toFunctionStatement();
118 if (!preanalyze(funstmt))
123 for (size_t i = 0; i < tree_->statements()->length(); i++) {
124 Statement *statement = tree_->statements()->at(i);
125 statement->accept(this);
128 return !cc_.failures();
132 SemanticAnalysis::visitAndApplyType(Expression *expression)
134 expression->accept(this);
135 return expression->type();
139 SemanticAnalysis::visitForLoad(Expression *expression)
141 Local<Type> type(zone_, visitAndApplyType(expression));
145 if (type->isReference()) {
146 expression->setType(type->contained());
147 } else if (expression->isIndexExpression()) {
149 expression->setType(type->contained());
150 } else if (expression->isCallExpression()) {
151 if (type->isVoid()) {
152 CallExpression *call = expression->toCallExpression();
153 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
158 return expression->type();
161 // :TODO: this leaks an interior pointer.
162 static inline const char *
163 GetTypeName(Type *type)
167 if (type->isFunction())
169 if (type->isReference())
170 type = type->contained();
172 return type->tag()->chars();
177 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
179 const char *op = TokenNames[token];
180 const char *name = GetTypeName(type);
182 cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
186 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
188 const char *op = TokenNames[token];
189 const char *leftName = GetTypeName(left);
190 const char *rightName = GetTypeName(right);
192 cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
196 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
198 if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
199 (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
201 // If either side is a float, the other side must be a float or int.
202 if (left->isFloat() || right->isFloat()) {
203 Type *floatType = left->isFloat() ? left : right;
204 Type *other = left->isFloat() ? right : left;
205 if (other->isFloat() || (other->isInt32() && !other->tag()))
210 if (token == TOK_OR || token == TOK_AND) {
211 if (!canTest(node, left) || !canTest(node, right))
213 return zone_->types()->getPrimitive(PrimitiveType_Int32);
216 if (token >= TOK_EQUALS && token <= TOK_GE) {
217 if ((left->isFloat() || (left->isInt32() && !left->tag())) &&
218 (right->isFloat() || (right->isInt32() && !right->tag())))
220 return zone_->types()->getPrimitive(PrimitiveType_Int32);
222 binaryTypeError(node, token, left, right);
226 if ((!left->isInt32() || left->tag()) ||
227 (!right->isInt32() || right->tag()))
229 binaryTypeError(node, token, left, right);
237 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
239 if (type->isArray() || (type->isInt32() && type->tag())) {
240 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
247 SemanticAnalysis::visitForLValue(Expression *expression)
249 if (expression->isIndexExpression()) {
250 Type *type = visitAndApplyType(expression);
254 if (type->isConst()) {
255 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
259 return type->contained();
262 if (!expression->isNameProxy()) {
263 cc_.reportError(expression->pos(), Message_ExpectedLValue);
267 NameProxy *proxy = expression->toNameProxy();
268 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
269 cc_.reportError(expression->pos(), Message_ExpectedLValue);
273 Variable *var = proxy->binding()->toVariable();
277 if (var->type()->isReference()) {
278 if (var->type()->isConst()) {
279 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
282 return var->type()->contained();
287 SemanticAnalysis::ControlStatus
288 SemanticAnalysis::visitForControl(Statement *statement)
290 ControlScope scope(&control_);
291 statement->accept(this);
292 return scope.status();
296 SemanticAnalysis::visit(NameProxy *name)
298 name->setType(name->binding()->type());
302 SemanticAnalysis::visit(Assignment *node)
304 Local<Type> exprType(zone_, visitForLoad(node->expression()));
308 Local<Type> type(zone_, visitForLValue(node->lvalue()));
312 if (node->token() != TOK_ASSIGN) {
313 if (!typeCheckBinary(node, node->token(), type, exprType))
317 if (!typeCheckAssignment(node, exprType, type, true))
324 SemanticAnalysis::visit(IncDecExpression *node)
326 Local<Type> type(zone_, visitForLValue(node->expression()));
330 assert(!type->isReference());
332 if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
333 unaryTypeError(node, node->token(), type);
341 SemanticAnalysis::visit(UnaryExpression *node)
343 Local<Type> type(zone_, visitForLoad(node->expression()));
347 switch (node->token())
350 if (!canTest(node->expression(), type))
352 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
359 if (!type->isFloat() && (!type->isInt32() || type->tag())) {
360 unaryTypeError(node, node->token(), type);
367 assert(node->token() == TOK_TILDE);
368 if (!type->isInt32() || type->tag()) {
369 unaryTypeError(node, node->token(), type);
378 SemanticAnalysis::visit(BinaryExpression *node)
380 Local<Type> left(zone_, visitForLoad(node->left()));
381 Local<Type> right(zone_, visitForLoad(node->right()));
385 Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
389 node->setType(result);
393 SemanticAnalysis::visit(ReturnStatement *node)
395 // Set this early, so if we error we don't get more errors.
396 control_->returns(Returns_Always);
398 if (!node->expression()) {
399 if (!function_->returnType()->isVoid())
400 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
404 Local<Type> type(zone_, visitForLoad(node->expression()));
408 Local<Type> returnType(zone_, function_->returnType());
409 if (!typeCheckAssignment(node, type, returnType, true))
414 SemanticAnalysis::visit(ForStatement *node)
416 LoopScope loop(&loop_);
419 scope_ = node->scope();
421 if (node->initialization())
422 node->initialization()->accept(this);
424 if (node->condition()) {
425 Local<Type> type(zone_, visitForLoad(node->condition()));
426 if (!type || !canTest(node->condition(), type)) {
432 node->update()->accept(this);
434 ControlStatus status = visitForControl(node->body());
436 // If there is a condition, we treat this like a while loop. Otherwise,
437 // join point is only reachable if the loop contains a break. The
438 // termination status doesn't tell us anything yet.
439 if (node->condition() || loop.breaks())
440 control_->merge(status, ControlStatus(false, Returns_Never));
442 control_->terminate(status.returns());
445 scope_ = scope_->enclosing();
449 SemanticAnalysis::visit(WhileStatement *node)
451 LoopScope loop(&loop_);
453 Local<Type> type(zone_, visitForLoad(node->condition()));
454 if (!type || !canTest(node->condition(), type)) {
458 ControlStatus status = visitForControl(node->body());
460 // Detect loops that will always have a fork in the control-flow graph.
461 // This will be a |while| loop, or a |do-while| loop whose body does
464 // For now, we treat these as an |if| regardless of the direction the
465 // branch can take. That means the control-flow is always conditional.
466 if (node->token() == TOK_WHILE ||
467 !status.terminates() ||
470 control_->merge(status, ControlStatus(false, Returns_Never));
472 // At this point, we've got a do-while loop with a |return| or
473 // |continue|, meaning that the rest of the block is unreachable.
474 control_->terminate(status.returns());
479 SemanticAnalysis::visit(BlockStatement *node)
482 scope_ = node->scope();
483 for (size_t i = 0; i < node->statements()->length(); i++) {
484 Statement *statement = node->statements()->at(i);
485 statement->accept(this);
488 scope_ = scope_->enclosing();
492 SemanticAnalysis::visit(VariableDeclaration *node)
494 Local<String> tag(zone_, node->tag());
495 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
499 if (node->postDimensions()) {
500 Local<Type> init(zone_);
501 if (node->initialization()) {
502 if ((init = visitForLoad(node->initialization())) == NULL)
506 if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
507 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
511 // If we have an initializer, make sure it's the same type.
512 if (init && node->postDimensions()->length() != init->levels()) {
513 cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
517 Local<Type> check(zone_, init);
518 for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
519 Expression *expr = node->postDimensions()->at(i);
523 Local<Type> exprType(zone_, visitForLoad(expr));
527 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
528 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
533 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
536 cc_.reportError(expr->pos(), Message_BadArraySize);
539 if (size >= INT_MAX / sizeof(int)) {
540 cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
545 if (check->elements() == -1) {
546 cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
550 if (check->isCharArray()) {
551 if (check->elements() > size) {
552 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
555 } else if (check->elements() != size) {
556 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
562 cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
566 // here until we get dynamic array support.
567 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
571 // Infer the size from the initializer.
573 cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
576 if (init->elements() == -1) {
577 cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
580 size = init->elements();
583 type = zone_->types()->unsafeArray(type, size, false);
588 check = check->contained();
591 // Right now, any array is allowed on the LIFO heap. In case the
592 // runtime actually decides to use the LIFO heap, we must reserve
593 // a slot so we can unwind the heap when the current scope leaves.
594 scope_->setUsesLifoHeap();
596 if (node->initialization()) {
597 Local<Type> right(zone_, visitForLoad(node->initialization()));
600 if (!typeCheckAssignment(node, type, right, true))
603 if (type->primitive() == PrimitiveType_Char) {
604 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
609 node->variable()->setType(type);
613 SemanticAnalysis::visit(IntegerLiteral *node)
615 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
619 SemanticAnalysis::visit(ExpressionStatement *node)
621 visitAndApplyType(node->expression());
625 SemanticAnalysis::preanalyze(FunctionStatement *node)
627 Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
631 // Apply types to arguments.
632 for (size_t i = 0; i < node->parameters()->length(); i++) {
633 Parameter *parameter = node->parameters()->at(i);
635 Local<String> tag(zone_, parameter->tag());
636 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
640 if (parameter->reference()) {
641 if (parameter->dimensions()) {
642 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
646 type = zone_->types()->getReference(type, parameter->isConst());
649 } else if (parameter->dimensions()) {
650 if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
651 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
655 if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
656 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
660 for (size_t i = parameter->dimensions()->length() - 1;
661 i < parameter->dimensions()->length();
664 int size = Type::UNKNOWN_SIZE;
665 if (Expression *expr = parameter->dimensions()->at(i)) {
667 if (!EvaluateForConstant(expr, &box)) {
668 cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
674 type = zone_->types()->unsafeArray(type, size, parameter->isConst());
680 if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) ||
681 (type->isReference() && type->contained()->primitive() == PrimitiveType_Char))
683 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
687 args->set(zone_, i, type);
688 parameter->variable()->setType(type);
691 Local<Type> returnType(zone_);
692 if (node->hasExplicitReturn() || node->fun()->isNative())
693 returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
695 returnType = zone_->types()->getVoid();
699 Local<Type> funtype(zone_);
700 if (node->fun()->isNative())
701 funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic());
703 funtype = zone_->types()->newFunction(returnType, args);
707 // If the function already has a type, it was forward declared before, and
708 // now this is our chance to type check the second declaration.
709 if (node->fun()->type()) {
710 Local<Type> forward(zone_, node->fun()->type());
711 if (!Type::Compare(funtype, forward)) {
712 cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
715 node->fun()->setForwardType(forward);
718 node->fun()->setType(funtype);
724 SemanticAnalysis::visit(FunctionStatement *node)
726 function_ = node->fun()->type();
727 scope_ = node->scope();
729 ControlScope control(&control_);
731 node->body()->accept(this);
733 ControlStatus status = control.status();
734 if (status.returns() == Returns_Sometimes) {
735 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
736 } else if (status.returns() == Returns_Never) {
737 if (!function_->returnType()->isVoid())
738 cc_.reportError(node->pos(), Message_MissingReturnValue);
747 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
749 Local<Type> actual(zone_, argActual);
750 Local<Type> given(zone_, argGiven);
752 if (!given->isArray()) {
753 cc_.reportError(node->pos(), Message_ExpectedArray);
756 if (given->levels() != actual->levels()) {
757 cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
762 while (given->isArray()) {
763 if (actual->elements() != -1) {
765 if (given->elements() == -1 || actual->elements() == -1) {
766 cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
770 if (actual->isCharArray()) {
771 // String assignment can have a truncated |given|.
772 if (given->elements() > actual->elements()) {
773 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
777 if (given->elements() != actual->elements()) {
778 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
783 if (actual->elements() != -1 && given->elements() != actual->elements()) {
784 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
789 given = given->contained();
790 actual = actual->contained();
793 if (given->primitive() != actual->primitive()) {
794 // :TODO: leaks an interior pointer.
795 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
796 const char *actualTag = given->tag() ? given->tag()->chars() : "_";
797 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
805 SemanticAnalysis::typeCheckAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
807 Local<Type> actual(zone_, argActual);
808 Local<Type> given(zone_, argGiven);
810 if (actual->isArray())
811 return typeCheckArrayAssignment(node, given, actual, forAssign);
813 if (given->isArray()) {
814 cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
818 // The given type may not have been dereferenced.
819 if (given->isReference())
820 given = given->contained();
821 if (actual->isReference())
822 actual = actual->contained();
824 if (!given->isPrimitive() || !actual->isPrimitive()) {
825 cc_.reportError(node->pos(), Message_UnsupportedType);
829 if (given->primitive() != actual->primitive()) {
830 // :TODO: leaks an interior pointer
831 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
832 const char *actualTag = given->tag() ? given->tag()->chars() : "_";
833 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
841 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
843 return typeCheckAssignment(node, given, actual, false);
847 SemanticAnalysis::visit(CallExpression *node)
849 Local<Type> type(zone_, visitForLoad(node->callee()));
853 if (!type->isFunction()) {
854 cc_.reportError(node->pos(), Message_CalleeNotFunction);
857 if (node->arguments()->length() != type->parameters()->length()) {
858 if (!type->isNative() ||
859 !type->isNativeVariadic() ||
860 node->arguments()->length() < type->parameters()->length())
862 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
867 // Currently, only calls from a NameProxy are possible.
868 NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
869 if (fun->isForward()) {
870 cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
874 for (unsigned i = 0; i < node->arguments()->length(); i++) {
875 // Note: we don't compute references unless the callee needs a
877 Expression *expression = node->arguments()->at(i);
878 Local<Type> given(zone_, visitAndApplyType(expression));
882 // Since we skip a load, check for a call expression that returns void.
883 if (given->isVoid()) {
884 assert(expression->isCallExpression());
885 CallExpression *call = expression->toCallExpression();
886 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
890 // If it's an IndexExpression, we special case the ability to compute
892 if (expression->isIndexExpression())
893 given = given->contained();
895 bool mustComputeReference;
896 if (i >= type->parameters()->length()) {
897 // Special handling for natives. Arguments past the formal must
898 // always have references computed. However, arrays are already
899 // references for natives.
900 assert(type->isNative() && type->isNativeVariadic());
901 mustComputeReference = !given->isReference() && !given->isArray();
903 Local<Type> actual(zone_, type->parameterAt(i));
904 if (!typeCheckParameter(expression, given, actual))
906 mustComputeReference = actual->isReference() && !given->isReference();
909 // If the actual is a reference, and the given is not, we'll need to
910 // compute a reference, which may be allocated on the stack.
911 if (mustComputeReference)
912 scope_->setUsesLifoHeap();
915 node->setType(fun->type()->returnType());
919 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
921 // If both sides terminate in a return, we consider this a return as well.
922 if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
923 terminate(Returns_Always);
927 ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
931 if (left.terminates() && right.terminates())
938 SemanticAnalysis::visit(IfStatement *node)
940 Local<Type> type(zone_, visitForLoad(node->condition()));
944 if (!canTest(node, type))
947 ControlStatus trueBranch = visitForControl(node->ifTrue());
948 ControlStatus falseBranch = ControlStatus(false, Returns_Never);
951 falseBranch = visitForControl(node->ifFalse());
953 control_->merge(trueBranch, falseBranch);
957 SemanticAnalysis::visit(IndexExpression *node)
959 Local<Type> left(zone_, visitForLoad(node->left()));
960 Local<Type> right(zone_, visitForLoad(node->right()));
965 if (!right->isInt32()) {
966 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
969 if (!left->isArray()) {
970 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
977 SemanticAnalysis::visit(EnumStatement *node)
979 // Forbid the blessed types.
980 Local<String> tag(zone_, node->name());
981 if (!strcmp(tag->chars(), "Float") ||
982 !strcmp(tag->chars(), "String") ||
983 !strcmp(tag->chars(), "any") ||
984 !strcmp(tag->chars(), "bool"))
986 cc_.reportError(node->pos(), Message_InvalidEnumName);
990 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
995 for (size_t i = 0; i < node->entries()->length(); i++) {
996 EnumStatement::Entry &entry = node->entries()->at(i);
998 BoxedPrimitive box = BoxedPrimitive::Int(value);
1000 entry.expr->accept(this);
1001 if (!EvaluateForConstant(entry.expr, &box)) {
1002 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
1006 assert(box.type() == PrimitiveType_Int32);
1007 value = box.toInt();
1010 entry.name->set(type, box);
1016 SemanticAnalysis::visit(StringLiteral *node)
1018 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
1022 type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
1026 node->setType(type);
1030 SemanticAnalysis::visit(FloatLiteral *node)
1032 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
1036 node->setType(type);
1040 SemanticAnalysis::visit(BreakStatement *node)
1043 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
1047 // Note: ignore breaks that occur in unreachable control-flow.
1048 if (!control_->status().terminates())
1051 control_->terminate(Returns_Never);
1055 SemanticAnalysis::visit(ContinueStatement *node)
1058 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
1062 // Note: ignore continues that occur in unreachable control-flow.
1063 if (!control_->status().terminates())
1064 loop_->addContinue();
1066 control_->terminate(Returns_Never);