gollvm: refactor unit testing hooks for expected results

Refactor the code in the gollvm unit test that stores expected results
(golden outputs). No change in functionality; this is just to lay the
groundwork for introducing a mode automated way to remaster expected
results when many results change (due to changes in LLVM IR dumps).

Updates golang/go#38728.

Change-Id: I9968ecfa1e62a20700ee324a4792c3a96ea30858
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/232738
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: eric fang <eric.fang@arm.com>
diff --git a/unittests/BackendCore/BackendArrayStruct.cpp b/unittests/BackendCore/BackendArrayStruct.cpp
index 249e8cb..8a558aa 100644
--- a/unittests/BackendCore/BackendArrayStruct.cpp
+++ b/unittests/BackendCore/BackendArrayStruct.cpp
@@ -78,7 +78,7 @@
   Bexpression *bc2 = mkInt32Const(be, 2);
   h.mkAssign(bfex2, bc2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { i8*, i32 }* %loc1 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i8*, i32 }* @const.0 to i8*), i64 16, i1 false)
     store { i8*, i32 }* %loc1, { i8*, i32 }** %loc2
@@ -92,7 +92,7 @@
     %loc2.ld.0 = load { i8*, i32 }*, { i8*, i32 }** %loc2
     %field.2 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc2.ld.0, i32 0, i32 1
     store i32 2, i32* %field.2
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -144,7 +144,7 @@
   Bexpression *fex2 = be->struct_field_expression(sex2, 1, loc);
   h.mkAssign(vex2, fex2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %tmp.0 = alloca { i8*, i32 }
@@ -165,7 +165,7 @@
       store i32 42, i32* %z
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -230,7 +230,7 @@
   Bexpression *eex3 = be->array_index_expression(aex3, iex3, loc);
   h.mkAssign(vex3, eex3);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %tmp.0 = alloca [4 x i64]
@@ -261,7 +261,7 @@
       store i64 %.index.ld.1, i64* %w
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -305,7 +305,7 @@
       be->array_constructor_expression(at4, indexes3, vals3, loc);
   h.mkLocal("ac", at4, arcon3);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast [4 x i64]* %aa to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ([4 x i64]* @const.0 to i8*), i64 32, i1 false)
     %cast.1 = bitcast [4 x i64]* %ab to i8*
@@ -320,7 +320,7 @@
     store i64 0, i64* %index.2
     %index.3 = getelementptr [4 x i64], [4 x i64]* %ac, i32 0, i32 3
     store i64 0, i64* %index.3
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -366,7 +366,7 @@
   Bexpression *scon2 = be->constructor_expression(s2t, vals2, loc);
   h.mkLocal("loc2", s2t, scon2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { i32*, i32 }* %loc1 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i32*, i32 }* @const.0 to i8*), i64 16, i1 false)
     %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc1, i32 0, i32 1
@@ -375,7 +375,7 @@
     store i32* %param1.addr, i32** %field.1
     %field.2 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc2, i32 0, i32 1
     store i32 %loc1.field.ld.0, i32* %field.2
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -422,7 +422,7 @@
   Bexpression *vex = be->var_expression(loc1, loc);
   h.mkAssign(vex, scon2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { { i32*, i32 }, float }* %loc1 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ { i32*, i32 }, float }* @const.0 to i8*), i64 24, i1 false)
     %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %tmp.0, i32 0, i32 0
@@ -435,7 +435,7 @@
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 16, i1 false)
     %field.3 = getelementptr inbounds { { i32*, i32 }, float }, { { i32*, i32 }, float }* %loc1, i32 0, i32 1
     store float 3.000000e+00, float* %field.3
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -471,14 +471,14 @@
   Bexpression *scon = be->constructor_expression(s2t, vals, loc);
   h.mkAssign(dex, scon);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %p0.ld.0 = load { i32*, i32 }*, { i32*, i32 }** %p0.addr
     %p1.ld.0 = load i32*, i32** %p1.addr
     %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 0
     store i32* %p1.ld.0, i32** %field.0
     %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 1
     store i32 101, i32* %field.1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -525,13 +525,13 @@
   Bexpression *scon2 = be->constructor_expression(s1t, vals2, loc);
   h.mkLocal("t2", s1t, scon2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %x.ld.0 = load i32, i32* @x
     store i32 %x.ld.0, i32* getelementptr inbounds ({ i32 }, { i32 }* @t, i32 0, i32 0)
     %t.field.ld.0 = load i32, i32* getelementptr inbounds ({ i32 }, { i32 }* @t, i32 0, i32 0)
     %field.2 = getelementptr inbounds { i32 }, { i32 }* %t2, i32 0, i32 0
     store i32 %t.field.ld.0, i32* %field.2
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -579,7 +579,7 @@
   // aa[aa[1]] = aa[aa[3]]
   h.mkAssign(aa4, aa3);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast [4 x i64]* %aa to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ([4 x i64]* @const.0 to i8*), i64 32, i1 false)
     %index.0 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i32 1
@@ -590,7 +590,7 @@
     %index.3 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 %aa.index.ld.1
     %aa.index.ld.2 = load i64, i64* %index.3
     store i64 %aa.index.ld.2, i64* %index.1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -648,7 +648,7 @@
     Bexpression *bi64five = mkInt64Const(be, 5);
     h.mkAssign(fx, bi64five);
 
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       %cast.0 = bitcast [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1 to i8*
       call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ([10 x { i8, [4 x { i64, i64 }*], i8 }*]* @const.0 to i8*), i64 80, i1 false)
       %index.0 = getelementptr [10 x { i8, [4 x { i64, i64 }*], i8 }*], [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1, i32 0, i32 7
@@ -658,7 +658,7 @@
       %.field.index.ld.0 = load { i64, i64 }*, { i64, i64 }** %index.1
       %field.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %.field.index.ld.0, i32 0, i32 0
       store i64 5, i64* %field.1
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = h.expectBlock(exp);
     EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -679,7 +679,7 @@
     Bexpression *fx = be->struct_field_expression(iar3, 1, loc);
     h.mkLocal("q", bi64t, fx);
 
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       %index.2 = getelementptr [10 x { i8, [4 x { i64, i64 }*], i8 }*], [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1, i32 0, i32 0
       %t1.index.ld.1 = load { i8, [4 x { i64, i64 }*], i8 }*, { i8, [4 x { i64, i64 }*], i8 }** %index.2
       %field.2 = getelementptr inbounds { i8, [4 x { i64, i64 }*], i8 }, { i8, [4 x { i64, i64 }*], i8 }* %t1.index.ld.1, i32 0, i32 1
@@ -688,7 +688,7 @@
       %field.3 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %.field.index.ld.1, i32 0, i32 1
       %.field.ld.0 = load i64, i64* %field.3
       store i64 %.field.ld.0, i64* %q
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = h.expectBlock(exp);
     EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -729,7 +729,7 @@
   Bexpression *ve4 = be->var_expression(y2, loc);
   h.mkAssign(ve3, ve4);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { i8* }* %x1 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i8* }* @const.0 to i8*), i64 8, i1 false)
     %cast.1 = bitcast { i8* }* %y1 to i8*
@@ -744,7 +744,7 @@
     %cast.6 = bitcast { i64, i64, i64, i64, i64, i64 }* %x2 to i8*
     %cast.7 = bitcast { i64, i64, i64, i64, i64, i64 }* %y2 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 48, i1 false)
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -786,13 +786,13 @@
   Bexpression *aex2 = be->address_expression(fex2, loc);
   h.mkLocal("a2", bpi32t, aex2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { i32 }* %t1 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 bitcast ({ i32 }* @const.0 to i8*), i64 4, i1 false)
     %field.0 = getelementptr inbounds { i32 }, { i32 }* %t1, i32 0, i32 0
     store i32* %field.0, i32** %a1
     store i32* getelementptr inbounds ({ i32 }, { i32 }* @t2, i32 0, i32 0), i32** %a2
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
diff --git a/unittests/BackendCore/BackendCABIOracleTests.cpp b/unittests/BackendCore/BackendCABIOracleTests.cpp
index f43f8a8..f01b819 100644
--- a/unittests/BackendCore/BackendCABIOracleTests.cpp
+++ b/unittests/BackendCore/BackendCABIOracleTests.cpp
@@ -53,16 +53,16 @@
                                       L_RES, st2,
                                       L_END);
     CABIOracle cab(befty1, be->typeManager());
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       Return: Direct { { double, double } } sigOffset: -1
       Param 1: Direct AttrNest { i8* } sigOffset: 0
       Param 2: Direct AttrSext { i8 } sigOffset: 1
       Param 3: Direct { float } sigOffset: 2
       Param 4: Ignore { void } sigOffset: -1
       Param 5: Direct { i64 } sigOffset: 3
