Fix switch statement validation corner cases

The grammar needs to generate AST nodes even for no-op statements,
since they might be the last statement in a switch statement that is
required for switch statement validity. Change the grammar to generate
nodes from empty blocks and empty declarations.

We also need to do some further processing of the AST. This is because
PruneEmptyDeclarations will still remove empty declarations, and at
least the NVIDIA driver GLSL compiler doesn't accept some types of
no-op statements as the last statement inside a switch statement. So
after parsing has finished we do rudimentary dead code elimination to
remove dead cases from the end of switch statements.

BUG=angleproject:2181
TEST=angle_unittests

Change-Id: I586f2e4a3ac2171e65f1f0ccb7a7de220e3cc225
Reviewed-on: https://chromium-review.googlesource.com/712574
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 1d8d111..4574a8a 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -2135,20 +2135,13 @@
 {
     TInfoSinkBase &out = getInfoSink();
 
-    if (node->getStatementList())
+    ASSERT(node->getStatementList());
+    if (visit == PreVisit)
     {
-        if (visit == PreVisit)
-        {
-            node->setStatementList(RemoveSwitchFallThrough(node->getStatementList()));
-        }
-        outputTriplet(out, visit, "switch (", ") ", "");
-        // The curly braces get written when visiting the statementList block.
+        node->setStatementList(RemoveSwitchFallThrough(node->getStatementList()));
     }
-    else
-    {
-        // No statementList, so it won't output curly braces
-        outputTriplet(out, visit, "switch (", ") {", "}\n");
-    }
+    outputTriplet(out, visit, "switch (", ") ", "");
+    // The curly braces get written when visiting the statementList block.
     return true;
 }