Commit 98493ddc by Jamie Madill Committed by Shannon Woods

Simplified TType class by carving out TStructure and TField.

R=kbr@chromium.org Review URL: https://codereview.appspot.com/9866043 git-svn-id: https://angleproject.googlecode.com/svn/trunk@2423 736b8ea6-26fd-11df-bfd4-992fa37f6226 TRAC #23415 Authored-by: alokp@chromium.org Signed-off-by: Shannon Woods Signed-off-by Nicolas Capens Merged-by: Jamie Madill
parent f386bf76
...@@ -55,11 +55,11 @@ bool FlagStd140Structs::isInStd140InterfaceBlock(TIntermTyped *node) const ...@@ -55,11 +55,11 @@ bool FlagStd140Structs::isInStd140InterfaceBlock(TIntermTyped *node) const
const TType &type = node->getType(); const TType &type = node->getType();
if (type.isInterfaceBlockMember() || type.getBasicType() == EbtInterfaceBlock)
{
// determine if we are in the standard layout // determine if we are in the standard layout
const TType &interfaceBlockType = (type.isInterfaceBlockMember() ? *type.getInterfaceBlockType() : type); const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
return (interfaceBlockType.getLayoutQualifier().blockStorage == EbsStd140); if (interfaceBlock)
{
return (interfaceBlock->blockStorage() == EbsStd140);
} }
return false; return false;
......
...@@ -447,19 +447,18 @@ void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltI ...@@ -447,19 +447,18 @@ void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltI
// //
// Depth range in window coordinates // Depth range in window coordinates
// //
TTypeList *members = NewPoolTTypeList(); TFieldList *fields = NewPoolTFieldList();
TTypeLine near = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; TSourceLoc zeroSourceLoc = {0};
TTypeLine far = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), zeroSourceLoc);
TTypeLine diff = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), zeroSourceLoc);
near.type->setFieldName("near"); TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), zeroSourceLoc);
far.type->setFieldName("far"); fields->push_back(near);
diff.type->setFieldName("diff"); fields->push_back(far);
members->push_back(near); fields->push_back(diff);
members->push_back(far); TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
members->push_back(diff); TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
TVariable *depthRangeParameters = new TVariable(NewPoolTString("gl_DepthRangeParameters"), TType(members, "gl_DepthRangeParameters"), true);
symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters); symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters);
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(members, "gl_DepthRangeParameters")); TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
depthRange->setQualifier(EvqUniform); depthRange->setQualifier(EvqUniform);
symbolTable.insert(COMMON_BUILTINS, *depthRange); symbolTable.insert(COMMON_BUILTINS, *depthRange);
......
...@@ -1142,16 +1142,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -1142,16 +1142,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray) bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{ {
const TTypeList* fields = leftNodeType.getStruct(); const TFieldList& fields = leftNodeType.getStruct()->fields();
size_t structSize = fields->size(); size_t structSize = fields.size();
size_t index = 0; size_t index = 0;
for (size_t j = 0; j < structSize; j++) { for (size_t j = 0; j < structSize; j++) {
size_t size = (*fields)[j].type->getObjectSize(); size_t size = fields[j]->type()->getObjectSize();
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
if ((*fields)[j].type->getBasicType() == EbtStruct) { if (fields[j]->type()->getBasicType() == EbtStruct) {
if (!CompareStructure(*(*fields)[j].type, &rightUnionArray[index], &leftUnionArray[index])) if (!CompareStructure(*fields[j]->type(), &rightUnionArray[index], &leftUnionArray[index]))
return false; return false;
} else { } else {
if (leftUnionArray[index] != rightUnionArray[index]) if (leftUnionArray[index] != rightUnionArray[index])
......
...@@ -79,25 +79,9 @@ void TOutputGLSLBase::writeVariableType(const TType& type) ...@@ -79,25 +79,9 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
out << type.getQualifierString() << " "; out << type.getQualifierString() << " ";
// Declare the struct if we have not done so already. // Declare the struct if we have not done so already.
if ((type.getBasicType() == EbtStruct) && if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct()))
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{ {
out << "struct " << hashName(type.getTypeName()) << "{\n"; declareStruct(type.getStruct());
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
{
const TType* fieldType = (*structure)[i].type;
ASSERT(fieldType != NULL);
if (writeVariablePrecision(fieldType->getPrecision()))
out << " ";
out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
if (fieldType->isArray())
out << arrayBrackets(*fieldType);
out << ";\n";
}
out << "}";
mDeclaredStructs.insert(type.getTypeName());
} }
else else
{ {
...@@ -138,15 +122,16 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type, ...@@ -138,15 +122,16 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
{ {
out << hashName(type.getTypeName()) << "("; const TStructure* structure = type.getStruct();
const TTypeList* structure = type.getStruct(); out << hashName(structure->name()) << "(";
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i) const TFieldList& fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{ {
const TType* fieldType = (*structure)[i].type; const TType* fieldType = fields[i]->type();
ASSERT(fieldType != NULL); ASSERT(fieldType != NULL);
pConstUnion = writeConstantUnion(*fieldType, pConstUnion); pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
if (i != structure->size() - 1) out << ", "; if (i != fields.size() - 1) out << ", ";
} }
out << ")"; out << ")";
} }
...@@ -260,12 +245,18 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node) ...@@ -260,12 +245,18 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
if (visit == InVisit) if (visit == InVisit)
{ {
// Here we are writing out "foo.bar", where "foo" is struct
// and "bar" is field. In AST, it is represented as a binary
// node, where left child represents "foo" and right child "bar".
// The node itself represents ".". The struct field "bar" is
// actually stored as an index into TStructure::fields.
out << "."; out << ".";
// TODO(alokp): ASSERT const TStructure* structure = node->getLeft()->getType().getStruct();
TString fieldName = node->getType().getFieldName(); const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
const TField* field = structure->fields()[index->getIConst(0)];
const TType& structType = node->getLeft()->getType(); TString fieldName = field->name();
if (!mSymbolTable.findBuiltIn(structType.getTypeName())) if (!mSymbolTable.findBuiltIn(structure->name()))
fieldName = hashName(fieldName); fieldName = hashName(fieldName);
out << fieldName; out << fieldName;
...@@ -596,7 +587,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -596,7 +587,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
{ {
const TType& type = node->getType(); const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct); ASSERT(type.getBasicType() == EbtStruct);
out << hashName(type.getTypeName()) << "("; out << hashName(type.getStruct()->name()) << "(";
} }
else if (visit == InVisit) else if (visit == InVisit)
{ {
...@@ -765,7 +756,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type) ...@@ -765,7 +756,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type)
else else
{ {
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
out << hashName(type.getTypeName()); out << hashName(type.getStruct()->name());
else else
out << type.getBasicString(); out << type.getBasicString();
} }
...@@ -798,3 +789,29 @@ TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name) ...@@ -798,3 +789,29 @@ TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
return name; return name;
return hashName(name); return hashName(name);
} }
bool TOutputGLSLBase::structDeclared(const TStructure* structure) const
{
return mDeclaredStructs.find(structure->name()) != mDeclaredStructs.end();
}
void TOutputGLSLBase::declareStruct(const TStructure* structure)
{
TInfoSinkBase& out = objSink();
out << "struct " << hashName(structure->name()) << "{\n";
const TFieldList& fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
const TField* field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(field->name());
if (field->type()->isArray())
out << arrayBrackets(*field->type());
out << ";\n";
}
out << "}";
mDeclaredStructs.insert(structure->name());
}
...@@ -52,6 +52,9 @@ protected: ...@@ -52,6 +52,9 @@ protected:
TString hashFunctionName(const TString& mangled_name); TString hashFunctionName(const TString& mangled_name);
private: private:
bool structDeclared(const TStructure* structure) const;
void declareStruct(const TStructure* structure);
TInfoSinkBase& mObjSink; TInfoSinkBase& mObjSink;
bool mDeclaringVariables; bool mDeclaringVariables;
......
...@@ -241,15 +241,15 @@ int OutputHLSL::vectorSize(const TType &type) const ...@@ -241,15 +241,15 @@ int OutputHLSL::vectorSize(const TType &type) const
return elementSize * arraySize; return elementSize * arraySize;
} }
TString OutputHLSL::interfaceBlockUniformName(const TType &interfaceBlockType, const TType &uniformType) TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field)
{ {
if (interfaceBlockType.hasInstanceName()) if (interfaceBlock.hasInstanceName())
{ {
return interfaceBlockType.getTypeName() + "." + uniformType.getFieldName(); return interfaceBlock.name() + "." + field.name();
} }
else else
{ {
return uniformType.getFieldName(); return field.name();
} }
} }
...@@ -258,49 +258,115 @@ TString OutputHLSL::decoratePrivate(const TString &privateText) ...@@ -258,49 +258,115 @@ TString OutputHLSL::decoratePrivate(const TString &privateText)
return "dx_" + privateText; return "dx_" + privateText;
} }
TString OutputHLSL::interfaceBlockStructName(const TType &interfaceBlockType) TString OutputHLSL::interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlock)
{ {
return decoratePrivate(interfaceBlockType.getTypeName()) + "_type"; return decoratePrivate(interfaceBlock.name()) + "_type";
} }
TString OutputHLSL::interfaceBlockInstanceString(const TType& interfaceBlockType, unsigned int arrayIndex) TString OutputHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex)
{ {
if (!interfaceBlockType.hasInstanceName()) if (!interfaceBlock.hasInstanceName())
{ {
return ""; return "";
} }
else if (interfaceBlockType.isArray()) else if (interfaceBlock.isArray())
{ {
return decoratePrivate(interfaceBlockType.getInstanceName()) + "_" + str(arrayIndex); return decoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex);
} }
else else
{ {
return decorate(interfaceBlockType.getInstanceName()); return decorate(interfaceBlock.instanceName());
} }
} }
TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType, TLayoutBlockStorage blockStorage) TString OutputHLSL::interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
{ {
const TLayoutMatrixPacking matrixPacking = memberType.getLayoutQualifier().matrixPacking; const TType &fieldType = *field.type();
const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
ASSERT(matrixPacking != EmpUnspecified); ASSERT(matrixPacking != EmpUnspecified);
if (memberType.isMatrix()) if (fieldType.isMatrix())
{ {
// Use HLSL row-major packing for GLSL column-major matrices // Use HLSL row-major packing for GLSL column-major matrices
const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major"); const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
return matrixPackString + " " + typeString(memberType); return matrixPackString + " " + typeString(fieldType);
} }
else if (memberType.getBasicType() == EbtStruct) else if (fieldType.getStruct())
{ {
// Use HLSL row-major packing for GLSL column-major matrices // Use HLSL row-major packing for GLSL column-major matrices
return structureTypeName(memberType, matrixPacking == EmpColumnMajor, blockStorage == EbsStd140); return structureTypeName(*fieldType.getStruct(), matrixPacking == EmpColumnMajor, blockStorage == EbsStd140);
} }
else else
{ {
return typeString(memberType); return typeString(fieldType);
} }
} }
TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage)
{
TString hlsl;
int elementIndex = 0;
for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++)
{
const TField &field = *interfaceBlock.fields()[typeIndex];
const TType &fieldType = *field.type();
if (blockStorage == EbsStd140)
{
// 2 and 3 component vector types in some cases need pre-padding
hlsl += std140PrePaddingString(fieldType, &elementIndex);
}
hlsl += " " + interfaceBlockFieldTypeString(field, blockStorage) +
" " + decorate(field.name()) + arrayString(fieldType) + ";\n";
// must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff
if (blockStorage == EbsStd140)
{
const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
hlsl += std140PostPaddingString(fieldType, useHLSLRowMajorPacking);
}
}
return hlsl;
}
TString OutputHLSL::interfaceBlockStructString(const TInterfaceBlock &interfaceBlock)
{
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
return "struct " + interfaceBlockStructNameString(interfaceBlock) + "\n"
"{\n" +
interfaceBlockFieldString(interfaceBlock, blockStorage) +
"};\n\n";
}
TString OutputHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex)
{
const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? decorate(str(arrayIndex)) : "");
const TString &blockName = interfaceBlock.name() + arrayIndexString;
TString hlsl;
hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n"
"{\n";
if (interfaceBlock.hasInstanceName())
{
hlsl += " " + interfaceBlockStructNameString(interfaceBlock) + " " + interfaceBlockInstanceString(interfaceBlock, arrayIndex) + ";\n";
}
else
{
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
hlsl += interfaceBlockFieldString(interfaceBlock, blockStorage);
}
hlsl += "};\n\n";
return hlsl;
}
TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex) TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex)
{ {
if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray()) if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
...@@ -370,9 +436,9 @@ TString OutputHLSL::std140PostPaddingString(const TType &type, bool useHLSLRowMa ...@@ -370,9 +436,9 @@ TString OutputHLSL::std140PostPaddingString(const TType &type, bool useHLSLRowMa
const GLenum glType = glVariableType(type); const GLenum glType = glVariableType(type);
numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix); numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
} }
else if (type.getBasicType() == EbtStruct) else if (type.getStruct())
{ {
const TString &structName = structureTypeName(type, useHLSLRowMajorPacking, true); const TString &structName = structureTypeName(*type.getStruct(), useHLSLRowMajorPacking, true);
numComponents = mStd140StructElementIndexes[structName]; numComponents = mStd140StructElementIndexes[structName];
if (numComponents == 0) if (numComponents == 0)
...@@ -394,72 +460,6 @@ TString OutputHLSL::std140PostPaddingString(const TType &type, bool useHLSLRowMa ...@@ -394,72 +460,6 @@ TString OutputHLSL::std140PostPaddingString(const TType &type, bool useHLSLRowMa
return padding; return padding;
} }
TString OutputHLSL::interfaceBlockMemberString(const TTypeList &typeList, TLayoutBlockStorage blockStorage)
{
TString hlsl;
int elementIndex = 0;
for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++)
{
const TType &memberType = *typeList[typeIndex].type;
if (blockStorage == EbsStd140)
{
// 2 and 3 component vector types in some cases need pre-padding
hlsl += std140PrePaddingString(memberType, &elementIndex);
}
hlsl += " " + interfaceBlockMemberTypeString(memberType, blockStorage) +
" " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n";
// must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff
if (blockStorage == EbsStd140)
{
const bool useHLSLRowMajorPacking = (memberType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
hlsl += std140PostPaddingString(memberType, useHLSLRowMajorPacking);
}
}
return hlsl;
}
TString OutputHLSL::interfaceBlockStructString(const TType &interfaceBlockType)
{
const TTypeList &typeList = *interfaceBlockType.getStruct();
const TLayoutBlockStorage blockStorage = interfaceBlockType.getLayoutQualifier().blockStorage;
return "struct " + interfaceBlockStructName(interfaceBlockType) + "\n"
"{\n" +
interfaceBlockMemberString(typeList, blockStorage) +
"};\n\n";
}
TString OutputHLSL::interfaceBlockString(const TType &interfaceBlockType, unsigned int registerIndex, unsigned int arrayIndex)
{
const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? decorate(str(arrayIndex)) : "");
const TString &blockName = interfaceBlockType.getTypeName() + arrayIndexString;
TString hlsl;
hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n"
"{\n";
if (interfaceBlockType.hasInstanceName())
{
hlsl += " " + interfaceBlockStructName(interfaceBlockType) + " " + interfaceBlockInstanceString(interfaceBlockType, arrayIndex) + ";\n";
}
else
{
const TTypeList &typeList = *interfaceBlockType.getStruct();
const TLayoutBlockStorage blockStorage = interfaceBlockType.getLayoutQualifier().blockStorage;
hlsl += interfaceBlockMemberString(typeList, blockStorage);
}
hlsl += "};\n\n";
return hlsl;
}
// Use the same layout for packed and shared // Use the same layout for packed and shared
void setBlockLayout(InterfaceBlock *interfaceBlock, BlockLayoutType newLayout) void setBlockLayout(InterfaceBlock *interfaceBlock, BlockLayoutType newLayout)
{ {
...@@ -502,7 +502,7 @@ BlockLayoutType convertBlockLayoutType(TLayoutBlockStorage blockStorage) ...@@ -502,7 +502,7 @@ BlockLayoutType convertBlockLayoutType(TLayoutBlockStorage blockStorage)
} }
} }
TString OutputHLSL::structInitializerString(int indent, const TTypeList &structMembers, const TString &structName) TString OutputHLSL::structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName)
{ {
TString init; TString init;
...@@ -521,19 +521,20 @@ TString OutputHLSL::structInitializerString(int indent, const TTypeList &structM ...@@ -521,19 +521,20 @@ TString OutputHLSL::structInitializerString(int indent, const TTypeList &structM
init += preIndentString + "{\n"; init += preIndentString + "{\n";
for (unsigned int memberIndex = 0; memberIndex < structMembers.size(); memberIndex++) const TFieldList &fields = structure.fields();
for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{ {
const TType &memberType = *structMembers[memberIndex].type; const TField &field = *fields[fieldIndex];
const TString &fieldName = decorate(memberType.getFieldName()); const TString &fieldName = rhsStructName + "." + decorate(field.name());
const TType &fieldType = *field.type();
if (memberType.getBasicType() == EbtStruct) if (fieldType.getStruct())
{ {
const TTypeList &nestedStructMembers = *memberType.getStruct(); init += structInitializerString(indent + 1, *fieldType.getStruct(), fieldName);
init += structInitializerString(indent + 1, nestedStructMembers, structName + "." + fieldName);
} }
else else
{ {
init += fullIndentString + structName + "." + fieldName + ",\n"; init += fullIndentString + fieldName + ",\n";
} }
} }
...@@ -577,40 +578,39 @@ void OutputHLSL::header() ...@@ -577,40 +578,39 @@ void OutputHLSL::header()
for (ReferencedSymbols::const_iterator interfaceBlockIt = mReferencedInterfaceBlocks.begin(); interfaceBlockIt != mReferencedInterfaceBlocks.end(); interfaceBlockIt++) for (ReferencedSymbols::const_iterator interfaceBlockIt = mReferencedInterfaceBlocks.begin(); interfaceBlockIt != mReferencedInterfaceBlocks.end(); interfaceBlockIt++)
{ {
const TType &nodeType = interfaceBlockIt->second->getType(); const TType &nodeType = interfaceBlockIt->second->getType();
const TType &interfaceBlockType = nodeType.isInterfaceBlockMember() ? *nodeType.getInterfaceBlockType() : nodeType; const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
const TString &blockName = interfaceBlockType.getTypeName(); const TFieldList &fieldList = interfaceBlock.fields();
const TTypeList &typeList = *interfaceBlockType.getStruct();
const unsigned int arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getArraySize() : 0; unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize());
sh::InterfaceBlock interfaceBlock(blockName.c_str(), arraySize, mInterfaceBlockRegister); sh::InterfaceBlock activeBlock(interfaceBlock.name().c_str(), arraySize, mInterfaceBlockRegister);
for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++) for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
{ {
const TType &memberType = *typeList[typeIndex].type; const TField &field = *fieldList[typeIndex];
const TString &fullUniformName = interfaceBlockUniformName(interfaceBlockType, memberType); const TString &fullUniformName = interfaceBlockFieldString(interfaceBlock, field);
declareUniformToList(memberType, fullUniformName, typeIndex, interfaceBlock.activeUniforms); declareUniformToList(*field.type(), fullUniformName, typeIndex, activeBlock.activeUniforms);
} }
mInterfaceBlockRegister += std::max(1u, interfaceBlock.arraySize); mInterfaceBlockRegister += std::max(1u, arraySize);
BlockLayoutType blockLayoutType = convertBlockLayoutType(interfaceBlockType.getLayoutQualifier().blockStorage); BlockLayoutType blockLayoutType = convertBlockLayoutType(interfaceBlock.blockStorage());
setBlockLayout(&interfaceBlock, blockLayoutType); setBlockLayout(&activeBlock, blockLayoutType);
mActiveInterfaceBlocks.push_back(interfaceBlock); mActiveInterfaceBlocks.push_back(activeBlock);
if (interfaceBlockType.hasInstanceName()) if (interfaceBlock.hasInstanceName())
{ {
interfaceBlocks += interfaceBlockStructString(interfaceBlockType); interfaceBlocks += interfaceBlockStructString(interfaceBlock);
} }
if (arraySize > 0) if (arraySize > 0)
{ {
for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{ {
interfaceBlocks += interfaceBlockString(interfaceBlockType, interfaceBlock.registerIndex + arrayIndex, arrayIndex); interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex + arrayIndex, arrayIndex);
} }
} }
else else
{ {
interfaceBlocks += interfaceBlockString(interfaceBlockType, interfaceBlock.registerIndex, GL_INVALID_INDEX); interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex, GL_INVALID_INDEX);
} }
} }
...@@ -618,12 +618,11 @@ void OutputHLSL::header() ...@@ -618,12 +618,11 @@ void OutputHLSL::header()
{ {
TIntermTyped *structNode = flaggedStructIt->first; TIntermTyped *structNode = flaggedStructIt->first;
const TString &mappedName = flaggedStructIt->second; const TString &mappedName = flaggedStructIt->second;
const TType &structType = structNode->getType(); const TStructure &structure = *structNode->getType().getStruct();
const TTypeList &structMembers = *structType.getStruct();
const TString &originalName = mFlaggedStructOriginalNames[structNode]; const TString &originalName = mFlaggedStructOriginalNames[structNode];
flaggedStructs += "static " + decorate(structType.getTypeName()) + " " + mappedName + " =\n"; flaggedStructs += "static " + decorate(structure.name()) + " " + mappedName + " =\n";
flaggedStructs += structInitializerString(0, structMembers, originalName); flaggedStructs += structInitializerString(0, structure, originalName);
flaggedStructs += "\n"; flaggedStructs += "\n";
} }
...@@ -1463,23 +1462,19 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) ...@@ -1463,23 +1462,19 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
if (qualifier == EvqUniform) if (qualifier == EvqUniform)
{ {
if (node->getType().isInterfaceBlockMember()) const TType& nodeType = node->getType();
{ const TInterfaceBlock* interfaceBlock = nodeType.getInterfaceBlock();
const TString& interfaceBlockTypeName = node->getType().getInterfaceBlockType()->getTypeName();
mReferencedInterfaceBlocks[interfaceBlockTypeName] = node; if (interfaceBlock)
out << decorateUniform(name, node->getType());
}
else if (node->getBasicType() == EbtInterfaceBlock)
{ {
const TString& interfaceBlockTypeName = node->getType().getTypeName(); mReferencedInterfaceBlocks[interfaceBlock->name()] = node;
mReferencedInterfaceBlocks[interfaceBlockTypeName] = node;
out << decorateUniform(name, node->getType());
} }
else else
{ {
mReferencedUniforms[name] = node; mReferencedUniforms[name] = node;
out << decorateUniform(name, node->getType());
} }
out << decorateUniform(name, nodeType);
} }
else if (qualifier == EvqAttribute || qualifier == EvqVertexInput) else if (qualifier == EvqAttribute || qualifier == EvqVertexInput)
{ {
...@@ -1624,13 +1619,18 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1624,13 +1619,18 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
break; break;
case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break; case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break;
case EOpIndexDirect: case EOpIndexDirect:
if (node->getLeft()->getBasicType() == EbtInterfaceBlock) {
const TType& leftType = node->getLeft()->getType();
if (leftType.isInterfaceBlock())
{ {
if (visit == PreVisit) if (visit == PreVisit)
{ {
const TType &interfaceBlockType = node->getLeft()->getType(); TInterfaceBlock* interfaceBlock = leftType.getInterfaceBlock();
mReferencedInterfaceBlocks[interfaceBlockType.getInstanceName()] = node->getLeft()->getAsSymbolNode(); const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
out << interfaceBlockInstanceString(interfaceBlockType, node->getRight()->getAsConstantUnion()->getIConst(0));
mReferencedInterfaceBlocks[interfaceBlock->instanceName()] = node->getLeft()->getAsSymbolNode();
out << interfaceBlockInstanceString(*interfaceBlock, arrayIndex);
return false; return false;
} }
} }
...@@ -1638,6 +1638,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1638,6 +1638,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{ {
outputTriplet(visit, "", "[", "]"); outputTriplet(visit, "", "[", "]");
} }
}
break; break;
case EOpIndexIndirect: case EOpIndexIndirect:
// We do not currently support indirect references to interface blocks // We do not currently support indirect references to interface blocks
...@@ -1645,10 +1646,23 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1645,10 +1646,23 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
outputTriplet(visit, "", "[", "]"); outputTriplet(visit, "", "[", "]");
break; break;
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
if (visit == InVisit)
{
const TStructure* structure = node->getLeft()->getType().getStruct();
const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
const TField* field = structure->fields()[index->getIConst(0)];
out << "." + decorateField(field->name(), *structure);
return false;
}
break;
case EOpIndexDirectInterfaceBlock: case EOpIndexDirectInterfaceBlock:
if (visit == InVisit) if (visit == InVisit)
{ {
out << "." + decorateField(node->getType().getFieldName(), node->getLeft()->getType()); const TInterfaceBlock* interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
const TField* field = interfaceBlock->fields()[index->getIConst(0)];
out << "." + decorate(field->name());
return false; return false;
} }
...@@ -1717,18 +1731,19 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1717,18 +1731,19 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
out << "!("; out << "!(";
} }
const TTypeList *fields = node->getLeft()->getType().getStruct(); const TStructure &structure = *node->getLeft()->getType().getStruct();
const TFieldList &fields = structure.fields();
for (size_t i = 0; i < fields->size(); i++) for (size_t i = 0; i < fields.size(); i++)
{ {
const TType *fieldType = (*fields)[i].type; const TField *field = fields[i];
node->getLeft()->traverse(this); node->getLeft()->traverse(this);
out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()) + " == "; out << "." + decorateField(field->name(), structure) + " == ";
node->getRight()->traverse(this); node->getRight()->traverse(this);
out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()); out << "." + decorateField(field->name(), structure);
if (i < fields->size() - 1) if (i < fields.size() - 1)
{ {
out << " && "; out << " && ";
} }
...@@ -1996,7 +2011,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1996,7 +2011,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (variable->getType().getStruct()) if (variable->getType().getStruct())
{ {
addConstructor(variable->getType(), scopedStruct(variable->getType().getTypeName()), NULL); addConstructor(variable->getType(), scopedStruct(variable->getType().getStruct()->name()), NULL);
} }
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
...@@ -2123,7 +2138,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2123,7 +2138,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (symbol->getType().getStruct()) if (symbol->getType().getStruct())
{ {
addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL); addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL);
} }
out << argumentString(symbol); out << argumentString(symbol);
...@@ -2319,8 +2334,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2319,8 +2334,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
outputTriplet(visit, "mat4(", ", ", ")"); outputTriplet(visit, "mat4(", ", ", ")");
break; break;
case EOpConstructStruct: case EOpConstructStruct:
addConstructor(node->getType(), scopedStruct(node->getType().getTypeName()), &node->getSequence()); addConstructor(node->getType(), scopedStruct(node->getType().getStruct()->name()), &node->getSequence());
outputTriplet(visit, structLookup(node->getType().getTypeName()) + "_ctor(", ", ", ")"); outputTriplet(visit, structLookup(node->getType().getStruct()->name()) + "_ctor(", ", ", ")");
break; break;
case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break;
...@@ -2910,15 +2925,17 @@ TString OutputHLSL::qualifierString(TQualifier qualifier) ...@@ -2910,15 +2925,17 @@ TString OutputHLSL::qualifierString(TQualifier qualifier)
TString OutputHLSL::typeString(const TType &type) TString OutputHLSL::typeString(const TType &type)
{ {
if (type.getBasicType() == EbtStruct) const TStructure* structure = type.getStruct();
if (structure)
{ {
if (type.getTypeName() != "") const TString& typeName = structure->name();
if (typeName != "")
{ {
return structLookup(type.getTypeName()); return structLookup(typeName);
} }
else // Nameless structure, define in place else // Nameless structure, define in place
{ {
return structureString(type, false, false); return structureString(*structure, false, false);
} }
} }
else if (type.isMatrix()) else if (type.isMatrix())
...@@ -3038,42 +3055,41 @@ TString OutputHLSL::initializer(const TType &type) ...@@ -3038,42 +3055,41 @@ TString OutputHLSL::initializer(const TType &type)
return "{" + string + "}"; return "{" + string + "}";
} }
TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing) TString OutputHLSL::structureString(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing)
{ {
ASSERT(structType.getStruct()); const TFieldList &fields = structure.fields();
const bool isNameless = (structure.name() == "");
const TTypeList &fields = *structType.getStruct(); const TString &structName = structureTypeName(structure, useHLSLRowMajorPacking, useStd140Packing);
const bool isNameless = (structType.getTypeName() == "");
const TString &structName = structureTypeName(structType, useHLSLRowMajorPacking, useStd140Packing);
const TString declareString = (isNameless ? "struct" : "struct " + structName); const TString declareString = (isNameless ? "struct" : "struct " + structName);
TString structure; TString string;
structure += declareString + "\n" string += declareString + "\n"
"{\n"; "{\n";
int elementIndex = 0; int elementIndex = 0;
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
const TType &field = *fields[i].type; const TField &field = *fields[i];
const TType &fieldType = *field.type();
const TStructure *fieldStruct = fieldType.getStruct();
const TString &fieldTypeString = fieldStruct ? structureTypeName(*fieldStruct, useHLSLRowMajorPacking, useStd140Packing) : typeString(fieldType);
if (useStd140Packing) if (useStd140Packing)
{ {
structure += std140PrePaddingString(field, &elementIndex); string += std140PrePaddingString(*field.type(), &elementIndex);
} }
structure += " " + structureTypeName(field, useHLSLRowMajorPacking, useStd140Packing) + " " + string += " " + fieldTypeString + " " + decorateField(field.name(), structure) + arrayString(fieldType) + ";\n";
decorateField(field.getFieldName(), structType) + arrayString(field) + ";\n";
if (useStd140Packing) if (useStd140Packing)
{ {
structure += std140PostPaddingString(field, useHLSLRowMajorPacking); string += std140PostPaddingString(*field.type(), useHLSLRowMajorPacking);
} }
} }
// Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable
structure += (isNameless ? "} " : "};\n"); string += (isNameless ? "} " : "};\n");
// Add remaining element index to the global map, for use with nested structs in standard layouts // Add remaining element index to the global map, for use with nested structs in standard layouts
if (useStd140Packing) if (useStd140Packing)
...@@ -3081,17 +3097,12 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo ...@@ -3081,17 +3097,12 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo
mStd140StructElementIndexes[structName] = elementIndex; mStd140StructElementIndexes[structName] = elementIndex;
} }
return structure; return string;
} }
TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing) TString OutputHLSL::structureTypeName(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing)
{ {
if (structType.getBasicType() != EbtStruct) if (structure.name() == "")
{
return typeString(structType);
}
if (structType.getTypeName() == "")
{ {
return ""; return "";
} }
...@@ -3112,7 +3123,7 @@ TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMa ...@@ -3112,7 +3123,7 @@ TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMa
prefix += "rm"; prefix += "rm";
} }
return prefix + typeString(structType); return prefix + structLookup(structure.name());
} }
void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
...@@ -3137,37 +3148,38 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ...@@ -3137,37 +3148,38 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
typedef std::vector<TType> ParameterArray; typedef std::vector<TType> ParameterArray;
ParameterArray ctorParameters; ParameterArray ctorParameters;
if (type.getStruct()) const TStructure* structure = type.getStruct();
if (structure)
{ {
mStructNames.insert(decorate(name)); mStructNames.insert(decorate(name));
const TString &structure = structureString(type, false, false); const TString &structString = structureString(*structure, false, false);
if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end()) if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end())
{ {
// Add row-major packed struct for interface blocks // Add row-major packed struct for interface blocks
TString rowMajorString = "#pragma pack_matrix(row_major)\n" + TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
structureString(type, true, false) + structureString(*structure, true, false) +
"#pragma pack_matrix(column_major)\n"; "#pragma pack_matrix(column_major)\n";
const TString &std140Prefix = "std"; const TString &std140Prefix = "std";
TString std140String = structureString(type, false, true); TString std140String = structureString(*structure, false, true);
const TString &std140RowMajorPrefix = "std_rm"; const TString &std140RowMajorPrefix = "std_rm";
TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" + TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
structureString(type, true, true) + structureString(*structure, true, true) +
"#pragma pack_matrix(column_major)\n"; "#pragma pack_matrix(column_major)\n";
mStructDeclarations.push_back(structure); mStructDeclarations.push_back(structString);
mStructDeclarations.push_back(rowMajorString); mStructDeclarations.push_back(rowMajorString);
mStructDeclarations.push_back(std140String); mStructDeclarations.push_back(std140String);
mStructDeclarations.push_back(std140RowMajorString); mStructDeclarations.push_back(std140RowMajorString);
} }
const TTypeList &fields = *type.getStruct(); const TFieldList &fields = structure->fields();
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
ctorParameters.push_back(*fields[i].type); ctorParameters.push_back(*fields[i]->type());
} }
} }
else if (parameters) else if (parameters)
...@@ -3338,19 +3350,20 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -3338,19 +3350,20 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
{ {
TInfoSinkBase &out = mBody; TInfoSinkBase &out = mBody;
if (type.getBasicType() == EbtStruct) const TStructure* structure = type.getStruct();
if (structure)
{ {
out << structLookup(type.getTypeName()) + "_ctor("; out << structLookup(structure->name()) + "_ctor(";
const TTypeList *structure = type.getStruct(); const TFieldList& fields = structure->fields();
for (size_t i = 0; i < structure->size(); i++) for (size_t i = 0; i < fields.size(); i++)
{ {
const TType *fieldType = (*structure)[i].type; const TType *fieldType = fields[i]->type();
constUnion = writeConstantUnion(*fieldType, constUnion); constUnion = writeConstantUnion(*fieldType, constUnion);
if (i != structure->size() - 1) if (i != fields.size() - 1)
{ {
out << ", "; out << ", ";
} }
...@@ -3456,9 +3469,9 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type) ...@@ -3456,9 +3469,9 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type)
return decorate(string); return decorate(string);
} }
TString OutputHLSL::decorateField(const TString &string, const TType &structure) TString OutputHLSL::decorateField(const TString &string, const TStructure &structure)
{ {
if (structure.getTypeName().compare(0, 3, "gl_") != 0) if (structure.name().compare(0, 3, "gl_") != 0)
{ {
return decorate(string); return decorate(string);
} }
...@@ -3504,31 +3517,32 @@ int OutputHLSL::uniformRegister(TIntermSymbol *uniform) ...@@ -3504,31 +3517,32 @@ int OutputHLSL::uniformRegister(TIntermSymbol *uniform)
return index; return index;
} }
void OutputHLSL::declareUniformToList(const TType &type, const TString &name, int index, ActiveUniforms& output) void OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, ActiveUniforms& output)
{ {
const TTypeList *structure = type.getStruct(); const TStructure *structure = type.getStruct();
if (!structure) if (!structure)
{ {
const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor); const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor);
output.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize(), (unsigned int)index, isRowMajorMatrix)); output.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize(), (unsigned int)registerIndex, isRowMajorMatrix));
} }
else else
{ {
Uniform structUniform(GL_NONE, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), (unsigned int)index, false); Uniform structUniform(GL_NONE, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), (unsigned int)registerIndex, false);
int fieldIndex = index; int fieldRegister = registerIndex;
const TFieldList &fields = structure->fields();
for (size_t i = 0; i < structure->size(); i++) for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{ {
TType fieldType = *(*structure)[i].type; TField *field = fields[fieldIndex];
const TString &fieldName = fieldType.getFieldName(); TType *fieldType = field->type();
// make sure to copy matrix packing information // make sure to copy matrix packing information
fieldType.setLayoutQualifier(type.getLayoutQualifier()); fieldType->setLayoutQualifier(type.getLayoutQualifier());
declareUniformToList(fieldType, fieldName, fieldIndex, structUniform.fields); declareUniformToList(*fieldType, field->name(), fieldRegister, structUniform.fields);
fieldIndex += fieldType.totalRegisterCount(); fieldRegister += fieldType->totalRegisterCount();
} }
output.push_back(structUniform); output.push_back(structUniform);
......
...@@ -40,14 +40,14 @@ class OutputHLSL : public TIntermTraverser ...@@ -40,14 +40,14 @@ class OutputHLSL : public TIntermTraverser
TString typeString(const TType &type); TString typeString(const TType &type);
TString textureString(const TType &type); TString textureString(const TType &type);
TString interpolationString(TQualifier qualifier); TString interpolationString(TQualifier qualifier);
TString structureString(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing); TString structureString(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
TString structureTypeName(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing); TString structureTypeName(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
static TString qualifierString(TQualifier qualifier); static TString qualifierString(TQualifier qualifier);
static TString arrayString(const TType &type); static TString arrayString(const TType &type);
static TString initializer(const TType &type); static TString initializer(const TType &type);
static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes
static TString decorateUniform(const TString &string, const TType &type); static TString decorateUniform(const TString &string, const TType &type);
static TString decorateField(const TString &string, const TType &structure); static TString decorateField(const TString &string, const TStructure &structure);
protected: protected:
void header(); void header();
...@@ -187,20 +187,20 @@ class OutputHLSL : public TIntermTraverser ...@@ -187,20 +187,20 @@ class OutputHLSL : public TIntermTraverser
TString registerString(TIntermSymbol *operand); TString registerString(TIntermSymbol *operand);
int samplerRegister(TIntermSymbol *sampler); int samplerRegister(TIntermSymbol *sampler);
int uniformRegister(TIntermSymbol *uniform); int uniformRegister(TIntermSymbol *uniform);
void declareUniformToList(const TType &type, const TString &name, int index, ActiveUniforms& output); void declareUniformToList(const TType &type, const TString &name, int registerIndex, ActiveUniforms& output);
void declareUniform(const TType &type, const TString &name, int index); void declareUniform(const TType &type, const TString &name, int index);
TString interfaceBlockUniformName(const TType &interfaceBlockType, const TType &uniformType); TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field);
TString decoratePrivate(const TString &privateText); TString decoratePrivate(const TString &privateText);
TString interfaceBlockStructName(const TType &interfaceBlockType); TString interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlockType);
TString interfaceBlockInstanceString(const TType& interfaceBlockType, unsigned int arrayIndex); TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
TString interfaceBlockMemberTypeString(const TType &memberType, TLayoutBlockStorage blockStorage); TString interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage);
TString interfaceBlockMemberString(const TTypeList &typeList, TLayoutBlockStorage blockStorage); TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
TString interfaceBlockStructString(const TType &interfaceBlockType); TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
TString interfaceBlockString(const TType &interfaceBlockType, unsigned int registerIndex, unsigned int arrayIndex); TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
TString std140PrePaddingString(const TType &type, int *elementIndex); TString std140PrePaddingString(const TType &type, int *elementIndex);
TString std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking); TString std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking);
TString structInitializerString(int indent, const TTypeList &structMembers, const TString &structName); TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
static GLenum glVariableType(const TType &type); static GLenum glVariableType(const TType &type);
static GLenum glVariablePrecision(const TType &type); static GLenum glVariablePrecision(const TType &type);
......
...@@ -532,7 +532,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n ...@@ -532,7 +532,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n
return true; return true;
} }
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) { if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
return true; return true;
} }
...@@ -672,10 +672,10 @@ bool TParseContext::containsSampler(TType& type) ...@@ -672,10 +672,10 @@ bool TParseContext::containsSampler(TType& type)
if (IsSampler(type.getBasicType())) if (IsSampler(type.getBasicType()))
return true; return true;
if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtInterfaceBlock) { if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
TTypeList& structure = *type.getStruct(); const TFieldList& fields = type.getStruct()->fields();
for (unsigned int i = 0; i < structure.size(); ++i) { for (unsigned int i = 0; i < fields.size(); ++i) {
if (containsSampler(*structure[i].type)) if (containsSampler(*fields[i]->type()))
return true; return true;
} }
} }
...@@ -1503,9 +1503,9 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type ...@@ -1503,9 +1503,9 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
TIntermAggregate* aggrNode = node->getAsAggregate(); TIntermAggregate* aggrNode = node->getAsAggregate();
TTypeList::const_iterator memberTypes; TFieldList::const_iterator memberTypes;
if (op == EOpConstructStruct) if (op == EOpConstructStruct)
memberTypes = type->getStruct()->begin(); memberTypes = type->getStruct()->fields().begin();
TType elementType = *type; TType elementType = *type;
if (type->isArray()) if (type->isArray())
...@@ -1527,7 +1527,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type ...@@ -1527,7 +1527,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
if (type->isArray()) if (type->isArray())
newNode = constructStruct(node, &elementType, 1, node->getLine(), false); newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
else if (op == EOpConstructStruct) else if (op == EOpConstructStruct)
newNode = constructStruct(node, (*memberTypes).type, 1, node->getLine(), false); newNode = constructStruct(node, (*memberTypes)->type(), 1, node->getLine(), false);
else else
newNode = constructBuiltIn(type, op, node, node->getLine(), false); newNode = constructBuiltIn(type, op, node, node->getLine(), false);
...@@ -1558,7 +1558,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type ...@@ -1558,7 +1558,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
if (type->isArray()) if (type->isArray())
newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true); newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
else if (op == EOpConstructStruct) else if (op == EOpConstructStruct)
newNode = constructStruct(*p, (memberTypes[paramCount]).type, paramCount+1, node->getLine(), true); newNode = constructStruct(*p, (memberTypes[paramCount])->type(), paramCount+1, node->getLine(), true);
else else
newNode = constructBuiltIn(type, op, *p, node->getLine(), true); newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
...@@ -1817,14 +1817,14 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, co ...@@ -1817,14 +1817,14 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, co
// //
TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line) TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line)
{ {
const TTypeList* fields = node->getType().getStruct(); const TFieldList& fields = node->getType().getStruct()->fields();
size_t instanceSize = 0; size_t instanceSize = 0;
for (size_t index = 0; index < fields->size(); ++index) { for (size_t index = 0; index < fields.size(); ++index) {
if ((*fields)[index].type->getFieldName() == identifier) { if (fields[index]->name() == identifier) {
break; break;
} else { } else {
instanceSize += (*fields)[index].type->getObjectSize(); instanceSize += fields[index]->type()->getObjectSize();
} }
} }
...@@ -1847,8 +1847,8 @@ TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTy ...@@ -1847,8 +1847,8 @@ TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTy
// //
// Interface/uniform blocks // Interface/uniform blocks
// //
TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TTypeList* typeList, TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
const TString& instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine) const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
{ {
if (reservedErrorCheck(nameLine, blockName)) if (reservedErrorCheck(nameLine, blockName))
recover(); recover();
...@@ -1881,94 +1881,95 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif ...@@ -1881,94 +1881,95 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif
recover(); recover();
} }
// check for sampler types // check for sampler types and apply layout qualifiers
for (size_t memberIndex = 0; memberIndex < typeList->size(); ++memberIndex) { for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) {
const TTypeLine& memberTypeLine = (*typeList)[memberIndex]; TField* field = (*fieldList)[memberIndex];
TType* memberType = memberTypeLine.type; TType* fieldType = field->type();
if (IsSampler(memberType->getBasicType())) { if (IsSampler(fieldType->getBasicType())) {
error(memberTypeLine.line, "unsupported type", memberType->getBasicString(), "sampler types are not allowed in interface blocks"); error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks");
recover(); recover();
} }
const TQualifier qualifier = memberTypeLine.type->getQualifier(); const TQualifier qualifier = fieldType->getQualifier();
switch (qualifier) switch (qualifier)
{ {
case EvqGlobal: case EvqGlobal:
case EvqUniform: case EvqUniform:
break; break;
default: default:
error(memberTypeLine.line, "invalid qualifier on interface block member", getQualifierString(qualifier)); error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier));
recover(); recover();
break; break;
} }
// check layout qualifiers // check layout qualifiers
TLayoutQualifier memberLayoutQualifier = memberType->getLayoutQualifier(); TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
if (layoutLocationErrorCheck(memberTypeLine.line, memberLayoutQualifier)) if (layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
{ {
recover(); recover();
} }
if (memberLayoutQualifier.blockStorage != EbsUnspecified) if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
{ {
error(memberTypeLine.line, "invalid layout qualifier:", getBlockStorageString(memberLayoutQualifier.blockStorage), "cannot be used here"); error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
recover(); recover();
} }
if (memberLayoutQualifier.matrixPacking == EmpUnspecified) if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
{ {
memberLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking; fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
} }
else if (!memberType->isMatrix()) else if (!fieldType->isMatrix())
{ {
error(memberTypeLine.line, "invalid layout qualifier:", getMatrixPackingString(memberLayoutQualifier.matrixPacking), "can only be used on matrix types"); error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types");
recover(); recover();
} }
memberType->setLayoutQualifier(memberLayoutQualifier); fieldType->setLayoutQualifier(fieldLayoutQualifier);
} }
TType* interfaceBlock = new TType(typeList, blockName); // add array index
interfaceBlock->setBasicType(EbtInterfaceBlock); int arraySize = 0;
interfaceBlock->setQualifier(typeQualifier.qualifier); if (arrayIndex != NULL)
interfaceBlock->setLayoutQualifier(blockLayoutQualifier); {
if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
recover();
}
TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize);
TString symbolName = ""; TString symbolName = "";
int symbolId = 0; int symbolId = 0;
if (instanceName == "") if (!instanceName)
{ {
// define symbols for the members of the interface block // define symbols for the members of the interface block
for (size_t memberIndex = 0; memberIndex < typeList->size(); ++memberIndex) { for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
const TTypeLine& memberTypeLine = (*typeList)[memberIndex]; {
TType* memberType = memberTypeLine.type; TField* field = (*fieldList)[memberIndex];
memberType->setInterfaceBlockType(interfaceBlock); TType* fieldType = field->type();
TVariable* memberVariable = new TVariable(&memberType->getFieldName(), *memberType);
memberVariable->setQualifier(typeQualifier.qualifier); // set parent pointer of the field variable
if (!symbolTable.declare(*memberVariable)) { fieldType->setInterfaceBlock(interfaceBlock);
error(memberTypeLine.line, "redefinition", memberType->getFieldName().c_str(), "interface block member name");
TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
fieldVariable->setQualifier(typeQualifier.qualifier);
if (!symbolTable.declare(*fieldVariable)) {
error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
recover(); recover();
} }
} }
} }
else else
{ {
interfaceBlock->setInstanceName(instanceName);
// add array index
if (arrayIndex != NULL)
{
int size;
if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, size))
recover();
interfaceBlock->setArraySize(size);
}
// add a symbol for this interface block // add a symbol for this interface block
TVariable* instanceTypeDef = new TVariable(&instanceName, *interfaceBlock, false); TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
instanceTypeDef->setQualifier(typeQualifier.qualifier); instanceTypeDef->setQualifier(typeQualifier.qualifier);
if (!symbolTable.declare(*instanceTypeDef)) { if (!symbolTable.declare(*instanceTypeDef)) {
error(instanceLine, "redefinition", instanceName.c_str(), "interface block instance name"); error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
recover(); recover();
} }
...@@ -1976,9 +1977,10 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif ...@@ -1976,9 +1977,10 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif
symbolName = instanceTypeDef->getName(); symbolName = instanceTypeDef->getName();
} }
exitStructDeclaration(); TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine);
TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, *interfaceBlock, typeQualifier.line), nameLine);
aggregate->setOp(EOpDeclaration); aggregate->setOp(EOpDeclaration);
exitStructDeclaration();
return aggregate; return aggregate;
} }
...@@ -2008,21 +2010,21 @@ const int kWebGLMaxStructNesting = 4; ...@@ -2008,21 +2010,21 @@ const int kWebGLMaxStructNesting = 4;
} // namespace } // namespace
bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType) bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field)
{ {
if (!isWebGLBasedSpec(shaderSpec)) { if (!isWebGLBasedSpec(shaderSpec)) {
return false; return false;
} }
if (fieldType.getBasicType() != EbtStruct) { if (field.type()->getBasicType() != EbtStruct) {
return false; return false;
} }
// We're already inside a structure definition at this point, so add // We're already inside a structure definition at this point, so add
// one to the field's struct nesting. // one to the field's struct nesting.
if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) { if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "Reference of struct type " << fieldType.getTypeName() extraInfoStream << "Reference of struct type " << field.type()->getStruct()->name()
<< " exceeds maximum struct nesting of " << kWebGLMaxStructNesting; << " exceeds maximum struct nesting of " << kWebGLMaxStructNesting;
std::string extraInfo = extraInfoStream.str(); std::string extraInfo = extraInfoStream.str();
error(line, "", "", extraInfo.c_str()); error(line, "", "", extraInfo.c_str());
...@@ -2115,7 +2117,7 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co ...@@ -2115,7 +2117,7 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
} }
else else
{ {
if (baseExpression->getBasicType() == EbtInterfaceBlock) if (baseExpression->isInterfaceBlock())
{ {
error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions"); error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions");
recover(); recover();
...@@ -2137,10 +2139,15 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co ...@@ -2137,10 +2139,15 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
} }
else if (baseExpression->isArray()) else if (baseExpression->isArray())
{ {
if (baseExpression->getType().getStruct()) const TType &baseType = baseExpression->getType();
if (baseType.getStruct())
{
TType copyOfType(baseType.getStruct());
indexedExpression->setType(copyOfType);
}
else if (baseType.isInterfaceBlock())
{ {
TType copyOfType(baseExpression->getType().getStruct(), baseExpression->getType().getTypeName()); TType copyOfType(baseType.getInterfaceBlock(), baseType.getQualifier(), baseType.getLayoutQualifier(), 0);
copyOfType.setBasicType(baseExpression->getType().getBasicType()); // necessary to preserve interface block basic type
indexedExpression->setType(copyOfType); indexedExpression->setType(copyOfType);
} }
else else
...@@ -2247,8 +2254,8 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2247,8 +2254,8 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
else if (baseExpression->getBasicType() == EbtStruct) else if (baseExpression->getBasicType() == EbtStruct)
{ {
bool fieldFound = false; bool fieldFound = false;
const TTypeList* fields = baseExpression->getType().getStruct(); const TFieldList& fields = baseExpression->getType().getStruct()->fields();
if (fields == 0) if (fields.empty())
{ {
error(dotLocation, "structure has no fields", "Internal Error"); error(dotLocation, "structure has no fields", "Internal Error");
recover(); recover();
...@@ -2257,9 +2264,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2257,9 +2264,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
else else
{ {
unsigned int i; unsigned int i;
for (i = 0; i < fields->size(); ++i) for (i = 0; i < fields.size(); ++i)
{ {
if ((*fields)[i].type->getFieldName() == fieldString) if (fields[i]->name() == fieldString)
{ {
fieldFound = true; fieldFound = true;
break; break;
...@@ -2277,7 +2284,7 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2277,7 +2284,7 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
} }
else else
{ {
indexedExpression->setType(*(*fields)[i].type); indexedExpression->setType(*fields[i]->type());
// change the qualifier of the return type, not of the structure field // change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures. // as the structure definition is shared between various structures.
indexedExpression->getTypePointer()->setQualifier(EvqConst); indexedExpression->getTypePointer()->setQualifier(EvqConst);
...@@ -2287,9 +2294,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2287,9 +2294,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
{ {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i); unionArray->setIConst(i);
TIntermTyped* index = intermediate.addConstantUnion(unionArray, *(*fields)[i].type, fieldLocation); TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation); indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation);
indexedExpression->setType(*(*fields)[i].type); indexedExpression->setType(*fields[i]->type());
} }
} }
else else
...@@ -2300,11 +2307,11 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2300,11 +2307,11 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
} }
} }
} }
else if (baseExpression->getBasicType() == EbtInterfaceBlock) else if (baseExpression->isInterfaceBlock())
{ {
bool fieldFound = false; bool fieldFound = false;
const TTypeList* fields = baseExpression->getType().getStruct(); const TFieldList& fields = baseExpression->getType().getInterfaceBlock()->fields();
if (fields == 0) if (fields.empty())
{ {
error(dotLocation, "interface block has no fields", "Internal Error"); error(dotLocation, "interface block has no fields", "Internal Error");
recover(); recover();
...@@ -2313,9 +2320,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2313,9 +2320,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
else else
{ {
unsigned int i; unsigned int i;
for (i = 0; i < fields->size(); ++i) for (i = 0; i < fields.size(); ++i)
{ {
if ((*fields)[i].type->getFieldName() == fieldString) if (fields[i]->name() == fieldString)
{ {
fieldFound = true; fieldFound = true;
break; break;
...@@ -2325,9 +2332,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2325,9 +2332,9 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
{ {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i); unionArray->setIConst(i);
TIntermTyped* index = intermediate.addConstantUnion(unionArray, *(*fields)[i].type, fieldLocation); TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, dotLocation); indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, dotLocation);
indexedExpression->setType(*(*fields)[i].type); indexedExpression->setType(*fields[i]->type());
} }
else else
{ {
...@@ -2446,17 +2453,17 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif ...@@ -2446,17 +2453,17 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif
return joinedQualifier; return joinedQualifier;
} }
TTypeList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifier, TTypeList *typeList) TFieldList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList)
{ {
if (voidErrorCheck(typeSpecifier.line, (*typeList)[0].type->getFieldName(), typeSpecifier)) { if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier)) {
recover(); recover();
} }
for (unsigned int i = 0; i < typeList->size(); ++i) { for (unsigned int i = 0; i < fieldList->size(); ++i) {
// //
// Careful not to replace already known aspects of type, like array-ness // Careful not to replace already known aspects of type, like array-ness
// //
TType* type = (*typeList)[i].type; TType* type = (*fieldList)[i]->type();
type->setBasicType(typeSpecifier.type); type->setBasicType(typeSpecifier.type);
type->setPrimarySize(typeSpecifier.primarySize); type->setPrimarySize(typeSpecifier.primarySize);
type->setSecondarySize(typeSpecifier.secondarySize); type->setSecondarySize(typeSpecifier.secondarySize);
...@@ -2473,46 +2480,46 @@ TTypeList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifi ...@@ -2473,46 +2480,46 @@ TTypeList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifi
type->setArraySize(typeSpecifier.arraySize); type->setArraySize(typeSpecifier.arraySize);
if (typeSpecifier.userDef) { if (typeSpecifier.userDef) {
type->setStruct(typeSpecifier.userDef->getStruct()); type->setStruct(typeSpecifier.userDef->getStruct());
type->setTypeName(typeSpecifier.userDef->getTypeName());
} }
if (structNestingErrorCheck(typeSpecifier.line, *type)) { if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) {
recover(); recover();
} }
} }
return typeList; return fieldList;
} }
TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString &structName, TTypeList* typeList) TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList)
{ {
TType* structure = new TType(typeList, structName); TStructure* structure = new TStructure(structName, fieldList);
TType* structureType = new TType(structure);
if (!structName.empty()) if (!structName->empty())
{ {
if (reservedErrorCheck(nameLine, structName)) if (reservedErrorCheck(nameLine, *structName))
{ {
recover(); recover();
} }
TVariable* userTypeDef = new TVariable(&structName, *structure, true); TVariable* userTypeDef = new TVariable(structName, *structureType, true);
if (!symbolTable.declare(*userTypeDef)) { if (!symbolTable.declare(*userTypeDef)) {
error(nameLine, "redefinition", structName.c_str(), "struct"); error(nameLine, "redefinition", structName->c_str(), "struct");
recover(); recover();
} }
} }
// ensure we do not specify any storage qualifiers on the struct members // ensure we do not specify any storage qualifiers on the struct members
for (unsigned int typeListIndex = 0; typeListIndex < typeList->size(); typeListIndex++) for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
{ {
const TTypeLine &typeLine = (*typeList)[typeListIndex]; const TField &field = *(*fieldList)[typeListIndex];
const TQualifier qualifier = typeLine.type->getQualifier(); const TQualifier qualifier = field.type()->getQualifier();
switch (qualifier) switch (qualifier)
{ {
case EvqGlobal: case EvqGlobal:
case EvqTemporary: case EvqTemporary:
break; break;
default: default:
error(typeLine.line, "invalid qualifier on struct member", getQualifierString(qualifier)); error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier));
recover(); recover();
break; break;
} }
...@@ -2520,7 +2527,7 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou ...@@ -2520,7 +2527,7 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou
TPublicType publicType; TPublicType publicType;
publicType.setBasic(EbtStruct, EvqTemporary, structLine); publicType.setBasic(EbtStruct, EvqTemporary, structLine);
publicType.userDef = structure; publicType.userDef = structureType;
exitStructDeclaration(); exitStructDeclaration();
return publicType; return publicType;
......
...@@ -142,11 +142,11 @@ struct TParseContext { ...@@ -142,11 +142,11 @@ struct TParseContext {
TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression); TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation); TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation);
TTypeList *addStructDeclaratorList(const TPublicType& typeSpecifier, TTypeList *typeList); TFieldList *addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList);
TPublicType addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString &structName, TTypeList* typeList); TPublicType addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList);
TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TTypeList* typeList, TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
const TString& instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine); const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine);
TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine); TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine); TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
...@@ -158,7 +158,7 @@ struct TParseContext { ...@@ -158,7 +158,7 @@ struct TParseContext {
bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier); bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier);
void exitStructDeclaration(); void exitStructDeclaration();
bool structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType); bool structNestingErrorCheck(const TSourceLoc& line, const TField& field);
}; };
int PaParseStrings(size_t count, const char* const string[], const int length[], int PaParseStrings(size_t count, const char* const string[], const int length[],
......
...@@ -23,20 +23,19 @@ int TSymbolTableLevel::uniqueId = 0; ...@@ -23,20 +23,19 @@ int TSymbolTableLevel::uniqueId = 0;
TType::TType(const TPublicType &p) : TType::TType(const TPublicType &p) :
type(p.type), precision(p.precision), qualifier(p.qualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), layoutQualifier(p.layoutQualifier), arraySize(p.arraySize), type(p.type), precision(p.precision), qualifier(p.qualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), layoutQualifier(p.layoutQualifier), arraySize(p.arraySize),
interfaceBlockType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0) interfaceBlock(0), structure(0)
{ {
if (p.userDef) { if (p.userDef) {
structure = p.userDef->getStruct(); structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
computeDeepestStructNesting();
} }
} }
// //
// Recursively generate mangled names. // Recursively generate mangled names.
// //
void TType::buildMangledName(TString& mangledName) TString TType::buildMangledName() const
{ {
TString mangledName;
if (isMatrix()) if (isMatrix())
mangledName += 'm'; mangledName += 'm';
else if (isVector()) else if (isVector())
...@@ -45,7 +44,6 @@ void TType::buildMangledName(TString& mangledName) ...@@ -45,7 +44,6 @@ void TType::buildMangledName(TString& mangledName)
switch (type) { switch (type) {
case EbtFloat: mangledName += 'f'; break; case EbtFloat: mangledName += 'f'; break;
case EbtInt: mangledName += 'i'; break; case EbtInt: mangledName += 'i'; break;
case EbtUInt: mangledName += 'u'; break;
case EbtBool: mangledName += 'b'; break; case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break; case EbtSampler2D: mangledName += "s2"; break;
case EbtSampler3D: mangledName += "s3"; break; case EbtSampler3D: mangledName += "s3"; break;
...@@ -59,33 +57,9 @@ void TType::buildMangledName(TString& mangledName) ...@@ -59,33 +57,9 @@ void TType::buildMangledName(TString& mangledName)
case EbtUSampler3D: mangledName += "us3"; break; case EbtUSampler3D: mangledName += "us3"; break;
case EbtUSamplerCube: mangledName += "usC"; break; case EbtUSamplerCube: mangledName += "usC"; break;
case EbtUSampler2DArray: mangledName += "us2a"; break; case EbtUSampler2DArray: mangledName += "us2a"; break;
case EbtStruct: case EbtStruct: mangledName += structure->mangledName(); break;
mangledName += "struct-"; case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
if (typeName) default: break;
mangledName += *typeName;
{// support MSVC++6.0
for (unsigned int i = 0; i < structure->size(); ++i) {
mangledName += '-';
(*structure)[i].type->buildMangledName(mangledName);
}
}
break;
case EbtInterfaceBlock:
{
mangledName += "interface-block-";
if (typeName)
{
mangledName += *typeName;
}
for (unsigned int i = 0; i < structure->size(); ++i)
{
mangledName += '-';
(*structure)[i].type->buildMangledName(mangledName);
}
}
break;
default:
break;
} }
if (isMatrix()) if (isMatrix())
...@@ -98,6 +72,7 @@ void TType::buildMangledName(TString& mangledName) ...@@ -98,6 +72,7 @@ void TType::buildMangledName(TString& mangledName)
{ {
mangledName += static_cast<char>('0' + getNominalSize()); mangledName += static_cast<char>('0' + getNominalSize());
} }
if (isArray()) { if (isArray()) {
char buf[20]; char buf[20];
snprintf(buf, sizeof(buf), "%d", arraySize); snprintf(buf, sizeof(buf), "%d", arraySize);
...@@ -105,6 +80,7 @@ void TType::buildMangledName(TString& mangledName) ...@@ -105,6 +80,7 @@ void TType::buildMangledName(TString& mangledName)
mangledName += buf; mangledName += buf;
mangledName += ']'; mangledName += ']';
} }
return mangledName;
} }
size_t TType::getObjectSize() const size_t TType::getObjectSize() const
...@@ -112,7 +88,7 @@ size_t TType::getObjectSize() const ...@@ -112,7 +88,7 @@ size_t TType::getObjectSize() const
size_t totalSize; size_t totalSize;
if (getBasicType() == EbtStruct) if (getBasicType() == EbtStruct)
totalSize = getStructSize(); totalSize = structure->objectSize();
else else
totalSize = primarySize * secondarySize; totalSize = primarySize * secondarySize;
...@@ -127,57 +103,47 @@ size_t TType::getObjectSize() const ...@@ -127,57 +103,47 @@ size_t TType::getObjectSize() const
return totalSize; return totalSize;
} }
size_t TType::getStructSize() const bool TStructure::containsArrays() const
{ {
if (!getStruct()) { for (size_t i = 0; i < mFields->size(); ++i) {
assert(false && "Not a struct"); const TType* fieldType = (*mFields)[i]->type();
return 0; if (fieldType->isArray() || fieldType->isStructureContainingArrays())
} return true;
if (structureSize == 0) {
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++) {
size_t fieldSize = ((*tl).type)->getObjectSize();
if (fieldSize > INT_MAX - structureSize)
structureSize = INT_MAX;
else
structureSize += fieldSize;
}
} }
return false;
return structureSize;
} }
void TType::computeDeepestStructNesting() TString TFieldListCollection::buildMangledName() const
{ {
if (!getStruct()) { TString mangledName(mangledNamePrefix());
return; mangledName += *mName;
} for (size_t i = 0; i < mFields->size(); ++i) {
mangledName += '-';
int maxNesting = 0; mangledName += (*mFields)[i]->type()->getMangledName();
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
} }
return mangledName;
deepestStructNesting = 1 + maxNesting;
} }
bool TType::isStructureContainingArrays() const size_t TFieldListCollection::calculateObjectSize() const
{ {
if (!structure) size_t size = 0;
{ for (size_t i = 0; i < mFields->size(); ++i) {
return false; size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
if (fieldSize > INT_MAX - size)
size = INT_MAX;
else
size += fieldSize;
} }
return size;
}
for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++) int TStructure::calculateDeepestNesting() const
{ {
if (member->type->isArray() || int maxNesting = 0;
member->type->isStructureContainingArrays()) for (size_t i = 0; i < mFields->size(); ++i) {
{ maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
return true;
}
} }
return 1 + maxNesting;
return false;
} }
// //
......
...@@ -7,28 +7,131 @@ ...@@ -7,28 +7,131 @@
#ifndef _TYPES_INCLUDED #ifndef _TYPES_INCLUDED
#define _TYPES_INCLUDED #define _TYPES_INCLUDED
#include "common/angleutils.h"
#include "compiler/BaseTypes.h" #include "compiler/BaseTypes.h"
#include "compiler/Common.h" #include "compiler/Common.h"
#include "compiler/debug.h" #include "compiler/debug.h"
class TType;
struct TPublicType; struct TPublicType;
class TType;
// class TField
// Need to have association of line numbers to types in a list for building structs. {
// public:
struct TTypeLine { POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator);
TType* type; TField(TType* type, TString* name, const TSourceLoc& line) : mType(type), mName(name), mLine(line) {}
TSourceLoc line;
// TODO(alokp): We should only return const type.
// Fix it by tweaking grammar.
TType* type() { return mType; }
const TType* type() const { return mType; }
const TString& name() const { return *mName; }
const TSourceLoc& line() const { return mLine; }
private:
DISALLOW_COPY_AND_ASSIGN(TField);
TType* mType;
TString* mName;
TSourceLoc mLine;
}; };
typedef TVector<TTypeLine> TTypeList;
inline TTypeList* NewPoolTTypeList() typedef TVector<TField*> TFieldList;
inline TFieldList* NewPoolTFieldList()
{ {
void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList)); void* memory = GlobalPoolAllocator.allocate(sizeof(TFieldList));
return new(memory) TTypeList; return new(memory) TFieldList;
} }
class TFieldListCollection
{
public:
const TString& name() const { return *mName; }
const TFieldList& fields() const { return *mFields; }
const TString& mangledName() const {
if (mMangledName.empty())
mMangledName = buildMangledName();
return mMangledName;
}
size_t objectSize() const {
if (mObjectSize == 0)
mObjectSize = calculateObjectSize();
return mObjectSize;
};
protected:
TFieldListCollection(const TString* name, TFieldList* fields)
: mName(name),
mFields(fields),
mObjectSize(0) {
}
TString buildMangledName() const;
size_t calculateObjectSize() const;
virtual TString mangledNamePrefix() const = 0;
const TString* mName;
TFieldList* mFields;
mutable TString mMangledName;
mutable size_t mObjectSize;
};
// May also represent interface blocks
class TStructure : public TFieldListCollection
{
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator);
TStructure(const TString* name, TFieldList* fields)
: TFieldListCollection(name, fields),
mDeepestNesting(0) {
}
int deepestNesting() const {
if (mDeepestNesting == 0)
mDeepestNesting = calculateDeepestNesting();
return mDeepestNesting;
}
bool containsArrays() const;
private:
DISALLOW_COPY_AND_ASSIGN(TStructure);
virtual TString mangledNamePrefix() const { return "struct-"; }
int calculateDeepestNesting() const;
mutable int mDeepestNesting;
};
class TInterfaceBlock : public TFieldListCollection
{
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator);
TInterfaceBlock(const TString* name, TFieldList* fields, const TString* instanceName, int arraySize, const TLayoutQualifier& layoutQualifier)
: TFieldListCollection(name, fields),
mInstanceName(instanceName),
mArraySize(arraySize),
mBlockStorage(layoutQualifier.blockStorage),
mMatrixPacking(layoutQualifier.matrixPacking) {
}
const TString& instanceName() const { return *mInstanceName; }
bool hasInstanceName() const { return mInstanceName != NULL; }
bool isArray() const { return mArraySize > 0; }
int arraySize() const { return mArraySize; }
TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
TLayoutMatrixPacking matrixPacking() const { return mMatrixPacking; }
private:
DISALLOW_COPY_AND_ASSIGN(TInterfaceBlock);
virtual TString mangledNamePrefix() const { return "iblock-"; }
const TString* mInstanceName; // for interface block instance names
int mArraySize; // 0 if not an array
TLayoutBlockStorage mBlockStorage;
TLayoutMatrixPacking mMatrixPacking;
};
// //
// Base class for things that have a type. // Base class for things that have a type.
// //
...@@ -39,15 +142,19 @@ public: ...@@ -39,15 +142,19 @@ public:
TType() {} TType() {}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int ps = 1, int ss = 1, bool a = false) : TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int ps = 1, int ss = 1, bool a = false) :
type(t), precision(p), qualifier(q), primarySize(ps), secondarySize(ss), array(a), layoutQualifier(TLayoutQualifier::create()), arraySize(0), type(t), precision(p), qualifier(q), primarySize(ps), secondarySize(ss), array(a), layoutQualifier(TLayoutQualifier::create()), arraySize(0),
interfaceBlockType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0), instanceName(0) interfaceBlock(0), structure(0)
{ {
} }
explicit TType(const TPublicType &p); explicit TType(const TPublicType &p);
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) : TType(TStructure* userDef, TPrecision p = EbpUndefined) :
type(EbtStruct), precision(p), qualifier(EvqTemporary), primarySize(1), secondarySize(1), array(false), layoutQualifier(TLayoutQualifier::create()), arraySize(0), type(EbtStruct), precision(p), qualifier(EvqTemporary), primarySize(1), secondarySize(1), array(false), layoutQualifier(TLayoutQualifier::create()), arraySize(0),
interfaceBlockType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), instanceName(0) interfaceBlock(0), structure(userDef)
{
}
TType(TInterfaceBlock* interfaceBlockIn, TQualifier qualifierIn, TLayoutQualifier layoutQualifierIn, int arraySizeIn) :
type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn), primarySize(1), secondarySize(1), array(arraySizeIn > 0), layoutQualifier(layoutQualifierIn), arraySize(arraySizeIn),
interfaceBlock(interfaceBlockIn), structure(0)
{ {
typeName = NewPoolTString(n.c_str());
} }
TBasicType getBasicType() const { return type; } TBasicType getBasicType() const { return type; }
...@@ -74,15 +181,14 @@ public: ...@@ -74,15 +181,14 @@ public:
int elementRegisterCount() const int elementRegisterCount() const
{ {
TTypeList *structure = getStruct();
if (structure) if (structure)
{ {
const TFieldList& fields = structure->fields();
int registerCount = 0; int registerCount = 0;
for (size_t i = 0; i < structure->size(); i++) for (size_t i = 0; i < fields.size(); i++)
{ {
registerCount += (*structure)[i].type->totalRegisterCount(); registerCount += fields[i]->type()->totalRegisterCount();
} }
return registerCount; return registerCount;
...@@ -114,65 +220,25 @@ public: ...@@ -114,65 +220,25 @@ public:
int getArraySize() const { return arraySize; } int getArraySize() const { return arraySize; }
void setArraySize(int s) { array = true; arraySize = s; } void setArraySize(int s) { array = true; arraySize = s; }
void clearArrayness() { array = false; arraySize = 0; } void clearArrayness() { array = false; arraySize = 0; }
void setInterfaceBlockType(TType* t) { interfaceBlockType = t; }
TType* getInterfaceBlockType() const { return interfaceBlockType; } TInterfaceBlock* getInterfaceBlock() const { return interfaceBlock; }
bool isInterfaceBlockMember() const { return interfaceBlockType != NULL; } void setInterfaceBlock(TInterfaceBlock* interfaceBlockIn) { interfaceBlock = interfaceBlockIn; }
bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
bool isVector() const { return primarySize > 1 && secondarySize == 1; } bool isVector() const { return primarySize > 1 && secondarySize == 1; }
bool isScalar() const { return primarySize == 1 && secondarySize == 1 && !structure; } bool isScalar() const { return primarySize == 1 && secondarySize == 1 && !structure; }
bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); } bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
TTypeList* getStruct() const { return structure; } TStructure* getStruct() const { return structure; }
void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); } void setStruct(TStructure* s) { structure = s; }
const TString& getTypeName() const
{
assert(typeName);
return *typeName;
}
void setTypeName(const TString& n)
{
typeName = NewPoolTString(n.c_str());
}
bool isField() const { return fieldName != 0; }
const TString& getFieldName() const
{
assert(fieldName);
return *fieldName;
}
void setFieldName(const TString& n)
{
fieldName = NewPoolTString(n.c_str());
}
TString& getMangledName() {
if (!mangled) {
mangled = NewPoolTString("");
buildMangledName(*mangled);
*mangled += ';' ;
}
return *mangled;
}
void setInstanceName(const TString& n) const TString& getMangledName() {
{ if (mangled.empty()) {
assert(type == EbtInterfaceBlock); mangled = buildMangledName();
instanceName = NewPoolTString(n.c_str()); mangled += ';';
} }
bool hasInstanceName() const return mangled;
{
assert(type == EbtInterfaceBlock);
return instanceName != NULL;
}
const TString& getInstanceName() const
{
assert(type == EbtInterfaceBlock);
assert(instanceName);
return *instanceName;
} }
bool sameElementType(const TType& right) const { bool sameElementType(const TType& right) const {
...@@ -220,12 +286,16 @@ public: ...@@ -220,12 +286,16 @@ public:
// For type "nesting2", this method would return 2 -- the number // For type "nesting2", this method would return 2 -- the number
// of structures through which indirection must occur to reach the // of structures through which indirection must occur to reach the
// deepest field (nesting2.field1.position). // deepest field (nesting2.field1.position).
int getDeepestStructNesting() const { return deepestStructNesting; } int getDeepestStructNesting() const {
return structure ? structure->deepestNesting() : 0;
}
bool isStructureContainingArrays() const; bool isStructureContainingArrays() const {
return structure ? structure->containsArrays() : false;
}
private: protected:
void buildMangledName(TString&); TString buildMangledName() const;
size_t getStructSize() const; size_t getStructSize() const;
void computeDeepestStructNesting(); void computeDeepestStructNesting();
...@@ -237,16 +307,14 @@ private: ...@@ -237,16 +307,14 @@ private:
int primarySize; // size of vector or cols matrix int primarySize; // size of vector or cols matrix
int secondarySize; // rows of a matrix int secondarySize; // rows of a matrix
int arraySize; int arraySize;
TType* interfaceBlockType;
TTypeList* structure; // 0 unless this is a struct // 0 unless this is an interface block, or interface block member variable
mutable size_t structureSize; TInterfaceBlock* interfaceBlock;
int deepestStructNesting;
// 0 unless this is a struct
TStructure* structure;
TString *fieldName; // for structure field names mutable TString mangled;
TString *mangled;
TString *typeName; // for structure field type name
TString *instanceName; // for interface block instance names
}; };
// //
......
...@@ -173,14 +173,15 @@ void getUserDefinedVariableInfo(const TType& type, ...@@ -173,14 +173,15 @@ void getUserDefinedVariableInfo(const TType& type,
TVariableInfoList& infoList, TVariableInfoList& infoList,
ShHashFunction64 hashFunction) ShHashFunction64 hashFunction)
{ {
ASSERT(type.getBasicType() == EbtStruct); ASSERT(type.getBasicType() == EbtStruct || type.isInterfaceBlock());
const TTypeList* structure = type.getStruct(); const TFieldList& fields = type.getStruct()->fields();
for (size_t i = 0; i < structure->size(); ++i) { for (size_t i = 0; i < fields.size(); ++i) {
const TType* fieldType = (*structure)[i].type; const TType& fieldType = *(fields[i]->type());
getVariableInfo(*fieldType, const TString& fieldName = fields[i]->name();
name + "." + fieldType->getFieldName(), getVariableInfo(fieldType,
mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction), name + "." + fieldName,
mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
infoList, infoList,
hashFunction); hashFunction);
} }
......
...@@ -79,8 +79,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -79,8 +79,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TQualifier qualifier; TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TTypeLine typeLine; TField* field;
TTypeList* typeList; TFieldList* fieldList;
}; };
} interm; } interm;
} }
...@@ -189,8 +189,8 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) ...@@ -189,8 +189,8 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason)
%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier %type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier
%type <interm.type> type_specifier_no_prec type_specifier_nonarray %type <interm.type> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier %type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator %type <interm.field> struct_declarator
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier %type <interm.function> function_header function_declarator function_identifier
%type <interm.function> function_header_with_parameters function_call_header %type <interm.function> function_header_with_parameters function_call_header
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
...@@ -818,15 +818,15 @@ declaration ...@@ -818,15 +818,15 @@ declaration
} }
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON {
ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks");
$$ = context->addInterfaceBlock($1, @2, *$2.string, $3, "", @$, NULL, @$); $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @$, NULL, @$);
} }
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON { | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON {
ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks");
$$ = context->addInterfaceBlock($1, @2, *$2.string, $3, *$5.string, @5, NULL, @$); $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @$);
} }
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON { | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON {
ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks");
$$ = context->addInterfaceBlock($1, @2, *$2.string, $3, *$5.string, @5, $7, @6); $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6);
} }
| type_qualifier SEMICOLON { | type_qualifier SEMICOLON {
context->parseGlobalLayoutQualifier($1); context->parseGlobalLayoutQualifier($1);
...@@ -1519,10 +1519,10 @@ type_specifier_nonarray ...@@ -1519,10 +1519,10 @@ type_specifier_nonarray
struct_specifier struct_specifier
: STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
$$ = context->addStructure(@1, @2, *$2.string, $5); $$ = context->addStructure(@1, @2, $2.string, $5);
} }
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
$$ = context->addStructure(@1, @$, "", $4); $$ = context->addStructure(@1, @$, NewPoolTString(""), $4);
} }
; ;
...@@ -1532,14 +1532,15 @@ struct_declaration_list ...@@ -1532,14 +1532,15 @@ struct_declaration_list
} }
| struct_declaration_list struct_declaration { | struct_declaration_list struct_declaration {
$$ = $1; $$ = $1;
for (unsigned int i = 0; i < $2->size(); ++i) { for (size_t i = 0; i < $2->size(); ++i) {
for (unsigned int j = 0; j < $$->size(); ++j) { TField* field = (*$2)[i];
if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) { for (size_t j = 0; j < $$->size(); ++j) {
context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str()); if ((*$$)[j]->name() == field->name()) {
context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
context->recover(); context->recover();
} }
} }
$$->push_back((*$2)[i]); $$->push_back(field);
} }
} }
; ;
...@@ -1558,7 +1559,7 @@ struct_declaration ...@@ -1558,7 +1559,7 @@ struct_declaration
struct_declarator_list struct_declarator_list
: struct_declarator { : struct_declarator {
$$ = NewPoolTTypeList(); $$ = NewPoolTFieldList();
$$->push_back($1); $$->push_back($1);
} }
| struct_declarator_list COMMA struct_declarator { | struct_declarator_list COMMA struct_declarator {
...@@ -1571,20 +1572,20 @@ struct_declarator ...@@ -1571,20 +1572,20 @@ struct_declarator
if (context->reservedErrorCheck(@1, *$1.string)) if (context->reservedErrorCheck(@1, *$1.string))
context->recover(); context->recover();
$$.type = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
$$.type->setFieldName(*$1.string); $$ = new TField(type, $1.string, @1);
} }
| identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck(@1, *$1.string)) if (context->reservedErrorCheck(@1, *$1.string))
context->recover(); context->recover();
$$.type = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
$$.type->setFieldName(*$1.string);
int size; int size;
if (context->arraySizeErrorCheck(@2, $3, size)) if (context->arraySizeErrorCheck(@3, $3, size))
context->recover(); context->recover();
$$.type->setArraySize(size); type->setArraySize(size);
$$ = new TField(type, $1.string, @1);
} }
; ;
......
...@@ -294,8 +294,8 @@ typedef union YYSTYPE ...@@ -294,8 +294,8 @@ typedef union YYSTYPE
TQualifier qualifier; TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TTypeLine typeLine; TField* field;
TTypeList* typeList; TFieldList* fieldList;
}; };
} interm; } interm;
...@@ -808,13 +808,13 @@ static const yytype_uint16 yyrline[] = ...@@ -808,13 +808,13 @@ static const yytype_uint16 yyrline[] =
1355, 1360, 1365, 1370, 1375, 1380, 1385, 1390, 1395, 1400, 1355, 1360, 1365, 1370, 1375, 1380, 1385, 1390, 1395, 1400,
1405, 1410, 1415, 1420, 1425, 1430, 1435, 1440, 1444, 1448, 1405, 1410, 1415, 1420, 1425, 1430, 1435, 1440, 1444, 1448,
1452, 1456, 1460, 1464, 1468, 1472, 1476, 1480, 1484, 1488, 1452, 1456, 1460, 1464, 1468, 1472, 1476, 1480, 1484, 1488,
1496, 1504, 1508, 1521, 1521, 1524, 1524, 1530, 1533, 1548, 1496, 1504, 1508, 1521, 1521, 1524, 1524, 1530, 1533, 1549,
1551, 1560, 1564, 1570, 1577, 1592, 1596, 1600, 1601, 1607, 1552, 1561, 1565, 1571, 1578, 1593, 1597, 1601, 1602, 1608,
1608, 1609, 1610, 1611, 1615, 1616, 1616, 1616, 1626, 1627, 1609, 1610, 1611, 1612, 1616, 1617, 1617, 1617, 1627, 1628,
1631, 1631, 1632, 1632, 1637, 1640, 1650, 1653, 1659, 1660, 1632, 1632, 1633, 1633, 1638, 1641, 1651, 1654, 1660, 1661,
1664, 1672, 1676, 1686, 1691, 1708, 1708, 1713, 1713, 1720, 1665, 1673, 1677, 1687, 1692, 1709, 1709, 1714, 1714, 1721,
1720, 1728, 1731, 1737, 1740, 1746, 1750, 1757, 1764, 1771, 1721, 1729, 1732, 1738, 1741, 1747, 1751, 1758, 1765, 1772,
1778, 1789, 1798, 1802, 1809, 1812, 1818, 1818 1779, 1790, 1799, 1803, 1810, 1813, 1819, 1819
}; };
#endif #endif
...@@ -3333,7 +3333,7 @@ yyreduce: ...@@ -3333,7 +3333,7 @@ yyreduce:
{ {
ES3_ONLY(getQualifierString((yyvsp[(1) - (5)].interm.type).qualifier), (yylsp[(1) - (5)]), "interface blocks"); ES3_ONLY(getQualifierString((yyvsp[(1) - (5)].interm.type).qualifier), (yylsp[(1) - (5)]), "interface blocks");
(yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (5)].interm.type), (yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(3) - (5)].interm.typeList), "", (yyloc), NULL, (yyloc)); (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (5)].interm.type), (yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(3) - (5)].interm.fieldList), NULL, (yyloc), NULL, (yyloc));
} }
break; break;
...@@ -3341,7 +3341,7 @@ yyreduce: ...@@ -3341,7 +3341,7 @@ yyreduce:
{ {
ES3_ONLY(getQualifierString((yyvsp[(1) - (6)].interm.type).qualifier), (yylsp[(1) - (6)]), "interface blocks"); ES3_ONLY(getQualifierString((yyvsp[(1) - (6)].interm.type).qualifier), (yylsp[(1) - (6)]), "interface blocks");
(yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (6)].interm.type), (yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string, (yyvsp[(3) - (6)].interm.typeList), *(yyvsp[(5) - (6)].lex).string, (yylsp[(5) - (6)]), NULL, (yyloc)); (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (6)].interm.type), (yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string, (yyvsp[(3) - (6)].interm.fieldList), (yyvsp[(5) - (6)].lex).string, (yylsp[(5) - (6)]), NULL, (yyloc));
} }
break; break;
...@@ -3349,7 +3349,7 @@ yyreduce: ...@@ -3349,7 +3349,7 @@ yyreduce:
{ {
ES3_ONLY(getQualifierString((yyvsp[(1) - (9)].interm.type).qualifier), (yylsp[(1) - (9)]), "interface blocks"); ES3_ONLY(getQualifierString((yyvsp[(1) - (9)].interm.type).qualifier), (yylsp[(1) - (9)]), "interface blocks");
(yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (9)].interm.type), (yylsp[(2) - (9)]), *(yyvsp[(2) - (9)].lex).string, (yyvsp[(3) - (9)].interm.typeList), *(yyvsp[(5) - (9)].lex).string, (yylsp[(5) - (9)]), (yyvsp[(7) - (9)].interm.intermTypedNode), (yylsp[(6) - (9)])); (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (9)].interm.type), (yylsp[(2) - (9)]), *(yyvsp[(2) - (9)].lex).string, (yyvsp[(3) - (9)].interm.fieldList), (yyvsp[(5) - (9)].lex).string, (yylsp[(5) - (9)]), (yyvsp[(7) - (9)].interm.intermTypedNode), (yylsp[(6) - (9)]));
} }
break; break;
...@@ -4381,7 +4381,7 @@ yyreduce: ...@@ -4381,7 +4381,7 @@ yyreduce:
case 184: case 184:
{ {
(yyval.interm.type) = context->addStructure((yylsp[(1) - (6)]), (yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string, (yyvsp[(5) - (6)].interm.typeList)); (yyval.interm.type) = context->addStructure((yylsp[(1) - (6)]), (yylsp[(2) - (6)]), (yyvsp[(2) - (6)].lex).string, (yyvsp[(5) - (6)].interm.fieldList));
} }
break; break;
...@@ -4393,29 +4393,30 @@ yyreduce: ...@@ -4393,29 +4393,30 @@ yyreduce:
case 186: case 186:
{ {
(yyval.interm.type) = context->addStructure((yylsp[(1) - (5)]), (yyloc), "", (yyvsp[(4) - (5)].interm.typeList)); (yyval.interm.type) = context->addStructure((yylsp[(1) - (5)]), (yyloc), NewPoolTString(""), (yyvsp[(4) - (5)].interm.fieldList));
} }
break; break;
case 187: case 187:
{ {
(yyval.interm.typeList) = (yyvsp[(1) - (1)].interm.typeList); (yyval.interm.fieldList) = (yyvsp[(1) - (1)].interm.fieldList);
} }
break; break;
case 188: case 188:
{ {
(yyval.interm.typeList) = (yyvsp[(1) - (2)].interm.typeList); (yyval.interm.fieldList) = (yyvsp[(1) - (2)].interm.fieldList);
for (unsigned int i = 0; i < (yyvsp[(2) - (2)].interm.typeList)->size(); ++i) { for (size_t i = 0; i < (yyvsp[(2) - (2)].interm.fieldList)->size(); ++i) {
for (unsigned int j = 0; j < (yyval.interm.typeList)->size(); ++j) { TField* field = (*(yyvsp[(2) - (2)].interm.fieldList))[i];
if ((*(yyval.interm.typeList))[j].type->getFieldName() == (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName()) { for (size_t j = 0; j < (yyval.interm.fieldList)->size(); ++j) {
context->error((*(yyvsp[(2) - (2)].interm.typeList))[i].line, "duplicate field name in structure:", "struct", (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName().c_str()); if ((*(yyval.interm.fieldList))[j]->name() == field->name()) {
context->error((yylsp[(2) - (2)]), "duplicate field name in structure:", "struct", field->name().c_str());
context->recover(); context->recover();
} }
} }
(yyval.interm.typeList)->push_back((*(yyvsp[(2) - (2)].interm.typeList))[i]); (yyval.interm.fieldList)->push_back(field);
} }
} }
break; break;
...@@ -4423,7 +4424,7 @@ yyreduce: ...@@ -4423,7 +4424,7 @@ yyreduce:
case 189: case 189:
{ {
(yyval.interm.typeList) = context->addStructDeclaratorList((yyvsp[(1) - (3)].interm.type), (yyvsp[(2) - (3)].interm.typeList)); (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[(1) - (3)].interm.type), (yyvsp[(2) - (3)].interm.fieldList));
} }
break; break;
...@@ -4433,22 +4434,22 @@ yyreduce: ...@@ -4433,22 +4434,22 @@ yyreduce:
// ES3 Only, but errors should be handled elsewhere // ES3 Only, but errors should be handled elsewhere
(yyvsp[(2) - (4)].interm.type).qualifier = (yyvsp[(1) - (4)].interm.type).qualifier; (yyvsp[(2) - (4)].interm.type).qualifier = (yyvsp[(1) - (4)].interm.type).qualifier;
(yyvsp[(2) - (4)].interm.type).layoutQualifier = (yyvsp[(1) - (4)].interm.type).layoutQualifier; (yyvsp[(2) - (4)].interm.type).layoutQualifier = (yyvsp[(1) - (4)].interm.type).layoutQualifier;
(yyval.interm.typeList) = context->addStructDeclaratorList((yyvsp[(2) - (4)].interm.type), (yyvsp[(3) - (4)].interm.typeList)); (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[(2) - (4)].interm.type), (yyvsp[(3) - (4)].interm.fieldList));
} }
break; break;
case 191: case 191:
{ {
(yyval.interm.typeList) = NewPoolTTypeList(); (yyval.interm.fieldList) = NewPoolTFieldList();
(yyval.interm.typeList)->push_back((yyvsp[(1) - (1)].interm.typeLine)); (yyval.interm.fieldList)->push_back((yyvsp[(1) - (1)].interm.field));
} }
break; break;
case 192: case 192:
{ {
(yyval.interm.typeList)->push_back((yyvsp[(3) - (3)].interm.typeLine)); (yyval.interm.fieldList)->push_back((yyvsp[(3) - (3)].interm.field));
} }
break; break;
...@@ -4458,8 +4459,8 @@ yyreduce: ...@@ -4458,8 +4459,8 @@ yyreduce:
if (context->reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string)) if (context->reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string))
context->recover(); context->recover();
(yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
(yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (1)].lex).string); (yyval.interm.field) = new TField(type, (yyvsp[(1) - (1)].lex).string, (yylsp[(1) - (1)]));
} }
break; break;
...@@ -4469,13 +4470,13 @@ yyreduce: ...@@ -4469,13 +4470,13 @@ yyreduce:
if (context->reservedErrorCheck((yylsp[(1) - (4)]), *(yyvsp[(1) - (4)].lex).string)) if (context->reservedErrorCheck((yylsp[(1) - (4)]), *(yyvsp[(1) - (4)].lex).string))
context->recover(); context->recover();
(yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
(yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (4)].lex).string);
int size; int size;
if (context->arraySizeErrorCheck((yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size)) if (context->arraySizeErrorCheck((yylsp[(3) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
context->recover(); context->recover();
(yyval.interm.typeLine).type->setArraySize(size); type->setArraySize(size);
(yyval.interm.field) = new TField(type, (yyvsp[(1) - (4)].lex).string, (yylsp[(1) - (4)]));
} }
break; break;
......
...@@ -211,8 +211,8 @@ typedef union YYSTYPE ...@@ -211,8 +211,8 @@ typedef union YYSTYPE
TQualifier qualifier; TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TTypeLine typeLine; TField* field;
TTypeList* typeList; TFieldList* fieldList;
}; };
} interm; } interm;
......
...@@ -271,6 +271,7 @@ public: ...@@ -271,6 +271,7 @@ public:
int getNominalSize() const { return type.getNominalSize(); } int getNominalSize() const { return type.getNominalSize(); }
int getSecondarySize() const { return type.getSecondarySize(); } int getSecondarySize() const { return type.getSecondarySize(); }
bool isInterfaceBlock() const { return type.isInterfaceBlock(); }
bool isMatrix() const { return type.isMatrix(); } bool isMatrix() const { return type.isMatrix(); }
bool isArray() const { return type.isArray(); } bool isArray() const { return type.isArray(); }
bool isVector() const { return type.isVector(); } bool isVector() const { return type.isVector(); }
......
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