Fix the visibility of methods of explicit template instantiation definition
when using -fvisibility-inlines-hidden. This matches gcc's behavior and
documentation.

Fixes PR11642.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147295 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 84a2a59..f9e57bc 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -568,6 +568,7 @@
     // about whether containing classes have visibility attributes,
     // and that's intentional.
     if (TSK != TSK_ExplicitInstantiationDeclaration &&
+        TSK != TSK_ExplicitInstantiationDefinition &&
         F.ConsiderGlobalVisibility &&
         MD->getASTContext().getLangOptions().InlineVisibilityHidden) {
       // InlineVisibilityHidden only applies to definitions, and
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index f7fabed..d660b1b 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -97,3 +97,14 @@
 
   // CHECK: define available_externally void @_ZN5test22ns3fooINS_1BINS_1AEEEEEvv()
 }
+
+namespace PR11642 {
+  template <typename T>
+  class Foo {
+  public:
+    T foo(T x) { return x; }
+  };
+  extern template class Foo<int>;
+  template class Foo<int>;
+  // CHECK: define weak_odr i32 @_ZN7PR116423FooIiE3fooEi
+}