-    )RAW_RESULT";
+    )RAW_RESULT");
     std::string reason;
-    bool equal = difftokens(exp, cab.toString(), reason);
+    bool equal = difftokens(exp.content, cab.toString(), reason);
     EXPECT_EQ("pass", equal ? "pass" : reason);
     EXPECT_EQ(repr(cab.getFunctionTypeForABI()),
               "{ double, double } (i8*, i8, float, i64)");
@@ -531,7 +531,7 @@
   rvals2.push_back(call);
   Bstatement *rst2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %p3.ld.0 = load i8, i8* %p3.addr
     %sub.0 = sub i8 %p3.ld.0, 1
     %p4.ld.0 = load i8, i8* %p4.addr
@@ -551,7 +551,7 @@
     %cast.4 = bitcast { double, float, float }* %sret.actual.0 to { double, <2 x float> }*
     %ld.5 = load { double, <2 x float> }, { double, <2 x float> }* %cast.4
     ret { double, <2 x float> } %ld.5
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectStmt(rst2, exp);
   EXPECT_TRUE(isOK && "Statement does not have expected contents");
@@ -650,7 +650,7 @@
   rvals2.push_back(call);
   Bstatement *rst2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %p3.ld.0 = load i8, i8* %p3.addr
     %sub.0 = sub i8 %p3.ld.0, 1
     %p4.ld.0 = load i8, i8* %p4.addr
@@ -673,7 +673,7 @@
     %cast.6 = bitcast { double, float, float }* %sret.actual.0 to { i64, i64 }*
     %ld.5 = load { i64, i64 }, { i64, i64 }* %cast.6
     ret { i64, i64 } %ld.5
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectStmt(rst2, exp);
   EXPECT_TRUE(isOK && "Statement does not have expected contents");
@@ -715,7 +715,7 @@
   rvals.push_back(call);
   h.mkReturn(rvals);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast [2 x float]* %p0.addr to <2 x float>*
     %ld.0 = load <2 x float>, <2 x float>* %cast.0
     call addrspace(0) void @foo([3 x double]* sret "go_sret" %sret.actual.0, i8* nest undef, <2 x float> %ld.0)
@@ -723,7 +723,7 @@
     %cast.2 = bitcast [3 x double]* %sret.actual.0 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 24, i1 false)
     ret void
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -759,7 +759,7 @@
   rvals.push_back(call);
   h.mkReturn(rvals);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %ld.0 = load [2 x float], [2 x float]* %p0.addr
     %call.0 = call addrspace(0) { double, double, double } @foo(i8* nest undef, [2 x float] %ld.0)
     %cast.1 = bitcast [3 x double]* %sret.actual.0 to { double, double, double }*
@@ -767,7 +767,7 @@
     %cast.2 = bitcast [3 x double]* %sret.actual.0 to { double, double, double }*
     %ld.1 = load { double, double, double }, { double, double, double }* %cast.2
     ret { double, double, double } %ld.1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -812,10 +812,10 @@
   rvals.push_back(call);
   h.mkReturn(rvals);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     call addrspace(0) void @foo(i8* nest undef, i32 4)
     ret void
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -838,9 +838,9 @@
   std::vector<Bexpression *> args;
   h.mkExprStmt(be->call_expression(func, fn, args, nullptr, h.loc()));
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     call addrspace(0) void @llvm.trap()
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -894,7 +894,7 @@
   std::vector<Bexpression *> rvals = {call2};
   h.mkReturn(rvals);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { float, float }* %p0.addr to <2 x float>*
     %ld.0 = load <2 x float>, <2 x float>* %cast.0
     %field0.0 = getelementptr inbounds { double, double }, { double, double }* %p1.addr, i32 0, i32 0
@@ -916,7 +916,7 @@
     %cast.8 = bitcast { float, float }* %sret.actual.1 to <2 x float>*
     %ld.6 = load <2 x float>, <2 x float>* %cast.8
     ret <2 x float> %ld.6
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -967,7 +967,7 @@
   std::vector<Bexpression *> rvals = {call2};
   h.mkReturn(rvals);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { float, float }* %p0.addr to [2 x float]*
     %ld.0 = load [2 x float], [2 x float]* %cast.0
     %cast.1 = bitcast { double, double }* %p1.addr to [2 x double]*
@@ -983,7 +983,7 @@
     store { float, float } %call.1, { float, float }* %sret.actual.1
     %ld.4 = load { float, float }, { float, float }* %sret.actual.1
     ret { float, float } %ld.4
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
diff --git a/unittests/BackendCore/BackendCallTests.cpp b/unittests/BackendCore/BackendCallTests.cpp
index 5e172dc..47816fd 100644
--- a/unittests/BackendCore/BackendCallTests.cpp
+++ b/unittests/BackendCore/BackendCallTests.cpp
@@ -46,12 +46,12 @@
   Bvariable *x = h.mkLocal("x", bi64t, call);
   h.mkReturn(be->var_expression(x, loc));
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %call.0 = call addrspace(0) i64 @foo(i8* nest undef, i32 3, i32 6, i64* null)
     store i64 %call.0, i64* %x
     %x.ld.0 = load i64, i64* %x
     ret i64 %x.ld.0
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -79,9 +79,9 @@
   Bexpression *call = be->call_expression(func, fn, args, nullptr, loc);
   h.mkExprStmt(call);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     call addrspace(0) void @bar(i8* nest undef)
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -118,11 +118,11 @@
   Bstatement *s1 = h.mkReturn(rvals, FcnTestHarness::NoAppend);
 
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       %cast.0 = bitcast { i8*, i32*, i64*, i64 }* %sret.formal.0 to i8*
       call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i8*, i32*, i64*, i64 }* @const.0 to i8*), i64 32, i1 false)
       ret void
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = h.expectStmt(s1, exp);
     EXPECT_TRUE(isOK && "First return stmt does not have expected contents");
@@ -142,7 +142,7 @@
   Bstatement *s2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend);
 
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       %p0.ld.0 = load i8*, i8** %p0.addr
       %field.0 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 0
       store i8* %p0.ld.0, i8** %field.0
@@ -156,7 +156,7 @@
       %cast.3 = bitcast { i8*, i32*, i64*, i64 }* %tmp.0 to i8*
       call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 32, i1 false)
       ret void
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = h.expectStmt(s2, exp);
     EXPECT_TRUE(isOK && "Second return stmt does not have expected contents");
@@ -205,7 +205,7 @@
   h.mkIf(cond, be->block_statement(nrcblock), nullptr,
          FcnTestHarness::YesAppend);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       br i1 true, label %then.0, label %else.0
@@ -220,7 +220,7 @@
     else.0:                                           ; preds = %entry
       br label %fallthrough.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
diff --git a/unittests/BackendCore/BackendDebugEmit.cpp b/unittests/BackendCore/BackendDebugEmit.cpp
index b54cb05..31fa907 100644
--- a/unittests/BackendCore/BackendDebugEmit.cpp
+++ b/unittests/BackendCore/BackendDebugEmit.cpp
@@ -41,7 +41,7 @@
   Btype *bu32t = be->integer_type(true, 32);
   h.mkLocal("x", bu32t);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %x = alloca i32
