Merge pull request #1098 from LoopDawg/attribute-gets

HLSL: nonfunctional: add helper access methods to TAttributeMap
This commit is contained in:
John Kessenich 2017-10-11 06:05:06 +03:00 committed by GitHub
commit 60e9161100
3 changed files with 85 additions and 56 deletions

View File

@ -36,6 +36,7 @@
#include "hlslAttributes.h" #include "hlslAttributes.h"
#include <cstdlib> #include <cstdlib>
#include <cctype> #include <cctype>
#include <algorithm>
namespace glslang { namespace glslang {
// Map the given string to an attribute enum from TAttributeType, // Map the given string to an attribute enum from TAttributeType,
@ -131,4 +132,51 @@ namespace glslang {
return attributes.find(attr) != attributes.end(); return attributes.find(attr) != attributes.end();
} }
// extract integers out of attribute arguments stored in attribute aggregate
bool TAttributeMap::getInt(TAttributeType attr, int& value, int argNum) const
{
const TConstUnion* intConst = getConstUnion(attr, EbtInt, argNum);
if (intConst == nullptr)
return false;
value = intConst->getIConst();
return true;
};
// extract strings out of attribute arguments stored in attribute aggregate.
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
bool TAttributeMap::getString(TAttributeType attr, TString& value, int argNum, bool convertToLower) const
{
const TConstUnion* stringConst = getConstUnion(attr, EbtString, argNum);
if (stringConst == nullptr)
return false;
value = *stringConst->getSConst();
// Convenience.
if (convertToLower)
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
return true;
};
// Helper to get attribute const union. Returns nullptr on failure.
const TConstUnion* TAttributeMap::getConstUnion(TAttributeType attr, TBasicType basicType, int argNum) const
{
const TIntermAggregate* attrAgg = (*this)[attr];
if (attrAgg == nullptr)
return nullptr;
if (argNum >= int(attrAgg->getSequence().size()))
return nullptr;
const TConstUnion* constVal = &attrAgg->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
if (constVal == nullptr || constVal->getType() != basicType)
return nullptr;
return constVal;
}
} // end namespace glslang } // end namespace glslang

View File

