@@ -1892,42 +1892,51 @@ void collect_type_info(const FunctionDecl* FD, QualType& QT,
18921892
18931893void make_narg_ctor (const FunctionDecl* FD, const unsigned N,
18941894 std::ostringstream& typedefbuf, std::ostringstream& callbuf,
1895- const std::string& class_name, int indent_level) {
1895+ const std::string& class_name, int indent_level,
1896+ bool array = false ) {
18961897 // Make a code string that follows this pattern:
18971898 //
18981899 // ClassName(args...)
1900+ // OR
1901+ // ClassName[nary] // array of objects
18991902 //
19001903
1901- callbuf << class_name << " (" ;
1902- for (unsigned i = 0U ; i < N; ++i) {
1903- const ParmVarDecl* PVD = FD->getParamDecl (i);
1904- QualType Ty = PVD->getType ();
1905- QualType QT = Ty.getCanonicalType ();
1906- std::string type_name;
1907- EReferenceType refType = kNotReference ;
1908- bool isPointer = false ;
1909- collect_type_info (FD, QT, typedefbuf, callbuf, type_name, refType,
1910- isPointer, indent_level, true );
1911- if (i) {
1912- callbuf << ' ,' ;
1913- if (i % 2 ) {
1914- callbuf << ' ' ;
1904+ if (array)
1905+ callbuf << class_name << " [nary]" ;
1906+ else
1907+ callbuf << class_name;
1908+ if (N) {
1909+ callbuf << " (" ;
1910+ for (unsigned i = 0U ; i < N; ++i) {
1911+ const ParmVarDecl* PVD = FD->getParamDecl (i);
1912+ QualType Ty = PVD->getType ();
1913+ QualType QT = Ty.getCanonicalType ();
1914+ std::string type_name;
1915+ EReferenceType refType = kNotReference ;
1916+ bool isPointer = false ;
1917+ collect_type_info (FD, QT, typedefbuf, callbuf, type_name, refType,
1918+ isPointer, indent_level, true );
1919+ if (i) {
1920+ callbuf << ' ,' ;
1921+ if (i % 2 ) {
1922+ callbuf << ' ' ;
1923+ } else {
1924+ callbuf << " \n " ;
1925+ indent (callbuf, indent_level);
1926+ }
1927+ }
1928+ if (refType != kNotReference ) {
1929+ callbuf << " (" << type_name.c_str ()
1930+ << (refType == kLValueReference ? " &" : " &&" ) << " )*("
1931+ << type_name.c_str () << " *)args[" << i << " ]" ;
1932+ } else if (isPointer) {
1933+ callbuf << " *(" << type_name.c_str () << " **)args[" << i << " ]" ;
19151934 } else {
1916- callbuf << " \n " ;
1917- indent (callbuf, indent_level + 1 );
1935+ callbuf << " *(" << type_name.c_str () << " *)args[" << i << " ]" ;
19181936 }
19191937 }
1920- if (refType != kNotReference ) {
1921- callbuf << " (" << type_name.c_str ()
1922- << (refType == kLValueReference ? " &" : " &&" ) << " )*("
1923- << type_name.c_str () << " *)args[" << i << " ]" ;
1924- } else if (isPointer) {
1925- callbuf << " *(" << type_name.c_str () << " **)args[" << i << " ]" ;
1926- } else {
1927- callbuf << " *(" << type_name.c_str () << " *)args[" << i << " ]" ;
1928- }
1938+ callbuf << " )" ;
19291939 }
1930- callbuf << " )" ;
19311940}
19321941
19331942const DeclContext* get_non_transparent_decl_context (const FunctionDecl* FD) {
@@ -2085,18 +2094,59 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
20852094 std::ostringstream& buf, int indent_level) {
20862095 // Make a code string that follows this pattern:
20872096 //
2088- // (*(ClassName**)ret) = (obj) ?
2089- // new (*(ClassName**)ret) ClassName(args...) : new ClassName(args...);
2090- //
2097+ // Array new if nary has been passed, and nargs is 0 (must be default ctor)
2098+ // if (nary) {
2099+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName[nary] :
2100+ // new ClassName[nary];
2101+ // }
2102+ // else {
2103+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName(args...)
2104+ // : new ClassName(args...);
2105+ // }
20912106 {
20922107 std::ostringstream typedefbuf;
20932108 std::ostringstream callbuf;
20942109 //
20952110 // Write the return value assignment part.
20962111 //
20972112 indent (callbuf, indent_level);
2113+ auto * CD = dyn_cast<CXXConstructorDecl>(FD);
2114+
2115+ // Activate this block only if array new is possible
2116+ // if (nary) {
2117+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName[nary]
2118+ // : new ClassName[nary];
2119+ // }
2120+ // else {
2121+ if (!CD->isDefaultConstructor () && CD->getNumParams () == 0 ) {
2122+ callbuf << " if (nary > 1) {\n " ;
2123+ indent (callbuf, indent_level);
2124+ callbuf << " (*(" << class_name << " **)ret) = " ;
2125+ callbuf << " (is_arena) ? new (*(" << class_name << " **)ret) " ;
2126+ make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level,
2127+ true );
2128+
2129+ callbuf << " : new " ;
2130+ //
2131+ // Write the actual expression.
2132+ //
2133+ make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level,
2134+ true );
2135+ //
2136+ // End the new expression statement.
2137+ //
2138+ callbuf << " ;\n " ;
2139+ indent (callbuf, indent_level);
2140+ callbuf << " }\n " ;
2141+ callbuf << " else {\n " ;
2142+ }
2143+
2144+ // Standard branch:
2145+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName(args...)
2146+ // : new ClassName(args...);
2147+ indent (callbuf, indent_level);
20982148 callbuf << " (*(" << class_name << " **)ret) = " ;
2099- callbuf << " (obj ) ? new (*(" << class_name << " **)ret) " ;
2149+ callbuf << " (is_arena ) ? new (*(" << class_name << " **)ret) " ;
21002150 make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level);
21012151
21022152 callbuf << " : new " ;
@@ -2108,6 +2158,10 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
21082158 // End the new expression statement.
21092159 //
21102160 callbuf << " ;\n " ;
2161+ indent (callbuf, --indent_level);
2162+ if (!CD->isDefaultConstructor () && CD->getNumParams () == 0 )
2163+ callbuf << " }\n " ;
2164+
21112165 //
21122166 // Output the whole new expression and return statement.
21132167 //
@@ -2620,8 +2674,14 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
26202674 " __attribute__((annotate(\" __cling__ptrcheck(off)\" )))\n "
26212675 " extern \" C\" void " ;
26222676 buf << wrapper_name;
2623- buf << " (void* obj, int nargs, void** args, void* ret)\n "
2624- " {\n " ;
2677+ if (Cpp::IsConstructor (FD)) {
2678+ buf << " (void* ret, unsigned long nary, unsigned long nargs, void** args, "
2679+ " void* is_arena)\n "
2680+ " {\n " ;
2681+ } else
2682+ buf << " (void* obj, unsigned long nargs, void** args, void* ret)\n "
2683+ " {\n " ;
2684+
26252685 ++indent_level;
26262686 if (min_args == num_params) {
26272687 // No parameters with defaults.
0 commit comments