@@ -1885,42 +1885,51 @@ void collect_type_info(const FunctionDecl* FD, QualType& QT,
18851885
18861886void make_narg_ctor (const FunctionDecl* FD, const unsigned N,
18871887 std::ostringstream& typedefbuf, std::ostringstream& callbuf,
1888- const std::string& class_name, int indent_level) {
1888+ const std::string& class_name, int indent_level,
1889+ bool array = false ) {
18891890 // Make a code string that follows this pattern:
18901891 //
18911892 // ClassName(args...)
1893+ // OR
1894+ // ClassName[nary] // array of objects
18921895 //
18931896
1894- callbuf << class_name << " (" ;
1895- for (unsigned i = 0U ; i < N; ++i) {
1896- const ParmVarDecl* PVD = FD->getParamDecl (i);
1897- QualType Ty = PVD->getType ();
1898- QualType QT = Ty.getCanonicalType ();
1899- std::string type_name;
1900- EReferenceType refType = kNotReference ;
1901- bool isPointer = false ;
1902- collect_type_info (FD, QT, typedefbuf, callbuf, type_name, refType,
1903- isPointer, indent_level, true );
1904- if (i) {
1905- callbuf << ' ,' ;
1906- if (i % 2 ) {
1907- callbuf << ' ' ;
1897+ if (array)
1898+ callbuf << class_name << " [nary]" ;
1899+ else
1900+ callbuf << class_name;
1901+ if (N) {
1902+ callbuf << " (" ;
1903+ for (unsigned i = 0U ; i < N; ++i) {
1904+ const ParmVarDecl* PVD = FD->getParamDecl (i);
1905+ QualType Ty = PVD->getType ();
1906+ QualType QT = Ty.getCanonicalType ();
1907+ std::string type_name;
1908+ EReferenceType refType = kNotReference ;
1909+ bool isPointer = false ;
1910+ collect_type_info (FD, QT, typedefbuf, callbuf, type_name, refType,
1911+ isPointer, indent_level, true );
1912+ if (i) {
1913+ callbuf << ' ,' ;
1914+ if (i % 2 ) {
1915+ callbuf << ' ' ;
1916+ } else {
1917+ callbuf << " \n " ;
1918+ indent (callbuf, indent_level);
1919+ }
1920+ }
1921+ if (refType != kNotReference ) {
1922+ callbuf << " (" << type_name.c_str ()
1923+ << (refType == kLValueReference ? " &" : " &&" ) << " )*("
1924+ << type_name.c_str () << " *)args[" << i << " ]" ;
1925+ } else if (isPointer) {
1926+ callbuf << " *(" << type_name.c_str () << " **)args[" << i << " ]" ;
19081927 } else {
1909- callbuf << " \n " ;
1910- indent (callbuf, indent_level + 1 );
1928+ callbuf << " *(" << type_name.c_str () << " *)args[" << i << " ]" ;
19111929 }
19121930 }
1913- if (refType != kNotReference ) {
1914- callbuf << " (" << type_name.c_str ()
1915- << (refType == kLValueReference ? " &" : " &&" ) << " )*("
1916- << type_name.c_str () << " *)args[" << i << " ]" ;
1917- } else if (isPointer) {
1918- callbuf << " *(" << type_name.c_str () << " **)args[" << i << " ]" ;
1919- } else {
1920- callbuf << " *(" << type_name.c_str () << " *)args[" << i << " ]" ;
1921- }
1931+ callbuf << " )" ;
19221932 }
1923- callbuf << " )" ;
19241933}
19251934
19261935const DeclContext* get_non_transparent_decl_context (const FunctionDecl* FD) {
@@ -2072,18 +2081,59 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
20722081 std::ostringstream& buf, int indent_level) {
20732082 // Make a code string that follows this pattern:
20742083 //
2075- // (*(ClassName**)ret) = (obj) ?
2076- // new (*(ClassName**)ret) ClassName(args...) : new ClassName(args...);
2077- //
2084+ // Array new if nary has been passed, and nargs is 0 (must be default ctor)
2085+ // if (nary) {
2086+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName[nary] :
2087+ // new ClassName[nary];
2088+ // }
2089+ // else {
2090+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName(args...)
2091+ // : new ClassName(args...);
2092+ // }
20782093 {
20792094 std::ostringstream typedefbuf;
20802095 std::ostringstream callbuf;
20812096 //
20822097 // Write the return value assignment part.
20832098 //
20842099 indent (callbuf, indent_level);
2100+ auto * CD = dyn_cast<CXXConstructorDecl>(FD);
2101+
2102+ // Activate this block only if array new is possible
2103+ // if (nary) {
2104+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName[nary]
2105+ // : new ClassName[nary];
2106+ // }
2107+ // else {
2108+ if (!CD->isDefaultConstructor () && CD->getNumParams () == 0 ) {
2109+ callbuf << " if (nary > 1) {\n " ;
2110+ indent (callbuf, indent_level);
2111+ callbuf << " (*(" << class_name << " **)ret) = " ;
2112+ callbuf << " (is_arena) ? new (*(" << class_name << " **)ret) " ;
2113+ make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level,
2114+ true );
2115+
2116+ callbuf << " : new " ;
2117+ //
2118+ // Write the actual expression.
2119+ //
2120+ make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level,
2121+ true );
2122+ //
2123+ // End the new expression statement.
2124+ //
2125+ callbuf << " ;\n " ;
2126+ indent (callbuf, indent_level);
2127+ callbuf << " }\n " ;
2128+ callbuf << " else {\n " ;
2129+ }
2130+
2131+ // Standard branch:
2132+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName(args...)
2133+ // : new ClassName(args...);
2134+ indent (callbuf, indent_level);
20852135 callbuf << " (*(" << class_name << " **)ret) = " ;
2086- callbuf << " (obj ) ? new (*(" << class_name << " **)ret) " ;
2136+ callbuf << " (is_arena ) ? new (*(" << class_name << " **)ret) " ;
20872137 make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level);
20882138
20892139 callbuf << " : new " ;
@@ -2095,6 +2145,10 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
20952145 // End the new expression statement.
20962146 //
20972147 callbuf << " ;\n " ;
2148+ indent (callbuf, --indent_level);
2149+ if (!CD->isDefaultConstructor () && CD->getNumParams () == 0 )
2150+ callbuf << " }\n " ;
2151+
20982152 //
20992153 // Output the whole new expression and return statement.
21002154 //
@@ -2607,8 +2661,14 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
26072661 " __attribute__((annotate(\" __cling__ptrcheck(off)\" )))\n "
26082662 " extern \" C\" void " ;
26092663 buf << wrapper_name;
2610- buf << " (void* obj, int nargs, void** args, void* ret)\n "
2611- " {\n " ;
2664+ if (Cpp::IsConstructor (FD)) {
2665+ buf << " (void* ret, unsigned long nary, unsigned long nargs, void** args, "
2666+ " void* is_arena)\n "
2667+ " {\n " ;
2668+ } else
2669+ buf << " (void* obj, unsigned long nargs, void** args, void* ret)\n "
2670+ " {\n " ;
2671+
26122672 ++indent_level;
26132673 if (min_args == num_params) {
26142674 // No parameters with defaults.
0 commit comments