From 7bd57c72907bc875c91a2167b978c4474ab6d726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Wed, 24 Apr 2024 08:33:25 +0200 Subject: [PATCH] Simplify handling of enum aliases (#1850) --- VulkanHppGenerator.cpp | 65 ++++++++++++++++-------------------------- VulkanHppGenerator.hpp | 2 +- XMLHelper.hpp | 26 +---------------- 3 files changed, 27 insertions(+), 66 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index f305942..5d51d9c 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -1231,12 +1231,6 @@ void VulkanHppGenerator::checkEnumCorrectness() const checkEnumCorrectness( ext.requireData ); } - // enum alias checks - for ( auto const & alias : m_enumAliases ) - { - checkForError( m_enums.contains( alias.second.name ), alias.second.xmlLine, "enum <" + alias.first + "> uses unknown alias <" + alias.second.name + ">" ); - } - // special check for VkFormat if ( !m_formats.empty() ) { @@ -1305,7 +1299,7 @@ void VulkanHppGenerator::checkEnumCorrectness( std::vector const & else { // every enum not listed in the m_enums, should be an alias of such a thing - checkForError( m_enumAliases.contains( type ), typeIt->second.xmlLine, "enum type <" + type + "> is not listed as an enum" ); + checkForError( findByNameOrAlias( m_enums, type ) != m_enums.end(), typeIt->second.xmlLine, "enum type <" + type + "> is not listed as an enum" ); } } break; @@ -5429,9 +5423,9 @@ std::string VulkanHppGenerator::generateCppModuleEnumUsings() const auto const enumName = stripPrefix( enumIt->first, "Vk" ); localUsings += replaceWithMap( usingTemplate, { { "enumName", enumName } } ); - if ( auto const aliasIt = findAlias( enumIt->first, m_enumAliases ); aliasIt != m_enumAliases.end() ) + for ( auto const & alias : enumIt->second.aliases ) { - localUsings += replaceWithMap( usingTemplate, { { "enumName", stripPrefix( aliasIt->first, "Vk" ) } } ); + localUsings += replaceWithMap( usingTemplate, { { "enumName", stripPrefix( alias.first, "Vk" ) } } ); } if ( auto const bitmaskIt = @@ -6561,7 +6555,6 @@ std::string VulkanHppGenerator::generateEnum( std::pair c bitmask = generateBitmask( bitmaskIt, surroundingProtect ); } - auto aliasEnumIt = findAlias( enumData.first, m_enumAliases ); std::string enumValues, previousEnter, previousLeave; std::map valueToNameMap; for ( auto const & value : enumData.second.values ) @@ -6585,36 +6578,35 @@ std::string VulkanHppGenerator::generateEnum( std::pair c } enumValues += " " + valueName + " = " + value.name + ",\n"; - for ( auto const & alias : value.aliases ) + for ( auto const & valueAlias : value.aliases ) { std::string enumName = enumData.first; - auto aliasIt = std::find_if( m_enumAliases.begin(), m_enumAliases.end(), [&enumData]( auto const & ad ) { return ad.second.name == enumData.first; } ); - if ( aliasIt != m_enumAliases.end() ) + if ( !enumData.second.aliases.empty() ) { - assert( std::find_if( std::next( aliasIt ), m_enumAliases.end(), [&enumData]( auto const & ad ) { return ad.second.name == enumData.first; } ) == - m_enumAliases.end() ); - std::string enumTag = findTag( enumData.first ); - std::string aliasTag = findTag( aliasIt->first ); - std::string valueTag = findTag( alias.first ); - if ( ( stripPostfix( enumData.first, enumTag ) == stripPostfix( aliasIt->first, aliasTag ) ) && ( aliasTag == valueTag ) ) + assert( enumData.second.aliases.size() == 1 ); + auto enumAliasIt = enumData.second.aliases.begin(); + std::string enumTag = findTag( enumData.first ); + std::string aliasTag = findTag( enumAliasIt->first ); + std::string valueTag = findTag( valueAlias.first ); + if ( ( stripPostfix( enumData.first, enumTag ) == stripPostfix( enumAliasIt->first, aliasTag ) ) && ( aliasTag == valueTag ) ) { - enumName = aliasIt->first; + enumName = enumAliasIt->first; } } - std::string aliasName = generateEnumValueName( enumName, alias.first, enumData.second.isBitmask ); - auto [mapIt, inserted] = valueToNameMap.insert( { aliasName, alias.first } ); + std::string aliasName = generateEnumValueName( enumName, valueAlias.first, enumData.second.isBitmask ); + auto [mapIt, inserted] = valueToNameMap.insert( { aliasName, valueAlias.first } ); if ( inserted ) { - enumValues += " " + aliasName + " = " + alias.first + ",\n"; + enumValues += " " + aliasName + " = " + valueAlias.first + ",\n"; } else { // some aliases are so close to the original, that no new entry can be generated! - assert( mapIt->second != alias.first ); + assert( mapIt->second != valueAlias.first ); checkForError( ( mapIt->second == value.name ) || value.aliases.contains( mapIt->second ), - alias.second, - "generated enum alias value name <" + aliasName + ">, generated from <" + alias.first + + valueAlias.second, + "generated enum alias value name <" + aliasName + ">, generated from <" + valueAlias.first + "> is already generated from different enum value <" + mapIt->second + ">" ); } } @@ -6634,9 +6626,9 @@ std::string VulkanHppGenerator::generateEnum( std::pair c } std::string enumUsing; - if ( aliasEnumIt != m_enumAliases.end() ) + for ( auto const & alias : enumData.second.aliases ) { - enumUsing += " using " + stripPrefix( aliasEnumIt->first, "Vk" ) + " = " + stripPrefix( enumData.first, "Vk" ) + ";\n"; + enumUsing += " using " + stripPrefix( alias.first, "Vk" ) + " = " + stripPrefix( enumData.first, "Vk" ) + ";\n"; } const std::string enumTemplate = R"( enum class ${enumName}${baseType} @@ -12963,15 +12955,7 @@ void VulkanHppGenerator::readEnums( tinyxml2::XMLElement const * element ) checkForError( !type.empty(), line, "enum without type" ); // get the EnumData entry in enum map - auto enumIt = m_enums.find( name ); - if ( enumIt == m_enums.end() ) - { - auto aliasIt = m_enumAliases.find( name ); - if ( aliasIt != m_enumAliases.end() ) - { - enumIt = m_enums.find( aliasIt->second.name ); - } - } + auto enumIt = findByNameOrAlias( m_enums, name ); checkForError( enumIt != m_enums.end(), line, "enum <" + name + "> is not listed as enum in the types section" ); checkForError( enumIt->second.values.empty(), line, "enum <" + name + "> already holds values" ); @@ -13871,8 +13855,7 @@ void VulkanHppGenerator::readRequireEnum( // enum aliases that don't extend something are listed as constants auto typeIt = m_types.find( alias ); checkForError( typeIt != m_types.end(), line, "enum alias <" + name + "> is an alias of an unknown enum <" + alias + ">" ); - checkForError( - typeIt->second.category == TypeCategory::Constant, line, "enum alias <" + name + "> is an alias of a non-constant type <" + alias + ">" ); + checkForError( typeIt->second.category == TypeCategory::Constant, line, "enum alias <" + name + "> is an alias of a non-constant type <" + alias + ">" ); checkForError( m_types.insert( { name, TypeData{ TypeCategory::Constant, { requiredBy }, line } } ).second, line, "required enum <" + name + "> already specified" ); @@ -14837,7 +14820,9 @@ void VulkanHppGenerator::readTypeEnum( tinyxml2::XMLElement const * element, std } else { - checkForError( m_enumAliases.insert( { name, { alias, line } } ).second, line, "enum <" + name + "> already specified as some alias" ); + auto enumIt = m_enums.find( alias ); + checkForError( enumIt != m_enums.end(), line, "enum <" + name + "> is an alias of an unknown enum <" + alias + ">" ); + checkForError( enumIt->second.aliases.insert( { name, line } ).second, line, "enum <" + name + "> already specified as some alias" ); } } diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 0d45ccc..59d34a3 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -160,6 +160,7 @@ private: void addEnumValue( int line, std::string const & valueName, std::string const & protect, std::string const & bitpos, std::string const & value, bool supported ); + std::map aliases = {}; std::string bitwidth = {}; bool isBitmask = false; std::vector valueAliases = {}; // temporary storage for aliases, as they might be specified before the actual value is specified @@ -1037,7 +1038,6 @@ private: std::map m_constants; std::map m_defines; DefinesPartition m_definesPartition; // partition defined macros into mutually-exclusive sets of callees, callers, and values - std::map m_enumAliases; std::map m_enums; std::set m_extendedStructs; // structs which are referenced by the structextends tag std::vector m_extensions; diff --git a/XMLHelper.hpp b/XMLHelper.hpp index e41ef9c..5ae7a77 100644 --- a/XMLHelper.hpp +++ b/XMLHelper.hpp @@ -422,7 +422,7 @@ inline std::string stripPrefix( std::string const & value, std::string const & p inline std::string toCamelCase( std::string const & value, bool keepSeparatedNumbersSeparated ) { - assert( !value.empty() && ( isupper( value[0] ) || isdigit( value[0] ) ) ); + assert( value.empty() || isupper( value[0] ) || isdigit( value[0] ) ); std::string result; result.reserve( value.size() ); for ( size_t i = 0; i < value.size(); ++i ) @@ -439,30 +439,6 @@ inline std::string toCamelCase( std::string const & value, bool keepSeparatedNum result.push_back( ( ( 0 == i ) || ( value[i - 1] == '_' ) || isdigit( value[i - 1] ) ) ? value[i] : static_cast( tolower( value[i] ) ) ); } } -#if 0 - bool keepUpper = true; - for ( auto c : value ) - { - if ( c == '_' ) - { - keepUpper = true; - } - else if ( isdigit( c ) ) - { - keepUpper = true; - result.push_back( c ); - } - else if ( keepUpper ) - { - result.push_back( c ); - keepUpper = false; - } - else - { - result.push_back( static_cast( tolower( c ) ) ); - } - } -#endif return result; }