// // This function returns an element of an array accessed from a constant array. The values are retrieved from // the symbol table and parse-tree is built for the type of the element. The input // to the function could either be a symbol node (a[0] where a is a constant array)that represents a // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure) // TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line) { TIntermTyped* typedNode; TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TType arrayElementType = node->getType(); arrayElementType.clearArrayness(); if (index >= node->getType().getArraySize()) { error(line, "", "[", "array field selection out of range '%d'", index); recover(); index = 0; } int arrayElementSize = arrayElementType.getObjectSize(); if (tempConstantNode) { ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); } else { error(line, "Cannot offset into the array", "Error", ""); recover(); return 0; } return typedNode; }
void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) { ConstantUnion* leftUnionArray = unionArray; int instanceSize = type.getObjectSize(); if (index >= instanceSize) return; if (!singleConstantParam) { int size = node->getType().getObjectSize(); ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); for (int i=0; i < size; i++) { if (index >= instanceSize) return; leftUnionArray[index] = rightUnionArray[i]; (index)++; } } else { int totalSize = index + size; ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); if (!isMatrix) { int count = 0; for (int i = index; i < totalSize; i++) { if (i >= instanceSize) return; leftUnionArray[i] = rightUnionArray[count]; (index)++; if (node->getType().getObjectSize() > 1) count++; } } else { // for matrix constructors int count = 0; int element = index; for (int i = index; i < totalSize; i++) { if (i >= instanceSize) return; if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 ) leftUnionArray[i] = rightUnionArray[count]; else leftUnionArray[i].setFConst(0.0f); (index)++; if (node->getType().getObjectSize() > 1) count++; } } } }
bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray) { if (leftNodeType.isArray()) { TType typeWithoutArrayness = leftNodeType; typeWithoutArrayness.clearArrayness(); int arraySize = leftNodeType.getArraySize(); for (int i = 0; i < arraySize; ++i) { int offset = typeWithoutArrayness.getObjectSize() * i; if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset])) return false; } } else return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray); return true; }
// // Initializers show up in several places in the grammar. Have one set of // code to handle them here. // bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) { TType type = TType(pType); if (variable == 0) { if (reservedErrorCheck(line, identifier)) return true; if (voidErrorCheck(line, identifier, pType)) return true; // // add variable to symbol table // variable = new TVariable(&identifier, type); if (! symbolTable.insert(*variable)) { error(line, "redefinition", variable->getName().c_str(), ""); return true; // don't delete variable, it's used by error recovery, and the pool // pop will take care of the memory } } // // identifier must be of type constant, a global, or a temporary // TQualifier qualifier = variable->getType().getQualifier(); if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), ""); return true; } // // test for and propagate constant // if (qualifier == EvqConst) { if (qualifier != initializer->getType().getQualifier()) { error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); variable->getType().setQualifier(EvqTemporary); return true; } if (type != initializer->getType()) { error(line, " non-matching types for const initializer ", variable->getType().getQualifierString(), ""); variable->getType().setQualifier(EvqTemporary); return true; } if (initializer->getAsConstantUnion()) { ConstantUnion* unionArray = variable->getConstPointer(); if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) { *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0]; } else { variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); } } else if (initializer->getAsSymbolNode()) { const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol()); const TVariable* tVar = static_cast<const TVariable*>(symbol); ConstantUnion* constArray = tVar->getConstPointer(); variable->shareConstPointer(constArray); } else { error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); variable->getType().setQualifier(EvqTemporary); return true; } } if (qualifier != EvqConst) { TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line); if (intermNode == 0) { assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); return true; } } else intermNode = 0; return false; }
void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) { if (!node->getUnionArrayPointer()) { // The constant was not initialized, this should already have been logged assert(infoSink.info.size() != 0); return; } ConstantUnion* leftUnionArray = unionArray; size_t instanceSize = type.getObjectSize(); if (index >= instanceSize) return; if (!singleConstantParam) { size_t objectSize = node->getType().getObjectSize(); ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); for (size_t i=0; i < objectSize; i++) { if (index >= instanceSize) return; leftUnionArray[index] = rightUnionArray[i]; (index)++; } } else { size_t totalSize = index + size; ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); if (!isDiagonalMatrixInit) { int count = 0; for (size_t i = index; i < totalSize; i++) { if (i >= instanceSize) return; leftUnionArray[i] = rightUnionArray[count]; (index)++; if (node->getType().getObjectSize() > 1) count++; } } else { // for matrix diagonal constructors from a single scalar for (int i = 0, col = 0; col < matrixCols; col++) { for (int row = 0; row < matrixRows; row++, i++) { if (col == row) { leftUnionArray[i] = rightUnionArray[0]; } else { leftUnionArray[i].setFConst(0.0f); } (index)++; } } } } }
void TConstTraverser::visitConstantUnion(TIntermConstantUnion *node) { if (!node->getUnionArrayPointer()) { // The constant was not initialized, this should already have been logged ASSERT(mInfoSink.info.size() != 0); return; } TConstantUnion *leftUnionArray = mUnionArray; size_t instanceSize = mType.getObjectSize(); TBasicType basicType = mType.getBasicType(); if (mIndex >= instanceSize) return; if (!mSingleConstantParam) { size_t objectSize = node->getType().getObjectSize(); const TConstantUnion *rightUnionArray = node->getUnionArrayPointer(); for (size_t i=0; i < objectSize; i++) { if (mIndex >= instanceSize) return; leftUnionArray[mIndex].cast(basicType, rightUnionArray[i]); mIndex++; } } else { size_t totalSize = mIndex + mSize; const TConstantUnion *rightUnionArray = node->getUnionArrayPointer(); if (!mIsDiagonalMatrixInit) { int count = 0; for (size_t i = mIndex; i < totalSize; i++) { if (i >= instanceSize) return; leftUnionArray[i].cast(basicType, rightUnionArray[count]); mIndex++; if (node->getType().getObjectSize() > 1) count++; } } else { // for matrix diagonal constructors from a single scalar for (int i = 0, col = 0; col < mMatrixCols; col++) { for (int row = 0; row < mMatrixRows; row++, i++) { if (col == row) { leftUnionArray[i].cast(basicType, rightUnionArray[0]); } else { leftUnionArray[i].setFConst(0.0f); } mIndex++; } } } } }
void StructureHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) { if (name == "") { return; // Nameless structures don't have constructors } if (type.getStruct() && mStructNames.find(name) != mStructNames.end()) { return; // Already added } TType ctorType = type; ctorType.clearArrayness(); ctorType.setPrecision(EbpHigh); ctorType.setQualifier(EvqTemporary); typedef std::vector<TType> ParameterArray; ParameterArray ctorParameters; const TStructure* structure = type.getStruct(); if (structure) { mStructNames.insert(name); // Add element index storeStd140ElementIndex(*structure, false); storeStd140ElementIndex(*structure, true); const TString &structString = defineQualified(*structure, false, false); if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end()) { // Add row-major packed struct for interface blocks TString rowMajorString = "#pragma pack_matrix(row_major)\n" + defineQualified(*structure, true, false) + "#pragma pack_matrix(column_major)\n"; TString std140String = defineQualified(*structure, false, true); TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" + defineQualified(*structure, true, true) + "#pragma pack_matrix(column_major)\n"; mStructDeclarations.push_back(structString); mStructDeclarations.push_back(rowMajorString); mStructDeclarations.push_back(std140String); mStructDeclarations.push_back(std140RowMajorString); } const TFieldList &fields = structure->fields(); for (unsigned int i = 0; i < fields.size(); i++) { ctorParameters.push_back(*fields[i]->type()); } } else if (parameters) { for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) { ctorParameters.push_back((*parameter)->getAsTyped()->getType()); } } else UNREACHABLE(); TString constructor; if (ctorType.getStruct()) { constructor += name + " " + name + "_ctor("; } else // Built-in type { constructor += TypeString(ctorType) + " " + name + "("; } for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++) { const TType ¶mType = ctorParameters[parameter]; constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType); if (parameter < ctorParameters.size() - 1) { constructor += ", "; } } constructor += ")\n" "{\n"; if (ctorType.getStruct()) { constructor += " " + name + " structure = {"; } else { constructor += " return " + TypeString(ctorType) + "("; } if (ctorType.isMatrix() && ctorParameters.size() == 1) { int rows = ctorType.getRows(); int cols = ctorType.getCols(); const TType ¶meter = ctorParameters[0]; if (parameter.isScalar()) { for (int col = 0; col < cols; col++) { for (int row = 0; row < rows; row++) { constructor += TString((row == col) ? "x0" : "0.0"); if (row < rows - 1 || col < cols - 1) { constructor += ", "; } } } } else if (parameter.isMatrix()) { for (int col = 0; col < cols; col++) { for (int row = 0; row < rows; row++) { if (row < parameter.getRows() && col < parameter.getCols()) { constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]"; } else { constructor += TString((row == col) ? "1.0" : "0.0"); } if (row < rows - 1 || col < cols - 1) { constructor += ", "; } } } } else { ASSERT(rows == 2 && cols == 2 && parameter.isVector() && parameter.getNominalSize() == 4); constructor += "x0"; } } else { size_t remainingComponents = ctorType.getObjectSize(); size_t parameterIndex = 0; while (remainingComponents > 0) { const TType ¶meter = ctorParameters[parameterIndex]; const size_t parameterSize = parameter.getObjectSize(); bool moreParameters = parameterIndex + 1 < ctorParameters.size(); constructor += "x" + str(parameterIndex); if (ctorType.getStruct()) { ASSERT(remainingComponents == parameterSize || moreParameters); ASSERT(parameterSize <= remainingComponents); remainingComponents -= parameterSize; } else if (parameter.isScalar()) { remainingComponents -= parameter.getObjectSize(); } else if (parameter.isVector()) { if (remainingComponents == parameterSize || moreParameters) { ASSERT(parameterSize <= remainingComponents); remainingComponents -= parameterSize; } else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize())) { switch (remainingComponents) { case 1: constructor += ".x"; break; case 2: constructor += ".xy"; break; case 3: constructor += ".xyz"; break; case 4: constructor += ".xyzw"; break; default: UNREACHABLE(); } remainingComponents = 0; } else UNREACHABLE(); } else if (parameter.isMatrix()) { int column = 0; while (remainingComponents > 0 && column < parameter.getCols()) { constructor += "[" + str(column) + "]"; if (remainingComponents < static_cast<size_t>(parameter.getRows())) { switch (remainingComponents) { case 1: constructor += ".x"; break; case 2: constructor += ".xy"; break; case 3: constructor += ".xyz"; break; default: UNREACHABLE(); } remainingComponents = 0; } else { remainingComponents -= parameter.getRows(); if (remainingComponents > 0) { constructor += ", x" + str(parameterIndex); } } column++; } } else UNREACHABLE(); if (moreParameters) { parameterIndex++; } if (remainingComponents) { constructor += ", "; } } } if (ctorType.getStruct()) { constructor += "};\n" " return structure;\n" "}\n"; } else { constructor += ");\n" "}\n"; } mConstructors.insert(constructor); }
void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) { if (!node->getUnionArrayPointer()) { // The constant was not initialized, this should already have been logged assert(infoSink.info.size() != 0); return; } ConstantUnion* leftUnionArray = unionArray; size_t instanceSize = type.getObjectSize(); if (index >= instanceSize) return; if (!singleConstantParam) { size_t size = node->getType().getObjectSize(); ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); for (size_t i = 0; i < size; i++) { if (index >= instanceSize) return; leftUnionArray[index] = rightUnionArray[i]; (index)++; } } else { size_t totalSize = index + size; ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); if (!isMatrix) { size_t count = 0; for (size_t i = index; i < totalSize; i++) { if (i >= instanceSize) return; leftUnionArray[i] = rightUnionArray[count]; (index)++; if (node->getType().getObjectSize() > 1) count++; } } else { // for matrix constructors size_t count = 0; size_t element = index; for (size_t i = index; i < totalSize; i++) { if (i >= instanceSize) return; if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 ) leftUnionArray[i] = rightUnionArray[count]; else leftUnionArray[i].setFConst(0.0f); (index)++; if (node->getType().getObjectSize() > 1) count++; } } } }