Support =default and =delete methods in Interrogate

This commit is contained in:
rdb 2016-01-03 19:56:20 +01:00
parent 84e15316cc
commit be60303502
8 changed files with 1895 additions and 1794 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1524,6 +1524,14 @@ maybe_initialize_or_function_body:
| '=' const_expr ';'
{
$$ = $2;
}
| '=' KW_DEFAULT ';'
{
$$ = new CPPExpression(CPPExpression::get_default());
}
| '=' KW_DELETE ';'
{
$$ = new CPPExpression(CPPExpression::get_delete());
}
| '=' '{' structure_init '}'
{

View File

@ -494,6 +494,30 @@ get_nullptr() {
return expr;
}
////////////////////////////////////////////////////////////////////
// Function: CPPExpression::get_default
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
const CPPExpression &CPPExpression::
get_default() {
static CPPExpression expr(0);
expr._type = T_default;
return expr;
}
////////////////////////////////////////////////////////////////////
// Function: CPPExpression::get_delete
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
const CPPExpression &CPPExpression::
get_delete() {
static CPPExpression expr(0);
expr._type = T_delete;
return expr;
}
////////////////////////////////////////////////////////////////////
// Function: CPPExpression::Destructor
// Access: Public
@ -1619,6 +1643,14 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
}
break;
case T_default:
out << "default";
break;
case T_delete:
out << "delete";
break;
default:
out << "(** invalid operand type " << (int)_type << " **)";
}

View File

@ -52,6 +52,8 @@ public:
static CPPExpression raw_literal(const string &raw, CPPInstance *lit_op);
static const CPPExpression &get_nullptr();
static const CPPExpression &get_default();
static const CPPExpression &get_delete();
~CPPExpression();
@ -124,6 +126,10 @@ public:
T_trinary_operation,
T_literal,
T_raw_literal,
// These are used when parsing =default and =delete methods.
T_default,
T_delete,
};
Type _type;

View File

@ -251,12 +251,20 @@ void CPPInstance::
set_initializer(CPPExpression *initializer) {
if (_type->as_function_type() != (CPPFunctionType *)NULL) {
// This is a function declaration.
if (initializer == (CPPExpression *)NULL) {
_storage_class &= ~SC_pure_virtual;
} else {
_storage_class |= SC_pure_virtual;
}
_storage_class &= ~(SC_pure_virtual | SC_defaulted | SC_deleted);
_initializer = (CPPExpression *)NULL;
if (initializer != (CPPExpression *)NULL) {
if (initializer->_type == CPPExpression::T_integer) { // = 0
_storage_class |= SC_pure_virtual;
} else if (initializer->_type == CPPExpression::T_default) {
_storage_class |= SC_defaulted;
} else if (initializer->_type == CPPExpression::T_delete) {
_storage_class |= SC_deleted;
}
}
} else {
_initializer = initializer;
}
@ -622,6 +630,12 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
if (_storage_class & SC_pure_virtual) {
out << " = 0";
}
if (_storage_class & SC_defaulted) {
out << " = default";
}
if (_storage_class & SC_deleted) {
out << " = delete";
}
if (_initializer != NULL) {
out << " = " << *_initializer;
}

View File

@ -60,6 +60,10 @@ public:
// And this is for methods tagged with __extension, which declares
// extension methods defined separately from the source code.
SC_extension = 0x2000,
// These are for =default and =delete functions.
SC_defaulted = 0x4000,
SC_deleted = 0x8000,
};
CPPInstance(CPPType *type, const string &name, int storage_class = 0);

View File

@ -190,6 +190,11 @@ is_trivial() const {
return false;
}
// The following checks don't apply for defaulted functions.
if (inst->_storage_class & CPPInstance::SC_defaulted) {
continue;
}
assert(inst->_type != (CPPType *)NULL);
CPPFunctionType *ftype = inst->_type->as_function_type();
assert(ftype != (CPPFunctionType *)NULL);
@ -197,7 +202,8 @@ is_trivial() const {
if (ftype->_flags & (CPPFunctionType::F_destructor |
CPPFunctionType::F_move_constructor |
CPPFunctionType::F_copy_constructor)) {
// User-provided destructors and copy/move constructors are not trivial.
// User-provided destructors and copy/move constructors are not
// trivial unless they are defaulted (and not virtual).
return false;
}
@ -584,7 +590,10 @@ get_virtual_funcs(VFunctions &funcs) const {
CPPFunctionType *base_ftype = inst->_type->as_function_type();
assert(base_ftype != (CPPFunctionType *)NULL);
if ((base_ftype->_flags & CPPFunctionType::F_destructor) != 0) {
if (inst->_storage_class & CPPInstance::SC_deleted) {
// Ignore deleted functions.
} else if ((base_ftype->_flags & CPPFunctionType::F_destructor) != 0) {
// Match destructor-for-destructor; don't try to match
// destructors up by name.
CPPInstance *destructor = get_destructor();
@ -646,7 +655,8 @@ get_virtual_funcs(VFunctions &funcs) const {
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
if ((inst->_storage_class & CPPInstance::SC_virtual) != 0) {
if ((inst->_storage_class & CPPInstance::SC_virtual) != 0 &&
(inst->_storage_class & CPPInstance::SC_deleted) == 0) {
// Here's a virtual function.
funcs.push_back(inst);
}

View File

@ -1134,8 +1134,8 @@ scan_function(CPPInstance *function) {
return;
}
if ((function->_storage_class & CPPInstance::SC_static) != 0) {
// The function is static, so can't be exported.
if ((function->_storage_class & (CPPInstance::SC_static | CPPInstance::SC_deleted)) != 0) {
// The function is static or deleted, so can't be exported.
return;
}
@ -2821,6 +2821,11 @@ define_method(CPPInstance *function, InterrogateType &itype,
return;
}
if (function->_storage_class & CPPInstance::SC_deleted) {
// It was explicitly marked as deleted.
return;
}
// As a special kludgey extension, we consider a public static
// method called "get_class_type()" to be marked published, even if
// it is not. This allows us to export all of the TypeHandle system