#include <algorithm>
#include <cstring>
#include <functional>
#include <limits>
#include <regex>
#include <string>
#include <utility>
#include <vector>

#include "UhdmAst.h"
#include "frontends/ast/ast.h"
#include "libs/sha1/sha1.h"

// UHDM
#include <uhdm/ExprEval.h>
#include <uhdm/uhdm.h>
#include <uhdm/vpi_user.h>

#include "third_party/yosys/const2ast.h"

YOSYS_NAMESPACE_BEGIN
namespace VERILOG_FRONTEND
{
extern bool sv_mode;
}
YOSYS_NAMESPACE_END

namespace systemverilog_plugin
{

using namespace ::Yosys;

namespace AST
{
using namespace ::Yosys::AST;

namespace Extended
{
enum AstNodeTypeExtended {
    AST_DOT = ::Yosys::AST::AST_BIND + 1, // here we always want to point to the last element of yosys' AstNodeType
    AST_BREAK,
    AST_CONTINUE
};
}
} // namespace AST

namespace attr_id
{
static IdString partial;
static IdString packed_ranges;
static IdString unpacked_ranges;
static IdString force_convert;
static IdString is_imported;
static IdString is_simplified_wire;
static IdString low_high_bound;
}; // namespace attr_id

// TODO(mglb): use attr_id::* directly everywhere and remove those methods.
/*static*/ const IdString &UhdmAst::partial() { return attr_id::partial; }
/*static*/ const IdString &UhdmAst::packed_ranges() { return attr_id::packed_ranges; }
/*static*/ const IdString &UhdmAst::unpacked_ranges() { return attr_id::unpacked_ranges; }
/*static*/ const IdString &UhdmAst::force_convert() { return attr_id::force_convert; }
/*static*/ const IdString &UhdmAst::is_imported() { return attr_id::is_imported; }
/*static*/ const IdString &UhdmAst::is_simplified_wire() { return attr_id::is_simplified_wire; }
/*static*/ const IdString &UhdmAst::low_high_bound() { return attr_id::low_high_bound; }

void attr_id_init()
{
    // Initialize only once
    static bool already_initialized = false;
    if (already_initialized)
        return;
    already_initialized = true;

    // Actual initialization

    // Register IdStrings. Can't be done statically, as the IdString class uses resources created during Yosys initialization which happens after
    // static initialization of the plugin when everything is statically linked.
    attr_id::partial = IdString("$systemverilog_plugin$partial");
    attr_id::packed_ranges = IdString("$systemverilog_plugin$packed_ranges");
    attr_id::unpacked_ranges = IdString("$systemverilog_plugin$unpacked_ranges");
    attr_id::force_convert = IdString("$systemverilog_plugin$force_convert");
    attr_id::is_imported = IdString("$systemverilog_plugin$is_imported");
    attr_id::is_simplified_wire = IdString("$systemverilog_plugin$is_simplified_wire");
    attr_id::low_high_bound = IdString("$systemverilog_plugin$low_high_bound");
}

void attr_id_cleanup()
{
    // Release static copies of private IdStrings.
    attr_id::low_high_bound = IdString();
    attr_id::is_simplified_wire = IdString();
    attr_id::is_imported = IdString();
    attr_id::force_convert = IdString();
    attr_id::unpacked_ranges = IdString();
    attr_id::packed_ranges = IdString();
    attr_id::partial = IdString();
}

// Delete the selected attribute if it exists.
// Does nothing if the node doesn't exist, or the attribute doesn't exists.
static void delete_attribute(AST::AstNode *node, const IdString &attribute)
{
    if (!node)
        return;

    if (node->attributes.count(attribute)) {
        delete node->attributes[attribute];
        node->attributes.erase(attribute);
    }
}

// Delete all attributes that belong to the SV plugin.
// The attributes beloning to Yosys are *not* deleted here.
static void delete_internal_attributes(AST::AstNode *node)
{
    if (!node)
        return;

    for (auto &attr : {UhdmAst::partial(), UhdmAst::packed_ranges(), UhdmAst::unpacked_ranges(), UhdmAst::force_convert(), UhdmAst::is_imported(),
                       UhdmAst::is_simplified_wire(), UhdmAst::low_high_bound()}) {
        delete_attribute(node, attr);
    }
}

// Delete all children nodes.
// Does *not* delete attributes.
// This function exists as Yosys's function node->delete_children() does remove all children and attributes.
static void delete_children(AST::AstNode *node)
{
    if (!node)
        return;

    for (auto *child : node->children) {
        delete child;
    }
    node->children.clear();
}

static void simplify(AST::AstNode *current_node, AST::AstNode *parent_node);

static void sanitize_symbol_name(std::string &name)
{
    if (!name.empty()) {
        auto pos = name.find_last_of('@');
        name = name.substr(pos + 1);
        // symbol names must begin with '\'
        name.insert(0, "\\");
    }
}

static std::string get_name(vpiHandle obj_h, bool prefer_full_name = false)
{
    auto first_check = prefer_full_name ? vpiFullName : vpiName;
    auto last_check = prefer_full_name ? vpiName : vpiFullName;
    std::string name;
    if (auto s = vpi_get_str(first_check, obj_h)) {
        name = s;
    } else if (auto s = vpi_get_str(vpiDefName, obj_h)) {
        name = s;
    } else if (auto s = vpi_get_str(last_check, obj_h)) {
        name = s;
    }
    if (name.rfind('.') != std::string::npos) {
        name = name.substr(name.rfind('.') + 1);
    }
    sanitize_symbol_name(name);
    return name;
}

static std::string strip_package_name(std::string name)
{
    auto sep_index = name.find("::");
    if (sep_index != string::npos) {
        name = name.substr(sep_index + 1);
        name[0] = '\\';
    }
    return name;
}

static std::string get_object_name(vpiHandle obj_h, const std::vector<int> &name_fields = {vpiName})
{
    std::string objectName;
    for (auto name : name_fields) {
        if (auto s = vpi_get_str(name, obj_h)) {
            objectName = s;
            sanitize_symbol_name(objectName);
            break;
        }
    }
    return objectName;
}

static AST::AstNode *mkconst_real(double d)
{
    AST::AstNode *node = new AST::AstNode(AST::AST_REALVALUE);
    node->realvalue = d;
    return node;
}

static AST::AstNode *make_range(int left, int right, bool is_signed = false)
{
    // generate a pre-validated range node for a fixed signal range.
    auto range = new AST::AstNode(AST::AST_RANGE);
    range->range_left = left;
    range->range_right = right;
    range->range_valid = true;
    range->children.push_back(AST::AstNode::mkconst_int(left, true));
    range->children.push_back(AST::AstNode::mkconst_int(right, true));
    range->is_signed = is_signed;
    return range;
}

static void copy_packed_unpacked_attribute(AST::AstNode *from, AST::AstNode *to)
{
    if (!to->attributes.count(UhdmAst::packed_ranges()))
        to->attributes[UhdmAst::packed_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
    if (!to->attributes.count(UhdmAst::unpacked_ranges()))
        to->attributes[UhdmAst::unpacked_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
    if (from->attributes.count(UhdmAst::packed_ranges())) {
        for (auto r : from->attributes[UhdmAst::packed_ranges()]->children) {
            to->attributes[UhdmAst::packed_ranges()]->children.push_back(r->clone());
        }
    }
    if (from->attributes.count(UhdmAst::unpacked_ranges())) {
        for (auto r : from->attributes[UhdmAst::unpacked_ranges()]->children) {
            to->attributes[UhdmAst::unpacked_ranges()]->children.push_back(r->clone());
        }
    }
}

static int get_max_offset_struct(AST::AstNode *node)
{
    // get the width from the MS member in the struct
    // as members are laid out from left to right in the packed wire
    log_assert(node->type == AST::AST_STRUCT || node->type == AST::AST_UNION);
    while (node->range_left < 0) {
        node = node->children[0];
    }
    return node->range_left;
}

static void visitEachDescendant(AST::AstNode *node, const std::function<void(AST::AstNode *)> &f)
{
    for (auto child : node->children) {
        f(child);
        visitEachDescendant(child, f);
    }
}

static void add_multirange_wire(AST::AstNode *node, std::vector<AST::AstNode *> packed_ranges, std::vector<AST::AstNode *> unpacked_ranges,
                                bool reverse = true)
{
    delete_attribute(node, UhdmAst::packed_ranges());
    node->attributes[UhdmAst::packed_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
    if (!packed_ranges.empty()) {
        if (reverse)
            std::reverse(packed_ranges.begin(), packed_ranges.end());
        node->attributes[UhdmAst::packed_ranges()]->children = std::move(packed_ranges);
    }

    delete_attribute(node, UhdmAst::unpacked_ranges());
    node->attributes[UhdmAst::unpacked_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
    if (!unpacked_ranges.empty()) {
        if (reverse)
            std::reverse(unpacked_ranges.begin(), unpacked_ranges.end());
        node->attributes[UhdmAst::unpacked_ranges()]->children = std::move(unpacked_ranges);
    }
}

static size_t add_multirange_attribute(AST::AstNode *wire_node, const std::vector<AST::AstNode *> ranges)
{
    size_t size = 1;
    for (size_t i = 0; i < ranges.size(); i++) {
        log_assert(AST_INTERNAL::current_ast_mod);
        if (ranges[i]->children.size() == 1) {
            ranges[i]->children.push_back(ranges[i]->children[0]->clone());
        }
        simplify(ranges[i], wire_node);
        while (ranges[i]->simplify(true, false, false, 1, -1, false, false)) {
        }
        // this workaround case, where yosys doesn't follow id2ast and simplifies it to resolve constant
        if (ranges[i]->children[0]->id2ast) {
            simplify(ranges[i]->children[0]->id2ast, ranges[i]->children[0]);
            while (ranges[i]->children[0]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
            }
        }
        if (ranges[i]->children[1]->id2ast) {
            simplify(ranges[i]->children[1]->id2ast, ranges[i]->children[1]);
            while (ranges[i]->children[1]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
            }
        }
        simplify(ranges[i], wire_node);
        while (ranges[i]->simplify(true, false, false, 1, -1, false, false)) {
        }
        log_assert(ranges[i]->children[0]->type == AST::AST_CONSTANT);
        log_assert(ranges[i]->children[1]->type == AST::AST_CONSTANT);
        if (wire_node->type != AST::AST_STRUCT_ITEM) {
            wire_node->multirange_dimensions.push_back(min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer));
            wire_node->multirange_swapped.push_back(ranges[i]->range_swapped);
        }
        auto elem_size = max(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer) -
                         min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer) + 1;
        if (wire_node->type != AST::AST_STRUCT_ITEM || (wire_node->type == AST::AST_STRUCT_ITEM && i == 0)) {
            wire_node->multirange_dimensions.push_back(elem_size);
        }
        size *= elem_size;
    }
    return size;
}

static AST::AstNode *convert_range(AST::AstNode *id, int packed_ranges_size, int unpacked_ranges_size, int i)
{
    log_assert(AST_INTERNAL::current_ast_mod);
    log_assert(AST_INTERNAL::current_scope.count(id->str));
    AST::AstNode *wire_node = AST_INTERNAL::current_scope[id->str];
    log_assert(!wire_node->multirange_dimensions.empty());
    int elem_size = 1;
    std::vector<int> single_elem_size;
    single_elem_size.push_back(elem_size);
    for (size_t j = 0; (j + 1) < wire_node->multirange_dimensions.size(); j = j + 2) {
        elem_size *= wire_node->multirange_dimensions[j + 1] - wire_node->multirange_dimensions[j];
        single_elem_size.push_back(elem_size);
    }
    std::reverse(single_elem_size.begin(), single_elem_size.end());
    log_assert(i < (unpacked_ranges_size + packed_ranges_size));
    log_assert(!id->children.empty());
    AST::AstNode *result = nullptr;
    // we want to start converting from the end
    if (i < static_cast<int>(id->children.size()) - 1) {
        result = convert_range(id, packed_ranges_size, unpacked_ranges_size, i + 1);
    }
    // special case, we want to select whole wire
    if (id->children.size() == 0 && i == 0) {
        result = make_range(single_elem_size[i] - 1, 0);
    } else {
        AST::AstNode *range_left = nullptr;
        AST::AstNode *range_right = nullptr;
        if (id->children[i]->children.size() == 2) {
            range_left = id->children[i]->children[0]->clone();
            range_right = id->children[i]->children[1]->clone();
        } else {
            range_left = id->children[i]->children[0]->clone();
            range_right = id->children[i]->children[0]->clone();
        }
        if (!wire_node->multirange_swapped.empty()) {
            bool is_swapped = wire_node->multirange_swapped[wire_node->multirange_swapped.size() - i - 1];
            auto right_idx = wire_node->multirange_dimensions.size() - (i * 2) - 2;
            if (is_swapped) {
                auto left_idx = wire_node->multirange_dimensions.size() - (i * 2) - 1;
                auto elem_size = wire_node->multirange_dimensions[left_idx] - wire_node->multirange_dimensions[right_idx];
                range_left = new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(elem_size - 1, false), range_left);
                range_right = new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(elem_size - 1, false), range_right);
            } else if (wire_node->multirange_dimensions[right_idx] != 0) {
                range_left =
                  new AST::AstNode(AST::AST_SUB, range_left, AST::AstNode::mkconst_int(wire_node->multirange_dimensions[right_idx], false));
                range_right =
                  new AST::AstNode(AST::AST_SUB, range_right, AST::AstNode::mkconst_int(wire_node->multirange_dimensions[right_idx], false));
            }
        }
        range_left = new AST::AstNode(AST::AST_SUB,
                                      new AST::AstNode(AST::AST_MUL, new AST::AstNode(AST::AST_ADD, range_left, AST::AstNode::mkconst_int(1, false)),
                                                       AST::AstNode::mkconst_int(single_elem_size[i + 1], false)),
                                      AST::AstNode::mkconst_int(1, false));
        range_right = new AST::AstNode(AST::AST_MUL, range_right, AST::AstNode::mkconst_int(single_elem_size[i + 1], false));
        if (result) {
            range_right = new AST::AstNode(AST::AST_ADD, range_right, result->children[1]->clone());
            range_left = new AST::AstNode(AST::AST_SUB, new AST::AstNode(AST::AST_ADD, range_right->clone(), result->children[0]->clone()),
                                          result->children[1]->clone());
            delete result;
            result = nullptr;
        }
        result = new AST::AstNode(AST::AST_RANGE, range_left, range_right);
    }
    // return range from *current* selected range
    // in the end, it results in whole selected range
    id->basic_prep = true;
    return result;
}

static void resolve_wiretype(AST::AstNode *wire_node)
{
    AST::AstNode *wiretype_node = nullptr;
    if (!wire_node->children.empty()) {
        if (wire_node->children[0]->type == AST::AST_WIRETYPE) {
            wiretype_node = wire_node->children[0];
        }
    }
    if (wire_node->children.size() > 1) {
        if (wire_node->children[1]->type == AST::AST_WIRETYPE) {
            wiretype_node = wire_node->children[1];
        }
    }
    if (wiretype_node == nullptr)
        return;
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    // First check if it has already defined ranges
    if (wire_node->attributes.count(UhdmAst::packed_ranges())) {
        for (auto r : wire_node->attributes[UhdmAst::packed_ranges()]->children) {
            packed_ranges.push_back(r->clone());
        }
    }
    if (wire_node->attributes.count(UhdmAst::unpacked_ranges())) {
        for (auto r : wire_node->attributes[UhdmAst::unpacked_ranges()]->children) {
            unpacked_ranges.push_back(r->clone());
        }
    }
    AST::AstNode *wiretype_ast = nullptr;
    log_assert(AST_INTERNAL::current_scope.count(wiretype_node->str));
    wiretype_ast = AST_INTERNAL::current_scope[wiretype_node->str];
    // we need to setup current top ast as this simplify
    // needs to have access to all already defined ids
    while (wire_node->simplify(true, false, false, 1, -1, false, false)) {
    }
    if (wiretype_ast->children[0]->type == AST::AST_STRUCT && wire_node->type == AST::AST_WIRE) {
        auto struct_width = get_max_offset_struct(wiretype_ast->children[0]);
        wire_node->range_left = struct_width;
        wire_node->children[0]->range_left = struct_width;
        wire_node->children[0]->children[0]->integer = struct_width;
    }
    if (wiretype_ast && wire_node->attributes.count(ID::wiretype)) {
        log_assert(wiretype_ast->type == AST::AST_TYPEDEF);
        wire_node->attributes[ID::wiretype]->id2ast = wiretype_ast->children[0];
    }
    if ((wire_node->children[0]->type == AST::AST_RANGE || (wire_node->children.size() > 1 && wire_node->children[1]->type == AST::AST_RANGE)) &&
        wire_node->multirange_dimensions.empty()) {
        if (wiretype_ast && !wiretype_ast->children.empty() && wiretype_ast->children[0]->attributes.count(UhdmAst::packed_ranges()) &&
            wiretype_ast->children[0]->attributes.count(UhdmAst::unpacked_ranges())) {
            for (auto r : wiretype_ast->children[0]->attributes[UhdmAst::packed_ranges()]->children) {
                packed_ranges.push_back(r->clone());
            }
            for (auto r : wiretype_ast->children[0]->attributes[UhdmAst::unpacked_ranges()]->children) {
                unpacked_ranges.push_back(r->clone());
            }
        } else {
            if (wire_node->children[0]->type == AST::AST_RANGE)
                packed_ranges.push_back(wire_node->children[0]->clone());
            else if (wire_node->children[1]->type == AST::AST_RANGE)
                packed_ranges.push_back(wire_node->children[1]->clone());
            else
                log_error("Unhandled case in resolve_wiretype!\n");
        }
        AST::AstNode *value = nullptr;
        if (wire_node->children[0]->type != AST::AST_RANGE) {
            value = wire_node->children[0]->clone();
        }
        delete_children(wire_node);
        if (value)
            wire_node->children.push_back(value);
        wire_node->attributes[UhdmAst::packed_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
        if (!packed_ranges.empty()) {
            std::reverse(packed_ranges.begin(), packed_ranges.end());
            wire_node->attributes[UhdmAst::packed_ranges()]->children.insert(wire_node->attributes[UhdmAst::packed_ranges()]->children.end(),
                                                                             packed_ranges.begin(), packed_ranges.end());
            packed_ranges.clear();
        }

        wire_node->attributes[UhdmAst::unpacked_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
        if (!unpacked_ranges.empty()) {
            wire_node->attributes[UhdmAst::unpacked_ranges()]->children.insert(wire_node->attributes[UhdmAst::unpacked_ranges()]->children.end(),
                                                                               unpacked_ranges.begin(), unpacked_ranges.end());
            unpacked_ranges.clear();
        }
    }
    for (auto *range : packed_ranges) {
        delete range;
    }
    for (auto *range : unpacked_ranges) {
        delete range;
    }
}

static void add_force_convert_attribute(AST::AstNode *wire_node, uint32_t val = 1)
{
    AST::AstNode *&attr = wire_node->attributes[UhdmAst::force_convert()];
    if (!attr) {
        attr = AST::AstNode::mkconst_int(val, true);
    } else if (attr->integer != val) {
        attr->integer = val;
    }
}

static void check_memories(AST::AstNode *node, std::string scope, std::map<std::string, AST::AstNode *> &memories)
{
    for (auto *child : node->children) {
        check_memories(child, node->type == AST::AST_GENBLOCK ? scope + "." + node->str : scope, memories);
    }

    if (node->str == "\\$readmemh") {
        if (node->children.size() != 2 || node->children[1]->str.empty() || node->children[1]->type != AST::AST_IDENTIFIER) {
            log_error("%s:%d: Wrong usage of '\\$readmemh'\n", node->filename.c_str(), node->location.first_line);
        }
        // TODO: Look for the memory in all other scope levels, like we do in case of AST::AST_IDENTIFIER,
        // as here the memory can also be defined before before the current scope.
        std::string name = scope + "." + node->children[1]->str;
        const auto iter = memories.find(name);
        if (iter != memories.end()) {
            add_force_convert_attribute(iter->second, 0);
        }
    }

    if (node->type == AST::AST_WIRE) {
        const std::size_t packed_ranges_count =
          node->attributes.count(UhdmAst::packed_ranges()) ? node->attributes[UhdmAst::packed_ranges()]->children.size() : 0;
        const std::size_t unpacked_ranges_count =
          node->attributes.count(UhdmAst::unpacked_ranges()) ? node->attributes[UhdmAst::unpacked_ranges()]->children.size() : 0;

        if (packed_ranges_count == 1 && unpacked_ranges_count == 1) {
            std::string name = scope + "." + node->str;
            auto [iter, did_insert] = memories.insert_or_assign(std::move(name), node);
            log_assert(did_insert);
        }
        return;
    }

    if (node->type == AST::AST_IDENTIFIER) {
        std::string full_id = scope;
        std::size_t scope_end_pos = scope.size();

        for (;;) {
            full_id += "." + node->str;
            const auto iter = memories.find(full_id);
            if (iter != memories.end()) {
                // Memory node found!
                if (!iter->second->attributes.count(UhdmAst::force_convert())) {
                    const bool is_full_memory_access = (node->children.size() == 0);
                    const bool is_slice_memory_access = (node->children.size() == 1 && node->children[0]->children.size() != 1);
                    // convert memory to list of registers
                    // in case of access to whole memory
                    // or slice of memory
                    // e.g.
                    // logic [3:0] mem [8:0];
                    // always_ff @ (posedge clk) begin
                    //   mem <= '{default:0};
                    //   mem[7:1] <= mem[6:0];
                    // end
                    // don't convert in case of accessing
                    // memory using address, e.g.
                    // mem[0] <= '{default:0}
                    if (is_full_memory_access || is_slice_memory_access) {
                        add_force_convert_attribute(iter->second);
                    }
                }
                break;
            } else {
                if (scope_end_pos == 0) {
                    // We reached the top scope and the memory node wasn't found.
                    break;
                } else {
                    // Memory node wasn't found.
                    // Erase node name and last segment of the scope to check the previous scope.
                    // FIXME: This doesn't work with escaped identifiers containing a dot.
                    scope_end_pos = full_id.find_last_of('.', scope_end_pos - 1);
                    if (scope_end_pos == std::string::npos) {
                        scope_end_pos = 0;
                    }
                    full_id.erase(scope_end_pos);
                }
            }
        }
    }
}

static void check_memories(AST::AstNode *node)
{
    std::map<std::string, AST::AstNode *> memories;
    check_memories(node, "", memories);
}

static void warn_start_range(const std::vector<AST::AstNode *> ranges)
{
    for (size_t i = 0; i < ranges.size(); i++) {
        auto start_elem = min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer);
        if (start_elem != 0) {
            log_file_warning(ranges[i]->filename, ranges[i]->location.first_line, "Limited support for multirange wires that don't start from 0\n");
        }
    }
}

// This function is workaround missing support for multirange (with n-ranges) packed/unpacked nodes
// It converts multirange node to single-range node and translates access to this node
// to correct range
static void convert_packed_unpacked_range(AST::AstNode *wire_node)
{
    resolve_wiretype(wire_node);
    const std::vector<AST::AstNode *> packed_ranges = wire_node->attributes.count(UhdmAst::packed_ranges())
                                                        ? wire_node->attributes[UhdmAst::packed_ranges()]->children
                                                        : std::vector<AST::AstNode *>();
    const std::vector<AST::AstNode *> unpacked_ranges = wire_node->attributes.count(UhdmAst::unpacked_ranges())
                                                          ? wire_node->attributes[UhdmAst::unpacked_ranges()]->children
                                                          : std::vector<AST::AstNode *>();
    if (packed_ranges.empty() && unpacked_ranges.empty()) {
        delete_attribute(wire_node, UhdmAst::packed_ranges());
        delete_attribute(wire_node, UhdmAst::unpacked_ranges());
        wire_node->range_left = 0;
        wire_node->range_right = 0;
        wire_node->range_valid = true;
        return;
    }
    std::vector<AST::AstNode *> ranges;

    // Convert only when node is not a memory and at least 1 of the ranges has more than 1 range
    const bool convert_node = [&]() {
        if (wire_node->type == AST::AST_MEMORY)
            return false;
        if (packed_ranges.size() > 1)
            return true;
        if (unpacked_ranges.size() > 1)
            return true;
        if (wire_node->attributes.count(ID::wiretype))
            return true;
        if (wire_node->type == AST::AST_PARAMETER)
            return true;
        if (wire_node->type == AST::AST_LOCALPARAM)
            return true;
        if ((wire_node->is_input || wire_node->is_output) && (packed_ranges.size() > 0 || unpacked_ranges.size() > 0))
            return true;
        if (wire_node->attributes.count(UhdmAst::force_convert()) && wire_node->attributes[UhdmAst::force_convert()]->integer == 1)
            return true;
        return false;
    }();
    if (convert_node) {
        // if not already converted
        if (wire_node->multirange_dimensions.empty()) {
            const size_t packed_size = add_multirange_attribute(wire_node, packed_ranges);
            const size_t unpacked_size = add_multirange_attribute(wire_node, unpacked_ranges);
            if (packed_ranges.size() == 1 && unpacked_ranges.empty()) {
                ranges.push_back(packed_ranges[0]->clone());
            } else if (unpacked_ranges.size() == 1 && packed_ranges.empty()) {
                ranges.push_back(unpacked_ranges[0]->clone());
            } else {
                // currently we have limited support
                // for multirange wires that doesn't start from 0
                warn_start_range(packed_ranges);
                warn_start_range(unpacked_ranges);
                const size_t size = packed_size * unpacked_size;
                log_assert(size >= 1);
                ranges.push_back(make_range(size - 1, 0));
            }
        }
    } else {
        for (auto r : packed_ranges) {
            ranges.push_back(r->clone());
        }
        for (auto r : unpacked_ranges) {
            ranges.push_back(r->clone());
        }
        // if there is only one packed and one unpacked range,
        // and wire is not port wire, change type to AST_MEMORY
        if (wire_node->type == AST::AST_WIRE && packed_ranges.size() == 1 && unpacked_ranges.size() == 1 && !wire_node->is_input &&
            !wire_node->is_output) {
            wire_node->type = AST::AST_MEMORY;
            wire_node->is_logic = true;
        }
    }

    if (wire_node->type == AST::AST_STRUCT_ITEM || wire_node->type == AST::AST_STRUCT) {
        delete_attribute(wire_node, UhdmAst::packed_ranges());
        delete_attribute(wire_node, UhdmAst::unpacked_ranges());
    }

    // Insert new range
    wire_node->children.insert(wire_node->children.end(), ranges.begin(), ranges.end());
}

static AST::AstNode *expand_dot(const AST::AstNode *current_struct, const AST::AstNode *search_node)
{
    AST::AstNode *current_struct_elem = nullptr;
    auto search_str = search_node->str.find("\\") == 0 ? search_node->str.substr(1) : search_node->str;
    auto struct_elem_it =
      std::find_if(current_struct->children.begin(), current_struct->children.end(), [&](AST::AstNode *node) { return node->str == search_str; });
    if (struct_elem_it == current_struct->children.end()) {
        current_struct->dumpAst(NULL, "struct >");
        log_error("Couldn't find search elem: %s in struct\n", search_str.c_str());
    }
    current_struct_elem = *struct_elem_it;

    AST::AstNode *left = nullptr, *right = nullptr;
    if (current_struct_elem->type == AST::AST_STRUCT_ITEM) {
        left = AST::AstNode::mkconst_int(current_struct_elem->range_left, true);
        right = AST::AstNode::mkconst_int(current_struct_elem->range_right, true);
    } else if (current_struct_elem->type == AST::AST_STRUCT) {
        // Struct can have multiple range, so to get size of 1 struct,
        // we get left range for first children, and right range for last children
        left = AST::AstNode::mkconst_int(current_struct_elem->children.front()->range_left, true);
        right = AST::AstNode::mkconst_int(current_struct_elem->children.back()->range_right, true);
    } else if (current_struct_elem->type == AST::AST_UNION) {
        left = AST::AstNode::mkconst_int(current_struct_elem->range_left, true);
        right = AST::AstNode::mkconst_int(current_struct_elem->range_right, true);
    } else {
        // Structs currently can only have AST_STRUCT, AST_STRUCT_ITEM, or AST_UNION.
        log_file_error(current_struct_elem->filename, current_struct_elem->location.first_line,
                       "Accessing struct member of type %s is unsupported.\n", type2str(current_struct_elem->type).c_str());
    }

    auto elem_size =
      new AST::AstNode(AST::AST_ADD, new AST::AstNode(AST::AST_SUB, left->clone(), right->clone()), AST::AstNode::mkconst_int(1, true));
    AST::AstNode *sub_dot = nullptr;
    AST::AstNode *struct_range = nullptr;

    for (auto c : search_node->children) {
        if (c->type == static_cast<int>(AST::Extended::AST_DOT)) {
            // There should be only 1 AST_DOT node children
            log_assert(!sub_dot);
            sub_dot = expand_dot(current_struct_elem, c);
        }
        if (c->type == AST::AST_RANGE) {
            // Currently supporting only 1 range
            log_assert(!struct_range);
            struct_range = c;
        }
    }
    if (sub_dot) {
        // First select correct element in first struct
        std::swap(left, sub_dot->children[0]);
        std::swap(right, sub_dot->children[1]);
        delete sub_dot;
    }
    if (struct_range) {
        // now we have correct element set,
        // but we still need to set correct struct
        log_assert(!struct_range->children.empty());
        if (current_struct_elem->type == AST::AST_STRUCT_ITEM) {
            // if we selecting range of struct item, just add this range
            // to our current select
            if (struct_range->children.size() == 2) {
                auto range_size = new AST::AstNode(
                  AST::AST_ADD, new AST::AstNode(AST::AST_SUB, struct_range->children[0]->clone(), struct_range->children[1]->clone()),
                  AST::AstNode::mkconst_int(1, true));
                right = new AST::AstNode(AST::AST_ADD, right, struct_range->children[1]->clone());
                left = new AST::AstNode(
                  AST::AST_ADD, left,
                  new AST::AstNode(AST::AST_ADD, struct_range->children[1]->clone(), new AST::AstNode(AST::AST_SUB, range_size, elem_size->clone())));
            } else if (struct_range->children.size() == 1) {
                if (!current_struct_elem->multirange_dimensions.empty()) {
                    right = new AST::AstNode(AST::AST_ADD, right,
                                             new AST::AstNode(AST::AST_MUL, struct_range->children[0]->clone(),
                                                              AST::AstNode::mkconst_int(current_struct_elem->multirange_dimensions.back(), true)));
                    delete left;
                    left = new AST::AstNode(AST::AST_ADD, right->clone(),
                                            AST::AstNode::mkconst_int(current_struct_elem->multirange_dimensions.back() - 1, true));
                } else {
                    right = new AST::AstNode(AST::AST_ADD, right, struct_range->children[0]->clone());
                    delete left;
                    left = right->clone();
                }
            } else {
                struct_range->dumpAst(NULL, "range >");
                log_error("Unhandled range select (AST_STRUCT_ITEM) in AST_DOT!\n");
            }
        } else if (current_struct_elem->type == AST::AST_STRUCT) {
            if (struct_range->children.size() == 2) {
                right = new AST::AstNode(AST::AST_ADD, right, struct_range->children[1]->clone());
                auto range_size = new AST::AstNode(
                  AST::AST_ADD, new AST::AstNode(AST::AST_SUB, struct_range->children[0]->clone(), struct_range->children[1]->clone()),
                  AST::AstNode::mkconst_int(1, true));
                left = new AST::AstNode(AST::AST_ADD, left, new AST::AstNode(AST::AST_SUB, range_size, elem_size->clone()));
            } else if (struct_range->children.size() == 1) {
                AST::AstNode *mul = new AST::AstNode(AST::AST_MUL, elem_size->clone(), struct_range->children[0]->clone());

                left = new AST::AstNode(AST::AST_ADD, left, mul);
                right = new AST::AstNode(AST::AST_ADD, right, mul->clone());
            } else {
                struct_range->dumpAst(NULL, "range >");
                log_error("Unhandled range select (AST_STRUCT) in AST_DOT!\n");
            }
        } else {
            log_file_error(current_struct_elem->filename, current_struct_elem->location.first_line,
                           "Accessing member of a slice of type %s is unsupported.\n", type2str(current_struct_elem->type).c_str());
        }
    }
    delete elem_size;
    // Return range from the begining of *current* struct
    // When all AST_DOT are expanded it will return range
    // from original wire
    return new AST::AstNode(AST::AST_RANGE, left, right);
}

static AST::AstNode *convert_dot(AST::AstNode *wire_node, AST::AstNode *node, AST::AstNode *dot)
{
    AST::AstNode *struct_node = nullptr;
    if (wire_node->type == AST::AST_STRUCT || wire_node->type == AST::AST_UNION) {
        struct_node = wire_node;
    } else if (wire_node->attributes.count(ID::wiretype)) {
        log_assert(wire_node->attributes[ID::wiretype]->id2ast);
        struct_node = wire_node->attributes[ID::wiretype]->id2ast;
    } else {
        log_file_error(wire_node->filename, wire_node->location.first_line, "Unsupported node type: %s\n", type2str(wire_node->type).c_str());
    }
    log_assert(struct_node);
    auto expanded = expand_dot(struct_node, dot);
    if (node->children[0]->type == AST::AST_RANGE) {
        int struct_size_int = get_max_offset_struct(struct_node) + 1;
        log_assert(!wire_node->multirange_dimensions.empty());
        int range = wire_node->multirange_dimensions.back() - 1;
        if (!wire_node->attributes[UhdmAst::unpacked_ranges()]->children.empty() &&
            wire_node->attributes[UhdmAst::unpacked_ranges()]->children.back()->range_left == range) {
            expanded->children[1] = new AST::AstNode(
              AST::AST_ADD, expanded->children[1],
              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32),
                               new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(range, true, 32), node->children[0]->children[0]->clone())));
            expanded->children[0] = new AST::AstNode(
              AST::AST_ADD, expanded->children[0],
              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32),
                               new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(range, true, 32), node->children[0]->children[0]->clone())));
        } else {
            expanded->children[1] = new AST::AstNode(
              AST::AST_ADD, expanded->children[1],
              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32), node->children[0]->children[0]->clone()));
            expanded->children[0] = new AST::AstNode(
              AST::AST_ADD, expanded->children[0],
              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32), node->children[0]->children[0]->clone()));
        }
    }
    return expanded;
}

