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

Function generateVariantFinalizer

src/ast/ast_generate.cpp:1877–1936  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1875 }
1876
1877 FunctionPtr generateVariantFinalizer ( const LineInfo & at, const TypeDeclPtr & variantType ) {
1878 DAS_ASSERT(variantType->isVariant() && "can only finalize variant");
1879 auto fn = new Function();
1880 fn->privateFunction = true;
1881 fn->generated = true;
1882 fn->name = "finalize";
1883 fn->at = fn->atDecl = at;
1884 fn->result = new TypeDecl(Type::tVoid);
1885 auto arg0 = new Variable();
1886 arg0->at = at;
1887 arg0->name = "__this";
1888 arg0->type = new TypeDecl(*variantType);
1889 arg0->type->constant = false;
1890 arg0->type->ref = false;
1891 arg0->type->isExplicit = true;
1892 fn->arguments.push_back(arg0);
1893 auto block = new ExprBlock();
1894 block->at = at;
1895 ExprIfThenElse * topIf = nullptr;
1896 ExprIfThenElse * lastIf = nullptr;
1897 bool needUnsafe = false;
1898 for ( size_t argi=0, argis=variantType->argTypes.size(); argi!=argis; ++argi ) {
1899 if ( !variantType->argTypes[argi]->constant && variantType->argTypes[argi]->needDelete() ) {
1900 if ( variantType->argTypes[argi]->isPointer() && variantType->argTypes[argi]->firstType
1901 && variantType->argTypes[argi]->firstType->constant ) continue;
1902 const string & argn = variantType->argNames[argi];
1903 auto lv = new ExprVar(at, "__this");
1904 auto lf = new ExprField(at, lv, argn);
1905 lf->alwaysSafe = true;
1906 auto cl = new ExprDelete(at, lf);
1907 cl->alwaysSafe = true;
1908 auto cb = new ExprBlock();
1909 cb->at = at;
1910 cb->list.push_back(cl);
1911 auto av = new ExprVar(at, "__this");
1912 auto isv = new ExprIsVariant(at, av, argn);
1913 auto thisIf = new ExprIfThenElse(at, isv, cb, nullptr);
1914 if ( lastIf ) {
1915 lastIf->if_false = thisIf;
1916 lastIf = thisIf;
1917 } else {
1918 topIf = lastIf = thisIf;
1919 }
1920 if ( variantType->argTypes[argi]->isPointer() ) {
1921 needUnsafe = true;
1922 }
1923 }
1924 }
1925 if (topIf) block->list.push_back(topIf);
1926 auto mz = new ExprMemZero(at, "memzero");
1927 auto lvar = new ExprVar(at, "__this");
1928 mz->arguments.push_back(lvar);
1929 block->list.push_back(mz);
1930 fn->body = block;
1931 if ( needUnsafe ) {
1932 wrapInUnsafe(fn);
1933 }
1934 verifyGenerated(fn->body);

Callers 1

visitMethod · 0.85

Calls 7

wrapInUnsafeFunction · 0.85
verifyGeneratedFunction · 0.85
isVariantMethod · 0.80
isPointerMethod · 0.80
push_backMethod · 0.45
sizeMethod · 0.45
needDeleteMethod · 0.45

Tested by

no test coverage detected