Merge changes If71ba334,Ia7c3ee02,I2c99fad6

* changes:
  Android Patch: ICU-20308 Define a fixed suffix without the ICU version suffix
  Cherry-pick: ICU-20309 "#if !UCONFIG_NO_CONVERSION" block should include the doxygen doc for uregex_openC
  Cherry-pick: ICU-20307 Add reldatefmt.h and compactdecimalformat.h into test/hdrtst/cxxfiles.txt
diff --git a/icu4c/source/Android.bp b/icu4c/source/Android.bp
index 5a5c11d..b5203e8 100644
--- a/icu4c/source/Android.bp
+++ b/icu4c/source/Android.bp
@@ -17,7 +17,7 @@
     "i18n",
 ]
 
-cc_library_static {
+cc_library {
     name: "libicuuc_stubdata",
     host_supported: true,
     srcs: ["stubdata/stubdata.cpp"],
@@ -27,4 +27,9 @@
         "-Werror",
     ],
     cppflags: ["-std=c++11"],
+    target: {
+        windows: {
+            enabled: true,
+        },
+    },
 }
diff --git a/icu4c/source/common/Android.bp b/icu4c/source/common/Android.bp
index 953ebc1..165da2c 100644
--- a/icu4c/source/common/Android.bp
+++ b/icu4c/source/common/Android.bp
@@ -66,5 +66,17 @@
     host_supported: true,
     unique_host_soname: true,
     defaults: ["libicuuc_defaults"],
-    static_libs: ["libicuuc_stubdata"],
+    target: {
+        android: {
+            static_libs: ["libicuuc_stubdata"],
+        },
+        not_windows: {
+            static_libs: ["libicuuc_stubdata"],
+        },
+        windows: {
+            enabled: true,
+            // Windows requires importing data as a DLL when building with U_COMMON_IMPLEMENTATION
+            shared_libs: ["libicuuc_stubdata"],
+        },
+    },
 }
diff --git a/icu4c/source/common/umutex.h b/icu4c/source/common/umutex.h
index 015a12f..a15e7a4 100644
--- a/icu4c/source/common/umutex.h
+++ b/icu4c/source/common/umutex.h
@@ -54,15 +54,23 @@
 
 #include <atomic>
 
-U_NAMESPACE_BEGIN
-
 // Export an explicit template instantiation of std::atomic<int32_t>. 
 // When building DLLs for Windows this is required as it is used as a data member of the exported SharedObject class.
 // See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.
-#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
+#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN && !defined(U_IN_DOXYGEN)
+  #if defined(__clang__)
+  // Suppress the warning that the explicit instantiation after explicit specialization has no effect.
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Winstantiation-after-specialization"
+  #endif
 template struct U_COMMON_API std::atomic<int32_t>;
+  #if defined(__clang__)
+  #pragma clang diagnostic pop
+  #endif
 #endif
 
+U_NAMESPACE_BEGIN
+
 typedef std::atomic<int32_t> u_atomic_int32_t;
 #define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
 
diff --git a/icu4c/source/i18n/unicode/numberrangeformatter.h b/icu4c/source/i18n/unicode/numberrangeformatter.h
index 5054683..d5466b1 100644
--- a/icu4c/source/i18n/unicode/numberrangeformatter.h
+++ b/icu4c/source/i18n/unicode/numberrangeformatter.h
@@ -185,8 +185,14 @@
  * Export an explicit template instantiation. See datefmt.h
  * (When building DLLs for Windows this is required.)
  */
-#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN && !defined(U_IN_DOXYGEN)
-template struct U_I18N_API std::atomic<impl::NumberRangeFormatterImpl*>;
+#if U_PLATFORM == U_PF_WINDOWS && !defined(U_IN_DOXYGEN)
+} // namespace icu::number
+U_NAMESPACE_END
+
+template struct U_I18N_API std::atomic< U_NAMESPACE_QUALIFIER number::impl::NumberRangeFormatterImpl*>;
+
+U_NAMESPACE_BEGIN
+namespace number {  // icu::number
 #endif
 /** \endcond */
 
diff --git a/icu4c/source/test/intltest/numbertest.h b/icu4c/source/test/intltest/numbertest.h
index 49c2d44..1c109df 100644
--- a/icu4c/source/test/intltest/numbertest.h
+++ b/icu4c/source/test/intltest/numbertest.h
@@ -10,6 +10,7 @@
 #include "intltest.h"
 #include "number_affixutils.h"
 #include "numparse_stringsegment.h"
+#include "numrange_impl.h"
 #include "unicode/locid.h"
 #include "unicode/numberformatter.h"
 #include "unicode/numberrangeformatter.h"
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/aosp/Annotations.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/aosp/Annotations.java
index bcb4e01..5c0884e 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/aosp/Annotations.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/aosp/Annotations.java
@@ -68,6 +68,7 @@
         "dalvik.annotation.compat.UnsupportedAppUsage")
         .addProperty("maxTargetSdk", int.class)
         .addProperty("trackingBug", long.class)
+        .addProperty("implicitMember", String.class)
         .addProperty("expectedSignature", String.class);
     try {
       return AddAnnotation.fromJsonFile(annotationClass, unsupportedAppUsagePath);
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/BodyDeclarationLocator.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/BodyDeclarationLocator.java
index 4d67951..d80196e 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/BodyDeclarationLocator.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/BodyDeclarationLocator.java
@@ -48,4 +48,10 @@
    * declaring type of the method. When called on a {@link TypeLocator} it returns {@code this}.
    */
   TypeLocator getTypeLocator();
+
+  @Override
+  boolean equals(Object object);
+
+  @Override
+  int hashCode();
 }
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/EnumConstantLocator.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/EnumConstantLocator.java
index 164094a..d9cd1a7 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/EnumConstantLocator.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/EnumConstantLocator.java
@@ -15,6 +15,7 @@
  */
 package com.google.currysrc.api.process.ast;
 
