diff --git a/Test/baseResults/hlsl.switch.frag.out b/Test/baseResults/hlsl.switch.frag.out
new file mode 100755
index 0000000000000000000000000000000000000000..7163bc05f6224586b457c99b234f2974bb293f48
--- /dev/null
+++ b/Test/baseResults/hlsl.switch.frag.out
@@ -0,0 +1,376 @@
+hlsl.switch.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:56  Function Definition: PixelShaderFunction(vf4;i1;i1; (temp 4-component vector of float)
+0:2    Function Parameters: 
+0:2      'input' (in 4-component vector of float)
+0:2      'c' (in int)
+0:2      'd' (in int)
+0:?     Sequence
+0:3      'c' (in int)
+0:7      switch
+0:7      condition
+0:7        'c' (in int)
+0:7      body
+0:7        Sequence
+0:9          default: 
+0:7          Sequence
+0:7            Branch: Break
+0:12      switch
+0:12      condition
+0:12        'c' (in int)
+0:12      body
+0:12        Sequence
+0:13          case:  with expression
+0:13            Constant:
+0:13              1 (const int)
+0:?           Sequence
+0:14            Pre-Increment (temp 4-component vector of float)
+0:14              'input' (in 4-component vector of float)
+0:15            Branch: Break
+0:16          case:  with expression
+0:16            Constant:
+0:16              2 (const int)
+0:?           Sequence
+0:17            Pre-Decrement (temp 4-component vector of float)
+0:17              'input' (in 4-component vector of float)
+0:18            Branch: Break
+0:21      switch
+0:21      condition
+0:21        'c' (in int)
+0:21      body
+0:21        Sequence
+0:22          case:  with expression
+0:22            Constant:
+0:22              1 (const int)
+0:?           Sequence
+0:23            Pre-Increment (temp 4-component vector of float)
+0:23              'input' (in 4-component vector of float)
+0:24            Branch: Break
+0:25          case:  with expression
+0:25            Constant:
+0:25              2 (const int)
+0:?           Sequence
+0:26            switch
+0:26            condition
+0:26              'd' (in int)
+0:26            body
+0:26              Sequence
+0:27                case:  with expression
+0:27                  Constant:
+0:27                    2 (const int)
+0:?                 Sequence
+0:28                  add second child into first child (temp 4-component vector of float)
+0:28                    'input' (in 4-component vector of float)
+0:28                    Constant:
+0:28                      2.000000
+0:29                  Branch: Break
+0:30                case:  with expression
+0:30                  Constant:
+0:30                    3 (const int)
+0:?                 Sequence
+0:31                  add second child into first child (temp 4-component vector of float)
+0:31                    'input' (in 4-component vector of float)
+0:31                    Constant:
+0:31                      3.000000
+0:32                  Branch: Break
+0:34            Branch: Break
+0:35          default: 
+0:?           Sequence
+0:36            add second child into first child (temp 4-component vector of float)
+0:36              'input' (in 4-component vector of float)
+0:36              Constant:
+0:36                4.000000
+0:39      switch
+0:39      condition
+0:39        'c' (in int)
+0:39      body
+0:39        Sequence
+0:40          case:  with expression
+0:40            Constant:
+0:40              1 (const int)
+0:39          Sequence
+0:39            Branch: Break
+0:43      switch
+0:43      condition
+0:43        'c' (in int)
+0:43      body
+0:43        Sequence
+0:44          case:  with expression
+0:44            Constant:
+0:44              1 (const int)
+0:45          case:  with expression
+0:45            Constant:
+0:45              2 (const int)
+0:46          case:  with expression
+0:46            Constant:
+0:46              3 (const int)
+0:?           Sequence
+0:47            Pre-Increment (temp 4-component vector of float)
+0:47              'input' (in 4-component vector of float)
+0:48            Branch: Break
+0:49          case:  with expression
+0:49            Constant:
+0:49              4 (const int)
+0:50          case:  with expression
+0:50            Constant:
+0:50              5 (const int)
+0:?           Sequence
+0:51            Pre-Decrement (temp 4-component vector of float)
+0:51              'input' (in 4-component vector of float)
+0:54      Branch: Return with expression
+0:54        'input' (in 4-component vector of float)
+0:?   Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:56  Function Definition: PixelShaderFunction(vf4;i1;i1; (temp 4-component vector of float)
+0:2    Function Parameters: 
+0:2      'input' (in 4-component vector of float)
+0:2      'c' (in int)
+0:2      'd' (in int)
+0:?     Sequence
+0:3      'c' (in int)
+0:7      switch
+0:7      condition
+0:7        'c' (in int)
+0:7      body
+0:7        Sequence
+0:9          default: 
+0:7          Sequence
+0:7            Branch: Break
+0:12      switch
+0:12      condition
+0:12        'c' (in int)
+0:12      body
+0:12        Sequence
+0:13          case:  with expression
+0:13            Constant:
+0:13              1 (const int)
+0:?           Sequence
+0:14            Pre-Increment (temp 4-component vector of float)
+0:14              'input' (in 4-component vector of float)
+0:15            Branch: Break
+0:16          case:  with expression
+0:16            Constant:
+0:16              2 (const int)
+0:?           Sequence
+0:17            Pre-Decrement (temp 4-component vector of float)
+0:17              'input' (in 4-component vector of float)
+0:18            Branch: Break
+0:21      switch
+0:21      condition
+0:21        'c' (in int)
+0:21      body
+0:21        Sequence
+0:22          case:  with expression
+0:22            Constant:
+0:22              1 (const int)
+0:?           Sequence
+0:23            Pre-Increment (temp 4-component vector of float)
+0:23              'input' (in 4-component vector of float)
+0:24            Branch: Break
+0:25          case:  with expression
+0:25            Constant:
+0:25              2 (const int)
+0:?           Sequence
+0:26            switch
+0:26            condition
+0:26              'd' (in int)
+0:26            body
+0:26              Sequence
+0:27                case:  with expression
+0:27                  Constant:
+0:27                    2 (const int)
+0:?                 Sequence
+0:28                  add second child into first child (temp 4-component vector of float)
+0:28                    'input' (in 4-component vector of float)
+0:28                    Constant:
+0:28                      2.000000
+0:29                  Branch: Break
+0:30                case:  with expression
+0:30                  Constant:
+0:30                    3 (const int)
+0:?                 Sequence
+0:31                  add second child into first child (temp 4-component vector of float)
+0:31                    'input' (in 4-component vector of float)
+0:31                    Constant:
+0:31                      3.000000
+0:32                  Branch: Break
+0:34            Branch: Break
+0:35          default: 
+0:?           Sequence
+0:36            add second child into first child (temp 4-component vector of float)
+0:36              'input' (in 4-component vector of float)
+0:36              Constant:
+0:36                4.000000
+0:39      switch
+0:39      condition
+0:39        'c' (in int)
+0:39      body
+0:39        Sequence
+0:40          case:  with expression
+0:40            Constant:
+0:40              1 (const int)
+0:39          Sequence
+0:39            Branch: Break
+0:43      switch
+0:43      condition
+0:43        'c' (in int)
+0:43      body
+0:43        Sequence
+0:44          case:  with expression
+0:44            Constant:
+0:44              1 (const int)
+0:45          case:  with expression
+0:45            Constant:
+0:45              2 (const int)
+0:46          case:  with expression
+0:46            Constant:
+0:46              3 (const int)
+0:?           Sequence
+0:47            Pre-Increment (temp 4-component vector of float)
+0:47              'input' (in 4-component vector of float)
+0:48            Branch: Break
+0:49          case:  with expression
+0:49            Constant:
+0:49              4 (const int)
+0:50          case:  with expression
+0:50            Constant:
+0:50              5 (const int)
+0:?           Sequence
+0:51            Pre-Decrement (temp 4-component vector of float)
+0:51              'input' (in 4-component vector of float)
+0:54      Branch: Return with expression
+0:54        'input' (in 4-component vector of float)
+0:?   Linker Objects
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 82
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "PixelShaderFunction" 8 21 41
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 450
+                              Name 4  "PixelShaderFunction"
+                              Name 8  "c"
+                              Name 21  "input"
+                              Name 41  "d"
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypePointer Input 6(int)
+            8(c):      7(ptr) Variable Input
+              18:             TypeFloat 32
+              19:             TypeVector 18(float) 4
+              20:             TypePointer Input 19(fvec4)
+       21(input):     20(ptr) Variable Input
+              23:   18(float) Constant 1065353216
+           41(d):      7(ptr) Variable Input
+              46:   18(float) Constant 1073741824
+              51:   18(float) Constant 1077936128
+              58:   18(float) Constant 1082130432
+4(PixelShaderFunction):           2 Function None 3
+               5:             Label
+               9:      6(int) Load 8(c)
+                              SelectionMerge 11 None
+                              Switch 9 10
+              10:               Label
+                                Branch 11
+              11:             Label
+              14:      6(int) Load 8(c)
+                              SelectionMerge 17 None
+                              Switch 14 17 
+                                     case 1: 15
+                                     case 2: 16
+              15:               Label
+              22:   19(fvec4)   Load 21(input)
+              24:   19(fvec4)   CompositeConstruct 23 23 23 23
+              25:   19(fvec4)   FAdd 22 24
+                                Store 21(input) 25
+                                Branch 17
+              16:               Label
+              27:   19(fvec4)   Load 21(input)
+              28:   19(fvec4)   CompositeConstruct 23 23 23 23
+              29:   19(fvec4)   FSub 27 28
+                                Store 21(input) 29
+                                Branch 17
+              17:             Label
+              32:      6(int) Load 8(c)
+                              SelectionMerge 36 None
+                              Switch 32 35 
+                                     case 1: 33
+                                     case 2: 34
+              35:               Label
+              59:   19(fvec4)   Load 21(input)
+              60:   19(fvec4)   CompositeConstruct 58 58 58 58
+              61:   19(fvec4)   FAdd 59 60
+                                Store 21(input) 61
+                                Branch 36
+              33:               Label
+              37:   19(fvec4)   Load 21(input)
+              38:   19(fvec4)   CompositeConstruct 23 23 23 23
+              39:   19(fvec4)   FAdd 37 38
+                                Store 21(input) 39
+                                Branch 36
+              34:               Label
+              42:      6(int)   Load 41(d)
+                                SelectionMerge 45 None
+                                Switch 42 45 
+                                       case 2: 43
+                                       case 3: 44
+              43:                 Label
+              47:   19(fvec4)     Load 21(input)
+              48:   19(fvec4)     CompositeConstruct 46 46 46 46
+              49:   19(fvec4)     FAdd 47 48
+                                  Store 21(input) 49
+                                  Branch 45
+              44:                 Label
+              52:   19(fvec4)     Load 21(input)
+              53:   19(fvec4)     CompositeConstruct 51 51 51 51
+              54:   19(fvec4)     FAdd 52 53
+                                  Store 21(input) 54
+                                  Branch 45
+              45:               Label
+                                Branch 36
+              36:             Label
+              63:      6(int) Load 8(c)
+                              SelectionMerge 65 None
+                              Switch 63 65 
+                                     case 1: 64
+              64:               Label
+                                Branch 65
+              65:             Label
+              68:      6(int) Load 8(c)
+                              SelectionMerge 71 None
+                              Switch 68 71 
+                                     case 1: 69
+                                     case 2: 69
+                                     case 3: 69
+                                     case 4: 70
+                                     case 5: 70
+              69:               Label
+              72:   19(fvec4)   Load 21(input)
+              73:   19(fvec4)   CompositeConstruct 23 23 23 23
+              74:   19(fvec4)   FAdd 72 73
+                                Store 21(input) 74
+                                Branch 71
+              70:               Label
+              76:   19(fvec4)   Load 21(input)
+              77:   19(fvec4)   CompositeConstruct 23 23 23 23
+              78:   19(fvec4)   FSub 76 77
+                                Store 21(input) 78
+                                Branch 71
+              71:             Label
+              80:   19(fvec4) Load 21(input)
+                              ReturnValue 80
+                              FunctionEnd
diff --git a/Test/hlsl.switch.frag b/Test/hlsl.switch.frag
new file mode 100644
index 0000000000000000000000000000000000000000..88239c2bec9ab5f164d2a09852a809699ecf38ff
--- /dev/null
+++ b/Test/hlsl.switch.frag
@@ -0,0 +1,55 @@
+float4 PixelShaderFunction(float4 input, int c, int d) : COLOR0
+{
+    switch(c)
+    {
+    }
+
+    switch(c)
+    {
+    default:
+    }
+
+    switch (c) {
+    case 1:
+        ++input;
+        break;
+    case 2:
+        --input;
+        break;
+    }
+
+    switch (c) {
+    case 1:
+        ++input;
+        break;
+    case 2:
+        switch (d) {
+        case 2:
+            input += 2.0;
+            break;
+        case 3:
+            input += 3.0;
+            break;
+        }
+        break;
+    default:
+        input += 4.0;
+    }
+
+    switch (c) {
+    case 1:
+    }
+
+    switch (c) {
+    case 1:
+    case 2:
+    case 3:
+        ++input;
+        break;
+    case 4:
+    case 5:
+        --input;
+    }
+
+    return input;
+}
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index d9218958bf1ae4ea7c80f31313b6d377578e2bd7..fe68a980ae8022e14006aea7fea58ee57f2ff867 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -100,6 +100,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.scope.frag", "PixelShaderFunction"},
         {"hlsl.sin.frag", "PixelShaderFunction"},
         {"hlsl.struct.frag", "PixelShaderFunction"},
+        {"hlsl.switch.frag", "PixelShaderFunction"},
         {"hlsl.swizzle.frag", "PixelShaderFunction"},
         {"hlsl.whileLoop.frag", "PixelShaderFunction"},
         {"hlsl.void.frag", "PixelShaderFunction"},
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index ae978190266ace07530aa8b34dc22b914eb125ba..417e4cb47f065ed6df54c223240c11a1074dd006 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -1322,8 +1322,16 @@ bool HlslGrammar::acceptCompoundStatement(TIntermNode*& retStatement)
     // statement statement ...
     TIntermNode* statement = nullptr;
     while (acceptStatement(statement)) {
-        // hook it up
-        compoundStatement = intermediate.growAggregate(compoundStatement, statement);
+        TIntermBranch* branch = statement ? statement->getAsBranchNode() : nullptr;
+        if (branch != nullptr && (branch->getFlowOp() == EOpCase ||
+                                  branch->getFlowOp() == EOpDefault)) {
+            // hook up individual subsequences within a switch statement
+            parseContext.wrapupSwitchSubsequence(compoundStatement, statement);
+            compoundStatement = nullptr;
+        } else {
+            // hook it up to the growing compound statement
+            compoundStatement = intermediate.growAggregate(compoundStatement, statement);
+        }
     }
     if (compoundStatement)
         compoundStatement->setOperator(EOpSequence);
@@ -1397,6 +1405,8 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
 
     case EHTokCase:
         return acceptCaseLabel(statement);
+    case EHTokDefault:
+        return acceptDefaultLabel(statement);
 
     case EHTokSemicolon:
         return acceptTokenClass(EHTokSemicolon);
@@ -1527,9 +1537,34 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
     return true;
 }
 
+// switch_statement
+//      : SWITCH LEFT_PAREN expression RIGHT_PAREN compound_statement
+//
 bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement)
 {
-    return false;
+    // SWITCH
+    TSourceLoc loc = token.loc;
+    if (! acceptTokenClass(EHTokSwitch))
+        return false;
+
+    // LEFT_PAREN expression RIGHT_PAREN
+    parseContext.pushScope();
+    TIntermTyped* switchExpression;
+    if (! acceptParenExpression(switchExpression)) {
+        parseContext.popScope();
+        return false;
+    }
+
+    // compound_statement
+    parseContext.pushSwitchSequence(new TIntermSequence);
+    bool statementOkay = acceptCompoundStatement(statement);
+    if (statementOkay)
+        statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr);
+
+    parseContext.popSwitchSequence();
+    parseContext.popScope();
+
+    return statementOkay;
 }
 
 // iteration_statement
