Types: Fix #1290: Rationalize and correct "mixed" style array dimensioning.

There a couple functional problems, which when reduced down also led to
some good simplifications and rationalization.  So, this commit:
 - corrects "mixed" functionality: int[A] f[B] -> f[B][A]
 - correct multi-identifier decls: int[A] f[B], g[C] -> f and g are independently sized.
 - increases symmetry between different places in the code that do this
 - makes fewer ways to do the same thing; several methods are just gone now
 - makes more clear when something is copied or shared
This commit is contained in:
John Kessenich 2018-03-26 00:38:53 -06:00
parent 1c3ab274b1
commit 859b0342b8
17 changed files with 1323 additions and 1289 deletions

View file

@ -1105,7 +1105,7 @@ void HlslParseContext::splitBuiltIn(const TString& baseName, const TType& member
TVariable* ioVar = makeInternalVariable(baseName + "." + memberType.getFieldName(), memberType);
if (arraySizes != nullptr && !memberType.isArray())
ioVar->getWritableType().newArraySizes(*arraySizes);
ioVar->getWritableType().copyArraySizes(*arraySizes);
splitBuiltIns[tInterstageIoData(memberType.getQualifier().builtIn, outerQualifier.storage)] = ioVar;
if (!isClipOrCullDistance(ioVar->getType()))
@ -1301,7 +1301,7 @@ int HlslParseContext::flattenStruct(const TVariable& variable, const TType& type
name + "." + dereferencedType.getFieldName(),
linkage, outerQualifier,
builtInArraySizes == nullptr && dereferencedType.isArray()
? &dereferencedType.getArraySizes()
? dereferencedType.getArraySizes()
: builtInArraySizes);
flattenData.offsets[pos++] = mpos;
}
@ -1512,9 +1512,9 @@ void HlslParseContext::fixBuiltInIoType(TType& type)
// Alter or set array size as needed.
if (requiredArraySize > 0) {
if (!type.isArray() || type.getOuterArraySize() != requiredArraySize) {
TArraySizes arraySizes;
arraySizes.addInnerSize(requiredArraySize);
type.newArraySizes(arraySizes);
TArraySizes* arraySizes = new TArraySizes;
arraySizes->addInnerSize(requiredArraySize);
type.transferArraySizes(arraySizes);
}
}
}
@ -2273,9 +2273,9 @@ void HlslParseContext::remapEntryPointIO(TFunction& function, TVariable*& return
outputType.shallowCopy(function.getType());
// vertices has necessarily already been set when handling entry point attributes.
TArraySizes arraySizes;
arraySizes.addInnerSize(intermediate.getVertices());
outputType.newArraySizes(arraySizes);
TArraySizes* arraySizes = new TArraySizes;
arraySizes->addInnerSize(intermediate.getVertices());
outputType.transferArraySizes(arraySizes);
clearUniformInputOutput(function.getWritableType().getQualifier());
returnValue = makeIoVariable("@entryPointOutput", outputType, EvqVaryingOut);
@ -2512,11 +2512,11 @@ TIntermAggregate* HlslParseContext::assignClipCullDistance(const TSourceLoc& loc
clipCullType.getQualifier() = clipCullNode->getType().getQualifier();
// Create required array dimension
TArraySizes arraySizes;
TArraySizes* arraySizes = new TArraySizes;
if (isImplicitlyArrayed)
arraySizes.addInnerSize(requiredOuterArraySize);
arraySizes.addInnerSize(requiredInnerArraySize);
clipCullType.newArraySizes(arraySizes);
arraySizes->addInnerSize(requiredOuterArraySize);
arraySizes->addInnerSize(requiredInnerArraySize);
clipCullType.transferArraySizes(arraySizes);
// Obtain symbol name: we'll use that for the symbol we introduce.
TIntermSymbol* sym = clipCullNode->getAsSymbolNode();
@ -3612,9 +3612,9 @@ TIntermConstantUnion* HlslParseContext::getSamplePosArray(int count)
TType retType(EbtFloat, EvqConst, 2);
if (numSamples != 1) {
TArraySizes arraySizes;
arraySizes.addInnerSize(numSamples);
retType.newArraySizes(arraySizes);
TArraySizes* arraySizes = new TArraySizes;
arraySizes->addInnerSize(numSamples);
retType.transferArraySizes(arraySizes);
}
return new TIntermConstantUnion(*values, retType);
@ -4311,9 +4311,9 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
// we construct an array from the separate args.
if (hasOffset4) {
TType arrayType(EbtInt, EvqTemporary, 2);
TArraySizes arraySizes;
arraySizes.addInnerSize(4);
arrayType.newArraySizes(arraySizes);
TArraySizes* arraySizes = new TArraySizes;
arraySizes->addInnerSize(4);
arrayType.transferArraySizes(arraySizes);
TIntermAggregate* initList = new TIntermAggregate(EOpNull);
@ -6343,11 +6343,11 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
// Types have to match, but we're still making the type.
// Finish making the type, and the comparison is done later
// when checking for conversion.
TArraySizes& arraySizes = type.getArraySizes();
TArraySizes& arraySizes = *type.getArraySizes();
// At least the dimensionalities have to match.
if (! function[0].type->isArray() ||
arraySizes.getNumDims() != function[0].type->getArraySizes().getNumDims() + 1) {
arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) {
error(loc, "array constructor argument not correct type to construct array element", "constructor", "");
return true;
}
@ -6357,7 +6357,7 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
// That means we need to adopt (from the first argument) the other array sizes into the type.
for (int d = 1; d < arraySizes.getNumDims(); ++d) {
if (arraySizes.getDimSize(d) == UnsizedArraySize) {
arraySizes.setDimSize(d, function[0].type->getArraySizes().getDimSize(d - 1));
arraySizes.setDimSize(d, function[0].type->getArraySizes()->getDimSize(d - 1));
}
}
}
@ -6621,20 +6621,6 @@ void HlslParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType&
}
}
// Merge array dimensions listed in 'sizes' onto the type's array dimensions.
//
// From the spec: "vec4[2] a[3]; // size-3 array of size-2 array of vec4"
//
// That means, the 'sizes' go in front of the 'type' as outermost sizes.
// 'type' is the type part of the declaration (to the left)
// 'sizes' is the arrayness tagged on the identifier (to the right)
//
void HlslParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes)
{
if (sizes)
type.addArrayOuterSizes(*sizes);
}
//
// Do all the semantic checking for declaring or redeclaring an array, with and
// without a size, and make the right changes to the symbol table.
@ -7946,8 +7932,10 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
variable->getType().getArraySizes()->getNumDims()) {
// adopt unsized sizes from the initializer's sizes
for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) {
if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize)
variable->getWritableType().getArraySizes().setDimSize(d, initializer->getType().getArraySizes()->getDimSize(d));
if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize) {
variable->getWritableType().getArraySizes()->setDimSize(d,
initializer->getType().getArraySizes()->getDimSize(d));
}
}
}
@ -8034,7 +8022,7 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
// Later on, initializer execution code will deal with array size logic.
TType arrayType;
arrayType.shallowCopy(type); // sharing struct stuff is fine
arrayType.newArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below
arrayType.copyArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below
// edit array sizes to fill in unsized dimensions
if (type.isImplicitlySizedArray())
@ -8044,10 +8032,10 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
if (arrayType.isArrayOfArrays() && initList->getSequence().size() > 0) {
TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped();
if (firstInit->getType().isArray() &&
arrayType.getArraySizes().getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) {
for (int d = 1; d < arrayType.getArraySizes().getNumDims(); ++d) {
if (arrayType.getArraySizes().getDimSize(d) == UnsizedArraySize)
arrayType.getArraySizes().setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1));
arrayType.getArraySizes()->getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) {
for (int d = 1; d < arrayType.getArraySizes()->getNumDims(); ++d) {
if (arrayType.getArraySizes()->getDimSize(d) == UnsizedArraySize)
arrayType.getArraySizes()->setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1));
}
}
}
@ -8539,7 +8527,7 @@ TIntermTyped* HlslParseContext::constructAggregate(TIntermNode* node, const TTyp
//
// Do everything needed to add an interface block.
//
void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TString* instanceName, TArraySizes* arraySizes)
void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TString* instanceName)
{
assert(type.getWritableStruct() != nullptr);
@ -8667,8 +8655,8 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS
const TString& interfaceName = (instanceName && !instanceName->empty()) ? *instanceName : type.getTypeName();
TType blockType(&typeList, interfaceName, type.getQualifier());
if (arraySizes)
blockType.newArraySizes(*arraySizes);
if (type.isArray())
blockType.transferArraySizes(type.getArraySizes());
// Add the variable, as anonymous or named instanceName.
// Make an anonymous variable if no name was provided.