static void setup_current_scope(std::unordered_map<std::string, AST::AstNode *> top_nodes, AST::AstNode *current_top_node)
{
    for (auto it = top_nodes.begin(); it != top_nodes.end(); it++) {
        if (!it->second)
            continue;
        if (it->second->type == AST::AST_PACKAGE) {
            for (auto &o : it->second->children) {
                // import only parameters
                if (o->type == AST::AST_TYPEDEF || o->type == AST::AST_PARAMETER || o->type == AST::AST_LOCALPARAM) {
                    // add imported nodes to current scope
                    AST_INTERNAL::current_scope[it->second->str + std::string("::") + o->str.substr(1)] = o;
                    AST_INTERNAL::current_scope[o->str] = o;
                } else if (o->type == AST::AST_ENUM) {
                    AST_INTERNAL::current_scope[o->str] = o;
                    for (auto c : o->children) {
                        AST_INTERNAL::current_scope[c->str] = c;
                    }
                }
            }
        }
    }
    for (auto &o : current_top_node->children) {
        if (o->type == AST::AST_TYPEDEF || o->type == AST::AST_PARAMETER || o->type == AST::AST_LOCALPARAM) {
            AST_INTERNAL::current_scope[o->str] = o;
        } else if (o->type == AST::AST_ENUM) {
            AST_INTERNAL::current_scope[o->str] = o;
            for (auto c : o->children) {
                AST_INTERNAL::current_scope[c->str] = c;
            }
        }
    }
    // hackish way of setting current_ast_mod as it is required
    // for simplify to get references for already defined ids
    AST_INTERNAL::current_ast_mod = current_top_node;
    log_assert(AST_INTERNAL::current_ast_mod != nullptr);
}

static int range_width_local(AST::AstNode *node, AST::AstNode *rnode)
{
    log_assert(rnode->type == AST::AST_RANGE);
    if (!rnode->range_valid) {
        log_file_error(node->filename, node->location.first_line, "Size must be constant in packed struct/union member %s\n", node->str.c_str());
    }
    // note: range swapping has already been checked for
    return rnode->range_left - rnode->range_right + 1;
}

static void save_struct_array_width_local(AST::AstNode *node, int width)
{
    // stash the stride for the array
    node->multirange_dimensions.push_back(width);
}

static int simplify_struct(AST::AstNode *snode, int base_offset, AST::AstNode *parent_node)
{
    // Struct members will be laid out in the structure contiguously from left to right.
    // Union members all have zero offset from the start of the union.
    // Determine total packed size and assign offsets.  Store these in the member node.
    bool is_union = (snode->type == AST::AST_UNION);
    int offset = 0;
    int packed_width = -1;
    for (auto s : snode->children) {
        if (s->type == AST::AST_RANGE) {
            while (s->simplify(true, false, false, 1, -1, false, false)) {
            };
        }
    }
    // embeded struct or union with range?
    auto it = std::remove_if(snode->children.begin(), snode->children.end(), [](AST::AstNode *node) { return node->type == AST::AST_RANGE; });
    std::vector<AST::AstNode *> ranges(it, snode->children.end());
    snode->children.erase(it, snode->children.end());
    if (!ranges.empty()) {
        if (ranges.size() > 1) {
            log_file_error(ranges[1]->filename, ranges[1]->location.first_line,
                           "Currently support for custom-type with range is limited to single range\n");
        }
        for (auto range : ranges) {
            snode->multirange_dimensions.push_back(min(range->range_left, range->range_right));
            snode->multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1);
            snode->multirange_swapped.push_back(range->range_swapped);
            delete range;
        }
    }
    // examine members from last to first
    for (auto it = snode->children.rbegin(); it != snode->children.rend(); ++it) {
        auto node = *it;
        int width;
        if (node->type == AST::AST_STRUCT || node->type == AST::AST_UNION) {
            // embedded struct or union
            width = simplify_struct(node, base_offset + offset, parent_node);
            if (!node->multirange_dimensions.empty()) {
                int number_of_structs = 1;
                number_of_structs = node->multirange_dimensions.back();
                width *= number_of_structs;
            }
            // set range of struct
            node->range_right = base_offset + offset;
            node->range_left = base_offset + offset + width - 1;
            node->range_valid = true;
        } else {
            log_assert(node->type == AST::AST_STRUCT_ITEM);
            if (node->children.size() > 0 && node->children[0]->type == AST::AST_RANGE) {
                // member width e.g. bit [7:0] a
                width = range_width_local(node, node->children[0]);
                if (node->children.size() == 2) {
                    if (node->children[1]->type == AST::AST_RANGE) {
                        // unpacked array e.g. bit [63:0] a [0:3]
                        auto rnode = node->children[1];
                        int array_count = range_width_local(node, rnode);
                        if (array_count == 1) {
                            // C-type array size e.g. bit [63:0] a [4]
                            array_count = rnode->range_left;
                        }
                        save_struct_array_width_local(node, width);
                        width *= array_count;
                    } else {
                        // array element must be single bit for a packed array
                        log_file_error(node->filename, node->location.first_line, "Unpacked array in packed struct/union member %s\n",
                                       node->str.c_str());
                    }
                }
                // range nodes are now redundant
                for (AST::AstNode *child : node->children)
                    delete child;
                node->children.clear();
            } else if (node->children.size() == 1 && node->children[0]->type == AST::AST_MULTIRANGE) {
                // packed 2D array, e.g. bit [3:0][63:0] a
                auto rnode = node->children[0];
                if (rnode->children.size() != 2) {
                    // packed arrays can only be 2D
                    log_file_error(node->filename, node->location.first_line, "Unpacked array in packed struct/union member %s\n", node->str.c_str());
                }
                int array_count = range_width_local(node, rnode->children[0]);
                width = range_width_local(node, rnode->children[1]);
                save_struct_array_width_local(node, width);
                width *= array_count;
                // range nodes are now redundant
                for (AST::AstNode *child : node->children)
                    delete child;
                node->children.clear();
            } else if (node->range_left < 0) {
                // 1 bit signal: bit, logic or reg
                width = 1;
            } else {
                // already resolved and compacted
                width = node->range_left - node->range_right + 1;
            }
            if (is_union) {
                node->range_right = base_offset;
                node->range_left = base_offset + width - 1;
            } else {
                node->range_right = base_offset + offset;
                node->range_left = base_offset + offset + width - 1;
            }
            node->range_valid = true;
        }
        if (is_union) {
            // check that all members have the same size
            if (packed_width == -1) {
                // first member
                packed_width = width;
            } else {
                if (packed_width != width) {

                    log_file_error(node->filename, node->location.first_line, "member %s of a packed union has %d bits, expecting %d\n",
                                   node->str.c_str(), width, packed_width);
                }
            }
        } else {
            offset += width;
        }
    }
    if (!snode->str.empty() && parent_node && parent_node->type != AST::AST_TYPEDEF && parent_node->type != AST::AST_STRUCT &&
        AST_INTERNAL::current_scope.count(snode->str) != 0) {
        AST_INTERNAL::current_scope[snode->str]->attributes[ID::wiretype] = AST::AstNode::mkconst_str(snode->str);
        AST_INTERNAL::current_scope[snode->str]->attributes[ID::wiretype]->id2ast = snode;
    }
    return (is_union ? packed_width : offset);
}

static void add_members_to_scope_local(AST::AstNode *snode, std::string name)
{
    // add all the members in a struct or union to local scope
    // in case later referenced in assignments
    log_assert(snode->type == AST::AST_STRUCT || snode->type == AST::AST_UNION);
    for (auto *node : snode->children) {
        auto member_name = name + "." + node->str;
        AST_INTERNAL::current_scope[member_name] = node;
        if (node->type != AST::AST_STRUCT_ITEM) {
            // embedded struct or union
            add_members_to_scope_local(node, name + "." + node->str);
        }
    }
}

static AST::AstNode *make_packed_struct_local(AST::AstNode *template_node, std::string &name)
{
    // create a wire for the packed struct
    auto wnode = new AST::AstNode(AST::AST_WIRE);
    wnode->str = name;
    wnode->is_logic = true;
    wnode->range_valid = true;
    wnode->is_signed = template_node->is_signed;
    int offset = get_max_offset_struct(template_node);
    auto range = make_range(offset, 0);
    copy_packed_unpacked_attribute(template_node, wnode);
    wnode->attributes[UhdmAst::packed_ranges()]->children.insert(wnode->attributes[UhdmAst::packed_ranges()]->children.begin(), range);
    // make sure this node is the one in scope for this name
    AST_INTERNAL::current_scope[name] = wnode;
    // add all the struct members to scope under the wire's name
    add_members_to_scope_local(template_node, name);
    return wnode;
}

static void simplify_format_string(AST::AstNode *current_node)
{
    std::string sformat = current_node->children[0]->str;
    std::string preformatted_string = "";
    int next_arg = 1;
    for (size_t i = 0; i < sformat.length(); i++) {
        if (sformat[i] == '%') {
            AST::AstNode *node_arg = current_node->children[next_arg];
            char cformat = sformat[++i];
            if (cformat == 'b' or cformat == 'B') {
                node_arg->simplify(true, false, false, 1, -1, false, false);
                if (node_arg->type != AST::AST_CONSTANT)
                    log_file_error(current_node->filename, current_node->location.first_line,
                                   "Failed to evaluate system task `%s' with non-constant argument.\n", current_node->str.c_str());

                RTLIL::Const val = node_arg->bitsAsConst();
                for (int j = val.size() - 1; j >= 0; j--) {
                    // We add ACII value of 0 to convert number to character
                    preformatted_string += ('0' + val[j]);
                }
                delete current_node->children[next_arg];
                current_node->children.erase(current_node->children.begin() + next_arg);
            } else {
                next_arg++;
                preformatted_string += std::string("%") + cformat;
            }
        } else {
            preformatted_string += sformat[i];
        }
    }
    delete current_node->children[0];
    current_node->children[0] = AST::AstNode::mkconst_str(preformatted_string);
}

