MCPcopy Create free account
hub / github.com/GaijinEntertainment/daScript / generateStructureFinalizer

Function generateStructureFinalizer

src/ast/ast_generate.cpp:526–596  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

524 }
525
526 FunctionPtr generateStructureFinalizer ( const StructurePtr & ls ) {
527 auto pFunc = new Function();
528 pFunc->privateFunction = true;
529 pFunc->generated = true;
530 pFunc->at = pFunc->atDecl = ls->at;
531 pFunc->name = "finalize";
532 if ( ls->isClass ) {
533 pFunc->isClassMethod = true;
534 pFunc->classParent = ls;
535 DAS_ASSERT(pFunc->classParent);
536 }
537 if ( ls->macroInterface ) pFunc->macroFunction = true;
538 auto fb = new ExprBlock();
539 fb->at = ls->at;
540 // For a class whose ancestry has a user finalizer, chain to the immediate
541 // parent: this finalizer owns only its own slice of the fields (everything
542 // past the parent prefix), then `delete cast<Parent>(__this)` runs the
543 // parent's finalize — the user one, or a generated chain finalizer that
544 // recurses the same way. Derived slice first, parent second (dtor order).
545 Structure * chainParent = ( ls->isClass && findChainFinalizerAncestor(ls) ) ? ls->parent : nullptr;
546 size_t firstOwnField = chainParent ? chainParent->fields.size() : 0;
547 // now finalize
548 bool needUnsafe = false;
549 for ( int stage=0; stage!=2; ++stage ) {
550 // stage 0 is iterators, stage 1 is everything else
551 for ( size_t fi=firstOwnField, fis=ls->fields.size(); fi!=fis; ++fi ) {
552 const auto & fl = ls->fields[fi];
553 if ( !fl.type->constant && !fl.capturedConstant && fl.type->needDelete() ) {
554 if ( !fl.doNotDelete && !fl.capturedRef ) {
555 if ( stage==0 && !fl.type->isIterator() ) continue;
556 if ( stage==1 && fl.type->isIterator() ) continue;
557 if ( fl.type->isPointer() && fl.type->firstType && fl.type->firstType->constant ) continue;
558 if ( ls->isLambda && !fl.type->isSafeToDelete() ) continue; // we don't do unsafe delete for lambda
559 auto fva = new ExprVar(fl.at, "__this");
560 auto fld = new ExprField(fl.at, fva, fl.name);
561 fld->ignoreCaptureConst = true;
562 auto delf = new ExprDelete(fl.at, fld);
563 delf->alwaysSafe = true;
564 fb->list.emplace_back(delf);
565 if ( fl.type->isPointer() ) {
566 needUnsafe = true;
567 }
568 }
569 }
570 }
571 }
572 if ( chainParent ) {
573 auto chthis = new ExprVar(ls->at, "__this");
574 auto chcast = new ExprCast(ls->at, chthis, new TypeDecl(chainParent));
575 auto chdel = new ExprDelete(ls->at, chcast);
576 chdel->alwaysSafe = true;
577 fb->list.push_back(chdel);
578 }
579 auto mz = new ExprMemZero(ls->at, "memzero");
580 auto lvar = new ExprVar(ls->at, "__this");
581 mz->arguments.push_back(lvar);
582 fb->list.push_back(mz);
583 pFunc->body = fb;

Callers 1

visitMethod · 0.85

Calls 9

wrapInUnsafeFunction · 0.85
verifyGeneratedFunction · 0.85
isIteratorMethod · 0.80
isPointerMethod · 0.80
sizeMethod · 0.45
needDeleteMethod · 0.45
isSafeToDeleteMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected