compiler/resolution/functionResolution.cpp
// Remove most uses of void variables and fields
Remove most uses of void variables and fields
Remove most uses of void variables and fields
forv_Vec(CallExpr, call, gCallExprs) {
    if (call->inTree()) {
      if (call->isPrimitive(PRIM_MOVE)) {
        if (isVoidOrVoidTupleType(call->get(2)->typeInfo()) ||
            call->get(2)->typeInfo() == dtVoid->refType) {
          INT_ASSERT(call->get(1)->typeInfo() == call->get(2)->typeInfo());
          if (CallExpr* rhs = toCallExpr(call->get(2))) {
            if (rhs->isPrimitive(PRIM_DEREF) ||
                rhs->isPrimitive(PRIM_GET_MEMBER) ||
                rhs->isPrimitive(PRIM_GET_MEMBER_VALUE)) {
              call->remove();
            } else {
              Expr* rmRhs = rhs->remove();
              call->insertBefore(rmRhs);
              call->remove();
            }
          } else if (isSymExpr(call->get(2))) {
            call->remove();
          }
        }
      } else if (call->isPrimitive(PRIM_SET_MEMBER)) {
        if (isVoidOrVoidTupleType(call->get(3)->typeInfo())) {
          INT_ASSERT(call->get(2)->typeInfo() == call->get(3)->typeInfo());
          if (CallExpr* rhs = toCallExpr(call->get(2))) {
            Expr* rmRhs = rhs->remove();
            call->insertBefore(rmRhs);
            call->remove();
          } else if (isSymExpr(call->get(2))) {
            call->remove();
          }
        }
      } else if (call->isPrimitive(PRIM_RETURN)) {
        if (isVoidOrVoidTupleType(call->get(1)->typeInfo()) ||
            call->get(1)->typeInfo() == dtVoid->refType) {
          if (SymExpr* ret = toSymExpr(call->get(1))) {
            if (ret->symbol() != gVoid) {
              SET_LINENO(call);
              call->replace(new CallExpr(PRIM_RETURN, gVoid));
            }
          }
        }
      } else if (call->isPrimitive(PRIM_YIELD)) {
        if (isVoidOrVoidTupleType(call->get(1)->typeInfo()) ||
            call->get(1)->typeInfo() == dtVoid->refType) {
          if (SymExpr* ret = toSymExpr(call->get(1))) {
            if (ret->symbol() != gVoid) {
              SET_LINENO(call);
              call->replace(new CallExpr(PRIM_YIELD, gVoid));
            }
          }
        }
      } else if (call->isPrimitive(PRIM_CALL_DESTRUCTOR)) {
        if (isVoidOrVoidTupleType(call->get(1)->typeInfo())) {
          call->remove();
        }
      }
      if (FnSymbol* fn = call->resolvedFunction()) {
        bool seenVoid = false;
        for_actuals(actual, call) {
          if (isVoidOrVoidTupleType(actual->typeInfo())) {
            actual->remove();
            seenVoid = true;
          }
        }
        if (seenVoid && fn->hasFlag(FLAG_AUTO_DESTROY_FN)) {
          INT_ASSERT(call->numActuals() == 0);
          call->remove();
        }
      }
    }
  }
forv_Vec ( CallExpr , call , gCallExprs ) { if ( call -> inTree ( ) ) { if ( call -> isPrimitive ( PRIM_MOVE ) ) { if ( isVoidOrVoidTupleType ( call -> get ( 2 ) -> typeInfo ( ) ) || call -> get ( 2 ) -> typeInfo ( ) == dtVoid -> refType ) { INT_ASSERT ( call -> get ( 1 ) -> typeInfo ( ) == call -> get ( 2 ) -> typeInfo ( ) ) ; if ( CallExpr * rhs = toCallExpr ( call -> get ( 2 ) ) ) { if ( rhs -> isPrimitive ( PRIM_DEREF ) || rhs -> isPrimitive ( PRIM_GET_MEMBER ) || rhs -> isPrimitive ( PRIM_GET_MEMBER_VALUE ) ) { call -> remove ( ) ; } else { Expr * rmRhs = rhs -> remove ( ) ; call -> insertBefore ( rmRhs ) ; call -> remove ( ) ; } } else if ( isSymExpr ( call -> get ( 2 ) ) ) { call -> remove ( ) ; } } } else if ( call -> isPrimitive ( PRIM_SET_MEMBER ) ) { if ( isVoidOrVoidTupleType ( call -> get ( 3 ) -> typeInfo ( ) ) ) { INT_ASSERT ( call -> get ( 2 ) -> typeInfo ( ) == call -> get ( 3 ) -> typeInfo ( ) ) ; if ( CallExpr * rhs = toCallExpr ( call -> get ( 2 ) ) ) { Expr * rmRhs = rhs -> remove ( ) ; call -> insertBefore ( rmRhs ) ; call -> remove ( ) ; } else if ( isSymExpr ( call -> get ( 2 ) ) ) { call -> remove ( ) ; } } } else if ( call -> isPrimitive ( PRIM_RETURN ) ) { if ( isVoidOrVoidTupleType ( call -> get ( 1 ) -> typeInfo ( ) ) || call -> get ( 1 ) -> typeInfo ( ) == dtVoid -> refType ) { if ( SymExpr * ret = toSymExpr ( call -> get ( 1 ) ) ) { if ( ret -> symbol ( ) != gVoid ) { SET_LINENO ( call ) ; call -> replace ( new CallExpr ( PRIM_RETURN , gVoid ) ) ; } } } } else if ( call -> isPrimitive ( PRIM_YIELD ) ) { if ( isVoidOrVoidTupleType ( call -> get ( 1 ) -> typeInfo ( ) ) || call -> get ( 1 ) -> typeInfo ( ) == dtVoid -> refType ) { if ( SymExpr * ret = toSymExpr ( call -> get ( 1 ) ) ) { if ( ret -> symbol ( ) != gVoid ) { SET_LINENO ( call ) ; call -> replace ( new CallExpr ( PRIM_YIELD , gVoid ) ) ; } } } } else if ( call -> isPrimitive ( PRIM_CALL_DESTRUCTOR ) ) { if ( isVoidOrVoidTupleType ( call -> get ( 1 ) -> typeInfo ( ) ) ) { call -> remove ( ) ; } } if ( FnSymbol * fn = call -> resolvedFunction ( ) ) { bool seenVoid = false ; for_actuals ( actual , call ) { if ( isVoidOrVoidTupleType ( actual -> typeInfo ( ) ) ) { actual -> remove ( ) ; seenVoid = true ; } } if ( seenVoid && fn -> hasFlag ( FLAG_AUTO_DESTROY_FN ) ) { INT_ASSERT ( call -> numActuals ( ) == 0 ) ; call -> remove ( ) ; } } } }
Remove most uses of void variables and fields
Remove most uses of void variables and fields
// Remove moves where the rhs has type void. If the rhs is a // call to something other than a few primitives, still make // that call, just don't move the result into anything. // Remove set_member(a, void, void) calls // Change functions that return void to use the global // void value instead of a local void. // Change iterators that yield void to use the global // void value instead of a local void. // Remove calls to destructors for homogeneous tuples of void // Remove actual arguments that are void from function calls // A 0-arg call to autoDestroy would upset later passes.