Move the logic for parsing structs and index/field selection expressions from…

Move the logic for parsing structs and index/field selection expressions from the grammar into TParseContext. TRAC #22930 Signed-off-by: Nicolas Capens Signed-off-by: Geoff Lang Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2340 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 1bddfb98
...@@ -1421,7 +1421,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS ...@@ -1421,7 +1421,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
// If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
// function and returns the parse-tree with the values of the embedded/nested struct. // function and returns the parse-tree with the values of the embedded/nested struct.
// //
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTyped *node, TSourceLoc line)
{ {
const TTypeList* fields = node->getType().getStruct(); const TTypeList* fields = node->getType().getStruct();
TIntermTyped *typedNode; TIntermTyped *typedNode;
...@@ -1502,6 +1502,362 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT ...@@ -1502,6 +1502,362 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT
} }
// //
// Parse an array index expression
//
TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, TSourceLoc location, TIntermTyped *indexExpression)
{
TIntermTyped *indexedExpression = NULL;
if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
{
if (baseExpression->getAsSymbolNode())
{
error(location, " left of '[' is not of type array, matrix, or vector ", baseExpression->getAsSymbolNode()->getSymbol().c_str());
}
else
{
error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
}
recover();
}
if (baseExpression->getType().getQualifier() == EvqConst && indexExpression->getQualifier() == EvqConst)
{
if (baseExpression->isArray())
{
// constant folding for arrays
indexedExpression = addConstArrayNode(indexExpression->getAsConstantUnion()->getIConst(0), baseExpression, location);
}
else if (baseExpression->isVector())
{
// constant folding for vectors
TVectorFields fields;
fields.num = 1;
fields.offsets[0] = indexExpression->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
indexedExpression = addConstVectorNode(fields, baseExpression, location);
}
else if (baseExpression->isMatrix())
{
// constant folding for matrices
indexedExpression = addConstMatrixNode(indexExpression->getAsConstantUnion()->getIConst(0), baseExpression, location);
}
}
else
{
if (indexExpression->getQualifier() == EvqConst)
{
if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= indexExpression->getAsConstantUnion()->getIConst(0) && !baseExpression->isArray() )
{
std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
}
else
{
if (baseExpression->isArray())
{
if (baseExpression->getType().getArraySize() == 0)
{
if (baseExpression->getType().getMaxArraySize() <= indexExpression->getAsConstantUnion()->getIConst(0))
{
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), indexExpression->getAsConstantUnion()->getIConst(0), true, location))
recover();
}
else
{
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), 0, false, location))
recover();
}
}
else if ( indexExpression->getAsConstantUnion()->getIConst(0) >= baseExpression->getType().getArraySize())
{
std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
}
}
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
}
}
else
{
if (baseExpression->isArray() && baseExpression->getType().getArraySize() == 0)
{
error(location, "", "[", "array must be redeclared with a size before being indexed with a variable");
recover();
}
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
}
}
if (indexedExpression == 0)
{
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f);
indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location);
}
else if (baseExpression->isArray())
{
if (baseExpression->getType().getStruct())
{
indexedExpression->setType(TType(baseExpression->getType().getStruct(), baseExpression->getType().getTypeName()));
}
else
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->isMatrix()));
}
if (baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
}
else if (baseExpression->isMatrix() && baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst, baseExpression->getNominalSize()));
}
else if (baseExpression->isMatrix())
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize()));
}
else if (baseExpression->isVector() && baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst));
}
else if (baseExpression->isVector())
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary));
}
else
{
indexedExpression->setType(baseExpression->getType());
}
return indexedExpression;
}
TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, TSourceLoc dotLocation, const TString &fieldString, TSourceLoc fieldLocation)
{
TIntermTyped *indexedExpression = NULL;
if (baseExpression->isArray())
{
error(fieldLocation, "cannot apply dot operator to an array", ".");
recover();
}
if (baseExpression->isVector())
{
TVectorFields fields;
if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
{
fields.num = 1;
fields.offsets[0] = 0;
recover();
}
if (baseExpression->getType().getQualifier() == EvqConst)
{
// constant folding for vector fields
indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);
if (indexedExpression == 0)
{
recover();
indexedExpression = baseExpression;
}
else
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst, (int) (fieldString).size()));
}
}
else
{
TString vectorString = fieldString;
TIntermTyped* index = intermediate.addSwizzle(fields, fieldLocation);
indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, (int) vectorString.size()));
}
}
else if (baseExpression->isMatrix())
{
TMatrixFields fields;
if (!parseMatrixFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
{
fields.wholeRow = false;
fields.wholeCol = false;
fields.row = 0;
fields.col = 0;
recover();
}
if (fields.wholeRow || fields.wholeCol)
{
error(dotLocation, " non-scalar fields not implemented yet", ".");
recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(0);
TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation);
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),EvqTemporary, baseExpression->getNominalSize()));
}
else
{
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(fields.col * baseExpression->getNominalSize() + fields.row);
TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation);
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision()));
}
}
else if (baseExpression->getBasicType() == EbtStruct)
{
bool fieldFound = false;
const TTypeList* fields = baseExpression->getType().getStruct();
if (fields == 0)
{
error(dotLocation, "structure has no fields", "Internal Error");
recover();
indexedExpression = baseExpression;
}
else
{
unsigned int i;
for (i = 0; i < fields->size(); ++i)
{
if ((*fields)[i].type->getFieldName() == fieldString)
{
fieldFound = true;
break;
}
}
if (fieldFound)
{
if (baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
if (indexedExpression == 0)
{
recover();
indexedExpression = baseExpression;
}
else
{
indexedExpression->setType(*(*fields)[i].type);
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
}
else
{
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped* index = intermediate.addConstantUnion(unionArray, *(*fields)[i].type, fieldLocation);
indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation);
indexedExpression->setType(*(*fields)[i].type);
}
}
else
{
error(dotLocation, " no such field in structure", fieldString.c_str());
recover();
indexedExpression = baseExpression;
}
}
}
else
{
error(dotLocation, " field selection requires structure, vector, or matrix on left hand side", fieldString.c_str());
recover();
indexedExpression = baseExpression;
}
return indexedExpression;
}
TTypeList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifier, TTypeList *typeList)
{
if (voidErrorCheck(typeSpecifier.line, (*typeList)[0].type->getFieldName(), typeSpecifier)) {
recover();
}
for (unsigned int i = 0; i < typeList->size(); ++i) {
//
// Careful not to replace already known aspects of type, like array-ness
//
TType* type = (*typeList)[i].type;
type->setBasicType(typeSpecifier.type);
type->setNominalSize(typeSpecifier.size);
type->setMatrix(typeSpecifier.matrix);
type->setPrecision(typeSpecifier.precision);
type->setQualifier(typeSpecifier.qualifier);
// don't allow arrays of arrays
if (type->isArray()) {
if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
recover();
}
if (typeSpecifier.array)
type->setArraySize(typeSpecifier.arraySize);
if (typeSpecifier.userDef) {
type->setStruct(typeSpecifier.userDef->getStruct());
type->setTypeName(typeSpecifier.userDef->getTypeName());
}
if (structNestingErrorCheck(typeSpecifier.line, *type)) {
recover();
}
}
return typeList;
}
TPublicType TParseContext::addStructure(TSourceLoc structLine, TSourceLoc nameLine, const TString &structName, TTypeList* typeList)
{
TType* structure = new TType(typeList, structName);
if (!structName.empty())
{
if (reservedErrorCheck(nameLine, structName))
{
recover();
}
TVariable* userTypeDef = new TVariable(&structName, *structure, true);
if (!symbolTable.declare(*userTypeDef)) {
error(nameLine, "redefinition", structName.c_str(), "struct");
recover();
}
}
// ensure we do not specify any storage qualifiers on the struct members
for (unsigned int typeListIndex = 0; typeListIndex < typeList->size(); typeListIndex++)
{
const TTypeLine &typeLine = (*typeList)[typeListIndex];
const TQualifier qualifier = typeLine.type->getQualifier();
switch (qualifier)
{
case EvqGlobal:
case EvqTemporary:
break;
default:
error(typeLine.line, "invalid qualifier on struct member", getQualifierString(qualifier));
recover();
break;
}
}
TPublicType publicType;
publicType.setBasic(EbtStruct, EvqTemporary, structLine);
publicType.userDef = structure;
exitStructDeclaration();
return publicType;
}
//
// Parse an array of strings using yyparse. // Parse an array of strings using yyparse.
// //
// Returns 0 for success. // Returns 0 for success.
......
...@@ -127,7 +127,12 @@ struct TParseContext { ...@@ -127,7 +127,12 @@ struct TParseContext {
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc); TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc); TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line); TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc); TIntermTyped* addConstStruct(const TString &identifier, TIntermTyped *node, TSourceLoc line);
TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, TSourceLoc location, TIntermTyped *indexExpression);
TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, TSourceLoc dotLocation, const TString &fieldString, TSourceLoc fieldLocation);
TTypeList *addStructDeclaratorList(const TPublicType& typeSpecifier, TTypeList *typeList);
TPublicType addStructure(TSourceLoc structLine, TSourceLoc nameLine, const TString &structName, TTypeList* typeList);
// Performs an error check for embedded struct declarations. // Performs an error check for embedded struct declarations.
// Returns true if an error was raised due to the declaration of // Returns true if an error was raised due to the declaration of
......
...@@ -252,187 +252,13 @@ postfix_expression ...@@ -252,187 +252,13 @@ postfix_expression
$$ = $1; $$ = $1;
} }
| postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { $$ = context->addIndexExpression($1, $2.line, $3);
if ($1->getAsSymbolNode())
context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str());
else
context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression");
context->recover();
}
if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
if ($1->isArray()) { // constant folding for arrays
$$ = context->addConstArrayNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
} else if ($1->isVector()) { // constant folding for vectors
TVectorFields fields;
fields.num = 1;
fields.offsets[0] = $3->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
$$ = context->addConstVectorNode(fields, $1, $2.line);
} else if ($1->isMatrix()) { // constant folding for matrices
$$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
}
} else {
if ($3->getQualifier() == EvqConst) {
if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getIConst(0) && !$1->isArray() ) {
std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str());
context->recover();
} else {
if ($1->isArray()) {
if ($1->getType().getArraySize() == 0) {
if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getIConst(0)) {
if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getIConst(0), true, $2.line))
context->recover();
} else {
if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
context->recover();
}
} else if ( $3->getAsConstantUnion()->getIConst(0) >= $1->getType().getArraySize()) {
std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str());
context->recover();
}
}
$$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
}
} else {
if ($1->isArray() && $1->getType().getArraySize() == 0) {
context->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
context->recover();
}
$$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
}
}
if ($$ == 0) {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line);
} else if ($1->isArray()) {
if ($1->getType().getStruct())
$$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
else
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
if ($1->getType().getQualifier() == EvqConst)
$$->getTypePointer()->setQualifier(EvqConst);
} else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, $1->getNominalSize()));
else if ($1->isMatrix())
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize()));
else if ($1->isVector() && $1->getType().getQualifier() == EvqConst)
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst));
else if ($1->isVector())
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary));
else
$$->setType($1->getType());
} }
| function_call { | function_call {
$$ = $1; $$ = $1;
} }
| postfix_expression DOT FIELD_SELECTION { | postfix_expression DOT FIELD_SELECTION {
if ($1->isArray()) { $$ = context->addFieldSelectionExpression($1, $2.line, *$3.string, $3.line);
context->error($3.line, "cannot apply dot operator to an array", ".");
context->recover();
}
if ($1->isVector()) {
TVectorFields fields;
if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
fields.num = 1;
fields.offsets[0] = 0;
context->recover();
}
if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
$$ = context->addConstVectorNode(fields, $1, $3.line);
if ($$ == 0) {
context->recover();
$$ = $1;
}
else
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size()));
} else {
TString vectorString = *$3.string;
TIntermTyped* index = context->intermediate.addSwizzle(fields, $3.line);
$$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size()));
}
} else if ($1->isMatrix()) {
TMatrixFields fields;
if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
fields.wholeRow = false;
fields.wholeCol = false;
fields.row = 0;
fields.col = 0;
context->recover();
}
if (fields.wholeRow || fields.wholeCol) {
context->error($2.line, " non-scalar fields not implemented yet", ".");
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(0);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
$$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
$$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize()));
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
$$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
$$->setType(TType($1->getBasicType(), $1->getPrecision()));
}
} else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false;
const TTypeList* fields = $1->getType().getStruct();
if (fields == 0) {
context->error($2.line, "structure has no fields", "Internal Error");
context->recover();
$$ = $1;
} else {
unsigned int i;
for (i = 0; i < fields->size(); ++i) {
if ((*fields)[i].type->getFieldName() == *$3.string) {
fieldFound = true;
break;
}
}
if (fieldFound) {
if ($1->getType().getQualifier() == EvqConst) {
$$ = context->addConstStruct(*$3.string, $1, $2.line);
if ($$ == 0) {
context->recover();
$$ = $1;
}
else {
$$->setType(*(*fields)[i].type);
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
$$->getTypePointer()->setQualifier(EvqConst);
}
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line);
$$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
$$->setType(*(*fields)[i].type);
}
} else {
context->error($2.line, " no such field in structure", $3.string->c_str());
context->recover();
$$ = $1;
}
}
} else {
context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
context->recover();
$$ = $1;
}
// don't delete $3.string, it's from the pool
} }
| postfix_expression INC_OP { | postfix_expression INC_OP {
if (context->lValueErrorCheck($2.line, "++", $1)) if (context->lValueErrorCheck($2.line, "++", $1))
...@@ -1805,24 +1631,10 @@ type_specifier_nonarray ...@@ -1805,24 +1631,10 @@ type_specifier_nonarray
struct_specifier struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { : STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
if (context->reservedErrorCheck($2.line, *$2.string)) $$ = context->addStructure($1.line, $2.line, *$2.string, $5);
context->recover();
TType* structure = new TType($5, *$2.string);
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! context->symbolTable.declare(*userTypeDef)) {
context->error($2.line, "redefinition", $2.string->c_str(), "struct");
context->recover();
}
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.userDef = structure;
context->exitStructDeclaration();
} }
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { | STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4, TString("")); $$ = context->addStructure($1.line, 0, "", $4);
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.userDef = structure;
context->exitStructDeclaration();
} }
; ;
...@@ -1846,37 +1658,7 @@ struct_declaration_list ...@@ -1846,37 +1658,7 @@ struct_declaration_list
struct_declaration struct_declaration
: type_specifier struct_declarator_list SEMICOLON { : type_specifier struct_declarator_list SEMICOLON {
$$ = $2; $$ = context->addStructDeclaratorList($1, $2);
if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
context->recover();
}
for (unsigned int i = 0; i < $$->size(); ++i) {
//
// Careful not to replace already known aspects of type, like array-ness
//
TType* type = (*$$)[i].type;
type->setBasicType($1.type);
type->setNominalSize($1.size);
type->setMatrix($1.matrix);
type->setPrecision($1.precision);
// don't allow arrays of arrays
if (type->isArray()) {
if (context->arrayTypeErrorCheck($1.line, $1))
context->recover();
}
if ($1.array)
type->setArraySize($1.arraySize);
if ($1.userDef) {
type->setStruct($1.userDef->getStruct());
type->setTypeName($1.userDef->getTypeName());
}
if (context->structNestingErrorCheck($1.line, *type)) {
context->recover();
}
}
} }
; ;
......
#line 17 "./glslang.l"
// //
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#line 25 "./glslang_lex.cpp"
#define YY_INT_ALIGNED short int #define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */ /* A lexical scanner generated by flex */
......
...@@ -714,27 +714,27 @@ static const yytype_int16 yyrhs[] = ...@@ -714,27 +714,27 @@ static const yytype_int16 yyrhs[] =
static const yytype_uint16 yyrline[] = static const yytype_uint16 yyrline[] =
{ {
0, 184, 184, 219, 222, 235, 240, 245, 251, 254, 0, 184, 184, 219, 222, 235, 240, 245, 251, 254,
333, 336, 437, 447, 460, 468, 568, 571, 579, 583, 257, 260, 263, 273, 286, 294, 394, 397, 405, 409,
590, 594, 601, 607, 616, 624, 679, 686, 696, 699, 416, 420, 427, 433, 442, 450, 505, 512, 522, 525,
709, 719, 740, 741, 742, 747, 748, 757, 769, 770, 535, 545, 566, 567, 568, 573, 574, 583, 595, 596,
778, 789, 793, 794, 804, 814, 824, 837, 838, 848, 604, 615, 619, 620, 630, 640, 650, 663, 664, 674,
861, 865, 869, 873, 874, 887, 888, 901, 902, 915, 687, 691, 695, 699, 700, 713, 714, 727, 728, 741,
916, 933, 934, 947, 948, 949, 950, 951, 955, 958, 742, 759, 760, 773, 774, 775, 776, 777, 781, 784,
969, 977, 1004, 1009, 1023, 1061, 1064, 1071, 1079, 1100, 795, 803, 830, 835, 849, 887, 890, 897, 905, 926,
1121, 1132, 1161, 1166, 1176, 1181, 1191, 1194, 1197, 1200, 947, 958, 987, 992, 1002, 1007, 1017, 1020, 1023, 1026,
1206, 1213, 1216, 1238, 1256, 1280, 1303, 1307, 1325, 1333, 1032, 1039, 1042, 1064, 1082, 1106, 1129, 1133, 1151, 1159,
1365, 1385, 1474, 1483, 1506, 1510, 1517, 1523, 1530, 1539, 1191, 1211, 1300, 1309, 1332, 1336, 1343, 1349, 1356, 1365,
1548, 1551, 1587, 1597, 1601, 1606, 1611, 1616, 1621, 1630, 1374, 1377, 1413, 1423, 1427, 1432, 1437, 1442, 1447, 1456,
1640, 1647, 1650, 1653, 1659, 1662, 1677, 1681, 1685, 1689, 1466, 1473, 1476, 1479, 1485, 1488, 1503, 1507, 1511, 1515,
1698, 1703, 1708, 1713, 1718, 1723, 1728, 1733, 1738, 1743, 1524, 1529, 1534, 1539, 1544, 1549, 1554, 1559, 1564, 1569,
1749, 1755, 1761, 1766, 1771, 1780, 1789, 1794, 1807, 1807, 1575, 1581, 1587, 1592, 1597, 1606, 1615, 1620, 1633, 1633,
1821, 1821, 1830, 1833, 1848, 1884, 1888, 1894, 1902, 1918, 1636, 1636, 1642, 1645, 1660, 1666, 1670, 1676, 1684, 1700,
1922, 1926, 1927, 1933, 1934, 1935, 1936, 1937, 1941, 1942, 1704, 1708, 1709, 1715, 1716, 1717, 1718, 1719, 1723, 1724,
1942, 1942, 1952, 1953, 1957, 1957, 1958, 1958, 1963, 1966, 1724, 1724, 1734, 1735, 1739, 1739, 1740, 1740, 1745, 1748,
1976, 1979, 1985, 1986, 1990, 1998, 2002, 2012, 2017, 2034, 1758, 1761, 1767, 1768, 1772, 1780, 1784, 1794, 1799, 1816,
2034, 2039, 2039, 2046, 2046, 2054, 2057, 2063, 2066, 2072, 1816, 1821, 1821, 1828, 1828, 1836, 1839, 1845, 1848, 1854,
2076, 2083, 2090, 2097, 2104, 2115, 2124, 2128, 2135, 2138, 1858, 1865, 1872, 1879, 1886, 1897, 1906, 1910, 1917, 1920,
2144, 2144 1926, 1926
}; };
#endif #endif
...@@ -2252,83 +2252,7 @@ yyreduce: ...@@ -2252,83 +2252,7 @@ yyreduce:
case 9: case 9:
{ {
if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { (yyval.interm.intermTypedNode) = context->addIndexExpression((yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode));
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode())
context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str());
else
context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression");
context->recover();
}
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst && (yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { // constant folding for arrays
(yyval.interm.intermTypedNode) = context->addConstArrayNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
} else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { // constant folding for vectors
TVectorFields fields;
fields.num = 1;
fields.offsets[0] = (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
(yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
} else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) { // constant folding for matrices
(yyval.interm.intermTypedNode) = context->addConstMatrixNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
}
} else {
if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
if (((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() || (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0) && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() ) {
std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str());
context->recover();
} else {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getMaxArraySize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0)) {
if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), true, (yyvsp[(2) - (4)].lex).line))
context->recover();
} else {
if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), 0, false, (yyvsp[(2) - (4)].lex).line))
context->recover();
}
} else if ( (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0) >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) {
std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str());
context->recover();
}
}
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
}
} else {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array must be redeclared with a size before being indexed with a variable");
context->recover();
}
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexIndirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
}
}
if ((yyval.interm.intermTypedNode) == 0) {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f);
(yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), (yyvsp[(2) - (4)].lex).line);
} else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct())
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getTypeName()));
else
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize(), (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()));
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
(yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
} else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqConst, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize()));
else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix())
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize()));
else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqConst));
else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector())
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary));
else
(yyval.interm.intermTypedNode)->setType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType());
} }
break; break;
...@@ -2342,105 +2266,7 @@ yyreduce: ...@@ -2342,105 +2266,7 @@ yyreduce:
case 11: case 11:
{ {
if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) { (yyval.interm.intermTypedNode) = context->addFieldSelectionExpression((yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyvsp[(3) - (3)].lex).line);
context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", ".");
context->recover();
}
if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isVector()) {
TVectorFields fields;
if (! context->parseVectorFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
fields.num = 1;
fields.offsets[0] = 0;
context->recover();
}
if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) { // constant folding for vector fields
(yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].lex).line);
if ((yyval.interm.intermTypedNode) == 0) {
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
else
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqConst, (int) (*(yyvsp[(3) - (3)].lex).string).size()));
} else {
TString vectorString = *(yyvsp[(3) - (3)].lex).string;
TIntermTyped* index = context->intermediate.addSwizzle(fields, (yyvsp[(3) - (3)].lex).line);
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpVectorSwizzle, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (int) vectorString.size()));
}
} else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isMatrix()) {
TMatrixFields fields;
if (! context->parseMatrixFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
fields.wholeRow = false;
fields.wholeCol = false;
fields.row = 0;
fields.col = 0;
context->recover();
}
if (fields.wholeRow || fields.wholeCol) {
context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", ".");
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(0);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(),EvqTemporary, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize()));
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(fields.col * (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize() + fields.row);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision()));
}
} else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType() == EbtStruct) {
bool fieldFound = false;
const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct();
if (fields == 0) {
context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error");
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
} else {
unsigned int i;
for (i = 0; i < fields->size(); ++i) {
if ((*fields)[i].type->getFieldName() == *(yyvsp[(3) - (3)].lex).string) {
fieldFound = true;
break;
}
}
if (fieldFound) {
if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) {
(yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
if ((yyval.interm.intermTypedNode) == 0) {
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
else {
(yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
(yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
}
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, (yyvsp[(3) - (3)].lex).line);
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
(yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
}
} else {
context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str());
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
}
} else {
context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str());
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
// don't delete $3.string, it's from the pool
} }
break; break;
...@@ -4135,18 +3961,7 @@ yyreduce: ...@@ -4135,18 +3961,7 @@ yyreduce:
case 149: case 149:
{ {
if (context->reservedErrorCheck((yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].lex).string)) (yyval.interm.type) = context->addStructure((yyvsp[(1) - (6)].lex).line, (yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].lex).string, (yyvsp[(5) - (6)].interm.typeList));
context->recover();
TType* structure = new TType((yyvsp[(5) - (6)].interm.typeList), *(yyvsp[(2) - (6)].lex).string);
TVariable* userTypeDef = new TVariable((yyvsp[(2) - (6)].lex).string, *structure, true);
if (! context->symbolTable.declare(*userTypeDef)) {
context->error((yyvsp[(2) - (6)].lex).line, "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct");
context->recover();
}
(yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (6)].lex).line);
(yyval.interm.type).userDef = structure;
context->exitStructDeclaration();
} }
break; break;
...@@ -4158,10 +3973,7 @@ yyreduce: ...@@ -4158,10 +3973,7 @@ yyreduce:
case 151: case 151:
{ {
TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), TString("")); (yyval.interm.type) = context->addStructure((yyvsp[(1) - (5)].lex).line, 0, "", (yyvsp[(4) - (5)].interm.typeList));
(yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
(yyval.interm.type).userDef = structure;
context->exitStructDeclaration();
} }
break; break;
...@@ -4191,37 +4003,7 @@ yyreduce: ...@@ -4191,37 +4003,7 @@ yyreduce:
case 154: case 154:
{ {
(yyval.interm.typeList) = (yyvsp[(2) - (3)].interm.typeList); (yyval.interm.typeList) = context->addStructDeclaratorList((yyvsp[(1) - (3)].interm.type), (yyvsp[(2) - (3)].interm.typeList));
if (context->voidErrorCheck((yyvsp[(1) - (3)].interm.type).line, (*(yyvsp[(2) - (3)].interm.typeList))[0].type->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
context->recover();
}
for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) {
//
// Careful not to replace already known aspects of type, like array-ness
//
TType* type = (*(yyval.interm.typeList))[i].type;
type->setBasicType((yyvsp[(1) - (3)].interm.type).type);
type->setNominalSize((yyvsp[(1) - (3)].interm.type).size);
type->setMatrix((yyvsp[(1) - (3)].interm.type).matrix);
type->setPrecision((yyvsp[(1) - (3)].interm.type).precision);
// don't allow arrays of arrays
if (type->isArray()) {
if (context->arrayTypeErrorCheck((yyvsp[(1) - (3)].interm.type).line, (yyvsp[(1) - (3)].interm.type)))
context->recover();
}
if ((yyvsp[(1) - (3)].interm.type).array)
type->setArraySize((yyvsp[(1) - (3)].interm.type).arraySize);
if ((yyvsp[(1) - (3)].interm.type).userDef) {
type->setStruct((yyvsp[(1) - (3)].interm.type).userDef->getStruct());
type->setTypeName((yyvsp[(1) - (3)].interm.type).userDef->getTypeName());
}
if (context->structNestingErrorCheck((yyvsp[(1) - (3)].interm.type).line, *type)) {
context->recover();
}
}
} }
break; break;
......
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