static void simplify(AST::AstNode *current_node, AST::AstNode *parent_node)
{
    auto dot_it = std::find_if(current_node->children.begin(), current_node->children.end(),
                               [](auto c) { return c->type == static_cast<int>(AST::Extended::AST_DOT); });
    AST::AstNode *dot = (dot_it != current_node->children.end()) ? *dot_it : nullptr;

    AST::AstNode *expanded = nullptr;
    if (dot) {
        if (!AST_INTERNAL::current_scope.count(current_node->str)) {
            // for accessing elements currently unsupported with AST_DOT
            // fallback to "." notation
            AST::AstNode *prefix_node = nullptr;
            AST::AstNode *parent_node = current_node;
            while (dot && !dot->str.empty()) {
                // it is not possible for AST_RANGE to be after AST::DOT (see process_hier_path function)
                if (parent_node->children[0]->type == AST::AST_RANGE) {
                    if (parent_node->children[1]->type == AST::AST_RANGE)
                        log_error("Multirange in AST_DOT is currently unsupported\n");

                    dot->type = AST::AST_IDENTIFIER;
                    simplify(dot, nullptr);
                    AST::AstNode *range_const = parent_node->children[0]->children[0];
                    prefix_node = new AST::AstNode(AST::AST_PREFIX, range_const->clone(), dot->clone());
                    break;
                } else {
                    current_node->str += "." + dot->str.substr(1);
                    dot_it = std::find_if(dot->children.begin(), dot->children.end(),
                                          [](auto c) { return c->type == static_cast<int>(AST::Extended::AST_DOT); });
                    parent_node = dot;
                    dot = (dot_it != dot->children.end()) ? *dot_it : nullptr;
                }
            }
            delete_children(current_node);
            if (prefix_node != nullptr) {
                current_node->type = AST::AST_PREFIX;
                current_node->children = prefix_node->children;

                prefix_node->children.clear();
                delete prefix_node;
            }
        } else {
            auto wire_node = AST_INTERNAL::current_scope[current_node->str];
            // make sure wire_node is already simplified
            simplify(wire_node, nullptr);
            expanded = convert_dot(wire_node, current_node, dot);
        }
    }
    if (expanded) {
        delete_children(current_node);
        current_node->children.push_back(expanded->clone());
        current_node->basic_prep = true;
        delete expanded;
        expanded = nullptr;
    }
    // First simplify children
    for (size_t i = 0; i < current_node->children.size(); i++) {
        simplify(current_node->children[i], current_node);
    }
    switch (current_node->type) {
    case AST::AST_TYPEDEF:
    case AST::AST_ENUM:
    case AST::AST_FUNCTION:
        AST_INTERNAL::current_scope[current_node->str] = current_node;
        break;
    case AST::AST_WIRE:
        delete_attribute(current_node, UhdmAst::is_simplified_wire());
        current_node->attributes[UhdmAst::is_simplified_wire()] = AST::AstNode::mkconst_int(1, true);
        [[fallthrough]];
    case AST::AST_PARAMETER:
    case AST::AST_LOCALPARAM:
        AST_INTERNAL::current_scope[current_node->str] = current_node;
        convert_packed_unpacked_range(current_node);
        break;
    case AST::AST_IDENTIFIER:
        if (!current_node->children.empty() && !current_node->basic_prep) {
            log_assert(AST_INTERNAL::current_ast_mod);
            if (!AST_INTERNAL::current_scope.count(current_node->str)) {
                break;
            }
            AST::AstNode *wire_node = AST_INTERNAL::current_scope[current_node->str];

            // if a wire is simplified multiple times, its ranges may be added multiple times and be redundant as a result
            if (!wire_node->attributes.count(UhdmAst::is_simplified_wire())) {
                simplify(wire_node, nullptr);
            }
            const int packed_ranges_size =
              wire_node->attributes.count(UhdmAst::packed_ranges()) ? wire_node->attributes[UhdmAst::packed_ranges()]->children.size() : 0;
            const int unpacked_ranges_size =
              wire_node->attributes.count(UhdmAst::unpacked_ranges()) ? wire_node->attributes[UhdmAst::unpacked_ranges()]->children.size() : 0;
            if ((wire_node->type == AST::AST_WIRE || wire_node->type == AST::AST_PARAMETER || wire_node->type == AST::AST_LOCALPARAM) &&
                (packed_ranges_size + unpacked_ranges_size > 1)) {
                auto *result = convert_range(current_node, packed_ranges_size, unpacked_ranges_size, 0);
                delete_children(current_node);
                current_node->children.push_back(result);
            }
        }
        break;
    case AST::AST_STRUCT:
    case AST::AST_UNION:
        simplify_struct(current_node, 0, parent_node);
        // instance rather than just a type in a typedef or outer struct?
        if (!current_node->str.empty() && current_node->str[0] == '\\') {
            // instance so add a wire for the packed structure
            auto wnode = make_packed_struct_local(current_node, current_node->str);
            convert_packed_unpacked_range(wnode);
            log_assert(AST_INTERNAL::current_ast_mod);
            AST_INTERNAL::current_ast_mod->children.push_back(wnode);
            AST_INTERNAL::current_scope[wnode->str]->attributes[ID::wiretype] = AST::AstNode::mkconst_str(current_node->str);
            AST_INTERNAL::current_scope[wnode->str]->attributes[ID::wiretype]->id2ast = current_node;
        }

        current_node->basic_prep = true;
        break;
    case AST::AST_STRUCT_ITEM:
        AST_INTERNAL::current_scope[current_node->str] = current_node;
        convert_packed_unpacked_range(current_node);
        while (current_node->simplify(true, false, false, 1, -1, false, false)) {
        };
        break;
    case AST::AST_TCALL:
        if (current_node->str == "$display" || current_node->str == "$write")
            simplify_format_string(current_node);
        break;
    case AST::AST_COND:
    case AST::AST_CONDX:
    case AST::AST_CONDZ:
        // handle custom low high bound
        if (current_node->attributes.count(UhdmAst::low_high_bound())) {
            log_assert(!current_node->children.empty());
            log_assert(current_node->children[0]->type == AST::AST_BLOCK);
            log_assert(current_node->children[0]->children.size() == 2);
            auto low_high_bound = current_node->children[0];
            // this is executed when condition is met
            // save pointer that will be added later again
            // as conditions needs to go before this block
            auto result = current_node->children[1];

            current_node->children[0] = nullptr;
            current_node->children[1] = nullptr;
            delete_children(current_node);
            while (low_high_bound->children[0]->simplify(true, false, false, 1, -1, false, false)) {
            };
            while (low_high_bound->children[1]->simplify(true, false, false, 1, -1, false, false)) {
            };
            log_assert(low_high_bound->children[0]->type == AST::AST_CONSTANT);
            log_assert(low_high_bound->children[1]->type == AST::AST_CONSTANT);
            const int low = low_high_bound->children[0]->integer;
            const int high = low_high_bound->children[1]->integer;
            const int range = low_high_bound->children[1]->range_valid
                                ? low_high_bound->children[1]->range_left
                                : low_high_bound->children[0]->range_valid ? low_high_bound->children[0]->range_left : 32;
            delete low_high_bound;
            // According to standard:
            // If the bound to the left of the colon is greater than the
            // bound to the right, the range is empty and contains no values.
            for (int i = low; i >= low && i <= high; i++) {
                current_node->children.push_back(AST::AstNode::mkconst_int(i, false, range));
            }
            current_node->children.push_back(result);
            delete_attribute(current_node, UhdmAst::low_high_bound());
        }
        break;
    default:
        break;
    }
}

static void clear_current_scope()
{
    // Remove clear current_scope from package nodes
    AST_INTERNAL::current_scope.clear();
    // unset current_ast_mod
    AST_INTERNAL::current_ast_mod = nullptr;
}

void UhdmAst::visit_one_to_many(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f)
{
    for (auto child : child_node_types) {
        vpiHandle itr = vpi_iterate(child, parent_handle);
        while (vpiHandle vpi_child_obj = vpi_scan(itr)) {
            UhdmAst uhdm_ast(this, shared, indent + "  ");
            auto *child_node = uhdm_ast.process_object(vpi_child_obj);
            f(child_node);
            vpi_release_handle(vpi_child_obj);
        }
        vpi_release_handle(itr);
    }
}

void UhdmAst::visit_one_to_one(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f)
{
    for (auto child : child_node_types) {
        vpiHandle itr = vpi_handle(child, parent_handle);
        if (itr) {
            UhdmAst uhdm_ast(this, shared, indent + "  ");
            auto *child_node = uhdm_ast.process_object(itr);
            f(child_node);
        }
        vpi_release_handle(itr);
    }
}

void UhdmAst::visit_range(vpiHandle obj_h, const std::function<void(AST::AstNode *)> &f)
{
    std::vector<AST::AstNode *> range_nodes;
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { range_nodes.push_back(node); });
    if (range_nodes.size() > 1) {
        auto multirange_node = new AST::AstNode(AST::AST_MULTIRANGE);
        multirange_node->children = range_nodes;
        f(multirange_node);
    } else if (!range_nodes.empty()) {
        f(range_nodes[0]);
    }
}

void UhdmAst::visit_default_expr(vpiHandle obj_h)
{
    UhdmAst initial_ast(parent, shared, indent);
    UhdmAst block_ast(&initial_ast, shared, indent);
    block_ast.visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *expr_node) {
        auto mod = find_ancestor({AST::AST_MODULE});
        AST::AstNode *initial_node = nullptr;
        AST::AstNode *block_node = nullptr;
        auto assign_node = new AST::AstNode(AST::AST_ASSIGN_EQ);
        auto id_node = new AST::AstNode(AST::AST_IDENTIFIER);
        id_node->str = current_node->str;

        for (auto child : mod->children) {
            if (child->type == AST::AST_INITIAL) {
                initial_node = child;
                break;
            }
        }
        // Ensure single AST_INITIAL node is located in AST_MODULE
        // before any AST_ALWAYS
        if (initial_node == nullptr) {
            initial_node = new AST::AstNode(AST::AST_INITIAL);
            auto insert_it = find_if(mod->children.begin(), mod->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_ALWAYS); });
            mod->children.insert(insert_it, initial_node);
        }
        // Ensure single AST_BLOCK node in AST_INITIAL
        if (!initial_node->children.empty() && initial_node->children[0]) {
            block_node = initial_node->children[0];
        } else {
            block_node = new AST::AstNode(AST::AST_BLOCK);
            initial_node->children.push_back(block_node);
        }
        auto block_child =
          find_if(block_node->children.begin(), block_node->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_ASSIGN_EQ); });
        // Insert AST_ASSIGN_EQ nodes that came from
        // custom_var or int_var before any other AST_ASSIGN_EQ
        // Especially before ones explicitly placed in initial block in source code
        block_node->children.insert(block_child, assign_node);
        assign_node->children.push_back(id_node);
        initial_ast.current_node = initial_node;
        block_ast.current_node = block_node;
        assign_node->children.push_back(expr_node);
    });
}

AST::AstNode *UhdmAst::process_value(vpiHandle obj_h)
{
    s_vpi_value val;
    vpi_get_value(obj_h, &val);
    std::string strValType = "'";
    bool is_signed = false;
    if (vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h)) {
        is_signed = vpi_get(vpiSigned, typespec_h);
        if (is_signed) {
            strValType += "s";
        }
    }
    if (val.format) { // Needed to handle parameter nodes without typespecs and constants
        switch (val.format) {
        case vpiScalarVal:
            return AST::AstNode::mkconst_int(val.value.scalar, false, 1);
        case vpiBinStrVal: {
            strValType += "b";
            break;
        }
        case vpiDecStrVal: {
            strValType += "d";
            break;
        }
        case vpiHexStrVal: {
            strValType += "h";
            break;
        }
        case vpiOctStrVal: {
            strValType += "o";
            break;
        }
        // Surelog reports constant integers as a unsigned, but by default int is signed
        // so we are treating here UInt in the same way as if they would be Int
        case vpiUIntVal:
            if (val.value.uint > std::numeric_limits<std::uint32_t>::max()) {
                // an integer is by default signed, so use 'sd despite the variant vpiUIntVal
                strValType = "'sd";
                string str_value = std::to_string(val.value.uint);
                val.value.str = strdup(str_value.c_str());
                break;
            }
            [[fallthrough]];
        case vpiIntVal: {
            if (val.value.integer > std::numeric_limits<std::int32_t>::max()) {
                strValType = "'sd";
                string str_value = std::to_string(val.value.integer);
                val.value.str = strdup(str_value.c_str());
                break;
            }

            int size = -1;
            // Surelog sometimes report size as part of vpiTypespec (e.g. int_typespec)
            // if it is the case, we need to set size to the left_range of first packed range
            visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
                if (node && node->attributes.count(UhdmAst::packed_ranges()) && node->attributes[UhdmAst::packed_ranges()]->children.size() &&
                    node->attributes[UhdmAst::packed_ranges()]->children[0]->children.size()) {
                    size = node->attributes[UhdmAst::packed_ranges()]->children[0]->children[0]->integer + 1;
                }
                delete node;
            });
            if (size == -1) {
                size = vpi_get(vpiSize, obj_h);
            }
            // Surelog by default returns 64 bit numbers and stardard says that they shall be at least 32bits
            // yosys is assuming that int/uint is 32 bit, so we are setting here correct size
            // NOTE: it *shouldn't* break on explicite 64 bit const values, as they *should* be handled
            // above by vpi*StrVal
            if (size == 64) {
                size = 32;
                is_signed = true;
            }
            auto c = AST::AstNode::mkconst_int(val.format == vpiUIntVal ? val.value.uint : val.value.integer, is_signed, size > 0 ? size : 32);
            if (size == 0 || size == -1)
                c->is_unsized = true;
            return c;
        }
        case vpiRealVal:
            return mkconst_real(val.value.real);
        case vpiStringVal:
            return AST::AstNode::mkconst_str(val.value.str);
        default: {
            const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
            report_error("%.*s:%d: Encountered unhandled constant format %d\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                         object->VpiLineNo(), val.format);
        }
        }
        // if this constant is under case/casex/casez
        // get current case type
        char caseType = ' ';
        if (vpiHandle caseItem_h = vpi_handle(vpiParent, obj_h)) {
            if (vpiHandle case_h = vpi_handle(vpiParent, caseItem_h)) {
                switch (vpi_get(vpiCaseType, case_h)) {
                case vpiCaseExact:
                    caseType = ' ';
                    break;
                case vpiCaseX:
                    caseType = 'x';
                    break;
                case vpiCaseZ:
                    caseType = 'z';
                    break;
                default: {
                    caseType = ' ';
                    break;
                }
                }
                vpi_release_handle(case_h);
            }
            vpi_release_handle(caseItem_h);
        }
        // handle vpiBinStrVal, vpiDecStrVal and vpiHexStrVal
        if (std::strchr(val.value.str, '\'')) {
            return ::systemverilog_plugin::const2ast(val.value.str, caseType, false);
        } else {
            auto size = vpi_get(vpiSize, obj_h);
            if (size == 0) {
                auto c = AST::AstNode::mkconst_int(atoi(val.value.str), true, 32);
                c->is_unsized = true;
                return c;
            } else {
                return ::systemverilog_plugin::const2ast(std::to_string(size) + strValType + val.value.str, caseType, false);
            }
        }
    }
    return nullptr;
}

void UhdmAst::transform_breaks_continues(AST::AstNode *loop, AST::AstNode *decl_block)
{
    AST::AstNode *break_wire = nullptr;
    AST::AstNode *continue_wire = nullptr;
    // Creates a 1-bit wire with the given name
    const auto make_cond_var = [this](const std::string &var_name) {
        auto cond_var =
          make_ast_node(AST::AST_WIRE, {make_ast_node(AST::AST_RANGE, {AST::AstNode::mkconst_int(0, false), AST::AstNode::mkconst_int(0, false)}),
                                        AST::AstNode::mkconst_int(0, false)});
        cond_var->str = var_name;
        cond_var->is_reg = true;
        return cond_var;
    };
    // Creates a conditional like 'if (!casevar) block'
    auto make_case = [this](AST::AstNode *block, const std::string &casevar_name) {
        auto *case_node = make_ast_node(AST::AST_CASE);
        auto *id = make_identifier(casevar_name);
        case_node->children.push_back(id);
        auto *constant = AST::AstNode::mkconst_int(0, false, 1);
        auto *cond_node = make_ast_node(AST::AST_COND);
        cond_node->children.push_back(constant);
        cond_node->children.push_back(block);
        case_node->children.push_back(cond_node);
        return case_node;
    };
    // Pre-declare this function to be able to call it recursively
    std::function<bool(AST::AstNode *)> transform_block;
    // Transforms the given block if it has a break or continue; recurses into child blocks; return true if a break/continue was encountered
    transform_block = [&](AST::AstNode *block) {
        auto wrap_and_transform = [&](decltype(block->children)::iterator it) {
            // Move the (it, end()) statements into a new block under 'if (!continue) {...}'
            auto *new_block = make_ast_node(AST::AST_BLOCK, {it, block->children.end()});
            block->children.erase(it, block->children.end());
            auto *case_node = make_case(new_block, continue_wire->str);
            block->children.push_back(case_node);
            transform_block(new_block);
        };

        for (auto it = block->children.begin(); it != block->children.end(); it++) {
            auto type = static_cast<int>((*it)->type);
            switch (type) {
            case AST::AST_BLOCK: {
                if (transform_block(*it)) {
                    // If there was a break/continue, we need to wrap the rest of the block in an if
                    wrap_and_transform(it + 1);
                    return true;
                }
                break;
            }
            case AST::AST_CASE: {
                // Go over each block in a case
                bool has_jump = false;
                for (auto *node : (*it)->children) {
                    if (node->type == AST::AST_COND)
                        has_jump = has_jump || transform_block(node->children.back());
                }
                if (has_jump) {
                    // If there was a break/continue, we need to wrap the rest of the block in an if
                    wrap_and_transform(it + 1);
                    return true;
                }
                break;
            }
            case AST::Extended::AST_BREAK:
            case AST::Extended::AST_CONTINUE: {
                std::for_each(it, block->children.end(), [](auto *node) { delete node; });
                block->children.erase(it, block->children.end());
                if (!continue_wire)
                    continue_wire = make_cond_var("$continue");
                auto *continue_id = make_identifier(continue_wire->str);
                block->children.push_back(make_ast_node(AST::AST_ASSIGN_EQ, {continue_id, AST::AstNode::mkconst_int(1, false)}));
                if (type == AST::Extended::AST_BREAK) {
                    if (!break_wire)
                        break_wire = make_cond_var("$break");
                    auto *break_id = make_identifier(break_wire->str);
                    block->children.push_back(make_ast_node(AST::AST_ASSIGN_EQ, {break_id, AST::AstNode::mkconst_int(1, false)}));
                }
                return true;
            }
            }
        }
        return false;
    };

    // Actual transformation starts here
    transform_block(loop->children.back());
    if (continue_wire) {
        auto *continue_id = make_identifier(continue_wire->str);
        // Reset $continue each iteration
        auto *continue_assign = make_ast_node(AST::AST_ASSIGN_EQ, {continue_id, AST::AstNode::mkconst_int(0, false)});
        decl_block->children.insert(decl_block->children.begin(), continue_wire);
        loop->children.back()->children.insert(loop->children.back()->children.begin(), continue_assign);
    }
    if (break_wire) {
        auto *break_id = make_identifier(break_wire->str);
        // Reset $break before the loop
        auto *break_assign = make_ast_node(AST::AST_ASSIGN_EQ, {break_id, AST::AstNode::mkconst_int(0, false)});
        decl_block->children.insert(decl_block->children.begin(), break_assign);
        decl_block->children.insert(decl_block->children.begin(), break_wire);
        if (loop->type == AST::AST_REPEAT || loop->type == AST::AST_FOR) {
            // Wrap loop body in 'if (!break) {...}'
            // Changing the for loop condition won't work here,
            // as then simplify fails with error "2nd expression of procedural for-loop is not constant!"
            auto *case_node = make_case(loop->children.back(), break_wire->str);
            auto *new_block = make_ast_node(AST::AST_BLOCK);
            new_block->children.push_back(case_node);
            new_block->str = loop->children.back()->str;
            loop->children.back() = new_block;
        } else if (loop->type == AST::AST_WHILE) {
            // Add the break var to the loop condition
            auto *break_id = make_identifier(break_wire->str);
            AST::AstNode *&loop_cond = loop->children[0];
            loop_cond = make_ast_node(AST::AST_LOGIC_AND, {make_ast_node(AST::AST_LOGIC_NOT, {break_id}), loop_cond});
        } else {
            log_error("break unsupported for this loop type");
        }
    }
}

AST::AstNode *UhdmAst::make_ast_node(AST::AstNodeType type, std::vector<AST::AstNode *> children, bool prefer_full_name)
{
    auto node = new AST::AstNode(type);
    node->str = get_name(obj_h, prefer_full_name);
    auto it = node_renames.find(node->str);
    if (it != node_renames.end())
        node->str = it->second;
    if (auto filename = vpi_get_str(vpiFile, obj_h)) {
        node->filename = filename;
    }
    if (unsigned int first_line = vpi_get(vpiLineNo, obj_h)) {
        node->location.first_line = first_line;
    }
    if (unsigned int last_line = vpi_get(vpiEndLineNo, obj_h)) {
        node->location.last_line = last_line;
    } else {
        node->location.last_line = node->location.first_line;
    }
    if (unsigned int first_col = vpi_get(vpiColumnNo, obj_h)) {
        node->location.first_column = first_col;
    }
    if (unsigned int last_col = vpi_get(vpiEndColumnNo, obj_h)) {
        node->location.last_column = last_col;
    } else {
        node->location.last_column = node->location.first_column;
    }
    node->children = children;
    return node;
}

AST::AstNode *UhdmAst::make_identifier(const std::string &name)
{
    auto *node = make_ast_node(AST::AST_IDENTIFIER);
    node->str = name;
    return node;
}

void UhdmAst::process_packed_array_typespec()
{
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    current_node = make_ast_node(AST::AST_WIRE);
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
    visit_one_to_one({vpiElemTypespec}, obj_h, [&](AST::AstNode *node) {
        if (node && node->type == AST::AST_STRUCT) {
            auto str = current_node->str;
            node->cloneInto(current_node);
            current_node->str = str;
            delete node;
        } else if (node) {
            current_node->str = node->str;
            if (node->type == AST::AST_ENUM && !node->children.empty()) {
                for (auto *c : node->children[0]->children) {
                    if (c->type == AST::AST_RANGE && c->str.empty())
                        packed_ranges.push_back(c);
                    else
                        delete c;
                }
                node->children[0]->children.clear();
            }
            delete node;
        }
    });
    add_multirange_wire(current_node, std::move(packed_ranges), std::move(unpacked_ranges));
}

