@@ -1853,42 +1853,51 @@ void collect_type_info(const FunctionDecl* FD, QualType& QT,
1853
1853
1854
1854
void make_narg_ctor (const FunctionDecl* FD, const unsigned N,
1855
1855
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 ) {
1857
1858
// Make a code string that follows this pattern:
1858
1859
//
1859
1860
// ClassName(args...)
1861
+ // OR
1862
+ // ClassName[nary] // array of objects
1860
1863
//
1861
1864
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 << " ]" ;
1876
1895
} else {
1877
- callbuf << " \n " ;
1878
- indent (callbuf, indent_level + 1 );
1896
+ callbuf << " *(" << type_name.c_str () << " *)args[" << i << " ]" ;
1879
1897
}
1880
1898
}
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 << " )" ;
1890
1900
}
1891
- callbuf << " )" ;
1892
1901
}
1893
1902
1894
1903
const DeclContext* get_non_transparent_decl_context (const FunctionDecl* FD) {
@@ -2040,18 +2049,59 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
2040
2049
std::ostringstream& buf, int indent_level) {
2041
2050
// Make a code string that follows this pattern:
2042
2051
//
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
+ // }
2046
2061
{
2047
2062
std::ostringstream typedefbuf;
2048
2063
std::ostringstream callbuf;
2049
2064
//
2050
2065
// Write the return value assignment part.
2051
2066
//
2052
2067
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 << " (is_arena) ? 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);
2053
2103
callbuf << " (*(" << class_name << " **)ret) = " ;
2054
- callbuf << " (obj ) ? new (*(" << class_name << " **)ret) " ;
2104
+ callbuf << " (is_arena ) ? new (*(" << class_name << " **)ret) " ;
2055
2105
make_narg_ctor (FD, N, typedefbuf, callbuf, class_name, indent_level);
2056
2106
2057
2107
callbuf << " : new " ;
@@ -2063,6 +2113,10 @@ void make_narg_ctor_with_return(const FunctionDecl* FD, const unsigned N,
2063
2113
// End the new expression statement.
2064
2114
//
2065
2115
callbuf << " ;\n " ;
2116
+ indent (callbuf, --indent_level);
2117
+ if (!CD->isDefaultConstructor () and CD->getNumParams () == 0 )
2118
+ callbuf << " }\n " ;
2119
+
2066
2120
//
2067
2121
// Output the whole new expression and return statement.
2068
2122
//
@@ -2575,8 +2629,14 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
2575
2629
" __attribute__((annotate(\" __cling__ptrcheck(off)\" )))\n "
2576
2630
" extern \" C\" void " ;
2577
2631
buf << wrapper_name;
2578
- buf << " (void* obj, int nargs, void** args, void* ret)\n "
2579
- " {\n " ;
2632
+ if (Cpp::IsConstructor (FD)) {
2633
+ buf << " (void* ret, unsigned long nary, unsigned long nargs, void** args, "
2634
+ " int is_arena)\n "
2635
+ " {\n " ;
2636
+ } else
2637
+ buf << " (void* obj, unsigned long nargs, void** args, void* ret)\n "
2638
+ " {\n " ;
2639
+
2580
2640
++indent_level;
2581
2641
if (min_args == num_params) {
2582
2642
// No parameters with defaults.
0 commit comments