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
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index bd08fa5..e002cdf 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -1421,7 +1421,7 @@
// 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.
//
-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();
TIntermTyped *typedNode;
@@ -1502,6 +1502,362 @@
}
//
+// 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.
//
// Returns 0 for success.
diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h
index d99dc60..de34275 100644
--- a/src/compiler/ParseHelper.h
+++ b/src/compiler/ParseHelper.h
@@ -127,7 +127,12 @@
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
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.
// Returns true if an error was raised due to the declaration of
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index dec932c..ca3a214 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -252,187 +252,13 @@
$$ = $1;
}
| postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
- if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
- 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());
+ $$ = context->addIndexExpression($1, $2.line, $3);
}
| function_call {
$$ = $1;
}
| postfix_expression DOT FIELD_SELECTION {
- if ($1->isArray()) {
- 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
+ $$ = context->addFieldSelectionExpression($1, $2.line, *$3.string, $3.line);
}
| postfix_expression INC_OP {
if (context->lValueErrorCheck($2.line, "++", $1))
@@ -1805,24 +1631,10 @@
struct_specifier
: 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->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();
+ $$ = context->addStructure($1.line, $2.line, *$2.string, $5);
}
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
- TType* structure = new TType($4, TString(""));
- $$.setBasic(EbtStruct, EvqTemporary, $1.line);
- $$.userDef = structure;
- context->exitStructDeclaration();
+ $$ = context->addStructure($1.line, 0, "", $4);
}
;
@@ -1846,37 +1658,7 @@
struct_declaration
: type_specifier struct_declarator_list SEMICOLON {
- $$ = $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();
- }
- }
+ $$ = context->addStructDeclaratorList($1, $2);
}
;
diff --git a/src/compiler/glslang_lex.cpp b/src/compiler/glslang_lex.cpp
index 0e59aef..b412f6c 100644
--- a/src/compiler/glslang_lex.cpp
+++ b/src/compiler/glslang_lex.cpp
@@ -1,4 +1,4 @@
-
+#line 17 "./glslang.l"
//
// 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
@@ -21,6 +21,8 @@
+#line 25 "./glslang_lex.cpp"
+
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index 5acc53f..4fff0b3 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -714,27 +714,27 @@
static const yytype_uint16 yyrline[] =
{
0, 184, 184, 219, 222, 235, 240, 245, 251, 254,
- 333, 336, 437, 447, 460, 468, 568, 571, 579, 583,
- 590, 594, 601, 607, 616, 624, 679, 686, 696, 699,
- 709, 719, 740, 741, 742, 747, 748, 757, 769, 770,
- 778, 789, 793, 794, 804, 814, 824, 837, 838, 848,
- 861, 865, 869, 873, 874, 887, 888, 901, 902, 915,
- 916, 933, 934, 947, 948, 949, 950, 951, 955, 958,
- 969, 977, 1004, 1009, 1023, 1061, 1064, 1071, 1079, 1100,
- 1121, 1132, 1161, 1166, 1176, 1181, 1191, 1194, 1197, 1200,
- 1206, 1213, 1216, 1238, 1256, 1280, 1303, 1307, 1325, 1333,
- 1365, 1385, 1474, 1483, 1506, 1510, 1517, 1523, 1530, 1539,
- 1548, 1551, 1587, 1597, 1601, 1606, 1611, 1616, 1621, 1630,
- 1640, 1647, 1650, 1653, 1659, 1662, 1677, 1681, 1685, 1689,
- 1698, 1703, 1708, 1713, 1718, 1723, 1728, 1733, 1738, 1743,
- 1749, 1755, 1761, 1766, 1771, 1780, 1789, 1794, 1807, 1807,
- 1821, 1821, 1830, 1833, 1848, 1884, 1888, 1894, 1902, 1918,
- 1922, 1926, 1927, 1933, 1934, 1935, 1936, 1937, 1941, 1942,
- 1942, 1942, 1952, 1953, 1957, 1957, 1958, 1958, 1963, 1966,
- 1976, 1979, 1985, 1986, 1990, 1998, 2002, 2012, 2017, 2034,
- 2034, 2039, 2039, 2046, 2046, 2054, 2057, 2063, 2066, 2072,
- 2076, 2083, 2090, 2097, 2104, 2115, 2124, 2128, 2135, 2138,
- 2144, 2144
+ 257, 260, 263, 273, 286, 294, 394, 397, 405, 409,
+ 416, 420, 427, 433, 442, 450, 505, 512, 522, 525,
+ 535, 545, 566, 567, 568, 573, 574, 583, 595, 596,
+ 604, 615, 619, 620, 630, 640, 650, 663, 664, 674,
+ 687, 691, 695, 699, 700, 713, 714, 727, 728, 741,
+ 742, 759, 760, 773, 774, 775, 776, 777, 781, 784,
+ 795, 803, 830, 835, 849, 887, 890, 897, 905, 926,
+ 947, 958, 987, 992, 1002, 1007, 1017, 1020, 1023, 1026,
+ 1032, 1039, 1042, 1064, 1082, 1106, 1129, 1133, 1151, 1159,
+ 1191, 1211, 1300, 1309, 1332, 1336, 1343, 1349, 1356, 1365,
+ 1374, 1377, 1413, 1423, 1427, 1432, 1437, 1442, 1447, 1456,
+ 1466, 1473, 1476, 1479, 1485, 1488, 1503, 1507, 1511, 1515,
+ 1524, 1529, 1534, 1539, 1544, 1549, 1554, 1559, 1564, 1569,
+ 1575, 1581, 1587, 1592, 1597, 1606, 1615, 1620, 1633, 1633,
+ 1636, 1636, 1642, 1645, 1660, 1666, 1670, 1676, 1684, 1700,
+ 1704, 1708, 1709, 1715, 1716, 1717, 1718, 1719, 1723, 1724,
+ 1724, 1724, 1734, 1735, 1739, 1739, 1740, 1740, 1745, 1748,
+ 1758, 1761, 1767, 1768, 1772, 1780, 1784, 1794, 1799, 1816,
+ 1816, 1821, 1821, 1828, 1828, 1836, 1839, 1845, 1848, 1854,
+ 1858, 1865, 1872, 1879, 1886, 1897, 1906, 1910, 1917, 1920,
+ 1926, 1926
};
#endif
@@ -2252,83 +2252,7 @@
case 9:
{
- if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) {
- 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());
+ (yyval.interm.intermTypedNode) = context->addIndexExpression((yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode));
}
break;
@@ -2342,105 +2266,7 @@
case 11:
{
- if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) {
- 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
+ (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);
}
break;
@@ -4135,18 +3961,7 @@
case 149:
{
- if (context->reservedErrorCheck((yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].lex).string))
- 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();
+ (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));
}
break;
@@ -4158,10 +3973,7 @@
case 151:
{
- TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), TString(""));
- (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
- (yyval.interm.type).userDef = structure;
- context->exitStructDeclaration();
+ (yyval.interm.type) = context->addStructure((yyvsp[(1) - (5)].lex).line, 0, "", (yyvsp[(4) - (5)].interm.typeList));
}
break;
@@ -4191,37 +4003,7 @@
case 154:
{
- (yyval.interm.typeList) = (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();
- }
- }
+ (yyval.interm.typeList) = context->addStructDeclaratorList((yyvsp[(1) - (3)].interm.type), (yyvsp[(2) - (3)].interm.typeList));
}
break;