Add OpCopyMemory test to SVA. (#2885)

This CL adds a test for OpCopyMemory and adds the needed IdMemorySemantics and
IdScope in order to extract the parameters.
diff --git a/tools/sva/src/parser.js b/tools/sva/src/parser.js
index 3eee661..ccf872a 100644
--- a/tools/sva/src/parser.js
+++ b/tools/sva/src/parser.js
@@ -170,8 +170,14 @@
 
     // TODO(dsinclair): There are a bunch of missing types here. See
     // https://github.com/KhronosGroup/SPIRV-Tools/blob/master/source/text.cpp#L210
+    //
+    // LiteralSpecConstantOpInteger
+    // PairLiteralIntegerIdRef
+    // PairIdRefLiteralInteger
+    // PairIdRefIdRef
     if (data.kind === "IdResult" || data.kind === "IdRef"
-        || data.kind === "IdResultType") {
+        || data.kind === "IdResultType" || data.kind === "IdScope"
+        || data.kind === "IdMemorySemantics") {
       if (t.type !== TokenType.kResultId) {
         this.error_ = t.line + ": expected result id";
         return undefined;
diff --git a/tools/sva/src/parser_test.js b/tools/sva/src/parser_test.js
index e64aabd..dffc0b3 100644
--- a/tools/sva/src/parser_test.js
+++ b/tools/sva/src/parser_test.js
@@ -456,9 +456,34 @@
     // let input = "%sum = OpSpecConstantOp %i32 IAdd %a %b";
   });
 
-  it.skip("handles OpCopyMemory", () => {
-    // let input = "OpCopyMemory %1 %2 " +
-    //             "Volatile|Nontemporal|MakePointerVisible %3 " +
-    //             "Aligned|MakePointerAvailable|NonPrivatePointer 16 %4";
+  it("handles OpCopyMemory", () => {
+    let input = "OpCopyMemory %1 %2 " +
+                "Volatile|Nontemporal|MakePointerVisible %3 " +
+                "Aligned|MakePointerAvailable|NonPrivatePointer 16 %4";
+
+    let l = new Lexer(input);
+    let p = new Parser(grammar, l);
+
+    let ast = p.parse();
+    assert.exists(ast, p.error);
+    assert.lengthOf(ast.instructions(), 1);
+
+    let inst = ast.instruction(0);
+    assert.lengthOf(inst.operands(), 4);
+    assert.equal(inst.operand(0).value(), 1);
+    assert.equal(inst.operand(1).value(), 2);
+
+    assert.equal(inst.operand(2).name(),
+        "Volatile|Nontemporal|MakePointerVisible");
+    assert.equal(inst.operand(2).value(), 21);
+    assert.lengthOf(inst.operand(2).params(), 1);
+    assert.equal(inst.operand(2).params()[0].value(), 3);
+
+    assert.equal(inst.operand(3).name(),
+        "Aligned|MakePointerAvailable|NonPrivatePointer");
+    assert.equal(inst.operand(3).value(), 42);
+    assert.lengthOf(inst.operand(3).params(), 2);
+    assert.equal(inst.operand(3).params()[0].value(), 16);
+    assert.equal(inst.operand(3).params()[1].value(), 4);
   });
 });