Commit 3875ffd1 by Olli Etuaho

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/265652Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent e7847b08
...@@ -1333,6 +1333,48 @@ TIntermAggregate *TParseContext::parseSingleInitDeclaration(TPublicType &publicT ...@@ -1333,6 +1333,48 @@ TIntermAggregate *TParseContext::parseSingleInitDeclaration(TPublicType &publicT
} }
} }
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, TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
const TSourceLoc &identifierLoc, const TSourceLoc &identifierLoc,
const TString *identifier, const TString *identifier,
...@@ -1483,6 +1525,61 @@ TIntermAggregate *TParseContext::parseInitDeclarator(TPublicType &publicType, TI ...@@ -1483,6 +1525,61 @@ TIntermAggregate *TParseContext::parseInitDeclarator(TPublicType &publicType, TI
} }
} }
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) void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
{ {
if (typeQualifier.qualifier != EvqUniform) if (typeQualifier.qualifier != EvqUniform)
......
...@@ -138,6 +138,13 @@ struct TParseContext { ...@@ -138,6 +138,13 @@ struct TParseContext {
const TSourceLoc &identifierLocation, const TString &identifier, const TSourceLoc &identifierLocation, const TString &identifier,
const TSourceLoc &initLocation, TIntermTyped *initializer); const TSourceLoc &initLocation, TIntermTyped *initializer);
// Parse a declaration like "type a[n] = initializer"
// Note that this does not apply to declarations like "type[n] a = initializer"
TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType,
const TSourceLoc &identifierLocation, const TString &identifier,
const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
const TSourceLoc &initLocation, TIntermTyped *initializer);
TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc,
const TString *identifier, const TSymbol *symbol); const TString *identifier, const TSymbol *symbol);
...@@ -150,6 +157,12 @@ struct TParseContext { ...@@ -150,6 +157,12 @@ struct TParseContext {
const TSourceLoc &identifierLocation, const TString &identifier, const TSourceLoc &identifierLocation, const TString &identifier,
const TSourceLoc &initLocation, TIntermTyped *initializer); const TSourceLoc &initLocation, TIntermTyped *initializer);
// Parse a declarator like "a[n] = initializer"
TIntermAggregate *parseArrayInitDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
const TSourceLoc& identifierLocation, const TString &identifier,
const TSourceLoc& indexLocation, TIntermTyped *indexExpression,
const TSourceLoc &initLocation, TIntermTyped *initializer);
void parseGlobalLayoutQualifier(const TPublicType &typeQualifier); void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
TFunction *addConstructorFunc(TPublicType publicType); TFunction *addConstructorFunc(TPublicType publicType);
TIntermTyped* addConstructor(TIntermNode*, TType*, TOperator, TFunction*, const TSourceLoc&); TIntermTyped* addConstructor(TIntermNode*, TType*, TOperator, TFunction*, const TSourceLoc&);
......
...@@ -889,6 +889,11 @@ init_declarator_list ...@@ -889,6 +889,11 @@ init_declarator_list
$$ = $1; $$ = $1;
$$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); $$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5);
} }
| init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
ES3_ONLY("=", @7, "first-class arrays (array initializer)");
$$ = $1;
$$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5, @7, $8);
}
| init_declarator_list COMMA identifier EQUAL initializer { | init_declarator_list COMMA identifier EQUAL initializer {
$$ = $1; $$ = $1;
$$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5);
...@@ -915,6 +920,11 @@ single_declaration ...@@ -915,6 +920,11 @@ single_declaration
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4);
} }
| fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
ES3_ONLY("=", @6, "first-class arrays (array initializer)");
$$.type = $1;
$$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7);
}
| fully_specified_type identifier EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment