From 48b559508286c8f19de60cf747a631fd527acb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Thu, 2 May 2024 09:28:44 +0200 Subject: [PATCH] Simplified handling of struct aliases (#1858) --- VulkanHppGenerator.cpp | 84 ++++++++++++++---------------------------- VulkanHppGenerator.hpp | 20 +++++----- 2 files changed, 39 insertions(+), 65 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 13532f4..8ef22de 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -1450,11 +1450,6 @@ void VulkanHppGenerator::checkHandleCorrectness() const void VulkanHppGenerator::checkStructCorrectness() const { - for ( auto const & structAlias : m_structAliases ) - { - checkForError( m_structs.contains( structAlias.second.name ), structAlias.second.xmlLine, "unknown struct alias <" + structAlias.second.name + ">" ); - } - std::set sTypeValues; for ( auto const & structure : m_structs ) { @@ -1468,7 +1463,7 @@ void VulkanHppGenerator::checkStructCorrectness() const // check for existence of all structs that are extended by this struct for ( auto const & extend : structure.second.structExtends ) { - checkForError( m_structs.contains( extend ) || m_structAliases.contains( extend ), + checkForError( findByNameOrAlias( m_structs, extend ) != m_structs.end(), structure.second.xmlLine, "struct <" + structure.first + "> extends unknown <" + extend + ">" ); } @@ -2140,6 +2135,20 @@ void VulkanHppGenerator::distributeSecondLevelCommands( std::set co } } +void VulkanHppGenerator::distributeStructAliases() +{ + for ( auto const & alias : m_structsAliases ) + { + auto structIt = m_structs.find( alias.second.name ); + checkForError( + structIt != m_structs.end(), alias.second.xmlLine, "struct alias <" + alias.first + "> references an unknown struct <" + alias.second.name + ">" ); + checkForError( structIt->second.aliases.insert( { alias.first, alias.second.xmlLine } ).second, + alias.second.xmlLine, + "struct alias <" + alias.first + "> already listed as an alias for struct <" + alias.second.name + ">" ); + } + m_structsAliases.clear(); +} + void VulkanHppGenerator::filterLenMembers() { for ( auto & sd : m_structs ) @@ -5251,15 +5260,9 @@ std::string VulkanHppGenerator::generateCppModuleStructUsings() const auto const structureType = stripPrefix( structIt->first, "Vk" ); localUsings += replaceWithMap( usingTemplate, { { "structName", structureType } } ); - // replace the findAlias call with the contents, because it includes an assert that breaks in Debug mode, which shouldn't break. There are multiple - // aliases for a given struct, and that's ok. Maybe we should refactor - for ( auto const & [alias, aliasData] : m_structAliases ) + for ( auto const & alias : structIt->second.aliases ) { - if ( aliasData.name == structIt->first ) - { - auto const aliasName = stripPrefix( alias, "Vk" ); - localUsings += replaceWithMap( usingTemplate, { { "structName", aliasName } } ); - } + localUsings += replaceWithMap( usingTemplate, { { "structName", stripPrefix( alias.first, "Vk" ) } } ); } } } @@ -10303,13 +10306,7 @@ std::string VulkanHppGenerator::generateStruct( std::pairsecond.category == TypeCategory::Struct ) || ( typeIt->second.category == TypeCategory::Union ) ) { - auto structIt = m_structs.find( member.type.type ); - if ( structIt == m_structs.end() ) - { - auto aliasIt = m_structAliases.find( member.type.type ); - assert( aliasIt != m_structAliases.end() ); - structIt = m_structs.find( aliasIt->second.name ); - } + auto structIt = findByNameOrAlias( m_structs, member.type.type ); assert( structIt != m_structs.end() ); if ( ( structure.first != member.type.type ) && !listedStructs.contains( member.type.type ) ) { @@ -11110,12 +11107,9 @@ ${members} str += replaceWithMap( cppTypeTemplate, { { "sTypeValue", sTypeValue }, { "structureType", structureType } } ); } - for ( auto const & alias : m_structAliases ) + for ( auto const & alias : structure.second.aliases ) { - if ( alias.second.name == structure.first ) - { - str += " using " + stripPrefix( alias.first, "Vk" ) + " = " + structureType + ";\n"; - } + str += " using " + stripPrefix( alias.first, "Vk" ) + " = " + structureType + ";\n"; } str += leave; @@ -11162,19 +11156,8 @@ std::string VulkanHppGenerator::generateStructExtendsStructs( std::vectorsecond.structExtends ) { - std::map::const_iterator itExtend = m_structs.find( extendName ); - if ( itExtend == m_structs.end() ) - { - // look if the extendName acutally is an alias of some other structure - auto aliasIt = m_structAliases.find( extendName ); - if ( aliasIt != m_structAliases.end() ) - { - itExtend = m_structs.find( aliasIt->second.name ); - assert( itExtend != m_structs.end() ); - } - } - - const auto [subEnter, subLeave] = generateProtection( getProtectFromType( itExtend->first ) ); + auto extendsIt = findByNameOrAlias( m_structs, extendName ); + const auto [subEnter, subLeave] = generateProtection( getProtectFromType( extendsIt->first ) ); if ( enter != subEnter ) { @@ -11234,12 +11217,9 @@ std::string VulkanHppGenerator::generateStructForwardDeclarations( std::vectorfirst, "Vk" ); str += ( structIt->second.isUnion ? " union " : " struct " ) + structureType + ";\n"; - for ( auto const & alias : m_structAliases ) + for ( auto const & alias : structIt->second.aliases ) { - if ( alias.second.name == type ) - { - str += " using " + stripPrefix( alias.first, "Vk" ) + " = " + structureType + ";\n"; - } + str += " using " + stripPrefix( alias.first, "Vk" ) + " = " + structureType + ";\n"; } } } @@ -12548,15 +12528,7 @@ bool VulkanHppGenerator::isStructureChainAnchor( std::string const & type ) cons { if ( type.starts_with( "Vk" ) ) { - auto it = m_structs.find( type ); - if ( it == m_structs.end() ) - { - auto aliasIt = m_structAliases.find( type ); - if ( aliasIt != m_structAliases.end() ) - { - it = m_structs.find( aliasIt->second.name ); - } - } + auto it = findByNameOrAlias( m_structs, type ); if ( it != m_structs.end() ) { return m_extendedStructs.contains( it->first ); @@ -13755,6 +13727,7 @@ void VulkanHppGenerator::readRegistry( tinyxml2::XMLElement const * element ) { readExtensions( child ); distributeEnumValueAliases(); // after extensions are read, there should be no more enums/aliases specified! + distributeStructAliases(); // and there should be no more structs/aliases specified } else if ( value == "feature" ) { @@ -14077,7 +14050,7 @@ void VulkanHppGenerator::readSPIRVCapabilityEnable( tinyxml2::XMLElement const * } else if ( attribute.first == "struct" ) { - checkForError( m_structs.contains( attribute.second ) || m_structAliases.contains( attribute.second ), + checkForError( findByNameOrAlias( m_structs, attribute.second ) != m_structs.end(), line, "unknown structure <" + attribute.second + "> specified for SPIR-V capability" ); } @@ -14979,8 +14952,7 @@ void VulkanHppGenerator::readTypeStruct( tinyxml2::XMLElement const * element, b std::string name = attributes.find( "name" )->second; checkForError( m_types.insert( { name, TypeData{ TypeCategory::Struct, {}, line } } ).second, line, "struct <" + name + "> already specified" ); - assert( !m_structAliases.contains( name ) ); - m_structAliases[name] = { alias, line }; + checkForError( m_structsAliases.insert( { name, { alias, line } } ).second, line, "struct alias <" + name + "> already listed" ); } else diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 4946d8a..860f49f 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -364,14 +364,15 @@ private: struct StructureData { - bool allowDuplicate = {}; - bool isUnion = {}; - bool returnedOnly = {}; - bool mutualExclusiveLens = {}; - std::vector members = {}; - std::vector structExtends = {}; - std::string subStruct = {}; - int xmlLine = {}; + std::map aliases = {}; + bool allowDuplicate = {}; + bool isUnion = {}; + bool returnedOnly = {}; + bool mutualExclusiveLens = {}; + std::vector members = {}; + std::vector structExtends = {}; + std::string subStruct = {}; + int xmlLine = {}; }; struct TagData @@ -472,6 +473,7 @@ private: std::set determineVoidPointerParams( std::vector const & params ) const; void distributeEnumValueAliases(); void distributeSecondLevelCommands( std::set const & specialFunctions ); + void distributeStructAliases(); void filterLenMembers(); std::map::const_iterator findAlias( std::string const & name, std::map const & aliases ) const; std::string findBaseName( std::string aliasName, std::map const & aliases ) const; @@ -1050,8 +1052,8 @@ private: std::map m_includes; std::map m_platforms; std::set m_RAIISpecialFunctions; - std::map m_structAliases; std::map m_structs; + std::map m_structsAliases; // temporary storage for aliases, as they might be listed before the actual struct is listed std::map m_tags; std::map m_types; std::set m_unsupportedExtensions;