diff --git a/include/bolt/CST.hpp b/include/bolt/CST.hpp index 67ca881b5..a41d0a5e9 100644 --- a/include/bolt/CST.hpp +++ b/include/bolt/CST.hpp @@ -197,12 +197,7 @@ namespace bolt { ++RefCount; } - inline void unref() { - --RefCount; - if (RefCount == 0) { - delete this; - } - } + void unref(); void setParents(); @@ -249,7 +244,7 @@ namespace bolt { virtual Scope* getScope(); - virtual ~Node(); + virtual ~Node() {} }; diff --git a/src/CST.cc b/src/CST.cc index 5cb02fbbb..8779dbb69 100644 --- a/src/CST.cc +++ b/src/CST.cc @@ -289,19 +289,26 @@ namespace bolt { } - Node::~Node() { + void Node::unref() { - struct UnrefVisitor : public CSTVisitor { + --RefCount; - void visit(Node* N) { - visitEachChild(N); - N->unref(); - } + if (RefCount == 0) { - }; + // You may be wondering why we aren't unreffing the children in the + // destructor. This is due to a behaviour in Clang where a top-level + // destructor ~Node() wont get access to the fields in derived classes + // because they may already have been destroyed. + struct UnrefVisitor : public CSTVisitor { + void visit(Node* N) { + N->unref(); + } + }; + UnrefVisitor V; + V.visitEachChild(this); - UnrefVisitor V; - V.visitEachChild(this); + delete this; + } }