@@ -50,7 +50,7 @@
                                   metadata !DIExpression()), !dbg !12
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(PreserveDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -76,14 +76,14 @@
   bool broken = h.finish(PreserveDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0, { i64, i64, i64 }* byval %p0) #0 {
     entry:
       call void @llvm.dbg.declare(metadata { i64, i64, i64 }* %p0, metadata !5,
                                   metadata !DIExpression()), !dbg !18
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -104,14 +104,14 @@
   bool broken = h.finish(PreserveDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0, { i64, i64, i64 }* %p0) #0 {
     entry:
       call void @llvm.dbg.declare(metadata { i64, i64, i64 }* %p0, metadata !5,
                                   metadata !DIExpression()), !dbg !18
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -211,13 +211,13 @@
   Btype *bu32t = be->integer_type(true, 32);
   h.mkLocal("x", bu32t);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 !dbg !5 {
     entry:
       %x = alloca i32
       ret void, !dbg !10
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(PreserveDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
diff --git a/unittests/BackendCore/BackendExprTests.cpp b/unittests/BackendCore/BackendExprTests.cpp
index d3ffd3c..c73e2c0 100644
--- a/unittests/BackendCore/BackendExprTests.cpp
+++ b/unittests/BackendCore/BackendExprTests.cpp
@@ -243,13 +243,13 @@
   Bexpression *fex = be->struct_field_expression(dex, 1, loc);
   h.mkAssign(fex, mkInt32Const(be, 22));
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     %cast.0 = bitcast i64* %x to { i32, i32 }*
     %field.0 = getelementptr inbounds { i32, i32 },
         { i32, i32 }* %cast.0, i32 0, i32 1
     store i32 22, i32* %field.0
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -295,7 +295,7 @@
     h.mkAssign(dex, mkInt32Const(be, 5));
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %param3.ld.0 = load i64*, i64** %param3.addr
     %cast.0 = bitcast i64* %param3.ld.0 to i32*
     store i32 5, i32* %cast.0
@@ -304,7 +304,7 @@
     %ftoui.0 = fptoui double %p.ld.0 to i64
     %itpcast.0 = inttoptr i64 %ftoui.0 to i32*
     store i32 5, i32* %itpcast.0
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -354,7 +354,7 @@
     }
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %p1.ld.0 = load double, double* %p1.addr
     %fptrunc.0 = fptrunc double %p1.ld.0 to float
     store float %fptrunc.0, float* %p0.addr
@@ -441,7 +441,7 @@
     %p4.ld.4 = load i32, i32* %p4.addr
     %zext.1 = zext i32 %p4.ld.4 to i64
     store i64 %zext.1, i64* %p5.addr
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -493,7 +493,7 @@
   Bexpression *convex4 = be->convert_expression(bc128t, yvex4, loc);
   h.mkAssign(xvex4, convex4);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %tmp.3 = alloca { double, double }
@@ -552,7 +552,7 @@
       call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.14, i8* align 8 %cast.15, i64 16, i1 false)
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -630,7 +630,7 @@
     }
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     store i64 0, i64* %y
     store double 0.000000e+00, double* %z
@@ -688,7 +688,7 @@
     %z.ld.5 = load double, double* %z
     %fcmp.5 = fcmp oge double 9.000000e+00, %z.ld.5
     %zext.17 = zext i1 %fcmp.5 to i8
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -727,7 +727,7 @@
     }
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     store double 0.000000e+00, double* %y
     %x.ld.0 = load i64, i64* %x
@@ -738,7 +738,7 @@
     %fadd.0 = fadd double 9.000000e+00, %y.ld.0
     %y.ld.1 = load double, double* %y
     %fsub.0 = fsub double 9.000000e+00, %y.ld.1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -769,7 +769,7 @@
   Bexpression *vex = be->var_expression(x, loc);
   h.mkAssign(vex, ypzpw);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     store i64 9, i64* %y
     store i64 10, i64* %z
@@ -780,7 +780,7 @@
     %w.ld.0 = load i64, i64* %w
     %add.1 = add i64 %add.0, %w.ld.0
     store i64 %add.1, i64* %x
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -825,7 +825,7 @@
     }
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     store i64 0, i64* %y
     store i8 0, i8* %z
@@ -886,7 +886,7 @@
     %z.ld.5 = load i8, i8* %z
     %z2.ld.5 = load i8, i8* %z2
     %iand.8 = and i8 %z.ld.5, %z2.ld.5
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -931,7 +931,7 @@
     }
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i16 0, i16* %x
     store i16 0, i16* %y
     store double 0.000000e+00, double* %z
@@ -951,7 +951,7 @@
     %fmul.0 = fmul double 9.000000e+00, %z.ld.0
     %z.ld.1 = load double, double* %z
     %fdiv.0 = fdiv double 9.000000e+00, %z.ld.1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -1011,7 +1011,7 @@
     h.addStmt(es);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     store i64 0, i64* %y
     store i64 0, i64* %s
@@ -1036,7 +1036,7 @@
     %y.ld.2 = load i64, i64* %y
     %trunc.0 = trunc i64 %y.ld.2 to i32
     %shr.2 = lshr i32 %z.ld.1, %trunc.0
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -1074,7 +1074,7 @@
     h.mkAssign(bvex, bop);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %tmp.12 = alloca { double, double }
@@ -1224,7 +1224,7 @@
       store i8 %ior.0, i8* %b
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1266,7 +1266,7 @@
   Bexpression *compex = be->complex_expression(bvex3, avex3, loc);
   h.mkAssign(xvex3, compex);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store double 0.000000e+00, double* %a
     store double 0.000000e+00, double* %b
     %cast.0 = bitcast { double, double }* %x to i8*
@@ -1283,7 +1283,7 @@
     store double %b.ld.0, double* %field.2
     %field.3 = getelementptr inbounds { double, double }, { double, double }* %x, i32 0, i32 1
     store double %a.ld.0, double* %field.3
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -1299,18 +1299,18 @@
 
   {
     Bexpression *snil = be->string_constant_expression("");
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
         i8* null
-      )RAW_RESULT";
+      )RAW_RESULT");
     bool isOK = h.expectValue(snil->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
   }
 
   {
     Bexpression *sblah = be->string_constant_expression("blah");
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       i8* getelementptr inbounds ([5 x i8], [5 x i8]* @const.0, i32 0, i32 0)
-    )RAW_RESULT";
+    )RAW_RESULT");
     bool isOK = h.expectValue(sblah->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
   }
@@ -1342,7 +1342,7 @@
                                                    call2, loc);
   h.mkExprStmt(condex);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %a = alloca i64
@@ -1367,7 +1367,7 @@
       call void @foo(i8* nest undef)
       br label %fallthrough.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1399,7 +1399,7 @@
                                                    ve, loc);
   h.mkExprStmt(condex);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %a = alloca i64
@@ -1417,7 +1417,7 @@
       store i64 %a.ld.0, i64* %tmpv.0
       br label %fallthrough.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1452,7 +1452,7 @@
                                                  vep0, bzero, loc);
   h.mkLocal("a", s2t, cond);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo({ [16 x i32], i32 }* sret %sret.formal.0, i8* nest %nest.0, { [16 x i32], i32 }* byval %p0, i32 %p1) #0 {
     entry:
       %p1.addr = alloca i32
@@ -1482,7 +1482,7 @@
       call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 bitcast ({ [16 x i32], i32 }* @const.0 to i8*), i64 68, i1 false)
       br label %fallthrough.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1527,7 +1527,7 @@
       be->conditional_expression(func, s2t, cmp, vep0, bzero, loc);
   h.mkLocal("a", s2t, cond);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo({ [16 x i32], i32 }* sret %sret.formal.0, i8* nest %nest.0, { [16 x i32], i32 }* %p0, i32 %p1) #0 {
     entry:
       %p1.addr = alloca i32
@@ -1557,7 +1557,7 @@
       call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 bitcast ({ [16 x i32], i32 }* @const.0 to i8*), i64 68, i1 false)
       br label %fallthrough.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1586,7 +1586,7 @@
   Bstatement *es = be->expression_statement(func, ce);
   h.addStmt(es);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
       entry:
         %param1.addr = alloca i32
