Add a synthesized StackElement containing the version of R8

This will always give us the version when we fail.

The output will look like this:
java.lang.NullPointerException
        at com.android.tools.r8.Version.R8AddVersionToStack(Version_1.6.32.java:0)
        at com.android.tools.r8.shaking.Enqueuer.<init>(Enqueuer.java:331)
        at com.android.tools.r8.shaking.EnqueuerFactory.createForInitialTreeShaking(EnqueuerFactory.java:16)


Change-Id: I7b41e59c80e26b66b11c67f50cc597832a397a73
diff --git a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
index 16bde83..d12c2a4 100644
--- a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
@@ -7,9 +7,11 @@
 import com.android.tools.r8.DiagnosticsHandler;
 import com.android.tools.r8.ResourceException;
 import com.android.tools.r8.StringConsumer;
+import com.android.tools.r8.Version;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
+import com.google.common.collect.ObjectArrays;
 import java.io.IOException;
 import java.nio.file.FileSystemException;
 import java.nio.file.Paths;
@@ -71,6 +73,13 @@
         throw reporter.fatalError(new ExceptionDiagnostic(e, e.getOrigin()));
       } catch (AssertionError e) {
         throw reporter.fatalError(new ExceptionDiagnostic(e, Origin.unknown()));
+      } catch (Exception e) {
+        String filename = "Version_" + Version.LABEL + ".java";
+        StackTraceElement versionElement = new StackTraceElement(
+            Version.class.getSimpleName(), "fakeStackEntry", filename, 0);
+        StackTraceElement[] withVersion = ObjectArrays.concat(versionElement, e.getStackTrace());
+        e.setStackTrace(withVersion);
+        throw e;
       }
       reporter.failIfPendingErrors();
     } catch (AbortException e) {