static void add_or_replace_child(AST::AstNode *parent, AST::AstNode *child)
{
    if (!child->str.empty()) {
        auto it = std::find_if(parent->children.begin(), parent->children.end(),
                               [child](AST::AstNode *existing_child) { return existing_child->str == child->str; });
        if (it != parent->children.end()) {
            // If port direction is already set, copy it to replaced child node
            if ((*it)->is_input || (*it)->is_output) {
                child->is_input = (*it)->is_input;
                child->is_output = (*it)->is_output;
                child->port_id = (*it)->port_id;
                if (child->type == AST::AST_MEMORY)
                    child->type = AST::AST_WIRE;
            }
            child->is_signed = child->is_signed || (*it)->is_signed;
            if (!(*it)->children.empty() && child->children.empty()) {
                // This is a bit ugly, but if the child we're replacing has children and
                // our node doesn't, we copy its children to not lose any information
                for (auto grandchild : (*it)->children) {
                    child->children.push_back(grandchild->clone());
                    if (child->type == AST::AST_WIRE && grandchild->type == AST::AST_WIRETYPE)
                        child->is_custom_type = true;
                }
            }
            if ((*it)->attributes.count(UhdmAst::packed_ranges()) && child->attributes.count(UhdmAst::packed_ranges())) {
                if ((!(*it)->attributes[UhdmAst::packed_ranges()]->children.empty() &&
                     child->attributes[UhdmAst::packed_ranges()]->children.empty())) {

                    delete_attribute(child, UhdmAst::packed_ranges());
                    child->attributes[UhdmAst::packed_ranges()] = (*it)->attributes[UhdmAst::packed_ranges()]->clone();
                }
            }
            if ((*it)->attributes.count(UhdmAst::unpacked_ranges()) && child->attributes.count(UhdmAst::unpacked_ranges())) {
                if ((!(*it)->attributes[UhdmAst::unpacked_ranges()]->children.empty() &&
                     child->attributes[UhdmAst::unpacked_ranges()]->children.empty())) {

                    delete_attribute(child, UhdmAst::unpacked_ranges());
                    child->attributes[UhdmAst::unpacked_ranges()] = (*it)->attributes[UhdmAst::unpacked_ranges()]->clone();
                }
            }
            // Surelog doesn't report correct sign value for param_assign nodes
            // and only default vpiParameter node have correct sign value, so
            // if we are overriding parameter, copy sign value from current node to the new node
            if (((*it)->type == AST::AST_PARAMETER || (*it)->type == AST::AST_LOCALPARAM) && child->children.size() && (*it)->children.size()) {
                child->children[0]->is_signed = (*it)->children[0]->is_signed;
            }
            delete *it;
            *it = child;
            return;
        }
        parent->children.push_back(child);
    } else if (child->type == AST::AST_INITIAL) {
        // Special case for initials
        // Ensure that there is only one AST_INITIAL in the design
        // And there is only one AST_BLOCK inside that initial
        // Copy nodes from child initial to parent initial
        auto initial_node_it =
          find_if(parent->children.begin(), parent->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_INITIAL); });
        if (initial_node_it != parent->children.end()) {
            AST::AstNode *initial_node = *initial_node_it;

            // simplify assumes that initial has a block under it
            // In case we don't have one (there were no statements under the initial), let's add it
            if (initial_node->children.empty()) {
                initial_node->children.push_back(new AST::AstNode(AST::AST_BLOCK));
            }

            log_assert(initial_node->children[0]->type == AST::AST_BLOCK);
            log_assert(!(child->children.empty()));
            log_assert(child->children[0]->type == AST::AST_BLOCK);

            AST::AstNode *block_node = initial_node->children[0];
            AST::AstNode *child_block_node = child->children[0];

            // Place the contents of child block node inside parent block
            for (auto child_block_child : child_block_node->children)
                block_node->children.push_back(child_block_child->clone());
            // Place the remaining contents of child initial node inside the parent initial
            for (auto initial_child = child->children.begin() + 1; initial_child != child->children.end(); ++initial_child) {
                initial_node->children.push_back((*initial_child)->clone());
            }
            delete child;
        } else {
            // Parent AST_INITIAL does not exist
            // Place child AST_INITIAL before AST_ALWAYS if found
            auto insert_it =
              find_if(parent->children.begin(), parent->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_ALWAYS); });
            parent->children.insert(insert_it, 1, child);
        }
    } else {
        parent->children.push_back(child);
    }
}

void UhdmAst::make_cell(vpiHandle obj_h, AST::AstNode *cell_node, AST::AstNode *type_node)
{
    if (cell_node->children.empty() || (!cell_node->children.empty() && cell_node->children[0]->type != AST::AST_CELLTYPE)) {
        auto typeNode = new AST::AstNode(AST::AST_CELLTYPE);
        typeNode->str = type_node->str;
        cell_node->children.insert(cell_node->children.begin(), typeNode);
    }
    // Add port connections as arguments
    vpiHandle port_itr = vpi_iterate(vpiPort, obj_h);
    while (vpiHandle port_h = vpi_scan(port_itr)) {
        std::string arg_name;
        if (auto s = vpi_get_str(vpiName, port_h)) {
            arg_name = s;
            sanitize_symbol_name(arg_name);
        }
        auto arg_node = new AST::AstNode(AST::AST_ARGUMENT);
        arg_node->str = arg_name;
        arg_node->filename = cell_node->filename;
        arg_node->location = cell_node->location;
        visit_one_to_one({vpiHighConn}, port_h, [&](AST::AstNode *node) {
            if (node) {
                if (node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
                    node->type = AST::AST_IDENTIFIER;
                }
                arg_node->children.push_back(node);
            }
        });
        cell_node->children.push_back(arg_node);
        shared.report.mark_handled(port_h);
        vpi_release_handle(port_h);
    }
    vpi_release_handle(port_itr);
}

void UhdmAst::move_type_to_new_typedef(AST::AstNode *current_node, AST::AstNode *type_node)
{
    auto typedef_node = new AST::AstNode(AST::AST_TYPEDEF);
    typedef_node->location = type_node->location;
    typedef_node->filename = type_node->filename;
    typedef_node->str = strip_package_name(type_node->str);
    for (auto c : current_node->children) {
        if (c->str == typedef_node->str) {
            return;
        }
    }
    if (type_node->type == AST::AST_STRUCT) {
        type_node->str.clear();
        typedef_node->children.push_back(type_node);
        current_node->children.push_back(typedef_node);
    } else if (type_node->type == AST::AST_ENUM) {
        if (type_node->attributes.count("\\enum_base_type")) {
            auto base_type = type_node->attributes["\\enum_base_type"];
            auto wire_node = new AST::AstNode(AST::AST_WIRE);
            wire_node->is_reg = true;
            for (auto c : base_type->children) {
                std::string enum_item_str = "\\enum_value_";
                log_assert(!c->children.empty());
                log_assert(c->children[0]->type == AST::AST_CONSTANT);
                int width = 1;
                bool is_signed = c->children[0]->is_signed;
                if (c->children.size() == 2) {
                    width = c->children[1]->children[0]->integer + 1;
                }
                RTLIL::Const val = c->children[0]->bitsAsConst(width, is_signed);
                enum_item_str.append(val.as_string());
                wire_node->attributes[enum_item_str.c_str()] = AST::AstNode::mkconst_str(c->str);
            }
            typedef_node->children.push_back(wire_node);
            current_node->children.push_back(typedef_node);
            delete type_node;
        } else {
            type_node->str = "$enum" + std::to_string(shared.next_enum_id());
            auto wire_node = new AST::AstNode(AST::AST_WIRE);
            wire_node->is_reg = true;
            wire_node->attributes["\\enum_type"] = AST::AstNode::mkconst_str(type_node->str);
            if (!type_node->children.empty() && type_node->children[0]->children.size() > 1) {
                wire_node->children.push_back(type_node->children[0]->children[1]->clone());
            } else {
                // Add default range
                wire_node->children.push_back(make_range(31, 0));
            }
            typedef_node->children.push_back(wire_node);
            current_node->children.push_back(type_node);
            current_node->children.push_back(typedef_node);
        }
    } else {
        type_node->str.clear();
        typedef_node->children.push_back(type_node);
        current_node->children.push_back(typedef_node);
    }
}

AST::AstNode *UhdmAst::find_ancestor(const std::unordered_set<AST::AstNodeType> &types)
{
    auto searched_node = this;
    while (searched_node) {
        if (searched_node->current_node) {
            if (types.find(searched_node->current_node->type) != types.end()) {
                return searched_node->current_node;
            }
        }
        searched_node = searched_node->parent;
    }
    return nullptr;
}

void UhdmAst::process_design()
{
    current_node = make_ast_node(AST::AST_DESIGN);
    visit_one_to_many({UHDM::uhdmallInterfaces, UHDM::uhdmtopPackages, UHDM::uhdmallModules, UHDM::uhdmtopModules, vpiTaskFunc}, obj_h,
                      [&](AST::AstNode *node) {
                          if (node) {
                              shared.top_nodes[node->str] = node;
                          }
                      });
    visit_one_to_many({vpiParameter, vpiParamAssign}, obj_h, [&](AST::AstNode *node) {});
    visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
        if (node)
            move_type_to_new_typedef(current_node, node);
    });
    // Add top level typedefs and params to scope
    setup_current_scope(shared.top_nodes, current_node);
    for (auto pair : shared.top_nodes) {
        if (!pair.second)
            continue;
        if (pair.second->type == AST::AST_PACKAGE) {
            check_memories(pair.second);
            setup_current_scope(shared.top_nodes, pair.second);
            simplify(pair.second, nullptr);
            clear_current_scope();
        }
    }
    setup_current_scope(shared.top_nodes, current_node);
    // Once we walked everything, unroll that as children of this node
    for (auto &pair : shared.top_nodes) {
        if (!pair.second)
            continue;
        if (!pair.second->get_bool_attribute(UhdmAst::partial())) {
            if (pair.second->type == AST::AST_PACKAGE)
                current_node->children.insert(current_node->children.begin(), pair.second);
            else {
                check_memories(pair.second);
                setup_current_scope(shared.top_nodes, pair.second);
                simplify(pair.second, nullptr);
                clear_current_scope();
                current_node->children.push_back(pair.second);
            }
        } else {
            log_warning("Removing unused module: %s from the design.\n", pair.second->str.c_str());
            // TODO: This should be properly erased from the module, but it seems that it's
            // needed to resolve scope
            delete pair.second;
            pair.second = nullptr;
        }
    }
}

void UhdmAst::simplify_parameter(AST::AstNode *parameter, AST::AstNode *module_node)
{
    setup_current_scope(shared.top_nodes, shared.current_top_node);
    visitEachDescendant(shared.current_top_node, [&](AST::AstNode *current_scope_node) {
        if (current_scope_node->type == AST::AST_TYPEDEF || current_scope_node->type == AST::AST_PARAMETER ||
            current_scope_node->type == AST::AST_LOCALPARAM) {
            AST_INTERNAL::current_scope[current_scope_node->str] = current_scope_node;
        }
    });
    if (module_node) {
        visitEachDescendant(module_node, [&](AST::AstNode *current_scope_node) {
            if (current_scope_node->type == AST::AST_TYPEDEF || current_scope_node->type == AST::AST_PARAMETER ||
                current_scope_node->type == AST::AST_LOCALPARAM) {
                AST_INTERNAL::current_scope[current_scope_node->str] = current_scope_node;
            }
        });
    }
    // first apply custom simplification step if needed
    simplify(parameter, module_node);
    // workaround for yosys sometimes not simplifying parameters children
    // parameters can have 2 children:
    // first child should be parameter value
    // second child should be parameter range (optional)
    log_assert(!parameter->children.empty());
    simplify(parameter->children[0], parameter);
    while (parameter->children[0]->simplify(true, false, false, 1, -1, false, false)) {
    }
    // follow id2ast as yosys doesn't do it by default
    if (parameter->children[0]->id2ast) {
        simplify(parameter->children[0]->id2ast, parameter);
        while (parameter->children[0]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
        }
    }
    if (parameter->children.size() > 1) {
        simplify(parameter->children[1], parameter);
        while (parameter->children[1]->simplify(true, false, false, 1, -1, false, false)) {
        }
        if (parameter->children[1]->id2ast) {
            simplify(parameter->children[1]->id2ast, parameter);
            while (parameter->children[1]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
            }
        }
    }
    // then simplify parameter to AST_CONSTANT or AST_REALVALUE
    while (parameter->simplify(true, false, false, 1, -1, false, false)) {
    }
    clear_current_scope();
}

void UhdmAst::process_module()
{
    std::string type = vpi_get_str(vpiDefName, obj_h);
    std::string name = vpi_get_str(vpiName, obj_h) ? vpi_get_str(vpiName, obj_h) : type;
    bool is_module_instance = type != name;
    sanitize_symbol_name(type);
    sanitize_symbol_name(name);
    type = strip_package_name(type);
    name = strip_package_name(name);
    if (!is_module_instance) {
        if (shared.top_nodes.find(type) != shared.top_nodes.end()) {
            current_node = shared.top_nodes[type];
            shared.current_top_node = current_node;
            auto process_it = std::find_if(current_node->children.begin(), current_node->children.end(),
                                           [](auto node) { return node->type == AST::AST_INITIAL || node->type == AST::AST_ALWAYS; });
            auto children_after_process = std::vector<AST::AstNode *>(process_it, current_node->children.end());
            current_node->children.erase(process_it, current_node->children.end());
            visit_one_to_many({vpiModule, vpiInterface, vpiParameter, vpiParamAssign, vpiPort, vpiNet, vpiArrayNet, vpiTaskFunc, vpiGenScopeArray,
                               vpiContAssign, vpiVariables},
                              obj_h, [&](AST::AstNode *node) {
                                  if (node) {
                                      add_or_replace_child(current_node, node);
                                  }
                              });
            // Primitives will have the same names (like "and"), so we need to make sure we don't replace them
            visit_one_to_many({vpiPrimitive}, obj_h, [&](AST::AstNode *node) {
                if (node) {
                    current_node->children.push_back(node);
                }
            });
            current_node->children.insert(current_node->children.end(), children_after_process.begin(), children_after_process.end());

            delete_attribute(current_node, UhdmAst::partial());
        } else {
            current_node = make_ast_node(AST::AST_MODULE);
            current_node->str = type;
            shared.top_nodes[current_node->str] = current_node;
            shared.current_top_node = current_node;
            current_node->attributes[UhdmAst::partial()] = AST::AstNode::mkconst_int(1, false, 1);
            visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
                if (node) {
                    move_type_to_new_typedef(current_node, node);
                }
            });
            visit_one_to_many({vpiModule, vpiParameter, vpiParamAssign, vpiNet, vpiArrayNet, vpiProcess}, obj_h, [&](AST::AstNode *node) {
                if (node) {
                    if (node->type == AST::AST_ASSIGN && node->children.size() < 2) {
                        delete node;
                        return;
                    }
                    add_or_replace_child(current_node, node);
                }
            });
        }
    } else {
        // Not a top module, create instance
        current_node = make_ast_node(AST::AST_CELL);
        std::vector<std::pair<RTLIL::IdString, RTLIL::Const>> parameters;
        visit_one_to_many({vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
            if (node && node->type == AST::AST_PARAMETER) {
                log_assert(!node->children.empty());
                if (node->children[0]->type != AST::AST_CONSTANT) {
                    if (shared.top_nodes.count(type)) {
                        simplify_parameter(node, shared.top_nodes[type]);
                    } else {
                        simplify_parameter(node, nullptr);
                    }
                }
                log_assert(node->children[0]->type == AST::AST_CONSTANT || node->children[0]->type == AST::AST_REALVALUE);
                parameters.push_back(std::make_pair(node->str, node->children[0]->asParaConst()));
            }
            delete node;
        });
        // We need to rename module to prevent name collision with the same module, but with different parameters
        std::string module_name = !parameters.empty() ? AST::derived_module_name(type, parameters).c_str() : type;
        auto module_node = shared.top_nodes[module_name];
        // true, when Surelog don't have definition of module while parsing design
        // if so, we leaving module parameters to yosys and don't rename module
        // as it will be done by yosys
        bool isPrimitive = false;
        if (!module_node) {
            module_node = shared.top_nodes[type];
            if (!module_node) {
                module_node = new AST::AstNode(AST::AST_MODULE);
                module_node->str = type;
                module_node->attributes[UhdmAst::partial()] = AST::AstNode::mkconst_int(2, false, 1);
                module_node->attributes[ID::whitebox] = AST::AstNode::mkconst_int(1, false, 1);
            }
            isPrimitive = module_node->attributes.count(UhdmAst::partial()) && module_node->attributes[UhdmAst::partial()]->integer == 2;
            if (!parameters.empty() && !isPrimitive) {
                module_node = module_node->clone();
                module_node->str = module_name;
            }
        }
        shared.top_nodes[module_node->str] = module_node;
        visit_one_to_many({vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
            if (node) {
                if (node->children[0]->type != AST::AST_CONSTANT) {
                    if (shared.top_nodes[type]) {
                        simplify_parameter(node, module_node);
                        log_assert(node->children[0]->type == AST::AST_CONSTANT || node->children[0]->type == AST::AST_REALVALUE);
                    }
                }
                // if module is primitive
                // Surelog doesn't have definition of this module,
                // so we need to left setting of parameters to yosys
                if (isPrimitive) {
                    node->type = AST::AST_PARASET;
                    current_node->children.push_back(node);
                } else {
                    add_or_replace_child(module_node, node);
                }
            }
        });
        if (module_node->attributes.count(UhdmAst::partial())) {
            AST::AstNode *attr = module_node->attributes.at(UhdmAst::partial());
            if (attr->type == AST::AST_CONSTANT)
                if (attr->integer == 1) {
                    delete_attribute(module_node, UhdmAst::partial());
                }
        }
        auto typeNode = new AST::AstNode(AST::AST_CELLTYPE);
        typeNode->str = module_node->str;
        current_node->children.insert(current_node->children.begin(), typeNode);
        auto old_top = shared.current_top_node;
        shared.current_top_node = module_node;
        visit_one_to_many({vpiVariables, vpiNet, vpiArrayNet, vpiInterface, vpiModule, vpiPort, vpiGenScopeArray, vpiContAssign, vpiTaskFunc}, obj_h,
                          [&](AST::AstNode *node) {
                              if (node) {
                                  add_or_replace_child(module_node, node);
                              }
                          });
        make_cell(obj_h, current_node, module_node);
        shared.current_top_node = old_top;
    }
}

void UhdmAst::process_struct_typespec()
{
    current_node = make_ast_node(AST::AST_STRUCT);
    visit_one_to_many({vpiTypespecMember}, obj_h, [&](AST::AstNode *node) {
        if (node->children.size() > 0 && node->children[0]->type == AST::AST_ENUM) {
            log_assert(node->children.size() == 1);
            log_assert(!node->children[0]->children.empty());
            log_assert(!node->children[0]->children[0]->children.empty());
            // TODO: add missing enum_type attribute
            AST::AstNode *range = nullptr;
            // check if single enum element is larger than 1 bit
            if (node->children[0]->children[0]->children.size() == 2) {
                range = node->children[0]->children[0]->children[1]->clone();
            } else {
                range = make_range(0, 0);
            }
            delete_children(node);
            node->children.push_back(range);
        }
        current_node->children.push_back(node);
    });
}

void UhdmAst::process_union_typespec()
{
    current_node = make_ast_node(AST::AST_UNION);
    visit_one_to_many({vpiTypespecMember}, obj_h, [&](AST::AstNode *node) {
        if (node->children.size() > 0 && node->children[0]->type == AST::AST_ENUM) {
            log_assert(node->children.size() == 1);
            log_assert(!node->children[0]->children.empty());
            log_assert(!node->children[0]->children[0]->children.empty());
            // TODO: add missing enum_type attribute
            AST::AstNode *range = nullptr;
            // check if single enum element is larger than 1 bit
            if (node->children[0]->children[0]->children.size() == 2) {
                range = node->children[0]->children[0]->children[1]->clone();
            } else {
                range = make_range(0, 0);
            }
            delete_children(node);
            node->children.push_back(range);
        }
        current_node->children.push_back(node);
    });
}

