Add parser support for initializing sized arrays
Still missing from this patch: HLSL output, implicitly sized arrays.
Tested with WebGL 2 test sdk/tests/deqp/data/gles3/shaders/arrays.html
TEST=WebGL 2 conformance tests
BUG=angleproject:941
Change-Id: I900f2af843fd8046f23dd4b77352e77026bbba84
Reviewed-on: https://chromium-review.googlesource.com/265652
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 5a6b60a..27eed39 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1333,6 +1333,48 @@
}
}
+TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
+{
+ mDeferredSingleDeclarationErrorCheck = false;
+
+ if (singleDeclarationErrorCheck(publicType, identifierLocation))
+ recover();
+
+ if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
+ {
+ recover();
+ }
+
+ TPublicType arrayType(publicType);
+
+ int size;
+ if (arraySizeErrorCheck(identifierLocation, indexExpression, size))
+ {
+ recover();
+ }
+ // Make the type an array even if size check failed.
+ // This ensures useless error messages regarding the variable's non-arrayness won't follow.
+ arrayType.setArraySize(size);
+
+ // initNode will correspond to the whole of "type b[n] = initializer".
+ TIntermNode *initNode = nullptr;
+ if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
+ {
+ return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr;
+ }
+ else
+ {
+ recover();
+ return nullptr;
+ }
+}
+
TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
const TSourceLoc &identifierLoc,
const TString *identifier,
@@ -1483,6 +1525,61 @@
}
}
+TIntermAggregate *TParseContext::parseArrayInitDeclarator(TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc& identifierLocation,
+ const TString &identifier,
+ const TSourceLoc& indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation, TIntermTyped *initializer)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
+ if (mDeferredSingleDeclarationErrorCheck)
+ {
+ if (singleDeclarationErrorCheck(publicType, identifierLocation))
+ recover();
+ mDeferredSingleDeclarationErrorCheck = false;
+ }
+
+ if (locationDeclaratorListCheck(identifierLocation, publicType))
+ recover();
+
+ if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
+ {
+ recover();
+ }
+
+ TPublicType arrayType(publicType);
+
+ int size;
+ if (arraySizeErrorCheck(identifierLocation, indexExpression, size))
+ {
+ recover();
+ }
+ // Make the type an array even if size check failed.
+ // This ensures useless error messages regarding the variable's non-arrayness won't follow.
+ arrayType.setArraySize(size);
+
+ // initNode will correspond to the whole of "b[n] = initializer".
+ TIntermNode *initNode = nullptr;
+ if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
+ {
+ if (initNode)
+ {
+ return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation);
+ }
+ else
+ {
+ return aggregateDeclaration;
+ }
+ }
+ else
+ {
+ recover();
+ return nullptr;
+ }
+}
+
void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
{
if (typeQualifier.qualifier != EvqUniform)