Example #1
0
static void addCloneOfInitBlock(Expr* aInit, SymbolMap& map, ShadowVarSymbol* svar) {
  //
  // We have to clone IB as a whole. This is to ensure that the uses
  // of any symbols that the original IB defines (via DefExprs
  // within that IB) get converted to uses of these symbols' copies.
  //
  BlockStmt* copyIB = svar->initBlock()->copy(&map);
  aInit->insertBefore(copyIB);
  // Let's drop the BlockStmt wrapper, to simplify the AST.
  copyIB->flattenAndRemove();
}
Example #2
0
static void addCloneOfDeinitBlock(Expr* aFini, SymbolMap& map, ShadowVarSymbol* svar) {
  BlockStmt* copyDB = svar->deinitBlock()->copy(&map);
  aFini->insertAfter(copyDB);
  // Let's drop the BlockStmt wrapper, to simplify the AST.
  copyDB->flattenAndRemove();
}
Example #3
0
void AutoDestroyScope::variablesDestroy(Expr*      refStmt,
                                        VarSymbol* excludeVar,
                                        std::set<VarSymbol*>* ignored) const {
  // Handle the primary locals
  if (mLocalsHandled == false) {
    Expr*  insertBeforeStmt = refStmt;
    Expr*  noop             = NULL;
    size_t count            = mLocalsAndDefers.size();

    // If this is a simple nested block, insert after the final stmt
    // But always insert the destruction calls in reverse declaration order.
    // Do not get tricked by sequences of unreachable code
    if (refStmt->next == NULL) {
      if (mParent != NULL && isGotoStmt(refStmt) == false) {
        SET_LINENO(refStmt);
        // Add a PRIM_NOOP to insert before
        noop = new CallExpr(PRIM_NOOP);
        refStmt->insertAfter(noop);
        insertBeforeStmt = noop;
      }
    }

    for (size_t i = 1; i <= count; i++) {
      BaseAST*  localOrDefer = mLocalsAndDefers[count - i];
      VarSymbol* var = toVarSymbol(localOrDefer);
      DeferStmt* defer = toDeferStmt(localOrDefer);
      // This code only handles VarSymbols and DeferStmts.
      // It handles both in one vector because the order
      // of interleaving matters.
      INT_ASSERT(var || defer);

      if (var != NULL && var != excludeVar &&
          (ignored == NULL || ignored->count(var) == 0)) {
        if (FnSymbol* autoDestroyFn = autoDestroyMap.get(var->type)) {
          SET_LINENO(var);

          INT_ASSERT(autoDestroyFn->hasFlag(FLAG_AUTO_DESTROY_FN));

          CallExpr* autoDestroy = new CallExpr(autoDestroyFn, var);

          insertBeforeStmt->insertBefore(autoDestroy);
        }
      }

      if (defer != NULL) {
        SET_LINENO(defer);
        BlockStmt* deferBlockCopy = defer->body()->copy();
        insertBeforeStmt->insertBefore(deferBlockCopy);
        deferBlockCopy->flattenAndRemove();
      }
    }

    // remove the PRIM_NOOP if we added one.
    if (noop != NULL)
      noop->remove();
  }

  // Handle the formal temps
  if (isReturnStmt(refStmt) == true) {
    size_t count = mFormalTemps.size();

    for (size_t i = 1; i <= count; i++) {
      VarSymbol* var = mFormalTemps[count - i];

      if (FnSymbol* autoDestroyFn = autoDestroyMap.get(var->type)) {
        SET_LINENO(var);

        refStmt->insertBefore(new CallExpr(autoDestroyFn, var));
      }
    }
  }
}