fixed: ast memory leak leaf nodes
This commit is contained in:
parent
f069d04ad1
commit
2de4f7b460
|
@ -41,6 +41,20 @@ AST_NODE_PTR AST_new_node(TokenLocation location, enum AST_SyntaxElement_t kind,
|
|||
return node;
|
||||
}
|
||||
|
||||
size_t AST_child_count(AST_NODE_PTR node) {
|
||||
assert(node != NULL);
|
||||
assert(node->children != NULL);
|
||||
|
||||
return node->children->len;
|
||||
}
|
||||
|
||||
AST_NODE_PTR AST_get_last_node(AST_NODE_PTR node) {
|
||||
assert(node != NULL);
|
||||
assert(node->children != NULL);
|
||||
|
||||
return AST_get_node(node, AST_child_count(node) - 1);
|
||||
}
|
||||
|
||||
static const char *lookup_table[AST_ELEMENT_COUNT] = {"__UNINIT__"};
|
||||
|
||||
void AST_init() {
|
||||
|
@ -198,14 +212,12 @@ AST_NODE_PTR AST_remove_child(AST_NODE_PTR owner, const size_t idx) {
|
|||
return child;
|
||||
}
|
||||
|
||||
AST_NODE_PTR AST_detach_child(AST_NODE_PTR owner, AST_NODE_PTR child) {
|
||||
assert(owner != NULL);
|
||||
AST_NODE_PTR AST_detach_child(AST_NODE_PTR child) {
|
||||
assert(child != NULL);
|
||||
assert(owner->children != NULL);
|
||||
|
||||
for (size_t i = 0; i < owner->children->len; i++) {
|
||||
if (AST_get_node(owner, i) == child) {
|
||||
return AST_remove_child(owner, i);
|
||||
for (size_t i = 0; i < AST_child_count(child->parent); i++) {
|
||||
if (AST_get_node(child->parent, i) == child) {
|
||||
return AST_remove_child(child->parent, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,23 +229,22 @@ void AST_delete_node(AST_NODE_PTR node) {
|
|||
|
||||
DEBUG("Deleting AST node: %p", node);
|
||||
|
||||
if (node->children == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->parent != NULL) {
|
||||
AST_NODE_PTR child = AST_detach_child(node->parent, node);
|
||||
AST_NODE_PTR child = AST_detach_child(node);
|
||||
assert(child == node);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node->children->len; i++) {
|
||||
// prevent detach of children node
|
||||
if (node->children != NULL) {
|
||||
for (size_t i = 0; i < AST_child_count(node); i++) {
|
||||
AST_NODE_PTR child = AST_get_node(node, i);
|
||||
// prevent detach of children node
|
||||
child->parent = NULL;
|
||||
AST_delete_node(child);
|
||||
}
|
||||
|
||||
g_array_free(node->children, TRUE);
|
||||
}
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,20 @@ void AST_init(void);
|
|||
[[gnu::nonnull(1)]]
|
||||
const char* AST_node_to_string(AST_NODE_PTR node);
|
||||
|
||||
/**
|
||||
* @brief Return the amount of children
|
||||
* @param node
|
||||
* @return
|
||||
*/
|
||||
size_t AST_child_count(AST_NODE_PTR node);
|
||||
|
||||
/**
|
||||
* @brief Return the last node of the children
|
||||
* @param node
|
||||
* @return
|
||||
*/
|
||||
AST_NODE_PTR AST_get_last_node(AST_NODE_PTR node);
|
||||
|
||||
/**
|
||||
* @brief Create a new node struct on the system heap. Initializes the struct with the given values.
|
||||
* All other fields are set to either NULL or 0. No allocation for children array is preformed.
|
||||
|
@ -162,13 +176,12 @@ AST_NODE_PTR AST_remove_child(AST_NODE_PTR owner, size_t idx);
|
|||
* @brief Detach a child from its parent. This involves removing the child from its parent
|
||||
* and marking the parent of the child as NULL.
|
||||
* @attention The returned pointer is still valid. It must be freed at some pointer later.
|
||||
* @param owner the owner to remove the child from
|
||||
* @param child the child to detach
|
||||
* @return a pointer to child detached
|
||||
*/
|
||||
[[nodiscard("pointer must be freed")]]
|
||||
[[gnu::nonnull(1), gnu::nonnull(1)]]
|
||||
AST_NODE_PTR AST_detach_child(AST_NODE_PTR owner, AST_NODE_PTR child);
|
||||
AST_NODE_PTR AST_detach_child(AST_NODE_PTR child);
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the n-th child of a node
|
||||
|
|
Loading…
Reference in New Issue