summaryrefslogtreecommitdiffstats
path: root/source/slang/lower.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-19 09:36:35 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-19 18:15:37 -0700
commit3f48e1c0d84bf4909954154ad147559656e87516 (patch)
tree0b93a109d51e6565560ad785519a863386490e2a /source/slang/lower.cpp
parenta2b8b4c20632d79721052abd232fe2d1bdf2700d (diff)
Try to improve handling of failures during compilation
The change is mostly about trying to make sure the compiler "fails safe" when it encounters an internal assumption that isn't met. Most internal errors will now throw exceptions (yes, exceptions are evil, but this will work for now), and these get caught in `spCompile` so that they don't propagate to the user (they just see a message that compilation aborted due to an internal error). Subsequent changes are going to need to work on diagnosing as many of these situations as possible, so that users can at least know what construct in their code was unexpected or unhandled by the compiler.
Diffstat (limited to 'source/slang/lower.cpp')
-rw-r--r--source/slang/lower.cpp77
1 files changed, 41 insertions, 36 deletions
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp
index c61003bc6..52b865ba3 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -186,7 +186,7 @@ class TupleVarDecl : public VarDeclBase
public:
virtual void accept(IDeclVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
TupleTypeModifier* tupleType;
@@ -201,7 +201,7 @@ class TupleExpr : public ExpressionSyntaxNode
public:
virtual void accept(IExprVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
struct Element
@@ -225,7 +225,7 @@ class VaryingTupleVarDecl : public VarDeclBase
public:
virtual void accept(IDeclVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
};
@@ -236,7 +236,7 @@ class VaryingTupleExpr : public ExpressionSyntaxNode
public:
virtual void accept(IExprVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
struct Element
@@ -667,10 +667,10 @@ struct LoweringVisitor
for (auto dd : decl->tupleDecls)
{
auto tupleVarMod = dd->FindModifier<TupleVarModifier>();
- assert(tupleVarMod);
+ SLANG_RELEASE_ASSERT(tupleVarMod);
auto tupleFieldMod = tupleVarMod->tupleField;
- assert(tupleFieldMod);
- assert(tupleFieldMod->decl);
+ SLANG_RELEASE_ASSERT(tupleFieldMod);
+ SLANG_RELEASE_ASSERT(tupleFieldMod->decl);
TupleExpr::Element elem;
elem.tupleFieldDeclRef = makeDeclRef(tupleFieldMod->decl);
@@ -799,7 +799,7 @@ struct LoweringVisitor
if (leftTuple->primaryExpr)
{
- assert(rightTuple->primaryExpr);
+ SLANG_RELEASE_ASSERT(rightTuple->primaryExpr);
resultTuple->primaryExpr = createAssignExpr(
leftTuple->primaryExpr,
@@ -807,7 +807,7 @@ struct LoweringVisitor
}
auto elementCount = leftTuple->tupleElements.Count();
- assert(elementCount == rightTuple->tupleElements.Count());
+ SLANG_RELEASE_ASSERT(elementCount == rightTuple->tupleElements.Count());
for (UInt ee = 0; ee < elementCount; ++ee)
{
auto leftElement = leftTuple->tupleElements[ee];
@@ -827,7 +827,7 @@ struct LoweringVisitor
}
else
{
- assert(!leftTuple && !rightTuple);
+ SLANG_RELEASE_ASSERT(!leftTuple && !rightTuple);
}
auto leftVaryingTuple = leftExpr.As<VaryingTupleExpr>();
@@ -838,10 +838,10 @@ struct LoweringVisitor
resultTuple->Type.type = lowerType(leftExpr->Type.type);
resultTuple->Position = leftExpr->Position;
- assert(resultTuple->Type.type);
+ SLANG_RELEASE_ASSERT(resultTuple->Type.type);
UInt elementCount = leftVaryingTuple->elements.Count();
- assert(elementCount == rightVaryingTuple->elements.Count());
+ SLANG_RELEASE_ASSERT(elementCount == rightVaryingTuple->elements.Count());
for (UInt ee = 0; ee < elementCount; ++ee)
{
@@ -1027,7 +1027,7 @@ struct LoweringVisitor
auto loweredExpr = new VaryingTupleExpr();
loweredExpr->Type.type = getSubscripResultType(baseExpr->Type.type);
- assert(loweredExpr->Type.type);
+ SLANG_RELEASE_ASSERT(loweredExpr->Type.type);
for (auto elem : baseVaryingTuple->elements)
{
@@ -1100,7 +1100,7 @@ struct LoweringVisitor
RefPtr<AggTypeCtorExpr> resultExpr = new AggTypeCtorExpr();
resultExpr->Type = varyingTupleExpr->Type;
resultExpr->base.type = varyingTupleExpr->Type.type;
- assert(resultExpr->Type.type);
+ SLANG_RELEASE_ASSERT(resultExpr->Type.type);
for (auto elem : varyingTupleExpr->elements)
{
@@ -1214,6 +1214,11 @@ struct LoweringVisitor
return loweredExpr;
}
+ DiagnosticSink* getSink()
+ {
+ return &shared->compileRequest->mSink;
+ }
+
RefPtr<ExpressionSyntaxNode> visitMemberExpressionSyntaxNode(
MemberExpressionSyntaxNode* expr)
{
@@ -1244,8 +1249,8 @@ struct LoweringVisitor
return tupleFieldExpr;
auto tupleFieldTupleExpr = tupleFieldExpr.As<TupleExpr>();
- assert(tupleFieldTupleExpr);
- assert(!tupleFieldTupleExpr->primaryExpr);
+ SLANG_RELEASE_ASSERT(tupleFieldTupleExpr);
+ SLANG_RELEASE_ASSERT(!tupleFieldTupleExpr->primaryExpr);
RefPtr<MemberExpressionSyntaxNode> loweredPrimaryExpr = new MemberExpressionSyntaxNode();
@@ -1274,11 +1279,11 @@ struct LoweringVisitor
}
}
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), expr, "failed to find tuple field during lowering");
}
// Default handling:
- assert(!dynamic_cast<TupleVarDecl*>(loweredDeclRef.getDecl()));
+ SLANG_RELEASE_ASSERT(!dynamic_cast<TupleVarDecl*>(loweredDeclRef.getDecl()));
RefPtr<MemberExpressionSyntaxNode> loweredExpr = new MemberExpressionSyntaxNode();
lowerExprCommon(loweredExpr, expr);
@@ -1344,7 +1349,7 @@ struct LoweringVisitor
return state->loweredStmt;
}
- assert(!"unexepcted");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), originalStmt, "failed to find outer statement during lowering");
return nullptr;
}
@@ -1755,7 +1760,7 @@ struct LoweringVisitor
if (auto litVal = dynamic_cast<ConstantIntVal*>(val))
return val;
- throw 99;
+ SLANG_UNEXPECTED("unhandled value kind");
}
RefPtr<Substitutions> translateSubstitutions(
@@ -1871,7 +1876,7 @@ struct LoweringVisitor
// translated, which the user will maintain via pua/pop.
//
- assert(parentDecl);
+ SLANG_RELEASE_ASSERT(parentDecl);
addMember(parentDecl, decl);
}
@@ -2337,7 +2342,7 @@ struct LoweringVisitor
continue;
// TODO: need to extract the initializer for this field
- assert(!info.initExpr);
+ SLANG_RELEASE_ASSERT(!info.initExpr);
RefPtr<ExpressionSyntaxNode> fieldInitExpr;
String fieldName = info.name + "_" + dd.GetName();
@@ -2346,7 +2351,7 @@ struct LoweringVisitor
Decl* originalFieldDecl;
shared->mapLoweredDeclToOriginal.TryGetValue(dd, originalFieldDecl);
- assert(originalFieldDecl);
+ SLANG_RELEASE_ASSERT(originalFieldDecl);
RefPtr<VarLayout> fieldLayout;
if(info.tupleTypeLayout)
@@ -2477,7 +2482,7 @@ struct LoweringVisitor
RefPtr<StructTypeLayout> tupleTypeLayout)
{
// Not handling initializers just yet...
- assert(!initExpr);
+ SLANG_RELEASE_ASSERT(!initExpr);
// We'll need a placeholder declaration to wrap the whole thing up:
RefPtr<TupleVarDecl> tupleDecl = new TupleVarDecl();
@@ -2745,7 +2750,7 @@ struct LoweringVisitor
// declarations.
// We can't easily support `in out` declarations with this approach
- assert(!(inRes && outRes));
+ SLANG_RELEASE_ASSERT(!(inRes && outRes));
RefPtr<ExpressionSyntaxNode> loweredExpr;
if (inRes)
@@ -2764,7 +2769,7 @@ struct LoweringVisitor
VaryingParameterDirection::Output);
}
- assert(loweredExpr);
+ SLANG_RELEASE_ASSERT(loweredExpr);
auto loweredDecl = createVaryingTupleVarDecl(
decl,
loweredExpr);
@@ -2987,7 +2992,7 @@ struct LoweringVisitor
RefPtr<ExpressionSyntaxNode> globalVarExpr;
// Handle system-value inputs/outputs
- assert(varLayout);
+ SLANG_RELEASE_ASSERT(varLayout);
auto systemValueSemantic = varLayout->systemValueSemantic;
if (systemValueSemantic.Length() != 0)
{
@@ -3124,7 +3129,7 @@ struct LoweringVisitor
}
else
{
- assert(!"unhandled");
+ getSink()->diagnose(info.varChain->varDecl, Diagnostics::unknownSystemValueSemantic, systemValueSemantic);
}
}
@@ -3202,7 +3207,7 @@ struct LoweringVisitor
RefPtr<ExpressionType> varType,
RefPtr<VarLayout> varLayout)
{
- assert(varLayout);
+ SLANG_RELEASE_ASSERT(varLayout);
if (auto basicType = varType->As<BasicExpressionType>())
{
@@ -3252,7 +3257,7 @@ struct LoweringVisitor
RefPtr<VaryingTupleExpr> tupleExpr = new VaryingTupleExpr();
tupleExpr->Type.type = varType;
- assert(tupleExpr->Type.type);
+ SLANG_RELEASE_ASSERT(tupleExpr->Type.type);
for (auto fieldDeclRef : getMembersOfType<VarDeclBase>(aggTypeDeclRef))
{
@@ -3271,14 +3276,14 @@ struct LoweringVisitor
// Need to find the layout for the given field...
Decl* originalFieldDecl = nullptr;
shared->mapLoweredDeclToOriginal.TryGetValue(fieldDeclRef.getDecl(), originalFieldDecl);
- assert(originalFieldDecl);
+ SLANG_RELEASE_ASSERT(originalFieldDecl);
auto structTypeLayout = varLayout->typeLayout.As<StructTypeLayout>();
- assert(structTypeLayout);
+ SLANG_RELEASE_EXPECT(structTypeLayout, "expected a structure type layout");
RefPtr<VarLayout> fieldLayout;
structTypeLayout->mapVarToLayout.TryGetValue(originalFieldDecl, fieldLayout);
- assert(fieldLayout);
+ SLANG_RELEASE_ASSERT(fieldLayout);
auto loweredFieldExpr = lowerShaderParameterToGLSLGLobalsRec(
fieldInfo,
@@ -3414,7 +3419,7 @@ struct LoweringVisitor
{
RefPtr<VarLayout> paramLayout;
entryPointLayout->mapVarToLayout.TryGetValue(paramDecl.Ptr(), paramLayout);
- assert(paramLayout);
+ SLANG_RELEASE_ASSERT(paramLayout);
RefPtr<Variable> localVarDecl = new Variable();
localVarDecl->Position = paramDecl->Position;
@@ -3657,13 +3662,13 @@ static RefPtr<StructTypeLayout> getGlobalStructLayout(
auto elementTypeStructLayout = elementTypeLayout.As<StructTypeLayout>();
// We expect all constant buffers to contain `struct` types for now
- assert(elementTypeStructLayout);
+ SLANG_RELEASE_ASSERT(elementTypeStructLayout);
globalStructLayout = elementTypeStructLayout.Ptr();
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled type for global-scope parameter layout");
}
return globalStructLayout;
}