C++ modules: merging for enumerations and enumerators with multiple definitions
(eg through template instantiations in multiple modules).

llvm-svn: 192740
diff --git a/clang/test/Modules/Inputs/cxx-templates-a.h b/clang/test/Modules/Inputs/cxx-templates-a.h
index d2261f6a..0ca6e34 100644
--- a/clang/test/Modules/Inputs/cxx-templates-a.h
+++ b/clang/test/Modules/Inputs/cxx-templates-a.h
@@ -33,3 +33,10 @@
 
 template<int> struct MergeTemplates;
 MergeTemplates<0> *merge_templates_a;
+
+auto enum_a_from_a = CommonTemplate<int>::a;
+const auto enum_c_from_a = CommonTemplate<int>::c;
+
+template<int> struct UseInt;
+template<typename T> void UseRedeclaredEnum(UseInt<T() + CommonTemplate<char>::a>);
+constexpr void (*UseRedeclaredEnumA)(UseInt<1>) = UseRedeclaredEnum<int>;
diff --git a/clang/test/Modules/Inputs/cxx-templates-b.h b/clang/test/Modules/Inputs/cxx-templates-b.h
index 6cc951b..f0921a7 100644
--- a/clang/test/Modules/Inputs/cxx-templates-b.h
+++ b/clang/test/Modules/Inputs/cxx-templates-b.h
@@ -44,6 +44,13 @@
   b = c;
 }
 
+auto enum_b_from_b = CommonTemplate<int>::b;
+const auto enum_c_from_b = CommonTemplate<int>::c;
+
+template<int> struct UseInt;
+template<typename T> void UseRedeclaredEnum(UseInt<T() + CommonTemplate<char>::a>);
+constexpr void (*UseRedeclaredEnumB)(UseInt<1>) = UseRedeclaredEnum<int>;
+
 @import cxx_templates_a;
 template<typename T> void UseDefinedInBImplIndirectly(T &v) {
   PerformDelayedLookup(v);
diff --git a/clang/test/Modules/Inputs/cxx-templates-common.h b/clang/test/Modules/Inputs/cxx-templates-common.h
index 6993da8..40a11e2 100644
--- a/clang/test/Modules/Inputs/cxx-templates-common.h
+++ b/clang/test/Modules/Inputs/cxx-templates-common.h
@@ -5,3 +5,7 @@
   struct Inner {};
   friend void FoundByADL(DefinedInCommon);
 };
+
+template<typename T> struct CommonTemplate {
+  enum E { a = 1, b = 2, c = 3 };
+};
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index 911f953..0965aa8 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -5,6 +5,7 @@
 
 @import cxx_templates_a;
 @import cxx_templates_b;
+@import cxx_templates_common;
 
 template<typename, char> struct Tmpl_T_C {};
 template<typename, int, int> struct Tmpl_T_I_I {};
@@ -12,6 +13,8 @@
 template<typename A, typename B, A> struct Tmpl_T_T_A {};
 template<typename A, typename B, B> struct Tmpl_T_T_B {};
 
+template<int> struct UseInt {};
+
 void g() {
   f(0);
   f<double>(1.0);
@@ -71,6 +74,19 @@
   PerformDelayedLookup(defined_in_b_impl); // expected-note {{in instantiation of}}
 
   merge_templates_a = merge_templates_b; // ok, same type
+
+  using T = decltype(enum_a_from_a);
+  using T = decltype(enum_b_from_b);
+  T e = true ? enum_a_from_a : enum_b_from_b;
+
+  UseRedeclaredEnum<int>(UseInt<1>());
+  // FIXME: Reintroduce this once we merge function template specializations.
+  //static_assert(UseRedeclaredEnumA == UseRedeclaredEnumB, "");
+  //static_assert(UseRedeclaredEnumA == UseRedeclaredEnum<int>, "");
+  //static_assert(UseRedeclaredEnumB == UseRedeclaredEnum<int>, "");
+  static_assert(enum_c_from_a == enum_c_from_b, "");
+  CommonTemplate<int> cti;
+  CommonTemplate<int>::E eee = CommonTemplate<int>::c;
 }
 
 RedeclaredAsFriend<int> raf1;