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(); }
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(); }
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)); } } } }