Second step in generalizing handling of attribute "altLen" (#1529)

This commit is contained in:
Andreas Süßenbach 2023-03-13 09:08:01 +01:00 committed by GitHub
parent f4b679c7e7
commit aac3be4855
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 260 additions and 201 deletions

View File

@ -20,23 +20,23 @@
#include <regex> #include <regex>
#include <sstream> #include <sstream>
void checkAttributes( int line, void checkAttributes( int line,
std::map<std::string, std::string> const & attributes, std::map<std::string, std::string> const & attributes,
std::map<std::string, std::set<std::string>> const & required, std::map<std::string, std::set<std::string>> const & required,
std::map<std::string, std::set<std::string>> const & optional ); std::map<std::string, std::set<std::string>> const & optional );
void checkElements( int line, void checkElements( int line,
std::vector<tinyxml2::XMLElement const *> const & elements, std::vector<tinyxml2::XMLElement const *> const & elements,
std::map<std::string, bool> const & required, std::map<std::string, bool> const & required,
std::set<std::string> const & optional = {} ); std::set<std::string> const & optional = {} );
void checkForError( bool condition, int line, std::string const & message ); void checkForError( bool condition, int line, std::string const & message );
void checkForWarning( bool condition, int line, std::string const & message ); void checkForWarning( bool condition, int line, std::string const & message );
std::vector<std::string> filterConstants( std::vector<std::string> const & names ); std::vector<std::pair<std::string, size_t>> filterNumbers( std::vector<std::string> const & names );
std::string generateCArraySizes( std::vector<std::string> const & sizes ); std::string generateCArraySizes( std::vector<std::string> const & sizes );
std::string generateNamespacedType( std::string const & type ); std::string generateNamespacedType( std::string const & type );
std::string generateNoDiscard( bool returnsSomething, bool multiSuccessCodes, bool multiErrorCodes ); std::string generateNoDiscard( bool returnsSomething, bool multiSuccessCodes, bool multiErrorCodes );
std::string generateStandardArray( std::string const & type, std::vector<std::string> const & sizes ); std::string generateStandardArray( std::string const & type, std::vector<std::string> const & sizes );
std::string generateStandardArrayWrapper( std::string const & type, std::vector<std::string> const & sizes ); std::string generateStandardArrayWrapper( std::string const & type, std::vector<std::string> const & sizes );
std::map<std::string, std::string> getAttributes( tinyxml2::XMLElement const * element ); std::map<std::string, std::string> getAttributes( tinyxml2::XMLElement const * element );
template <typename ElementContainer> template <typename ElementContainer>
std::vector<tinyxml2::XMLElement const *> getChildElements( ElementContainer const * element ); std::vector<tinyxml2::XMLElement const *> getChildElements( ElementContainer const * element );
bool isNumber( std::string const & name ); bool isNumber( std::string const & name );
@ -57,7 +57,6 @@ std::string trimEnd( std::string const & in
std::string trimStars( std::string const & input ); std::string trimStars( std::string const & input );
void writeToFile( std::string const & str, std::string const & fileName ); void writeToFile( std::string const & str, std::string const & fileName );
const std::set<std::string> altLens = { "2*VK_UUID_SIZE", "codeSize / 4", "(rasterizationSamples + 31) / 32" };
const std::set<std::string> specialPointerTypes = { "Display", "IDirectFB", "wl_display", "xcb_connection_t", "_screen_window" }; const std::set<std::string> specialPointerTypes = { "Display", "IDirectFB", "wl_display", "xcb_connection_t", "_screen_window" };
// //
@ -75,6 +74,7 @@ VulkanHppGenerator::VulkanHppGenerator( tinyxml2::XMLDocument const & document,
checkElements( line, elements, { { "registry", true } } ); checkElements( line, elements, { { "registry", true } } );
checkForError( elements.size() == 1, line, "encountered " + std::to_string( elements.size() ) + " elements named <registry> but only one is allowed" ); checkForError( elements.size() == 1, line, "encountered " + std::to_string( elements.size() ) + " elements named <registry> but only one is allowed" );
readRegistry( elements[0] ); readRegistry( elements[0] );
filterLenMembers();
checkCorrectness(); checkCorrectness();
handleRemovals(); handleRemovals();
@ -1558,7 +1558,7 @@ std::vector<std::map<std::string, VulkanHppGenerator::CommandData>::const_iterat
return true; return true;
}; };
return ( destructorParam.name == desctructorHandleParamIt->len ) || return ( destructorParam.name == desctructorHandleParamIt->lenExpression ) ||
( std::find_if( commandIt->second.params.begin(), commandIt->second.params.end(), isDestructorParamType ) != commandIt->second.params.end() ); ( std::find_if( commandIt->second.params.begin(), commandIt->second.params.end(), isDestructorParamType ) != commandIt->second.params.end() );
}; };
@ -1644,9 +1644,9 @@ std::set<size_t> VulkanHppGenerator::determineSkippedParams( std::vector<ParamDa
// skip the size parameters (get derived from an array), and a stride parameter // skip the size parameters (get derived from an array), and a stride parameter
for ( auto const & vpi : vectorParams ) for ( auto const & vpi : vectorParams )
{ {
assert( !params[vpi.first].len.empty() ); assert( !params[vpi.first].lenExpression.empty() );
if ( ( ( std::find_if( returnParams.begin(), returnParams.end(), [&vpi]( size_t rpi ) { return vpi.first == rpi; } ) == returnParams.end() ) && if ( ( ( std::find_if( returnParams.begin(), returnParams.end(), [&vpi]( size_t rpi ) { return vpi.first == rpi; } ) == returnParams.end() ) &&
isParam( params[vpi.first].len, params ) ) || isParam( params[vpi.first].lenExpression, params ) ) ||
( singular && params[vpi.second.lenParam].type.isValue() ) ) ( singular && params[vpi.second.lenParam].type.isValue() ) )
{ {
skippedParams.insert( vpi.second.lenParam ); skippedParams.insert( vpi.second.lenParam );
@ -1700,21 +1700,23 @@ std::map<size_t, VulkanHppGenerator::VectorParamData> VulkanHppGenerator::determ
// look for the parameters whose len equals the name of an other parameter // look for the parameters whose len equals the name of an other parameter
for ( size_t i = 0; i < params.size(); i++ ) for ( size_t i = 0; i < params.size(); i++ )
{ {
if ( !params[i].len.empty() && ( params[i].len != "null-terminated" ) ) if ( !params[i].lenExpression.empty() && ( params[i].lenExpression != "null-terminated" ) )
{ {
VectorParamData & vpd = vectorParams[i]; VectorParamData & vpd = vectorParams[i];
if ( !params[i].lenParams.empty() ) if ( params[i].lenParams.empty() )
{
std::string len = params[i].lenExpression;
assert( std::find_if( params.begin(), params.end(), [&len]( auto const & pd ) { return ( len == pd.name ); } ) == params.end() );
auto lenIt = std::find_if( params.begin(), params.end(), [this, &len]( auto const & pd ) { return isLenByStructMember( len, pd ); } );
assert( lenIt != params.end() );
vpd.lenParam = std::distance( params.begin(), lenIt );
}
else
{ {
assert( params[i].lenParams.size() == 1 ); assert( params[i].lenParams.size() == 1 );
assert( params[i].len == "(" + params[i].lenParams[0] + " + 31) / 32" ); vpd.lenParam = params[i].lenParams[0].second;
} }
std::string len = params[i].lenParams.empty() ? params[i].len : params[i].lenParams[0];
auto lenIt =
std::find_if( params.begin(), params.end(), [&len, this]( auto const & pd ) { return ( len == pd.name ) || isLenByStructMember( len, pd ); } );
assert( lenIt != params.end() );
vpd.lenParam = std::distance( params.begin(), lenIt );
if ( !params[i].stride.empty() ) if ( !params[i].stride.empty() )
{ {
std::string const & stride = params[i].stride; std::string const & stride = params[i].stride;
@ -1783,6 +1785,31 @@ void VulkanHppGenerator::distributeSecondLevelCommands( std::set<std::string> co
} }
} }
void VulkanHppGenerator::filterLenMembers()
{
for ( auto & sd : m_structs )
{
for ( auto & member : sd.second.members )
{
std::erase_if( member.lenMembers,
[this]( std::pair<std::string, size_t> const & nameIndex ) { return m_constants.find( nameIndex.first ) != m_constants.end(); } );
for ( auto & lenMember : member.lenMembers )
{
if ( lenMember.second == size_t( ~0 ) )
{
auto lenMemberIt = findStructMemberIt( lenMember.first, sd.second.members );
checkForError( lenMemberIt != sd.second.members.end(),
member.xmlLine,
"struct member <" + member.name + "> uses unknown len member <" + lenMember.first + "> in its \"altlen\" attribute <" +
member.lenExpressions[0] + ">" );
lenMember.second = std::distance( sd.second.members.cbegin(), lenMemberIt );
}
}
}
}
}
std::map<std::string, VulkanHppGenerator::AliasData>::const_iterator VulkanHppGenerator::findAlias( std::string const & name, std::map<std::string, VulkanHppGenerator::AliasData>::const_iterator VulkanHppGenerator::findAlias( std::string const & name,
std::map<std::string, AliasData> const & aliases ) const std::map<std::string, AliasData> const & aliases ) const
{ {
@ -1809,6 +1836,12 @@ std::vector<VulkanHppGenerator::FeatureData>::const_iterator VulkanHppGenerator:
return std::find_if( m_features.begin(), m_features.end(), [&name]( FeatureData const & fd ) { return fd.name == name; } ); return std::find_if( m_features.begin(), m_features.end(), [&name]( FeatureData const & fd ) { return fd.name == name; } );
} }
std::vector<VulkanHppGenerator::ParamData>::const_iterator VulkanHppGenerator::findParamIt( std::string const & name,
std::vector<ParamData> const & paramData ) const
{
return std::find_if( paramData.begin(), paramData.end(), [&name]( ParamData const & pd ) { return pd.name == name; } );
}
std::vector<VulkanHppGenerator::MemberData>::const_iterator VulkanHppGenerator::findStructMemberIt( std::string const & name, std::vector<VulkanHppGenerator::MemberData>::const_iterator VulkanHppGenerator::findStructMemberIt( std::string const & name,
std::vector<MemberData> const & memberData ) const std::vector<MemberData> const & memberData ) const
{ {
@ -1911,7 +1944,7 @@ std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector<ParamD
if ( singularParams.find( i ) != singularParams.end() ) if ( singularParams.find( i ) != singularParams.end() )
{ {
assert( !params[i].optional ); assert( !params[i].optional );
assert( params[i].type.isConstPointer() && !params[i].len.empty() && !isLenByStructMember( params[i].len, params ) && assert( params[i].type.isConstPointer() && !params[i].lenExpression.empty() && !isLenByStructMember( params[i].lenExpression, params ) &&
params[i].type.type.starts_with( "Vk" ) ); params[i].type.type.starts_with( "Vk" ) );
assert( !isHandleType( params[i].type.type ) ); assert( !isHandleType( params[i].type.type ) );
assert( composedType.ends_with( " *" ) ); assert( composedType.ends_with( " *" ) );
@ -1921,7 +1954,7 @@ std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector<ParamD
{ {
assert( composedType.ends_with( " *" ) ); assert( composedType.ends_with( " *" ) );
std::string name = startLowerCase( stripPrefix( params[i].name, "p" ) ); std::string name = startLowerCase( stripPrefix( params[i].name, "p" ) );
if ( params[i].len.empty() ) if ( params[i].lenExpression.empty() )
{ {
assert( withDispatcher || !isHandleType( params[i].type.type ) ); assert( withDispatcher || !isHandleType( params[i].type.type ) );
assert( !params[i].type.prefix.empty() && ( params[i].type.postfix == "*" ) ); assert( !params[i].type.prefix.empty() && ( params[i].type.postfix == "*" ) );
@ -1947,7 +1980,7 @@ std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector<ParamD
// a const-pointer with a non-empty len is either null-terminated (aka a string) or represented by an // a const-pointer with a non-empty len is either null-terminated (aka a string) or represented by an
// ArrayProxy // ArrayProxy
assert( params[i].arraySizes.empty() ); assert( params[i].arraySizes.empty() );
if ( params[i].len == "null-terminated" ) if ( params[i].lenExpression == "null-terminated" )
{ {
assert( params[i].type.type == "char" ); assert( params[i].type.type == "char" );
if ( params[i].optional ) if ( params[i].optional )
@ -1984,7 +2017,7 @@ std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector<ParamD
else if ( params[i].type.isNonConstPointer() ) else if ( params[i].type.isNonConstPointer() )
{ {
assert( withDispatcher || !isHandleType( params[i].type.type ) ); assert( withDispatcher || !isHandleType( params[i].type.type ) );
assert( params[i].len.empty() && !params[i].optional ); assert( params[i].lenExpression.empty() && !params[i].optional );
assert( composedType.ends_with( " *" ) ); assert( composedType.ends_with( " *" ) );
argumentList += stripPostfix( composedType, " *" ) + " & " + params[i].name; argumentList += stripPostfix( composedType, " *" ) + " & " + params[i].name;
} }
@ -2012,7 +2045,7 @@ std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector<ParamD
{ {
for ( auto sp : skippedParams ) for ( auto sp : skippedParams )
{ {
if ( !params[sp].len.empty() ) if ( !params[sp].lenExpression.empty() )
{ {
if ( encounteredArgument ) if ( encounteredArgument )
{ {
@ -2306,7 +2339,7 @@ std::string VulkanHppGenerator::generateCallArgumentsEnhanced( CommandData const
{ {
case 1: case 1:
assert( isHandleType( commandData.params[0].type.type ) && commandData.params[0].type.isValue() ); assert( isHandleType( commandData.params[0].type.type ) && commandData.params[0].type.isValue() );
assert( commandData.params[0].arraySizes.empty() && commandData.params[0].len.empty() ); assert( commandData.params[0].arraySizes.empty() && commandData.params[0].lenExpression.empty() );
assert( commandData.params[0].type.type == commandData.handle ); assert( commandData.params[0].type.type == commandData.handle );
arguments = "static_cast<" + commandData.handle + ">( m_" + startLowerCase( stripPrefix( commandData.handle, "Vk" ) ) + " )"; arguments = "static_cast<" + commandData.handle + ">( m_" + startLowerCase( stripPrefix( commandData.handle, "Vk" ) ) + " )";
encounteredArgument = true; encounteredArgument = true;
@ -2314,13 +2347,13 @@ std::string VulkanHppGenerator::generateCallArgumentsEnhanced( CommandData const
case 2: case 2:
{ {
assert( isHandleType( commandData.params[0].type.type ) && commandData.params[0].type.isValue() ); assert( isHandleType( commandData.params[0].type.type ) && commandData.params[0].type.isValue() );
assert( commandData.params[0].arraySizes.empty() && commandData.params[0].len.empty() ); assert( commandData.params[0].arraySizes.empty() && commandData.params[0].lenExpression.empty() );
assert( commandData.params[0].type.type == commandData.handle ); assert( commandData.params[0].type.type == commandData.handle );
auto handleIt = m_handles.find( commandData.params[1].type.type ); auto handleIt = m_handles.find( commandData.params[1].type.type );
assert( handleIt != m_handles.end() ); assert( handleIt != m_handles.end() );
arguments = "static_cast<" + commandData.handle + ">( m_" + startLowerCase( stripPrefix( commandData.handle, "Vk" ) ) + " )"; arguments = "static_cast<" + commandData.handle + ">( m_" + startLowerCase( stripPrefix( commandData.handle, "Vk" ) ) + " )";
assert( commandData.params[1].type.isValue() && commandData.params[1].arraySizes.empty() && commandData.params[1].len.empty() ); assert( commandData.params[1].type.isValue() && commandData.params[1].arraySizes.empty() && commandData.params[1].lenExpression.empty() );
arguments += ", static_cast<" + commandData.params[1].type.type + ">( m_" + arguments += ", static_cast<" + commandData.params[1].type.type + ">( m_" +
generateRAIIHandleConstructorParamName( handleIt->first, handleIt->second.destructorIt ) + " )"; generateRAIIHandleConstructorParamName( handleIt->first, handleIt->second.destructorIt ) + " )";
encounteredArgument = true; encounteredArgument = true;
@ -2337,7 +2370,7 @@ std::string VulkanHppGenerator::generateCallArgumentsEnhanced( CommandData const
arguments += ", "; arguments += ", ";
} }
assert( isHandleType( commandData.params[i].type.type ) && commandData.params[i].type.isValue() ); assert( isHandleType( commandData.params[i].type.type ) && commandData.params[i].type.isValue() );
assert( commandData.params[i].arraySizes.empty() && commandData.params[i].len.empty() ); assert( commandData.params[i].arraySizes.empty() && commandData.params[i].lenExpression.empty() );
arguments += "m_" + startLowerCase( stripPrefix( commandData.params[i].type.type, "Vk" ) ); arguments += "m_" + startLowerCase( stripPrefix( commandData.params[i].type.type, "Vk" ) );
encounteredArgument = true; encounteredArgument = true;
} }
@ -2397,7 +2430,7 @@ std::string VulkanHppGenerator::generateCallArgumentsStandard( std::string const
} }
if ( ( param.type.type == handle ) && param.type.isValue() ) if ( ( param.type.type == handle ) && param.type.isValue() )
{ {
assert( param.arraySizes.empty() && param.len.empty() ); assert( param.arraySizes.empty() && param.lenExpression.empty() );
arguments += "m_" + startLowerCase( stripPrefix( param.type.type, "Vk" ) ); arguments += "m_" + startLowerCase( stripPrefix( param.type.type, "Vk" ) );
} }
else else
@ -2467,10 +2500,10 @@ std::string VulkanHppGenerator::generateCallArgumentEnhancedConstPointer( ParamD
assert( !param.optional ); assert( !param.optional );
// if at all, this is the first argument, and it's the implicitly provided member handle // if at all, this is the first argument, and it's the implicitly provided member handle
assert( paramIndex == 0 ); assert( paramIndex == 0 );
assert( param.arraySizes.empty() && param.len.empty() ); assert( param.arraySizes.empty() && param.lenExpression.empty() );
argument = "m_" + startLowerCase( stripPrefix( param.type.type, "Vk" ) ); argument = "m_" + startLowerCase( stripPrefix( param.type.type, "Vk" ) );
} }
else if ( param.len.empty() ) else if ( param.lenExpression.empty() )
{ {
// this const-pointer parameter has no length, that is it's a const-pointer to a single value // this const-pointer parameter has no length, that is it's a const-pointer to a single value
if ( param.type.type == "void" ) if ( param.type.type == "void" )
@ -2492,7 +2525,7 @@ std::string VulkanHppGenerator::generateCallArgumentEnhancedConstPointer( ParamD
argument = "reinterpret_cast<" + param.type.compose( "" ) + ">( " + argument + " )"; argument = "reinterpret_cast<" + param.type.compose( "" ) + ">( " + argument + " )";
} }
} }
else if ( param.len == "null-terminated" ) else if ( param.lenExpression == "null-terminated" )
{ {
// this const-pointer parameter is "null-terminated", that is it's a string // this const-pointer parameter is "null-terminated", that is it's a string
assert( ( param.type.type == "char" ) && param.arraySizes.empty() ); assert( ( param.type.type == "char" ) && param.arraySizes.empty() );
@ -2533,7 +2566,7 @@ std::string VulkanHppGenerator::generateCallArgumentEnhancedNonConstPointer( Par
{ {
std::string argument; std::string argument;
std::string name = startLowerCase( stripPrefix( param.name, "p" ) ); std::string name = startLowerCase( stripPrefix( param.name, "p" ) );
if ( param.len.empty() ) if ( param.lenExpression.empty() )
{ {
assert( param.arraySizes.empty() ); assert( param.arraySizes.empty() );
if ( param.type.type.starts_with( "Vk" ) ) if ( param.type.type.starts_with( "Vk" ) )
@ -2548,7 +2581,7 @@ std::string VulkanHppGenerator::generateCallArgumentEnhancedNonConstPointer( Par
} }
else else
{ {
// the non-const pointer has a len -> it will be represented by some array // the non-const pointer has a lenExpression -> it will be represented by some array
assert( param.arraySizes.empty() ); assert( param.arraySizes.empty() );
if ( nonConstPointerAsNullptr ) if ( nonConstPointerAsNullptr )
{ {
@ -2580,12 +2613,12 @@ std::string VulkanHppGenerator::generateCallArgumentEnhancedValue( std::vector<P
{ {
std::string argument; std::string argument;
ParamData const & param = params[paramIndex]; ParamData const & param = params[paramIndex];
assert( param.len.empty() ); assert( param.lenExpression.empty() );
if ( param.type.type.starts_with( "Vk" ) ) if ( param.type.type.starts_with( "Vk" ) )
{ {
if ( param.arraySizes.empty() ) if ( param.arraySizes.empty() )
{ {
auto pointerIt = std::find_if( params.begin(), params.end(), [&param]( ParamData const & pd ) { return pd.len == param.name; } ); auto pointerIt = std::find_if( params.begin(), params.end(), [&param]( ParamData const & pd ) { return pd.lenExpression == param.name; } );
if ( pointerIt != params.end() ) if ( pointerIt != params.end() )
{ {
assert( !param.optional ); assert( !param.optional );
@ -2611,7 +2644,7 @@ std::string VulkanHppGenerator::generateCallArgumentEnhancedValue( std::vector<P
} }
else else
{ {
auto pointerIt = std::find_if( params.begin(), params.end(), [&param]( ParamData const & pd ) { return pd.len == param.name; } ); auto pointerIt = std::find_if( params.begin(), params.end(), [&param]( ParamData const & pd ) { return pd.lenExpression == param.name; } );
if ( pointerIt != params.end() ) if ( pointerIt != params.end() )
{ {
// this parameter is the len of some other -> replace it with that parameter's size // this parameter is the len of some other -> replace it with that parameter's size
@ -2982,7 +3015,7 @@ std::string VulkanHppGenerator::generateCommandEnhanced( std::string const &
std::set<size_t> templatedParams = ( name == "vkGetMemoryHostPointerPropertiesEXT" ) ? std::set<size_t>() : determineVoidPointerParams( commandData.params ); std::set<size_t> templatedParams = ( name == "vkGetMemoryHostPointerPropertiesEXT" ) ? std::set<size_t>() : determineVoidPointerParams( commandData.params );
std::set<size_t> singularParams = singular ? determineSingularParams( returnParams[0], vectorParams ) : std::set<size_t>(); std::set<size_t> singularParams = singular ? determineSingularParams( returnParams[0], vectorParams ) : std::set<size_t>();
std::pair<bool, std::map<size_t, std::vector<size_t>>> vectorSizeCheck = std::pair<bool, std::map<size_t, std::vector<size_t>>> vectorSizeCheck =
needsVectorSizeCheck( commandData.params, vectorParams, returnParams, singularParams ); needsVectorSizeCheck( commandData.params, vectorParams, returnParams, singularParams, skippedParams );
bool enumerating = determineEnumeration( vectorParams, returnParams ); bool enumerating = determineEnumeration( vectorParams, returnParams );
std::vector<std::string> dataTypes = determineDataTypes( commandData.params, vectorParams, returnParams, templatedParams ); std::vector<std::string> dataTypes = determineDataTypes( commandData.params, vectorParams, returnParams, templatedParams );
@ -3700,7 +3733,7 @@ std::string VulkanHppGenerator::generateCommandResultSingleSuccessWithErrors1Ret
case 1: case 1:
if ( returnParam == vectorParams.begin()->first ) if ( returnParam == vectorParams.begin()->first )
{ {
if ( isLenByStructMember( commandData.params[vectorParams.begin()->first].len, commandData.params[vectorParams.begin()->second.lenParam] ) ) if ( isLenByStructMember( commandData.params[vectorParams.begin()->first].lenExpression, commandData.params[vectorParams.begin()->second.lenParam] ) )
{ {
return generateCommandSetInclusive( name, return generateCommandSetInclusive( name,
commandData, commandData,
@ -4297,7 +4330,8 @@ std::string VulkanHppGenerator::generateCommandVoid1Return(
!isStructureChainAnchor( commandData.params[vectorParams.begin()->first].type.type ) && !isStructureChainAnchor( commandData.params[vectorParams.begin()->first].type.type ) &&
( commandData.params[vectorParams.begin()->first].type.type != "void" ) ) ( commandData.params[vectorParams.begin()->first].type.type != "void" ) )
{ {
if ( isLenByStructMember( commandData.params[vectorParams.begin()->first].len, commandData.params[vectorParams.begin()->second.lenParam] ) ) if ( isLenByStructMember( commandData.params[vectorParams.begin()->first].lenExpression,
commandData.params[vectorParams.begin()->second.lenParam] ) )
{ {
return generateCommandSetInclusive( name, return generateCommandSetInclusive( name,
commandData, commandData,
@ -4767,7 +4801,7 @@ std::string VulkanHppGenerator::generateDataPreparation( CommandData const &
assert( !enumerating ); assert( !enumerating );
std::string className = initialSkipCount ? stripPrefix( commandData.params[initialSkipCount - 1].type.type, "Vk" ) : ""; std::string className = initialSkipCount ? stripPrefix( commandData.params[initialSkipCount - 1].type.type, "Vk" ) : "";
std::string deleterDefinition; std::string deleterDefinition;
std::vector<std::string> lenParts = tokenize( commandData.params[returnParams[0]].len, "->" ); std::vector<std::string> lenParts = tokenize( commandData.params[returnParams[0]].lenExpression, "->" );
switch ( lenParts.size() ) switch ( lenParts.size() )
{ {
case 1: deleterDefinition = "ObjectDestroy<" + className + ", Dispatch> deleter( *this, allocator, d )"; break; case 1: deleterDefinition = "ObjectDestroy<" + className + ", Dispatch> deleter( *this, allocator, d )"; break;
@ -6331,14 +6365,15 @@ std::string VulkanHppGenerator::generateLenInitializer(
else else
{ {
auto arrayIt = litit->second.front(); auto arrayIt = litit->second.front();
assert( ( arrayIt->len.front() == litit->first->name ) || ( ( arrayIt->len.front() == "codeSize / 4" ) && ( litit->first->name == "codeSize" ) ) ); assert( ( arrayIt->lenExpressions.front() == litit->first->name ) ||
( ( arrayIt->lenExpressions.front() == "codeSize / 4" ) && ( litit->first->name == "codeSize" ) ) );
assert( arrayIt->name.starts_with( "p" ) ); assert( arrayIt->name.starts_with( "p" ) );
std::string argumentName = startLowerCase( stripPrefix( arrayIt->name, "p" ) ) + "_"; std::string argumentName = startLowerCase( stripPrefix( arrayIt->name, "p" ) ) + "_";
assert( mit->type.prefix.empty() && mit->type.postfix.empty() ); assert( mit->type.prefix.empty() && mit->type.postfix.empty() );
initializer = argumentName + ".size()"; initializer = argumentName + ".size()";
if ( arrayIt->len.front() == "codeSize / 4" ) if ( arrayIt->lenExpressions.front() == "codeSize / 4" )
{ {
initializer += " * 4"; initializer += " * 4";
} }
@ -6876,7 +6911,7 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandEnhanced( std::string c
std::string nodiscard = generateNoDiscard( std::string nodiscard = generateNoDiscard(
!returnParams.empty() || ( ( commandData.returnType != "VkResult" ) && ( commandData.returnType != "void" ) ), 1 < commandData.successCodes.size(), false ); !returnParams.empty() || ( ( commandData.returnType != "VkResult" ) && ( commandData.returnType != "void" ) ), 1 < commandData.successCodes.size(), false );
std::pair<bool, std::map<size_t, std::vector<size_t>>> vectorSizeCheck = std::pair<bool, std::map<size_t, std::vector<size_t>>> vectorSizeCheck =
needsVectorSizeCheck( commandData.params, vectorParams, returnParams, singularParams ); needsVectorSizeCheck( commandData.params, vectorParams, returnParams, singularParams, skippedParams );
std::string noexceptString = generateNoExcept( commandData.errorCodes, returnParams, vectorParams, flavourFlags, vectorSizeCheck.first, true ); std::string noexceptString = generateNoExcept( commandData.errorCodes, returnParams, vectorParams, flavourFlags, vectorSizeCheck.first, true );
std::string returnType = generateReturnType( commandData, returnParams, vectorParams, flavourFlags, true, dataType ); std::string returnType = generateReturnType( commandData, returnParams, vectorParams, flavourFlags, true, dataType );
@ -7129,10 +7164,10 @@ std::string VulkanHppGenerator::generateRAIIHandleConstructorArgument( ParamData
std::string argumentType = generateNamespacedType( param.type.type ); std::string argumentType = generateNamespacedType( param.type.type );
if ( param.optional ) if ( param.optional )
{ {
assert( param.len.empty() ); assert( param.lenExpression.empty() );
argument = "VULKAN_HPP_NAMESPACE::Optional<const " + argumentType + "> " + argumentName + ( definition ? "" : " = nullptr" ); argument = "VULKAN_HPP_NAMESPACE::Optional<const " + argumentType + "> " + argumentName + ( definition ? "" : " = nullptr" );
} }
else if ( param.len.empty() ) else if ( param.lenExpression.empty() )
{ {
argument = argumentType + " const & " + argumentName; argument = argumentType + " const & " + argumentName;
} }
@ -7217,17 +7252,17 @@ std::string VulkanHppGenerator::generateRAIIHandleConstructorArguments( std::pai
constructorIt->second.params.end(), constructorIt->second.params.end(),
[&handle]( ParamData const & pd ) { return pd.type.type == handle.first; } ); [&handle]( ParamData const & pd ) { return pd.type.type == handle.first; } );
assert( typeIt != constructorIt->second.params.end() ); assert( typeIt != constructorIt->second.params.end() );
assert( typeIt->len == param.name ); assert( typeIt->lenExpression == param.name );
#endif #endif
continue; continue;
} }
else if ( std::find_if( constructorIt->second.params.begin(), else if ( std::find_if( constructorIt->second.params.begin(),
constructorIt->second.params.end(), constructorIt->second.params.end(),
[&param]( ParamData const & pd ) { return pd.len == param.name; } ) != constructorIt->second.params.end() ) [&param]( ParamData const & pd ) { return pd.lenExpression == param.name; } ) != constructorIt->second.params.end() )
{ {
// this is the len of an other parameter, which will be mapped to an ArrayProxy // this is the len of an other parameter, which will be mapped to an ArrayProxy
assert( param.type.isValue() && ( param.type.type == "uint32_t" ) ); assert( param.type.isValue() && ( param.type.type == "uint32_t" ) );
assert( param.arraySizes.empty() && param.len.empty() && !param.optional ); assert( param.arraySizes.empty() && param.lenExpression.empty() && !param.optional );
continue; continue;
} }
arguments += ", " + generateRAIIHandleConstructorArgument( param, false, singular, takesOwnership ); arguments += ", " + generateRAIIHandleConstructorArgument( param, false, singular, takesOwnership );
@ -7266,10 +7301,10 @@ std::string
if ( param.type.type == handle.first ) if ( param.type.type == handle.first )
{ {
assert( param.type.isNonConstPointer() && param.arraySizes.empty() ); assert( param.type.isNonConstPointer() && param.arraySizes.empty() );
if ( param.len.empty() || !singularParams.empty() ) if ( param.lenExpression.empty() || !singularParams.empty() )
{ {
assert( !param.optional ); assert( !param.optional );
assert( singularParams.empty() || ( param.len == constructorIt->second.params[*singularParams.begin()].name ) ); assert( singularParams.empty() || ( param.lenExpression == constructorIt->second.params[*singularParams.begin()].name ) );
std::string paramName = generateRAIIHandleConstructorParamName( handle.first, handle.second.destructorIt ); std::string paramName = generateRAIIHandleConstructorParamName( handle.first, handle.second.destructorIt );
arguments += "reinterpret_cast<" + handle.first + "*>( &m_" + paramName + " )"; arguments += "reinterpret_cast<" + handle.first + "*>( &m_" + paramName + " )";
} }
@ -7296,7 +7331,7 @@ std::string
} }
else if ( m_handles.find( param.type.type ) != m_handles.end() ) else if ( m_handles.find( param.type.type ) != m_handles.end() )
{ {
assert( param.type.isValue() && param.arraySizes.empty() && param.len.empty() ); assert( param.type.isValue() && param.arraySizes.empty() && param.lenExpression.empty() );
if ( param.optional ) if ( param.optional )
{ {
arguments += param.name + " ? static_cast<" + param.type.type + ">( **" + param.name + " ) : 0"; arguments += param.name + " ? static_cast<" + param.type.type + ">( **" + param.name + " ) : 0";
@ -7406,19 +7441,20 @@ std::string
} }
else if ( destructorParam.type.type == "VkAllocationCallbacks" ) else if ( destructorParam.type.type == "VkAllocationCallbacks" )
{ {
assert( destructorParam.type.isConstPointer() && destructorParam.arraySizes.empty() && destructorParam.len.empty() && destructorParam.optional ); assert( destructorParam.type.isConstPointer() && destructorParam.arraySizes.empty() && destructorParam.lenExpression.empty() &&
destructorParam.optional );
initializationList += "m_allocator( static_cast<const VULKAN_HPP_NAMESPACE::AllocationCallbacks *>( allocator ) ), "; initializationList += "m_allocator( static_cast<const VULKAN_HPP_NAMESPACE::AllocationCallbacks *>( allocator ) ), ";
} }
else if ( isHandleType( destructorParam.type.type ) ) else if ( isHandleType( destructorParam.type.type ) )
{ {
assert( destructorParam.type.isValue() && destructorParam.arraySizes.empty() && destructorParam.len.empty() && !destructorParam.optional ); assert( destructorParam.type.isValue() && destructorParam.arraySizes.empty() && destructorParam.lenExpression.empty() && !destructorParam.optional );
initializationList += "m_" + destructorParam.name + "( "; initializationList += "m_" + destructorParam.name + "( ";
auto constructorParamIt = std::find_if( constructorIt->second.params.begin(), auto constructorParamIt = std::find_if( constructorIt->second.params.begin(),
constructorIt->second.params.end(), constructorIt->second.params.end(),
[&destructorParam]( ParamData const & pd ) { return pd.type.type == destructorParam.type.type; } ); [&destructorParam]( ParamData const & pd ) { return pd.type.type == destructorParam.type.type; } );
if ( constructorParamIt != constructorIt->second.params.end() ) if ( constructorParamIt != constructorIt->second.params.end() )
{ {
assert( constructorParamIt->type.isValue() && constructorParamIt->arraySizes.empty() && constructorParamIt->len.empty() && assert( constructorParamIt->type.isValue() && constructorParamIt->arraySizes.empty() && constructorParamIt->lenExpression.empty() &&
!constructorParamIt->optional ); !constructorParamIt->optional );
if ( constructorParamIt->type.type == "Vk" + parentType ) if ( constructorParamIt->type.type == "Vk" + parentType )
{ {
@ -7439,7 +7475,7 @@ std::string
auto structureMemberIt = findStructMemberItByType( destructorParam.type.type, structureIt->second.members ); auto structureMemberIt = findStructMemberItByType( destructorParam.type.type, structureIt->second.members );
if ( structureMemberIt != structureIt->second.members.end() ) if ( structureMemberIt != structureIt->second.members.end() )
{ {
assert( constructorParam.type.isConstPointer() && constructorParam.arraySizes.empty() && constructorParam.len.empty() && assert( constructorParam.type.isConstPointer() && constructorParam.arraySizes.empty() && constructorParam.lenExpression.empty() &&
!constructorParam.optional ); !constructorParam.optional );
initializationList += startLowerCase( stripPrefix( constructorParam.name, "p" ) ) + "." + structureMemberIt->name; initializationList += startLowerCase( stripPrefix( constructorParam.name, "p" ) ) + "." + structureMemberIt->name;
#if !defined( NDEBUG ) #if !defined( NDEBUG )
@ -7536,7 +7572,7 @@ std::pair<std::string, std::string> VulkanHppGenerator::generateRAIIHandleConstr
case 1: case 1:
if ( returnParams[0] == vectorParams.begin()->first ) if ( returnParams[0] == vectorParams.begin()->first )
{ {
if ( isLenByStructMember( constructorIt->second.params[vectorParams.begin()->first].len, if ( isLenByStructMember( constructorIt->second.params[vectorParams.begin()->first].lenExpression,
constructorIt->second.params[vectorParams.begin()->second.lenParam] ) ) constructorIt->second.params[vectorParams.begin()->second.lenParam] ) )
{ {
auto handleParamIt = constructorIt->second.params.begin() + returnParams[0]; auto handleParamIt = constructorIt->second.params.begin() + returnParams[0];
@ -7726,10 +7762,10 @@ std::string VulkanHppGenerator::generateRAIIHandleConstructorVector( std::pair<s
std::string vectorSize; std::string vectorSize;
auto lenIt = std::find_if( constructorIt->second.params.begin(), auto lenIt = std::find_if( constructorIt->second.params.begin(),
constructorIt->second.params.end(), constructorIt->second.params.end(),
[&handleParamIt]( ParamData const & pd ) { return pd.name == handleParamIt->len; } ); [&handleParamIt]( ParamData const & pd ) { return pd.name == handleParamIt->lenExpression; } );
if ( lenIt == constructorIt->second.params.end() ) if ( lenIt == constructorIt->second.params.end() )
{ {
std::vector<std::string> lenParts = tokenize( handleParamIt->len, "->" ); std::vector<std::string> lenParts = tokenize( handleParamIt->lenExpression, "->" );
assert( lenParts.size() == 2 ); assert( lenParts.size() == 2 );
lenIt = std::find_if( lenIt = std::find_if(
constructorIt->second.params.begin(), constructorIt->second.params.end(), [&lenParts]( ParamData const & pd ) { return pd.name == lenParts[0]; } ); constructorIt->second.params.begin(), constructorIt->second.params.end(), [&lenParts]( ParamData const & pd ) { return pd.name == lenParts[0]; } );
@ -7744,9 +7780,10 @@ std::string VulkanHppGenerator::generateRAIIHandleConstructorVector( std::pair<s
} }
else else
{ {
auto arrayIt = std::find_if( constructorIt->second.params.begin(), auto arrayIt =
constructorIt->second.params.end(), std::find_if( constructorIt->second.params.begin(),
[&lenIt, &handleParamIt]( ParamData const & pd ) { return ( pd.len == lenIt->name ) && ( pd.name != handleParamIt->name ); } ); constructorIt->second.params.end(),
[&lenIt, &handleParamIt]( ParamData const & pd ) { return ( pd.lenExpression == lenIt->name ) && ( pd.name != handleParamIt->name ); } );
assert( arrayIt != constructorIt->second.params.end() ); assert( arrayIt != constructorIt->second.params.end() );
vectorSize = startLowerCase( stripPrefix( arrayIt->name, "p" ) ) + ".size()"; vectorSize = startLowerCase( stripPrefix( arrayIt->name, "p" ) ) + ".size()";
} }
@ -7997,19 +8034,19 @@ std::string VulkanHppGenerator::generateRAIIHandleDestructorCallArguments( std::
else else
{ {
assert( param.type.isConstPointer() ); assert( param.type.isConstPointer() );
assert( !param.len.empty() && assert( !param.lenExpression.empty() &&
( std::find_if( destructorIt->second.params.begin(), ( std::find_if( destructorIt->second.params.begin(),
destructorIt->second.params.end(), destructorIt->second.params.end(),
[&param]( ParamData const & pd ) { return pd.name == param.len; } ) != destructorIt->second.params.end() ) ); [&param]( ParamData const & pd ) { return pd.name == param.lenExpression; } ) != destructorIt->second.params.end() ) );
arguments += "reinterpret_cast<" + param.type.type + " const *>( &" + argument + " )"; arguments += "reinterpret_cast<" + param.type.type + " const *>( &" + argument + " )";
} }
} }
else else
{ {
assert( ( param.type.type == "uint32_t" ) && param.type.isValue() && param.arraySizes.empty() && param.len.empty() && !param.optional ); assert( ( param.type.type == "uint32_t" ) && param.type.isValue() && param.arraySizes.empty() && param.lenExpression.empty() && !param.optional );
assert( std::find_if( destructorIt->second.params.begin(), assert( std::find_if( destructorIt->second.params.begin(),
destructorIt->second.params.end(), destructorIt->second.params.end(),
[&param]( ParamData const & pd ) { return pd.len == param.name; } ) != destructorIt->second.params.end() ); [&param]( ParamData const & pd ) { return pd.lenExpression == param.name; } ) != destructorIt->second.params.end() );
arguments += "1"; arguments += "1";
} }
encounteredArgument = true; encounteredArgument = true;
@ -8063,7 +8100,7 @@ std::tuple<std::string, std::string, std::string, std::string, std::string, std:
else if ( std::find_if( handle.second.destructorIt->second.params.begin(), else if ( std::find_if( handle.second.destructorIt->second.params.begin(),
handle.second.destructorIt->second.params.end(), handle.second.destructorIt->second.params.end(),
[&destructorParam]( ParamData const & pd ) [&destructorParam]( ParamData const & pd )
{ return pd.len == destructorParam.name; } ) == handle.second.destructorIt->second.params.end() ) { return pd.lenExpression == destructorParam.name; } ) == handle.second.destructorIt->second.params.end() )
{ {
std::string name = destructorParam.name; std::string name = destructorParam.name;
if ( !destructorParam.type.isValue() ) if ( !destructorParam.type.isValue() )
@ -8238,7 +8275,7 @@ std::string VulkanHppGenerator::generateRAIIHandleSingularConstructorArguments(
( std::find_if( handle.second.destructorIt->second.params.begin(), ( std::find_if( handle.second.destructorIt->second.params.begin(),
handle.second.destructorIt->second.params.end(), handle.second.destructorIt->second.params.end(),
[&destructorParam]( ParamData const & pd ) [&destructorParam]( ParamData const & pd )
{ return pd.len == destructorParam.name; } ) == handle.second.destructorIt->second.params.end() ) ) { return pd.lenExpression == destructorParam.name; } ) == handle.second.destructorIt->second.params.end() ) )
{ {
if ( std::find_if( constructorIt->second.params.begin(), if ( std::find_if( constructorIt->second.params.begin(),
constructorIt->second.params.end(), constructorIt->second.params.end(),
@ -8326,18 +8363,24 @@ std::string VulkanHppGenerator::generateRAIIHandleVectorSizeCheck( std::string c
if ( cvm.second.size() == 1 ) if ( cvm.second.size() == 1 )
{ {
std::string sizeValue; std::string sizeValue;
if ( isLenByStructMember( commandData.params[cvm.second[0]].len, commandData.params[cvm.first] ) ) if ( isLenByStructMember( commandData.params[cvm.second[0]].lenExpression, commandData.params[cvm.first] ) )
{ {
std::vector<std::string> lenParts = tokenize( commandData.params[cvm.second[0]].len, "->" ); std::vector<std::string> lenParts = tokenize( commandData.params[cvm.second[0]].lenExpression, "->" );
assert( lenParts.size() == 2 ); assert( lenParts.size() == 2 );
sizeValue = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + lenParts[1]; sizeValue = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + lenParts[1];
} }
else else
{ {
assert( !commandData.params[cvm.second[0]].lenParams.empty() ); assert( !commandData.params[cvm.second[0]].lenParams.empty() );
assert( commandData.params[cvm.second[0]].len == "(" + commandData.params[cvm.second[0]].lenParams[0] + " + 31) / 32" ); if ( commandData.params[cvm.first].type.type == "VkSampleCountFlagBits" )
assert( commandData.params[cvm.first].type.type == "VkSampleCountFlagBits" ); {
sizeValue = "( static_cast<uint32_t>( " + commandData.params[cvm.second[0]].lenParams[0] + " ) + 31 ) / 32"; assert( commandData.params[cvm.second[0]].lenExpression == "(" + commandData.params[cvm.second[0]].lenParams[0].first + " + 31) / 32" );
sizeValue = "( static_cast<uint32_t>( " + commandData.params[cvm.second[0]].lenParams[0].first + " ) + 31 ) / 32";
}
else
{
sizeValue = commandData.params[cvm.second[0]].lenExpression;
}
} }
sizeChecks += replaceWithMap( sizeChecks += replaceWithMap(
throwTemplateSingle, { { "className", className }, { "commandName", commandName }, { "sizeValue", sizeValue }, { "vectorName", firstVectorName } } ); throwTemplateSingle, { { "className", className }, { "commandName", commandName }, { "sizeValue", sizeValue }, { "vectorName", firstVectorName } } );
@ -8875,14 +8918,14 @@ std::string VulkanHppGenerator::generateStructCompareOperators( std::pair<std::s
spaceshipMembers += spaceshipMembers +=
replaceWithMap( spaceshipMemberTemplate, { { "name", member.name }, { "ordering", spaceshipOrdering }, { "type", member.type.type } } ); replaceWithMap( spaceshipMemberTemplate, { { "name", member.name }, { "ordering", spaceshipOrdering }, { "type", member.type.type } } );
} }
else if ( member.type.type == "char" && !member.len.empty() ) else if ( member.type.type == "char" && !member.lenExpressions.empty() )
{ {
// compare null-terminated strings // compare null-terminated strings
nonDefaultCompare = true; nonDefaultCompare = true;
assert( member.len.size() < 3 ); assert( member.lenExpressions.size() < 3 );
if ( member.len.size() == 1 ) if ( member.lenExpressions.size() == 1 )
{ {
assert( member.len[0] == "null-terminated" ); assert( member.lenExpressions[0] == "null-terminated" );
compareMembers += intro + "( ( " + member.name + " == rhs." + member.name + " ) || ( strcmp( " + member.name + ", rhs." + member.name + " ) == 0 ) )"; compareMembers += intro + "( ( " + member.name + " == rhs." + member.name + " ) || ( strcmp( " + member.name + ", rhs." + member.name + " ) == 0 ) )";
static const std::string spaceshipMemberTemplate = static const std::string spaceshipMemberTemplate =
@ -8894,11 +8937,11 @@ std::string VulkanHppGenerator::generateStructCompareOperators( std::pair<std::s
} }
else else
{ {
assert( member.len[1] == "null-terminated" ); assert( member.lenExpressions[1] == "null-terminated" );
assert( ( member.type.prefix == "const" ) && ( member.type.postfix == "* const *" ) ); assert( ( member.type.prefix == "const" ) && ( member.type.postfix == "* const *" ) );
static const std::string compareMemberTemplate = static const std::string compareMemberTemplate =
R"(std::equal( ${name}, ${name} + ${count}, rhs.${name}, []( char const * left, char const * right ) { return ( left == right ) || ( strcmp( left, right ) == 0 ); } ))"; R"(std::equal( ${name}, ${name} + ${count}, rhs.${name}, []( char const * left, char const * right ) { return ( left == right ) || ( strcmp( left, right ) == 0 ); } ))";
compareMembers += intro + replaceWithMap( compareMemberTemplate, { { "count", member.len[0] }, { "name", member.name } } ); compareMembers += intro + replaceWithMap( compareMemberTemplate, { { "count", member.lenExpressions[0] }, { "name", member.name } } );
static const std::string spaceshipMemberTemplate = R"( for ( size_t i = 0; i < ${count}; ++i ) static const std::string spaceshipMemberTemplate = R"( for ( size_t i = 0; i < ${count}; ++i )
{ {
@ -8908,7 +8951,7 @@ std::string VulkanHppGenerator::generateStructCompareOperators( std::pair<std::s
} }
)"; )";
spaceshipMembers += spaceshipMembers +=
replaceWithMap( spaceshipMemberTemplate, { { "count", member.len[0] }, { "name", member.name }, { "ordering", spaceshipOrdering } } ); replaceWithMap( spaceshipMemberTemplate, { { "count", member.lenExpressions[0] }, { "name", member.name }, { "ordering", spaceshipOrdering } } );
} }
} }
else else
@ -9039,17 +9082,16 @@ std::string VulkanHppGenerator::generateStructConstructors( std::pair<std::strin
std::string VulkanHppGenerator::generateStructConstructorsEnhanced( std::pair<std::string, StructureData> const & structData ) const std::string VulkanHppGenerator::generateStructConstructorsEnhanced( std::pair<std::string, StructureData> const & structData ) const
{ {
if ( std::find_if( structData.second.members.begin(), if ( std::find_if( structData.second.members.begin(), structData.second.members.end(), [this]( MemberData const & md ) { return hasLen( md ); } ) !=
structData.second.members.end(), structData.second.members.end() )
[this, &structData]( MemberData const & md ) { return hasLen( structData.second.members, md ); } ) != structData.second.members.end() )
{ {
// map from len-members to all the array members using that len // map from len-members to all the array members using that len
std::map<std::vector<MemberData>::const_iterator, std::vector<std::vector<MemberData>::const_iterator>> lenIts; std::map<std::vector<MemberData>::const_iterator, std::vector<std::vector<MemberData>::const_iterator>> lenIts;
for ( auto mit = structData.second.members.begin(); mit != structData.second.members.end(); ++mit ) for ( auto mit = structData.second.members.begin(); mit != structData.second.members.end(); ++mit )
{ {
if ( hasLen( structData.second.members, *mit ) ) if ( hasLen( *mit ) )
{ {
std::string lenName = ( mit->len.front() == "codeSize / 4" ) ? "codeSize" : mit->len.front(); std::string lenName = ( mit->lenExpressions.front() == "codeSize / 4" ) ? "codeSize" : mit->lenExpressions.front();
auto lenIt = findStructMemberIt( lenName, structData.second.members ); auto lenIt = findStructMemberIt( lenName, structData.second.members );
assert( lenIt != mit ); assert( lenIt != mit );
lenIts[lenIt].push_back( mit ); lenIts[lenIt].push_back( mit );
@ -9079,7 +9121,7 @@ std::string VulkanHppGenerator::generateStructConstructorsEnhanced( std::pair<st
( firstArgument ? ": " : ", " ) + mit->name + "( " + generateLenInitializer( mit, litit, structData.second.mutualExclusiveLens ) + " )"; ( firstArgument ? ": " : ", " ) + mit->name + "( " + generateLenInitializer( mit, litit, structData.second.mutualExclusiveLens ) + " )";
sizeChecks += generateSizeCheck( litit->second, stripPrefix( structData.first, "Vk" ), structData.second.mutualExclusiveLens ); sizeChecks += generateSizeCheck( litit->second, stripPrefix( structData.first, "Vk" ), structData.second.mutualExclusiveLens );
} }
else if ( hasLen( structData.second.members, *mit ) ) else if ( hasLen( *mit ) )
{ {
assert( mit->name.starts_with( "p" ) ); assert( mit->name.starts_with( "p" ) );
std::string argumentName = startLowerCase( stripPrefix( mit->name, "p" ) ) + "_"; std::string argumentName = startLowerCase( stripPrefix( mit->name, "p" ) ) + "_";
@ -9283,12 +9325,12 @@ std::string VulkanHppGenerator::generateStructHashSum( std::string const & struc
} }
hashSum += " }\n"; hashSum += " }\n";
} }
else if ( member.type.type == "char" && !member.len.empty() ) else if ( member.type.type == "char" && !member.lenExpressions.empty() )
{ {
assert( member.len.size() < 3 ); assert( member.lenExpressions.size() < 3 );
if ( member.len.size() == 1 ) if ( member.lenExpressions.size() == 1 )
{ {
assert( member.len[0] == "null-terminated" ); assert( member.lenExpressions[0] == "null-terminated" );
hashSum += " for ( const char* p = " + structName + "." + member.name + "; *p != '\\0'; ++p )\n"; hashSum += " for ( const char* p = " + structName + "." + member.name + "; *p != '\\0'; ++p )\n";
hashSum += " {\n"; hashSum += " {\n";
hashSum += " VULKAN_HPP_HASH_COMBINE( seed, *p );\n"; hashSum += " VULKAN_HPP_HASH_COMBINE( seed, *p );\n";
@ -9296,8 +9338,8 @@ std::string VulkanHppGenerator::generateStructHashSum( std::string const & struc
} }
else else
{ {
assert( member.len[1] == "null-terminated" ); assert( member.lenExpressions[1] == "null-terminated" );
hashSum += " for ( size_t i = 0; i < " + structName + "." + member.len[0] + "; ++i )\n"; hashSum += " for ( size_t i = 0; i < " + structName + "." + member.lenExpressions[0] + "; ++i )\n";
hashSum += " {\n"; hashSum += " {\n";
hashSum += " for ( const char* p = " + structName + "." + member.name + "[i]; *p != '\\0'; ++p )\n"; hashSum += " for ( const char* p = " + structName + "." + member.name + "[i]; *p != '\\0'; ++p )\n";
hashSum += " {\n"; hashSum += " {\n";
@ -9715,20 +9757,20 @@ std::string VulkanHppGenerator::generateStructSetter( std::string const & struct
{ "reference", ( member.type.postfix.empty() && ( m_structs.find( member.type.type ) != m_structs.end() ) ) ? "const & " : "" }, { "reference", ( member.type.postfix.empty() && ( m_structs.find( member.type.type ) != m_structs.end() ) ) ? "const & " : "" },
{ "structureName", structureName } } ); { "structureName", structureName } } );
if ( hasLen( memberData, member ) ) if ( hasLen( member ) )
{ {
assert( member.name.front() == 'p' ); assert( member.name.front() == 'p' );
std::string arrayName = startLowerCase( stripPrefix( member.name, "p" ) ); std::string arrayName = startLowerCase( stripPrefix( member.name, "p" ) );
std::string lenName, lenValue; std::string lenName, lenValue;
if ( member.len[0] == "codeSize / 4" ) if ( member.lenExpressions[0] == "codeSize / 4" )
{ {
lenName = "codeSize"; lenName = "codeSize";
lenValue = arrayName + "_.size() * 4"; lenValue = arrayName + "_.size() * 4";
} }
else else
{ {
lenName = member.len[0]; lenName = member.lenExpressions[0];
lenValue = arrayName + "_.size()"; lenValue = arrayName + "_.size()";
} }
@ -10224,18 +10266,24 @@ std::string VulkanHppGenerator::generateVectorSizeCheck( std::string const &
if ( cvm.second.size() == 1 ) if ( cvm.second.size() == 1 )
{ {
std::string sizeValue; std::string sizeValue;
if ( isLenByStructMember( commandData.params[cvm.second[0]].len, commandData.params[cvm.first] ) ) if ( isLenByStructMember( commandData.params[cvm.second[0]].lenExpression, commandData.params[cvm.first] ) )
{ {
std::vector<std::string> lenParts = tokenize( commandData.params[cvm.second[0]].len, "->" ); std::vector<std::string> lenParts = tokenize( commandData.params[cvm.second[0]].lenExpression, "->" );
assert( lenParts.size() == 2 ); assert( lenParts.size() == 2 );
sizeValue = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + lenParts[1]; sizeValue = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + lenParts[1];
} }
else else
{ {
assert( !commandData.params[cvm.second[0]].lenParams.empty() ); assert( !commandData.params[cvm.second[0]].lenParams.empty() );
assert( commandData.params[cvm.second[0]].len == "(" + commandData.params[cvm.second[0]].lenParams[0] + " + 31) / 32" ); if ( commandData.params[cvm.first].type.type == "VkSampleCountFlagBits" )
assert( commandData.params[cvm.first].type.type == "VkSampleCountFlagBits" ); {
sizeValue = "( static_cast<uint32_t>( " + commandData.params[cvm.second[0]].lenParams[0] + " ) + 31 ) / 32"; assert( commandData.params[cvm.second[0]].lenExpression == "(" + commandData.params[cvm.second[0]].lenParams[0].first + " + 31) / 32" );
sizeValue = "( static_cast<uint32_t>( " + commandData.params[cvm.second[0]].lenParams[0].first + " ) + 31 ) / 32";
}
else
{
sizeValue = commandData.params[cvm.second[0]].lenExpression;
}
} }
assertions += replaceWithMap( assertTemplateSingle, { { "sizeValue", sizeValue }, { "vectorName", firstVectorName } } ); assertions += replaceWithMap( assertTemplateSingle, { { "sizeValue", sizeValue }, { "vectorName", firstVectorName } } );
throws += replaceWithMap( throwTemplateSingle, throws += replaceWithMap( throwTemplateSingle,
@ -10406,7 +10454,7 @@ std::string VulkanHppGenerator::getVectorSize( std::vector<ParamData> const &
std::set<size_t> const & templatedParams ) const std::set<size_t> const & templatedParams ) const
{ {
std::string vectorSize; std::string vectorSize;
std::vector<std::string> lenParts = tokenize( params[returnParam].len, "->" ); std::vector<std::string> lenParts = tokenize( params[returnParam].lenExpression, "->" );
switch ( lenParts.size() ) switch ( lenParts.size() )
{ {
case 1: case 1:
@ -10592,14 +10640,11 @@ bool VulkanHppGenerator::handleRemovalType( std::string const & type, std::vecto
return removed; return removed;
} }
bool VulkanHppGenerator::hasLen( std::vector<MemberData> const & members, MemberData const & md ) const bool VulkanHppGenerator::hasLen( MemberData const & memberData ) const
{ {
if ( !md.len.empty() && !( md.len[0] == "null-terminated" ) && ( ( altLens.find( md.len[0] ) == altLens.end() ) || ( md.len[0] == "codeSize / 4" ) ) ) assert( memberData.lenMembers.size() <= memberData.lenExpressions.size() );
{ return !memberData.lenMembers.empty() && ( ( memberData.lenExpressions[0] == memberData.lenMembers[0].first ) ||
auto lenIt = findStructMemberIt( md.len.front(), members ); ( memberData.lenExpressions[0] == ( memberData.lenMembers[0].first + " / 4" ) ) );
return ( lenIt == members.end() ) || lenIt->type.isValue();
}
return false;
} }
bool VulkanHppGenerator::hasParentHandle( std::string const & handle, std::string const & parent ) const bool VulkanHppGenerator::hasParentHandle( std::string const & handle, std::string const & parent ) const
@ -10723,7 +10768,7 @@ bool VulkanHppGenerator::isMultiSuccessCodeConstructor( std::vector<std::map<std
bool VulkanHppGenerator::isParam( std::string const & name, std::vector<ParamData> const & params ) const bool VulkanHppGenerator::isParam( std::string const & name, std::vector<ParamData> const & params ) const
{ {
return std::find_if( params.begin(), params.end(), [&name]( ParamData const & pd ) { return pd.name == name; } ) != params.end(); return findParamIt( name, params ) != params.end();
} }
bool VulkanHppGenerator::isStructMember( std::string const & name, std::vector<MemberData> const & memberData ) const bool VulkanHppGenerator::isStructMember( std::string const & name, std::vector<MemberData> const & memberData ) const
@ -10823,23 +10868,29 @@ bool VulkanHppGenerator::isTypeUsed( std::string const & type ) const
std::pair<bool, std::map<size_t, std::vector<size_t>>> VulkanHppGenerator::needsVectorSizeCheck( std::vector<ParamData> const & params, std::pair<bool, std::map<size_t, std::vector<size_t>>> VulkanHppGenerator::needsVectorSizeCheck( std::vector<ParamData> const & params,
std::map<size_t, VectorParamData> const & vectorParams, std::map<size_t, VectorParamData> const & vectorParams,
std::vector<size_t> const & returnParams, std::vector<size_t> const & returnParams,
std::set<size_t> const & singularParams ) const std::set<size_t> const & singularParams,
std::set<size_t> const & skippedParams ) const
{ {
std::map<size_t, std::vector<size_t>> countToVectorMap; std::map<size_t, std::vector<size_t>> countToVectorMap;
for ( auto const & vpi : vectorParams ) for ( auto const & vpi : vectorParams )
{ {
if ( ( vpi.second.lenParam != INVALID_INDEX ) && ( std::find( returnParams.begin(), returnParams.end(), vpi.first ) == returnParams.end() ) && if ( ( vpi.second.lenParam != INVALID_INDEX ) && ( std::find( returnParams.begin(), returnParams.end(), vpi.first ) == returnParams.end() ) &&
( ( singularParams.find( vpi.second.lenParam ) == singularParams.end() ) || ( ( singularParams.find( vpi.second.lenParam ) == singularParams.end() ) ||
isLenByStructMember( params[vpi.first].len, params[vpi.second.lenParam] ) ) ) isLenByStructMember( params[vpi.first].lenExpression, params[vpi.second.lenParam] ) ) )
{ {
countToVectorMap[vpi.second.lenParam].push_back( vpi.first ); countToVectorMap[vpi.second.lenParam].push_back( vpi.first );
} }
} }
return std::make_pair( std::find_if( countToVectorMap.begin(), return std::make_pair( std::find_if( countToVectorMap.begin(),
countToVectorMap.end(), countToVectorMap.end(),
[this, &params]( auto const & cvm ) { [this, &params, &skippedParams]( auto const & cvm )
return ( 1 < cvm.second.size() ) || isLenByStructMember( params[cvm.second[0]].len, params[cvm.first] ) || {
!params[cvm.second[0]].lenParams.empty(); return ( 1 < cvm.second.size() ) || isLenByStructMember( params[cvm.second[0]].lenExpression, params[cvm.first] ) ||
( std::find_if( params[cvm.second[0]].lenParams.begin(),
params[cvm.second[0]].lenParams.end(),
[&skippedParams]( std::pair<std::string, size_t> const & lenParam ) {
return skippedParams.find( lenParam.second ) != skippedParams.end();
} ) == params[cvm.second[0]].lenParams.end() );
} ) != countToVectorMap.end(), } ) != countToVectorMap.end(),
countToVectorMap ); countToVectorMap );
} }
@ -10916,23 +10967,18 @@ void VulkanHppGenerator::readCommand( tinyxml2::XMLElement const * element )
} }
} }
std::for_each( commandData.params.begin(), for ( auto & param : commandData.params )
commandData.params.end(), {
[&commandData]( ParamData & currentParam ) for ( auto & lenParam : param.lenParams )
{ {
std::for_each( currentParam.lenParams.begin(), auto paramIt = findParamIt( lenParam.first, commandData.params );
currentParam.lenParams.end(), checkForError( paramIt != commandData.params.end(),
[&commandData, &currentParam]( std::string const & lenName ) param.xmlLine,
{ "param <" + param.name + "> uses unknown len parameter <" + lenParam.first + "> in its \"altlen\" attribute <" + param.lenExpression +
checkForError( std::find_if( commandData.params.begin(), ">" );
commandData.params.end(), lenParam.second = std::distance( commandData.params.cbegin(), paramIt );
[&lenName]( ParamData const & pd ) }
{ return pd.name == lenName; } ) != commandData.params.end(), }
currentParam.xmlLine,
"param <" + currentParam.name + "> uses unknown len parameter <" + lenName +
"> in its \"altlen\" attribute <" + currentParam.len + ">" );
} );
} );
assert( !name.empty() ); assert( !name.empty() );
checkForError( ( commandData.returnType == "VkResult" ) || commandData.errorCodes.empty(), checkForError( ( commandData.returnType == "VkResult" ) || commandData.errorCodes.empty(),
@ -10980,9 +11026,9 @@ std::pair<bool, VulkanHppGenerator::ParamData> VulkanHppGenerator::readCommandPa
{ {
if ( attribute.first == "altlen" ) if ( attribute.first == "altlen" )
{ {
assert( paramData.len.empty() ); assert( paramData.lenExpression.empty() );
paramData.len = attribute.second; paramData.lenExpression = attribute.second;
paramData.lenParams = filterConstants( tokenizeAny( attribute.second, " /()+" ) ); paramData.lenParams = filterNumbers( tokenizeAny( attribute.second, " /()+" ) );
} }
else if ( attribute.first == "api" ) else if ( attribute.first == "api" )
{ {
@ -10990,12 +11036,20 @@ std::pair<bool, VulkanHppGenerator::ParamData> VulkanHppGenerator::readCommandPa
} }
else if ( attribute.first == "len" ) else if ( attribute.first == "len" )
{ {
if ( paramData.len.empty() ) if ( paramData.lenExpression.empty() )
{ {
checkForError( ( attribute.second == "null-terminated" ) || isParam( attribute.second, params ) || isLenByStructMember( attribute.second, params ), paramData.lenExpression = attribute.second;
line, auto paramIt = findParamIt( attribute.second, params );
"attribute <len> holds an unknown value <" + attribute.second + ">" ); if ( paramIt != params.end() )
paramData.len = attribute.second; {
paramData.lenParams.push_back( { attribute.second, std::distance( params.cbegin(), paramIt ) } );
}
else
{
checkForError( ( attribute.second == "null-terminated" ) || isLenByStructMember( attribute.second, params ),
line,
"attribute <len> holds an unknown value <" + attribute.second + ">" );
}
} }
} }
else if ( attribute.first == "stride" ) else if ( attribute.first == "stride" )
@ -12322,10 +12376,12 @@ void VulkanHppGenerator::readStructMember( tinyxml2::XMLElement const * element,
} }
else if ( attribute.first == "altlen" ) else if ( attribute.first == "altlen" )
{ {
assert( memberData.len.empty() ); assert( memberData.lenExpressions.empty() );
memberData.len = tokenize( attribute.second, "," ); memberData.lenExpressions = tokenize( attribute.second, "," );
checkForError( memberData.len.size() == 1, line, "member attribute <altlen> holds unknown number of data: " + std::to_string( memberData.len.size() ) ); checkForError( memberData.lenExpressions.size() == 1,
checkForError( altLens.find( memberData.len[0] ) != altLens.end(), line, "member attribute <altlen> holds unknown value <" + memberData.len[0] + ">" ); line,
"member attribute <altlen> holds unknown number of data: " + std::to_string( memberData.lenExpressions.size() ) );
memberData.lenMembers = filterNumbers( tokenizeAny( attribute.second, " /()+*" ) );
} }
else if ( attribute.second == "deprecated" ) else if ( attribute.second == "deprecated" )
{ {
@ -12334,25 +12390,26 @@ void VulkanHppGenerator::readStructMember( tinyxml2::XMLElement const * element,
} }
else if ( attribute.first == "len" ) else if ( attribute.first == "len" )
{ {
if ( memberData.len.empty() ) if ( memberData.lenExpressions.empty() )
{ {
memberData.len = tokenize( attribute.second, "," ); memberData.lenExpressions = tokenize( attribute.second, "," );
checkForError( !memberData.len.empty() && ( memberData.len.size() <= 2 ), checkForError( !memberData.lenExpressions.empty() && ( memberData.lenExpressions.size() <= 2 ),
line, line,
"member attribute <len> holds unknown number of data: " + std::to_string( memberData.len.size() ) ); "member attribute <len> holds unknown number of data: " + std::to_string( memberData.lenExpressions.size() ) );
if ( memberData.len[0] != "null-terminated" ) if ( memberData.lenExpressions[0] != "null-terminated" )
{ {
auto lenMember = findStructMemberIt( memberData.len[0], members ); auto lenMemberIt = findStructMemberIt( memberData.lenExpressions[0], members );
checkForError( lenMember != members.end(), line, "member attribute <len> holds unknown value <" + memberData.len[0] + ">" ); checkForError( lenMemberIt != members.end(), line, "member attribute <len> holds unknown value <" + memberData.lenExpressions[0] + ">" );
checkForError( lenMember->type.prefix.empty(), checkForError( lenMemberIt->type.prefix.empty(),
line, line,
"member attribute <len> references a member of unexpected type <" + lenMember->type.compose( "VULKAN_HPP_NAMESPACE" ) + ">" ); "member attribute <len> references a member of unexpected type <" + lenMemberIt->type.compose( "VULKAN_HPP_NAMESPACE" ) + ">" );
memberData.lenMembers.push_back( { memberData.lenExpressions[0], std::distance( members.cbegin(), lenMemberIt ) } );
} }
if ( 1 < memberData.len.size() ) if ( 1 < memberData.lenExpressions.size() )
{ {
checkForError( ( memberData.len[1] == "1" ) || ( memberData.len[1] == "null-terminated" ), checkForError( ( memberData.lenExpressions[1] == "1" ) || ( memberData.lenExpressions[1] == "null-terminated" ),
line, line,
"member attribute <len> holds unknown second value <" + memberData.len[1] + ">" ); "member attribute <len> holds unknown second value <" + memberData.lenExpressions[1] + ">" );
} }
} }
} }
@ -12919,11 +12976,11 @@ void VulkanHppGenerator::readTypeStruct( tinyxml2::XMLElement const * element, b
bool warned = false; bool warned = false;
for ( auto m0It = it->second.members.begin(); !warned && ( m0It != it->second.members.end() ); ++m0It ) for ( auto m0It = it->second.members.begin(); !warned && ( m0It != it->second.members.end() ); ++m0It )
{ {
if ( !m0It->len.empty() && ( m0It->len.front() != "null-terminated" ) ) if ( !m0It->lenExpressions.empty() && ( m0It->lenExpressions.front() != "null-terminated" ) )
{ {
for ( auto m1It = std::next( m0It ); !warned && ( m1It != it->second.members.end() ); ++m1It ) for ( auto m1It = std::next( m0It ); !warned && ( m1It != it->second.members.end() ); ++m1It )
{ {
if ( !m1It->len.empty() && ( m0It->len.front() == m1It->len.front() ) ) if ( !m1It->lenExpressions.empty() && ( m0It->lenExpressions.front() == m1It->lenExpressions.front() ) )
{ {
if ( mutualExclusiveStructs.find( it->first ) != mutualExclusiveStructs.end() ) if ( mutualExclusiveStructs.find( it->first ) != mutualExclusiveStructs.end() )
{ {
@ -13337,18 +13394,16 @@ void checkForWarning( bool condition, int line, std::string const & message )
} }
} }
std::vector<std::string> filterConstants( std::vector<std::string> const & names ) std::vector<std::pair<std::string, size_t>> filterNumbers( std::vector<std::string> const & names )
{ {
std::vector<std::string> filteredNames; std::vector<std::pair<std::string, size_t>> filteredNames;
std::for_each( names.begin(), for ( auto const & name : names )
names.end(), {
[&filteredNames]( std::string const & name ) if ( !isNumber( name ) )
{ {
if ( !isNumber( name ) ) filteredNames.push_back( { name, ~0 } );
{ }
filteredNames.push_back( name ); }
}
} );
return filteredNames; return filteredNames;
} }

View File

@ -160,14 +160,14 @@ private:
{ {
ParamData( int line ) : optional( false ), xmlLine( line ) {} ParamData( int line ) : optional( false ), xmlLine( line ) {}
TypeInfo type; TypeInfo type;
std::string name; std::string name;
std::vector<std::string> arraySizes; std::vector<std::string> arraySizes;
std::string len; std::string lenExpression;
std::vector<std::string> lenParams; std::vector<std::pair<std::string, size_t>> lenParams;
bool optional; bool optional;
std::string stride; std::string stride;
int xmlLine; int xmlLine;
}; };
struct CommandData struct CommandData
@ -344,18 +344,19 @@ private:
{ {
MemberData( int line ) : xmlLine( line ) {} MemberData( int line ) : xmlLine( line ) {}
TypeInfo type; TypeInfo type;
std::string name; std::string name;
std::vector<std::string> arraySizes; std::vector<std::string> arraySizes;
std::string bitCount; std::string bitCount;
std::vector<std::string> len; std::vector<std::string> lenExpressions;
bool noAutoValidity = false; std::vector<std::pair<std::string, size_t>> lenMembers;
std::vector<bool> optional; bool noAutoValidity = false;
std::vector<std::string> selection; std::vector<bool> optional;
std::string selector; std::vector<std::string> selection;
std::string value; std::string selector;
std::string usedConstant; std::string value;
int xmlLine; std::string usedConstant;
int xmlLine;
}; };
struct PlatformData struct PlatformData
@ -484,9 +485,11 @@ private:
std::map<size_t, VectorParamData> determineVectorParams( std::vector<ParamData> const & params ) const; std::map<size_t, VectorParamData> determineVectorParams( std::vector<ParamData> const & params ) const;
std::set<size_t> determineVoidPointerParams( std::vector<ParamData> const & params ) const; std::set<size_t> determineVoidPointerParams( std::vector<ParamData> const & params ) const;
void distributeSecondLevelCommands( std::set<std::string> const & specialFunctions ); void distributeSecondLevelCommands( std::set<std::string> const & specialFunctions );
void filterLenMembers();
std::map<std::string, AliasData>::const_iterator findAlias( std::string const & name, std::map<std::string, AliasData> const & aliases ) const; std::map<std::string, AliasData>::const_iterator findAlias( std::string const & name, std::map<std::string, AliasData> const & aliases ) const;
std::string findBaseName( std::string aliasName, std::map<std::string, AliasData> const & aliases ) const; std::string findBaseName( std::string aliasName, std::map<std::string, AliasData> const & aliases ) const;
std::vector<FeatureData>::const_iterator findFeature( std::string const & name ) const; std::vector<FeatureData>::const_iterator findFeature( std::string const & name ) const;
std::vector<ParamData>::const_iterator findParamIt( std::string const & name, std::vector<ParamData> const & paramData ) const;
std::vector<MemberData>::const_iterator findStructMemberIt( std::string const & name, std::vector<MemberData> const & memberData ) const; std::vector<MemberData>::const_iterator findStructMemberIt( std::string const & name, std::vector<MemberData> const & memberData ) const;
std::vector<MemberData>::const_iterator findStructMemberItByType( std::string const & type, std::vector<MemberData> const & memberData ) const; std::vector<MemberData>::const_iterator findStructMemberItByType( std::string const & type, std::vector<MemberData> const & memberData ) const;
std::vector<ExtensionData>::const_iterator findSupportedExtension( std::string const & name ) const; std::vector<ExtensionData>::const_iterator findSupportedExtension( std::string const & name ) const;
@ -917,7 +920,7 @@ private:
bool handleRemovalCommand( std::string const & command, std::vector<RequireData> & requireData ); bool handleRemovalCommand( std::string const & command, std::vector<RequireData> & requireData );
void handleRemovals(); void handleRemovals();
bool handleRemovalType( std::string const & type, std::vector<RequireData> & requireData ); bool handleRemovalType( std::string const & type, std::vector<RequireData> & requireData );
bool hasLen( std::vector<MemberData> const & members, MemberData const & md ) const; bool hasLen( MemberData const & md ) const;
bool hasParentHandle( std::string const & handle, std::string const & parent ) const; bool hasParentHandle( std::string const & handle, std::string const & parent ) const;
bool isDeviceCommand( CommandData const & commandData ) const; bool isDeviceCommand( CommandData const & commandData ) const;
bool isExtension( std::string const & name ) const; bool isExtension( std::string const & name ) const;
@ -937,7 +940,8 @@ private:
std::pair<bool, std::map<size_t, std::vector<size_t>>> needsVectorSizeCheck( std::vector<ParamData> const & params, std::pair<bool, std::map<size_t, std::vector<size_t>>> needsVectorSizeCheck( std::vector<ParamData> const & params,
std::map<size_t, VectorParamData> const & vectorParams, std::map<size_t, VectorParamData> const & vectorParams,
std::vector<size_t> const & returnParams, std::vector<size_t> const & returnParams,
std::set<size_t> const & singularParams ) const; std::set<size_t> const & singularParams,
std::set<size_t> const & skippedParams ) const;
void readCommand( tinyxml2::XMLElement const * element ); void readCommand( tinyxml2::XMLElement const * element );
std::pair<bool, ParamData> readCommandParam( tinyxml2::XMLElement const * element, std::vector<ParamData> const & params ); std::pair<bool, ParamData> readCommandParam( tinyxml2::XMLElement const * element, std::vector<ParamData> const & params );
std::pair<std::string, std::string> readCommandProto( tinyxml2::XMLElement const * element ); std::pair<std::string, std::string> readCommandProto( tinyxml2::XMLElement const * element );