@@ -1601,7 +1601,7 @@
         %x.ld.0 = load i64, i64* %x
         ret i64 0
       }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1636,7 +1636,7 @@
   Bstatement *st2 = be->assignment_statement(func, yvex, ce, loc);
   h.addStmt(st2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
       entry:
       %tmp.0 = alloca { i64, i64 }
@@ -1663,7 +1663,7 @@
       call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 16, i1 false)
       ret i64 0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1698,7 +1698,7 @@
   Bexpression *dex = be->indirect_expression(bi32t, guard, false, loc);
   h.mkAssign(dex, mkInt32Const(be, 7));
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0, i32* %p0, i32* %p1) #0 {
     entry:
       %p0.addr = alloca i32*
@@ -1727,7 +1727,7 @@
       store i32* %p0.ld.1, i32** %tmpv.0
       br label %fallthrough.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1771,7 +1771,7 @@
   Bexpression *veq = be->var_expression(qv, loc);
   h.mkLocal("r", bf64t, be->unary_expression(OPERATOR_MINUS, veq, loc));
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i8 0, i8* %x
     %x.ld.0 = load i8, i8* %x
     %icmp.0 = icmp ne i8 %x.ld.0, 0
@@ -1790,7 +1790,7 @@
     %q.ld.0 = load double, double* %q
     %fsub.0 = fsub double -0.000000e+00, %q.ld.0
     store double %fsub.0, double* %r
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -1818,9 +1818,9 @@
   Bexpression *call1 = h.mkCallExpr(be, func, nil, nil, nil, nullptr);
   h.mkExprStmt(call1);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     call addrspace(0) void @foo(i8* nest undef, i8* null, i32* null, i64* null)
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   // Note that this
   bool isOK = h.expectBlock(exp);
diff --git a/unittests/BackendCore/BackendFcnTests.cpp b/unittests/BackendCore/BackendFcnTests.cpp
index dd5bc52..d87ef1b 100644
--- a/unittests/BackendCore/BackendFcnTests.cpp
+++ b/unittests/BackendCore/BackendFcnTests.cpp
@@ -34,8 +34,8 @@
   BFunctionType *befty1 = mkFuncTyp(be, L_END);
   h.mkFunction("foo", befty1);
 
-  const char *exp = R"RAW_RESULT(
-    )RAW_RESULT";
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
+    )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -66,8 +66,8 @@
                                     L_END);
   h.mkFunction("foo", befty1);
 
-  const char *exp = R"RAW_RESULT(
-    )RAW_RESULT";
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
+    )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -239,8 +239,8 @@
                                     L_END);
   h.mkFunction("foo", befty1);
 
-  const char *exp = R"RAW_RESULT(
-    )RAW_RESULT";
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
+    )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -297,11 +297,11 @@
   Bexpression *call = h.mkCallExpr(be, bfcn, ve, nullptr);
   h.mkExprStmt(call);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     %x.ld.0 = load i64, i64* %x
     %call.0 = call addrspace(0) i64 @llvm.cttz.i64(i64 %x.ld.0, i1 true)
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -363,7 +363,7 @@
     h.mkExprStmt(call);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     store i64 10101, i64* %y
     %cast.0 = bitcast i64* %x to i8*
@@ -375,7 +375,7 @@
     %cast.4 = bitcast i64* %y to i8*
     %cast.5 = bitcast i64* %x to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* %cast.4, i8* %cast.5, i64 8, i1 false)
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -424,13 +424,13 @@
   Bexpression *call32 = h.mkCallExpr(be, bf2, mkInt32Const(be, 32), nullptr);
   h.mkLocal("y", bi32t, call32);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %call.0 = call addrspace(0) i64 @syscall(i8* nest undef, i64 64)
     store i64 %call.0, i64* %x
     %call.1 = call addrspace(0) i32 bitcast (i64 (i8*, i64)*
           @syscall to i32 (i8*, i32)*)(i8* nest undef, i32 32)
     store i32 %call.1, i32* %y
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -498,7 +498,7 @@
   Bexpression *call4 = h.mkCallExpr(be, bf4, nullptr);
   h.mkLocal("y", bps1t, call4);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %call.0 = call addrspace(0) i32 @bar(i8* nest undef)
     store i32 %call.0, i32* %a
     %call.1 = call addrspace(0) i32 @bar(i8* nest undef)
@@ -507,7 +507,7 @@
     store {}* %call.2, {}** %x
     %call.3 = call addrspace(0) { i32 }* @baz(i8* nest undef)
     store { i32 }* %call.3, { i32 }** %y
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
diff --git a/unittests/BackendCore/BackendNodeTests.cpp b/unittests/BackendCore/BackendNodeTests.cpp
index dbed932..4dfe887 100644
--- a/unittests/BackendCore/BackendNodeTests.cpp
+++ b/unittests/BackendCore/BackendNodeTests.cpp
@@ -91,7 +91,7 @@
 
   EXPECT_EQ(res1, matsub);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     node - pre 18
     pre child + 18 15
     node + pre 15
@@ -122,13 +122,13 @@
     node deref post 17
     post child deref 18 17
     node - post 18
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   std::string reason;
-  bool equal = difftokens(exp, vis.str(), reason);
+  bool equal = difftokens(exp.content, vis.str(), reason);
   EXPECT_EQ("pass", equal ? "pass" : reason);
   if (!equal) {
-    std::cerr << "expected dump:\n" << exp << "\n";
+    std::cerr << "expected dump:\n" << exp.content << "\n";
     std::cerr << "result dump:\n" << vis.str() << "\n";
   }
 
@@ -162,7 +162,7 @@
   Bexpression *matclone = be->nodeBuilder().cloneSubtree(matadd);
   EXPECT_NE(add, matclone);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %x.ld.0 = load i32, i32* %x
     %z.ld.0 = load i16, i16* %z
     %sext.0 = sext i16 %z.ld.0 to i32
@@ -170,7 +170,7 @@
     %y.ld.0 = load i32*, i32** %y
     %.ld.0 = load i32, i32* %y.ld.0
     %add.1 = add i32 %add.0, %.ld.0
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectRepr(matadd, exp);
   EXPECT_TRUE(isOK && "expr does not have expected contents");
@@ -204,7 +204,7 @@
   Bexpression *add = be->binary_expression(OPERATOR_PLUS, der, der, loc);
   Bexpression *matadd = be->materialize(add);
 
-  const char *exp2 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp2, R"RAW_RESULT(
     %field.0 = getelementptr inbounds { { i32*, i32 }, { i32*, i32 } }, { { i32*, i32 }, { i32*, i32 } }* %x, i32 0, i32 0
     %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %field.0, i32 0, i32 0
     %x.field.field.ld.0 = load i32*, i32** %field.1
@@ -214,7 +214,7 @@
     %.field.field.ld.0 = load i32*, i32** %field.3
     %.ld.1 = load i32, i32* %.field.field.ld.0
     %add.0 = add i32 %.ld.0, %.ld.1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectRepr(matadd, exp2);
   EXPECT_TRUE(isOK && "expr does not have expected contents");
diff --git a/unittests/BackendCore/BackendPointerExprTests.cpp b/unittests/BackendCore/BackendPointerExprTests.cpp
index 75f4596..12a7f2b 100644
--- a/unittests/BackendCore/BackendPointerExprTests.cpp
+++ b/unittests/BackendCore/BackendPointerExprTests.cpp
@@ -71,7 +71,7 @@
     h.addStmt(as);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 10, i64* %y
     store i64* null, i64** %x
     store i64* %y, i64** %x
@@ -80,7 +80,7 @@
     store i64 %.ld.0, i64* %y
     %x.ld.1 = load i64*, i64** %x
     store i64 3, i64* %x.ld.1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -129,7 +129,7 @@
   Bexpression *rvex3 = be->var_expression(bfpv2, loc);
   h.mkAssign(vex3, rvex3);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %cast.0 = bitcast { i64 }* %fdloc1 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i64 }* @const.0 to i8*), i64 8, i1 false)
     store { i64 }* %fdloc1, { i64 }** %fploc1
@@ -140,7 +140,7 @@
     %fploc2.ld.0 = load { i64 (i8*, i32, i32, i64*)* }*, { i64 (i8*, i32, i32, i64*)* }** %fploc2
     %cast.2 = bitcast { i64 (i8*, i32, i32, i64*)* }* %fploc2.ld.0 to { i64 }*
     store { i64 }* %cast.2, { i64 }** %fploc1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -156,9 +156,9 @@
 
   // Manufacture a nil pointer expression
   Bexpression *npe = be->nil_pointer_expression();
