| 1810 | } |
| 1811 | |
| 1812 | FunctionPtr makeCloneVariant ( const LineInfo & at, const TypeDeclPtr & variantType, bool fromConst ) { |
| 1813 | DAS_ASSERT(variantType->isVariant() && "can only clone variant"); |
| 1814 | auto fn = new Function(); |
| 1815 | fn->generated = true; |
| 1816 | fn->safeImplicit = true; |
| 1817 | fn->privateFunction = true; |
| 1818 | fn->name = "clone"; |
| 1819 | fn->at = fn->atDecl = at; |
| 1820 | fn->result = new TypeDecl(Type::tVoid); |
| 1821 | auto arg0 = new Variable(); |
| 1822 | arg0->at = at; |
| 1823 | arg0->name = "dest"; |
| 1824 | arg0->type = new TypeDecl(*variantType); |
| 1825 | arg0->type->constant = false; |
| 1826 | arg0->type->explicitConst = false; |
| 1827 | arg0->type->ref = false; |
| 1828 | fn->arguments.push_back(arg0); |
| 1829 | auto arg1 = new Variable(); |
| 1830 | arg1->at = at; |
| 1831 | arg1->name = "src"; |
| 1832 | arg1->type = new TypeDecl(*variantType); |
| 1833 | arg1->type->constant = fromConst; |
| 1834 | arg1->type->explicitConst = true; |
| 1835 | arg1->type->ref = false; |
| 1836 | arg1->type->implicit = true; |
| 1837 | fn->arguments.push_back(arg1); |
| 1838 | auto block = new ExprBlock(); |
| 1839 | block->at = at; |
| 1840 | ExprIfThenElse * topIf = nullptr; |
| 1841 | ExprIfThenElse * lastIf = nullptr; |
| 1842 | for ( size_t argi=0, argis=variantType->argTypes.size(); argi!=argis; ++argi ) { |
| 1843 | const string & argn = variantType->argNames[argi]; |
| 1844 | auto cb = new ExprBlock(); |
| 1845 | cb->at = at; |
| 1846 | auto vd = new ExprVar(at, "dest"); |
| 1847 | auto vi = new ExprConstInt(at, int32_t(argi)); |
| 1848 | auto svi = new ExprCall(at, "set_variant_index"); |
| 1849 | svi->alwaysSafe = true; |
| 1850 | svi->arguments.push_back(vd); |
| 1851 | svi->arguments.push_back(vi); |
| 1852 | cb->list.push_back(svi); |
| 1853 | auto lv = new ExprVar(at, "dest"); |
| 1854 | auto lf = new ExprField(at, lv, argn); |
| 1855 | lf->alwaysSafe = true; |
| 1856 | auto rv = new ExprVar(at, "src"); |
| 1857 | auto rf = new ExprField(at, rv, argn); |
| 1858 | rf->alwaysSafe = true; |
| 1859 | auto cl = new ExprClone(at, lf, rf); |
| 1860 | cb->list.push_back(cl); |
| 1861 | auto av = new ExprVar(at, "src"); |
| 1862 | auto isv = new ExprIsVariant(at, av, argn); |
| 1863 | auto thisIf = new ExprIfThenElse(at, isv, cb, nullptr); |
| 1864 | if ( lastIf ) { |
| 1865 | lastIf->if_false = thisIf; |
| 1866 | lastIf = thisIf; |
| 1867 | } else { |
| 1868 | topIf = lastIf = thisIf; |
| 1869 | } |
no test coverage detected