@@ -1718,9 +1753,48 @@ bool HlslGrammar::acceptJumpStatement(TIntermNode*& statement)
     return true;
 }
 
+// case_label
+//      : CASE expression COLON
+//
 bool HlslGrammar::acceptCaseLabel(TIntermNode*& statement)
 {
-    return false;
+    TSourceLoc loc = token.loc;
+    if (! acceptTokenClass(EHTokCase))
+        return false;
+
+    TIntermTyped* expression;
+    if (! acceptExpression(expression)) {
+        expected("case expression");
+        return false;
+    }
+
+    if (! acceptTokenClass(EHTokColon)) {
+        expected(":");
+        return false;
+    }
+
+    statement = parseContext.intermediate.addBranch(EOpCase, expression, loc);
+
+    return true;
+}
+
+// default_label
+//      : DEFAULT COLON
+//
+bool HlslGrammar::acceptDefaultLabel(TIntermNode*& statement)
+{
+    TSourceLoc loc = token.loc;
+    if (! acceptTokenClass(EHTokDefault))
+        return false;
+
+    if (! acceptTokenClass(EHTokColon)) {
+        expected(":");
+        return false;
+    }
+
+    statement = parseContext.intermediate.addBranch(EOpDefault, loc);
+
+    return true;
 }
 
 // array_specifier
diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h
index baeb686e1210592d13295547f529ff844d1edef3..f00ed4e07bd792f49e3f7abfea848d0c637c31a7 100755
--- a/hlsl/hlslGrammar.h
+++ b/hlsl/hlslGrammar.h
@@ -88,6 +88,7 @@ namespace glslang {
         bool acceptIterationStatement(TIntermNode*&);
         bool acceptJumpStatement(TIntermNode*&);
         bool acceptCaseLabel(TIntermNode*&);
+        bool acceptDefaultLabel(TIntermNode*&);
         void acceptArraySpecifier(TArraySizes*&);
         void acceptPostDecls(TType&);
 
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 928021ebf57f4e7605e9d3c794a9da8a11e58caf..297bfce51b8093685332feec866e1f6bcdbb85f6 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -3969,8 +3969,6 @@ void HlslParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIn
     TIntermSequence* switchSequence = switchSequenceStack.back();
 
     if (statements) {
-        if (switchSequence->size() == 0)
-            error(statements->getLoc(), "cannot have statements before first case/default label", "switch", "");
         statements->setOperator(EOpSequence);
         switchSequence->push_back(statements);
     }
diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h
index 9b8ff2dd847c18a19a564c4c739e25668bf5b412..502337112fead9ad429c10f6a713cf0f54fcdbdc 100755
--- a/hlsl/hlslParseHelper.h
+++ b/hlsl/hlslParseHelper.h
@@ -147,6 +147,9 @@ public:
     void pushScope()       { symbolTable.push(); }
     void popScope()        { symbolTable.pop(0); }
 
+    void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); }
+    void popSwitchSequence() { switchSequenceStack.pop_back(); }
+
 protected:
     void inheritGlobalDefaults(TQualifier& dst) const;
     TVariable* makeInternalVariable(const char* name, const TType&) const;
@@ -166,7 +169,6 @@ protected:
     int structNestingLevel;      // 0 if outside blocks and structures
     int controlFlowNestingLevel; // 0 if outside all flow control
     TList<TIntermSequence*> switchSequenceStack;  // case, node, case, case, node, ...; ensure only one node between cases;   stack of them for nesting
-    TList<int> switchLevel;      // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
     bool inEntrypoint;           // if inside a function, true if the function is the entry point
     bool postMainReturn;         // if inside a function, true if the function is the entry point and this is after a return statement
     const TType* currentFunctionType;  // the return type of the function that's currently being parsed