void UhdmAst::process_array_typespec()
{
    current_node = make_ast_node(AST::AST_WIRE);
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    visit_one_to_one({vpiElemTypespec}, obj_h, [&](AST::AstNode *node) {
        if (node && node->type == AST::AST_STRUCT) {
            auto str = current_node->str;
            node->cloneInto(current_node);
            current_node->str = str;
            delete node;
        }
    });
    if (auto elemtypespec_h = vpi_handle(vpiElemTypespec, obj_h)) {
        visit_one_to_many({vpiRange}, elemtypespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
        vpi_release_handle(elemtypespec_h);
    }
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

void UhdmAst::process_typespec_member()
{
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    current_node = make_ast_node(AST::AST_STRUCT_ITEM);
    current_node->str = current_node->str.substr(1);
    vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h);
    int typespec_type = vpi_get(vpiType, typespec_h);
    const uhdm_handle *const handle = (const uhdm_handle *)typespec_h;
    const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
    switch (typespec_type) {
    case vpiBitTypespec:
    case vpiLogicTypespec: {
        current_node->is_logic = true;
        visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
        shared.report.mark_handled(typespec_h);
        break;
    }
    case vpiByteTypespec: {
        current_node->is_signed = vpi_get(vpiSigned, typespec_h);
        packed_ranges.push_back(make_range(7, 0));
        shared.report.mark_handled(typespec_h);
        break;
    }
    case vpiShortIntTypespec: {
        current_node->is_signed = vpi_get(vpiSigned, typespec_h);
        packed_ranges.push_back(make_range(15, 0));
        shared.report.mark_handled(typespec_h);
        break;
    }
    case vpiIntTypespec:
    case vpiIntegerTypespec: {
        current_node->is_signed = vpi_get(vpiSigned, typespec_h);
        packed_ranges.push_back(make_range(31, 0));
        shared.report.mark_handled(typespec_h);
        break;
    }
    case vpiTimeTypespec:
    case vpiLongIntTypespec: {
        current_node->is_signed = vpi_get(vpiSigned, typespec_h);
        packed_ranges.push_back(make_range(63, 0));
        shared.report.mark_handled(typespec_h);
        break;
    }
    case vpiStructTypespec:
    case vpiUnionTypespec:
    case vpiEnumTypespec: {
        visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
            if (typespec_type == vpiStructTypespec || typespec_type == vpiUnionTypespec) {
                auto str = current_node->str;
                node->cloneInto(current_node);
                current_node->str = str;
                delete node;
            } else if (typespec_type == vpiEnumTypespec) {
                current_node->children.push_back(node);
            } else {
                delete node;
            }
        });
        break;
    }
    case vpiPackedArrayTypespec:
        visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
            if (node && node->type == AST::AST_STRUCT) {
                auto str = current_node->str;
                if (node->attributes.count(UhdmAst::packed_ranges())) {
                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
                        packed_ranges.push_back(r->clone());
                    }
                    std::reverse(packed_ranges.begin(), packed_ranges.end());
                    delete_attribute(node, UhdmAst::packed_ranges());
                }
                if (node->attributes.count(UhdmAst::unpacked_ranges())) {
                    for (auto r : node->attributes[UhdmAst::unpacked_ranges()]->children) {
                        unpacked_ranges.push_back(r->clone());
                    }
                    delete_attribute(node, UhdmAst::unpacked_ranges());
                }
                node->cloneInto(current_node);
                current_node->str = str;
                current_node->children.insert(current_node->children.end(), packed_ranges.begin(), packed_ranges.end());
                packed_ranges.clear();
                delete node;
            } else if (node) {
                auto str = current_node->str;
                if (node->attributes.count(UhdmAst::packed_ranges())) {
                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
                        packed_ranges.push_back(r->clone());
                    }
                    std::reverse(packed_ranges.begin(), packed_ranges.end());
                    delete_attribute(node, UhdmAst::packed_ranges());
                }
                if (node->attributes.count(UhdmAst::unpacked_ranges())) {
                    for (auto r : node->attributes[UhdmAst::unpacked_ranges()]->children) {
                        unpacked_ranges.push_back(r->clone());
                    }
                    delete_attribute(node, UhdmAst::unpacked_ranges());
                }
                node->cloneInto(current_node);
                current_node->str = str;
                current_node->type = AST::AST_STRUCT_ITEM;
                delete node;
            }
        });
        break;
    case vpiVoidTypespec: {
        report_error("%.*s:%d: Void typespecs are currently unsupported", (int)object->VpiFile().length(), object->VpiFile().data(),
                     object->VpiLineNo());
        break;
    }
    case vpiClassTypespec: {
        report_error("%.*s:%d: Class typespecs are unsupported", (int)object->VpiFile().length(), object->VpiFile().data(), object->VpiLineNo());
        break;
    }
    default: {
        report_error("%.*s:%d: Encountered unhandled typespec in process_typespec_member: '%.*s' of type '%s'\n", (int)object->VpiFile().length(),
                     object->VpiFile().data(), object->VpiLineNo(), (int)object->VpiName().length(), object->VpiName().data(),
                     UHDM::VpiTypeName(typespec_h).c_str());
        break;
    }
    }
    vpi_release_handle(typespec_h);
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

static UHDM::expr *reduce_expression(const UHDM::any *expr, const UHDM::any *inst, const UHDM::any *pexpr)
{
    log_assert(expr);
    log_assert(inst);
    log_assert(pexpr);

    bool invalidvalue = false;
    UHDM::ExprEval eval;
    UHDM::expr *resolved_operation = eval.reduceExpr(expr, invalidvalue, inst, pexpr);
    log_assert(!invalidvalue);
    return resolved_operation;
}

void UhdmAst::process_enum_typespec()
{
    // BaseTypespec specifies underlying type of the enum.
    // The BaseTypespec has at most one explicit packed dimension (range).
    // When base type is not specified in SystemVerilog code, it is assumed to be an int.
    // Type of enum items (constants) is the same as the enum type.
    current_node = make_ast_node(AST::AST_ENUM);

    const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
    const auto *enum_object = (const UHDM::enum_typespec *)handle->object;
    const auto *typespec = enum_object->Base_typespec();

    if (typespec && typespec->UhdmType() == UHDM::uhdmlogic_typespec) {
        // If it's a logic_typespec, try to reduce expressions inside of it.
        // The `reduceExpr` function needs the whole context of the enum typespec
        //   so it's called here instead of `process_operation` or any other more specific function.

        const UHDM::logic_typespec *logic_typespec_obj = enum_object->Base_typespec()->Cast<const UHDM::logic_typespec *>();
        std::vector<UHDM::range *> ranges;
        // Check if ranges exist, as Ranges() returns a pointer to std::vector.
        if (logic_typespec_obj->Ranges()) {
            ranges = *(logic_typespec_obj->Ranges());
        }
        for (UHDM::range *range_obj : ranges) {
            // For each range, take both left and right and reduce them if they're of type uhdmoperation.
            const auto *leftrange_obj = range_obj->Left_expr();
            const auto *rightrange_obj = range_obj->Right_expr();
            log_assert(leftrange_obj);
            log_assert(rightrange_obj);

            if (leftrange_obj->UhdmType() == UHDM::uhdmoperation) {
                // Substitute the previous leftrange with the resolved operation result.
                range_obj->Left_expr(reduce_expression(leftrange_obj, enum_object->Instance() ? enum_object->Instance() : enum_object->VpiParent(),
                                                       enum_object->VpiParent()));
            }
            if (rightrange_obj->UhdmType() == UHDM::uhdmoperation) {
                // Substitute the previous rightrange with the resolved operation result.
                range_obj->Right_expr(reduce_expression(rightrange_obj, enum_object->Instance() ? enum_object->Instance() : enum_object->VpiParent(),
                                                        enum_object->VpiParent()));
            }
        }
    }

    bool has_base_type = false;
    visit_one_to_one({vpiBaseTypespec}, obj_h, [&](AST::AstNode *node) {
        has_base_type = true;
        current_node->children = std::move(node->children);
        current_node->attributes = std::move(node->attributes);
        current_node->is_signed = node->is_signed;
        current_node->is_logic = node->is_logic;
        delete node;
    });
    if (!has_base_type) {
        // Base typespec is `int` by default
        // TODO (mglb): This is almost the same code as in `process_int_typespec()`. Put common code in dedicated function.
        std::vector<AST::AstNode *> packed_ranges;
        packed_ranges.push_back(make_range(31, 0));
        add_multirange_wire(current_node, std::move(packed_ranges), {});
        current_node->is_signed = true;
    }
    // We have to restore node's range_* properties if there's no range.
    const auto range_left = current_node->range_left;
    const auto range_right = current_node->range_right;
    const auto range_valid = current_node->range_valid;
    // Create a range from the typespec just for the purpose of copying it to consts.
    convert_packed_unpacked_range(current_node);
    const auto range_it = std::find_if(current_node->children.cbegin(), current_node->children.cend(),
                                       [](const AST::AstNode *n) { return n->type == AST::AST_RANGE || n->type == AST::AST_MULTIRANGE; });
    const auto *const range = range_it != current_node->children.cend() ? *range_it : nullptr;
    if (range) {
        current_node->children.erase(range_it);
    } else {
        current_node->range_left = range_left;
        current_node->range_right = range_right;
        current_node->range_valid = range_valid;
    }

    visit_one_to_one({vpiTypedefAlias}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->attributes["\\enum_base_type"] = node;
        }
    });
    visit_one_to_many({vpiEnumConst}, obj_h, [&](AST::AstNode *node) {
        // Enum const must have the same type and ranges as the enum.
        node->is_logic = current_node->is_logic;
        node->is_signed = current_node->is_signed;
        if (range) {
            node->children.push_back(range->clone());
            node->range_valid = true;
        } else {
            node->range_left = range_left;
            node->range_right = range_right;
            node->range_valid = range_valid;
        }
        // IMPORTANT: invalidates `range_it`!
        current_node->children.push_back(node);
    });
    if (range) {
        delete range;
    }
}

void UhdmAst::process_enum_const()
{
    current_node = make_ast_node(AST::AST_ENUM_ITEM);
    AST::AstNode *constant_node = process_value(obj_h);
    if (constant_node) {
        constant_node->filename = current_node->filename;
        constant_node->location = current_node->location;
        current_node->children.push_back(constant_node);
    }
}

void UhdmAst::process_custom_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
        if (node->str.empty()) {
            // anonymous typespec, move the children to variable
            current_node->type = node->type;
            copy_packed_unpacked_attribute(node, current_node);
            current_node->children = std::move(node->children);
        } else {
            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
            wiretype_node->str = node->str;
            current_node->children.push_back(wiretype_node);
        }
        delete node;
    });
    auto type = vpi_get(vpiType, obj_h);
    if (type == vpiEnumVar || type == vpiStructVar || type == vpiUnionVar) {
        visit_default_expr(obj_h);
    }
    current_node->is_custom_type = true;
}

void UhdmAst::process_int_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    auto left_const = AST::AstNode::mkconst_int(31, true);
    auto right_const = AST::AstNode::mkconst_int(0, true);
    auto range = new AST::AstNode(AST::AST_RANGE, left_const, right_const);
    current_node->children.push_back(range);
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
    visit_default_expr(obj_h);
}

void UhdmAst::process_real_var()
{
    auto module_node = find_ancestor({AST::AST_MODULE});
    auto wire_node = make_ast_node(AST::AST_WIRE);
    auto left_const = AST::AstNode::mkconst_int(63, true);
    auto right_const = AST::AstNode::mkconst_int(0, true);
    auto range = new AST::AstNode(AST::AST_RANGE, left_const, right_const);
    wire_node->children.push_back(range);
    wire_node->is_signed = true;
    module_node->children.push_back(wire_node);
    current_node = make_ast_node(AST::AST_IDENTIFIER);
    visit_default_expr(obj_h);
}

void UhdmAst::process_array_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
        if (node->str.empty()) {
            // anonymous typespec, move the children to variable
            current_node->type = node->type;
            current_node->children = std::move(node->children);
        } else {
            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
            wiretype_node->str = node->str;
            current_node->children.push_back(wiretype_node);
            current_node->is_custom_type = true;
        }
        delete node;
    });
    vpiHandle itr = vpi_iterate(vpi_get(vpiType, obj_h) == vpiArrayVar ? vpiReg : vpiElement, obj_h);
    while (vpiHandle reg_h = vpi_scan(itr)) {
        if (vpi_get(vpiType, reg_h) == vpiStructVar || vpi_get(vpiType, reg_h) == vpiEnumVar) {
            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
                if (node->str.empty()) {
                    // anonymous typespec, move the children to variable
                    current_node->type = node->type;
                    current_node->children = std::move(node->children);
                } else {
                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    current_node->children.push_back(wiretype_node);
                    current_node->is_custom_type = true;
                }
                delete node;
            });
        } else if (vpi_get(vpiType, reg_h) == vpiLogicVar) {
            current_node->is_logic = true;
            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
                if (node->str.empty()) {
                    // anonymous typespec, move the children to variable
                    current_node->type = node->type;
                    current_node->children = std::move(node->children);
                } else {
                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    current_node->children.push_back(wiretype_node);
                    current_node->is_custom_type = true;
                }
                delete node;
            });
            visit_one_to_many({vpiRange}, reg_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
        } else if (vpi_get(vpiType, reg_h) == vpiIntVar) {
            packed_ranges.push_back(make_range(31, 0));
            visit_default_expr(reg_h);
        }
        vpi_release_handle(reg_h);
    }
    vpi_release_handle(itr);
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    visit_default_expr(obj_h);
}

void UhdmAst::process_packed_array_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
        if (node->str.empty()) {
            // anonymous typespec, move the children to variable
            current_node->type = node->type;
            current_node->children = std::move(node->children);
        } else {
            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
            wiretype_node->str = node->str;
            current_node->children.push_back(wiretype_node);
            current_node->is_custom_type = true;
        }
        delete node;
    });
    vpiHandle itr = vpi_iterate(vpi_get(vpiType, obj_h) == vpiArrayVar ? vpiReg : vpiElement, obj_h);
    while (vpiHandle reg_h = vpi_scan(itr)) {
        if (vpi_get(vpiType, reg_h) == vpiStructVar || vpi_get(vpiType, reg_h) == vpiEnumVar) {
            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
                if (node->str.empty()) {
                    // anonymous typespec, move the children to variable
                    current_node->type = node->type;
                    current_node->children = std::move(node->children);
                } else {
                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    current_node->children.push_back(wiretype_node);
                    current_node->is_custom_type = true;
                }
                delete node;
            });
        } else if (vpi_get(vpiType, reg_h) == vpiLogicVar) {
            current_node->is_logic = true;
            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
                if (node->str.empty()) {
                    // anonymous typespec, move the children to variable
                    current_node->type = node->type;
                    current_node->children = std::move(node->children);
                } else {
                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    current_node->children.push_back(wiretype_node);
                    current_node->is_custom_type = true;
                }
                delete node;
            });
            visit_one_to_many({vpiRange}, reg_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
        } else if (vpi_get(vpiType, reg_h) == vpiIntVar) {
            packed_ranges.push_back(make_range(31, 0));
            visit_default_expr(reg_h);
        }
        vpi_release_handle(reg_h);
    }
    vpi_release_handle(itr);
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    visit_default_expr(obj_h);
}

void UhdmAst::process_param_assign()
{
    current_node = make_ast_node(AST::AST_PARAMETER);
    visit_one_to_one({vpiLhs}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->type = node->type;
            current_node->str = node->str;
            // Here we need to copy any ranges that is already present in lhs,
            // but we want to skip actual value, as it is set in rhs
            for (auto *c : node->children) {
                if (c->type != AST::AST_CONSTANT) {
                    current_node->children.push_back(c->clone());
                }
            }
            delete_children(node);
            copy_packed_unpacked_attribute(node, current_node);
            current_node->is_custom_type = node->is_custom_type;
            auto it = shared.param_types.find(current_node->str);
            if (it == shared.param_types.end())
                shared.param_types[current_node->str] = shared.param_types[node->str];
            delete node;
        }
    });
    visit_one_to_one({vpiRhs}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (node->children.size() > 1 && (node->children[1]->type == AST::AST_PARAMETER || node->children[1]->type == AST::AST_LOCALPARAM)) {
                node->children[1]->type = AST::AST_IDENTIFIER;
            }
            current_node->children.insert(current_node->children.begin(), node);
        }
    });
}

void UhdmAst::process_cont_assign_var_init()
{
    current_node = make_ast_node(AST::AST_INITIAL);
    auto block_node = make_ast_node(AST::AST_BLOCK);
    auto assign_node = make_ast_node(AST::AST_ASSIGN_LE);
    block_node->children.push_back(assign_node);
    current_node->children.push_back(block_node);

    visit_one_to_one({vpiLhs, vpiRhs}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (node->type == AST::AST_WIRE || node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
                assign_node->children.push_back(new AST::AstNode(AST::AST_IDENTIFIER));
                assign_node->children.back()->str = node->str;
                delete node;
            } else {
                assign_node->children.push_back(node);
            }
        }
    });
}

void UhdmAst::process_cont_assign_net()
{
    current_node = make_ast_node(AST::AST_ASSIGN);

    visit_one_to_one({vpiLhs, vpiRhs}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (node->type == AST::AST_WIRE || node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
                current_node->children.push_back(new AST::AstNode(AST::AST_IDENTIFIER));
                current_node->children.back()->str = node->str;
            } else {
                current_node->children.push_back(node->clone());
            }
            delete node;
        }
    });
}

void UhdmAst::process_cont_assign()
{
    auto net_decl_assign = vpi_get(vpiNetDeclAssign, obj_h);
    vpiHandle node_lhs_h = vpi_handle(vpiLhs, obj_h);
    auto lhs_net_type = vpi_get(vpiNetType, node_lhs_h);
    vpi_release_handle(node_lhs_h);

    // Check if lhs is a subtype of a net
    bool isNet;
    if (lhs_net_type >= vpiWire && lhs_net_type <= vpiUwire)
        isNet = true;
    else
        // lhs is a variable
        isNet = false;
    if (net_decl_assign && !isNet)
        process_cont_assign_var_init();
    else
        process_cont_assign_net();
}

void UhdmAst::process_assignment(const UHDM::BaseClass *object)
{
    auto type = vpi_get(vpiBlocking, obj_h) == 1 ? AST::AST_ASSIGN_EQ : AST::AST_ASSIGN_LE;
    bool shift_unsigned = false;
    int op_type = vpi_get(vpiOpType, obj_h);
    AST::AstNodeType node_type;
    current_node = make_ast_node(type);

    visit_one_to_one({vpiLhs, vpiRhs}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            // fix node types for some assignments
            // yosys requires that declaration of variable
            // and assignment are separated
            switch (node->type) {
            case AST::AST_WIRE:
                // wires can be declarated inside initialization block of for block
                if (AST::AstNode *for_block = find_ancestor({AST::AST_BLOCK})) {
                    if (for_block->str.find("$fordecl_block") != std::string::npos)
                        break;
                }
                [[fallthrough]];
            case AST::AST_PARAMETER:
            case AST::AST_LOCALPARAM:
                node->type = AST::AST_IDENTIFIER;
                delete_children(node);
                delete_attribute(node, UhdmAst::packed_ranges());
                delete_attribute(node, UhdmAst::unpacked_ranges());
                break;
            default:
                break;
            };
            current_node->children.push_back(node);
        }
    });
    if (op_type && op_type != vpiAssignmentOp) {
        switch (op_type) {
        case vpiSubOp:
            node_type = AST::AST_SUB;
            break;
        case vpiDivOp:
            node_type = AST::AST_DIV;
            break;
        case vpiModOp:
            node_type = AST::AST_MOD;
            break;
        case vpiLShiftOp:
            node_type = AST::AST_SHIFT_LEFT;
            shift_unsigned = true;
            break;
        case vpiRShiftOp:
            node_type = AST::AST_SHIFT_RIGHT;
            shift_unsigned = true;
            break;
        case vpiAddOp:
            node_type = AST::AST_ADD;
            break;
        case vpiMultOp:
            node_type = AST::AST_MUL;
            break;
        case vpiBitAndOp:
            node_type = AST::AST_BIT_AND;
            break;
        case vpiBitOrOp:
            node_type = AST::AST_BIT_OR;
            break;
        case vpiBitXorOp:
            node_type = AST::AST_BIT_XOR;
            break;
        case vpiArithLShiftOp:
            node_type = AST::AST_SHIFT_SLEFT;
            shift_unsigned = true;
            break;
        case vpiArithRShiftOp:
            node_type = AST::AST_SHIFT_SRIGHT;
            shift_unsigned = true;
            break;
        default:
            delete current_node;
            current_node = nullptr;
            report_error("%.*s:%d: Encountered unhandled compound assignment with operation type %d\n", (int)object->VpiFile().length(),
                         object->VpiFile().data(), object->VpiLineNo(), op_type);
            return;
        }
        log_assert(current_node->children.size() == 2);
        auto child_node = new AST::AstNode(node_type, current_node->children[0]->clone(), current_node->children[1]);
        current_node->children[1] = child_node;
        if (shift_unsigned) {
            log_assert(current_node->children[1]->children.size() == 2);
            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]->children[1]);
            current_node->children[1]->children[1] = unsigned_node;
        }
    }
    if (current_node->children.size() == 1 && current_node->children[0]->type == AST::AST_WIRE) {
        auto top_node = find_ancestor({AST::AST_MODULE});
        if (!top_node)
            return;
        top_node->children.push_back(current_node->children[0]->clone());
        current_node = nullptr;
    }
}

void UhdmAst::process_packed_array_net()
{
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    current_node = make_ast_node(AST::AST_WIRE);
    visit_one_to_many({vpiElement}, obj_h, [&](AST::AstNode *node) {
        if (node && GetSize(node->children) == 1)
            current_node->children.push_back(node->children[0]->clone());
        current_node->is_custom_type = node->is_custom_type;
        delete node;
    });
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

void UhdmAst::process_array_net(const UHDM::BaseClass *object)
{
    current_node = make_ast_node(AST::AST_WIRE);
    vpiHandle itr = vpi_iterate(vpiNet, obj_h);
    std::vector<AST::AstNode *> packed_ranges;
    std::vector<AST::AstNode *> unpacked_ranges;
    while (vpiHandle net_h = vpi_scan(itr)) {
        auto net_type = vpi_get(vpiType, net_h);
        if (net_type == vpiLogicNet) {
            current_node->is_logic = true;
            current_node->is_signed = vpi_get(vpiSigned, net_h);
            vpiHandle typespec_h = vpi_handle(vpiTypespec, net_h);
            if (!typespec_h) {
                typespec_h = vpi_handle(vpiTypespec, obj_h);
            }
            if (typespec_h) {
                visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
                vpi_release_handle(typespec_h);
            } else {
                visit_one_to_many({vpiRange}, net_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
            }
            shared.report.mark_handled(net_h);
        } else if (net_type == vpiStructNet) {
            visit_one_to_one({vpiTypespec}, net_h, [&](AST::AstNode *node) {
                if (node->str.empty()) {
                    // anonymous typespec, move the children to variable
                    current_node->type = node->type;
                    current_node->children = std::move(node->children);
                } else {
                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    current_node->children.push_back(wiretype_node);
                    current_node->is_custom_type = true;
                }
                delete node;
            });
        }
        vpi_release_handle(net_h);
    }
    vpi_release_handle(itr);
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

void UhdmAst::process_package()
{
    current_node = make_ast_node(AST::AST_PACKAGE);
    shared.current_top_node = current_node;
    visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            move_type_to_new_typedef(current_node, node);
        }
    });
    visit_one_to_many({vpiParameter, vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            node->str = strip_package_name(node->str);
            for (auto c : node->children) {
                c->str = strip_package_name(c->str);
            }
            add_or_replace_child(current_node, node);
        }
    });
    visit_one_to_many({vpiTaskFunc}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });
}

