diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 6e6a120..98a6d86 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.2.25";
+  public static final String LABEL = "1.2.26";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index e3ec746..01fff01 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -161,7 +161,7 @@
   }
 
   private void parseError(DexItem item, Origin origin, GenericSignatureFormatError e) {
-    StringBuilder message = new StringBuilder("Invalid class signature for ");
+    StringBuilder message = new StringBuilder("Invalid signature for ");
     if (item instanceof DexClass) {
       message.append("class ");
       message.append(((DexClass) item).getType().toSourceString());
@@ -183,12 +183,14 @@
       clazz.annotations = rewriteGenericSignatures(clazz.annotations,
           genericSignatureParser::parseClassSignature,
           e -> parseError(clazz, clazz.getOrigin(), e));
-      clazz.forEachField(field -> rewriteGenericSignatures(
-          field.annotations, genericSignatureParser::parseFieldSignature,
-          e -> parseError(field, clazz.getOrigin(), e)));
-      clazz.forEachMethod(method -> rewriteGenericSignatures(
-          method.annotations, genericSignatureParser::parseMethodSignature,
-          e -> parseError(method, clazz.getOrigin(), e)));
+      clazz.forEachField(field ->
+          field.annotations = rewriteGenericSignatures(
+              field.annotations, genericSignatureParser::parseFieldSignature,
+              e -> parseError(field, clazz.getOrigin(), e)));
+      clazz.forEachMethod(method ->
+        method.annotations = rewriteGenericSignatures(
+            method.annotations, genericSignatureParser::parseMethodSignature,
+            e -> parseError(method, clazz.getOrigin(), e)));
     }
   }
 
@@ -506,11 +508,18 @@
       String enclosingRenamedBinaryName =
           getClassBinaryNameFromDescriptor(
               renaming.getOrDefault(enclosingType, enclosingType.descriptor).toString());
-      String renamed =
-          getClassBinaryNameFromDescriptor(
-              renaming.getOrDefault(type, type.descriptor).toString());
-      String outName = renamed.substring(enclosingRenamedBinaryName.length() + 1);
-      renamedSignature.append(outName);
+      DexString renamedDescriptor = renaming.get(type);
+      if (renamedDescriptor != null) {
+        // Pick the renamed inner class from the fully renamed binary name.
+        String fullRenamedBinaryName =
+            getClassBinaryNameFromDescriptor(renamedDescriptor.toString());
+        renamedSignature.append(
+            fullRenamedBinaryName.substring(enclosingRenamedBinaryName.length() + 1));
+      } else {
+        // Did not find the class - keep the inner class name as is.
+        // TODO(110085899): Warn about missing classes in signatures?
+        renamedSignature.append(name);
+      }
       return type;
     }
 
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
index 5b549a3..c1f6a7d 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
@@ -84,7 +84,7 @@
       throw e;
     } catch (Throwable t) {
       Error e = new GenericSignatureFormatError(
-          "Unknown error parsing generic signature: " + t.getMessage());
+          "Unknown error parsing class signature: " + t.getMessage());
       e.addSuppressed(t);
       throw e;
     }
@@ -100,7 +100,7 @@
       throw e;
     } catch (Throwable t) {
       Error e = new GenericSignatureFormatError(
-          "Unknown error parsing generic signature: " + t.getMessage());
+          "Unknown error parsing method signature: " + t.getMessage());
       e.addSuppressed(t);
       throw e;
     }
@@ -112,14 +112,14 @@
       setInput(signature);
       parseFieldTypeSignature();
       actions.stop();
-  } catch (GenericSignatureFormatError e) {
-    throw e;
-  } catch (Throwable t) {
-    Error e = new GenericSignatureFormatError(
-        "Unknown error parsing generic signature: " + t.getMessage());
-    e.addSuppressed(t);
-    throw e;
-  }
+    } catch (GenericSignatureFormatError e) {
+      throw e;
+    } catch (Throwable t) {
+      Error e = new GenericSignatureFormatError(
+          "Unknown error parsing field signature: " + t.getMessage());
+      e.addSuppressed(t);
+      throw e;
+    }
   }
 
   private void setInput(String input) {
diff --git a/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java b/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
index 1d1604b..957bc1d 100644
--- a/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
+++ b/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
@@ -350,7 +350,8 @@
     forMethodSignatures(this::parseMethodSignature);
   }
 