-  const char *exp1 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp1, R"RAW_RESULT(
     i64* null
-  )RAW_RESULT";
+  )RAW_RESULT");
   bool isOK = h.expectValue(npe->value(), exp1);
   EXPECT_TRUE(isOK && "Value does not have expected contents");
 
@@ -187,7 +187,7 @@
     h.mkAssign(vel, cmp);
   }
 
-  const char *exp2 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp2, R"RAW_RESULT(
     store i8 0, i8* %b1
     store i8* null, i8** %pb1
     %pb1.ld.0 = load i8*, i8** %pb1
@@ -198,7 +198,7 @@
     %icmp.1 = icmp eq i8* null, %pb1.ld.1
     %zext.1 = zext i1 %icmp.1 to i8
     store i8 %zext.1, i8* %b1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK2 = h.expectBlock(exp2);
   EXPECT_TRUE(isOK2 && "Block does not have expected contents");
@@ -224,12 +224,12 @@
   Bexpression *deref2 = be->indirect_expression(bst, npe2, false, loc);
   h.mkLocal("y", bst, deref2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %deref.ld.0 = load i32, i32* null
     store i32 %deref.ld.0, i32* %x
     %cast.2 = bitcast { i32, i32 }* %y to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 null, i64 8, i1 false)
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -320,7 +320,7 @@
     h.mkAssign(ve0, cmp);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store %CPT.0* null, %CPT.0** %cpv1
     store %CPT.0* null, %CPT.0** %cpv2
     %cast.0 = bitcast %CPT.0** %cpv2 to %CPT.0*
@@ -353,7 +353,7 @@
     %icmp.2 = icmp eq %CPT.0* %cpv1.ld.1, %.ld.1
     %zext.2 = zext i1 %icmp.2 to i8
     store i8 %zext.2, i8* %b3
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -421,7 +421,7 @@
     h.mkAssign(ve0, cmp);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store %CPT.0* null, %CPT.0** %x
     store %CPT.0** null, %CPT.0*** %y
     %cast.0 = bitcast %CPT.0*** %y to %CPT.0*
@@ -434,7 +434,7 @@
     %icmp.0 = icmp eq %CPT.0* %x.ld.0, %.ld.0
     %zext.0 = zext i1 %icmp.0 to i8
     store i8 %zext.0, i8* %b1
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -476,7 +476,7 @@
     h.mkAssign(ve, con32);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %param3.ld.0 = load i64*, i64** %param3.addr
     %ptroff.0 = getelementptr i64, i64* %param3.ld.0, i32 5
     store i64 9, i64* %ptroff.0
@@ -485,7 +485,7 @@
     %.ptroff.ld.0 = load i64, i64* %ptroff.1
     %trunc.0 = trunc i64 %.ptroff.ld.0 to i32
     store i32 %trunc.0, i32* %param1.addr
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -515,10 +515,10 @@
   Bexpression *vexl = be->var_expression(p3, loc);
   h.mkAssign(vexl, ad3);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %x
     store i64* %x, i64** %param3.addr
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -568,11 +568,11 @@
     h.mkAssign(fex, val2);
   }
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i32 0, i32* inttoptr (i64 65793 to i32*)
     store i64 2, i64* getelementptr inbounds ({ i64, i64 }, { i64, i64 }*
       inttoptr (i64 34661 to { i64, i64 }*), i32 0, i32 1)
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -622,11 +622,11 @@
   h.mkLocal("x", pbefty1);
   h.mkLocal("y", pbefty2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)* null, i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)** %x
     store i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)* null, i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)** %y
 
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
diff --git a/unittests/BackendCore/BackendStmtTests.cpp b/unittests/BackendCore/BackendStmtTests.cpp
index f00301b..5f3cd2c 100644
--- a/unittests/BackendCore/BackendStmtTests.cpp
+++ b/unittests/BackendCore/BackendStmtTests.cpp
@@ -79,13 +79,13 @@
   ASSERT_TRUE(as2 != nullptr);
   h.addStmt(as2);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     store i64 0, i64* %loc1
       store i64 123, i64* %loc1
       store i64 0, i64* %loc2
       %loc1.ld.0 = load i64, i64* %loc1
       store i64 %loc1.ld.0, i64* %loc2
-  )RAW_RESULT";
+  )RAW_RESULT");
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 
@@ -115,12 +115,12 @@
   Bexpression *ve1 = be->var_expression(loc1, loc);
   Bstatement *ret = h.mkReturn(ve1);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     %loc1.ld.0 = load i64, i64* %loc1
     ret i64 %loc1.ld.0
-  )RAW_RESULT";
+  )RAW_RESULT");
   std::string reason;
-  bool equal = difftokens(exp, repr(ret), reason);
+  bool equal = difftokens(exp.content, repr(ret), reason);
   EXPECT_EQ("pass", equal ? "pass" : reason);
 
   // error handling
@@ -156,7 +156,7 @@
   Bexpression *addexpr = be->binary_expression(OPERATOR_PLUS, ve2, mkInt64Const(be, 20), loc);
   h.mkReturn(addexpr);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
     entry:
       %param1.addr = alloca i32
@@ -170,7 +170,7 @@
       %x.ld.0 = load i64, i64* %x
       ret i64 %x.ld.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -239,7 +239,7 @@
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %loc1 = alloca i8
@@ -250,7 +250,7 @@
       store i8 0, i8* %loc1
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -309,7 +309,7 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 
   // verify
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
     entry:
       %param1.addr = alloca i32
@@ -339,7 +339,7 @@
       store i64 987, i64* %loc1
       br label %fallthrough.1
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -427,7 +427,7 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 
   // verify
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
     entry:
       %param1.addr = alloca i32
@@ -487,7 +487,7 @@
       store i64 %mul.0, i64* %tmpv.0
       br label %fallthrough.0
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -576,7 +576,7 @@
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
     entry:
       %x = alloca i8
@@ -599,7 +599,7 @@
     cont.0:                                           ; preds = %finish.0
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -689,7 +689,7 @@
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @baz(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
     entry:
       %ehtmp.0 = alloca { i8*, i32 }
@@ -778,7 +778,7 @@
     finret.0:                                         ; preds = %cont.0
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -878,7 +878,7 @@
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define i64 @baz(i8* nest %nest.0, i64 %p0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
     entry:
       %ehtmp.0 = alloca { i8*, i32 }
@@ -963,7 +963,7 @@
       %ret.ld.1 = load i64, i64* %ret
       ret i64 %ret.ld.1
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
diff --git a/unittests/BackendCore/BackendVarTests.cpp b/unittests/BackendCore/BackendVarTests.cpp
index 6fac914..c62b087 100644
--- a/unittests/BackendCore/BackendVarTests.cpp
+++ b/unittests/BackendCore/BackendVarTests.cpp
@@ -299,10 +299,10 @@
                                 desct, loc, scon);
 
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       @desc = internal constant { i64 } { i64 ptrtoint
       (i64 (i8*, i32, i32, i64*)* @foo to i64) }
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = h.expectValue(ims->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -314,9 +314,9 @@
                                 desct, loc, be->zero_expression(desct));
 
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       @abc = weak constant { i64 } zeroinitializer, comdat
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = h.expectValue(ims2->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -384,9 +384,9 @@
   be->implicit_variable_set_init(ims1, "x", bst,
                                  isHidden, isConst, isCommon, con1);
 
-  const char *exp1 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp1, R"RAW_RESULT(
     @v1 = global { i32, i32 } { i32 101, i32 202 }, align 8
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK1 = h.expectValue(ims1->value(), exp1);
   EXPECT_TRUE(isOK1 && "Value does not have expected contents");
@@ -399,9 +399,9 @@
   be->implicit_variable_set_init(ims2, "x", bst,
                                  isHidden, isConst, isCommon, nullptr);
 
-  const char *exp2 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp2, R"RAW_RESULT(
     @v2 = weak constant { i32, i32 } zeroinitializer, comdat, align 8
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK2 = h.expectValue(ims2->value(), exp2);
   EXPECT_TRUE(isOK2 && "Value does not have expected contents");
@@ -533,7 +533,7 @@
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
       entry:
       %x = alloca i32
@@ -554,7 +554,7 @@
       call void @llvm.lifetime.end.p0i8(i64 8, i8* %3)
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -628,30 +628,30 @@
   be->global_variable_set_init(ga2, ear2);
 
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       @emptystruct = global { i8 } zeroinitializer
-    )RAW_RESULT";
+    )RAW_RESULT");
     bool isOK = h.expectValue(gs1->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
   }
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       @emptys2f = global { { i8 }, {} } zeroinitializer
-    )RAW_RESULT";
+    )RAW_RESULT");
     bool isOK = h.expectValue(gs2->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
   }
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       @emptyar = global [1 x { { i8 }, {} }] zeroinitializer
-    )RAW_RESULT";
+    )RAW_RESULT");
     bool isOK = h.expectValue(ga1->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
   }
   {
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       @emptyintar = global [1 x i32] zeroinitializer
-    )RAW_RESULT";
+    )RAW_RESULT");
     bool isOK = h.expectValue(ga2->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
   }
