Browse Source

Support implicitly generated copy constructor and default constructor in interrogate

rdb 10 years ago
parent
commit
83ed206551

+ 20 - 0
dtool/src/cppparser/cppArrayType.cxx

@@ -87,6 +87,26 @@ is_trivial() const {
   return _element_type->is_trivial();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPArrayType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPArrayType::
+is_default_constructible() const {
+  return _element_type->is_default_constructible();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPArrayType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPArrayType::
+is_copy_constructible() const {
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPArrayType::is_equivalent
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppArrayType.h

@@ -41,6 +41,8 @@ public:
                                 CPPScope *global_scope);
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

+ 20 - 0
dtool/src/cppparser/cppConstType.cxx

@@ -112,6 +112,26 @@ is_trivial() const {
   return _wrapped_around->is_trivial();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPConstType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPConstType::
+is_default_constructible() const {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPConstType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPConstType::
+is_copy_constructible() const {
+  return _wrapped_around->is_copy_constructible();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPConstType::is_equivalent
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppConstType.h

@@ -39,6 +39,8 @@ public:
 
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

+ 20 - 0
dtool/src/cppparser/cppExtensionType.cxx

@@ -114,6 +114,26 @@ is_trivial() const {
   return (_type == T_enum);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPExtensionType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPExtensionType::
+is_default_constructible() const {
+  return (_type == T_enum);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPExtensionType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPExtensionType::
+is_copy_constructible() const {
+  return (_type == T_enum);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPExtensionType::substitute_decl
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppExtensionType.h

@@ -48,6 +48,8 @@ public:
   virtual bool is_incomplete() const;
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
 
   virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
                                           CPPScope *current_scope,

+ 20 - 0
dtool/src/cppparser/cppPointerType.cxx

@@ -114,6 +114,26 @@ is_trivial() const {
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPPointerType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPPointerType::
+is_default_constructible() const {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPPointerType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPPointerType::
+is_copy_constructible() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPPointerType::is_equivalent
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppPointerType.h

@@ -39,6 +39,8 @@ public:
 
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

+ 20 - 0
dtool/src/cppparser/cppReferenceType.cxx

@@ -113,6 +113,26 @@ is_trivial() const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPReferenceType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPReferenceType::
+is_default_constructible() const {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPReferenceType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPReferenceType::
+is_copy_constructible() const {
+  return (_value_category == VC_lvalue);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPReferenceType::is_equivalent
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppReferenceType.h

@@ -45,6 +45,8 @@ public:
 
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

+ 20 - 0
dtool/src/cppparser/cppSimpleType.cxx

@@ -51,6 +51,26 @@ is_trivial() const {
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPSimpleType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPSimpleType::
+is_default_constructible() const {
+  return (_type != T_void);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPSimpleType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPSimpleType::
+is_copy_constructible() const {
+  return (_type != T_void);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPSimpleType::is_parameter_expr
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppSimpleType.h

@@ -79,6 +79,8 @@ public:
 
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
   virtual bool is_parameter_expr() const;
 
   virtual string get_preferred_name() const;

+ 284 - 4
dtool/src/cppparser/cppStructType.cxx

@@ -229,6 +229,193 @@ is_trivial() const {
   return is_default_constructible;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPStructType::
+is_default_constructible() const {
+  return is_default_constructible(V_public);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPStructType::
+is_copy_constructible() const {
+  return is_copy_constructible(V_public);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::is_default_constructible
+//       Access: Public
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPStructType::
+is_default_constructible(CPPVisibility min_vis) const {
+  CPPInstance *constructor = get_default_constructor();
+  if (constructor != (CPPInstance *)NULL) {
+    // It has a default constructor.
+    if (constructor->_vis > min_vis) {
+      // Inaccessible default constructor.
+      return false;
+    }
+
+    if (constructor->_storage_class & CPPInstance::SC_deleted) {
+      // Deleted default constructor.
+      return false;
+    }
+
+    return true;
+  }
+
+  // Does it have constructors at all?  If so, no implicit one is generated.
+  if (get_constructor() != (CPPFunctionGroup *)NULL) {
+    return false;
+  }
+
+  // Implicit default constructor.  Check if the implicit default
+  // constructor is deleted.
+  Derivation::const_iterator di;
+  for (di = _derivation.begin(); di != _derivation.end(); ++di) {
+    CPPStructType *base = (*di)._base->as_struct_type();
+    if (base != NULL) {
+      if (!base->is_default_constructible(V_protected)) {
+        return false;
+      }
+    }
+  }
+
+  // Make sure all members are default-constructible or have default values.
+  CPPScope::Variables::const_iterator vi;
+  for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
+    CPPInstance *instance = (*vi).second;
+    assert(instance != NULL);
+
+    if (instance->_storage_class & CPPInstance::SC_static) {
+      // Static members don't count.
+      continue;
+    }
+
+    if (instance->_initializer != (CPPExpression *)NULL) {
+      // It has a default value.
+      continue;
+    }
+
+    if (!instance->_type->is_default_constructible()) {
+      return false;
+    }
+  }
+
+  // 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::is_copy_constructible
+//       Access: Public
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPStructType::
+is_copy_constructible(CPPVisibility min_vis) const {
+  CPPInstance *constructor = get_copy_constructor();
+  if (constructor != (CPPInstance *)NULL) {
+    // It has a copy constructor.
+    if (constructor->_vis > min_vis) {
+      // Inaccessible copy constructor.
+      return false;
+    }
+
+    if (constructor->_storage_class & CPPInstance::SC_deleted) {
+      // Deleted copy constructor.
+      return false;
+    }
+
+    return true;
+  }
+
+  CPPInstance *destructor = get_destructor();
+  if (destructor != (CPPInstance *)NULL) {
+    if (destructor->_vis > min_vis) {
+      // Inaccessible destructor.
+      return false;
+    }
+
+    if (destructor->_storage_class & CPPInstance::SC_deleted) {
+      // Deleted destructor.
+      return false;
+    }
+  }
+
+  // Implicit copy constructor.  Check if the implicit copy
+  // constructor is deleted.
+  Derivation::const_iterator di;
+  for (di = _derivation.begin(); di != _derivation.end(); ++di) {
+    CPPStructType *base = (*di)._base->as_struct_type();
+    if (base != NULL) {
+      if (!base->is_copy_constructible(V_protected)) {
+        return false;
+      }
+    }
+  }
+
+  // Make sure all members are copy-constructible.
+  CPPScope::Variables::const_iterator vi;
+  for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
+    CPPInstance *instance = (*vi).second;
+    assert(instance != NULL);
+
+    if (instance->_storage_class & CPPInstance::SC_static) {
+      // Static members don't count.
+      continue;
+    }
+
+    if (!instance->_type->is_copy_constructible()) {
+      return false;
+    }
+  }
+
+  // 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;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPStructType::check_virtual
 //       Access: Public
@@ -250,7 +437,7 @@ is_trivial() const {
 //               virtual function pointer), or false otherwise.
 ////////////////////////////////////////////////////////////////////
 bool CPPStructType::
-check_virtual() {
+check_virtual() const {
   VFunctions funcs;
   get_virtual_funcs(funcs);
   return !funcs.empty();
@@ -291,9 +478,7 @@ is_incomplete() const {
 ////////////////////////////////////////////////////////////////////
 CPPFunctionGroup *CPPStructType::
 get_constructor() const {
-  // Iterate through all the functions that begin with '~' until we
-  // find one that claims to be a destructor.  In theory, there should
-  // only be one such function.
+  // Just look for the function with the same name as the class.
   CPPScope::Functions::const_iterator fi;
   fi = _scope->_functions.find(get_simple_name());
   if (fi != _scope->_functions.end()) {
@@ -303,6 +488,101 @@ get_constructor() const {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::get_default_constructor
+//       Access: Public
+//  Description: Returns the default constructor defined for the
+//               struct type, or NULL if there is none.
+////////////////////////////////////////////////////////////////////
+CPPInstance *CPPStructType::
+get_default_constructor() const {
+  CPPFunctionGroup *fgroup = get_constructor();
+  if (fgroup == (CPPFunctionGroup *)NULL) {
+    return (CPPInstance *)NULL;
+  }
+
+  CPPFunctionGroup::Instances::const_iterator ii;
+  for (ii = fgroup->_instances.begin();
+       ii != fgroup->_instances.end();
+       ++ii) {
+    CPPInstance *inst = (*ii);
+    assert(inst->_type != (CPPType *)NULL);
+
+    CPPFunctionType *ftype = inst->_type->as_function_type();
+    assert(ftype != (CPPFunctionType *)NULL);
+
+    if (ftype->_parameters->_parameters.size() == 0 ||
+        ftype->_parameters->_parameters.front()->_initializer != NULL) {
+      // It takes 0 parameters (or all parameters have default values).
+      return inst;
+    }
+  }
+
+  return (CPPInstance *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::get_copy_constructor
+//       Access: Public
+//  Description: Returns the copy constructor defined for the struct
+//               type, or NULL if no copy constructor exists.
+////////////////////////////////////////////////////////////////////
+CPPInstance *CPPStructType::
+get_copy_constructor() const {
+  CPPFunctionGroup *fgroup = get_constructor();
+  if (fgroup == (CPPFunctionGroup *)NULL) {
+    return (CPPInstance *)NULL;
+  }
+
+  CPPFunctionGroup::Instances::const_iterator ii;
+  for (ii = fgroup->_instances.begin();
+       ii != fgroup->_instances.end();
+       ++ii) {
+    CPPInstance *inst = (*ii);
+    assert(inst->_type != (CPPType *)NULL);
+
+    CPPFunctionType *ftype = inst->_type->as_function_type();
+    assert(ftype != (CPPFunctionType *)NULL);
+
+    if ((ftype->_flags & CPPFunctionType::F_copy_constructor) != 0) {
+      return inst;
+    }
+  }
+
+  return (CPPInstance *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::get_move_constructor
+//       Access: Public
+//  Description: Returns the move constructor defined for the struct
+//               type, or NULL if no move constructor exists.
+////////////////////////////////////////////////////////////////////
+CPPInstance *CPPStructType::
+get_move_constructor() const {
+  CPPFunctionGroup *fgroup = get_constructor();
+  if (fgroup == (CPPFunctionGroup *)NULL) {
+    return (CPPInstance *)NULL;
+  }
+
+  CPPFunctionGroup::Instances::const_iterator ii;
+  for (ii = fgroup->_instances.begin();
+       ii != fgroup->_instances.end();
+       ++ii) {
+    CPPInstance *inst = (*ii);
+    assert(inst->_type != (CPPType *)NULL);
+
+    CPPFunctionType *ftype = inst->_type->as_function_type();
+    assert(ftype != (CPPFunctionType *)NULL);
+
+    if ((ftype->_flags & CPPFunctionType::F_move_constructor) != 0) {
+      return inst;
+    }
+  }
+
+  return (CPPInstance *)NULL;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPStructType::get_destructor
 //       Access: Public

+ 8 - 1
dtool/src/cppparser/cppStructType.h

@@ -46,12 +46,19 @@ public:
   CPPScope *get_scope() const;
 
   bool is_abstract() const;
-  bool check_virtual();
+  bool check_virtual() const;
   virtual bool is_fully_specified() const;
   virtual bool is_incomplete() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
+  bool is_default_constructible(CPPVisibility min_vis) const;
+  bool is_copy_constructible(CPPVisibility min_vis) const;
 
   CPPFunctionGroup *get_constructor() const;
+  CPPInstance *get_default_constructor() const;
+  CPPInstance *get_copy_constructor() const;
+  CPPInstance *get_move_constructor() const;
   CPPInstance *get_destructor() const;
 
   virtual CPPDeclaration *

+ 20 - 0
dtool/src/cppparser/cppType.cxx

@@ -79,6 +79,26 @@ is_trivial() const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPType::
+is_default_constructible() const {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPType::
+is_copy_constructible() const {
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPType::is_parameter_expr
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppType.h

@@ -49,6 +49,8 @@ public:
 
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
   virtual bool is_parameter_expr() const;
 
   bool has_typedef_name() const;

+ 20 - 0
dtool/src/cppparser/cppTypedefType.cxx

@@ -189,6 +189,26 @@ is_trivial() const {
   return _type->is_trivial();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPTypedefType::is_default_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is default-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPTypedefType::
+is_default_constructible() const {
+  return _type->is_default_constructible();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPTypedefType::is_copy_constructible
+//       Access: Public, Virtual
+//  Description: Returns true if the type is copy-constructible.
+////////////////////////////////////////////////////////////////////
+bool CPPTypedefType::
+is_copy_constructible() const {
+  return _type->is_copy_constructible();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPTypedefType::is_fully_specified
 //       Access: Public, Virtual

+ 2 - 0
dtool/src/cppparser/cppTypedefType.h

@@ -43,6 +43,8 @@ public:
   virtual bool is_incomplete() const;
   virtual bool is_tbd() const;
   virtual bool is_trivial() const;
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
 
   virtual bool is_fully_specified() const;
 

+ 46 - 0
dtool/src/interrogate/interrogateBuilder.cxx

@@ -2684,6 +2684,52 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
     }
   }
 
+  // See if we need to generate an implicit default constructor.
+  CPPFunctionGroup *constructor = cpptype->get_constructor();
+  if (constructor == (CPPFunctionGroup *)NULL && cpptype->is_default_constructible()) {
+    // Make a default constructor.
+    CPPType *void_type = TypeManager::get_void_type();
+    CPPParameterList *params = new CPPParameterList;
+    CPPFunctionType *ftype = new CPPFunctionType(void_type, params, CPPFunctionType::F_constructor);
+
+    // Now make up an instance for the default constructor.
+    CPPInstance *function = new CPPInstance(ftype, cpptype->get_simple_name());
+    function->_storage_class |= CPPInstance::SC_inline | CPPInstance::SC_defaulted;
+    function->_vis = V_published;
+
+    FunctionIndex index = get_function(function, "", cpptype, cpptype->get_scope(), 0);
+    if (find(itype._constructors.begin(), itype._constructors.end(),
+             index) == itype._constructors.end()) {
+      itype._constructors.push_back(index);
+    }
+  }
+
+  // See if we need to generate an implicit copy constructor.
+  CPPInstance *copy_constructor = cpptype->get_copy_constructor();
+  if (copy_constructor == (CPPInstance *)NULL &&
+      cpptype->is_copy_constructible()) {
+    // Make an implicit copy constructor.
+    CPPType *const_ref_type = TypeManager::wrap_const_reference(cpptype);
+    CPPInstance *param = new CPPInstance(const_ref_type, NULL);
+
+    CPPType *void_type = TypeManager::get_void_type();
+    CPPParameterList *params = new CPPParameterList;
+    params->_parameters.push_back(param);
+    const int flags = CPPFunctionType::F_constructor | CPPFunctionType::F_copy_constructor;
+    CPPFunctionType *ftype = new CPPFunctionType(void_type, params, flags);
+
+    // Now make up an instance for the copy constructor.
+    CPPInstance *function = new CPPInstance(ftype, cpptype->get_simple_name());
+    function->_storage_class |= CPPInstance::SC_inline | CPPInstance::SC_defaulted;
+    function->_vis = V_published;
+
+    FunctionIndex index = get_function(function, "", cpptype, cpptype->get_scope(), 0);
+    if (find(itype._constructors.begin(), itype._constructors.end(),
+             index) == itype._constructors.end()) {
+      itype._constructors.push_back(index);
+    }
+  }
+
   if ((itype._flags & InterrogateType::F_inherited_destructor) != 0) {
     // If we have inherited our virtual destructor from our base
     // class, go ahead and assign the same function index.

+ 11 - 0
dtool/src/parser-inc/iostream

@@ -59,6 +59,8 @@ __published:
 protected:
   // Force this to be a non-trivial type.
   ios_base() {};
+private:
+  ios_base(const ios_base &);
 };
 class ios : public ios_base {
 __published:
@@ -69,6 +71,9 @@ __published:
   bool fail() const;
   bool bad() const;
   void clear();
+
+protected:
+  ios();
 };
 
 // We actually want to wrap streampos as streamoff.
@@ -76,6 +81,8 @@ __published:
 
 class ostream : virtual public ios {
 __published:
+  ostream(const ostream&) = delete;
+
   void put(char c);
   void flush();
   streampos tellp();
@@ -84,6 +91,8 @@ __published:
 };
 class istream : virtual public ios {
 __published:
+  istream(const istream&) = delete;
+
   int get();
   streampos tellg();
   void seekg(streampos pos);
@@ -91,6 +100,8 @@ __published:
 };
 class iostream : public istream, public ostream {
 __published:
+  iostream(const iostream&) = delete;
+
   void flush();
 };