-  private void failingParseAction(Consumer<GenericSignatureParser<String>> parse)
+  private void failingParseAction(
+      Consumer<GenericSignatureParser<String>> parse, String errorMessageType)
       throws Exception {
     class ThrowsInParserActionBase<E extends Error> extends ReGenerateGenericSignatureRewriter {
       protected Supplier<? extends E> exceptionSupplier;
@@ -452,7 +453,8 @@
           assertEquals("ERROR", e.getMessage());
         } else {
           plainErrorCount++;
-          assertEquals("Unknown error parsing generic signature: ERROR", e.getMessage());
+          assertEquals("Unknown error parsing "
+              + errorMessageType + " signature: ERROR", e.getMessage());
         }
       }
     }
@@ -463,10 +465,10 @@
   public void failingParseAction() throws Exception {
     // These signatures hits all action callbacks.
     failingParseAction(parser -> parser.parseClassSignature(
-        "<U:Ljava/lang/Object;>LOuter<TT;>.Inner;Ljava/util/List<TU;>;"));
+        "<U:Ljava/lang/Object;>LOuter<TT;>.Inner;Ljava/util/List<TU;>;"), "class");
     failingParseAction(
-        parser -> parser.parseFieldSignature("LOuter$InnerInterface<TU;>.Inner;"));
+        parser -> parser.parseFieldSignature("LOuter$InnerInterface<TU;>.Inner;"), "field");
     failingParseAction(
-        parser -> parser.parseMethodSignature("(LOuter$InnerInterface<TU;>.Inner;)V"));
+        parser -> parser.parseMethodSignature("(LOuter$InnerInterface<TU;>.Inner;)V"), "method");
   }
 }
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
index 68cd36f..b9ff7ea 100644
--- a/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
@@ -424,7 +424,7 @@
 
   @Test
   public void classSignatureOuter_classNotFound() throws Exception {
-    String signature = "<T:LNotFound;>LNotFound;";
+    String signature = "<T:LNotFound;>LAlsoNotFound;";
     testSingleClass("Outer", signature, this::noWarnings, inspector -> {
       assertThat(inspector.clazz("NotFound"), not(isPresent()));
       ClassSubject outer = inspector.clazz("Outer");
@@ -433,11 +433,51 @@
   }
 
   @Test
+  public void classSignatureExtendsInner_innerClassNotFound() throws Exception {
+    String signature = "LOuter<TT;>.NotFound;";
+    testSingleClass("Outer$ExtendsInner", signature, this::noWarnings, inspector -> {
+      assertThat(inspector.clazz("NotFound"), not(isPresent()));
+      ClassSubject outer = inspector.clazz("Outer$ExtendsInner");
+      assertEquals(signature, outer.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void classSignatureExtendsInner_outerAndInnerClassNotFound() throws Exception {
+    String signature = "LNotFound<TT;>.AlsoNotFound;";
+    testSingleClass("Outer$ExtendsInner", signature, this::noWarnings, inspector -> {
+      assertThat(inspector.clazz("NotFound"), not(isPresent()));
+      ClassSubject outer = inspector.clazz("Outer$ExtendsInner");
+      assertEquals(signature, outer.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void classSignatureExtendsInner_nestedInnerClassNotFound() throws Exception {
+    String signature = "LOuter<TT;>.Inner.NotFound;";
+    testSingleClass("Outer$ExtendsInner", signature, this::noWarnings, inspector -> {
+      assertThat(inspector.clazz("NotFound"), not(isPresent()));
+      ClassSubject outer = inspector.clazz("Outer$ExtendsInner");
+      assertEquals(signature, outer.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void classSignatureExtendsInner_multipleMestedInnerClassesNotFound() throws Exception {
+    String signature = "LOuter<TT;>.NotFound.AlsoNotFound;";
+    testSingleClass("Outer$ExtendsInner", signature, this::noWarnings, inspector -> {
+      assertThat(inspector.clazz("NotFound"), not(isPresent()));
+      ClassSubject outer = inspector.clazz("Outer$ExtendsInner");
+      assertEquals(signature, outer.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
   public void classSignatureOuter_invalid() throws Exception {
     testSingleClass("Outer", "X", diagnostics -> {
       assertEquals(1, diagnostics.warnings.size());
       DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
-          "Invalid class signature for class Outer", "Expected L at position 1");
+          "Invalid signature for class Outer", "Expected L at position 1");
     }, inspector -> noSignatureAttribute(inspector.clazz("Outer")));
   }
 
@@ -446,7 +486,7 @@
     testSingleClass("Outer", "<L", diagnostics -> {
       assertEquals(1, diagnostics.warnings.size());
       DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
-          "Invalid class signature for class Outer", "Unexpected end of signature at position 3");
+          "Invalid signature for class Outer", "Unexpected end of signature at position 3");
     }, inspector -> noSignatureAttribute(inspector.clazz("Outer")));
   }
 
@@ -455,7 +495,7 @@
     testSingleClass("Outer$ExtendsInner", "X", diagnostics -> {
       assertEquals(1, diagnostics.warnings.size());
       DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
-          "Invalid class signature for class Outer$ExtendsInner", "Expected L at position 1");
+          "Invalid signature for class Outer$ExtendsInner", "Expected L at position 1");
     }, inspector -> noSignatureAttribute(inspector.clazz("Outer$ExtendsInner")));
   }
 
@@ -464,7 +504,7 @@
     testSingleClass("Outer$Inner$ExtendsInnerInner", "X", diagnostics -> {
       assertEquals(1, diagnostics.warnings.size());
       DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
-          "Invalid class signature for class Outer$Inner$ExtendsInnerInner",
+          "Invalid signature for class Outer$Inner$ExtendsInnerInner",
           "Expected L at position 1");
     }, inspector -> noSignatureAttribute(inspector.clazz("Outer$Inner$ExtendsInnerInner")));
   }
@@ -488,7 +528,7 @@
     testSingleClass("Outer$ExtendsInner", signature, diagnostics -> {
       assertEquals(1, diagnostics.warnings.size());
       DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
-          "Invalid class signature for class Outer$ExtendsInner", "Expected ; at position 16");
+          "Invalid signature for class Outer$ExtendsInner", "Expected ; at position 16");
     }, inspector -> {
       noSignatureAttribute(inspector.clazz("Outer$ExtendsInner"));
     });
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
new file mode 100644
index 0000000..e48ce56
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
@@ -0,0 +1,289 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming;
+
+import static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
+import static com.android.tools.r8.utils.DexInspectorMatchers.isRenamed;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_SUPER;
+import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
+import static org.objectweb.asm.Opcodes.ALOAD;
+import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static org.objectweb.asm.Opcodes.PUTFIELD;
+import static org.objectweb.asm.Opcodes.RETURN;
+import static org.objectweb.asm.Opcodes.V1_8;
+
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.DiagnosticsChecker;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.StringConsumer;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.graph.invokesuper.Consumer;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
+import com.android.tools.r8.utils.DexInspector.FieldSubject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import org.junit.Test;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+
+public class MinifierFieldSignatureTest extends TestBase {
+  /*
+
+  class Fields<X extends String> {
+    class Inner {
+    }
+    public X anX;
+    public X[] anArrayOfX;
+    public Fields<X> aFieldsOfX;
+    public Fields<X>.Inner aFieldsOfXInner;
+  }
+
+  */
+
+  private String anXSignature = "TX;";
+  private String anArrayOfXSignature = "[TX;";
+  private String aFieldsOfXSignature = "LFields<TX;>;";
+  private String aFieldsOfXInnerSignature = "LFields<TX;>.Inner;";
+
+  public byte[] dumpFields(Map<String, String> signatures) throws Exception {
+
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+    String signature;
+
+    cw.visit(V1_8, ACC_SUPER, "Fields", "<X:Ljava/lang/String;>Ljava/lang/Object;",
+        "java/lang/Object", null);
+
+    cw.visitInnerClass("Fields$Inner", "Fields", "Inner", 0);
+
+    {
+      signature = signatures.get("anX");
+      signature = signature == null ? anXSignature : signature;
+      fv = cw.visitField(ACC_PUBLIC, "anX", "Ljava/lang/String;", signature, null);
+      fv.visitEnd();
+    }
+    {
+      signature = signatures.get("anArrayOfX");
+      signature = signature == null ? anArrayOfXSignature : signature;
+      fv = cw.visitField(
+          ACC_PUBLIC, "anArrayOfX", "[Ljava/lang/String;", signature, null);
+      fv.visitEnd();
+    }
+    {
+      signature = signatures.get("aFieldsOfX");
+      signature = signature == null ? aFieldsOfXSignature : signature;
+      fv = cw.visitField(ACC_PUBLIC, "aFieldsOfX", "LFields;", signature, null);
+      fv.visitEnd();
+    }
+    {
+      signature = signatures.get("aFieldsOfXInner");
+      signature = signature == null ? aFieldsOfXInnerSignature : signature;
+      fv = cw.visitField(
+          ACC_PUBLIC, "aFieldsOfXInner", "LFields$Inner;", signature, null);
+      fv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(0, "<init>", "()V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(1, 1);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  public byte[] dumpInner() throws Exception {
+
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+
+    cw.visit(V1_8, ACC_SUPER, "Fields$Inner", null, "java/lang/Object", null);
+
+    cw.visitInnerClass("Fields$Inner", "Fields", "Inner", 0);
+
+    {
+      fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "LFields;", null, null);
+      fv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(0, "<init>", "(LFields;)V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitFieldInsn(PUTFIELD, "Fields$Inner", "this$0", "LFields;");
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(2, 2);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private FieldSubject lookupAnX(DexInspector inspector) {
+    ClassSubject clazz = inspector.clazz("Fields");
+    return clazz.field("java.lang.String", "anX");
+  }
+
+  private FieldSubject lookupAnArrayOfX(DexInspector inspector) {
+    ClassSubject clazz = inspector.clazz("Fields");
+    return clazz.field("java.lang.String[]", "anArrayOfX");
+  }
+
+  private FieldSubject lookupAFieldsOfX(DexInspector inspector) {
+    ClassSubject clazz = inspector.clazz("Fields");
+    return clazz.field("Fields", "aFieldsOfX");
+  }
+
+  public void runTest(
+      ImmutableMap<String, String> signatures,
+      Consumer<DiagnosticsChecker> diagnostics,
+      Consumer<DexInspector> inspect)
+      throws Exception {
+    DiagnosticsChecker checker = new DiagnosticsChecker();
+    DexInspector inspector = new DexInspector(
+      ToolHelper.runR8(R8Command.builder(checker)
+          .addClassProgramData(dumpFields(signatures), Origin.unknown())
+          .addClassProgramData(dumpInner(), Origin.unknown())
+          .addProguardConfiguration(ImmutableList.of(
+              "-keepattributes InnerClasses,EnclosingMethod,Signature",
+              "-keep,allowobfuscation class ** { *; }"
+          ), Origin.unknown())
+          .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+          .setProguardMapConsumer(StringConsumer.emptyConsumer())
+          .build()));
+    // All classes are kept, and renamed.
+    ClassSubject clazz = inspector.clazz("Fields");
+    assertThat(clazz, isRenamed());
+    assertThat(inspector.clazz("Fields$Inner"), isRenamed());
+
+    FieldSubject anX = lookupAnX(inspector);
+    FieldSubject anArrayOfX = lookupAnArrayOfX(inspector);
+    FieldSubject aFieldsOfX =lookupAFieldsOfX(inspector);
+    FieldSubject aFieldsOfXInner = clazz.field("Fields$Inner", "aFieldsOfXInner");
+
+    // Check that all fields have been renamed
+    assertThat(anX, isRenamed());
+    assertThat(anArrayOfX, isRenamed());
+    assertThat(aFieldsOfX, isRenamed());
+    assertThat(aFieldsOfXInner, isRenamed());
+
+    //System.out.println(generic.getFinalSignatureAttribute());
+    //System.out.println(generic.getOriginalSignatureAttribute());
+
+    // Test that methods have their original signature if the default was provided.
+    if (!signatures.containsKey("anX")) {
+      assertEquals(anXSignature, anX.getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("anArrayOfX")) {
+      assertEquals(anArrayOfXSignature, anArrayOfX.getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("aFieldsOfX")) {
+      assertEquals(
+          aFieldsOfXSignature, aFieldsOfX.getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("aFieldsOfXInner")) {
+      assertEquals(
+          aFieldsOfXInnerSignature, aFieldsOfXInner.getOriginalSignatureAttribute());
+    }
+
+    diagnostics.accept(checker);
+    inspect.accept(inspector);
+  }
+
+  private void testSingleField(String name, String signature,
+      Consumer<DiagnosticsChecker> diagnostics,
+      Consumer<DexInspector> inspector)
+      throws Exception {
+    ImmutableMap<String, String> signatures = ImmutableMap.of(name, signature);
+    runTest(signatures, diagnostics, inspector);
+  }
+
+  private void isOriginUnknown(Origin origin) {
+    assertSame(Origin.unknown(), origin);
+  }
+
+  private void noWarnings(DiagnosticsChecker checker) {
+    assertEquals(0, checker.warnings.size());
+  }
+
+  private void noInspection(DexInspector inspector) {
+  }
+
+  private void noSignatureAttribute(FieldSubject field) {
+    assertThat(field, isPresent());
+    assertNull(field.getFinalSignatureAttribute());
+    assertNull(field.getOriginalSignatureAttribute());
+  }
+
+  @Test
+  public void originalJavacSignatures() throws Exception {
+    // Test using the signatures generated by javac.
+    runTest(ImmutableMap.of(), this::noWarnings, this::noInspection);
+  }
+
+  @Test
+  public void signatureEmpty() throws Exception {
+    testSingleField("anX", "", this::noWarnings,
+        inspector -> noSignatureAttribute(lookupAnX(inspector)));
+  }
+
+  @Test
+  public void signatureInvalid() throws Exception {
+    testSingleField("anX", "X", diagnostics -> {
+      assertEquals(1, diagnostics.warnings.size());
+      // TODO(sgjesse): The position 2 reported here is one off.
+      DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
+          "Invalid signature for field",
+          "java.lang.String Fields.anX",
+          "Expected L, [ or T at position 2");
+    }, inspector -> noSignatureAttribute(lookupAnX(inspector)));
+  }
+
+  @Test
+  public void classNotFound() throws Exception {
+    String signature = "LNotFound<TX;>.InnerNotFound.InnerAlsoNotFound;";
+    testSingleField("anX", signature, this::noWarnings, inspector -> {
+      assertThat(inspector.clazz("NotFound"), not(isPresent()));
+      assertEquals(signature, lookupAnX(inspector).getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void multipleWarnings() throws Exception {
+    runTest(ImmutableMap.of(
+        "anX", "X",
+        "anArrayOfX", "X",
+        "aFieldsOfX", "X"
+    ), diagnostics -> {
+      assertEquals(3, diagnostics.warnings.size());
+    }, inspector -> {
+      noSignatureAttribute(lookupAnX(inspector));
+      noSignatureAttribute(lookupAnArrayOfX(inspector));
+      noSignatureAttribute(lookupAFieldsOfX(inspector));
+    });
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
new file mode 100644
index 0000000..41750ae
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
@@ -0,0 +1,314 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming;
+
+import static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
+import static com.android.tools.r8.utils.DexInspectorMatchers.isRenamed;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_STATIC;
+import static org.objectweb.asm.Opcodes.ACC_SUPER;
+import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
+import static org.objectweb.asm.Opcodes.ACONST_NULL;
+import static org.objectweb.asm.Opcodes.ALOAD;
+import static org.objectweb.asm.Opcodes.ARETURN;
+import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static org.objectweb.asm.Opcodes.PUTFIELD;
+import static org.objectweb.asm.Opcodes.RETURN;
+import static org.objectweb.asm.Opcodes.V1_8;
+
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.DiagnosticsChecker;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.StringConsumer;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.graph.invokesuper.Consumer;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
+import com.android.tools.r8.utils.DexInspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import org.junit.Test;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+public class MinifierMethodSignatureTest extends TestBase {
+  /*
+
+  class Methods<X extends Throwable> {
+    class Inner {
+    }
+    public static <T extends Throwable> T generic(T a, Methods<T>.Inner b) { return null; }
+    public Methods<X>.Inner parameterizedReturn() { return null; }
+    public void parameterizedArguments(X a, Methods<X>.Inner b) { }
+    public void parametrizedThrows() throws X { }
+  }
+
+  */
+
+  private String genericSignature = "<T:Ljava/lang/Throwable;>(TT;LMethods<TT;>.Inner;)TT;";
+  private String parameterizedReturnSignature = "()LMethods<TX;>.Inner;";
+  private String parameterizedArgumentsSignature = "(TX;LMethods<TX;>.Inner;)V";
+  private String parametrizedThrowsSignature = "()V^TX;";
+
+  private byte[] dumpMethods(Map<String, String> signatures) throws Exception {
+
+    ClassWriter cw = new ClassWriter(0);
+    MethodVisitor mv;
+    String signature;
+
+    cw.visit(V1_8, ACC_SUPER, "Methods", "<X:Ljava/lang/Throwable;>Ljava/lang/Object;",
+        "java/lang/Object", null);
+
+    cw.visitInnerClass("Methods$Inner", "Methods", "Inner", 0);
+
+    {
+      mv = cw.visitMethod(0, "<init>", "()V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(1, 1);
+      mv.visitEnd();
+    }
+    {
+      signature = signatures.get("generic");
+      signature = signature == null ? genericSignature : signature;
+      mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "generic",
+          "(Ljava/lang/Throwable;LMethods$Inner;)Ljava/lang/Throwable;",
+          signature, null);
+      mv.visitCode();
+      mv.visitInsn(ACONST_NULL);
+      mv.visitInsn(ARETURN);
+      mv.visitMaxs(1, 2);
+      mv.visitEnd();
+    }
+    {
+      signature = signatures.get("parameterizedReturn");
+      signature = signature == null ? parameterizedReturnSignature : signature;
+      mv = cw.visitMethod(ACC_PUBLIC, "parameterizedReturn", "()LMethods$Inner;",
+          signature, null);
+      mv.visitCode();
+      mv.visitInsn(ACONST_NULL);
+      mv.visitInsn(ARETURN);
+      mv.visitMaxs(1, 1);
+      mv.visitEnd();
+    }
+    {
+      signature = signatures.get("parameterizedArguments");
+      signature = signature == null ? parameterizedArgumentsSignature : signature;
+      mv = cw.visitMethod(ACC_PUBLIC, "parameterizedArguments",
+          "(Ljava/lang/Throwable;LMethods$Inner;)V", signature, null);
+      mv.visitCode();
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(0, 3);
+      mv.visitEnd();
+    }
+    {
+      signature = signatures.get("parametrizedThrows");
+      signature = signature == null ? parametrizedThrowsSignature : signature;
+      mv = cw.visitMethod(ACC_PUBLIC, "parametrizedThrows", "()V", signature,
+          new String[] { "java/lang/Throwable" });
+      mv.visitCode();
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(0, 1);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private byte[] dumpInner() throws Exception {
+
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+
+    cw.visit(V1_8, ACC_SUPER, "Methods$Inner", null, "java/lang/Object", null);
+
+    cw.visitInnerClass("Methods$Inner", "Methods", "Inner", 0);
+
+    {
+      fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "LMethods;", null, null);
+      fv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(0, "<init>", "(LMethods;)V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitFieldInsn(PUTFIELD, "Methods$Inner", "this$0", "LMethods;");
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(2, 2);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private MethodSubject lookupGeneric(DexInspector inspector) {
+    ClassSubject clazz = inspector.clazz("Methods");
+    return clazz.method(
+        "java.lang.Throwable", "generic", ImmutableList.of("java.lang.Throwable", "Methods$Inner"));
+  }
+
+  private MethodSubject lookupParameterizedReturn(DexInspector inspector) {
+    ClassSubject clazz = inspector.clazz("Methods");
+    return clazz.method(
+        "Methods$Inner", "parameterizedReturn", ImmutableList.of());
+  }
+
+  private MethodSubject lookupParameterizedArguments(DexInspector inspector) {
+    ClassSubject clazz = inspector.clazz("Methods");
+    return clazz.method(
+        "void", "parameterizedArguments", ImmutableList.of("java.lang.Throwable", "Methods$Inner"));
+  }
+
+  public void runTest(
+      ImmutableMap<String, String> signatures,
+      Consumer<DiagnosticsChecker> diagnostics,
+      Consumer<DexInspector> inspect)
+      throws Exception {
+    DiagnosticsChecker checker = new DiagnosticsChecker();
+    DexInspector inspector = new DexInspector(
+      ToolHelper.runR8(R8Command.builder(checker)
+          .addClassProgramData(dumpMethods(signatures), Origin.unknown())
+          .addClassProgramData(dumpInner(), Origin.unknown())
+          .addProguardConfiguration(ImmutableList.of(
+              "-keepattributes InnerClasses,EnclosingMethod,Signature",
+              "-keep,allowobfuscation class ** { *; }"
+          ), Origin.unknown())
+          .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+          .setProguardMapConsumer(StringConsumer.emptyConsumer())
+          .build()));
+    // All classes are kept, and renamed.
+    ClassSubject clazz = inspector.clazz("Methods");
+    assertThat(clazz, isRenamed());
+    assertThat(inspector.clazz("Methods$Inner"), isRenamed());
+
+    MethodSubject generic = lookupGeneric(inspector);
+    MethodSubject parameterizedReturn = lookupParameterizedReturn(inspector);
+    MethodSubject parameterizedArguments = lookupParameterizedArguments(inspector);
+    MethodSubject parametrizedThrows =
+        clazz.method("void", "parametrizedThrows", ImmutableList.of());
+
+    // Check that all methods have been renamed
+    assertThat(generic, isRenamed());
+    assertThat(parameterizedReturn, isRenamed());
+    assertThat(parameterizedArguments, isRenamed());
+    assertThat(parametrizedThrows, isRenamed());
+
+    // Test that methods have their original signature if the default was provided.
+    if (!signatures.containsKey("generic")) {
+      assertEquals(genericSignature, generic.getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("parameterizedReturn")) {
+      assertEquals(
+          parameterizedReturnSignature, parameterizedReturn.getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("parameterizedArguments")) {
+      assertEquals(
+          parameterizedArgumentsSignature, parameterizedArguments.getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("parametrizedThrows")) {
+      assertEquals(
+          parametrizedThrowsSignature, parametrizedThrows.getOriginalSignatureAttribute());
+    }
+
+    diagnostics.accept(checker);
+    inspect.accept(inspector);
+  }
+
+  private void testSingleMethod(String name, String signature,
+      Consumer<DiagnosticsChecker> diagnostics,
+      Consumer<DexInspector> inspector)
+      throws Exception {
+    ImmutableMap<String, String> signatures = ImmutableMap.of(name, signature);
+    runTest(signatures, diagnostics, inspector);
+  }
+
+  private void isOriginUnknown(Origin origin) {
+    assertSame(Origin.unknown(), origin);
+  }
+
+  private void noWarnings(DiagnosticsChecker checker) {
+    assertEquals(0, checker.warnings.size());
+  }
+
+  private void noInspection(DexInspector inspector) {
+  }
+
+  private void noSignatureAttribute(MethodSubject method) {
+    assertThat(method, isPresent());
+    assertNull(method.getFinalSignatureAttribute());
+    assertNull(method.getOriginalSignatureAttribute());
+  }
+
+  @Test
+  public void originalJavacSignatures() throws Exception {
+    // Test using the signatures generated by javac.
+    runTest(ImmutableMap.of(), this::noWarnings, this::noInspection);
+  }
+
+  @Test
+  public void signatureEmpty() throws Exception {
+    testSingleMethod("generic", "", this::noWarnings, inspector -> {
+      noSignatureAttribute(lookupGeneric(inspector));
+    });
+  }
+
+  @Test
+  public void signatureInvalid() throws Exception {
+    testSingleMethod("generic", "X", diagnostics -> {
+      assertEquals(1, diagnostics.warnings.size());
+      DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
+          "Invalid signature for method",
+          "java.lang.Throwable Methods.generic(java.lang.Throwable, Methods$Inner)",
+          "Expected ( at position 1");
+    }, inspector -> noSignatureAttribute(lookupGeneric(inspector)));
+  }
+
+  @Test
+  public void classNotFound() throws Exception {
+    String signature = "<T:LNotFound;>(TT;LAlsoNotFound<TT;>.InnerNotFound.InnerAlsoNotFound;)TT;";
+    testSingleMethod("generic", signature, this::noWarnings,
+        inspector -> {
+          ClassSubject methods = inspector.clazz("Methods");
+          MethodSubject method =
+              methods.method("java.lang.Throwable", "generic",
+                  ImmutableList.of("java.lang.Throwable", "Methods$Inner"));
+          assertThat(inspector.clazz("NotFound"), not(isPresent()));
+          assertEquals(signature, method.getOriginalSignatureAttribute());
+        });
+  }
+
+  @Test
+  public void multipleWarnings() throws Exception {
+    runTest(ImmutableMap.of(
+        "generic", "X",
+        "parameterizedReturn", "X",
+        "parameterizedArguments", "X"
+    ), diagnostics -> {
+      assertEquals(3, diagnostics.warnings.size());
+    }, inspector -> {
+      noSignatureAttribute(lookupGeneric(inspector));
+      noSignatureAttribute(lookupParameterizedReturn(inspector));
+      noSignatureAttribute(lookupParameterizedArguments(inspector));
+    });
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/DexInspector.java b/src/test/java/com/android/tools/r8/utils/DexInspector.java
index e7e882a..fd32ec7 100644
--- a/src/test/java/com/android/tools/r8/utils/DexInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/DexInspector.java
@@ -886,7 +886,31 @@
     @Override
     public MethodSignature getOriginalSignature() {
       MethodSignature signature = getFinalSignature();
-      MemberNaming memberNaming = clazz.naming != null ? clazz.naming.lookup(signature) : null;
+      if (clazz.naming == null) {
+        return signature;
+      }
+
+      // Map the parameters and return type to original names. This is needed as the in the
+      // Proguard map the names on the left side are the original names. E.g.
+      //
+      //   X -> a
+      //     X method(X) -> a
+      //
+      // whereas the final signature is for X.a is "a (a)"
+      String[] OriginalParameters = new String[signature.parameters.length];
+      for (int i = 0; i < OriginalParameters.length; i++) {
+        String obfuscated = signature.parameters[i];
+        String original = originalToObfuscatedMapping.inverse().get(obfuscated);
+        OriginalParameters[i] = original != null ? original : obfuscated;
+      }
+      String obfuscatedReturnType = signature.type;
+      String originalReturnType = originalToObfuscatedMapping.inverse().get(obfuscatedReturnType);
+      String returnType = originalReturnType != null ? originalReturnType : obfuscatedReturnType;
+
+      MethodSignature lookupSignature =
+          new MethodSignature(signature.name, returnType, OriginalParameters);
+
+      MemberNaming memberNaming = clazz.naming.lookup(lookupSignature);
       return memberNaming != null
           ? (MethodSignature) memberNaming.getOriginalSignature()
           : signature;
@@ -1035,7 +1059,24 @@
     @Override
     public FieldSignature getOriginalSignature() {
       FieldSignature signature = getFinalSignature();
-      MemberNaming memberNaming = clazz.naming != null ? clazz.naming.lookup(signature) : null;
+      if (clazz.naming == null) {
+        return signature;
+      }
+
+      // Map the type to the original name. This is needed as the in the Proguard map the
+      // names on the left side are the original names. E.g.
+      //
+      //   X -> a
+      //     X field -> a
+      //
+      // whereas the final signature is for X.a is "a a"
+      String obfuscatedType = signature.type;
+      String originalType = originalToObfuscatedMapping.inverse().get(obfuscatedType);
+      String fieldType = originalType != null ? originalType : obfuscatedType;
+
+      FieldSignature lookupSignature = new FieldSignature(signature.name, fieldType);
+
+      MemberNaming memberNaming = clazz.naming.lookup(lookupSignature);
       return memberNaming != null
           ? (FieldSignature) memberNaming.getOriginalSignature()
           : signature;