void UhdmAst::process_interface()
{
    std::string type = vpi_get_str(vpiDefName, obj_h);
    std::string name = vpi_get_str(vpiName, obj_h) ? vpi_get_str(vpiName, obj_h) : type;
    sanitize_symbol_name(type);
    sanitize_symbol_name(name);
    AST::AstNode *elaboratedInterface;
    // Check if we have encountered this object before
    if (shared.top_nodes.find(type) != shared.top_nodes.end()) {
        // Was created before, fill missing
        elaboratedInterface = shared.top_nodes[type];
        visit_one_to_many({vpiPort, vpiVariables}, obj_h, [&](AST::AstNode *node) {
            if (node) {
                add_or_replace_child(elaboratedInterface, node);
            }
        });
    } else {
        // Encountered for the first time
        elaboratedInterface = new AST::AstNode(AST::AST_INTERFACE);
        elaboratedInterface->str = name;
        visit_one_to_many({vpiNet, vpiPort, vpiModport}, obj_h, [&](AST::AstNode *node) {
            if (node) {
                add_or_replace_child(elaboratedInterface, node);
            }
        });
    }
    shared.top_nodes[elaboratedInterface->str] = elaboratedInterface;
    if (name != type) {
        // Not a top module, create instance
        current_node = make_ast_node(AST::AST_CELL);
        make_cell(obj_h, current_node, elaboratedInterface);
    } else {
        current_node = elaboratedInterface;
    }
}

void UhdmAst::process_modport()
{
    current_node = make_ast_node(AST::AST_MODPORT);
    visit_one_to_many({vpiIODecl}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });
}

void UhdmAst::process_io_decl()
{
    current_node = nullptr;
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) { current_node = node; });
    if (current_node == nullptr) {
        current_node = make_ast_node(AST::AST_MODPORTMEMBER);
        visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
    }
    std::reverse(unpacked_ranges.begin(), unpacked_ranges.end());

    visit_one_to_one({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (!node->str.empty()) {
                auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
                wiretype_node->str = node->str;
                // wiretype needs to be 1st node (if port have also another range nodes)
                current_node->children.insert(current_node->children.begin(), wiretype_node);
                current_node->is_custom_type = true;
            } else {
                // anonymous typedef, just move children
                for (auto child : node->children) {
                    current_node->children.push_back(child->clone());
                }
                if (node->attributes.count(UhdmAst::packed_ranges())) {
                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
                        packed_ranges.push_back(r->clone());
                    }
                }
                if (node->attributes.count(UhdmAst::unpacked_ranges())) {
                    for (auto r : node->attributes[UhdmAst::unpacked_ranges()]->children) {
                        unpacked_ranges.push_back(r->clone());
                    }
                }
                current_node->is_logic = node->is_logic;
                current_node->is_reg = node->is_reg;
            }
            current_node->is_signed = node->is_signed;
            delete node;
        }
    });
    if (const int n = vpi_get(vpiDirection, obj_h)) {
        if (n == vpiInput) {
            current_node->is_input = true;
        } else if (n == vpiOutput) {
            current_node->is_output = true;
        } else if (n == vpiInout) {
            current_node->is_input = true;
            current_node->is_output = true;
        }
    }
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges, false);
}

void UhdmAst::process_always()
{
    current_node = make_ast_node(AST::AST_ALWAYS);
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            AST::AstNode *block = nullptr;
            if (node->type != AST::AST_BLOCK) {
                block = new AST::AstNode(AST::AST_BLOCK, node);
            } else {
                block = node;
            }
            current_node->children.push_back(block);
        } else {
            // create empty block
            current_node->children.push_back(new AST::AstNode(AST::AST_BLOCK));
        }
    });
    switch (vpi_get(vpiAlwaysType, obj_h)) {
    case vpiAlwaysComb:
        current_node->attributes[ID::always_comb] = AST::AstNode::mkconst_int(1, false);
        break;
    case vpiAlwaysFF:
        current_node->attributes[ID::always_ff] = AST::AstNode::mkconst_int(1, false);
        break;
    case vpiAlwaysLatch:
        current_node->attributes[ID::always_latch] = AST::AstNode::mkconst_int(1, false);
        break;
    default:
        break;
    }
}

void UhdmAst::process_event_control(const UHDM::BaseClass *object)
{
    current_node = make_ast_node(AST::AST_BLOCK);
    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            auto process_node = find_ancestor({AST::AST_ALWAYS});
            if (!process_node) {
                log_error("%.*s:%d: Currently supports only event control stmts inside 'always'\n", (int)object->VpiFile().length(),
                          object->VpiFile().data(), object->VpiLineNo());
            }
            process_node->children.push_back(node);
        }
        // is added inside vpiOperation
    });
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });
}

void UhdmAst::process_initial()
{
    current_node = make_ast_node(AST::AST_INITIAL);
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (node->type != AST::AST_BLOCK) {
                auto block_node = make_ast_node(AST::AST_BLOCK);
                block_node->children.push_back(node);
                node = block_node;
            }
            current_node->children.push_back(node);
        } else {
            current_node->children.push_back(make_ast_node(AST::AST_BLOCK));
        }
    });
}

void UhdmAst::process_begin(bool is_named)
{
    current_node = make_ast_node(AST::AST_BLOCK);
    if (!is_named) {
        // for unnamed block, reset block name
        current_node->str = "";
    }
    AST::AstNode *hierarchy_node = nullptr;
    static int unnamed_block_idx = 0;
    visit_one_to_many({vpiVariables}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (!is_named) {
                if (!hierarchy_node) {
                    // Create an implicit hierarchy scope
                    // simplify checks if sv_mode is set to true when wire is declared inside unnamed block
                    VERILOG_FRONTEND::sv_mode = true;
                    hierarchy_node = make_ast_node(AST::AST_BLOCK);
                    hierarchy_node->str = "$unnamed_block$" + std::to_string(unnamed_block_idx++);
                }
                hierarchy_node->children.push_back(node);
            } else {
                current_node->children.push_back(node);
            }
        }
    });
    visit_one_to_many({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if ((node->type == AST::AST_ASSIGN_EQ || node->type == AST::AST_ASSIGN_LE) && node->children.size() == 1) {
                auto func_node = find_ancestor({AST::AST_FUNCTION, AST::AST_TASK});
                if (!func_node) {
                    delete node;
                    return;
                }
                auto wire_node = new AST::AstNode(AST::AST_WIRE);
                wire_node->type = AST::AST_WIRE;
                wire_node->str = node->children[0]->str;
                func_node->children.push_back(wire_node);
                delete node;
            } else {
                if (hierarchy_node)
                    hierarchy_node->children.push_back(node);
                else
                    current_node->children.push_back(node);
            }
        }
    });
    if (hierarchy_node)
        current_node->children.push_back(hierarchy_node);
}

void UhdmAst::process_operation(const UHDM::BaseClass *object)
{
    auto operation = vpi_get(vpiOpType, obj_h);
    switch (operation) {
    case vpiStreamRLOp:
        process_stream_op();
        break;
    case vpiEventOrOp:
    case vpiListOp:
        process_list_op();
        break;
    case vpiCastOp:
        process_cast_op();
        break;
    case vpiInsideOp:
        process_inside_op();
        break;
    case vpiAssignmentPatternOp:
        process_assignment_pattern_op();
        break;
    case vpiWildEqOp:
    case vpiWildNeqOp: {
        report_error("%.*s:%d: Wildcard operators are not supported yet\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                     object->VpiLineNo());
        break;
    }
    default: {
        current_node = make_ast_node(AST::AST_NONE);
        visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
            if (node) {
                current_node->children.push_back(node);
            }
        });
        switch (operation) {
        case vpiMinusOp:
            current_node->type = AST::AST_NEG;
            break;
        case vpiPlusOp:
            current_node->type = AST::AST_POS;
            break;
        case vpiPosedgeOp:
            current_node->type = AST::AST_POSEDGE;
            break;
        case vpiNegedgeOp:
            current_node->type = AST::AST_NEGEDGE;
            break;
        case vpiUnaryAndOp:
            current_node->type = AST::AST_REDUCE_AND;
            break;
        case vpiUnaryOrOp:
            current_node->type = AST::AST_REDUCE_OR;
            break;
        case vpiUnaryXorOp:
            current_node->type = AST::AST_REDUCE_XOR;
            break;
        case vpiUnaryXNorOp:
            current_node->type = AST::AST_REDUCE_XNOR;
            break;
        case vpiUnaryNandOp: {
            auto not_node = new AST::AstNode(AST::AST_NONE, current_node);
            if (current_node->children.size() == 2) {
                current_node->type = AST::AST_BIT_AND;
                not_node->type = AST::AST_BIT_NOT;
            } else {
                current_node->type = AST::AST_REDUCE_AND;
                not_node->type = AST::AST_LOGIC_NOT;
            }
            current_node = not_node;
            break;
        }
        case vpiUnaryNorOp: {
            auto not_node = new AST::AstNode(AST::AST_NONE, current_node);
            if (current_node->children.size() == 2) {
                current_node->type = AST::AST_BIT_OR;
                not_node->type = AST::AST_BIT_NOT;
            } else {
                current_node->type = AST::AST_REDUCE_OR;
                not_node->type = AST::AST_LOGIC_NOT;
            }
            current_node = not_node;
            break;
        }
        case vpiBitNegOp:
            current_node->type = AST::AST_BIT_NOT;
            break;
        case vpiBitAndOp:
            current_node->type = AST::AST_BIT_AND;
            break;
        case vpiBitOrOp:
            current_node->type = AST::AST_BIT_OR;
            break;
        case vpiBitXorOp:
            current_node->type = AST::AST_BIT_XOR;
            break;
        case vpiBitXnorOp:
            current_node->type = AST::AST_BIT_XNOR;
            break;
        case vpiLShiftOp: {
            current_node->type = AST::AST_SHIFT_LEFT;
            log_assert(current_node->children.size() == 2);
            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
            current_node->children[1] = unsigned_node;
            break;
        }
        case vpiRShiftOp: {
            current_node->type = AST::AST_SHIFT_RIGHT;
            log_assert(current_node->children.size() == 2);
            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
            current_node->children[1] = unsigned_node;
            break;
        }
        case vpiNotOp:
            current_node->type = AST::AST_LOGIC_NOT;
            break;
        case vpiLogAndOp:
            current_node->type = AST::AST_LOGIC_AND;
            break;
        case vpiLogOrOp:
            current_node->type = AST::AST_LOGIC_OR;
            break;
        case vpiEqOp:
            current_node->type = AST::AST_EQ;
            break;
        case vpiNeqOp:
            current_node->type = AST::AST_NE;
            break;
        case vpiCaseEqOp:
            current_node->type = AST::AST_EQX;
            break;
        case vpiCaseNeqOp:
            current_node->type = AST::AST_NEX;
            break;
        case vpiGtOp:
            current_node->type = AST::AST_GT;
            break;
        case vpiGeOp:
            current_node->type = AST::AST_GE;
            break;
        case vpiLtOp:
            current_node->type = AST::AST_LT;
            break;
        case vpiLeOp:
            current_node->type = AST::AST_LE;
            break;
        case vpiSubOp:
            current_node->type = AST::AST_SUB;
            if (!current_node->children.empty() && current_node->children[0]->type == AST::AST_LOCALPARAM) {
                current_node->children[0]->type = AST::AST_IDENTIFIER;
            }
            break;
        case vpiAddOp:
            current_node->type = AST::AST_ADD;
            break;
        case vpiMultOp:
            current_node->type = AST::AST_MUL;
            break;
        case vpiDivOp:
            current_node->type = AST::AST_DIV;
            break;
        case vpiModOp:
            current_node->type = AST::AST_MOD;
            break;
        case vpiArithLShiftOp: {
            current_node->type = AST::AST_SHIFT_SLEFT;
            log_assert(current_node->children.size() == 2);
            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
            current_node->children[1] = unsigned_node;
            break;
        }
        case vpiArithRShiftOp: {
            current_node->type = AST::AST_SHIFT_SRIGHT;
            log_assert(current_node->children.size() == 2);
            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
            current_node->children[1] = unsigned_node;
            break;
        }
        case vpiPowerOp:
            current_node->type = AST::AST_POW;
            break;
        case vpiPostIncOp: {
            // TODO: Make this an actual post-increment op (currently it's a pre-increment)
            log_warning("%.*s:%d: Post-incrementation operations are handled as pre-incrementation.\n", (int)object->VpiFile().length(),
                        object->VpiFile().data(), object->VpiLineNo());
            [[fallthrough]];
        }
        case vpiPreIncOp: {
            current_node->type = AST::AST_ASSIGN_EQ;
            auto id = current_node->children[0]->clone();
            auto add_node = new AST::AstNode(AST::AST_ADD, id, AST::AstNode::mkconst_int(1, true));
            add_node->filename = current_node->filename;
            add_node->location = current_node->location;
            current_node->children.push_back(add_node);
            break;
        }
        case vpiPostDecOp: {
            // TODO: Make this an actual post-decrement op (currently it's a pre-decrement)
            log_warning("%.*s:%d: Post-decrementation operations are handled as pre-decrementation.\n", (int)object->VpiFile().length(),
                        object->VpiFile().data(), object->VpiLineNo());
            [[fallthrough]];
        }
        case vpiPreDecOp: {
            current_node->type = AST::AST_ASSIGN_EQ;
            auto id = current_node->children[0]->clone();
            auto add_node = new AST::AstNode(AST::AST_SUB, id, AST::AstNode::mkconst_int(1, true));
            add_node->filename = current_node->filename;
            add_node->location = current_node->location;
            current_node->children.push_back(add_node);
            break;
        }
        case vpiConditionOp:
            current_node->type = AST::AST_TERNARY;
            break;
        case vpiConcatOp: {
            current_node->type = AST::AST_CONCAT;
            std::reverse(current_node->children.begin(), current_node->children.end());
            break;
        }
        case vpiMultiConcatOp:
        case vpiMultiAssignmentPatternOp:
            current_node->type = AST::AST_REPLICATE;
            break;
        case vpiAssignmentOp:
            current_node->type = AST::AST_ASSIGN_EQ;
            break;
        case vpiStreamLROp: {
            auto concat_node = current_node->children.back();
            current_node->children.pop_back();
            delete current_node;
            current_node = concat_node;
            break;
        }
        case vpiNullOp: {
            delete current_node;
            current_node = nullptr;
            break;
        }
        case vpiMinTypMaxOp: {
            // ignore min and max and set only typ
            log_assert(current_node->children.size() == 3);
            auto tmp = current_node->children[1]->clone();
            delete current_node;
            current_node = tmp;
            break;
        }
        default: {
            delete current_node;
            current_node = nullptr;
            report_error("%.*s:%d: Encountered unhandled operation type %d\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                         object->VpiLineNo(), operation);
        }
        }
    }
    }
}

void UhdmAst::process_stream_op()
{
    // Create a for loop that does what a streaming operator would do
    auto block_node = find_ancestor({AST::AST_BLOCK, AST::AST_ALWAYS, AST::AST_INITIAL});
    auto process_node = find_ancestor({AST::AST_ALWAYS, AST::AST_INITIAL});
    auto module_node = find_ancestor({AST::AST_MODULE, AST::AST_FUNCTION, AST::AST_PACKAGE});
    log_assert(module_node);
    if (!process_node) {
        if (module_node->type != AST::AST_FUNCTION) {
            // Create a @* always block
            process_node = make_ast_node(AST::AST_ALWAYS);
            module_node->children.push_back(process_node);
            block_node = make_ast_node(AST::AST_BLOCK);
            process_node->children.push_back(block_node);
        } else {
            // Create only block
            block_node = make_ast_node(AST::AST_BLOCK);
            module_node->children.push_back(block_node);
        }
    }

    auto loop_id = shared.next_loop_id();
    auto loop_counter =
      make_ast_node(AST::AST_WIRE, {make_ast_node(AST::AST_RANGE, {AST::AstNode::mkconst_int(31, false), AST::AstNode::mkconst_int(0, false)})});
    loop_counter->is_reg = true;
    loop_counter->is_signed = true;
    loop_counter->str = "\\loop" + std::to_string(loop_id) + "::i";
    module_node->children.insert(module_node->children.end() - 1, loop_counter);
    auto loop_counter_ident = make_ast_node(AST::AST_IDENTIFIER);
    loop_counter_ident->str = loop_counter->str;

    auto lhs_node = find_ancestor({AST::AST_ASSIGN, AST::AST_ASSIGN_EQ, AST::AST_ASSIGN_LE})->children[0];
    // Temp var to allow concatenation
    AST::AstNode *temp_var = nullptr;
    AST::AstNode *bits_call = nullptr;
    if (lhs_node->type == AST::AST_WIRE) {
        module_node->children.insert(module_node->children.begin(), lhs_node->clone());
        temp_var = lhs_node->clone(); // if we already have wire as lhs, we want to create the same wire for temp_var
        lhs_node->delete_children();
        lhs_node->type = AST::AST_IDENTIFIER;
        bits_call = make_ast_node(AST::AST_FCALL, {lhs_node->clone()});
        bits_call->str = "\\$bits";
    } else {
        // otherwise, we need to calculate size using bits fcall
        bits_call = make_ast_node(AST::AST_FCALL, {lhs_node->clone()});
        bits_call->str = "\\$bits";
        temp_var =
          make_ast_node(AST::AST_WIRE, {make_ast_node(AST::AST_RANGE, {make_ast_node(AST::AST_SUB, {bits_call, AST::AstNode::mkconst_int(1, false)}),
                                                                       AST::AstNode::mkconst_int(0, false)})});
    }

    temp_var->str = "\\loop" + std::to_string(loop_id) + "::temp";
    module_node->children.insert(module_node->children.end() - 1, temp_var);
    auto temp_var_ident = make_ast_node(AST::AST_IDENTIFIER);
    temp_var_ident->str = temp_var->str;
    auto temp_assign = make_ast_node(AST::AST_ASSIGN_EQ, {temp_var_ident});
    block_node->children.push_back(temp_assign);

    // Assignment in the loop's block
    auto assign_node = make_ast_node(AST::AST_ASSIGN_EQ, {lhs_node->clone(), temp_var_ident->clone()});
    AST::AstNode *slice_size = nullptr; // First argument in streaming op
    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
        if (!slice_size && node->type == AST::AST_CONSTANT) {
            slice_size = node;
        } else {
            temp_assign->children.push_back(node);
        }
    });
    if (!slice_size) {
        slice_size = AST::AstNode::mkconst_int(1, true);
    }

    // Initialization of the loop counter to 0
    auto init_stmt = make_ast_node(AST::AST_ASSIGN_EQ, {loop_counter_ident, AST::AstNode::mkconst_int(0, true)});

    // Loop condition (loop counter < $bits(RHS))
    auto cond_stmt =
      make_ast_node(AST::AST_LE, {loop_counter_ident->clone(), make_ast_node(AST::AST_SUB, {bits_call->clone(), slice_size->clone()})});

    // Increment loop counter
    auto inc_stmt =
      make_ast_node(AST::AST_ASSIGN_EQ, {loop_counter_ident->clone(), make_ast_node(AST::AST_ADD, {loop_counter_ident->clone(), slice_size})});

    // Range on the LHS of the assignment
    auto lhs_range = make_ast_node(AST::AST_RANGE);
    auto lhs_selfsz = make_ast_node(
      AST::AST_SELFSZ, {make_ast_node(AST::AST_SUB, {make_ast_node(AST::AST_SUB, {bits_call->clone(), AST::AstNode::mkconst_int(1, true)}),
                                                     loop_counter_ident->clone()})});
    lhs_range->children.push_back(make_ast_node(AST::AST_ADD, {lhs_selfsz, AST::AstNode::mkconst_int(0, true)}));
    lhs_range->children.push_back(
      make_ast_node(AST::AST_SUB, {make_ast_node(AST::AST_ADD, {lhs_selfsz->clone(), AST::AstNode::mkconst_int(1, true)}), slice_size->clone()}));

    // Range on the RHS of the assignment
    auto rhs_range = make_ast_node(AST::AST_RANGE);
    auto rhs_selfsz = make_ast_node(AST::AST_SELFSZ, {loop_counter_ident->clone()});
    rhs_range->children.push_back(
      make_ast_node(AST::AST_SUB, {make_ast_node(AST::AST_ADD, {rhs_selfsz, slice_size->clone()}), AST::AstNode::mkconst_int(1, true)}));
    rhs_range->children.push_back(make_ast_node(AST::AST_ADD, {rhs_selfsz->clone(), AST::AstNode::mkconst_int(0, true)}));

    // Put ranges on the sides of the assignment
    assign_node->children[0]->children.push_back(lhs_range);
    assign_node->children[1]->children.push_back(rhs_range);

    // Putting the loop together
    auto loop_node = make_ast_node(AST::AST_FOR);
    loop_node->str = "$loop" + std::to_string(loop_id);
    loop_node->children.push_back(init_stmt);
    loop_node->children.push_back(cond_stmt);
    loop_node->children.push_back(inc_stmt);
    loop_node->children.push_back(make_ast_node(AST::AST_BLOCK, {assign_node}));
    loop_node->children[3]->str = "\\stream_op_block" + std::to_string(loop_id);

    block_node->children.push_back(make_ast_node(AST::AST_BLOCK, {loop_node}));

    // Do not create a node
    shared.report.mark_handled(obj_h);
}

void UhdmAst::process_list_op()
{
    // Add all operands as children of process node
    if (auto parent_node = find_ancestor({AST::AST_ALWAYS, AST::AST_COND})) {
        visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
            // add directly to process/cond node
            if (node) {
                parent_node->children.push_back(node);
            }
        });
    } else {
        log_error("Unhandled list op, couldn't find parent node.");
    }
    // Do not create a node
    shared.report.mark_handled(obj_h);
}

void UhdmAst::process_cast_op()
{
    current_node = make_ast_node(AST::AST_NONE);
    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
        node->cloneInto(current_node);
        delete node;
    });
    vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h);
    shared.report.mark_handled(typespec_h);
    vpi_release_handle(typespec_h);
}

void UhdmAst::process_inside_op()
{
    current_node = make_ast_node(AST::AST_EQ);
    AST::AstNode *lhs = nullptr;
    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
        if (!lhs) {
            lhs = node;
        }
        if (current_node->children.size() < 2) {
            current_node->children.push_back(node);
        } else {
            auto or_node = new AST::AstNode(AST::AST_LOGIC_OR);
            or_node->filename = current_node->filename;
            or_node->location = current_node->location;
            auto eq_node = new AST::AstNode(AST::AST_EQ);
            eq_node->filename = current_node->filename;
            eq_node->location = current_node->location;
            or_node->children.push_back(current_node);
            or_node->children.push_back(eq_node);
            eq_node->children.push_back(lhs->clone());
            eq_node->children.push_back(node);
            current_node = or_node;
        }
    });
}