@@ -680,14 +680,14 @@
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     define void @foo(i8* nest %nest.0) #0 {
     entry:
       %localemptys2f = alloca { {}, {} }
       %localemptyintar = alloca [0 x i32]
       ret void
     }
-  )RAW_RESULT";
+  )RAW_RESULT");
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Value does not have expected contents");
 }
diff --git a/unittests/BackendCore/TestUtils.cpp b/unittests/BackendCore/TestUtils.cpp
index 1ac9bb1..f3c6ee4 100644
--- a/unittests/BackendCore/TestUtils.cpp
+++ b/unittests/BackendCore/TestUtils.cpp
@@ -571,8 +571,9 @@
   curBlock_ = be()->block(func_, nullptr, *varlist, loc_, loc_);
 }
 
-bool FcnTestHarness::expectStmt(Bstatement *st, const std::string &expected)
+bool FcnTestHarness::expectStmt(Bstatement *st, const ExpectedDump &ed)
 {
+  const std::string &expected = ed.content;
   std::string reason;
   std::string actual(repr(st));
   bool equal = difftokens(expected, actual, reason);
@@ -581,8 +582,9 @@
   return equal;
 }
 
-bool FcnTestHarness::expectValue(llvm::Value *val, const std::string &expected)
+bool FcnTestHarness::expectValue(llvm::Value *val, const ExpectedDump &ed)
 {
+  const std::string &expected = ed.content;
   std::string reason;
   std::string actual(repr(val));
   bool equal = difftokens(expected, actual, reason);
@@ -591,8 +593,9 @@
   return equal;
 }
 
-bool FcnTestHarness::expectBlock(const std::string &expected)
+bool FcnTestHarness::expectBlock(const ExpectedDump &ed)
 {
+  const std::string &expected = ed.content;
   std::string reason;
   std::string actual(repr(curBlock_));
   bool equal = difftokens(expected, actual, reason);
@@ -619,8 +622,9 @@
   return countinstances(actual, expected);
 }
 
-bool FcnTestHarness::expectRepr(Bnode *node, const std::string &expected)
+bool FcnTestHarness::expectRepr(Bnode *node, const ExpectedDump &ed)
 {
+  const std::string &expected = ed.content;
   std::string reason;
   std::string actual(repr(node));
   bool equal = difftokens(expected, actual, reason);
diff --git a/unittests/BackendCore/TestUtils.h b/unittests/BackendCore/TestUtils.h
index 313af8e..b7ccc1d 100644
--- a/unittests/BackendCore/TestUtils.h
+++ b/unittests/BackendCore/TestUtils.h
@@ -29,8 +29,6 @@
 #include <stdarg.h>
 #include "gtest/gtest.h"
 
-#define RAW_RESULT(x) #x
-
 namespace goBackendUnitTests {
 
 // All supported calling conventions
@@ -226,19 +224,19 @@
 
   // Verify that block contains specified contents. Return false
   // and emit diagnostics if not.
-  bool expectBlock(const std::string &expected);
+  bool expectBlock(const ExpectedDump &expected);
 
   // Verify that stmt contains specified contents. Return false
   // and emit diagnostics if not.
-  bool expectStmt(Bstatement *st, const std::string &expected);
+  bool expectStmt(Bstatement *st, const ExpectedDump &expected);
 
   // Verify that value contains specified contents. Return false
   // and emit diagnostics if not.
-  bool expectValue(llvm::Value *val, const std::string &expected);
+  bool expectValue(llvm::Value *val, const ExpectedDump &expected);
 
   // Verify that repr() output contains specified contents. Return false
   // and emit diagnostics if not.
-  bool expectRepr(Bnode *node, const std::string &expected);
+  bool expectRepr(Bnode *node, const ExpectedDump &expected);
 
   // Verify that a dump of the module contains the specified token sequence
   // somewhere within it. To be used only if the various methods above
@@ -248,7 +246,7 @@
 
   // Return a count of the number of times we see the specified
   // token sequence within the module dump.
-  unsigned countInstancesInModuleDump(const std::string &expected);
+  unsigned countInstancesInModuleDump(const std::string &token);
 
   // Skip the checking at finish time for orphan CFG blocks.
   void allowOrphans() { findOrphanBBs_ = false; }
diff --git a/unittests/DriverUtils/DriverUtilsTests.cpp b/unittests/DriverUtils/DriverUtilsTests.cpp
index d764207..c10ef4c 100644
--- a/unittests/DriverUtils/DriverUtilsTests.cpp
+++ b/unittests/DriverUtils/DriverUtilsTests.cpp
@@ -217,8 +217,9 @@
 }
 
 template<class T>
-bool expectToString(T &cand, const std::string &expected)
+bool expectToString(T &cand, const ExpectedDump &ed)
 {
+  const std::string &expected = ed.content;
   std::string reason;
   std::string actual(cand.toString());
   bool equal = difftokens(expected, actual, reason);
@@ -233,9 +234,9 @@
     std::vector<std::string> t = { "/" };
     InspectFakeFS fake(t);
 
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
        dir /:
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = expectToString(fake, exp);
     EXPECT_TRUE(isOK);
@@ -245,10 +246,10 @@
     std::vector<std::string> t = { "/foo", "/bar", "/bar/baz" };
     InspectFakeFS fake(t);
 
-    const char *exp = R"RAW_RESULT(
+    DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
       dir /:  *bar foo
       dir /bar:  baz
-    )RAW_RESULT";
+    )RAW_RESULT");
 
     bool isOK = expectToString(fake, exp);
     EXPECT_TRUE(isOK);
@@ -283,23 +284,23 @@
 TEST(DriverUtilsTests, GCCInstallationDetectorBasicAmd64) {
 
   // Here we have two installations, version 6 and version 7.
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /mumble
       /usr/lib/gcc/x86_64-linux-gnu/6/32/crtbegin.o
       /usr/lib/gcc/x86_64-linux-gnu/blah
       /usr/lib/gcc/x86_64-linux-gnu/6/crtbegin.o
       /usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o
-    )RAW_RESULT";
+    )RAW_INPUT";
 
   // Case 1: no sysroot, looking for 64-bit compiler.
   DetectorHarness harness1(install, "x86_64-linux-gnu", "");
-  const char *exp64 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp64, R"RAW_RESULT(
       version: 7
       foundTriple: x86_64-linux-gnu
       libPath: /usr/lib/gcc/x86_64-linux-gnu/7
       parentLibPath: /usr/lib/gcc/x86_64-linux-gnu/7/../..
       installPath: /usr/lib/gcc/x86_64-linux-gnu/7
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK1 = expectToString(harness1.detector(), exp64);
   EXPECT_TRUE(isOK1);
 
@@ -307,13 +308,13 @@
   // compiler. Here we pick up version 6 since version 7 in this case
   // has no 32-bit libraries.
   DetectorHarness harness2(install, "i386-linux-gnu", "");