+import java.util.Objects;
 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
 import org.eclipse.jdt.core.dom.BodyDeclaration;
 import org.eclipse.jdt.core.dom.CompilationUnit;
@@ -87,6 +88,24 @@
   }
 
   @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof EnumConstantLocator)) {
+      return false;
+    }
+    EnumConstantLocator that = (EnumConstantLocator) o;
+    return Objects.equals(typeLocator, that.typeLocator) &&
+        Objects.equals(constantName, that.constantName);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(typeLocator, constantName);
+  }
+
+  @Override
   public String toString() {
     return "EnumConstantLocator{" +
         "typeLocator=" + typeLocator +
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/FieldLocator.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/FieldLocator.java
index b58db23..01c0fe2 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/FieldLocator.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/FieldLocator.java
@@ -15,6 +15,7 @@
  */
 package com.google.currysrc.api.process.ast;
 
+import java.util.Objects;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
 import org.eclipse.jdt.core.dom.BodyDeclaration;
@@ -114,6 +115,24 @@
   }
 
   @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof FieldLocator)) {
+      return false;
+    }
+    FieldLocator that = (FieldLocator) o;
+    return Objects.equals(typeLocator, that.typeLocator) &&
+        Objects.equals(fieldName, that.fieldName);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(typeLocator, fieldName);
+  }
+
+  @Override
   public String toString() {
     return "FieldLocator{" +
         "typeLocator=" + typeLocator +
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/MethodLocator.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/MethodLocator.java
index 399b2b7..fe1f10b 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/MethodLocator.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/MethodLocator.java
@@ -15,6 +15,7 @@
  */
 package com.google.currysrc.api.process.ast;
 
+import java.util.Objects;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
 import org.eclipse.jdt.core.dom.BodyDeclaration;
@@ -94,6 +95,25 @@
   }
 
   @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof MethodLocator)) {
+      return false;
+    }
+    MethodLocator that = (MethodLocator) o;
+    return Objects.equals(typeLocator, that.typeLocator) &&
+        Objects.equals(methodName, that.methodName) &&
+        Objects.equals(parameterMatcher, that.parameterMatcher);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(typeLocator, methodName, parameterMatcher);
+  }
+
+  @Override
   public String toString() {
     return "MethodLocator{" +
         "typeLocator=" + typeLocator +
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/PackageMatcher.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/PackageMatcher.java
index 4388bc6..6405803 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/PackageMatcher.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/PackageMatcher.java
@@ -15,6 +15,7 @@
  */
 package com.google.currysrc.api.process.ast;
 
+import java.util.Objects;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.PackageDeclaration;
@@ -62,4 +63,21 @@
     }
     return packageDeclaration.getName().getFullyQualifiedName();
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof PackageMatcher)) {
+      return false;
+    }
+    PackageMatcher that = (PackageMatcher) o;
+    return Objects.equals(packageName, that.packageName);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(packageName);
+  }
 }
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/ParameterMatcher.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/ParameterMatcher.java
index eedf9f9..bfab867 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/ParameterMatcher.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/ParameterMatcher.java
@@ -17,6 +17,7 @@
 
 import com.google.common.base.Joiner;
 
+import java.util.Objects;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
 
@@ -75,6 +76,23 @@
   }
 
   @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof ParameterMatcher)) {
+      return false;
+    }
+    ParameterMatcher that = (ParameterMatcher) o;
+    return Objects.equals(parameterTypes, that.parameterTypes);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(parameterTypes);
+  }
+
+  @Override
   public String toString() {
     return "ParameterMatcher{" +
         "parameterTypes=" + parameterTypes +
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/TypeLocator.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/TypeLocator.java
index b6f037b..6fb8ed9 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/TypeLocator.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/api/process/ast/TypeLocator.java
@@ -24,6 +24,7 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Objects;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
 import org.eclipse.jdt.core.dom.BodyDeclaration;
@@ -233,6 +234,24 @@
   }
 
   @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof TypeLocator)) {
+      return false;
+    }
+    TypeLocator that = (TypeLocator) o;
+    return Objects.equals(packageMatcher, that.packageMatcher) &&
+        Objects.equals(classNameElements, that.classNameElements);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(packageMatcher, classNameElements);
+  }
+
+  @Override
   public String toString() {
     return "TypeLocator{" +
         "packageMatcher=" + packageMatcher +
diff --git a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/processors/AnnotationInfo.java b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/processors/AnnotationInfo.java
index 1ae4a7d..48c440f 100644
--- a/tools/srcgen/currysrc/src/main/java/com/google/currysrc/processors/AnnotationInfo.java
+++ b/tools/srcgen/currysrc/src/main/java/com/google/currysrc/processors/AnnotationInfo.java
@@ -40,6 +40,14 @@
     return properties;
   }
 
+  @Override
+  public String toString() {
+    return "AnnotationInfo{" +
+        "annotationClass=" + annotationClass +
+        ", properties=" + properties +
+        '}';
+  }
+
   /**
    * Expected type of an annotation's properties.
    */
@@ -62,10 +70,11 @@
       return name;
     }
 
-    public Class<?> getPropertyType(String name) {
-      Class<?> type = propertyTypes.get(name);
+    public Class<?> getPropertyType(String propertyName) {
+      Class<?> type = propertyTypes.get(propertyName);
       if (type == null) {
-        throw new IllegalStateException(String.format("Unknown property: %s in %s", name, name));
+        throw new IllegalStateException(
+            String.format("Unknown property: %s in %s", propertyName, name));
       }
       return type;
     }