void UhdmAst::process_assignment_pattern_op()
{
    current_node = make_ast_node(AST::AST_CONCAT);
    if (auto param_node = find_ancestor({AST::AST_PARAMETER, AST::AST_LOCALPARAM})) {
        std::map<size_t, AST::AstNode *> ordered_children;
        visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
            if (node->type == AST::AST_ASSIGN || node->type == AST::AST_ASSIGN_EQ || node->type == AST::AST_ASSIGN_LE) {
                // Find at what position in the concat should we place this node
                auto key = node->children[0]->str;
                key = key.substr(key.find('.') + 1);
                auto param_type = shared.param_types[param_node->str];
                if (!param_type) {
                    log_error("Couldn't find parameter type for node: %s\n", param_node->str.c_str());
                }
                size_t pos =
                  std::find_if(param_type->children.begin(), param_type->children.end(), [key](AST::AstNode *child) { return child->str == key; }) -
                  param_type->children.begin();
                ordered_children.insert(std::make_pair(pos, node->children[1]->clone()));
                delete node;
            } else {
                current_node->children.push_back(node);
            }
        });
        for (auto p : ordered_children) {
            current_node->children.push_back(p.second);
        }
        std::reverse(current_node->children.begin(), current_node->children.end());
        return;
    }
    auto assign_node = find_ancestor({AST::AST_ASSIGN, AST::AST_ASSIGN_EQ, AST::AST_ASSIGN_LE});

    auto proc_node =
      find_ancestor({AST::AST_BLOCK, AST::AST_GENBLOCK, AST::AST_ALWAYS, AST::AST_INITIAL, AST::AST_MODULE, AST::AST_PACKAGE, AST::AST_CELL});
    if (proc_node && proc_node->type == AST::AST_CELL && shared.top_nodes.count(proc_node->children[0]->str)) {
        proc_node = shared.top_nodes[proc_node->children[0]->str];
    }
    std::vector<AST::AstNode *> assignments;
    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
        if (node->type == AST::AST_ASSIGN || node->type == AST::AST_ASSIGN_EQ || node->type == AST::AST_ASSIGN_LE) {
            assignments.push_back(node);
        } else {
            current_node->children.push_back(node);
        }
    });
    std::reverse(current_node->children.begin(), current_node->children.end());
    if (!assignments.empty()) {
        if (current_node->children.empty()) {
            delete assign_node->children[0];
            assign_node->children[0] = assignments[0]->children[0];
            current_node = assignments[0]->children[1];
            assignments[0]->children.clear();
            delete assignments[0];
            proc_node->children.insert(proc_node->children.end(), assignments.begin() + 1, assignments.end());
        } else {
            proc_node->children.insert(proc_node->children.end(), assignments.begin(), assignments.end());
        }
    }
}

void UhdmAst::process_bit_select()
{
    current_node = make_ast_node(AST::AST_IDENTIFIER);
    visit_one_to_one({vpiIndex}, obj_h, [&](AST::AstNode *node) {
        auto range_node = new AST::AstNode(AST::AST_RANGE, node);
        range_node->filename = current_node->filename;
        range_node->location = current_node->location;
        current_node->children.push_back(range_node);
    });
}

void UhdmAst::process_part_select()
{
    current_node = make_ast_node(AST::AST_IDENTIFIER);
    vpiHandle parent_h = vpi_handle(vpiParent, obj_h);
    current_node->str = get_name(parent_h);
    vpi_release_handle(parent_h);
    auto range_node = new AST::AstNode(AST::AST_RANGE);
    range_node->filename = current_node->filename;
    range_node->location = current_node->location;
    visit_one_to_one({vpiLeftRange, vpiRightRange}, obj_h, [&](AST::AstNode *node) { range_node->children.push_back(node); });
    current_node->children.push_back(range_node);
}

void UhdmAst::process_indexed_part_select()
{
    current_node = make_ast_node(AST::AST_IDENTIFIER);
    vpiHandle parent_h = vpi_handle(vpiParent, obj_h);
    current_node->str = get_name(parent_h);
    vpi_release_handle(parent_h);
    // TODO: check if there are other types, for now only handle 1 and 2 (+: and -:)
    auto indexed_part_select_type = vpi_get(vpiIndexedPartSelectType, obj_h) == 1 ? AST::AST_ADD : AST::AST_SUB;
    auto range_node = new AST::AstNode(AST::AST_RANGE);
    range_node->filename = current_node->filename;
    range_node->location = current_node->location;
    visit_one_to_one({vpiBaseExpr}, obj_h, [&](AST::AstNode *node) { range_node->children.push_back(node); });
    visit_one_to_one({vpiWidthExpr}, obj_h, [&](AST::AstNode *node) {
        auto right_range_node = new AST::AstNode(indexed_part_select_type);
        right_range_node->children.push_back(range_node->children[0]->clone());
        right_range_node->children.push_back(node);
        auto sub = new AST::AstNode(indexed_part_select_type == AST::AST_ADD ? AST::AST_SUB : AST::AST_ADD);
        sub->children.push_back(right_range_node);
        sub->children.push_back(AST::AstNode::mkconst_int(1, false, 1));
        range_node->children.push_back(sub);
        // range_node->children.push_back(right_range_node);
    });
    if (indexed_part_select_type == AST::AST_ADD) {
        std::reverse(range_node->children.begin(), range_node->children.end());
    }
    current_node->children.push_back(range_node);
}

void UhdmAst::process_if_else()
{
    current_node = make_ast_node(AST::AST_CASE);
    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) {
        if (!node) {
            log_error("Couldn't find node in if stmt. This can happend if unsupported '$value$plusargs' function is used inside if.\n");
        }
        auto reduce_node = new AST::AstNode(AST::AST_REDUCE_BOOL, node);
        current_node->children.push_back(reduce_node);
    });
    // If true:
    auto *condition = new AST::AstNode(AST::AST_COND);
    auto *constant = AST::AstNode::mkconst_int(1, false, 1);
    condition->children.push_back(constant);
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        auto *statements = new AST::AstNode(AST::AST_BLOCK);
        if (node)
            statements->children.push_back(node);
        condition->children.push_back(statements);
    });
    current_node->children.push_back(condition);
    // Else:
    if (vpi_get(vpiType, obj_h) == vpiIfElse) {
        auto *condition = new AST::AstNode(AST::AST_COND);
        auto *elseBlock = new AST::AstNode(AST::AST_DEFAULT);
        condition->children.push_back(elseBlock);
        visit_one_to_one({vpiElseStmt}, obj_h, [&](AST::AstNode *node) {
            auto *statements = new AST::AstNode(AST::AST_BLOCK);
            if (node)
                statements->children.push_back(node);
            condition->children.push_back(statements);
        });
        current_node->children.push_back(condition);
    }
}

void UhdmAst::process_for()
{
    current_node = make_ast_node(AST::AST_BLOCK);
    auto loop_id = shared.next_loop_id();
    current_node->str = "$fordecl_block" + std::to_string(loop_id);
    auto loop = make_ast_node(AST::AST_FOR);
    loop->str = "$loop" + std::to_string(loop_id);
    visit_one_to_many({vpiForInitStmt}, obj_h, [&](AST::AstNode *node) {
        if (node->type == AST::AST_ASSIGN_LE)
            node->type = AST::AST_ASSIGN_EQ;
        auto lhs = node->children[0];
        if (lhs->type == AST::AST_WIRE) {
            auto *wire = lhs->clone();
            wire->is_logic = true;
            current_node->children.push_back(wire);
            lhs->type = AST::AST_IDENTIFIER;
            lhs->is_signed = false;
            lhs->delete_children();
        }
        loop->children.push_back(node);
    });
    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { loop->children.push_back(node); });
    visit_one_to_many({vpiForIncStmt}, obj_h, [&](AST::AstNode *node) {
        if (node->type == AST::AST_ASSIGN_LE)
            node->type = AST::AST_ASSIGN_EQ;
        loop->children.push_back(node);
    });
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node->type != AST::AST_BLOCK) {
            auto *statements = make_ast_node(AST::AST_BLOCK);
            statements->str = current_node->str; // Needed in simplify step
            statements->children.push_back(node);
            loop->children.push_back(statements);
        } else {
            if (node->str == "") {
                node->str = loop->str;
            }
            loop->children.push_back(node);
        }
    });
    current_node->children.push_back(loop);
    transform_breaks_continues(loop, current_node);
}

void UhdmAst::process_gen_scope()
{
    current_node = make_ast_node(AST::AST_GENBLOCK);
    visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            move_type_to_new_typedef(current_node, node);
        }
    });

    visit_one_to_many(
      {vpiParamAssign, vpiParameter, vpiNet, vpiArrayNet, vpiVariables, vpiContAssign, vpiProcess, vpiModule, vpiGenScopeArray, vpiTaskFunc}, obj_h,
      [&](AST::AstNode *node) {
          if (node) {
              if ((node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) && node->children.empty()) {
                  delete node; // skip parameters without any children
              } else {
                  current_node->children.push_back(node);
              }
          }
      });
}

void UhdmAst::process_case()
{
    current_node = make_ast_node(AST::AST_CASE);
    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
    visit_one_to_many({vpiCaseItem}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
}

void UhdmAst::process_case_item()
{
    auto cond_type = AST::AST_COND;
    if (vpiHandle parent_h = vpi_handle(vpiParent, obj_h)) {
        switch (vpi_get(vpiCaseType, parent_h)) {
        case vpiCaseExact:
            cond_type = AST::AST_COND;
            break;
        case vpiCaseX:
            cond_type = AST::AST_CONDX;
            break;
        case vpiCaseZ:
            cond_type = AST::AST_CONDZ;
            break;
        default: {
            const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
            report_error("%.*s:%d: Unknown case type", (int)object->VpiFile().length(), object->VpiFile().data(), object->VpiLineNo());
        }
        }
        vpi_release_handle(parent_h);
    }
    current_node = make_ast_node(cond_type);
    vpiHandle itr = vpi_iterate(vpiExpr, obj_h);
    while (vpiHandle expr_h = vpi_scan(itr)) {
        // case ... inside statement, the operation is stored in UHDM inside case items
        // Retrieve just the InsideOp arguments here, we don't add any special handling
        if (vpi_get(vpiType, expr_h) == vpiOperation && vpi_get(vpiOpType, expr_h) == vpiInsideOp) {
            visit_one_to_many({vpiOperand}, expr_h, [&](AST::AstNode *node) {
                // Currently we are adding nodes directly to ancestor
                // inside process_list_op, so after this function, we have
                // nodes already in `current_node`.
                // We should probably refactor this to return node instead.
                // For now, make sure this function doesn't return any nodes.
                log_assert(node == nullptr);
            });
            // vpiListOp is returned in 2 cases:
            // a, b, c ... -> multiple vpiListOp with single item
            // [a : b] -> single vpiListOp with 2 items
            // single item is handled by default,
            // here handle 2 items with custom low_high_bound attribute
            if (current_node->children.size() == 2) {
                auto block = make_ast_node(AST::AST_BLOCK);
                block->children = std::move(current_node->children);
                current_node->children.clear();
                current_node->children.push_back(block);
                current_node->attributes[UhdmAst::low_high_bound()] = AST::AstNode::mkconst_int(1, false, 1);
            }
        } else {
            UhdmAst uhdm_ast(this, shared, indent + "  ");
            auto *node = uhdm_ast.process_object(expr_h);
            if (node) {
                current_node->children.push_back(node);
            }
        }
        // FIXME: If we release the handle here, visiting vpiStmt fails for some reason
        // vpi_release_handle(expr_h);
    }
    vpi_release_handle(itr);
    if (current_node->children.empty()) {
        current_node->children.push_back(new AST::AstNode(AST::AST_DEFAULT));
    }
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (node->type != AST::AST_BLOCK) {
                auto block_node = new AST::AstNode(AST::AST_BLOCK);
                block_node->children.push_back(node);
                node = block_node;
            }
            current_node->children.push_back(node);
        }
    });
}

void UhdmAst::process_range(const UHDM::BaseClass *object)
{
    current_node = make_ast_node(AST::AST_RANGE);
    visit_one_to_one({vpiLeftRange, vpiRightRange}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
    if (current_node->children.size() > 0) {
        if (current_node->children[0]->str == "unsized") {
            log_error("%.*s:%d: Currently not supported object of type 'unsized range'\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                      object->VpiLineNo());
        }
    }
    if (current_node->children.size() > 1) {
        if (current_node->children[1]->str == "unsized") {
            log_error("%.*s:%d: Currently not supported object of type 'unsized range'\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                      object->VpiLineNo());
        }
    }
}

void UhdmAst::process_return()
{
    current_node = make_ast_node(AST::AST_ASSIGN_EQ);
    auto func_node = find_ancestor({AST::AST_FUNCTION, AST::AST_TASK});
    if (!func_node->children.empty()) {
        auto lhs = new AST::AstNode(AST::AST_IDENTIFIER);
        lhs->str = func_node->children[0]->str;
        current_node->children.push_back(lhs);
    }
    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
}

void UhdmAst::process_function()
{
    current_node = make_ast_node(vpi_get(vpiType, obj_h) == vpiFunction ? AST::AST_FUNCTION : AST::AST_TASK);
    visit_one_to_one({vpiReturn}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            auto net_type = vpi_get(vpiNetType, obj_h);
            node->is_reg = net_type == vpiReg;
            node->str = current_node->str;
            current_node->children.push_back(node);
        }
    });
    visit_one_to_many({vpiParameter, vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            add_or_replace_child(current_node, node);
        }
    });
    visit_one_to_many({vpiIODecl}, obj_h, [&](AST::AstNode *node) {
        node->type = AST::AST_WIRE;
        node->port_id = shared.next_port_id();
        current_node->children.push_back(node);
    });
    visit_one_to_many({vpiVariables}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });
}

void UhdmAst::process_hier_path()
{
    current_node = make_ast_node(AST::AST_IDENTIFIER);
    current_node->str = "\\";
    AST::AstNode *top_node = nullptr;
    visit_one_to_many({vpiActual}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (node->str.find('[') != std::string::npos)
                node->str = node->str.substr(0, node->str.find('['));
            // for first node, just set correct string and move any children
            if (!top_node) {
                current_node->str += node->str.substr(1);
                current_node->children = std::move(node->children);
                node->children.clear();
                top_node = current_node;
                delete node;
            } else {
                if (node->str.empty()) {
                    log_assert(!node->children.empty());
                    top_node->children.push_back(node->children[0]);
                    node->children.erase(node->children.begin());
                    delete node;
                } else {
                    node->type = static_cast<AST::AstNodeType>(AST::Extended::AST_DOT);
                    top_node->children.push_back(node);
                    top_node = node;
                }
            }
        }
    });
}

void UhdmAst::process_gen_scope_array()
{
    current_node = make_ast_node(AST::AST_GENBLOCK);
    visit_one_to_many({vpiGenScope}, obj_h, [&](AST::AstNode *genscope_node) {
        for (auto *child : genscope_node->children) {
            if (child->type == AST::AST_PARAMETER || child->type == AST::AST_LOCALPARAM) {
                auto param_str = child->str.substr(1);
                auto array_str = "[" + param_str + "]";
                visitEachDescendant(genscope_node, [&](AST::AstNode *node) {
                    auto pos = node->str.find(array_str);
                    if (pos != std::string::npos) {
                        node->type = AST::AST_PREFIX;
                        auto *param = new AST::AstNode(AST::AST_IDENTIFIER);
                        param->str = child->str;
                        node->children.push_back(param);
                        auto bracket = node->str.rfind(']');
                        if (bracket + 2 <= node->str.size()) {
                            auto *field = new AST::AstNode(AST::AST_IDENTIFIER);
                            field->str = "\\" + node->str.substr(bracket + 2);
                            node->children.push_back(field);
                        }
                        node->str = node->str.substr(0, node->str.find('['));
                    }
                });
            }
        }
        current_node->children.insert(current_node->children.end(), genscope_node->children.begin(), genscope_node->children.end());
        genscope_node->children.clear();
        delete genscope_node;
    });
}

void UhdmAst::process_tagged_pattern()
{
    auto assign_node = find_ancestor({AST::AST_ASSIGN, AST::AST_ASSIGN_EQ, AST::AST_ASSIGN_LE});
    auto assign_type = AST::AST_ASSIGN;
    AST::AstNode *lhs_node = nullptr;
    if (assign_node) {
        assign_type = assign_node->type;
        lhs_node = assign_node->children[0]->clone();
    } else {
        lhs_node = new AST::AstNode(AST::AST_IDENTIFIER);
        auto ancestor = find_ancestor({AST::AST_WIRE, AST::AST_MEMORY, AST::AST_PARAMETER, AST::AST_LOCALPARAM});
        if (!ancestor) {
            log_error("Couldn't find ancestor for tagged pattern!\n");
        }
        lhs_node->str = ancestor->str;
    }
    current_node = new AST::AstNode(assign_type);
    current_node->children.push_back(lhs_node);
    auto typespec_h = vpi_handle(vpiTypespec, obj_h);
    if (vpi_get(vpiType, typespec_h) == vpiStringTypespec) {
        std::string field_name = vpi_get_str(vpiName, typespec_h);
        if (field_name != "default") { // TODO: better support of the default keyword
            auto field = new AST::AstNode(static_cast<AST::AstNodeType>(AST::Extended::AST_DOT));
            field->str = field_name;
            current_node->children[0]->children.push_back(field);
        }
    } else if (vpi_get(vpiType, typespec_h) == vpiIntegerTypespec) {
        s_vpi_value val;
        vpi_get_value(typespec_h, &val);
        auto range = new AST::AstNode(AST::AST_RANGE);
        auto index = AST::AstNode::mkconst_int(val.value.integer, false);
        range->children.push_back(index);
        current_node->children[0]->children.push_back(range);
    }
    vpi_release_handle(typespec_h);
    visit_one_to_one({vpiPattern}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
}

void UhdmAst::process_logic_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    current_node->is_logic = true;
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    // TODO: add const attribute, but it seems it is little more
    // then just setting boolean value
    // current_node->is_const = vpi_get(vpiConstantVariable, obj_h);
    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
        if (node->str.empty()) {
            // anonymous typespec, move the children to variable
            current_node->type = node->type;
            current_node->children = std::move(node->children);
        } else {
            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
            wiretype_node->str = node->str;
            current_node->children.push_back(wiretype_node);
            current_node->is_custom_type = true;
        }
        current_node->is_signed = node->is_signed;
        delete node;
    });
    // TODO: Handling below seems similar to other typespec accesses for range. Candidate for extraction to a function.
    if (auto typespec_h = vpi_handle(vpiTypespec, obj_h)) {
        visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
        vpi_release_handle(typespec_h);
    } else {
        visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
    }
    visit_default_expr(obj_h);
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

void UhdmAst::process_sys_func_call()
{
    current_node = make_ast_node(AST::AST_FCALL);

    std::string task_calls[] = {"\\$display", "\\$monitor", "\\$write", "\\$time", "\\$readmemh", "\\$readmemb", "\\$finish", "\\$stop"};

    if (current_node->str == "\\$signed") {
        current_node->type = AST::AST_TO_SIGNED;
    } else if (current_node->str == "\\$unsigned") {
        current_node->type = AST::AST_TO_UNSIGNED;
    } else if (std::find(std::begin(task_calls), std::end(task_calls), current_node->str) != std::end(task_calls)) {
        current_node->type = AST::AST_TCALL;
    }

    visit_one_to_many({vpiArgument}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });

    if (current_node->str == "\\$display" || current_node->str == "\\$write") {
        // According to standard, %h and %x mean the same, but %h is currently unsupported by mainline yosys
        std::string replaced_string = std::regex_replace(current_node->children[0]->str, std::regex("%[h|H]"), "%x");
        delete current_node->children[0];
        current_node->children[0] = AST::AstNode::mkconst_str(replaced_string);
    }

    std::string remove_backslash[] = {"\\$display", "\\$strobe",   "\\$write",    "\\$monitor", "\\$time",    "\\$finish",
                                      "\\$stop",    "\\$dumpfile", "\\$dumpvars", "\\$dumpon",  "\\$dumpoff", "\\$dumpall"};

    if (std::find(std::begin(remove_backslash), std::end(remove_backslash), current_node->str) != std::end(remove_backslash))
        current_node->str = current_node->str.substr(1);
}

void UhdmAst::process_tf_call(AST::AstNodeType type)
{
    current_node = make_ast_node(type);
    visit_one_to_many({vpiArgument}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
                node->type = AST::AST_IDENTIFIER;
                node->children.clear();
            }
            current_node->children.push_back(node);
        }
    });
    // Prefer fully qualified name of a function (prefixed with a scope).
    // This is important when a single function which has been imported from a package
    // calls another function that is not imported in the calling scope.
    if (vpiHandle function_h = vpi_handle(vpiFunction, obj_h)) {
        current_node->str = get_name(function_h, true);
        vpi_release_handle(function_h);
    }
}

void UhdmAst::process_immediate_assert()
{
    current_node = make_ast_node(AST::AST_ASSERT);
    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *n) {
        if (n) {
            current_node->children.push_back(n);
        }
    });
}

