From 2207dc92c66d8870b0c218cc058e2dfc1ac5e2ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Wed, 22 Feb 2023 16:20:44 +0100 Subject: [PATCH] Corrected handling of attribute "depends" of sections on extending enums. (#1517) --- VulkanHppGenerator.cpp | 64 +++++++++++++++++++++++++++-------- VulkanHppGenerator.hpp | 77 ++++++++++++++++++++++++------------------ 2 files changed, 94 insertions(+), 47 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index e4b947d..74ae510 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -882,14 +882,39 @@ void VulkanHppGenerator::checkEnumCorrectness() const { if ( !v.protect.empty() ) { +#if !defined(NDEBUG) + bool checked = false; +#endif auto extIt = m_extensions.find( v.extension ); assert( extIt != m_extensions.end() ); auto platformIt = m_platforms.find( extIt->second.platform ); - assert( platformIt != m_platforms.end() ); - checkForError( v.protect == platformIt->second.protect, - v.xmlLine, - "attribute of enum value <" + v.name + "> is \"" + v.protect + "\" but corresponding extension <" + v.extension + - "> belongs to platform <" + platformIt->first + "> with protection \"" + platformIt->second.protect + "\"" ); + if ( platformIt != m_platforms.end() ) + { + checkForError( v.protect == platformIt->second.protect, + v.xmlLine, + "attribute of enum value <" + v.name + "> is \"" + v.protect + "\" but corresponding extension <" + v.extension + + "> belongs to platform <" + platformIt->first + "> with protection \"" + platformIt->second.protect + "\"" ); +#if !defined( NDEBUG ) + checked = true; +#endif + } + for ( auto const & depends : v.depends ) + { + extIt = m_extensions.find( depends ); + assert( extIt != m_extensions.end() ); + platformIt = m_platforms.find( extIt->second.platform ); + if ( platformIt != m_platforms.end() ) + { + checkForError( v.protect == platformIt->second.protect, + v.xmlLine, + "attribute of enum value <" + v.name + "> is \"" + v.protect + "\" but corresponding extension <" + v.extension + + "> belongs to platform <" + platformIt->first + "> with protection \"" + platformIt->second.protect + "\"" ); +#if !defined( NDEBUG ) + checked = true; +#endif + } + } + assert( checked ); } } } @@ -10062,8 +10087,19 @@ std::pair VulkanHppGenerator::getPoolTypeAndName( std: std::string VulkanHppGenerator::getProtect( EnumValueData const & evd ) const { - assert( evd.protect.empty() || ( evd.protect == getProtectFromTitle( evd.extension ) ) ); - return evd.protect.empty() ? getProtectFromTitle( evd.extension ) : evd.protect; + if ( evd.protect.empty() ) + { + std::string protect = getProtectFromTitle( evd.extension ); + for ( auto dependsIt = evd.depends.begin(); protect.empty() && dependsIt != evd.depends.end(); ++dependsIt ) + { + protect = getProtectFromTitle( *dependsIt ); + } + return protect; + } + else + { + return evd.protect; + } } std::string VulkanHppGenerator::getProtectFromPlatform( std::string const & platform ) const @@ -10718,7 +10754,7 @@ void VulkanHppGenerator::readEnumsEnum( tinyxml2::XMLElement const * element, st checkForError( name.starts_with( prefix ), line, "encountered enum value <" + name + "> that does not begin with expected prefix <" + prefix + ">" ); checkForError( bitpos.empty() ^ value.empty(), line, "invalid set of attributes for enum <" + name + ">" ); - enumIt->second.addEnumValue( line, name, protect, !bitpos.empty(), "" ); + enumIt->second.addEnumValue( line, name, protect, !bitpos.empty(), "", {} ); } } @@ -10934,7 +10970,7 @@ void VulkanHppGenerator::readExtensionsExtensionRequire( tinyxml2::XMLElement co } else if ( value == "enum" ) { - readRequireEnum( child, extensionIt->first ); + readRequireEnum( child, extensionIt->first, depends ); } else if ( value == "type" ) { @@ -11091,7 +11127,7 @@ void VulkanHppGenerator::readFeatureRequire( tinyxml2::XMLElement const * elemen } else if ( value == "enum" ) { - readRequireEnum( child, "" ); + readRequireEnum( child, "", {} ); } else if ( value == "type" ) { @@ -11594,7 +11630,7 @@ void VulkanHppGenerator::readRequireCommandRemove( tinyxml2::XMLElement const * } } -void VulkanHppGenerator::readRequireEnum( tinyxml2::XMLElement const * element, std::string const & extensionName ) +void VulkanHppGenerator::readRequireEnum( tinyxml2::XMLElement const * element, std::string const & extensionName, std::vector const & depends ) { int line = element->GetLineNum(); std::map attributes = getAttributes( element ); @@ -11733,7 +11769,7 @@ void VulkanHppGenerator::readRequireEnum( tinyxml2::XMLElement const * element, checkForError( bitpos.empty() + offset.empty() + value.empty() == 2, line, "exactly one out of bitpos = <" + bitpos + ">, offset = <" + offset + ">, and value = <" + value + "> are supposed to be empty" ); - enumIt->second.addEnumValue( element->GetLineNum(), name, protect, !bitpos.empty(), extensionName ); + enumIt->second.addEnumValue( element->GetLineNum(), name, protect, !bitpos.empty(), extensionName, depends ); } else if ( value.empty() ) { @@ -13072,12 +13108,12 @@ void VulkanHppGenerator::EnumData::addEnumAlias( int line, std::string const & n } void VulkanHppGenerator::EnumData::addEnumValue( - int line, std::string const & valueName, std::string const & protect, bool bitpos, std::string const & extension ) + int line, std::string const & valueName, std::string const & protect, bool bitpos, std::string const & extension, std::vector const & depends ) { auto valueIt = std::find_if( values.begin(), values.end(), [&valueName]( EnumValueData const & evd ) { return evd.name == valueName; } ); if ( valueIt == values.end() ) { - values.emplace_back( line, valueName, protect, extension, bitpos ); + values.emplace_back( line, valueName, protect, extension, depends, bitpos ); } } diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index b4e453e..843ce4c 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -200,22 +200,33 @@ private: struct EnumValueData { - EnumValueData( int line, std::string const & name_, std::string const & protect_, std::string const & extension_, bool singleBit_ ) - : name( name_ ), extension( extension_ ), protect( protect_ ), singleBit( singleBit_ ), xmlLine( line ) + EnumValueData( int line, + std::string const & name_, + std::string const & protect_, + std::string const & extension_, + std::vector const & depends_, + bool singleBit_ ) + : name( name_ ), depends( depends_ ), extension( extension_ ), protect( protect_ ), singleBit( singleBit_ ), xmlLine( line ) { } - std::string name; - std::string extension; - std::string protect; - bool singleBit; - int xmlLine; + std::string name; + std::vector depends; + std::string extension; + std::string protect; + bool singleBit; + int xmlLine; }; struct EnumData { void addEnumAlias( int line, std::string const & name, std::string const & alias ); - void addEnumValue( int line, std::string const & valueName, std::string const & protect, bool bitpos, std::string const & extension ); + void addEnumValue( int line, + std::string const & valueName, + std::string const & protect, + bool bitpos, + std::string const & extension, + std::vector const & depends ); std::string alias = {}; // alias for this enum std::map aliases = {}; // aliases for the values @@ -950,31 +961,31 @@ private: void readRegistry( tinyxml2::XMLElement const * element ); void readRequireCommand( tinyxml2::XMLElement const * element, std::string const & title, RequireData & requireData ); void readRequireCommandRemove( tinyxml2::XMLElement const * element ); - void readRequireEnum( tinyxml2::XMLElement const * element, std::string const & extensionName ); - void readRequireEnumRemove( tinyxml2::XMLElement const * element ); - void readRequireTypeRemove( tinyxml2::XMLElement const * element ); - void readSPIRVCapabilities( tinyxml2::XMLElement const * element ); - void readSPIRVCapabilitiesSPIRVCapability( tinyxml2::XMLElement const * element ); - void readSPIRVCapabilitiesSPIRVCapabilityEnable( tinyxml2::XMLElement const * element ); - void readSPIRVCapabilitiesSPIRVCapabilityEnableExtension( int xmlLine, std::map const & attributes ); - void readSPIRVCapabilitiesSPIRVCapabilityEnableProperty( int xmlLine, std::map const & attributes ); - void readSPIRVCapabilitiesSPIRVCapabilityEnableStruct( int xmlLine, std::map const & attributes ); - void readSPIRVCapabilitiesSPIRVCapabilityEnableVersion( int xmlLine, std::map const & attributes ); - void readSPIRVExtensions( tinyxml2::XMLElement const * element ); - void readSPIRVExtensionsExtension( tinyxml2::XMLElement const * element ); - void readSPIRVExtensionsExtensionEnable( tinyxml2::XMLElement const * element ); - void readTags( tinyxml2::XMLElement const * element ); - void readTagsTag( tinyxml2::XMLElement const * element ); - void readTypes( tinyxml2::XMLElement const * element ); - void readTypesType( tinyxml2::XMLElement const * element ); - void readTypesTypeBasetype( tinyxml2::XMLElement const * element, std::map const & attributes ); - void readTypesTypeBitmask( tinyxml2::XMLElement const * element, std::map const & attributes ); - void readTypesTypeDefine( tinyxml2::XMLElement const * element, std::map const & attributes ); - void readTypesTypeEnum( tinyxml2::XMLElement const * element, std::map const & attributes ); - void readTypesTypeFuncpointer( tinyxml2::XMLElement const * element, std::map const & attributes ); - void readTypesTypeHandle( tinyxml2::XMLElement const * element, std::map const & attributes ); - void readTypesTypeInclude( tinyxml2::XMLElement const * element, std::map const & attributes ); - void readTypesTypeRequires( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readRequireEnum( tinyxml2::XMLElement const * element, std::string const & extensionName, std::vector const & depends ); + void readRequireEnumRemove( tinyxml2::XMLElement const * element ); + void readRequireTypeRemove( tinyxml2::XMLElement const * element ); + void readSPIRVCapabilities( tinyxml2::XMLElement const * element ); + void readSPIRVCapabilitiesSPIRVCapability( tinyxml2::XMLElement const * element ); + void readSPIRVCapabilitiesSPIRVCapabilityEnable( tinyxml2::XMLElement const * element ); + void readSPIRVCapabilitiesSPIRVCapabilityEnableExtension( int xmlLine, std::map const & attributes ); + void readSPIRVCapabilitiesSPIRVCapabilityEnableProperty( int xmlLine, std::map const & attributes ); + void readSPIRVCapabilitiesSPIRVCapabilityEnableStruct( int xmlLine, std::map const & attributes ); + void readSPIRVCapabilitiesSPIRVCapabilityEnableVersion( int xmlLine, std::map const & attributes ); + void readSPIRVExtensions( tinyxml2::XMLElement const * element ); + void readSPIRVExtensionsExtension( tinyxml2::XMLElement const * element ); + void readSPIRVExtensionsExtensionEnable( tinyxml2::XMLElement const * element ); + void readTags( tinyxml2::XMLElement const * element ); + void readTagsTag( tinyxml2::XMLElement const * element ); + void readTypes( tinyxml2::XMLElement const * element ); + void readTypesType( tinyxml2::XMLElement const * element ); + void readTypesTypeBasetype( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readTypesTypeBitmask( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readTypesTypeDefine( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readTypesTypeEnum( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readTypesTypeFuncpointer( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readTypesTypeHandle( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readTypesTypeInclude( tinyxml2::XMLElement const * element, std::map const & attributes ); + void readTypesTypeRequires( tinyxml2::XMLElement const * element, std::map const & attributes ); void readTypesTypeStruct( tinyxml2::XMLElement const * element, bool isUnion, std::map const & attributes ); void readTypesTypeStructMember( tinyxml2::XMLElement const * element, std::vector & members, bool isUnion ); void readTypesTypeStructMemberEnum( tinyxml2::XMLElement const * element, MemberData & memberData );