-  const char *exp32 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp32, R"RAW_RESULT(
       version: 6
       foundTriple: x86_64-linux-gnu
       libPath: /usr/lib/gcc/x86_64-linux-gnu/6/32
       parentLibPath: /usr/lib/gcc/x86_64-linux-gnu/6/../../..
       installPath: /usr/lib/gcc/x86_64-linux-gnu/6
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK2 = expectToString(harness2.detector(), exp32);
   EXPECT_TRUE(isOK2);
 }
@@ -321,68 +322,68 @@
 TEST(DriverUtilsTests, GCCInstallationDetectorBasicARM64) {
 
   // Here we have two installations, version 6 and version 7.
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /mumble
       /usr/lib/gcc/aarch64-linux-gnu/blah
       /usr/lib/gcc/aarch64-linux-gnu/6/crtbegin.o
       /usr/lib/gcc/aarch64-linux-gnu/7/crtbegin.o
-    )RAW_RESULT";
+    )RAW_INPUT";
 
   // Case 1: no sysroot, looking for 64-bit compiler.
   // Gcc doesn't support multilib on Arm64, so don't need
   // to test that case.
   DetectorHarness harness1(install, "aarch64-linux-gnu", "");
-  const char *exp64 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp64, R"RAW_RESULT(
       version: 7
       foundTriple: aarch64-linux-gnu
       libPath: /usr/lib/gcc/aarch64-linux-gnu/7
       parentLibPath: /usr/lib/gcc/aarch64-linux-gnu/7/../..
       installPath: /usr/lib/gcc/aarch64-linux-gnu/7
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK1 = expectToString(harness1.detector(), exp64);
   EXPECT_TRUE(isOK1);
 }
 
 TEST(DriverUtilsTests, GCCInstallationDetectorSysRootAmd64) {
 
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /mumble
       /usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o
       /mysysroot/usr/lib/gcc/x86_64-linux-gnu/6.2.3/crtbegin.o
-    )RAW_RESULT";
+    )RAW_INPUT";
 
   // We have GCC 7 installed on the host, but GCC 6 in sysroot,
   // which in this case is what we want.
   DetectorHarness harness1(install, "x86_64-linux-gnu", "/mysysroot");
-  const char *exp64 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp64, R"RAW_RESULT(
       version: 6.2.3
       foundTriple: x86_64-linux-gnu
       libPath: /mysysroot/usr/lib/gcc/x86_64-linux-gnu/6.2.3
       parentLibPath: /mysysroot/usr/lib/gcc/x86_64-linux-gnu/6.2.3/../..
       installPath: /mysysroot/usr/lib/gcc/x86_64-linux-gnu/6.2.3
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK1 = expectToString(harness1.detector(), exp64);
   EXPECT_TRUE(isOK1);
 }
 
 TEST(DriverUtilsTests, GCCInstallationDetectorSysRootARM64) {
 
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /mumble
       /usr/lib/gcc/aarch64-linux-gnu/7/crtbegin.o
       /mysysroot/usr/lib/gcc/aarch64-linux-gnu/6.2.3/crtbegin.o
-    )RAW_RESULT";
+    )RAW_INPUT";
 
   // We have GCC 7 installed on the host, but GCC 6 in sysroot,
   // which in this case is what we want.
   DetectorHarness harness1(install, "aarch64-linux-gnu", "/mysysroot");
-  const char *exp64 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp64, R"RAW_RESULT(
       version: 6.2.3
       foundTriple: aarch64-linux-gnu
       libPath: /mysysroot/usr/lib/gcc/aarch64-linux-gnu/6.2.3
       parentLibPath: /mysysroot/usr/lib/gcc/aarch64-linux-gnu/6.2.3/../..
       installPath: /mysysroot/usr/lib/gcc/aarch64-linux-gnu/6.2.3
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK1 = expectToString(harness1.detector(), exp64);
   EXPECT_TRUE(isOK1);
 }
@@ -393,35 +394,35 @@
   // of target triples and how GCC is installed. This test checks
   // to make sure we can accommodate such differences.
 
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /mumble
       /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
       /usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o
-    )RAW_RESULT";
+    )RAW_INPUT";
 
   // Case 1: install is x86_64-linux-gnu, but we are looking for
   // x86_64-unknown-linux-gnu
   DetectorHarness harness1(install, "x86_64-unknown-linux-gnu", "");
-  const char *exp1 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp1, R"RAW_RESULT(
       version: 7
       foundTriple: x86_64-linux-gnu
       libPath: /usr/lib/gcc/x86_64-linux-gnu/7
       parentLibPath: /usr/lib/gcc/x86_64-linux-gnu/7/../..
       installPath: /usr/lib/gcc/x86_64-linux-gnu/7
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK1 = expectToString(harness1.detector(), exp1);
   EXPECT_TRUE(isOK1);
 
   // Case 2: install is x86_64-linux-gnu, but we are looking for
   // x86_64-redhat-linux-gnu
   DetectorHarness harness2(install, "x86_64-redhat-linux-gnu", "");
-  const char *exp2 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp2, R"RAW_RESULT(
       version: 7
       foundTriple: x86_64-linux-gnu
       libPath: /usr/lib/gcc/x86_64-linux-gnu/7
       parentLibPath: /usr/lib/gcc/x86_64-linux-gnu/7/../..
       installPath: /usr/lib/gcc/x86_64-linux-gnu/7
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK2 = expectToString(harness2.detector(), exp2);
   EXPECT_TRUE(isOK2);
 }
@@ -432,66 +433,66 @@
   // of target triples and how GCC is installed. This test checks
   // to make sure we can accommodate such differences.
 
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /mumble
       /usr/lib/gcc/aarch64-linux-gnu/5/crtbegin.o
       /usr/lib/gcc/aarch64-linux-gnu/7/crtbegin.o
-    )RAW_RESULT";
+    )RAW_INPUT";
 
   // Case 1: install is aarch64-linux-gnu, but we are looking for
   // aarch64-unknown-linux-gnu
   DetectorHarness harness1(install, "aarch64-unknown-linux-gnu", "");
-  const char *exp1 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp1, R"RAW_RESULT(
       version: 7
       foundTriple: aarch64-linux-gnu
       libPath: /usr/lib/gcc/aarch64-linux-gnu/7
       parentLibPath: /usr/lib/gcc/aarch64-linux-gnu/7/../..
       installPath: /usr/lib/gcc/aarch64-linux-gnu/7
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK1 = expectToString(harness1.detector(), exp1);
   EXPECT_TRUE(isOK1);
 
   // Case 2: install is aarch64-linux-gnu, but we are looking for
   // aarch64-redhat-linux-gnu
   DetectorHarness harness2(install, "aarch64-redhat-linux-gnu", "");
-  const char *exp2 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp2, R"RAW_RESULT(
       version: 7
       foundTriple: aarch64-linux-gnu
       libPath: /usr/lib/gcc/aarch64-linux-gnu/7
       parentLibPath: /usr/lib/gcc/aarch64-linux-gnu/7/../..
       installPath: /usr/lib/gcc/aarch64-linux-gnu/7
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK2 = expectToString(harness2.detector(), exp2);
   EXPECT_TRUE(isOK2);
 }
 
 TEST(DriverUtilsTests, GCCInstallationDetectorBiarchAliasesAmd64) {
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /mumble
       /usr/lib/gcc/x86_64-redhat-linux/6/lib32/crtbegin.o
       /usr/lib/gcc/x86_64-redhat-linux/6/crtbegin.o
       /usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o
-    )RAW_RESULT";
+    )RAW_INPUT";
 
   // On 64-bit machine looking for 32-bit libraries, but here the
   // distro has decided to install 32-bit libraries in /lib32, not /32.
   DetectorHarness harness(install, "i386-linux-gnu", "");
-  const char *exp32 = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp32, R"RAW_RESULT(
       version: 6
       foundTriple: x86_64-redhat-linux
       libPath: /usr/lib/gcc/x86_64-redhat-linux/6/lib32
       parentLibPath: /usr/lib/gcc/x86_64-redhat-linux/6/../../..
       installPath: /usr/lib/gcc/x86_64-redhat-linux/6
