Variant AbstractTypeScope::doGetValue() { return constType(); }
Variable AbstractTypeScope::doGetField(const Variant &key, bool modifiable, bool createIfNeeded) { const ObjectType& cType = constType(); int64_t parameterIndex = -1LL; const size_t numberOfParameters = cType.numberOfParameters(); if (key.hasNumericalType()) { parameterIndex = key.toInteger(); if (parameterIndex < 0 || parameterIndex >= numberOfParameters) { if (createIfNeeded) { Log::error("Trying to assign a value to an out of bounds parameter"); } return Variable(); } } else if (key.type() == Variant::stringType) { const std::string str = key.toString(); if (!str.empty() && str[0]=='@') { auto it = reserved.find(str); if(it == reserved.end()) { Log::error("Unknown reserved field", str," for type ", cType); return Variable(); } const int tag = it->second; switch(tag) { case A_COUNT: return collector().copy(numberOfParameters, false); case A_ELEMENT_TYPE: return Variable(new ConstTypeElementTypeVariableImplementation(collector(), cType), false); case A_ELEMENT_COUNT: return Variable(new ConstTypeElementCountVariableImplementation(collector(), cType), false); case A_NAME: return Variable(new ConstTypeNameVariableImplementation(collector(), cType), false); } return Variable(); } else { parameterIndex = cType.typeTemplate().parameterNumber(str); if (parameterIndex == -1) { if (createIfNeeded) { Log::error("Trying to modify an unknown named parameter ", str, " for type ", cType); } return Variable(); } } } else { if (createIfNeeded) { Log::error("Trying to modify an invalid parameter ", key, " for type ", cType); } return Variable(); } if (parameterIndex != -1) { return Variable(new TypeParameterVariableImplementation(collector(), memory(), *this, parameterIndex), modifiable); } else { return Variable(); } }
TIntermTyped *CreateZeroNode(const TType &type) { TType constType(type); constType.setQualifier(EvqConst); if (!type.isArray() && type.getBasicType() != EbtStruct) { size_t size = constType.getObjectSize(); TConstantUnion *u = new TConstantUnion[size]; for (size_t i = 0; i < size; ++i) { switch (type.getBasicType()) { case EbtFloat: u[i].setFConst(0.0f); break; case EbtInt: u[i].setIConst(0); break; case EbtUInt: u[i].setUConst(0u); break; case EbtBool: u[i].setBConst(false); break; default: // CreateZeroNode is called by ParseContext that keeps parsing even when an // error occurs, so it is possible for CreateZeroNode to be called with // non-basic types. This happens only on error condition but CreateZeroNode // needs to return a value with the correct type to continue the typecheck. // That's why we handle non-basic type by setting whatever value, we just need // the type to be right. u[i].setIConst(42); break; } } TIntermConstantUnion *node = new TIntermConstantUnion(u, constType); return node; } if (type.getBasicType() == EbtVoid) { // Void array. This happens only on error condition, similarly to the case above. We don't // have a constructor operator for void, so this needs special handling. We'll end up with a // value without the array type, but that should not be a problem. while (constType.isArray()) { constType.toArrayElementType(); } return CreateZeroNode(constType); } TIntermSequence *arguments = new TIntermSequence(); if (type.isArray()) { TType elementType(type); elementType.toArrayElementType(); size_t arraySize = type.getOutermostArraySize(); for (size_t i = 0; i < arraySize; ++i) { arguments->push_back(CreateZeroNode(elementType)); } } else { ASSERT(type.getBasicType() == EbtStruct); TStructure *structure = type.getStruct(); for (const auto &field : structure->fields()) { arguments->push_back(CreateZeroNode(*field->type())); } } return TIntermAggregate::CreateConstructor(constType, arguments); }