mirror of
https://github.com/KhronosGroup/Vulkan-Hpp.git
synced 2024-09-20 05:52:16 +00:00
Merge pull request #983 from asuessenbach/enum
Re-arranged handling of FlagBits not listed as required for a Flags.
This commit is contained in:
commit
6bc8a07da2
@ -715,6 +715,16 @@ VulkanHppGenerator::VulkanHppGenerator( tinyxml2::XMLDocument const & document )
|
|||||||
readRegistry( elements[0] );
|
readRegistry( elements[0] );
|
||||||
checkCorrectness();
|
checkCorrectness();
|
||||||
|
|
||||||
|
// some "FlagBits" enums are not specified, but needed for our "Flags" handling -> add them here
|
||||||
|
for ( auto & feature : m_features )
|
||||||
|
{
|
||||||
|
addMissingFlagBits( feature.second.types, feature.first );
|
||||||
|
}
|
||||||
|
for ( auto & ext : m_extensions )
|
||||||
|
{
|
||||||
|
addMissingFlagBits( ext.second.types, ext.first );
|
||||||
|
}
|
||||||
|
|
||||||
for ( auto extensionIt = m_extensions.begin(); extensionIt != m_extensions.end(); ++extensionIt )
|
for ( auto extensionIt = m_extensions.begin(); extensionIt != m_extensions.end(); ++extensionIt )
|
||||||
{
|
{
|
||||||
int number = atoi( extensionIt->second.number.c_str() );
|
int number = atoi( extensionIt->second.number.c_str() );
|
||||||
@ -746,6 +756,46 @@ void VulkanHppGenerator::addCommand( std::string const & name, CommandData & com
|
|||||||
"command list of handle <" + handleIt->first + "> already holds a commnand <" + name + ">" );
|
"command list of handle <" + handleIt->first + "> already holds a commnand <" + name + ">" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanHppGenerator::addMissingFlagBits( std::vector<std::string> & types, std::string const & referencedIn )
|
||||||
|
{
|
||||||
|
std::vector<std::string> newTypes;
|
||||||
|
for ( auto & type : types )
|
||||||
|
{
|
||||||
|
auto bitmaskIt = m_bitmasks.find( type );
|
||||||
|
if ( ( bitmaskIt != m_bitmasks.end() ) && bitmaskIt->second.requirements.empty() )
|
||||||
|
{
|
||||||
|
size_t pos = bitmaskIt->first.find( "Flags" );
|
||||||
|
assert( pos != std::string::npos );
|
||||||
|
std::string flagBits = bitmaskIt->first.substr( 0, pos + 4 ) + "Bit" + bitmaskIt->first.substr( pos + 4 );
|
||||||
|
bitmaskIt->second.requirements = flagBits;
|
||||||
|
|
||||||
|
// some flagsBits are specified but never listed as required for any flags!
|
||||||
|
// so, even if this bitmask has not enum listed as required, it might still already exist in the enums list
|
||||||
|
if ( m_enums.find( flagBits ) == m_enums.end() )
|
||||||
|
{
|
||||||
|
EnumData flagBitsData( 0 );
|
||||||
|
flagBitsData.isBitmask = true;
|
||||||
|
m_enums.insert( std::make_pair( flagBits, flagBitsData ) );
|
||||||
|
|
||||||
|
assert( m_types.find( flagBits ) == m_types.end() );
|
||||||
|
TypeData typeData( TypeCategory::Bitmask );
|
||||||
|
typeData.referencedIn = referencedIn;
|
||||||
|
m_types.insert( std::make_pair( flagBits, typeData ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert( m_types.find( flagBits ) != m_types.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( std::find_if( types.begin(),
|
||||||
|
types.end(),
|
||||||
|
[&flagBits]( std::string const & type ) { return ( type == flagBits ); } ) == types.end() );
|
||||||
|
newTypes.push_back( flagBits );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types.insert( types.end(), newTypes.begin(), newTypes.end() );
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanHppGenerator::appendArgumentPlainType( std::string & str, ParamData const & paramData ) const
|
void VulkanHppGenerator::appendArgumentPlainType( std::string & str, ParamData const & paramData ) const
|
||||||
{
|
{
|
||||||
// this parameter is just a plain type
|
// this parameter is just a plain type
|
||||||
@ -889,11 +939,11 @@ void VulkanHppGenerator::appendBitmasks( std::string & str ) const
|
|||||||
str += "\n //=== " + feature.first + " ===\n";
|
str += "\n //=== " + feature.first + " ===\n";
|
||||||
for ( auto const & type : feature.second.types )
|
for ( auto const & type : feature.second.types )
|
||||||
{
|
{
|
||||||
auto bitmaskIt = m_bitmasks.find( type.first );
|
auto bitmaskIt = m_bitmasks.find( type );
|
||||||
if ( bitmaskIt != m_bitmasks.end() )
|
if ( bitmaskIt != m_bitmasks.end() )
|
||||||
{
|
{
|
||||||
assert( listedBitmasks.find( type.first ) == listedBitmasks.end() );
|
assert( listedBitmasks.find( type ) == listedBitmasks.end() );
|
||||||
listedBitmasks.insert( type.first );
|
listedBitmasks.insert( type );
|
||||||
appendBitmask( str, bitmaskIt );
|
appendBitmask( str, bitmaskIt );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -959,33 +1009,7 @@ void VulkanHppGenerator::appendBitmask( std::string & str,
|
|||||||
std::vector<EnumValueData> const & enumValues ) const
|
std::vector<EnumValueData> const & enumValues ) const
|
||||||
{
|
{
|
||||||
// each Flags class is using the class 'Flags' with the corresponding FlagBits enum as the template parameter
|
// each Flags class is using the class 'Flags' with the corresponding FlagBits enum as the template parameter
|
||||||
// if there's no enum for the FlagBits, introduce an artificial empty one
|
str += "\n using " + bitmaskName + " = Flags<" + enumName + ">;\n";
|
||||||
std::string emptyEnumName;
|
|
||||||
if ( enumName.empty() )
|
|
||||||
{
|
|
||||||
emptyEnumName = bitmaskName;
|
|
||||||
size_t pos = emptyEnumName.rfind( "Flags" );
|
|
||||||
assert( pos != std::string::npos );
|
|
||||||
emptyEnumName.replace( pos, 5, "FlagBits" );
|
|
||||||
|
|
||||||
// if this emptyEnumName is not in the list of enums, list it here
|
|
||||||
if ( m_enums.find( "Vk" + emptyEnumName ) == m_enums.end() )
|
|
||||||
{
|
|
||||||
const std::string templateString = R"x(
|
|
||||||
enum class ${enumName} : ${bitmaskType}
|
|
||||||
{};
|
|
||||||
|
|
||||||
VULKAN_HPP_INLINE std::string to_string( ${enumName} )
|
|
||||||
{
|
|
||||||
return "(void)";
|
|
||||||
}
|
|
||||||
)x";
|
|
||||||
|
|
||||||
str += replaceWithMap( templateString, { { "enumName", emptyEnumName }, { "bitmaskType", bitmaskType } } );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string name = ( enumName.empty() ? emptyEnumName : enumName );
|
|
||||||
str += "\n using " + bitmaskName + " = Flags<" + name + ">;\n";
|
|
||||||
|
|
||||||
if ( !enumValues.empty() )
|
if ( !enumValues.empty() )
|
||||||
{
|
{
|
||||||
@ -996,7 +1020,7 @@ void VulkanHppGenerator::appendBitmask( std::string & str,
|
|||||||
{
|
{
|
||||||
std::string enter, leave;
|
std::string enter, leave;
|
||||||
std::tie( enter, leave ) = generateProtection( value.extension );
|
std::tie( enter, leave ) = generateProtection( value.extension );
|
||||||
std::string valueName = generateEnumValueName( "Vk" + name, value.name, true, m_tags );
|
std::string valueName = generateEnumValueName( "Vk" + enumName, value.name, true, m_tags );
|
||||||
allFlags += ( ( previousEnter != enter ) ? ( "\n" + previousLeave + enter ) : "\n" ) + " " +
|
allFlags += ( ( previousEnter != enter ) ? ( "\n" + previousLeave + enter ) : "\n" ) + " " +
|
||||||
( encounteredFlag ? "| " : " " ) + bitmaskType + "( " + enumName + "::" + valueName + " )";
|
( encounteredFlag ? "| " : " " ) + bitmaskType + "( " + enumName + "::" + valueName + " )";
|
||||||
encounteredFlag = true;
|
encounteredFlag = true;
|
||||||
@ -2730,11 +2754,11 @@ void VulkanHppGenerator::appendEnums( std::string & str ) const
|
|||||||
str += "\n //=== " + feature.first + " ===\n";
|
str += "\n //=== " + feature.first + " ===\n";
|
||||||
for ( auto const & type : feature.second.types )
|
for ( auto const & type : feature.second.types )
|
||||||
{
|
{
|
||||||
auto enumIt = m_enums.find( type.first );
|
auto enumIt = m_enums.find( type );
|
||||||
if ( enumIt != m_enums.end() )
|
if ( enumIt != m_enums.end() )
|
||||||
{
|
{
|
||||||
assert( listedEnums.find( type.first ) == listedEnums.end() );
|
assert( listedEnums.find( type ) == listedEnums.end() );
|
||||||
listedEnums.insert( type.first );
|
listedEnums.insert( type );
|
||||||
|
|
||||||
str += "\n";
|
str += "\n";
|
||||||
appendEnum( str, *enumIt );
|
appendEnum( str, *enumIt );
|
||||||
@ -11225,6 +11249,16 @@ void VulkanHppGenerator::checkCorrectness()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// enum checks by features and extensions
|
||||||
|
for ( auto & feature : m_features )
|
||||||
|
{
|
||||||
|
checkEnumCorrectness( feature.second.types );
|
||||||
|
}
|
||||||
|
for ( auto & ext : m_extensions )
|
||||||
|
{
|
||||||
|
checkEnumCorrectness( ext.second.types );
|
||||||
|
}
|
||||||
|
|
||||||
// extension checks
|
// extension checks
|
||||||
for ( auto const & extension : m_extensions )
|
for ( auto const & extension : m_extensions )
|
||||||
{
|
{
|
||||||
@ -11421,6 +11455,29 @@ void VulkanHppGenerator::checkCorrectness()
|
|||||||
assert( sTypeValues.empty() );
|
assert( sTypeValues.empty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanHppGenerator::checkEnumCorrectness( std::vector<std::string> const & types ) const
|
||||||
|
{
|
||||||
|
for ( auto const & type : types )
|
||||||
|
{
|
||||||
|
auto enumIt = m_enums.find( type );
|
||||||
|
if ( ( enumIt != m_enums.end() ) && enumIt->second.isBitmask )
|
||||||
|
{
|
||||||
|
auto bitmaskIt =
|
||||||
|
std::find_if( m_bitmasks.begin(),
|
||||||
|
m_bitmasks.end(),
|
||||||
|
[&enumIt]( auto const & bitmask ) { return bitmask.second.requirements == enumIt->first; } );
|
||||||
|
check( bitmaskIt != m_bitmasks.end(),
|
||||||
|
enumIt->second.xmlLine,
|
||||||
|
"enum <" + enumIt->first +
|
||||||
|
"> is not listed as an requires or bitvalues for any bitmask in the types section" );
|
||||||
|
check( ( enumIt->second.bitwidth != "64" ) || ( bitmaskIt->second.type == "VkFlags64" ),
|
||||||
|
enumIt->second.xmlLine,
|
||||||
|
"enum <" + enumIt->first + "> is marked with bitwidth <64> but corresponding bitmask <" +
|
||||||
|
bitmaskIt->first + "> is not of type <VkFlags64>" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanHppGenerator::containsArray( std::string const & type ) const
|
bool VulkanHppGenerator::containsArray( std::string const & type ) const
|
||||||
{
|
{
|
||||||
// a simple recursive check if a type is or contains an array
|
// a simple recursive check if a type is or contains an array
|
||||||
@ -12835,18 +12892,9 @@ void VulkanHppGenerator::readEnums( tinyxml2::XMLElement const * element )
|
|||||||
if ( bitmask )
|
if ( bitmask )
|
||||||
{
|
{
|
||||||
check( name.find( "FlagBits" ) != std::string::npos, line, "bitmask <" + name + "> does not contain <FlagBits>" );
|
check( name.find( "FlagBits" ) != std::string::npos, line, "bitmask <" + name + "> does not contain <FlagBits>" );
|
||||||
auto bitmaskIt = std::find_if( m_bitmasks.begin(),
|
|
||||||
m_bitmasks.end(),
|
|
||||||
[&name]( auto const & bitmask ) { return bitmask.second.requirements == name; } );
|
|
||||||
check( bitmaskIt != m_bitmasks.end(),
|
|
||||||
line,
|
|
||||||
"enum <" + name + "> is not listed as an requires or bitvalues for any bitmask in the types section" );
|
|
||||||
check( ( bitwidth != "64" ) || ( bitmaskIt->second.type == "VkFlags64" ),
|
|
||||||
line,
|
|
||||||
"enum <" + name + "> is marked with bitwidth <64> but corresponding bitmask <" + bitmaskIt->first +
|
|
||||||
"> is not of type <VkFlags64>" );
|
|
||||||
}
|
}
|
||||||
enumIt->second.isBitmask = bitmask;
|
enumIt->second.isBitmask = bitmask;
|
||||||
|
enumIt->second.bitwidth = bitwidth;
|
||||||
|
|
||||||
// read the names of the enum values
|
// read the names of the enum values
|
||||||
for ( auto child : children )
|
for ( auto child : children )
|
||||||
@ -13326,13 +13374,8 @@ void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const *
|
|||||||
std::string name = attributes.find( "name" )->second;
|
std::string name = attributes.find( "name" )->second;
|
||||||
auto featureTypeIt = std::find_if( featureIt->second.types.begin(),
|
auto featureTypeIt = std::find_if( featureIt->second.types.begin(),
|
||||||
featureIt->second.types.end(),
|
featureIt->second.types.end(),
|
||||||
[&name]( std::pair<std::string, int> const & typeLine )
|
[&name]( std::string const & type ) { return type == name; } );
|
||||||
{ return ( typeLine.first == name ) && ( typeLine.second != 0 ); } );
|
check( featureTypeIt == featureIt->second.types.end(), line, "type <" + name + "> already listed for this feature!" );
|
||||||
check( featureTypeIt == featureIt->second.types.end(),
|
|
||||||
line,
|
|
||||||
"type <" + name + "> already listed for this feature on line " +
|
|
||||||
( ( featureTypeIt == featureIt->second.types.end() ) ? "" : std::to_string( featureTypeIt->second ) ) +
|
|
||||||
" !" );
|
|
||||||
|
|
||||||
// some types are in fact includes (like vk_platform) or defines (like VK_API_VERSION)
|
// some types are in fact includes (like vk_platform) or defines (like VK_API_VERSION)
|
||||||
if ( ( m_defines.find( name ) == m_defines.end() ) && ( m_includes.find( name ) == m_includes.end() ) )
|
if ( ( m_defines.find( name ) == m_defines.end() ) && ( m_includes.find( name ) == m_includes.end() ) )
|
||||||
@ -13344,51 +13387,7 @@ void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const *
|
|||||||
"type <" + name + "> already listed on feature <" + typeIt->second.referencedIn + ">" );
|
"type <" + name + "> already listed on feature <" + typeIt->second.referencedIn + ">" );
|
||||||
typeIt->second.referencedIn = featureIt->first;
|
typeIt->second.referencedIn = featureIt->first;
|
||||||
|
|
||||||
// add missing FlagBits here!
|
featureIt->second.types.push_back( name );
|
||||||
if ( ( name != "VkFlags" ) && endsWith( name, "Flags" ) )
|
|
||||||
{
|
|
||||||
assert( !featureIt->second.types.empty() );
|
|
||||||
std::string flagBits = name.substr( 0, name.length() - 5 ) + "FlagBits";
|
|
||||||
if ( featureIt->second.types.back().first != flagBits )
|
|
||||||
{
|
|
||||||
assert( std::find_if( featureIt->second.types.begin(),
|
|
||||||
featureIt->second.types.end(),
|
|
||||||
[&flagBits]( std::pair<std::string, int> const & typeLine )
|
|
||||||
{ return ( typeLine.first == flagBits ); } ) == featureIt->second.types.end() );
|
|
||||||
featureIt->second.types.push_back( std::make_pair( flagBits, 0 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter out FlagBits that are listed after their Flags!
|
|
||||||
// (and therefore have been added right before that Flags, above)
|
|
||||||
bool skipIt = false;
|
|
||||||
if ( endsWith( name, "FlagBits" ) )
|
|
||||||
{
|
|
||||||
assert( !featureIt->second.types.empty() );
|
|
||||||
std::string flags = name.substr( 0, name.length() - 4 ) + "s";
|
|
||||||
if ( featureIt->second.types.back().first == flags )
|
|
||||||
{
|
|
||||||
skipIt = true;
|
|
||||||
auto flagBitsIt = std::find_if( featureIt->second.types.begin(),
|
|
||||||
featureIt->second.types.end(),
|
|
||||||
[&name]( std::pair<std::string, int> const & typeLine )
|
|
||||||
{ return ( typeLine.first == name ); } );
|
|
||||||
assert( flagBitsIt != featureIt->second.types.end() );
|
|
||||||
assert( flagBitsIt->second == 0 );
|
|
||||||
flagBitsIt->second = line;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert( std::find_if( featureIt->second.types.begin(),
|
|
||||||
featureIt->second.types.end(),
|
|
||||||
[&flags]( std::pair<std::string, int> const & typeLine )
|
|
||||||
{ return ( typeLine.first == flags ); } ) == featureIt->second.types.end() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( !skipIt )
|
|
||||||
{
|
|
||||||
featureIt->second.types.push_back( std::make_pair( name, line ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +158,7 @@ private:
|
|||||||
|
|
||||||
std::string alias; // alias for this enum
|
std::string alias; // alias for this enum
|
||||||
std::map<std::string, EnumAliasData> aliases;
|
std::map<std::string, EnumAliasData> aliases;
|
||||||
|
std::string bitwidth;
|
||||||
bool isBitmask = false;
|
bool isBitmask = false;
|
||||||
std::vector<EnumValueData> values;
|
std::vector<EnumValueData> values;
|
||||||
int xmlLine;
|
int xmlLine;
|
||||||
@ -169,7 +170,7 @@ private:
|
|||||||
|
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
std::string number;
|
std::string number;
|
||||||
std::vector<std::pair<std::string, int>> types;
|
std::vector<std::string> types;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExtensionData
|
struct ExtensionData
|
||||||
@ -292,6 +293,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void addCommand( std::string const & name, CommandData & commandData );
|
void addCommand( std::string const & name, CommandData & commandData );
|
||||||
|
void addMissingFlagBits( std::vector<std::string> & types, std::string const & referencedIn );
|
||||||
void appendArgumentPlainType( std::string & str, ParamData const & paramData ) const;
|
void appendArgumentPlainType( std::string & str, ParamData const & paramData ) const;
|
||||||
void appendArguments( std::string & str,
|
void appendArguments( std::string & str,
|
||||||
CommandData const & commandData,
|
CommandData const & commandData,
|
||||||
@ -1067,6 +1069,7 @@ private:
|
|||||||
std::map<size_t, std::vector<size_t>> const & countToVectorMap,
|
std::map<size_t, std::vector<size_t>> const & countToVectorMap,
|
||||||
std::set<size_t> const & skippedParams ) const;
|
std::set<size_t> const & skippedParams ) const;
|
||||||
void checkCorrectness();
|
void checkCorrectness();
|
||||||
|
void checkEnumCorrectness( std::vector<std::string> const & types ) const;
|
||||||
bool containsArray( std::string const & type ) const;
|
bool containsArray( std::string const & type ) const;
|
||||||
bool containsUnion( std::string const & type ) const;
|
bool containsUnion( std::string const & type ) const;
|
||||||
size_t determineDefaultStartIndex( std::vector<ParamData> const & params,
|
size_t determineDefaultStartIndex( std::vector<ParamData> const & params,
|
||||||
@ -1197,14 +1200,14 @@ private:
|
|||||||
void readTypeEnum( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
|
void readTypeEnum( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
|
||||||
void readTypeInclude( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
|
void readTypeInclude( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
|
||||||
TypeInfo readTypeInfo( tinyxml2::XMLElement const * element ) const;
|
TypeInfo readTypeInfo( tinyxml2::XMLElement const * element ) const;
|
||||||
void readTypes( tinyxml2::XMLElement const * element );
|
void readTypes( tinyxml2::XMLElement const * element );
|
||||||
void registerDeleter( std::string const & name, std::pair<std::string, CommandData> const & commandData );
|
void registerDeleter( std::string const & name, std::pair<std::string, CommandData> const & commandData );
|
||||||
void renameFunctionParameters();
|
void renameFunctionParameters();
|
||||||
void rescheduleRAIIHandle( std::string & str,
|
void rescheduleRAIIHandle( std::string & str,
|
||||||
std::pair<std::string, HandleData> const & handle,
|
std::pair<std::string, HandleData> const & handle,
|
||||||
std::set<std::string> & listedHandles,
|
std::set<std::string> & listedHandles,
|
||||||
std::set<std::string> const & specialFunctions ) const;
|
std::set<std::string> const & specialFunctions ) const;
|
||||||
void setVulkanLicenseHeader( int line, std::string const & comment );
|
void setVulkanLicenseHeader( int line, std::string const & comment );
|
||||||
std::string toString( TypeCategory category );
|
std::string toString( TypeCategory category );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user