@@ -1853,42 +1853,51 @@ void collect_type_info(const FunctionDecl* FD, QualType& QT,
18531853
18541854void make_narg_ctor (const FunctionDecl* FD, const unsigned N,
18551855 std::ostringstream& typedefbuf, std::ostringstream& callbuf,
1856- const std::string& class_name, int indent_level) {
1856+ const std::string& class_name, int indent_level,
1857+ bool array = false ) {
18571858 // Make a code string that follows this pattern:
18581859 //
18591860 // ClassName(args...)
1861+ // OR
1862+ // ClassName[nary] // array of objects
18601863 //
18611864
1862- callbuf << class_name << " (" ;
1863- for (unsigned i = 0U ; i < N; ++i) {
1864- const ParmVarDecl* PVD = FD->getParamDecl (i);
1865- QualType Ty = PVD->getType ();
1866- QualType QT = Ty.getCanonicalType ();
1867- std::string type_name;
1868- EReferenceType refType = kNotReference ;
1869- bool isPointer = false ;
1870- collect_type_info (FD, QT, typedefbuf, callbuf, type_name, refType,
1871- isPointer, indent_level, true );
1872- if (i) {
1873- callbuf << ' ,' ;
1874- if (i % 2 ) {
1875- callbuf << ' ' ;
1865+ if (array)
1866+ callbuf << class_name << " [nary]" ;
1867+ else
1868+ callbuf << class_name;
1869+ if (N) {
1870+ callbuf << " (" ;
1871+ for (unsigned i = 0U ; i < N; ++i) {
1872+ const ParmVarDecl* PVD = FD->getParamDecl (i);
1873+ QualType Ty = PVD->getType ();
1874+ QualType QT = Ty.getCanonicalType ();
1875+ std::string type_name;
1876+ EReferenceType refType = kNotReference ;
1877+ bool isPointer = false ;
1878+ collect_type_info (FD, QT, typedefbuf, callbuf, type_name, refType,
1879+ isPointer, indent_level, true );
1880+ if (i) {
1881+ callbuf << ' ,' ;
1882+ if (i % 2 ) {
1883+ callbuf << ' ' ;
1884+ } else {
1885+ callbuf << " \n " ;
1886+ indent (callbuf, indent_level);
1887+ }
1888+ }
1889+ if (refType != kNotReference ) {
1890+ callbuf << " (" << type_name.c_str ()
1891+ << (refType == kLValueReference ? " &" : " &&" ) << " )*("
1892+ << type_name.c_str () << " *)args[" << i << " ]" ;
1893+ } else if (isPointer) {
1894+ callbuf << " *(" << type_name.c_str () << " **)args[" << i << " ]" ;
18761895 } else {
1877- callbuf << " \n " ;
1878- indent (callbuf, indent_level + 1 );
1896+ callbuf << " *(" << type_name.c_str () << " *)args[" << i << " ]" ;
18791897 }
18801898 }
1881- if (refType != kNotReference ) {
1882- callbuf << " (" << type_name.c_str ()
1883- << (refType == kLValueReference ? " &" : " &&" ) << " )*("
1884- << type_name.c_str () << " *)args[" << i << " ]" ;
1885- } else if (isPointer) {
1886- callbuf << " *(" << type_name.c_str () << " **)args[" << i << " ]" ;
1887- } else {
1888- callbuf << " *(" << type_name.c_str () << " *)args[" << i << " ]" ;
1889- }
1899+ callbuf << " )" ;
18901900 }
1891- callbuf << " )" ;
18921901}
18931902
18941903const DeclContext* get_non_transparent_decl_context (const FunctionDecl* FD) {
@@ -2040,16 +2049,57 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
20402049 std::ostringstream& buf, int indent_level) {
20412050 // Make a code string that follows this pattern:
20422051 //
2043- // (*(ClassName**)ret) = (obj) ?
2044- // new (*(ClassName**)ret) ClassName(args...) : new ClassName(args...);
2045- //
2052+ // Array new if nary has been passed, and nargs is 0 (must be default ctor)
2053+ // if (nary) {
2054+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName[nary] :
2055+ // new ClassName[nary];
2056+ // }
2057+ // else {
2058+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName(args...)
2059+ // : new ClassName(args...);
2060+ // }
20462061 {
20472062 std::ostringstream typedefbuf;
20482063 std::ostringstream callbuf;
20492064 //
20502065 // Write the return value assignment part.
20512066 //
20522067 indent (callbuf, indent_level);
2068+ auto * CD = dyn_cast<CXXConstructorDecl>(FD);
2069+
2070+ // Activate this block only if array new is possible
2071+ // if (nary) {
2072+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName[nary]
2073+ // : new ClassName[nary];
2074+ // }
2075+ // else {
2076+ if (!CD->isDefaultConstructor () and CD->getNumParams () == 0 ) {
2077+ callbuf << " if (nary > 1) {\n " ;
2078+ indent (callbuf, indent_level);
2079+ callbuf << " (*(" << class_name << " **)ret) = " ;
2080+ callbuf << " (obj) ? new (*(" << class_name << " **)ret) " ;
2081+ make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level,
2082+ true );
2083+
2084+ callbuf << " : new " ;
2085+ //
2086+ // Write the actual expression.
2087+ //
2088+ make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level,
2089+ true );
2090+ //
2091+ // End the new expression statement.
2092+ //
2093+ callbuf << " ;\n " ;
2094+ indent (callbuf, indent_level);
2095+ callbuf << " }\n " ;
2096+ callbuf << " else {\n " ;
2097+ }
2098+
2099+ // Standard branch:
2100+ // (*(ClassName**)ret) = (obj) ? new (*(ClassName**)ret) ClassName(args...)
2101+ // : new ClassName(args...);
2102+ indent (callbuf, indent_level);
20532103 callbuf << " (*(" << class_name << " **)ret) = " ;
20542104 callbuf << " (obj) ? new (*(" << class_name << " **)ret) " ;
20552105 make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level);
@@ -2063,6 +2113,10 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
20632113 // End the new expression statement.
20642114 //
20652115 callbuf << " ;\n " ;
2116+ indent (callbuf, --indent_level);
2117+ if (!CD->isDefaultConstructor () and CD->getNumParams () == 0 )
2118+ callbuf << " }\n " ;
2119+
20662120 //
20672121 // Output the whole new expression and return statement.
20682122 //
@@ -2575,7 +2629,8 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
25752629 " __attribute__((annotate(\" __cling__ptrcheck(off)\" )))\n "
25762630 " extern \" C\" void " ;
25772631 buf << wrapper_name;
2578- buf << " (void* obj, int nargs, void** args, void* ret)\n "
2632+ buf << " (void* obj, unsigned long nargs, void** args, void* ret, unsigned "
2633+ " long nary)\n "
25792634 " {\n " ;
25802635 ++indent_level;
25812636 if (min_args == num_params) {
0 commit comments