Ejemplo n.º 1
0
Variant AbstractTypeScope::doGetValue()
{
    return constType();
}
Ejemplo n.º 2
0
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();
    }
}
Ejemplo n.º 3
0
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);
}