From b2fb0f7134de4e0b1a0db685eb1ae3c0678a33c5 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 10 Jul 2017 10:44:02 -0700 Subject: Try to be more robust against un-checked types during lowering, etc. - Try to handle `ErrorType` gracefully when computing type layouts - When outputting a `TypeExp`, if the type part is errorneous (or missing), try to use the expression part - Make sure to lower the expressions side of a `TypeExp` during lowering --- source/slang/emit.cpp | 60 ++++++++++++++++++++++++++++++++++++++------ source/slang/lower.cpp | 1 + source/slang/reflection.cpp | 5 ++++ source/slang/type-layout.cpp | 35 ++++++++++++++++++++++++++ source/slang/type-layout.h | 3 +++ 5 files changed, 97 insertions(+), 7 deletions(-) (limited to 'source') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 155e1e39a..1630f1c79 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -1084,18 +1084,56 @@ struct EmitVisitor emitTypeImpl(type, nullptr); } + void emitTypeBasedOnExpr(ExpressionSyntaxNode* expr, EDeclarator* declarator) + { + if (auto subscriptExpr = dynamic_cast(expr)) + { + // Looks like an array + emitTypeBasedOnExpr(subscriptExpr->BaseExpression, declarator); + Emit("["); + if (auto indexExpr = subscriptExpr->IndexExpression) + { + EmitExpr(indexExpr); + } + Emit("]"); + } + else + { + // Default case + EmitExpr(expr); + EmitDeclarator(declarator); + } + } + + void EmitType(TypeExp const& typeExp, String const& name, CodePosition const& nameLoc) + { + if (!typeExp.type || typeExp.type->As()) + { + assert(typeExp.exp); + + EDeclarator nameDeclarator; + nameDeclarator.flavor = EDeclarator::Flavor::Name; + nameDeclarator.name = name; + nameDeclarator.loc = nameLoc; + + emitTypeBasedOnExpr(typeExp.exp, &nameDeclarator); + } + else + { + EmitType(typeExp.type, + typeExp.exp ? typeExp.exp->Position : CodePosition(), + name, nameLoc); + } + } + void EmitType(TypeExp const& typeExp, Token const& nameToken) { - EmitType(typeExp.type, - typeExp.exp ? typeExp.exp->Position : CodePosition(), - nameToken.Content, nameToken.Position); + EmitType(typeExp, nameToken.Content, nameToken.Position); } void EmitType(TypeExp const& typeExp, String const& name) { - EmitType(typeExp.type, - typeExp.exp ? typeExp.exp->Position : CodePosition(), - name, CodePosition()); + EmitType(typeExp, name, CodePosition()); } void emitTypeExp(TypeExp const& typeExp) @@ -2758,7 +2796,15 @@ struct EmitVisitor { EmitModifiers(declRef.getDecl()); - EmitType(GetType(declRef), declRef.getDecl()->getNameToken()); + auto type = GetType(declRef); + if (!type || type->As()) + { + EmitType(declRef.getDecl()->Type, declRef.getDecl()->getNameToken()); + } + else + { + EmitType(GetType(declRef), declRef.getDecl()->getNameToken()); + } EmitSemantics(declRef.getDecl()); diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 165812fae..9f117106b 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -445,6 +445,7 @@ struct LoweringVisitor { TypeExp result; result.type = lowerType(typeExp.type); + result.exp = lowerExpr(typeExp.exp); return result; } diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp index eb27df398..08621d9a3 100644 --- a/source/slang/reflection.cpp +++ b/source/slang/reflection.cpp @@ -148,6 +148,11 @@ SLANG_API SlangTypeKind spReflectionType_GetKind(SlangReflectionType* inType) return SLANG_TYPE_KIND_STRUCT; } } + else if (auto errorType = type->As()) + { + // This means we saw a type we didn't understand in the user's code + return SLANG_TYPE_KIND_NONE; + } assert(!"unexpected"); return SLANG_TYPE_KIND_NONE; diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp index 31c8ed607..9bc001e88 100644 --- a/source/slang/type-layout.cpp +++ b/source/slang/type-layout.cpp @@ -895,6 +895,28 @@ SimpleLayoutInfo GetLayoutImpl( rules, outTypeLayout); } + else if (auto imageType = type->As()) + { + // TODO: the logic here should really be defined by the rules, + // and not at this top level... + ShaderParameterKind kind; + switch( imageType->getAccess() ) + { + default: + kind = ShaderParameterKind::MutableImage; + break; + + case SLANG_RESOURCE_ACCESS_READ: + kind = ShaderParameterKind::Image; + break; + } + + return GetSimpleLayoutImpl( + rules->GetObjectLayout(kind), + type, + rules, + outTypeLayout); + } else if (auto textureSamplerType = type->As()) { // TODO: the logic here should really be defined by the rules, @@ -1126,6 +1148,19 @@ SimpleLayoutInfo GetLayoutImpl( return info; } } + else if (auto errorType = type->As()) + { + // An error type means that we encountered something we don't understand. + // + // We should probalby inform the user with an error message here. + + SimpleLayoutInfo info; + return GetSimpleLayoutImpl( + info, + type, + rules, + outTypeLayout); + } // catch-all case in case nothing matched assert(!"unimplemented"); diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h index 262a8c3b1..1a63a4883 100644 --- a/source/slang/type-layout.h +++ b/source/slang/type-layout.h @@ -415,6 +415,9 @@ enum class ShaderParameterKind InputRenderTarget, SamplerState, + + Image, + MutableImage, }; struct SimpleLayoutRulesImpl -- cgit v1.2.3 From d6d49eac224a0d03c8f941deb59ee1520ff0ab5e Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 10 Jul 2017 10:52:30 -0700 Subject: Add support for `imageBuffer` This was mostly just a missing `typedef` in the Slang standard library code. This should also cover `textureBuffer` and `samplerBuffer`. --- source/slang/emit.cpp | 1 + source/slang/slang-stdlib.cpp | 1 + source/slang/type-defs.h | 1 + 3 files changed, 3 insertions(+) (limited to 'source') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 1630f1c79..2791a436e 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -776,6 +776,7 @@ struct EmitVisitor case TextureType::Shape2D: Emit("2D"); break; case TextureType::Shape3D: Emit("3D"); break; case TextureType::ShapeCube: Emit("Cube"); break; + case TextureType::ShapeBuffer: Emit("Buffer"); break; default: assert(!"unreachable"); break; diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index 23d66201a..9d6f812cd 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -1914,6 +1914,7 @@ namespace Slang { "2D", TextureType::Shape2D, 2 }, { "3D", TextureType::Shape3D, 3 }, { "Cube", TextureType::ShapeCube, 3 }, + { "Buffer", TextureType::ShapeBuffer, 1 }, }; static const int kBaseTextureTypeCount = sizeof(kBaseTextureTypes) / sizeof(kBaseTextureTypes[0]); diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h index a01b49277..ae64cce2e 100644 --- a/source/slang/type-defs.h +++ b/source/slang/type-defs.h @@ -125,6 +125,7 @@ RAW( Shape2D = SLANG_TEXTURE_2D, Shape3D = SLANG_TEXTURE_3D, ShapeCube = SLANG_TEXTURE_CUBE, + ShapeBuffer = SLANG_TEXTURE_BUFFER, Shape1DArray = Shape1D | ArrayFlag, Shape2DArray = Shape2D | ArrayFlag, -- cgit v1.2.3