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;
|
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__"};
|
static const char *lookup_table[AST_ELEMENT_COUNT] = {"__UNINIT__"};
|
||||||
|
|
||||||
void AST_init() {
|
void AST_init() {
|
||||||
|
@ -175,7 +189,7 @@ AST_NODE_PTR AST_get_node(AST_NODE_PTR owner, const size_t idx) {
|
||||||
PANIC("AST owner node has no children");
|
PANIC("AST owner node has no children");
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_NODE_PTR child = ((AST_NODE_PTR*) owner->children->data)[idx];
|
AST_NODE_PTR child = ((AST_NODE_PTR *) owner->children->data)[idx];
|
||||||
|
|
||||||
if (child == NULL) {
|
if (child == NULL) {
|
||||||
PANIC("child node is NULL");
|
PANIC("child node is NULL");
|
||||||
|
@ -198,14 +212,12 @@ AST_NODE_PTR AST_remove_child(AST_NODE_PTR owner, const size_t idx) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_NODE_PTR AST_detach_child(AST_NODE_PTR owner, AST_NODE_PTR child) {
|
AST_NODE_PTR AST_detach_child(AST_NODE_PTR child) {
|
||||||
assert(owner != NULL);
|
|
||||||
assert(child != NULL);
|
assert(child != NULL);
|
||||||
assert(owner->children != NULL);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < owner->children->len; i++) {
|
for (size_t i = 0; i < AST_child_count(child->parent); i++) {
|
||||||
if (AST_get_node(owner, i) == child) {
|
if (AST_get_node(child->parent, i) == child) {
|
||||||
return AST_remove_child(owner, i);
|
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);
|
DEBUG("Deleting AST node: %p", node);
|
||||||
|
|
||||||
if (node->children == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->parent != NULL) {
|
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);
|
assert(child == node);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < node->children->len; i++) {
|
if (node->children != NULL) {
|
||||||
// prevent detach of children node
|
for (size_t i = 0; i < AST_child_count(node); i++) {
|
||||||
AST_NODE_PTR child = AST_get_node(node, i);
|
AST_NODE_PTR child = AST_get_node(node, i);
|
||||||
child->parent = NULL;
|
// prevent detach of children node
|
||||||
AST_delete_node(child);
|
child->parent = NULL;
|
||||||
|
AST_delete_node(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free(node->children, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_free(node->children, TRUE);
|
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,20 @@ void AST_init(void);
|
||||||
[[gnu::nonnull(1)]]
|
[[gnu::nonnull(1)]]
|
||||||
const char* AST_node_to_string(AST_NODE_PTR node);
|
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.
|
* @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.
|
* 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
|
* @brief Detach a child from its parent. This involves removing the child from its parent
|
||||||
* and marking the parent of the child as NULL.
|
* and marking the parent of the child as NULL.
|
||||||
* @attention The returned pointer is still valid. It must be freed at some pointer later.
|
* @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
|
* @param child the child to detach
|
||||||
* @return a pointer to child detached
|
* @return a pointer to child detached
|
||||||
*/
|
*/
|
||||||
[[nodiscard("pointer must be freed")]]
|
[[nodiscard("pointer must be freed")]]
|
||||||
[[gnu::nonnull(1), gnu::nonnull(1)]]
|
[[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
|
* @brief Return a pointer to the n-th child of a node
|
||||||
|
|
Loading…
Reference in New Issue