void UhdmAst::process_logic_typespec()
{
    current_node = make_ast_node(AST::AST_WIRE);
    current_node->is_logic = true;
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    if (!current_node->str.empty() && current_node->str.find("::") == std::string::npos) {
        std::string package_name = "";
        if (vpiHandle instance_h = vpi_handle(vpiInstance, obj_h)) {
            if (vpi_get(vpiType, instance_h) == vpiPackage) {
                package_name = get_object_name(instance_h, {vpiDefName});
                current_node->str = package_name + "::" + current_node->str.substr(1);
            }
            vpi_release_handle(instance_h);
        }
    }
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_int_typespec()
{
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    current_node = make_ast_node(AST::AST_WIRE);
    packed_ranges.push_back(make_range(31, 0));
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_shortint_typespec()
{
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    current_node = make_ast_node(AST::AST_WIRE);
    packed_ranges.push_back(make_range(15, 0));
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_longint_typespec()
{
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    current_node = make_ast_node(AST::AST_WIRE);
    packed_ranges.push_back(make_range(63, 0));
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_byte_typespec()
{
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    current_node = make_ast_node(AST::AST_WIRE);
    packed_ranges.push_back(make_range(7, 0));
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_time_typespec()
{
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    current_node = make_ast_node(AST::AST_WIRE);
    packed_ranges.push_back(make_range(63, 0));
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
    current_node->is_signed = false;
}

void UhdmAst::process_string_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    current_node->is_string = true;
    // FIXME:
    // this is only basic support for strings,
    // currently yosys doesn't support dynamic resize of wire
    // based on string size
    // here we try to get size of string based on provided const string
    // if it is not available, we are setting size to explicite 64 bits
    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *expr_node) {
        if (expr_node->type == AST::AST_CONSTANT) {
            auto left_const = AST::AstNode::mkconst_int(expr_node->range_left, true);
            auto right_const = AST::AstNode::mkconst_int(expr_node->range_right, true);
            auto range = make_ast_node(AST::AST_RANGE, {left_const, right_const});
            current_node->children.push_back(range);
        }
    });
    if (current_node->children.empty()) {
        auto left_const = AST::AstNode::mkconst_int(64, true);
        auto right_const = AST::AstNode::mkconst_int(0, true);
        auto range = make_ast_node(AST::AST_RANGE, {left_const, right_const});
        current_node->children.push_back(range);
    }
    visit_default_expr(obj_h);
}

void UhdmAst::process_string_typespec()
{
    current_node = make_ast_node(AST::AST_WIRE);
    current_node->is_string = true;
    // FIXME:
    // this is only basic support for strings,
    // currently yosys doesn't support dynamic resize of wire
    // based on string size
    // here, we are setting size to explicite 64 bits
    auto left_const = AST::AstNode::mkconst_int(64, true);
    auto right_const = AST::AstNode::mkconst_int(0, true);
    auto range = make_ast_node(AST::AST_RANGE, {left_const, right_const});
    current_node->children.push_back(range);
}

void UhdmAst::process_bit_typespec()
{
    current_node = make_ast_node(AST::AST_WIRE);
    visit_range(obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_repeat()
{
    auto loop_id = shared.next_loop_id();
    current_node = make_ast_node(AST::AST_BLOCK);
    current_node->str = "$repeatdecl_block" + std::to_string(loop_id);
    auto *loop = make_ast_node(AST::AST_REPEAT);
    loop->str = "$loop" + std::to_string(loop_id);
    current_node->children.push_back(loop);
    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { loop->children.push_back(node); });
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node->type != AST::AST_BLOCK) {
            node = new AST::AstNode(AST::AST_BLOCK, node);
        }
        if (node->str.empty()) {
            node->str = loop->str; // Needed in simplify step
        }
        loop->children.push_back(node);
    });
    transform_breaks_continues(loop, current_node);
}

void UhdmAst::process_var_select()
{
    current_node = make_ast_node(AST::AST_IDENTIFIER);
    visit_one_to_many({vpiIndex}, obj_h, [&](AST::AstNode *node) {
        if (node->str == current_node->str) {
            for (auto child : node->children) {
                current_node->children.push_back(child);
            }
            node->children.clear();
            delete node;
        } else {
            auto range_node = new AST::AstNode(AST::AST_RANGE);
            range_node->filename = current_node->filename;
            range_node->location = current_node->location;
            range_node->children.push_back(node);
            current_node->children.push_back(range_node);
        }
    });
}

void UhdmAst::process_port()
{
    current_node = make_ast_node(AST::AST_WIRE);
    current_node->port_id = shared.next_port_id();
    vpiHandle lowConn_h = vpi_handle(vpiLowConn, obj_h);
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    if (lowConn_h) {
        vpiHandle actual_h = vpi_handle(vpiActual, lowConn_h);
        auto actual_type = vpi_get(vpiType, actual_h);
        switch (actual_type) {
        case vpiModport: {
            vpiHandle iface_h = vpi_handle(vpiInterface, actual_h);
            if (iface_h) {
                std::string cellName, ifaceName;
                if (auto s = vpi_get_str(vpiName, actual_h)) {
                    cellName = s;
                    sanitize_symbol_name(cellName);
                }
                if (auto s = vpi_get_str(vpiDefName, iface_h)) {
                    ifaceName = s;
                    sanitize_symbol_name(ifaceName);
                }
                current_node->type = AST::AST_INTERFACEPORT;
                auto typeNode = new AST::AstNode(AST::AST_INTERFACEPORTTYPE);
                // Skip '\' in cellName
                typeNode->str = ifaceName + '.' + cellName.substr(1, cellName.length());
                current_node->children.push_back(typeNode);
                shared.report.mark_handled(actual_h);
                shared.report.mark_handled(iface_h);
                vpi_release_handle(iface_h);
            }
            break;
        }
        case vpiInterface: {
            auto typeNode = new AST::AstNode(AST::AST_INTERFACEPORTTYPE);
            if (auto s = vpi_get_str(vpiDefName, actual_h)) {
                typeNode->str = s;
                sanitize_symbol_name(typeNode->str);
            }
            current_node->type = AST::AST_INTERFACEPORT;
            current_node->children.push_back(typeNode);
            shared.report.mark_handled(actual_h);
            break;
        }
        case vpiLogicVar:
        case vpiLogicNet: {
            current_node->is_logic = true;
            current_node->is_signed = vpi_get(vpiSigned, actual_h);
            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
            shared.report.mark_handled(actual_h);
            break;
        }
        case vpiPackedArrayVar:
            visit_one_to_many({vpiElement}, actual_h, [&](AST::AstNode *node) {
                if (node && GetSize(node->children) == 1) {
                    current_node->children.push_back(node->children[0]->clone());
                    if (node->children[0]->type == AST::AST_WIRETYPE) {
                        current_node->is_custom_type = true;
                    }
                }
                delete node;
            });
            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
            shared.report.mark_handled(actual_h);
            break;
        case vpiPackedArrayNet:
            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
            shared.report.mark_handled(actual_h);
            break;
        case vpiArrayVar:
            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
            shared.report.mark_handled(actual_h);
            break;
        case vpiEnumNet:
        case vpiStructNet:
        case vpiArrayNet:
        case vpiStructVar:
        case vpiUnionVar:
        case vpiEnumVar:
        case vpiBitVar:
        case vpiByteVar:
        case vpiShortIntVar:
        case vpiLongIntVar:
        case vpiIntVar:
        case vpiIntegerVar:
            break;
        default: {
            const uhdm_handle *const handle = (const uhdm_handle *)actual_h;
            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
            report_error("%.*s:%d: Encountered unhandled type in process_port: %s\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                         object->VpiLineNo(), UHDM::VpiTypeName(actual_h).c_str());
            break;
        }
        }
        shared.report.mark_handled(lowConn_h);
        vpi_release_handle(actual_h);
        vpi_release_handle(lowConn_h);
    }
    visit_one_to_one({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            if (!current_node->children.empty() && current_node->children[0]->type != AST::AST_WIRETYPE) {
                if (!node->str.empty()) {
                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    // wiretype needs to be 1st node (if port have also another range nodes)
                    current_node->children.insert(current_node->children.begin(), wiretype_node);
                    current_node->is_custom_type = true;
                } else {
                    // anonymous typedef, just move children
                    current_node->children = std::move(node->children);
                }
            }
            current_node->is_signed = current_node->is_signed || node->is_signed;
            delete node;
        }
    });
    if (const int n = vpi_get(vpiDirection, obj_h)) {
        if (n == vpiInput) {
            current_node->is_input = true;
        } else if (n == vpiOutput) {
            current_node->is_output = true;
        } else if (n == vpiInout) {
            current_node->is_input = true;
            current_node->is_output = true;
        }
    }
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

void UhdmAst::process_net()
{
    current_node = make_ast_node(AST::AST_WIRE);
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    auto net_type = vpi_get(vpiNetType, obj_h);
    current_node->is_reg = net_type == vpiReg;
    current_node->is_output = net_type == vpiOutput;
    current_node->is_logic = !current_node->is_reg;
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
        if (node && !node->str.empty()) {
            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
            wiretype_node->str = node->str;
            // wiretype needs to be 1st node
            current_node->children.insert(current_node->children.begin(), wiretype_node);
            current_node->is_custom_type = true;
        }
        delete node;
    });
    if (vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h)) {
        visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
        vpi_release_handle(typespec_h);
    }
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

void UhdmAst::process_parameter()
{
    auto type = vpi_get(vpiLocalParam, obj_h) == 1 ? AST::AST_LOCALPARAM : AST::AST_PARAMETER;
    current_node = make_ast_node(type, {}, true);
    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
    vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h);
    if (typespec_h) {
        int typespec_type = vpi_get(vpiType, typespec_h);
        switch (typespec_type) {
        case vpiBitTypespec:
        case vpiLogicTypespec: {
            current_node->is_logic = true;
            visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
            shared.report.mark_handled(typespec_h);
            break;
        }
        case vpiByteTypespec: {
            packed_ranges.push_back(make_range(7, 0));
            shared.report.mark_handled(typespec_h);
            break;
        }
        case vpiEnumTypespec:
        case vpiRealTypespec:
        case vpiStringTypespec: {
            shared.report.mark_handled(typespec_h);
            break;
        }
        case vpiIntTypespec:
        case vpiIntegerTypespec: {
            visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
            if (packed_ranges.empty()) {
                packed_ranges.push_back(make_range(31, 0));
            }
            shared.report.mark_handled(typespec_h);
            break;
        }
        case vpiShortIntTypespec: {
            packed_ranges.push_back(make_range(15, 0));
            shared.report.mark_handled(typespec_h);
            break;
        }
        case vpiTimeTypespec:
        case vpiLongIntTypespec: {
            packed_ranges.push_back(make_range(63, 0));
            shared.report.mark_handled(typespec_h);
            break;
        }
        case vpiStructTypespec: {
            visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
                if (node && !node->str.empty()) {
                    auto wiretype_node = make_ast_node(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    current_node->children.push_back(wiretype_node);
                }
                current_node->is_custom_type = true;
                auto it = shared.param_types.find(current_node->str);
                if (it == shared.param_types.end()) {
                    shared.param_types.insert(std::make_pair(current_node->str, node));
                } else {
                    delete node;
                }
            });
            break;
        }
        case vpiPackedArrayTypespec:
        case vpiArrayTypespec: {
            shared.report.mark_handled(typespec_h);
            visit_one_to_one({vpiElemTypespec}, typespec_h, [&](AST::AstNode *node) {
                if (!node->str.empty()) {
                    auto wiretype_node = make_ast_node(AST::AST_WIRETYPE);
                    wiretype_node->str = node->str;
                    current_node->children.push_back(wiretype_node);
                    current_node->is_custom_type = true;
                    auto it = shared.param_types.find(current_node->str);
                    if (it == shared.param_types.end())
                        shared.param_types.insert(std::make_pair(current_node->str, node->clone()));
                }
                if (node && node->attributes.count(UhdmAst::packed_ranges())) {
                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
                        packed_ranges.push_back(r->clone());
                    }
                }
                delete node;
            });
            break;
        }
        default: {
            const uhdm_handle *const handle = (const uhdm_handle *)typespec_h;
            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
            report_error("%.*s:%d: Encountered unhandled typespec in process_parameter: '%.*s' of type '%s'\n", (int)object->VpiFile().length(),
                         object->VpiFile().data(), object->VpiLineNo(), (int)object->VpiName().length(), object->VpiName().data(),
                         UHDM::VpiTypeName(typespec_h).c_str());
            break;
        }
        }
        vpi_release_handle(typespec_h);
    }
    AST::AstNode *constant_node = process_value(obj_h);
    if (constant_node) {
        constant_node->filename = current_node->filename;
        constant_node->location = current_node->location;
        current_node->children.push_back(constant_node);
    }
    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
}

void UhdmAst::process_byte_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    current_node->children.push_back(make_range(7, 0));
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_long_int_var()
{
    current_node = make_ast_node(AST::AST_WIRE);
    current_node->children.push_back(make_range(63, 0));
    current_node->is_signed = vpi_get(vpiSigned, obj_h);
}

void UhdmAst::process_immediate_cover()
{
    current_node = make_ast_node(AST::AST_COVER);
    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });
}

void UhdmAst::process_immediate_assume()
{
    current_node = make_ast_node(AST::AST_ASSUME);
    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) {
        if (node) {
            current_node->children.push_back(node);
        }
    });
}

void UhdmAst::process_while()
{
    auto loop_id = shared.next_loop_id();
    current_node = make_ast_node(AST::AST_BLOCK);
    current_node->str = "$whiledecl_block" + std::to_string(loop_id);
    auto *loop = make_ast_node(AST::AST_WHILE);
    loop->str = "$loop" + std::to_string(loop_id);
    current_node->children.push_back(loop);
    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { loop->children.push_back(node); });
    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
        if (node->type != AST::AST_BLOCK) {
            node = make_ast_node(AST::AST_BLOCK, {node});
        }
        if (node->str.empty()) {
            node->str = loop->str; // Needed in simplify step
        }
        loop->children.push_back(node);
    });
    transform_breaks_continues(loop, current_node);
}

void UhdmAst::process_gate()
{
    current_node = make_ast_node(AST::AST_PRIMITIVE);
    switch (vpi_get(vpiPrimType, obj_h)) {
    case vpiAndPrim:
        current_node->str = "and";
        break;
    case vpiNandPrim:
        current_node->str = "nand";
        break;
    case vpiNorPrim:
        current_node->str = "nor";
        break;
    case vpiOrPrim:
        current_node->str = "or";
        break;
    case vpiXorPrim:
        current_node->str = "xor";
        break;
    case vpiXnorPrim:
        current_node->str = "xnor";
        break;
    case vpiBufPrim:
        current_node->str = "buf";
        break;
    case vpiNotPrim:
        current_node->str = "not";
        break;
    default:
        log_file_error(current_node->filename, current_node->location.first_line, "Encountered unhandled gate type: %s", current_node->str.c_str());
        break;
    }
    visit_one_to_many({vpiPrimTerm}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
}

void UhdmAst::process_primterm()
{
    current_node = make_ast_node(AST::AST_ARGUMENT);
    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
}

void UhdmAst::process_unsupported_stmt(const UHDM::BaseClass *object, bool is_error)
{
    const auto log_func = is_error ? log_error : log_warning;
    std::string prefix = object->VpiLineNo() ? (std::string(object->VpiFile()) + ":" + std::to_string(object->VpiLineNo()) + ": ") : "";
    log_func("%sCurrently not supported object of type '%s'\n", prefix.c_str(), UHDM::VpiTypeName(obj_h).c_str());
}

AST::AstNode *UhdmAst::process_object(vpiHandle obj_handle)
{
    obj_h = obj_handle;
    const unsigned object_type = vpi_get(vpiType, obj_h);
    const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
    const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
    for (auto *obj : shared.nonSynthesizableObjects) {
        if (!object->Compare(obj)) {
            log_warning("%.*s:%d: Skipping non-synthesizable object of type '%s'\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                        object->VpiLineNo(), UHDM::VpiTypeName(obj_h).c_str());
            return nullptr;
        }
    }

    if (shared.debug_flag) {
        std::cout << indent << "Object '" << object->VpiName() << "' of type '" << UHDM::VpiTypeName(obj_h) << '\'' << std::endl;
    }

    switch (object_type) {
    case vpiDesign:
        process_design();
        break;
    case vpiParameter:
        process_parameter();
        break;
    case vpiPort:
        process_port();
        break;
    case vpiModule:
        process_module();
        break;
    case vpiStructTypespec:
        process_struct_typespec();
        break;
    case vpiUnionTypespec:
        process_union_typespec();
        break;
    case vpiPackedArrayTypespec:
        process_packed_array_typespec();
        break;
    case vpiArrayTypespec:
        process_array_typespec();
        break;
    case vpiTypespecMember:
        process_typespec_member();
        break;
    case vpiEnumTypespec:
        process_enum_typespec();
        break;
    case vpiEnumConst:
        process_enum_const();
        break;
    case vpiEnumVar:
    case vpiEnumNet:
    case vpiStructVar:
    case vpiStructNet:
    case vpiUnionVar:
        process_custom_var();
        break;
    case vpiShortIntVar:
    case vpiIntVar:
    case vpiIntegerVar:
        process_int_var();
        break;
    case vpiShortRealVar:
    case vpiRealVar:
        process_real_var();
        break;
    case vpiPackedArrayVar:
        process_packed_array_var();
        break;
    case vpiArrayVar:
        process_array_var();
        break;
    case vpiParamAssign:
        process_param_assign();
        break;
    case vpiContAssign:
        process_cont_assign();
        break;
    case vpiAssignStmt:
    case vpiAssignment:
        process_assignment(object);
        break;
    case vpiInterfaceTypespec:
    case vpiRefVar:
    case vpiRefObj:
        current_node = make_ast_node(AST::AST_IDENTIFIER);
        break;
    case vpiNet:
        process_net();
        break;
    case vpiArrayNet:
        process_array_net(object);
        break;
    case vpiPackedArrayNet:
        process_packed_array_net();
        break;
    case vpiPackage:
        process_package();
        break;
    case vpiInterface:
        process_interface();
        break;
    case vpiModport:
        process_modport();
        break;
    case vpiIODecl:
        process_io_decl();
        break;
    case vpiAlways:
        process_always();
        break;
    case vpiEventControl:
        process_event_control(object);
        break;
    case vpiInitial:
        process_initial();
        break;
    case vpiFinal:
        process_unsupported_stmt(object, false);
        break;
    case vpiNamedBegin:
        process_begin(true);
        break;
    case vpiBegin:
        process_begin(false);
        break;
    case vpiCondition:
    case vpiOperation:
        process_operation(object);
        break;
    case vpiTaggedPattern:
        process_tagged_pattern();
        break;
    case vpiBitSelect:
        process_bit_select();
        break;
    case vpiPartSelect:
        process_part_select();
        break;
    case vpiIndexedPartSelect:
        process_indexed_part_select();
        break;
    case vpiVarSelect:
        process_var_select();
        break;
    case vpiIf:
    case vpiIfElse:
        process_if_else();
        break;
    case vpiFor:
        process_for();
        break;
    case vpiBreak:
        // Will be resolved later by loop processor
        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::Extended::AST_BREAK));
        break;
    case vpiContinue:
        // Will be resolved later by loop processor
        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::Extended::AST_CONTINUE));
        break;
    case vpiGenScopeArray:
        process_gen_scope_array();
        break;
    case vpiGenScope:
        process_gen_scope();
        break;
    case vpiCase:
        process_case();
        break;
    case vpiCaseItem:
        process_case_item();
        break;
    case vpiConstant:
        current_node = process_value(obj_h);
        break;
    case vpiRange:
        process_range(object);
        break;
    case vpiReturn:
        process_return();
        break;
    case vpiFunction:
    case vpiTask:
        process_function();
        break;
    case vpiBitVar:
    case vpiLogicVar:
        process_logic_var();
        break;
    case vpiSysFuncCall:
        process_sys_func_call();
        break;
    case vpiFuncCall:
        process_tf_call(AST::AST_FCALL);
        break;
    case vpiTaskCall:
        process_tf_call(AST::AST_TCALL);
        break;
    case vpiImmediateAssert:
        if (!shared.no_assert)
            process_immediate_assert();
        break;
    case vpiAssert:
        if (!shared.no_assert)
            process_unsupported_stmt(object);
        break;
    case vpiHierPath:
        process_hier_path();
        break;
    case UHDM::uhdmimport_typespec:
        break;
    case vpiLogicTypespec:
        process_logic_typespec();
        break;
    case vpiIntTypespec:
    case vpiIntegerTypespec:
        process_int_typespec();
        break;
    case vpiShortIntTypespec:
        process_shortint_typespec();
        break;
    case vpiLongIntTypespec:
        process_longint_typespec();
        break;
    case vpiTimeTypespec:
        process_time_typespec();
        break;
    case vpiBitTypespec:
        process_bit_typespec();
        break;
    case vpiByteTypespec:
        process_byte_typespec();
        break;
    case vpiStringVar:
        process_string_var();
        break;
    case vpiStringTypespec:
        process_string_typespec();
        break;
    case vpiRepeat:
        process_repeat();
        break;
    case vpiByteVar:
        process_byte_var();
        break;
    case vpiLongIntVar:
        process_long_int_var();
        break;
    case vpiImmediateCover:
        process_immediate_cover();
        break;
    case vpiImmediateAssume:
        process_immediate_assume();
        break;
    case vpiAssume:
        process_unsupported_stmt(object);
        break;
    case vpiWhile:
        process_while();
        break;
    case vpiGate:
        process_gate();
        break;
    case vpiPrimTerm:
        process_primterm();
        break;
    case vpiClockingBlock:
        process_unsupported_stmt(object);
        break;
    case vpiTypeParameter:
        // Instances in an `uhdmTopModules` tree already have all parameter references
        // substituted with the parameter type/value by Surelog,
        // so the plugin doesn't need to process the parameter itself.
        // Other parameter types are handled by the plugin
        // mainly because they were implemented before Surelog did the substitution.
        break;
    case vpiProgram:
    default:
        report_error("%.*s:%d: Encountered unhandled object '%.*s' of type '%s'\n", (int)object->VpiFile().length(), object->VpiFile().data(),
                     object->VpiLineNo(), (int)object->VpiName().length(), object->VpiName().data(), UHDM::VpiTypeName(obj_h).c_str());
        break;
    }

    // Check if we initialized the node in switch-case
    if (current_node) {
        if (current_node->type != AST::AST_NONE) {
            shared.report.mark_handled(object);
            return current_node;
        }
    }
    return nullptr;
}

AST::AstNode *UhdmAst::visit_designs(const std::vector<vpiHandle> &designs)
{
    attr_id_init();

    current_node = new AST::AstNode(AST::AST_DESIGN);
    for (auto design : designs) {
        UhdmAst ast(this, shared, indent);
        auto *processed_design_node = ast.process_object(design);
        // Flatten multiple designs into one
        current_node->children = std::move(processed_design_node->children);
        delete processed_design_node;
    }

    for (auto &[name, node] : shared.param_types) {
        delete node;
    }
    shared.param_types.clear();

    // Remove all internal attributes from the AST.
    visitEachDescendant(current_node, delete_internal_attributes);

    attr_id_cleanup();

    return current_node;
}

void UhdmAst::report_error(const char *format, ...) const
{
    va_list args;
    va_start(args, format);
    if (shared.stop_on_error) {
        logv_error(format, args);
    } else {
        logv_warning(format, args);
    }
}

} // namespace systemverilog_plugin
