Added complement operator support.
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_EQUALS && token <= TOK_OR) {
211 if ((left->isFloat() || (left->isInt32() && !left->tag())) &&
212 (right->isFloat() || (right->isInt32() && !right->tag())))
214 return zone_->types()->getPrimitive(PrimitiveType_Int32);
216 binaryTypeError(node, token, left, right);
220 if ((!left->isInt32() || left->tag()) ||
221 (!right->isInt32() || right->tag()))
223 binaryTypeError(node, token, left, right);
231 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
233 if (type->isArray()) {
234 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
241 SemanticAnalysis::visitForLValue(Expression *expression)
243 if (expression->isIndexExpression()) {
244 Type *type = visitAndApplyType(expression);
248 if (type->isConst()) {
249 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
253 return type->contained();
256 if (!expression->isNameProxy()) {
257 cc_.reportError(expression->pos(), Message_ExpectedLValue);
261 NameProxy *proxy = expression->toNameProxy();
262 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
263 cc_.reportError(expression->pos(), Message_ExpectedLValue);
267 Variable *var = proxy->binding()->toVariable();
271 if (var->type()->isReference()) {
272 if (var->type()->isConst()) {
273 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
276 return var->type()->contained();
281 SemanticAnalysis::ControlStatus
282 SemanticAnalysis::visitForControl(Statement *statement)
284 ControlScope scope(&control_);
285 statement->accept(this);
286 return scope.status();
290 SemanticAnalysis::visit(NameProxy *name)
292 name->setType(name->binding()->type());
296 SemanticAnalysis::visit(Assignment *node)
298 Local<Type> exprType(zone_, visitForLoad(node->expression()));
302 Local<Type> type(zone_, visitForLValue(node->lvalue()));
306 if (node->token() != TOK_ASSIGN) {
307 if (!typeCheckBinary(node, node->token(), type, exprType))
311 if (!typeCheckAssignment(node, exprType, type, true))
318 SemanticAnalysis::visit(IncDecExpression *node)
320 Local<Type> type(zone_, visitForLValue(node->expression()));
324 assert(!type->isReference());
326 if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
327 unaryTypeError(node, node->token(), type);
335 SemanticAnalysis::visit(UnaryExpression *node)
337 Local<Type> type(zone_, visitForLoad(node->expression()));
341 switch (node->token())
344 assert(node->token() == TOK_TILDE);
345 if (!type->isInt32() || type->tag()) {
346 unaryTypeError(node, node->token(), type);
356 SemanticAnalysis::visit(BinaryExpression *node)
358 Local<Type> left(zone_, visitForLoad(node->left()));
359 Local<Type> right(zone_, visitForLoad(node->right()));
363 Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
367 node->setType(result);
371 SemanticAnalysis::visit(ReturnStatement *node)
373 // Set this early, so if we error we don't get more errors.
374 control_->returns(Returns_Always);
376 if (!node->expression()) {
377 if (!function_->returnType()->isVoid())
378 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
382 Local<Type> type(zone_, visitForLoad(node->expression()));
386 Local<Type> returnType(zone_, function_->returnType());
387 if (!typeCheckAssignment(node, type, returnType, true))
392 SemanticAnalysis::visit(ForStatement *node)
394 LoopScope loop(&loop_);
397 scope_ = node->scope();
399 if (node->initialization())
400 node->initialization()->accept(this);
402 if (node->condition()) {
403 Local<Type> type(zone_, visitForLoad(node->condition()));
404 if (!type || !canTest(node->condition(), type)) {
410 node->update()->accept(this);
412 ControlStatus status = visitForControl(node->body());
414 // If there is a condition, we treat this like a while loop. Otherwise,
415 // join point is only reachable if the loop contains a break. The
416 // termination status doesn't tell us anything yet.
417 if (node->condition() || loop.breaks())
418 control_->merge(status, ControlStatus(false, Returns_Never));
420 control_->terminate(status.returns());
423 scope_ = scope_->enclosing();
427 SemanticAnalysis::visit(WhileStatement *node)
429 LoopScope loop(&loop_);
431 Local<Type> type(zone_, visitForLoad(node->condition()));
432 if (!type || !canTest(node->condition(), type)) {
436 ControlStatus status = visitForControl(node->body());
438 // Detect loops that will always have a fork in the control-flow graph.
439 // This will be a |while| loop, or a |do-while| loop whose body does
442 // For now, we treat these as an |if| regardless of the direction the
443 // branch can take. That means the control-flow is always conditional.
444 if (node->token() == TOK_WHILE ||
445 !status.terminates() ||
448 control_->merge(status, ControlStatus(false, Returns_Never));
450 // At this point, we've got a do-while loop with a |return| or
451 // |continue|, meaning that the rest of the block is unreachable.
452 control_->terminate(status.returns());
457 SemanticAnalysis::visit(BlockStatement *node)
460 scope_ = node->scope();
461 for (size_t i = 0; i < node->statements()->length(); i++) {
462 Statement *statement = node->statements()->at(i);
463 statement->accept(this);
466 scope_ = scope_->enclosing();
470 SemanticAnalysis::visit(VariableDeclaration *node)
472 Local<String> tag(zone_, node->tag());
473 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
477 if (node->postDimensions()) {
478 Local<Type> init(zone_);
479 if (node->initialization()) {
480 if ((init = visitForLoad(node->initialization())) == NULL)
484 if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
485 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
489 // If we have an initializer, make sure it's the same type.
490 if (init && node->postDimensions()->length() != init->levels()) {
491 cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
495 Local<Type> check(zone_, init);
496 for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
497 Expression *expr = node->postDimensions()->at(i);
501 Local<Type> exprType(zone_, visitForLoad(expr));
505 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
506 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
511 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
514 cc_.reportError(expr->pos(), Message_BadArraySize);
517 if (size >= INT_MAX / sizeof(int)) {
518 cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
523 if (check->elements() == -1) {
524 cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
528 if (check->isCharArray()) {
529 if (check->elements() > size) {
530 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
533 } else if (check->elements() != size) {
534 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
540 cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
544 // here until we get dynamic array support.
545 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
549 // Infer the size from the initializer.
551 cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
554 if (init->elements() == -1) {
555 cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
558 size = init->elements();
561 type = zone_->types()->unsafeArray(type, size, false);
566 check = check->contained();
569 // Right now, any array is allowed on the LIFO heap. In case the
570 // runtime actually decides to use the LIFO heap, we must reserve
571 // a slot so we can unwind the heap when the current scope leaves.
572 scope_->setUsesLifoHeap();
574 if (node->initialization()) {
575 Local<Type> right(zone_, visitForLoad(node->initialization()));
578 if (!typeCheckAssignment(node, type, right, true))
581 if (type->primitive() == PrimitiveType_Char) {
582 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
587 node->variable()->setType(type);
591 SemanticAnalysis::visit(IntegerLiteral *node)
593 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
597 SemanticAnalysis::visit(ExpressionStatement *node)
599 visitAndApplyType(node->expression());
603 SemanticAnalysis::preanalyze(FunctionStatement *node)
605 Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
609 // Apply types to arguments.
610 for (size_t i = 0; i < node->parameters()->length(); i++) {
611 Parameter *parameter = node->parameters()->at(i);
613 Local<String> tag(zone_, parameter->tag());
614 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
618 if (parameter->reference()) {
619 if (parameter->dimensions()) {
620 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
624 type = zone_->types()->getReference(type, parameter->isConst());
627 } else if (parameter->dimensions()) {
628 if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
629 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
633 if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
634 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
638 for (size_t i = parameter->dimensions()->length() - 1;
639 i < parameter->dimensions()->length();
642 int size = Type::UNKNOWN_SIZE;
643 if (Expression *expr = parameter->dimensions()->at(i)) {
645 if (!EvaluateForConstant(expr, &box)) {
646 cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
652 type = zone_->types()->unsafeArray(type, size, parameter->isConst());
658 if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) ||
659 (type->isReference() && type->contained()->primitive() == PrimitiveType_Char))
661 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
665 args->set(zone_, i, type);
666 parameter->variable()->setType(type);
669 Local<Type> returnType(zone_);
670 if (node->hasExplicitReturn() || node->fun()->isNative())
671 returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
673 returnType = zone_->types()->getVoid();
677 Local<Type> funtype(zone_);
678 if (node->fun()->isNative())
679 funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic());
681 funtype = zone_->types()->newFunction(returnType, args);
685 // If the function already has a type, it was forward declared before, and
686 // now this is our chance to type check the second declaration.
687 if (node->fun()->type()) {
688 Local<Type> forward(zone_, node->fun()->type());
689 if (!Type::Compare(funtype, forward)) {
690 cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
693 node->fun()->setForwardType(forward);
696 node->fun()->setType(funtype);
702 SemanticAnalysis::visit(FunctionStatement *node)
704 function_ = node->fun()->type();
705 scope_ = node->scope();
707 ControlScope control(&control_);
709 node->body()->accept(this);
711 ControlStatus status = control.status();
712 if (status.returns() == Returns_Sometimes) {
713 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
714 } else if (status.returns() == Returns_Never) {
715 if (!function_->returnType()->isVoid())
716 cc_.reportError(node->pos(), Message_MissingReturnValue);
725 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
727 Local<Type> actual(zone_, argActual);
728 Local<Type> given(zone_, argGiven);
730 if (!given->isArray()) {
731 cc_.reportError(node->pos(), Message_ExpectedArray);
734 if (given->levels() != actual->levels()) {
735 cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
740 while (given->isArray()) {
741 if (actual->elements() != -1) {
743 if (given->elements() == -1 || actual->elements() == -1) {
744 cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
748 if (actual->isCharArray()) {
749 // String assignment can have a truncated |given|.
750 if (given->elements() > actual->elements()) {
751 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
755 if (given->elements() != actual->elements()) {
756 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
761 if (actual->elements() != -1 && given->elements() != actual->elements()) {
762 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
767 given = given->contained();
768 actual = actual->contained();
771 if (given->primitive() != actual->primitive()) {
772 // :TODO: leaks an interior pointer.
773 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
774 const char *actualTag = given->tag() ? given->tag()->chars() : "_";
775 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
783 SemanticAnalysis::typeCheckAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
785 Local<Type> actual(zone_, argActual);
786 Local<Type> given(zone_, argGiven);
788 if (actual->isArray())
789 return typeCheckArrayAssignment(node, given, actual, forAssign);
791 if (given->isArray()) {
792 cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
796 // The given type may not have been dereferenced.
797 if (given->isReference())
798 given = given->contained();
799 if (actual->isReference())
800 actual = actual->contained();
802 if (!given->isPrimitive() || !actual->isPrimitive()) {
803 cc_.reportError(node->pos(), Message_UnsupportedType);
807 if (given->primitive() != actual->primitive()) {
808 // :TODO: leaks an interior pointer
809 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
810 const char *actualTag = given->tag() ? given->tag()->chars() : "_";
811 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
819 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
821 return typeCheckAssignment(node, given, actual, false);
825 SemanticAnalysis::visit(CallExpression *node)
827 Local<Type> type(zone_, visitForLoad(node->callee()));
831 if (!type->isFunction()) {
832 cc_.reportError(node->pos(), Message_CalleeNotFunction);
835 if (node->arguments()->length() != type->parameters()->length()) {
836 if (!type->isNative() ||
837 !type->isNativeVariadic() ||
838 node->arguments()->length() < type->parameters()->length())
840 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
845 // Currently, only calls from a NameProxy are possible.
846 NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
847 if (fun->isForward()) {
848 cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
852 for (unsigned i = 0; i < node->arguments()->length(); i++) {
853 // Note: we don't compute references unless the callee needs a
855 Expression *expression = node->arguments()->at(i);
856 Local<Type> given(zone_, visitAndApplyType(expression));
860 // Since we skip a load, check for a call expression that returns void.
861 if (given->isVoid()) {
862 assert(expression->isCallExpression());
863 CallExpression *call = expression->toCallExpression();
864 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
868 // If it's an IndexExpression, we special case the ability to compute
870 if (expression->isIndexExpression())
871 given = given->contained();
873 bool mustComputeReference;
874 if (i >= type->parameters()->length()) {
875 // Special handling for natives. Arguments past the formal must
876 // always have references computed. However, arrays are already
877 // references for natives.
878 assert(type->isNative() && type->isNativeVariadic());
879 mustComputeReference = !given->isReference() && !given->isArray();
881 Local<Type> actual(zone_, type->parameterAt(i));
882 if (!typeCheckParameter(expression, given, actual))
884 mustComputeReference = actual->isReference() && !given->isReference();
887 // If the actual is a reference, and the given is not, we'll need to
888 // compute a reference, which may be allocated on the stack.
889 if (mustComputeReference)
890 scope_->setUsesLifoHeap();
893 node->setType(fun->type()->returnType());
897 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
899 // If both sides terminate in a return, we consider this a return as well.
900 if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
901 terminate(Returns_Always);
905 ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
909 if (left.terminates() && right.terminates())
916 SemanticAnalysis::visit(IfStatement *node)
918 Local<Type> type(zone_, visitForLoad(node->condition()));
922 if (!canTest(node, type))
925 ControlStatus trueBranch = visitForControl(node->ifTrue());
926 ControlStatus falseBranch = ControlStatus(false, Returns_Never);
929 falseBranch = visitForControl(node->ifFalse());
931 control_->merge(trueBranch, falseBranch);
935 SemanticAnalysis::visit(IndexExpression *node)
937 Local<Type> left(zone_, visitForLoad(node->left()));
938 Local<Type> right(zone_, visitForLoad(node->right()));
943 if (!right->isInt32()) {
944 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
947 if (!left->isArray()) {
948 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
955 SemanticAnalysis::visit(EnumStatement *node)
957 // Forbid the blessed types.
958 Local<String> tag(zone_, node->name());
959 if (!strcmp(tag->chars(), "Float") ||
960 !strcmp(tag->chars(), "String") ||
961 !strcmp(tag->chars(), "any") ||
962 !strcmp(tag->chars(), "bool"))
964 cc_.reportError(node->pos(), Message_InvalidEnumName);
968 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
973 for (size_t i = 0; i < node->entries()->length(); i++) {
974 EnumStatement::Entry &entry = node->entries()->at(i);
976 BoxedPrimitive box = BoxedPrimitive::Int(value);
978 entry.expr->accept(this);
979 if (!EvaluateForConstant(entry.expr, &box)) {
980 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
984 assert(box.type() == PrimitiveType_Int32);
988 entry.name->set(type, box);
994 SemanticAnalysis::visit(StringLiteral *node)
996 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
1000 type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
1004 node->setType(type);
1008 SemanticAnalysis::visit(FloatLiteral *node)
1010 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
1014 node->setType(type);
1018 SemanticAnalysis::visit(BreakStatement *node)
1021 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
1025 // Note: ignore breaks that occur in unreachable control-flow.
1026 if (!control_->status().terminates())
1029 control_->terminate(Returns_Never);
1033 SemanticAnalysis::visit(ContinueStatement *node)
1036 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
1040 // Note: ignore continues that occur in unreachable control-flow.
1041 if (!control_->status().terminates())
1042 loop_->addContinue();
1044 control_->terminate(Returns_Never);