diff --git a/src/ccc/symbol_database.cpp b/src/ccc/symbol_database.cpp index 2527413..8bbefbf 100644 --- a/src/ccc/symbol_database.cpp +++ b/src/ccc/symbol_database.cpp @@ -826,35 +826,29 @@ bool SymbolDatabase::destroy_function(FunctionHandle handle) // ***************************************************************************** -NodeHandle::NodeHandle() {} - -NodeHandle::NodeHandle(const ast::Node* node) - : m_node(node) {} +MultiSymbolHandle::MultiSymbolHandle() {} template -NodeHandle::NodeHandle(const SymbolType& symbol, const ast::Node* node) +MultiSymbolHandle::MultiSymbolHandle(const SymbolType& symbol) : m_descriptor(SymbolType::DESCRIPTOR) - , m_symbol_handle(symbol.handle().value) - , m_node(node) - , m_generation(symbol.generation()) {} + , m_symbol_handle(symbol.handle().value) {} -bool NodeHandle::valid() const +bool MultiSymbolHandle::valid() const { - return m_node != nullptr; + return m_symbol_handle != (u32) -1; } -const ast::Node* NodeHandle::lookup_node(const SymbolDatabase& database) const +SymbolDescriptor MultiSymbolHandle::descriptor() const { - if(m_symbol_handle != (u32) -1) { - const Symbol* symbol = lookup_symbol(database); - if(!symbol || symbol->generation() != m_generation) { - return nullptr; - } - } - return m_node; + return m_descriptor; +} + +u32 MultiSymbolHandle::handle() const +{ + return m_symbol_handle; } -const Symbol* NodeHandle::lookup_symbol(const SymbolDatabase& database) const +const Symbol* MultiSymbolHandle::lookup_symbol(const SymbolDatabase& database) const { if(m_symbol_handle != (u32) -1) { switch(m_descriptor) { @@ -868,11 +862,46 @@ const Symbol* NodeHandle::lookup_symbol(const SymbolDatabase& database) const return nullptr; } +#define CCC_X(SymbolType, symbol_list) template MultiSymbolHandle::MultiSymbolHandle(const SymbolType& symbol); +CCC_FOR_EACH_SYMBOL_TYPE_DO_X +#undef CCC_X + +// ***************************************************************************** + +NodeHandle::NodeHandle() {} + +NodeHandle::NodeHandle(const ast::Node* node) + : m_node(node) {} + +template +NodeHandle::NodeHandle(const SymbolType& symbol, const ast::Node* node) + : m_symbol(symbol) + , m_node(node) + , m_generation(symbol.generation()) {} + +bool NodeHandle::valid() const +{ + return m_node != nullptr; +} + +const MultiSymbolHandle& NodeHandle::symbol() const +{ + return m_symbol; +} + +const ast::Node* NodeHandle::lookup_node(const SymbolDatabase& database) const +{ + const Symbol* symbol = m_symbol.lookup_symbol(database); + if(!symbol || symbol->generation() != m_generation) { + return nullptr; + } + return m_node; +} + NodeHandle NodeHandle::handle_for_child(const ast::Node* child_node) const { NodeHandle child_handle; - child_handle.m_descriptor = m_descriptor; - child_handle.m_symbol_handle = m_symbol_handle; + child_handle.m_symbol = m_symbol; child_handle.m_node = child_node; child_handle.m_generation = m_generation; return child_handle; diff --git a/src/ccc/symbol_database.h b/src/ccc/symbol_database.h index aef23db..94e8d92 100644 --- a/src/ccc/symbol_database.h +++ b/src/ccc/symbol_database.h @@ -10,7 +10,7 @@ namespace ccc { -// Define an X macro for all the symbol types. +// An X macro for all the symbol types. #define CCC_FOR_EACH_SYMBOL_TYPE_DO_X \ CCC_X(DataType, data_types) \ CCC_X(Function, functions) \ @@ -23,7 +23,7 @@ namespace ccc { CCC_X(SourceFile, source_files) \ CCC_X(SymbolSource, symbol_sources) -// Define an enum for all the symbol types. +// An enum for all the symbol types. enum class SymbolDescriptor { DATA_TYPE, FUNCTION, @@ -37,15 +37,15 @@ enum class SymbolDescriptor { SYMBOL_SOURCE }; -// Forward declare all the different types of symbol table objects. +// Forward declare all the different types of symbol objects. #define CCC_X(SymbolType, symbol_list) class SymbolType; CCC_FOR_EACH_SYMBOL_TYPE_DO_X #undef CCC_X class SymbolDatabase; -// Define strongly typed handles for all of the symbol table objects. These are -// here to solve the problem of dangling references to symbols. +// Strongly typed handles for all of the symbol objects. These are here to solve +// the problem of dangling references to symbols. template struct SymbolHandle { u32 value = (u32) -1; @@ -64,8 +64,8 @@ struct SymbolHandle { CCC_FOR_EACH_SYMBOL_TYPE_DO_X #undef CCC_X -// Define range types for all of the symbol table objects. Note that the last -// member actually points to the last real element in the range. +// Range types for all of the symbol objects. Note that the last member actually +// points to the last real element in the range. template struct SymbolRange { SymbolHandle first; @@ -598,7 +598,30 @@ class SymbolDatabase { } }; -// Define a strongly typed handle to an AST node. +// A handle to a symbol of any type. +class MultiSymbolHandle { +public: + // Create an empty multi symbol handle. + MultiSymbolHandle(); + + // Create a multi symbol handle of the specified type. + template + MultiSymbolHandle(const SymbolType& symbol); + + bool valid() const; + SymbolDescriptor descriptor() const; + u32 handle() const; + + const Symbol* lookup_symbol(const SymbolDatabase& database) const; + + friend auto operator<=>(const MultiSymbolHandle& lhs, const MultiSymbolHandle& rhs) = default; + +protected: + SymbolDescriptor m_descriptor = SymbolDescriptor::DATA_TYPE; + u32 m_symbol_handle = (u32) -1; +}; + +// A handle to an AST node. class NodeHandle { friend SymbolDatabase; public: @@ -615,18 +638,16 @@ class NodeHandle { template NodeHandle(const SymbolType& symbol, const ast::Node* node); - friend auto operator<=>(const NodeHandle& lhs, const NodeHandle& rhs) = default; - bool valid() const; + const MultiSymbolHandle& symbol() const; const ast::Node* lookup_node(const SymbolDatabase& database) const; - const Symbol* lookup_symbol(const SymbolDatabase& database) const; - NodeHandle handle_for_child(const ast::Node* child_node) const; + friend auto operator<=>(const NodeHandle& lhs, const NodeHandle& rhs) = default; + protected: - SymbolDescriptor m_descriptor = SymbolDescriptor::DATA_TYPE; - u32 m_symbol_handle = (u32) -1; + MultiSymbolHandle m_symbol; const ast::Node* m_node = nullptr; u32 m_generation = 0; };