This is further work towards decoupling the Expr layer from the Node layer.
This commit makes it so that ExprManager does memory management for Datatype while NodeManager maintains a list of DType.
As a reminder, the ownership policy (and level of indirection through DatatypeIndex) is necessary due to not being able to store Datatype within Node since this leads to circular dependencies in the Node AST.
}
}
#endif
+ // clear the datatypes
+ d_ownedDatatypes.clear();
delete d_nodeManager;
d_nodeManager = NULL;
-
} catch(Exception& e) {
Warning() << "CVC4 threw an exception during cleanup." << std::endl
<< e << std::endl;
std::map<std::string, DatatypeType> nameResolutions;
std::vector<DatatypeType> dtts;
- //have to build deep copy so that datatypes will live in NodeManager
+ // have to build deep copy so that datatypes will live in this class
std::vector< Datatype* > dt_copies;
for(std::vector<Datatype>::iterator i = datatypes.begin(), i_end = datatypes.end(); i != i_end; ++i) {
- dt_copies.push_back( new Datatype( *i ) );
+ d_ownedDatatypes.push_back(std::unique_ptr<Datatype>(new Datatype(*i)));
+ dt_copies.push_back(d_ownedDatatypes.back().get());
}
// First do some sanity checks, set up the final Type to be used for
// pred selector.
for(std::vector<Datatype*>::iterator i = dt_copies.begin(), i_end = dt_copies.end(); i != i_end; ++i) {
TypeNode* typeNode;
+ // register datatype with the node manager
+ unsigned index = d_nodeManager->registerDatatype((*i)->d_internal);
if( (*i)->getNumParameters() == 0 ) {
- unsigned index = d_nodeManager->registerDatatype( *i );
typeNode = new TypeNode(d_nodeManager->mkTypeConst(DatatypeIndexConstant(index)));
//typeNode = new TypeNode(d_nodeManager->mkTypeConst(*i));
} else {
- unsigned index = d_nodeManager->registerDatatype( *i );
TypeNode cons = d_nodeManager->mkTypeConst(DatatypeIndexConstant(index));
//TypeNode cons = d_nodeManager->mkTypeConst(*i);
std::vector< TypeNode > params;
new TypeNode(expr::exportTypeInternal(*t.d_typeNode, t.d_nodeManager, em->d_nodeManager, vmap)));
}
+const Datatype& ExprManager::getDatatypeForIndex(unsigned index) const
+{
+ // when the Node-level API is in place, this function will be deleted.
+ Assert(index < d_ownedDatatypes.size());
+ return *d_ownedDatatypes[index];
+}
+
${mkConst_implementations}
}/* CVC4 namespace */
// undefined, private copy constructor and assignment op (disallow copy)
ExprManager(const ExprManager&) = delete;
ExprManager& operator=(const ExprManager&) = delete;
-
-public:
+ /** A list of datatypes owned by this expr manager. */
+ std::vector<std::unique_ptr<Datatype> > d_ownedDatatypes;
+
+ public:
/**
* Creates an expression manager with default options.
*/
/** Returns the maximum arity of the given kind. */
static unsigned maxArity(Kind kind);
+ /**
+ * Return the datatype at the given index owned by this class. Type nodes are
+ * associated with datatypes through the DatatypeIndexConstant class. The
+ * argument index is intended to be a value taken from that class.
+ */
+ const Datatype& getDatatypeForIndex(unsigned index) const;
};/* class ExprManager */
${mkConst_instantiations}
d_rt_cache.d_children.clear();
d_rt_cache.d_data = dummy;
- // TODO: switch to DType
- for (std::vector<Datatype*>::iterator
- datatype_iter = d_ownedDatatypes.begin(),
- datatype_end = d_ownedDatatypes.end();
- datatype_iter != datatype_end; ++datatype_iter) {
- Datatype* datatype = *datatype_iter;
- delete datatype;
- }
- d_ownedDatatypes.clear();
+ d_ownedDTypes.clear();
Assert(!d_attrManager->inGarbageCollection());
d_options = NULL;
}
-unsigned NodeManager::registerDatatype(Datatype* dt) {
- unsigned sz = d_ownedDatatypes.size();
- d_ownedDatatypes.push_back( dt );
+size_t NodeManager::registerDatatype(std::shared_ptr<DType> dt)
+{
+ size_t sz = d_ownedDTypes.size();
+ d_ownedDTypes.push_back(dt);
return sz;
}
-const Datatype & NodeManager::getDatatypeForIndex( unsigned index ) const{
- // when the Node-level API is in place, this function will be deleted.
- Assert(index < d_ownedDatatypes.size());
- return *d_ownedDatatypes[index];
-}
-
const DType& NodeManager::getDTypeForIndex(unsigned index) const
{
- const Datatype& d = getDatatypeForIndex(index);
- // return its internal representation
- return *d.d_internal;
+ Assert(index < d_ownedDTypes.size());
+ return *d_ownedDTypes[index];
}
void NodeManager::reclaimZombies() {
std::vector<NodeManagerListener*> d_listeners;
/** A list of datatypes owned by this node manager. */
- std::vector<Datatype*> d_ownedDatatypes;
+ std::vector<std::shared_ptr<DType> > d_ownedDTypes;
/**
* A map of tuple and record types to their corresponding datatype.
}
/** register datatype */
- unsigned registerDatatype(Datatype* dt);
- /** get datatype for index */
- const Datatype & getDatatypeForIndex( unsigned index ) const;
+ size_t registerDatatype(std::shared_ptr<DType> dt);
+ /**
+ * Return the datatype at the given index owned by this class. Type nodes are
+ * associated with datatypes through the DatatypeIndexConstant class. The
+ * argument index is intended to be a value taken from that class.
+ *
+ * Type nodes must access their DTypes through a level of indirection to
+ * prevent cycles in the Node AST (as DTypes themselves contain Nodes), which
+ * would lead to memory leaks. Thus TypeNode are given a DatatypeIndexConstant
+ * which is used as an index to retrieve the DType via this call.
+ */
const DType& getDTypeForIndex(unsigned index) const;
/** Get a Kind from an operator expression */
if (d_typeNode->getKind() == kind::DATATYPE_TYPE)
{
DatatypeIndexConstant dic = d_typeNode->getConst<DatatypeIndexConstant>();
- return d_nodeManager->getDatatypeForIndex(dic.getIndex());
+ return d_nodeManager->toExprManager()->getDatatypeForIndex(dic.getIndex());
}
Assert(d_typeNode->getKind() == kind::PARAMETRIC_DATATYPE);
return DatatypeType((*d_typeNode)[0].toType()).getDatatype();
#include <typeinfo>
#include <vector>
-#include "expr/expr.h" // for ExprSetDepth etc..
-#include "expr/node_manager_attributes.h" // for VarNameAttr
-#include "options/language.h" // for LANG_AST
-#include "printer/dagification_visitor.h"
+#include "expr/dtype.h"
+#include "expr/expr.h" // for ExprSetDepth etc..
+#include "expr/node_manager_attributes.h" // for VarNameAttr
+#include "options/language.h" // for LANG_AST
#include "options/smt_options.h"
+#include "printer/dagification_visitor.h"
#include "smt/command.h"
#include "smt/smt_engine.h"
#include "smt_util/node_visitor.h"
break;
case kind::DATATYPE_TYPE: {
- const Datatype& dt = (NodeManager::currentNM()->getDatatypeForIndex( n.getConst< DatatypeIndexConstant >().getIndex() ));
+ const Datatype& dt =
+ NodeManager::currentNM()->toExprManager()->getDatatypeForIndex(
+ n.getConst<DatatypeIndexConstant>().getIndex());
if( dt.isTuple() ){
out << '[';
for (unsigned i = 0; i < dt[0].getNumArgs(); ++ i) {
// DATATYPES
case kind::PARAMETRIC_DATATYPE: {
- const Datatype & dt = (NodeManager::currentNM()->getDatatypeForIndex( n[0].getConst< DatatypeIndexConstant >().getIndex() ));
- out << dt.getName() << '[';
- for(unsigned i = 1; i < n.getNumChildren(); ++i) {
- if(i > 1) {
- out << ',';
- }
- out << n[i];
+ const DType& dt = NodeManager::currentNM()->getDTypeForIndex(
+ n[0].getConst<DatatypeIndexConstant>().getIndex());
+ out << dt.getName() << '[';
+ for (unsigned i = 1; i < n.getNumChildren(); ++i)
+ {
+ if (i > 1)
+ {
+ out << ',';
}
+ out << n[i];
+ }
out << ']';
}
return;
#include <typeinfo>
#include <vector>
+#include "expr/dtype.h"
#include "expr/node_manager_attributes.h"
#include "options/bv_options.h"
#include "options/language.h"
case kind::DATATYPE_TYPE:
{
- const Datatype& dt = (NodeManager::currentNM()->getDatatypeForIndex(
+ const DType& dt = (NodeManager::currentNM()->getDTypeForIndex(
n.getConst<DatatypeIndexConstant>().getIndex()));
if (dt.isTuple())
{