diff --git a/src/libs/glsl/glsl.h b/src/libs/glsl/glsl.h index e63ab44e89586958d3abac16455c9301c391f5e5..25a396759000621b1e1d053bc303e76b664c39aa 100644 --- a/src/libs/glsl/glsl.h +++ b/src/libs/glsl/glsl.h @@ -52,12 +52,12 @@ class MemoryPool; class Type; class UndefinedType; class VoidType; +class ScalarType; class BoolType; class IntType; class UIntType; class FloatType; class DoubleType; -class OpaqueType; class IndexType; class VectorType; class MatrixType; diff --git a/src/libs/glsl/glslengine.cpp b/src/libs/glsl/glslengine.cpp index 2b6ec6e03910cfdc0223ab1bc605ab376c7ef3d8..bd30f7a0dcec901f3b1f0a824a3edf51617bbb6f 100644 --- a/src/libs/glsl/glslengine.cpp +++ b/src/libs/glsl/glslengine.cpp @@ -185,6 +185,12 @@ const MatrixType *Engine::matrixType(const Type *elementType, int columns, int r vectorType(elementType, rows))); } +const ArrayType *Engine::arrayType(const Type *elementType) +{ + return _arrayTypes.intern(ArrayType(elementType)); +} + + QList<DiagnosticMessage> Engine::diagnosticMessages() const { return _diagnosticMessages; diff --git a/src/libs/glsl/glslengine.h b/src/libs/glsl/glslengine.h index 2d668ba37f06ec52bab940f04bbdba9fa381eb7b..5e1c906509be0cb3c6673051f39e8b808fa94f63 100644 --- a/src/libs/glsl/glslengine.h +++ b/src/libs/glsl/glslengine.h @@ -113,6 +113,7 @@ public: const SamplerType *samplerType(int kind); const VectorType *vectorType(const Type *elementType, int dimension); const MatrixType *matrixType(const Type *elementType, int columns, int rows); + const ArrayType *arrayType(const Type *elementType); // symbols Namespace *newNamespace(); @@ -136,6 +137,7 @@ private: QSet<QString> _numbers; TypeTable<VectorType> _vectorTypes; TypeTable<MatrixType> _matrixTypes; + TypeTable<ArrayType> _arrayTypes; TypeTable<SamplerType> _samplerTypes; MemoryPool _pool; QList<DiagnosticMessage> _diagnosticMessages; diff --git a/src/libs/glsl/glslsemantic.cpp b/src/libs/glsl/glslsemantic.cpp index 13542bb02cfe04bf48d471171a43d921b9c3a2f4..c01e460be2ab4287209f2d52a0fed9b10bc82d81 100644 --- a/src/libs/glsl/glslsemantic.cpp +++ b/src/libs/glsl/glslsemantic.cpp @@ -198,7 +198,11 @@ bool Semantic::visit(LiteralExpressionAST *ast) if (ast->value) { _expr.isConstant = true; - if (ast->value->endsWith(QLatin1Char('u')) || ast->value->endsWith(QLatin1Char('U'))) + if (ast->value->at(0) == QLatin1Char('t') && *ast->value == QLatin1String("true")) + _expr.type = _engine->boolType(); + else if (ast->value->at(0) == QLatin1Char('f') && *ast->value == QLatin1String("false")) + _expr.type = _engine->boolType(); + else if (ast->value->endsWith(QLatin1Char('u')) || ast->value->endsWith(QLatin1Char('U'))) _expr.type = _engine->uintType(); else if (ast->value->endsWith(QLatin1String("lf")) || ast->value->endsWith(QLatin1String("LF"))) _expr.type = _engine->doubleType(); @@ -217,11 +221,17 @@ bool Semantic::visit(BinaryExpressionAST *ast) _expr.isConstant = left.isConstant && right.isConstant; switch (ast->kind) { case AST::Kind_ArrayAccess: + if (left.type) { + if (const IndexType *idxType = left.type->asIndexType()) + _expr = idxType->indexElementType(); + else + _engine->error(ast->lineno, QString("Invalid type `%1' for array subscript").arg(left.type->toString())); + } break; + case AST::Kind_Modulus: case AST::Kind_Multiply: case AST::Kind_Divide: - case AST::Kind_Modulus: case AST::Kind_Plus: case AST::Kind_Minus: case AST::Kind_ShiftLeft: @@ -301,8 +311,56 @@ bool Semantic::visit(MemberAccessExpressionAST *ast) bool Semantic::implicitCast(const Type *type, const Type *target) const { - // ### implement me - return type->isEqualTo(target); + if (! (type && target)) { + return false; + } else if (type->isEqualTo(target)) { + return true; + } else if (target->asUIntType() != 0) { + return type->asIntType() != 0; + } else if (target->asFloatType() != 0) { + return type->asIntType() != 0 || + type->asUIntType() != 0; + } else if (target->asDoubleType() != 0) { + return type->asIntType() != 0 || + type->asUIntType() != 0 || + type->asFloatType() != 0; + } else if (const VectorType *targetVecTy = target->asVectorType()) { + if (const VectorType *vecTy = type->asVectorType()) { + if (targetVecTy->dimension() == vecTy->dimension()) { + const Type *targetElementType = targetVecTy->elementType(); + const Type *elementType = vecTy->elementType(); + + if (targetElementType->asUIntType() != 0) { + // uvec* -> ivec* + return elementType->asIntType() != 0; + } else if (targetElementType->asFloatType() != 0) { + // vec* -> ivec* | uvec* + return elementType->asIntType() != 0 || + elementType->asUIntType() != 0; + } else if (targetElementType->asDoubleType() != 0) { + // dvec* -> ivec* | uvec* | fvec* + return elementType->asIntType() != 0 || + elementType->asUIntType() != 0 || + elementType->asFloatType() != 0; + } + } + } + } else if (const MatrixType *targetMatTy = target->asMatrixType()) { + if (const MatrixType *matTy = type->asMatrixType()) { + if (targetMatTy->columns() == matTy->columns() && + targetMatTy->rows() == matTy->rows()) { + const Type *targetElementType = targetMatTy->elementType(); + const Type *elementType = matTy->elementType(); + + if (targetElementType->asDoubleType() != 0) { + // dmat* -> mat* + return elementType->asFloatType() != 0; + } + } + } + } + + return false; } bool Semantic::visit(FunctionCallExpressionAST *ast) @@ -337,11 +395,19 @@ bool Semantic::visit(FunctionCallExpressionAST *ast) candidates.append(f); } } - if (candidates.size() == 1) - _expr.type = candidates.first()->returnType(); - else + + if (candidates.isEmpty()) { + // ### error, unresolved call. + Q_ASSERT(! overloads->functions().isEmpty()); + _expr.type = overloads->functions().first()->returnType(); + } else { + _expr.type = candidates.first()->returnType(); + if (candidates.size() != 1) { + // ### error, ambiguous call + } + } } else { // called as constructor, e.g. vec2(a, b) _expr.type = id.type; @@ -693,7 +759,7 @@ bool Semantic::visit(ArrayTypeAST *ast) const Type *elementType = type(ast->elementType); Q_UNUSED(elementType); ExprResult size = expression(ast->size); - // ### array type + _type = _engine->arrayType(elementType); // ### ignore the size for now return false; } diff --git a/src/libs/glsl/glslsemantic.h b/src/libs/glsl/glslsemantic.h index d3b0ce3214116f7379ce6baaf19f9dc3685078c6..49bfe67739c71219dc5c0cdc85d8cbae5b41bd57 100644 --- a/src/libs/glsl/glslsemantic.h +++ b/src/libs/glsl/glslsemantic.h @@ -30,6 +30,7 @@ #define GLSLSEMANTIC_H #include "glslastvisitor.h" +#include "glsltype.h" namespace GLSL { @@ -43,8 +44,15 @@ public: ExprResult(const Type *type = 0, bool isConstant = false) : type(type), isConstant(isConstant) {} - bool isValid() const { return type != 0; } - operator bool() const { return type != 0; } + bool isValid() const { + if (! type) + return false; + else if (type->asUndefinedType() != 0) + return false; + return true; + } + + operator bool() const { return isValid(); } const Type *type; bool isConstant; diff --git a/src/libs/glsl/glsltype.h b/src/libs/glsl/glsltype.h index 18ea9416d46869e2209d0de33573f58b8f4721dd..cc9c8ff94e71c142674974f02d91f11c6745572f 100644 --- a/src/libs/glsl/glsltype.h +++ b/src/libs/glsl/glsltype.h @@ -47,7 +47,7 @@ public: virtual const UIntType *asUIntType() const { return 0; } virtual const FloatType *asFloatType() const { return 0; } virtual const DoubleType *asDoubleType() const { return 0; } - virtual const OpaqueType *asOpaqueType() const { return 0; } + virtual const ScalarType *asScalarType() const { return 0; } virtual const IndexType *asIndexType() const { return 0; } virtual const VectorType *asVectorType() const { return 0; } virtual const MatrixType *asMatrixType() const { return 0; } diff --git a/src/libs/glsl/glsltypes.h b/src/libs/glsl/glsltypes.h index f96171e905fd3f1f7768afcdff7764bb0792e0ac..1b81f20e6e326450c465bc28d68b091a8182d52d 100644 --- a/src/libs/glsl/glsltypes.h +++ b/src/libs/glsl/glsltypes.h @@ -38,10 +38,10 @@ namespace GLSL { -class GLSL_EXPORT OpaqueType: public Type +class GLSL_EXPORT ScalarType: public Type { public: - virtual const OpaqueType *asOpaqueType() const { return this; } + virtual const ScalarType *asScalarType() const { return this; } }; class GLSL_EXPORT UndefinedType: public Type @@ -62,7 +62,7 @@ public: virtual bool isLessThan(const Type *other) const; }; -class GLSL_EXPORT BoolType: public Type +class GLSL_EXPORT BoolType: public ScalarType { public: virtual QString toString() const { return QLatin1String("bool"); } @@ -71,7 +71,7 @@ public: virtual bool isLessThan(const Type *other) const; }; -class GLSL_EXPORT IntType: public Type +class GLSL_EXPORT IntType: public ScalarType { public: virtual QString toString() const { return QLatin1String("int"); } @@ -80,7 +80,7 @@ public: virtual bool isLessThan(const Type *other) const; }; -class GLSL_EXPORT UIntType: public Type +class GLSL_EXPORT UIntType: public ScalarType { public: virtual QString toString() const { return QLatin1String("uint"); } @@ -89,7 +89,7 @@ public: virtual bool isLessThan(const Type *other) const; }; -class GLSL_EXPORT FloatType: public Type +class GLSL_EXPORT FloatType: public ScalarType { public: virtual QString toString() const { return QLatin1String("float"); } @@ -98,7 +98,7 @@ public: virtual bool isLessThan(const Type *other) const; }; -class GLSL_EXPORT DoubleType: public Type +class GLSL_EXPORT DoubleType: public ScalarType { public: virtual QString toString() const { return QLatin1String("double"); }