@ -93,7 +93,16 @@ namespace glslang {
// True if entry exists in map (even if value is nullptr) // True if entry exists in map (even if value is nullptr)
bool contains(TAttributeType) const; bool contains(TAttributeType) const;
// Obtain attribute as integer
bool getInt(TAttributeType attr, int& value, int argNum = 0) const;
// Obtain attribute as string, with optional to-lower transform
bool getString(TAttributeType attr, TString& value, int argNum = 0, bool convertToLower = true) const;
protected: protected:
// Helper to get attribute const union
const TConstUnion* getConstUnion(TAttributeType attr, TBasicType, int argNum) const;
// Find an attribute enum given its name. // Find an attribute enum given its name.
static TAttributeType attributeFromName(const TString& nameSpace, const TString& name); static TAttributeType attributeFromName(const TString& nameSpace, const TString& name);

View File

@ -1717,36 +1717,33 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
} }
// MaxVertexCount // MaxVertexCount
const TIntermAggregate* maxVertexCount = attributes[EatMaxVertexCount]; if (attributes.contains(EatMaxVertexCount)) {
if (maxVertexCount != nullptr) { int maxVertexCount;
if (! intermediate.setVertices(maxVertexCount->getSequence()[0]->getAsConstantUnion()->
getConstArray()[0].getIConst())) { if (! attributes.getInt(EatMaxVertexCount, maxVertexCount)) {
error(loc, "cannot change previously set maxvertexcount attribute", "", ""); error(loc, "invalid maxvertexcount", "", "");
} else {
if (! intermediate.setVertices(maxVertexCount))
error(loc, "cannot change previously set maxvertexcount attribute", "", "");
} }
} }
// Handle [patchconstantfunction("...")] // Handle [patchconstantfunction("...")]
const TIntermAggregate* pcfAttr = attributes[EatPatchConstantFunc]; if (attributes.contains(EatPatchConstantFunc)) {
if (pcfAttr != nullptr) { TString pcfName;
const TConstUnion& pcfName = pcfAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0]; if (! attributes.getString(EatPatchConstantFunc, pcfName, 0, false)) {
if (pcfName.getType() != EbtString) {
error(loc, "invalid patch constant function", "", ""); error(loc, "invalid patch constant function", "", "");
} else { } else {
patchConstantFunctionName = *pcfName.getSConst(); patchConstantFunctionName = pcfName;
} }
} }
// Handle [domain("...")] // Handle [domain("...")]
const TIntermAggregate* domainAttr = attributes[EatDomain]; if (attributes.contains(EatDomain)) {
if (domainAttr != nullptr) { TString domainStr;
const TConstUnion& domainType = domainAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0]; if (! attributes.getString(EatDomain, domainStr)) {
if (domainType.getType() != EbtString) {
error(loc, "invalid domain", "", ""); error(loc, "invalid domain", "", "");
} else { } else {
TString domainStr = *domainType.getSConst();
std::transform(domainStr.begin(), domainStr.end(), domainStr.begin(), ::tolower);
TLayoutGeometry domain = ElgNone; TLayoutGeometry domain = ElgNone;
if (domainStr == "tri") { if (domainStr == "tri") {
@ -1770,15 +1767,11 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
} }
// Handle [outputtopology("...")] // Handle [outputtopology("...")]
const TIntermAggregate* topologyAttr = attributes[EatOutputTopology]; if (attributes.contains(EatOutputTopology)) {
if (topologyAttr != nullptr) { TString topologyStr;
const TConstUnion& topoType = topologyAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0]; if (! attributes.getString(EatOutputTopology, topologyStr)) {
if (topoType.getType() != EbtString) {
error(loc, "invalid outputtopology", "", ""); error(loc, "invalid outputtopology", "", "");
} else { } else {
TString topologyStr = *topoType.getSConst();
std::transform(topologyStr.begin(), topologyStr.end(), topologyStr.begin(), ::tolower);
TVertexOrder vertexOrder = EvoNone; TVertexOrder vertexOrder = EvoNone;
TLayoutGeometry primitive = ElgNone; TLayoutGeometry primitive = ElgNone;
@ -1808,15 +1801,11 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
} }
// Handle [partitioning("...")] // Handle [partitioning("...")]
const TIntermAggregate* partitionAttr = attributes[EatPartitioning]; if (attributes.contains(EatPartitioning)) {
if (partitionAttr != nullptr) { TString partitionStr;
const TConstUnion& partType = partitionAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0]; if (! attributes.getString(EatPartitioning, partitionStr)) {
if (partType.getType() != EbtString) {
error(loc, "invalid partitioning", "", ""); error(loc, "invalid partitioning", "", "");
} else { } else {
TString partitionStr = *partType.getSConst();
std::transform(partitionStr.begin(), partitionStr.end(), partitionStr.begin(), ::tolower);
TVertexSpacing partitioning = EvsNone; TVertexSpacing partitioning = EvsNone;
if (partitionStr == "integer") { if (partitionStr == "integer") {
@ -1837,14 +1826,11 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
} }
// Handle [outputcontrolpoints("...")] // Handle [outputcontrolpoints("...")]
const TIntermAggregate* outputControlPoints = attributes[EatOutputControlPoints]; if (attributes.contains(EatOutputControlPoints)) {
if (outputControlPoints != nullptr) { int ctrlPoints;
const TConstUnion& ctrlPointConst = if (! attributes.getInt(EatOutputControlPoints, ctrlPoints)) {
outputControlPoints->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
if (ctrlPointConst.getType() != EbtInt) {
error(loc, "invalid outputcontrolpoints", "", ""); error(loc, "invalid outputcontrolpoints", "", "");
} else { } else {
const int ctrlPoints = ctrlPointConst.getIConst();
if (! intermediate.setVertices(ctrlPoints)) { if (! intermediate.setVertices(ctrlPoints)) {
error(loc, "cannot change previously set outputcontrolpoints attribute", "", ""); error(loc, "cannot change previously set outputcontrolpoints attribute", "", "");
} }
@ -1856,37 +1842,23 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
// attributes. // attributes.
void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, TType& type) void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, TType& type)
{ {
// extract integers out of attribute arguments stored in attribute aggregate
const auto getInt = [&](TAttributeType attr, int argNum, int& value) -> bool {
const TIntermAggregate* attrAgg = attributes[attr];
if (attrAgg == nullptr)
return false;
if (argNum >= (int)attrAgg->getSequence().size())
return false;
const TConstUnion& intConst = attrAgg->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
if (intConst.getType() != EbtInt)
return false;
value = intConst.getIConst();
return true;
};
// location // location
int value; int value;
if (getInt(EatLocation, 0, value)) if (attributes.getInt(EatLocation, value))
type.getQualifier().layoutLocation = value; type.getQualifier().layoutLocation = value;
// binding // binding
if (getInt(EatBinding, 0, value)) { if (attributes.getInt(EatBinding, value)) {
type.getQualifier().layoutBinding = value; type.getQualifier().layoutBinding = value;
type.getQualifier().layoutSet = 0; type.getQualifier().layoutSet = 0;
} }
// set // set
if (getInt(EatBinding, 1, value)) if (attributes.getInt(EatBinding, value, 1))
type.getQualifier().layoutSet = value; type.getQualifier().layoutSet = value;
// input attachment // input attachment
if (getInt(EatInputAttachment, 0, value)) if (attributes.getInt(EatInputAttachment, value))
type.getQualifier().layoutAttachment = value; type.getQualifier().layoutAttachment = value;
} }