summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-10 10:44:02 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-10 10:44:02 -0700
commitb2fb0f7134de4e0b1a0db685eb1ae3c0678a33c5 (patch)
tree5597bca9d791391e069c8997a84ac9a8b1061024 /source
parent8abdf2dddd10feb9794c86cdf6b2159a2b6383e4 (diff)
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
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp60
-rw-r--r--source/slang/lower.cpp1
-rw-r--r--source/slang/reflection.cpp5
-rw-r--r--source/slang/type-layout.cpp35
-rw-r--r--source/slang/type-layout.h3
5 files changed, 97 insertions, 7 deletions
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<IndexExpressionSyntaxNode*>(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<ErrorType>())
+ {
+ 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<ErrorType>())
+ {
+ 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<ErrorType>())
+ {
+ // 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<GLSLImageType>())
+ {
+ // 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<TextureSamplerType>())
{
// 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<ErrorType>())
+ {
+ // 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