-    )RAW_RESULT";
+    )RAW_RESULT");
   bool isOK = expectToString(harness.detector(), exp32);
   EXPECT_TRUE(isOK);
 }
 
 TEST(DriverUtilsTests, DistroDetector) {
-  const char *install = R"RAW_RESULT(
+  const char *install = R"RAW_INPUT(
       /etc/lsb-release
       /etc/motd
-    )RAW_RESULT";
+    )RAW_INPUT";
   InspectFakeFS ffs(install);
 
   llvm::Triple target1("aarch64-none-linux-gnu");
diff --git a/unittests/GoDumpSpec/ParserTests.cpp b/unittests/GoDumpSpec/ParserTests.cpp
index 30b3204..dd3a24a 100644
--- a/unittests/GoDumpSpec/ParserTests.cpp
+++ b/unittests/GoDumpSpec/ParserTests.cpp
@@ -52,8 +52,9 @@
   return postProcessAndEmit(parser);
 }
 
-bool expectEqualTokens(const std::string &actual, const std::string &expected)
+bool expectEqualTokens(const std::string &actual, const ExpectedDump &ed)
 {
+  const std::string &expected = ed.content;
   std::string reason;
   bool equal = difftokens(expected, actual, reason);
   if (! equal)
@@ -63,106 +64,106 @@
 
 TEST(GoDumpSpecParserTests, BasicParser) {
 
-  const char *input = R"RAW_RESULT(
+  const char *input = R"RAW_INPUT(
     #define FOO BAR
     #define BLIX
     #define BAR 10
-    )RAW_RESULT";
+    )RAW_INPUT";
   EXPECT_TRUE(true);
 
   std::string result = processMacros(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     const _BAR = 10
     const _FOO = _BAR
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   EXPECT_TRUE(expectEqualTokens(result, exp));
 }
 
 TEST(GoDumpSpecParserTests, MacroDefCycle) {
 
-  const char *input = R"RAW_RESULT(
+  const char *input = R"RAW_INPUT(
     #define FOO BAR
     #define BLIX "hello world"
     #define BAR FOO
-    )RAW_RESULT";
+    )RAW_INPUT";
   EXPECT_TRUE(true);
 
   std::string result = processMacros(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     const _BLIX = "hello world"
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   EXPECT_TRUE(expectEqualTokens(result, exp));
 }
 
 TEST(GoDumpSpecParserTests, FunctionMacros) {
 
-  const char *input = R"RAW_RESULT(
+  const char *input = R"RAW_INPUT(
     #define ISFUNC() 99
     #define FOO(x,y) x+y
     #define BLIX (7.8e-2*9.01e-8+.00001)<<4u
     #define GLIX() FOO(3,4)
-    )RAW_RESULT";
+    )RAW_INPUT";
   EXPECT_TRUE(true);
 
   std::string result = processMacros(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     const _BLIX = (7.8e-2*9.01e-8+.00001)<<4
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   EXPECT_TRUE(expectEqualTokens(result, exp));
 }
 
 TEST(GoDumpSpecParserTests, BadStringLiterals) {
 
-  const char *input = R"RAW_RESULT(
+  const char *input = R"RAW_INPUT(
     #define BAD1 '\0'
     #define BAD2 "ok up until this: \0 "
     #define BAD3 '\xa'
     #define GOOD ""
-    )RAW_RESULT";
+    )RAW_INPUT";
   EXPECT_TRUE(true);
 
   std::string result = processMacros(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     const _GOOD = ""
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   EXPECT_TRUE(expectEqualTokens(result, exp));
 }
 
 TEST(GoDumpSpecParserTests, EmptyMacros) {
 
-  const char *input = R"RAW_RESULT(
+  const char *input = R"RAW_INPUT(
     #define EMPTY1
     #define EMPTY2 EMPTY1
     #define EMPTY3 EMPTY2 EMPTY1
     #define BAD (1+2)<<
     #define GOOD (1+2)<<9
-    )RAW_RESULT";
+    )RAW_INPUT";
   EXPECT_TRUE(true);
 
   std::string result = processMacros(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     const _GOOD = (1+2)<<9
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   EXPECT_TRUE(expectEqualTokens(result, exp));
 }
 
 TEST(GoDumpSpecParserTests, MacrosAndEnums) {
 
-  const char *input = R"RAW_RESULT(
+  const char *input = R"RAW_INPUT(
     #define E1 10
     #define E2 (EX + E1)
     #define EX "ignored"
-    )RAW_RESULT";
+    )RAW_INPUT";
   EXPECT_TRUE(true);
 
   MacroParser parser;
@@ -175,11 +176,11 @@
 
   std::string result = postProcessAndEmit(parser);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     const _E1 = 10
     const _E2 = (_EX + _E1)
     const _EX = 9
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   EXPECT_TRUE(expectEqualTokens(result, exp));
 }
diff --git a/unittests/GoDumpSpec/TokenizerTests.cpp b/unittests/GoDumpSpec/TokenizerTests.cpp
index 0125532..f376b52 100644
--- a/unittests/GoDumpSpec/TokenizerTests.cpp
+++ b/unittests/GoDumpSpec/TokenizerTests.cpp
@@ -50,8 +50,9 @@
   return ss.str();
 }
 
-bool expectTokens(MacroTokenizer &t, const std::string &expected)
+bool expectTokens(MacroTokenizer &t, const ExpectedDump &ed)
 {
+  const std::string &expected = ed.content;
   std::string reason;
   std::string actual(dump(t));
   bool equal = difftokens(expected, actual, reason);
@@ -64,13 +65,13 @@
   std::string input("1 2l .3f");
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     NCONST '1'
     SPACE ' '
     NCONST '2'
     SPACE ' '
     NCONST '.3'
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
@@ -80,13 +81,13 @@
   std::string input("\"s1\"'\\t''\\n''\\''\"internal \\\" here\"");
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     SCONST '"s1"'
     SCONST ''\t''
     SCONST ''\n''
     SCONST ''\'''
     SCONST '"internal \" here"'
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
@@ -96,7 +97,7 @@
   std::string input(std::string("2.898e-1 0xdeadbeef9 101ull"));
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     NCONST '2.898e'
     ADDSUB '-'
     NCONST '1'
@@ -104,7 +105,7 @@
     NCONST '0xdeadbeef9'
     SPACE ' '
     NCONST '101'
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
@@ -114,7 +115,7 @@
   std::string input(std::string("1(2/3)%3*_A_==1<<9>Q"));
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     NCONST '1'
     OPEN_PAREN '('
     NCONST '2'
@@ -131,7 +132,7 @@
     NCONST '9'
     BINOP '>'
     IDENTIFIER 'Q'
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
@@ -140,7 +141,7 @@
   std::string input(std::string("1|2&A^z!/!=~F"));
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     NCONST '1'
     BINOP '|'
     NCONST '2'
@@ -153,7 +154,7 @@
     BINOP '!='
     UNOP '^'
     IDENTIFIER 'F'
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
@@ -163,10 +164,10 @@
   std::string input(std::string("A=1"));
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     IDENTIFIER 'A'
     ERROR '='
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
@@ -176,9 +177,9 @@
   std::string input(std::string("'abc"));
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     ERROR ''
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
@@ -188,9 +189,9 @@
   std::string input(std::string("'\0'"));
   MacroTokenizer t(input);
 
-  const char *exp = R"RAW_RESULT(
+  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
     ERROR ''
-    )RAW_RESULT";
+    )RAW_RESULT");
 
   bool isOK = expectTokens(t, exp);
   EXPECT_TRUE(isOK);
diff --git a/unittests/TestUtils/DiffUtils.h b/unittests/TestUtils/DiffUtils.h
index 8b5e2cc..870822c 100644
--- a/unittests/TestUtils/DiffUtils.h
+++ b/unittests/TestUtils/DiffUtils.h
@@ -13,6 +13,18 @@
 #include <vector>
 
 #define RAW_RESULT(x) #x
+#define RAW_INPUT(x) #x
+
+struct ExpectedDump {
+  ExpectedDump(const char *c, const char *f, int l) :
+      content(c), file(f), line(l) { }
+  const char *content;
+  const char *file;
+  int line;
+};
+
+#define DECLARE_EXPECTED_OUTPUT(vname, x) \
+  ExpectedDump vname(x, __FILE__, __LINE__)
 
 namespace goBackendUnitTests {