interrogate: fix issues with abstract classes and covariance (fixes EggPolygon constructor)

This commit is contained in:
rdb 2016-12-05 17:22:24 -05:00
parent 6344c05b18
commit b182224463
3 changed files with 24 additions and 41 deletions

View File

@ -326,14 +326,17 @@ as_function_type() {
* This is similar to is_equal(), except it is more forgiving: it considers
* the functions to be equivalent only if the return type and the types of all
* parameters match.
*
* Note that this isn't symmetric to account for covariant return types.
*/
bool CPPFunctionType::
is_equivalent_function(const CPPFunctionType &other) const {
if (!_return_type->is_equivalent(*other._return_type)) {
match_virtual_override(const CPPFunctionType &other) const {
if (!_return_type->is_equivalent(*other._return_type) &&
!_return_type->is_convertible_to(other._return_type)) {
return false;
}
if (_flags != other._flags) {
if (((_flags ^ other._flags) & ~(F_override | F_final)) != 0) {
return false;
}

View File

@ -84,7 +84,7 @@ public:
virtual CPPFunctionType *as_function_type();
bool is_equivalent_function(const CPPFunctionType &other) const;
bool match_virtual_override(const CPPFunctionType &other) const;
CPPIdentifier *_class_owner;

View File

@ -378,6 +378,10 @@ is_constructible(const CPPType *given_type) const {
}
}
if (is_abstract()) {
return false;
}
// Check for a different constructor.
CPPFunctionGroup *fgroup = get_constructor();
if (fgroup != (CPPFunctionGroup *)NULL) {
@ -444,6 +448,10 @@ is_destructible() const {
*/
bool CPPStructType::
is_default_constructible(CPPVisibility min_vis) const {
if (is_abstract()) {
return false;
}
CPPInstance *constructor = get_default_constructor();
if (constructor != (CPPInstance *)NULL) {
// It has a default constructor.
@ -498,24 +506,6 @@ is_default_constructible(CPPVisibility min_vis) const {
}
}
// Check that we don't have pure virtual methods.
CPPScope::Functions::const_iterator fi;
for (fi = _scope->_functions.begin();
fi != _scope->_functions.end();
++fi) {
CPPFunctionGroup *fgroup = (*fi).second;
CPPFunctionGroup::Instances::const_iterator ii;
for (ii = fgroup->_instances.begin();
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
// Here's a pure virtual function.
return false;
}
}
}
return true;
}
@ -524,6 +514,10 @@ is_default_constructible(CPPVisibility min_vis) const {
*/
bool CPPStructType::
is_copy_constructible(CPPVisibility min_vis) const {
if (is_abstract()) {
return false;
}
CPPInstance *constructor = get_copy_constructor();
if (constructor != (CPPInstance *)NULL) {
// It has a copy constructor.
@ -581,24 +575,6 @@ is_copy_constructible(CPPVisibility min_vis) const {
}
}
// Check that we don't have pure virtual methods.
CPPScope::Functions::const_iterator fi;
for (fi = _scope->_functions.begin();
fi != _scope->_functions.end();
++fi) {
CPPFunctionGroup *fgroup = (*fi).second;
CPPFunctionGroup::Instances::const_iterator ii;
for (ii = fgroup->_instances.begin();
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
// Here's a pure virtual function.
return false;
}
}
}
return true;
}
@ -620,6 +596,10 @@ is_move_constructible(CPPVisibility min_vis) const {
return false;
}
if (is_abstract()) {
return false;
}
return true;
}
@ -1214,7 +1194,7 @@ get_virtual_funcs(VFunctions &funcs) const {
CPPFunctionType *new_ftype = new_inst->_type->as_function_type();
assert(new_ftype != (CPPFunctionType *)NULL);
if (new_ftype->is_equivalent_function(*base_ftype)) {
if (new_ftype->match_virtual_override(*base_ftype)) {
// It's a match! We now know it's virtual. Erase this function
// from the list, so we can add it back in below.
funcs.erase(vfi);