Refactor code and change change enum_scope_template test to use class enums. Fix few test cases.
- Change enum_scope_template test to use class enums. - Move the conversion of void* of ptr in swig wrapper to class pointer to Lib files. - Synchronize between old and new flow. Old flow to accept newly created objects, with the use of a new property SWIG_classWrapper to newly created objects. - ZEND_BEGIN_ARG_INFO_EX to hold exact number of arguments required. - Fix the constructor overloading bug in the in-house Swig_class_overload_dispatch function - Add helper function to check if the class is wrapped. - Add ZEND_ACC_ABSTRACT to virtual functions to make the class abstract. - Change how wname is selected for staticmemberfn. - Helper function to get names without namespace getNameWithoutNamespace. - Fix bugs on class entry level at class handler. - Move all entry level code to class handler from class decleration. - Checking if base.item is null before using it. - Check if the parent class is wrapped before using its class entry.
This commit is contained in:
parent
da53351cac
commit
a687b020e2
4 changed files with 114 additions and 58 deletions
|
|
@ -4,12 +4,12 @@ require "enum_scope_template.php";
|
|||
|
||||
check::classes(array("enum_scope_template", "TreeInt"));
|
||||
check::functions(array("chops","treeint_chops"));
|
||||
check::equal(0,TreeInt_Oak,"0==TreeInt_Oak");
|
||||
check::equal(1,TreeInt_Fir,"1==TreeInt_Fir");
|
||||
check::equal(2,TreeInt_Cedar,"2==TreeInt_Cedar");
|
||||
check::equal(TreeInt_Oak,chops(TreeInt_Oak),"TreeInt_Oak==chops(TreeInt_Oak)");
|
||||
check::equal(TreeInt_Fir,chops(TreeInt_Fir),"TreeInt_Fir==chops(TreeInt_Fir)");
|
||||
check::equal(TreeInt_Cedar,chops(TreeInt_Cedar),"TreeInt_Cedar==chops(TreeInt_Cedar)");
|
||||
check::equal(0,TreeInt::Oak,"0==TreeInt_Oak");
|
||||
check::equal(1,TreeInt::Fir,"1==TreeInt_Fir");
|
||||
check::equal(2,TreeInt::Cedar,"2==TreeInt_Cedar");
|
||||
check::equal(TreeInt::Oak,chops(TreeInt::Oak),"TreeInt_Oak==chops(TreeInt_Oak)");
|
||||
check::equal(TreeInt::Fir,chops(TreeInt::Fir),"TreeInt_Fir==chops(TreeInt_Fir)");
|
||||
check::equal(TreeInt::Cedar,chops(TreeInt::Cedar),"TreeInt_Cedar==chops(TreeInt_Cedar)");
|
||||
|
||||
check::done();
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
%typemap(in) SWIGTYPE ($&1_ltype tmp)
|
||||
%{
|
||||
if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) {
|
||||
$1 = *$obj_value;
|
||||
$1 = *(($1_ltype *)$obj_value);
|
||||
}
|
||||
else {
|
||||
if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL)
|
||||
|
|
@ -109,7 +109,7 @@
|
|||
SWIGTYPE []
|
||||
%{
|
||||
if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) {
|
||||
$1 = $obj_value;
|
||||
$1 = ($1_ltype) $obj_value;
|
||||
}
|
||||
else {
|
||||
if (SWIG_ConvertPtr(&$linput, (void **) &$1, $1_descriptor, 0) < 0)
|
||||
|
|
@ -120,7 +120,7 @@
|
|||
%typemap(in) SWIGTYPE &
|
||||
%{
|
||||
if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) {
|
||||
$1 = $obj_value;
|
||||
$1 = ($1_ltype) $obj_value;
|
||||
}
|
||||
else {
|
||||
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL)
|
||||
|
|
@ -131,7 +131,7 @@
|
|||
%typemap(in) SWIGTYPE &&
|
||||
%{
|
||||
if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) {
|
||||
$1 = $obj_value;
|
||||
$1 = ($1_ltype) $obj_value;
|
||||
}
|
||||
else {
|
||||
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
|
||||
|
|
@ -142,10 +142,15 @@
|
|||
|
||||
%typemap(in) SWIGTYPE *const& ($*ltype temp)
|
||||
%{
|
||||
if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) {
|
||||
SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor");
|
||||
if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) {
|
||||
$1 = ($1_ltype) $obj_value;
|
||||
}
|
||||
else {
|
||||
if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) {
|
||||
SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor");
|
||||
}
|
||||
$1 = ($1_ltype)&temp;
|
||||
}
|
||||
%}
|
||||
|
||||
%typemap(in) SWIGTYPE *DISOWN
|
||||
|
|
|
|||
|
|
@ -185,6 +185,14 @@ SWIG_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags) {
|
|||
|
||||
type_name=zend_rsrc_list_get_rsrc_type(Z_RES_P(z));
|
||||
|
||||
if (!type_name) {
|
||||
if (Z_TYPE_P(z) == IS_OBJECT) {
|
||||
HashTable * ht = Z_OBJ_HT_P(z)->get_properties(z);
|
||||
zval * _cPtr = zend_hash_str_find(ht, "_cPtr", sizeof("_cPtr") - 1);
|
||||
type_name=zend_rsrc_list_get_rsrc_type(Z_RES_P(_cPtr));
|
||||
}
|
||||
}
|
||||
|
||||
return SWIG_ConvertResourceData(p, type_name, ty);
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +215,13 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
|
|||
_cPtr = Z_INDIRECT_P(_cPtr);
|
||||
}
|
||||
if (Z_TYPE_P(_cPtr) == IS_RESOURCE) {
|
||||
*ptr = SWIG_ConvertResourcePtr(_cPtr, ty, flags);
|
||||
zval *zv;
|
||||
if (!zend_hash_str_exists(ht, "SWIG_classWrapper", sizeof("SWIG_classWrapper") - 1))
|
||||
zv = _cPtr;
|
||||
else
|
||||
zv = z;
|
||||
|
||||
*ptr = SWIG_ConvertResourcePtr(zv, ty, flags);
|
||||
return (*ptr == NULL ? -1 : 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -245,6 +259,8 @@ SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int userNewObj
|
|||
zval zv;
|
||||
ZVAL_RES(&zv,zend_register_resource(ptr,*(int *)(type->clientdata)));
|
||||
zend_hash_str_add(ht, "_cPtr", sizeof("_cPtr") - 1, &zv);
|
||||
ZVAL_TRUE(&zv);
|
||||
zend_hash_str_add(ht, "SWIG_classWrapper", sizeof("SWIG_classWrapper") - 1, &zv);
|
||||
}
|
||||
obj->newobject = userNewObj;
|
||||
}
|
||||
|
|
@ -252,7 +268,7 @@ SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int userNewObj
|
|||
static void
|
||||
SWIG_SetZval( zval *zv, zval *class_zv, int userNewObj ,int object, int class_obj ,void *ptr, swig_type_info *type, zend_object *std) {
|
||||
|
||||
if (class_obj) {
|
||||
if (class_obj == 1) {
|
||||
SWIG_generalize_object(class_zv, ptr, class_obj, userNewObj ,type);
|
||||
return;
|
||||
}
|
||||
|
|
@ -268,7 +284,10 @@ SWIG_SetZval( zval *zv, zval *class_zv, int userNewObj ,int object, int class_ob
|
|||
}
|
||||
|
||||
if (object == 2) {
|
||||
SWIG_SetPointerZval(zv,ptr,type,class_obj);
|
||||
int newobj = class_obj;
|
||||
if (class_obj == 2)
|
||||
newobj = 1;
|
||||
SWIG_SetPointerZval(zv,ptr,type,newobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ static void print_creation_free_wrapper(int item_index) {
|
|||
Printf(s_header, "zend_object * %s_object_new(zend_class_entry *ce) {\n",class_name);
|
||||
Printf(s_header, " swig_object_wrapper *obj = (swig_object_wrapper *)ecalloc(1,sizeof(swig_object_wrapper) + zend_object_properties_size(ce));\n");
|
||||
Printf(s_header, " zend_object_std_init(&obj->std, ce);\n");
|
||||
//Printf(s_header, " object_properties_init(&obj->std, ce);\n");
|
||||
Printf(s_header, " %s_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n",class_name);
|
||||
Printf(s_header, " %s_object_handlers.free_obj = %s_free_storage;\n",class_name,class_name);
|
||||
Printf(s_header, " %s_object_handlers.dtor_obj = %s_destroy_object;\n",class_name,class_name);
|
||||
|
|
@ -797,10 +798,11 @@ public:
|
|||
Append(arginfo_code, GetFlag(p, "tmap:in:byref") ? "1" : "0");
|
||||
}
|
||||
|
||||
int numberOfParams = Len(arginfo_code);
|
||||
if (!GetFlag(arginfo_used, arginfo_code)) {
|
||||
// Not had this one before, so emit it.
|
||||
SetFlag(arginfo_used, arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 0)\n", arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, numberOfParams);
|
||||
for (const char * p = Char(arginfo_code); *p; ++p) {
|
||||
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
|
||||
}
|
||||
|
|
@ -875,6 +877,8 @@ public:
|
|||
|
||||
String *f = NewString("");
|
||||
|
||||
int constructorOverload = (Cmp(Getattr(n, "nodeType"), "constructor") == 0);
|
||||
|
||||
/* Get a list of methods ranked by precedence values and argument count */
|
||||
List *dispatch = Swig_overload_rank(n, true);
|
||||
int nfunc = Len(dispatch);
|
||||
|
|
@ -887,10 +891,12 @@ public:
|
|||
bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0;
|
||||
int num_required = emit_num_required(pi)-1;
|
||||
int num_arguments = emit_num_arguments(pi)-1;
|
||||
if (GetFlag(n, "wrap:this")) {
|
||||
|
||||
if (constructorOverload) {
|
||||
num_required++;
|
||||
num_arguments++;
|
||||
}
|
||||
|
||||
if (num_arguments > *maxargs)
|
||||
*maxargs = num_arguments;
|
||||
|
||||
|
|
@ -907,7 +913,8 @@ public:
|
|||
int num_braces = 0;
|
||||
j = 0;
|
||||
Parm *pj = pi;
|
||||
pj = nextSibling(pj);
|
||||
if (!constructorOverload && pj)
|
||||
pj = nextSibling(pj);
|
||||
while (pj) {
|
||||
if (checkAttribute(pj, "tmap:in:numinputs", "0")) {
|
||||
pj = Getattr(pj, "tmap:in:next");
|
||||
|
|
@ -967,15 +974,11 @@ public:
|
|||
/* ------------------------------------------------------------
|
||||
* dispatchFunction()
|
||||
* ------------------------------------------------------------ */
|
||||
void dispatchFunction(Node *n) {
|
||||
void dispatchFunction(Node *n, int constructor) {
|
||||
/* Last node in overloaded chain */
|
||||
|
||||
int maxargs;
|
||||
String *tmp = NewStringEmpty();
|
||||
if (Swig_directorclass(n) && wrapperType == directorconstructor) {
|
||||
/* We have an extra 'this' parameter. */
|
||||
SetFlag(n, "wrap:this");
|
||||
}
|
||||
|
||||
String *dispatch = NULL;
|
||||
|
||||
|
|
@ -991,8 +994,10 @@ public:
|
|||
String *wname = NULL;
|
||||
String *modes = NULL;
|
||||
|
||||
if (class_name)
|
||||
wname = getWrapperMethodName(Getattr(n, "name"), symname);
|
||||
if (constructor)
|
||||
wname = NewString("__construct");
|
||||
else if (class_name)
|
||||
wname = getWrapperMethodName(class_name, symname);
|
||||
else
|
||||
wname = Swig_name_wrapper(symname);
|
||||
|
||||
|
|
@ -1068,6 +1073,16 @@ public:
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Helper function to check if class is wrapped */
|
||||
bool is_class_wrapped(String *className) {
|
||||
Iterator iterate;
|
||||
for (iterate = First(classes); iterate.item; iterate = Next(iterate)) {
|
||||
if (Cmp(iterate.item, className) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Is special return type */
|
||||
bool is_param_type_pointer(SwigType *t) {
|
||||
|
||||
|
|
@ -1097,7 +1112,7 @@ public:
|
|||
if (!GetFlag(arginfo_used, arginfo_code)) {
|
||||
// Not had this one before, so emit it.
|
||||
SetFlag(arginfo_used, arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 0)\n", arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 1)\n", arginfo_code);
|
||||
for (const char * p = Char(arginfo_code); *p; ++p) {
|
||||
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
|
||||
}
|
||||
|
|
@ -1111,7 +1126,7 @@ public:
|
|||
if (!GetFlag(arginfo_used, arginfo_code)) {
|
||||
// Not had this one before, so emit it.
|
||||
SetFlag(arginfo_used, arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 0)\n", arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 2)\n", arginfo_code);
|
||||
for (const char * p = Char(arginfo_code); *p; ++p) {
|
||||
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
|
||||
}
|
||||
|
|
@ -1277,10 +1292,13 @@ public:
|
|||
modes = getAccessMode(Getattr(n, "access"));
|
||||
|
||||
if (constructor) {
|
||||
Append(modes,"| ZEND_ACC_CTOR");
|
||||
Append(modes, " | ZEND_ACC_CTOR");
|
||||
}
|
||||
else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0)
|
||||
Append(modes,"| ZEND_ACC_STATIC");
|
||||
Append(modes, " | ZEND_ACC_STATIC");
|
||||
|
||||
if (Cmp(Getattr(n, "abstract"), "1") == 0)
|
||||
Append(modes, " | ZEND_ACC_ABSTRACT");
|
||||
|
||||
if (Getattr(n, "sym:overloaded")) {
|
||||
overloaded = 1;
|
||||
|
|
@ -1335,9 +1353,13 @@ public:
|
|||
}
|
||||
}
|
||||
else if (wrapperType == staticmemberfn) {
|
||||
char *ptr = Char(iname);
|
||||
ptr+= strlen(Char(iname)) - strlen(strrchr(GetChar(n, "name"),':') + 1);
|
||||
wname = (String*) ptr;
|
||||
if (Char(Strchr(name, ':'))) {
|
||||
char *ptr = Char(iname);
|
||||
ptr+= strlen(Char(iname)) - strlen(strrchr(GetChar(n, "name"),':') + 1);
|
||||
wname = (String*) ptr;
|
||||
}
|
||||
else
|
||||
wname = iname;
|
||||
}
|
||||
else {
|
||||
if (class_name) {
|
||||
|
|
@ -1485,13 +1507,11 @@ public:
|
|||
}
|
||||
|
||||
String *paramType_class = NULL;
|
||||
String *paramType_type = NULL;
|
||||
bool paramType_valid = is_class(pt);
|
||||
SwigType *resolved = SwigType_typedef_resolve_all(pt);
|
||||
|
||||
if (paramType_valid) {
|
||||
paramType_class = get_class_name(pt);
|
||||
paramType_type = Getattr(get_class_node(pt), "classtype");
|
||||
Chop(paramType_class);
|
||||
}
|
||||
|
||||
|
|
@ -1514,9 +1534,10 @@ public:
|
|||
Printf(param_zval, "getThis()");
|
||||
else
|
||||
Printf(param_zval, "&%s", source);
|
||||
Printf(param_value, "(%s *) SWIG_Z_FETCH_OBJ_P(%s)->ptr", paramType_type , param_zval);
|
||||
Printf(param_value, "%sSWIG_Z_FETCH_OBJ_P(%s)->ptr", SwigType_isreference(pt) ? "&" : "", param_zval);
|
||||
Replaceall(tm, "$obj_value", param_value);
|
||||
}
|
||||
Replaceall(tm, "$classFlag", "0");
|
||||
String *temp_obj = NewStringEmpty();
|
||||
Printf(temp_obj, "&%s", ln);
|
||||
Replaceall(tm, "$obj_value", is_param_type_pointer(resolved ? resolved : pt) ? "NULL" : temp_obj); // Adding this to compile. It won't reach this if $obj_val is required.
|
||||
|
|
@ -1579,6 +1600,7 @@ public:
|
|||
// Replaceall(tm,"$input",Getattr(p,"lname"));
|
||||
Replaceall(tm, "$target", "return_value");
|
||||
Replaceall(tm, "$result", "return_value");
|
||||
Replaceall(tm, "$classFlag", "0");
|
||||
Replaceall(tm, "$arg", Getattr(p, "emit:input"));
|
||||
Replaceall(tm, "$input", Getattr(p, "emit:input"));
|
||||
Printv(outarg, tm, "\n", NIL);
|
||||
|
|
@ -1602,10 +1624,12 @@ public:
|
|||
|
||||
String *retType_class = NULL;
|
||||
bool retType_valid = is_class(d);
|
||||
bool valid_wrapped_class = false;
|
||||
|
||||
if (retType_valid) {
|
||||
retType_class = get_class_name(d);
|
||||
Chop(retType_class);
|
||||
valid_wrapped_class = is_class_wrapped(retType_class);
|
||||
}
|
||||
|
||||
/* emit function call */
|
||||
|
|
@ -1621,11 +1645,11 @@ public:
|
|||
if (retType_class) {
|
||||
String *retZend_obj = NewStringEmpty();
|
||||
Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class);
|
||||
Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : retZend_obj) : "NULL");
|
||||
Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : (valid_wrapped_class ? retZend_obj : "NULL")) : "NULL");
|
||||
}
|
||||
Replaceall(tm, "$zend_obj", "NULL");
|
||||
Replaceall(tm, "$newobj", retType_valid ? "1" : "2");
|
||||
Replaceall(tm, "$c_obj", constructor? "1" : "0");
|
||||
Replaceall(tm, "$newobj", retType_valid ? (valid_wrapped_class ? "1" : "2") : "2");
|
||||
Replaceall(tm, "$c_obj", newobject? (valid_wrapped_class ? (constructor ? "1" : "0") : "2") : "0");
|
||||
Printf(f->code, "%s\n", tm);
|
||||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
|
||||
|
|
@ -1681,7 +1705,7 @@ public:
|
|||
wname = NULL;
|
||||
|
||||
if (overloaded && !Getattr(n, "sym:nextSibling")) {
|
||||
dispatchFunction(n);
|
||||
dispatchFunction(n, constructor);
|
||||
}
|
||||
|
||||
// Handle getters and setters.
|
||||
|
|
@ -2677,23 +2701,9 @@ done:
|
|||
|
||||
virtual int classDeclaration(Node *n) {
|
||||
if (!Getattr(n, "feature:onlychildren")) {
|
||||
String *className = Getattr(n, "name");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
Setattr(n, "php:proxy", symname);
|
||||
|
||||
if (className != symname)
|
||||
class_name = symname;
|
||||
else
|
||||
class_name = className;
|
||||
|
||||
if (Len(classes) != 0)
|
||||
Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
|
||||
|
||||
Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name);
|
||||
|
||||
Append(classes,class_name);
|
||||
}
|
||||
|
||||
return Language::classDeclaration(n);
|
||||
}
|
||||
|
||||
|
|
@ -2706,6 +2716,15 @@ done:
|
|||
return present_name;
|
||||
}
|
||||
|
||||
/* Helper method to get names without namespace
|
||||
*/
|
||||
String *getNameWithoutNamespace(char *name) {
|
||||
char *returnName = Char(strrchr(name, ':'));
|
||||
if (!returnName)
|
||||
return NULL;
|
||||
return NewString(returnName + 1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* classHandler()
|
||||
* ------------------------------------------------------------ */
|
||||
|
|
@ -2715,15 +2734,26 @@ done:
|
|||
current_class = n;
|
||||
String *className = Getattr(n, "name");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *nameSpace = NULL;
|
||||
//String *nameSpace = NULL;
|
||||
String *baseClassExtend = NULL;
|
||||
bool exceptionClassFlag = false;
|
||||
|
||||
//check for namespaces
|
||||
if (Strstr(className, ":"))
|
||||
nameSpace = getNameSpace(GetChar(n, "name"));
|
||||
//if (Strstr(className, ":"))
|
||||
//nameSpace = getNameSpace(GetChar(n, "name"));
|
||||
|
||||
if (className != symname)
|
||||
class_name = symname;
|
||||
else
|
||||
class_name = className;
|
||||
|
||||
if (Len(classes) != 0)
|
||||
Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
|
||||
|
||||
Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name);
|
||||
|
||||
class_type = Getattr(n, "classtype");
|
||||
Append(classes,class_name);
|
||||
Append(class_types, class_type);
|
||||
Append(class_need_free, "0");
|
||||
|
||||
|
|
@ -2752,7 +2782,8 @@ done:
|
|||
while (base.item && GetFlag(base.item, "feature:ignore")) {
|
||||
base = Next(base);
|
||||
}
|
||||
baseClassExtend = Getattr(base.item, "sym:name");
|
||||
if (base.item)
|
||||
baseClassExtend = Getattr(base.item, "sym:name");
|
||||
base = Next(base);
|
||||
if (base.item) {
|
||||
/* Warn about multiple inheritance for additional base class(es) */
|
||||
|
|
@ -2780,9 +2811,10 @@ done:
|
|||
Append(baseClassExtend, "_Exception");
|
||||
|
||||
Printf(s_oinit, "zend_class_entry *%s_ce = zend_lookup_class(zend_string_init(\"Exception\", sizeof(\"Exception\") - 1, 0));\n", baseClassExtend);
|
||||
exceptionClassFlag = true;
|
||||
}
|
||||
|
||||
if (baseClassExtend) {
|
||||
if (baseClassExtend && (exceptionClassFlag || is_class_wrapped(baseClassExtend))) {
|
||||
Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", class_name , class_name, baseClassExtend);
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue