sepavloff created this revision.
Herald added subscribers: JDevlieghere, eraman.

If a module contains opaque type and another one contains definition
of equivalent type in sense of C++, `llvm-link` merges these types.
In this procedure it can rely only on type name. An issue arises if
the type is a class template specialization. See the example.

File 1

  template<typename T> struct ABC;
  ABC<int> *var_1;

File 2

  template<typename T> struct ABC {
    T *f;
  };
  extern ABC<int> var_1;
  ABC<int*> var_2;

llvm-link produces module:

  %struct.ABC = type { i32** }
  @var_1 = global %struct.ABC* null, align 8
  @var_2 = global %struct.ABC zeroinitializer, align 8

Incomplete type `ABC<int>` from the first module becomes `ABC<int*>`. It
happens because structure types obtained from template specialization
share the same type name and differ from each other only by version
suffixes, in the example the types are named as `ABC` and `ABC.0`.
`llvm-link` cannot correctly merge these types.

This change enables template arguments in class template specializations.
Clang already prints them in class context, now they will appear in the
class name itself.


https://reviews.llvm.org/D40567

Files:
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.def
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/CodeGenAction.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGenCXX/apple-kext-indirect-call.cpp
  test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
  test/CodeGenCXX/captured-statements.cpp
  test/CodeGenCXX/const-init-cxx11.cpp
  test/CodeGenCXX/constructor-init.cpp
  test/CodeGenCXX/ctor-dtor-alias.cpp
  test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
  test/CodeGenCXX/debug-info-template.cpp
  test/CodeGenCXX/dllexport-pr26549.cpp
  test/CodeGenCXX/dllexport.cpp
  test/CodeGenCXX/dllimport.cpp
  test/CodeGenCXX/float128-declarations.cpp
  test/CodeGenCXX/float16-declarations.cpp
  test/CodeGenCXX/mangle-abi-tag.cpp
  test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
  test/CodeGenCXX/microsoft-abi-extern-template.cpp
  test/CodeGenCXX/microsoft-abi-vftables.cpp
  test/CodeGenCXX/ms-property.cpp
  test/CodeGenCXX/noinline-template.cpp
  test/CodeGenCXX/pr29160.cpp
  test/CodeGenCXX/static-init-3.cpp
  test/CodeGenCXX/template-anonymous-types.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/template-linkage.cpp
  test/CodeGenCXX/value-init.cpp
  test/CodeGenCXX/virtual-base-destructor-call.cpp
  test/CodeGenCoroutines/coro-await.cpp
  test/CodeGenObjCXX/arc-cxx11-init-list.mm
  test/CodeGenObjCXX/property-lvalue-capture.mm
  test/OpenMP/declare_reduction_codegen.cpp
  test/OpenMP/target_codegen.cpp
  test/OpenMP/target_parallel_codegen.cpp
  test/OpenMP/target_simd_codegen.cpp
  test/OpenMP/target_teams_codegen.cpp

Index: test/OpenMP/target_teams_codegen.cpp
===================================================================
--- test/OpenMP/target_teams_codegen.cpp
+++ test/OpenMP/target_teams_codegen.cpp
@@ -303,7 +303,7 @@
   // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
 
   // CHECK:       [[FAIL]]
-  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, %"struct.TT<long long, char>"{{[^,]+}})
   // CHECK-NEXT:  br label %[[END]]
   // CHECK:       [[END]]
   #pragma omp target teams if(target: n>20)
Index: test/OpenMP/target_simd_codegen.cpp
===================================================================
--- test/OpenMP/target_simd_codegen.cpp
+++ test/OpenMP/target_simd_codegen.cpp
@@ -292,7 +292,7 @@
   // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
 
   // CHECK:       [[FAIL]]
-  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, %"struct.TT<long long, char>"*{{[^,]+}})
   // CHECK-NEXT:  br label %[[END]]
   // CHECK:       [[END]]
   #pragma omp target simd if(target: n>20)
Index: test/OpenMP/target_parallel_codegen.cpp
===================================================================
--- test/OpenMP/target_parallel_codegen.cpp
+++ test/OpenMP/target_parallel_codegen.cpp
@@ -279,7 +279,7 @@
   // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
 
   // CHECK:       [[FAIL]]
-  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, %"struct.TT<long long, char>{{[^,]+}})
   // CHECK-NEXT:  br label %[[END]]
   // CHECK:       [[END]]
   #pragma omp target parallel if(target: n>20)
Index: test/OpenMP/target_codegen.cpp
===================================================================
--- test/OpenMP/target_codegen.cpp
+++ test/OpenMP/target_codegen.cpp
@@ -319,12 +319,12 @@
   // CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
   // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
   // CHECK:       [[FAIL]]
-  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, %"struct.TT<long long, char>"{{[^,]+}})
   // CHECK-NEXT:  br label %[[END]]
   // CHECK:       [[END]]
   // CHECK-NEXT:  br label %[[IFEND:.+]]
   // CHECK:       [[IFELSE]]
-  // CHECK:       call void [[HVT4]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+  // CHECK:       call void [[HVT4]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, %"struct.TT<long long, char>"{{[^,]+}})
   // CHECK-NEXT:  br label %[[IFEND]]
 
   // CHECK:       [[IFEND]]
Index: test/OpenMP/declare_reduction_codegen.cpp
===================================================================
--- test/OpenMP/declare_reduction_codegen.cpp
+++ test/OpenMP/declare_reduction_codegen.cpp
@@ -153,8 +153,8 @@
 }
 
 // CHECK: define internal {{.*}}void [[REGION]](
-// CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS,
-// CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%struct.SSS* [[SSS_PRIV]])
+// CHECK: [[SSS_PRIV:%.+]] = alloca %"struct.SSS<int>",
+// CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%"struct.SSS<int>"* [[SSS_PRIV]])
 // CHECK-NOT: {{call |invoke }}
 // CHECK: call {{.*}}i32 @__kmpc_reduce_nowait(
 
Index: test/CodeGenObjCXX/property-lvalue-capture.mm
===================================================================
--- test/CodeGenObjCXX/property-lvalue-capture.mm
+++ test/CodeGenObjCXX/property-lvalue-capture.mm
@@ -26,10 +26,10 @@
 
 // CHECK:   [[TWO:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load ![[MD_NUM:[0-9]+]]
 // CHECK:   [[THREE:%.*]] = bitcast [[ONET:%.*]]* [[ONE:%.*]] to i8*
-// CHECK:   [[CALL:%.*]] = call nonnull %struct.Quad2* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct.Quad2* (i8*, i8*)*)(i8* [[THREE]], i8* [[TWO]])
+// CHECK:   [[CALL:%.*]] = call nonnull %"struct.Quad2<double>"* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %"struct.Quad2<double>"* (i8*, i8*)*)(i8* [[THREE]], i8* [[TWO]])
 // CHECK:   [[FOUR:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2, align 8, !invariant.load ![[MD_NUM]]
 // CHECK:   [[FIVE:%.*]] = bitcast [[ONET]]* [[ZERO:%.*]] to i8*
-// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.Quad2*)*)(i8* [[FIVE]], i8* [[FOUR]], %struct.Quad2* nonnull [[CALL]])
+// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %"struct.Quad2<double>"*)*)(i8* [[FIVE]], i8* [[FOUR]], %"struct.Quad2<double>"* nonnull [[CALL]])
 
 
 struct A {
Index: test/CodeGenObjCXX/arc-cxx11-init-list.mm
===================================================================
--- test/CodeGenObjCXX/arc-cxx11-init-list.mm
+++ test/CodeGenObjCXX/arc-cxx11-init-list.mm
@@ -42,10 +42,10 @@
   return {@"str0", @"str1"};
 }
 
-// CHECK: define void @_Z4foo1v(%"class.std::initializer_list.0"* {{.*}} %[[AGG_RESULT:.*]])
-// CHECK: %[[BEGIN:.*]] = getelementptr inbounds %"class.std::initializer_list.0", %"class.std::initializer_list.0"* %[[AGG_RESULT]], i32 0, i32 0
+// CHECK: define void @_Z4foo1v(%"class.std::initializer_list<id>"* {{.*}} %[[AGG_RESULT:.*]])
+// CHECK: %[[BEGIN:.*]] = getelementptr inbounds %"class.std::initializer_list<id>", %"class.std::initializer_list<id>"* %[[AGG_RESULT]], i32 0, i32 0
 // CHECK: store i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[REFTMP]], i32 0, i32 0), i8*** %[[BEGIN]]
-// CHECK: %[[SIZE:.*]] = getelementptr inbounds %"class.std::initializer_list.0", %"class.std::initializer_list.0"* %[[AGG_RESULT]], i32 0, i32 1
+// CHECK: %[[SIZE:.*]] = getelementptr inbounds %"class.std::initializer_list<id>", %"class.std::initializer_list<id>"* %[[AGG_RESULT]], i32 0, i32 1
 // CHECK: store i32 2, i32* %[[SIZE]]
 // CHECK: ret void
 
Index: test/CodeGenCoroutines/coro-await.cpp
===================================================================
--- test/CodeGenCoroutines/coro-await.cpp
+++ test/CodeGenCoroutines/coro-await.cpp
@@ -339,8 +339,8 @@
   co_await TailCallAwait{};
 
   // CHECK: %[[RESULT:.+]] = call i8* @_ZN13TailCallAwait13await_suspendENSt12experimental16coroutine_handleIvEE(%struct.TailCallAwait*
-  // CHECK: %[[COERCE:.+]] = getelementptr inbounds %"struct.std::experimental::coroutine_handle", %"struct.std::experimental::coroutine_handle"* %[[TMP:.+]], i32 0, i32 0
+  // CHECK: %[[COERCE:.+]] = getelementptr inbounds %"struct.std::experimental::coroutine_handle<void>", %"struct.std::experimental::coroutine_handle<void>"* %[[TMP:.+]], i32 0, i32 0
   // CHECK: store i8* %[[RESULT]], i8** %[[COERCE]]
-  // CHECK: %[[ADDR:.+]] = call i8* @_ZNSt12experimental16coroutine_handleIvE7addressEv(%"struct.std::experimental::coroutine_handle"* %[[TMP]])
+  // CHECK: %[[ADDR:.+]] = call i8* @_ZNSt12experimental16coroutine_handleIvE7addressEv(%"struct.std::experimental::coroutine_handle<void>"* %[[TMP]])
   // CHECK: call void @llvm.coro.resume(i8* %[[ADDR]])
 }
Index: test/CodeGenCXX/virtual-base-destructor-call.cpp
===================================================================
--- test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -18,34 +18,34 @@
 
 // basic_iostream's complete dtor calls its base dtor, then its
 // virtual base's dtor.
-//  CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED1Ev(%struct.basic_iostream* {{.*}}%this) unnamed_addr
+//  CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED1Ev(%"struct.basic_iostream<char>"* {{.*}}%this) unnamed_addr
 //  CHECK: call {{.*}} @_ZN14basic_iostreamIcED2Ev
 //  CHECK: call {{.*}} @_ZN9basic_iosD2Ev
 
 // basic_istream's complete dtor calls the base dtor,
 // then its virtual base's base dtor.
-//  CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED1Ev(%struct.basic_istream* {{.*}}%this) unnamed_addr
+//  CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED1Ev(%"struct.basic_istream<char>"* {{.*}}%this) unnamed_addr
 //  CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev
 //  CHECK: call {{.*}} @_ZN9basic_iosD2Ev
 
 // basic_istream's deleting dtor calls the complete dtor, then
 // operator delete().
-//  CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED0Ev(%struct.basic_istream* {{.*}}%this) unnamed_addr
+//  CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED0Ev(%"struct.basic_istream<char>"* {{.*}}%this) unnamed_addr
 //  CHECK: call {{.*}} @_ZN13basic_istreamIcED1Ev
 //  CHECK: call {{.*}} @_ZdlPv
 
 // basic_iostream's deleting dtor calls its complete dtor, then
 // operator delete().
-//  CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* {{.*}}%this) unnamed_addr
+//  CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED0Ev(%"struct.basic_iostream<char>"* {{.*}}%this) unnamed_addr
 //  CHECK: call {{.*}} @_ZN14basic_iostreamIcED1Ev
 //  CHECK: call {{.*}} @_ZdlPv
 
 // basic_istream's base dtor is a no-op.
-//  CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* {{.*}}%this, i8** %vtt) unnamed_addr
+//  CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED2Ev(%"struct.basic_istream<char>"* {{.*}}%this, i8** %vtt) unnamed_addr
 //  CHECK-NOT: call
 //  CHECK: }
 
 // basic_iostream's base dtor calls its non-virtual base dtor.
-//  CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED2Ev(%struct.basic_iostream* {{.*}}%this, i8** %vtt) unnamed_addr
+//  CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED2Ev(%"struct.basic_iostream<char>"* {{.*}}%this, i8** %vtt) unnamed_addr
 //  CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev
 //  CHECK: }
Index: test/CodeGenCXX/value-init.cpp
===================================================================
--- test/CodeGenCXX/value-init.cpp
+++ test/CodeGenCXX/value-init.cpp
@@ -323,7 +323,7 @@
   return a.n;
 } // CHECK-LABEL: }
 
-// CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3<int>"* %this) unnamed_addr
 // CHECK: call void @llvm.memset.p0i8.i64
 // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
 // CHECK-NEXT: ret void
Index: test/CodeGenCXX/template-linkage.cpp
===================================================================
--- test/CodeGenCXX/template-linkage.cpp
+++ test/CodeGenCXX/template-linkage.cpp
@@ -40,7 +40,7 @@
 extern template struct X0<char>;
 extern template struct X1<char>;
 
-// CHECK-LABEL: define linkonce_odr void @_ZN2X1IcED1Ev(%struct.X1* %this) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN2X1IcED1Ev(%"struct.X1<char>"* %this) unnamed_addr
 void test_X1() {
   X1<char> i1c;
 }
Index: test/CodeGenCXX/template-instantiation.cpp
===================================================================
--- test/CodeGenCXX/template-instantiation.cpp
+++ test/CodeGenCXX/template-instantiation.cpp
@@ -18,7 +18,7 @@
 // CHECK2-NOT: _ZTVN5test31SIiEE
 // CHECK2-NOT: _ZTSN5test31SIiEE
 
-// CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* %this) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C<int>"* %this) unnamed_addr
 // CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
 // CHECK-LABEL: define available_externally void @_ZN5test21CIiE6zedbarEd(
 
Index: test/CodeGenCXX/template-anonymous-types.cpp
===================================================================
--- test/CodeGenCXX/template-anonymous-types.cpp
+++ test/CodeGenCXX/template-anonymous-types.cpp
@@ -27,10 +27,10 @@
   // Now check for the class template instantiations.
   //
   // BAR's instantiation of X:
-  // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt_EE1fEv(%struct.X* %this)
-  // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt_EEC2ES1_(%struct.X* %this, i32 %t) unnamed_addr
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt_EE1fEv(%"struct.X<S::(anonymous enum at {{.*}}template-anonymous-types.cpp:4:3)>"* %this)
+  // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt_EEC2ES1_(%"struct.X<S::(anonymous enum at {{.*}}template-anonymous-types.cpp:4:3)>"* %this, i32 %t) unnamed_addr
   //
   // FOO's instantiation of X:
-  // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt0_EE1fEv(%struct.X.0* %this)
-  // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt0_EEC2ES1_(%struct.X.0* %this, i32 %t) unnamed_addr
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt0_EE1fEv(%"struct.X<S::(anonymous enum at {{.*}}template-anonymous-types.cpp:5:3)>"* %this)
+  // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt0_EEC2ES1_(%"struct.X<S::(anonymous enum at {{.*}}template-anonymous-types.cpp:5:3)>"* %this, i32 %t) unnamed_addr
 }
Index: test/CodeGenCXX/static-init-3.cpp
===================================================================
--- test/CodeGenCXX/static-init-3.cpp
+++ test/CodeGenCXX/static-init-3.cpp
@@ -16,8 +16,8 @@
     }
 };
 
-// CHECK: @_ZN2X1I2X2I1BEE8instanceE = linkonce_odr global %struct.X2* null, align 8
-// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = linkonce_odr global %struct.X2* null, align 8
+// CHECK: @_ZN2X1I2X2I1BEE8instanceE = linkonce_odr global %"struct.X2<B>"* null, align 8
+// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = linkonce_odr global %"struct.X2<B>"* null, align 8
 template<class T> T & X1<T>::instance = X1<T>::get();
 
 class A { };
Index: test/CodeGenCXX/pr29160.cpp
===================================================================
--- test/CodeGenCXX/pr29160.cpp
+++ test/CodeGenCXX/pr29160.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -triple i686-linux-gnu %s -o /dev/null -S -emit-llvm
+// RUN: %clang_cc1 -std=c++11 -triple i686-linux-gnu %s -o /dev/null -S
 //
 // This test's failure mode is running ~forever. (For some value of "forever"
 // that's greater than 25 minutes on my machine)
Index: test/CodeGenCXX/noinline-template.cpp
===================================================================
--- test/CodeGenCXX/noinline-template.cpp
+++ test/CodeGenCXX/noinline-template.cpp
@@ -3,7 +3,7 @@
 // This was a problem in Sema, but only shows up as noinline missing
 // in CodeGen.
 
-// CHECK: define linkonce_odr {{.*}}void @_ZN6VectorIiE13growStorageByEv(%struct.Vector* %this) [[NI:#[0-9]+]]
+// CHECK: define linkonce_odr {{.*}}void @_ZN6VectorIiE13growStorageByEv(%"struct.Vector<int>"* %this) [[NI:#[0-9]+]]
 
 template <class Ty> struct Vector  {
   void growStorageBy();
Index: test/CodeGenCXX/ms-property.cpp
===================================================================
--- test/CodeGenCXX/ms-property.cpp
+++ test/CodeGenCXX/ms-property.cpp
@@ -58,56 +58,56 @@
   // CHECK: [[J:%.+]] = load i32, i32* %
   // CHECK-NEXT: call void @"\01?PutX@S@@QEAAXHHH@Z"(%class.S* %{{.+}}, i32 23, i32 1, i32 [[J]])
   p1->x[23][1] = j;
-  // CHECK: call float @"\01?GetX@?$St@M@@QEAAMMM@Z"(%class.St* %{{.+}}, float 2.230000e+02, float 1.100000e+01)
+  // CHECK: call float @"\01?GetX@?$St@M@@QEAAMMM@Z"(%"class.St<float>"* %{{.+}}, float 2.230000e+02, float 1.100000e+01)
   float j1 = p2->x[223][11];
   // CHECK: [[J1:%.+]] = load float, float* %
-  // CHECK-NEXT: [[CALL:%.+]] = call float @"\01?PutX@?$St@M@@QEAAMMMM@Z"(%class.St* %{{.+}}, float 2.300000e+01, float 1.000000e+00, float [[J1]])
+  // CHECK-NEXT: [[CALL:%.+]] = call float @"\01?PutX@?$St@M@@QEAAMMMM@Z"(%"class.St<float>"* %{{.+}}, float 2.300000e+01, float 1.000000e+00, float [[J1]])
   // CHECK-NEXT: [[CONV:%.+]] = fptosi float [[CALL]] to i32
   // CHECK-NEXT: store i32 [[CONV]], i32*
   argc = p2->x[23][1] = j1;
   // CHECK: [[IDX:%.+]] = call i32 @"\01?idx@@YAHXZ"()
   // CHECK-NEXT: [[CONV:%.+]] = sitofp i32 [[IDX]] to float
-  // CHECK-NEXT: [[GET:%.+]] = call float @"\01?GetX@?$St@M@@QEAAMMM@Z"(%class.St* %{{.+}}, float [[CONV]], float 1.000000e+00)
+  // CHECK-NEXT: [[GET:%.+]] = call float @"\01?GetX@?$St@M@@QEAAMMM@Z"(%"class.St<float>"* %{{.+}}, float [[CONV]], float 1.000000e+00)
   // CHECK-NEXT: [[INC:%.+]] = fadd float [[GET]], 1.000000e+00
   // CHECK-NEXT: [[CONV:%.+]] = sitofp i32 [[IDX]] to float
-  // CHECK-NEXT: call float @"\01?PutX@?$St@M@@QEAAMMMM@Z"(%class.St* %{{.+}}, float [[CONV]], float 1.000000e+00, float [[INC]])
+  // CHECK-NEXT: call float @"\01?PutX@?$St@M@@QEAAMMMM@Z"(%"class.St<float>"* %{{.+}}, float [[CONV]], float 1.000000e+00, float [[INC]])
   ++p2->x[idx()][1];
   // CHECK: call void @"\01??$foo@H@@YAXHH@Z"(i32 %{{.+}}, i32 %{{.+}})
   foo(argc, (int)argv[0][0]);
-  // CHECK: [[P2:%.+]] = load %class.St*, %class.St** %
+  // CHECK: [[P2:%.+]] = load %"class.St<float>"*, %"class.St<float>"** %
   // CHECK: [[T_X:%.+]] = call i32 @"\01?get_x@Test1@@QEBAHXZ"(%class.Test1* %{{.+}})
   // CHECK: [[P1:%.+]] = load %class.S*, %class.S** %
   // CHECK: [[P1_X_22_33:%.+]] = call i32 @"\01?GetX@S@@QEAAHHH@Z"(%class.S* [[P1]], i32 22, i32 33)
   // CHECK: [[CAST:%.+]] = sitofp i32 [[P1_X_22_33]] to double
   // CHECK: [[ARGC:%.+]] = load i32, i32* %
   // CHECK: [[CAST2:%.+]] = trunc i32 [[T_X]] to i8
-  // CHECK: call void @"\01?PutY@?$St@M@@QEAAXDHN@Z"(%class.St* [[P2]], i8 [[CAST2]], i32 [[ARGC]], double [[CAST]])
+  // CHECK: call void @"\01?PutY@?$St@M@@QEAAXDHN@Z"(%"class.St<float>"* [[P2]], i8 [[CAST2]], i32 [[ARGC]], double [[CAST]])
   p2->y[t.X][argc] =  p1->x[22][33];
-  // CHECK: [[P2_1:%.+]] = load %class.St*, %class.St**
-  // CHECK: [[P2_2:%.+]] = load %class.St*, %class.St**
+  // CHECK: [[P2_1:%.+]] = load %"class.St<float>"*, %"class.St<float>"**
+  // CHECK: [[P2_2:%.+]] = load %"class.St<float>"*, %"class.St<float>"**
   // CHECK: [[P1:%.+]] = load %class.S*, %class.S**
   // CHECK: [[ARGC:%.+]] = load i32, i32* %
   // CHECK: [[P1_X_ARGC_0:%.+]] = call i32 @"\01?GetX@S@@QEAAHHH@Z"(%class.S* [[P1]], i32 [[ARGC]], i32 0)
   // CHECK: [[CAST:%.+]] = trunc i32 [[P1_X_ARGC_0]] to i8
-  // CHECK: [[P2_Y_p1_X_ARGC_0_T:%.+]] = call i8 @"\01?GetY@?$St@M@@QEAADDVTest1@@@Z"(%class.St* [[P2_2]], i8 [[CAST]], %class.Test1* %{{.+}})
+  // CHECK: [[P2_Y_p1_X_ARGC_0_T:%.+]] = call i8 @"\01?GetY@?$St@M@@QEAADDVTest1@@@Z"(%"class.St<float>"* [[P2_2]], i8 [[CAST]], %class.Test1* %{{.+}})
   // CHECK: [[CAST:%.+]] = sitofp i8 [[P2_Y_p1_X_ARGC_0_T]] to float
   // CHECK: [[J:%.+]] = load i32, i32* %
   // CHECK: [[CAST1:%.+]] = sitofp i32 [[J]] to float
   // CHECK: [[J:%.+]] = load i32, i32* %
   // CHECK: [[CAST2:%.+]] = sitofp i32 [[J]] to float
-  // CHECK: call float @"\01?PutX@?$St@M@@QEAAMMMM@Z"(%class.St* [[P2_1]], float [[CAST2]], float [[CAST1]], float [[CAST]])
+  // CHECK: call float @"\01?PutX@?$St@M@@QEAAMMMM@Z"(%"class.St<float>"* [[P2_1]], float [[CAST2]], float [[CAST1]], float [[CAST]])
   p2->x[j][j] = p2->y[p1->x[argc][0]][t];
   // CHECK: [[CALL:%.+]] = call %class.Test1* @"\01?GetTest1@Test1@@SAPEAV1@XZ"()
   // CHECK-NEXT: call i32 @"\01?get_x@Test1@@QEBAHXZ"(%class.Test1* [[CALL]])
   return Test1::GetTest1()->X;
 }
 
 // CHECK: define linkonce_odr void @"\01??$foo@H@@YAXHH@Z"(i32 %{{.+}}, i32 %{{.+}})
-// CHECK: call i32 @"\01?GetX@?$St@H@@QEAAHHH@Z"(%class.St{{.+}}* [[BAR:%.+]], i32 %{{.+}} i32 %{{.+}})
-// CHECK: call i32 @"\01?PutX@?$St@H@@QEAAHHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}}, i32 %{{.+}}, i32 %{{.+}})
-// CHECK: call i32 @"\01?GetX@?$St@H@@QEAAHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}} i32 %{{.+}})
-// CHECK: call void @"\01?PutY@?$St@H@@QEAAXDHN@Z"(%class.St{{.+}}* [[BAR]], i8 %{{.+}}, i32 %{{.+}}, double %{{.+}}
-// CHECK: call i32 @"\01?GetX@?$St@H@@QEAAHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}} i32 %{{.+}})
-// CHECK: call i8 @"\01?GetY@?$St@H@@QEAADDVTest1@@@Z"(%class.St{{.+}}* [[BAR]], i8 %{{.+}}, %class.Test1* %{{.+}})
-// CHECK: call i32 @"\01?PutX@?$St@H@@QEAAHHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}}, i32 %{{.+}}, i32 %{{.+}})
+// CHECK: call i32 @"\01?GetX@?$St@H@@QEAAHHH@Z"(%"class.St{{.+}}"* [[BAR:%.+]], i32 %{{.+}} i32 %{{.+}})
+// CHECK: call i32 @"\01?PutX@?$St@H@@QEAAHHHH@Z"(%"class.St{{.+}}"* [[BAR]], i32 %{{.+}}, i32 %{{.+}}, i32 %{{.+}})
+// CHECK: call i32 @"\01?GetX@?$St@H@@QEAAHHH@Z"(%"class.St{{.+}}"* [[BAR]], i32 %{{.+}} i32 %{{.+}})
+// CHECK: call void @"\01?PutY@?$St@H@@QEAAXDHN@Z"(%"class.St{{.+}}"* [[BAR]], i8 %{{.+}}, i32 %{{.+}}, double %{{.+}}
+// CHECK: call i32 @"\01?GetX@?$St@H@@QEAAHHH@Z"(%"class.St{{.+}}"* [[BAR]], i32 %{{.+}} i32 %{{.+}})
+// CHECK: call i8 @"\01?GetY@?$St@H@@QEAADDVTest1@@@Z"(%"class.St{{.+}}"* [[BAR]], i8 %{{.+}}, %class.Test1* %{{.+}})
+// CHECK: call i32 @"\01?PutX@?$St@H@@QEAAHHHH@Z"(%"class.St{{.+}}"* [[BAR]], i32 %{{.+}}, i32 %{{.+}}, i32 %{{.+}})
 #endif //HEADER
Index: test/CodeGenCXX/microsoft-abi-vftables.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -49,7 +49,7 @@
 
 extern template class Y<int>;
 template Y<int>::Y();
-// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$Y@H@@6B@" to i8*), i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat($"\01??_7?$Y@H@@6B@")
+// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$Y@H@@6B@" to i8*), i8* bitcast (i8* (%"struct.Y<int>"*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat($"\01??_7?$Y@H@@6B@")
 // RTTI-DAG: @"\01??_7?$Y@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_Y]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat
+// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (i8* (%"struct.Y<int>"*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat
Index: test/CodeGenCXX/microsoft-abi-extern-template.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-extern-template.cpp
+++ test/CodeGenCXX/microsoft-abi-extern-template.cpp
@@ -4,16 +4,16 @@
 // own copy the vftable when emitting the available externally constructor.
 
 // CHECK: @"\01??_7?$Foo@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [
-// CHECK-SAME:   i8* bitcast (i8* (%struct.Foo*, i32)* @"\01??_G?$Foo@H@@UEAAPEAXI@Z" to i8*)
+// CHECK-SAME:   i8* bitcast (i8* (%"struct.Foo<int>"*, i32)* @"\01??_G?$Foo@H@@UEAAPEAXI@Z" to i8*)
 // CHECK-SAME: ] }, comdat
 
-// CHECK-LABEL: define %struct.Foo* @"\01?f@@YAPEAU?$Foo@H@@XZ"()
-// CHECK: call %struct.Foo* @"\01??0?$Foo@H@@QEAA@XZ"(%struct.Foo* %{{.*}})
+// CHECK-LABEL: define %"struct.Foo<int>"* @"\01?f@@YAPEAU?$Foo@H@@XZ"()
+// CHECK: call %"struct.Foo<int>"* @"\01??0?$Foo@H@@QEAA@XZ"(%"struct.Foo<int>"* %{{.*}})
 
-// CHECK: define available_externally %struct.Foo* @"\01??0?$Foo@H@@QEAA@XZ"(%struct.Foo* returned %this)
+// CHECK: define available_externally %"struct.Foo<int>"* @"\01??0?$Foo@H@@QEAA@XZ"(%"struct.Foo<int>"* returned %this)
 // CHECK:   store {{.*}} @"\01??_7?$Foo@H@@6B@"
 
-// CHECK: define linkonce_odr i8* @"\01??_G?$Foo@H@@UEAAPEAXI@Z"(%struct.Foo* %this, i32 %should_call_delete)
+// CHECK: define linkonce_odr i8* @"\01??_G?$Foo@H@@UEAAPEAXI@Z"(%"struct.Foo<int>"* %this, i32 %should_call_delete)
 
 struct Base {
   virtual ~Base();
Index: test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
+++ test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
@@ -57,4 +57,4 @@
 
 // Test that we mangle in the vbptr offset, which is 12 here.
 //
-// CHECK: define weak_odr x86_thiscallcc %struct.ClassTemplate* @"\01??0?$ClassTemplate@$J??_9MostGeneral@@$BA@AEA@M@3@@QAE@XZ"
+// CHECK: define weak_odr x86_thiscallcc %"struct.ClassTemplate<&MostGeneral::h>"* @"\01??0?$ClassTemplate@$J??_9MostGeneral@@$BA@AEA@M@3@@QAE@XZ"
Index: test/CodeGenCXX/mangle-abi-tag.cpp
===================================================================
--- test/CodeGenCXX/mangle-abi-tag.cpp
+++ test/CodeGenCXX/mangle-abi-tag.cpp
@@ -145,7 +145,7 @@
   f13();
 }
 // f13()::L::foo[abi:C][abi:D]()
-// CHECK-DAG: define linkonce_odr %struct.E* @_ZZ3f13vEN1L3fooB1CB1DEv(
+// CHECK-DAG: define linkonce_odr %"struct.E<int>"* @_ZZ3f13vEN1L3fooB1CB1DEv(
 
 // f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B]
 // CHECK-DAG: @_ZZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B =
Index: test/CodeGenCXX/float16-declarations.cpp
===================================================================
--- test/CodeGenCXX/float16-declarations.cpp
+++ test/CodeGenCXX/float16-declarations.cpp
@@ -110,10 +110,10 @@
 // CHECK-DAG:  call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
 
   S1<_Float16> s1 = { 132.f16 };
-// CHECK-AARCH64-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2
+// CHECK-AARCH64-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %"struct.S1<_Float16>" { half 0xH5820 }, align 2
 // CHECK-X86-DAG:     @_ZZ4mainE2s1 = private unnamed_addr constant { i16 } { i16 22560 }, align 2
-// CHECK-DAG:  [[S1:%[0-9]+]] = bitcast %struct.S1* %{{.*}} to i8*
-// CHECK-AARCH64-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[S1]], i8* bitcast (%struct.S1* @_ZZ4mainE2s1 to i8*), i64 2, i32 2, i1 false)
+// CHECK-DAG:  [[S1:%[0-9]+]] = bitcast %"struct.S1<_Float16>"* %{{.*}} to i8*
+// CHECK-AARCH64-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[S1]], i8* bitcast (%"struct.S1<_Float16>"* @_ZZ4mainE2s1 to i8*), i64 2, i32 2, i1 false)
 // CHECK-X86-DAG:     call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* bitcast ({ i16 }* @_ZZ4mainE2s1 to i8*), i64 2, i32 2, i1 false)
 
   _Float16 f4l = func1n(f1l)  + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
Index: test/CodeGenCXX/float128-declarations.cpp
===================================================================
--- test/CodeGenCXX/float128-declarations.cpp
+++ test/CodeGenCXX/float128-declarations.cpp
@@ -88,7 +88,7 @@
 // CHECK-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128 %arg)
 // CHECK-DAG: define linkonce_odr fp128 @_ZN2C16func2cEU10__float128(fp128 %arg)
 // CHECK-DAG: define linkonce_odr fp128 @_Z6func1tIU10__float128ET_S0_(fp128 %arg)
-// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %"struct.S1<__float128>" { fp128 0xL00000000000000004006080000000000 }
 // CHECK-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
 // CHECK-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
 // CHECK-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
@@ -110,7 +110,7 @@
 // CHECK-X86-DAG: define linkonce_odr void @_ZN2C1C2Eg(%class.C1* %this, fp128 %arg)
 // CHECK-X86-DAG: define linkonce_odr fp128 @_ZN2C16func2cEg(fp128 %arg)
 // CHECK-X86-DAG: define linkonce_odr fp128 @_Z6func1tIgET_S0_(fp128 %arg)
-// CHECK-X86-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-X86-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %"struct.S1<__float128>" { fp128 0xL00000000000000004006080000000000 }
 // CHECK-X86-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
 // CHECK-X86-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
 // CHECK-X86-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
@@ -132,7 +132,7 @@
 // CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128*
 // CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C16func2cEU10__float128(fp128*
 // CHECK-SYSZ-DAG: define linkonce_odr void @_Z6func1tIU10__float128ET_S0_(fp128*
-// CHECK-SYSZ-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-SYSZ-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %"struct.S1<__float128>" { fp128 0xL00000000000000004006080000000000 }
 // CHECK-SYSZ-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
 // CHECK-SYSZ-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
 // CHECK-SYSZ-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -820,16 +820,16 @@
 USECLASS(ExplicitInstantiationDeclImportedDefTemplate<int>);
 USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f);
 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ"
-// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclImportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ"
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %"struct.ExplicitInstantiationDeclImportedDefTemplate<int>"* @"\01??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ"
 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv
 
 template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} };
 extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>;
 template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate<int>;
 USECLASS(ExplicitInstantiationDeclExportedDefImportedTemplate<int>);
 USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate<int>, f);
 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ"
-// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefImportedTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ"
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %"struct.ExplicitInstantiationDeclExportedDefImportedTemplate<int>"* @"\01??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ"
 
 template <typename T> struct PR23770BaseTemplate { void f() {} };
 template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
Index: test/CodeGenCXX/dllexport.cpp
===================================================================
--- test/CodeGenCXX/dllexport.cpp
+++ test/CodeGenCXX/dllexport.cpp
@@ -564,7 +564,7 @@
 template <typename T> struct __declspec(dllexport) U { void foo() {} };
 struct __declspec(dllexport) V : public U<int> { };
 // U<int>'s assignment operator is emitted.
-// M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z"
+// M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %"struct.U<int>"* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z"
 
 struct __declspec(dllexport) W { virtual void foo(); };
 void W::foo() {}
@@ -701,13 +701,13 @@
 // Do not assert about generating code for constexpr functions twice during explicit instantiation (PR21718).
 template <typename T> struct ExplicitInstConstexprMembers {
   // Copy assignment operator
-  // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %struct.ExplicitInstConstexprMembers* @"\01??4?$ExplicitInstConstexprMembers@X@@QAEAAU0@ABU0@@Z"
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %"struct.ExplicitInstConstexprMembers<void>"* @"\01??4?$ExplicitInstConstexprMembers@X@@QAEAAU0@ABU0@@Z"
 
   constexpr ExplicitInstConstexprMembers() {}
-  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@XZ"
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.ExplicitInstConstexprMembers<void>"* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@XZ"
 
   ExplicitInstConstexprMembers(const ExplicitInstConstexprMembers&) = default;
-  // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@ABU0@@Z"
+  // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %"struct.ExplicitInstConstexprMembers<void>"* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@ABU0@@Z"
 
   constexpr int f() const { return 42; }
   // M32-DAG: define weak_odr dllexport x86_thiscallcc i32 @"\01?f@?$ExplicitInstConstexprMembers@X@@QBEHXZ"
@@ -729,7 +729,7 @@
 template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefTemplate<int>;
 USEMEMFUNC(ExplicitInstantiationDeclExportedDefTemplate<int>, f);
 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAEXXZ"
-// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ"
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.ExplicitInstantiationDeclExportedDefTemplate<int>"* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ"
 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv
 
 template <typename T> struct ImplicitInstantiationExportedExplicitInstantiationDefTemplate { virtual void f() {} };
@@ -780,7 +780,7 @@
 };
 Base<int> base;
 struct __declspec(dllexport) T : Base<int> { };
-// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Base"* @"\01??0?$Base@H@InClassInits@@QAE@XZ"
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Base<int>"* @"\01??0?$Base@H@InClassInits@@QAE@XZ"
 
 struct A { A(int); };
 struct __declspec(dllexport) U {
@@ -800,7 +800,7 @@
   // the default ctor must still be delayed.
   struct __declspec(dllexport) T : Base<int> {};
 };
-// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Evil::Base"* @"\01??0?$Base@H@Evil@InClassInits@@QAE@XZ"
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Evil::Base<int>"* @"\01??0?$Base@H@Evil@InClassInits@@QAE@XZ"
 
 template <typename T> struct Foo {};
 template <typename T> struct Bar {
Index: test/CodeGenCXX/dllexport-pr26549.cpp
===================================================================
--- test/CodeGenCXX/dllexport-pr26549.cpp
+++ test/CodeGenCXX/dllexport-pr26549.cpp
@@ -3,7 +3,7 @@
 template <typename> struct MessageT { };
 extern template struct MessageT<int>;
 
-// CHECK: define weak_odr dllexport {{.*}} %struct.MessageT* @"\01??4?$MessageT@H@@QEAAAEAU0@AEBU0@@Z"(
+// CHECK: define weak_odr dllexport {{.*}} %"struct.MessageT<int>"* @"\01??4?$MessageT@H@@QEAAAEAU0@AEBU0@@Z"(
 template struct __declspec(dllexport) MessageT<int>;
 // Previously we crashed when this dllexport was the last thing in the file.
 // DO NOT ADD MORE TESTS AFTER THIS LINE!
Index: test/CodeGenCXX/debug-info-template.cpp
===================================================================
--- test/CodeGenCXX/debug-info-template.cpp
+++ test/CodeGenCXX/debug-info-template.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s
 
 // CHECK: @tci = global %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]]
-// CHECK: @tcn = global %struct.TC zeroinitializer, align 1, !dbg [[TCN:![0-9]+]]
-// CHECK: @nn = global %struct.NN zeroinitializer, align 1, !dbg [[NN:![0-9]+]]
+// CHECK: @tcn = global %"struct.TC<int, -3, nullptr, nullptr, nullptr, nullptr>" zeroinitializer, align 1, !dbg [[TCN:![0-9]+]]
+// CHECK: @nn = global %"struct.NN<tmpl_impl, &glb, &glb>" zeroinitializer, align 1, !dbg [[NN:![0-9]+]]
 
 // CHECK: !DICompileUnit(
 // CHECK: [[EMPTY:![0-9]*]] = !{}
Index: test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
===================================================================
--- test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -517,13 +517,13 @@
   void f1() {
     // CHECK-LABEL: @_ZN9B197730102f1Ev
     testcase a{{"", ENUM_CONSTANT}};
-    // X86: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** %{{.*}}, align 8
-    // AMD: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* addrspacecast{{.*}} bitcast ([1 x { i8*, i32 }] addrspace(2)* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair"] addrspace(2)*){{.*}}, i64 0, i64 0), %"struct.B19773010::pair"** %{{.*}}, align 8
+    // X86: store %"struct.B19773010::pair<const char *, B19773010::E>"* getelementptr inbounds ([1 x %"struct.B19773010::pair<const char *, B19773010::E>"], [1 x %"struct.B19773010::pair<const char *, B19773010::E>"]* bitcast ([1 x { i8*, i32 }]* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair<const char *, B19773010::E>"]*), i64 0, i64 0), %"struct.B19773010::pair<const char *, B19773010::E>"** %{{.*}}, align 8
+    // AMD: store %"struct.B19773010::pair<const char *, B19773010::E>"* getelementptr inbounds ([1 x %"struct.B19773010::pair<const char *, B19773010::E>"], [1 x %"struct.B19773010::pair<const char *, B19773010::E>"]* addrspacecast{{.*}} bitcast ([1 x { i8*, i32 }] addrspace(2)* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair<const char *, B19773010::E>"] addrspace(2)*){{.*}}, i64 0, i64 0), %"struct.B19773010::pair<const char *, B19773010::E>"** %{{.*}}, align 8
   }
   void f2() {
     // CHECK-LABEL: @_ZN9B197730102f2Ev
-    // X86: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** getelementptr inbounds ([2 x %"class.std::initializer_list.10"], [2 x %"class.std::initializer_list.10"]* @_ZZN9B197730102f2EvE1p, i64 0, i64 1, i32 0), align 16
-    // AMD: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* addrspacecast{{.*}} bitcast ([1 x { i8*, i32 }] addrspace(1)* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair"] addrspace(1)*){{.*}}, i64 0, i64 0), %"struct.B19773010::pair"** getelementptr inbounds ([2 x %"class.std::initializer_list.10"], [2 x %"class.std::initializer_list.10"]* addrspacecast{{.*}}@_ZZN9B197730102f2EvE1p{{.*}}, i64 0, i64 1, i32 0), align 8
+    // X86: store %"struct.B19773010::pair<const char *, B19773010::E>"* getelementptr inbounds ([1 x %"struct.B19773010::pair<const char *, B19773010::E>"], [1 x %"struct.B19773010::pair<const char *, B19773010::E>"]* bitcast ([1 x { i8*, i32 }]* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair<const char *, B19773010::E>"]*), i64 0, i64 0), %"struct.B19773010::pair<const char *, B19773010::E>"** getelementptr inbounds ([2 x %"class.std::initializer_list<B19773010::pair<const char *, B19773010::E> >"], [2 x %"class.std::initializer_list<B19773010::pair<const char *, B19773010::E> >"]* @_ZZN9B197730102f2EvE1p, i64 0, i64 1, i32 0), align 16
+    // AMD: store %"struct.B19773010::pair<const char *, B19773010::E>"* getelementptr inbounds ([1 x %"struct.B19773010::pair<const char *, B19773010::E>"], [1 x %"struct.B19773010::pair<const char *, B19773010::E>"]* addrspacecast{{.*}} bitcast ([1 x { i8*, i32 }] addrspace(1)* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair<const char *, B19773010::E>"] addrspace(1)*){{.*}}, i64 0, i64 0), %"struct.B19773010::pair<const char *, B19773010::E>"** getelementptr inbounds ([2 x %"class.std::initializer_list<B19773010::pair<const char *, B19773010::E> >"], [2 x %"class.std::initializer_list<B19773010::pair<const char *, B19773010::E> >"]* addrspacecast{{.*}}@_ZZN9B197730102f2EvE1p{{.*}}, i64 0, i64 1, i32 0), align 8
     static std::initializer_list<pair<const char *, E>> a, p[2] =
         {a, {{"", ENUM_CONSTANT}}};
   }
Index: test/CodeGenCXX/ctor-dtor-alias.cpp
===================================================================
--- test/CodeGenCXX/ctor-dtor-alias.cpp
+++ test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -15,7 +15,7 @@
 // weak_odr constructors and destructors.
 
 // CHECK1: @_ZN5test16foobarIvEC1Ev = weak_odr alias void {{.*}} @_ZN5test16foobarIvEC2Ev
-// CHECK1: @_ZN5test16foobarIvED1Ev = weak_odr alias void (%"struct.test1::foobar"*), void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvED2Ev
+// CHECK1: @_ZN5test16foobarIvED1Ev = weak_odr alias void (%"struct.test1::foobar<void>"*), void (%"struct.test1::foobar<void>"*)* @_ZN5test16foobarIvED2Ev
 // CHECK1: define weak_odr void @_ZN5test16foobarIvEC2Ev({{.*}} comdat($_ZN5test16foobarIvEC5Ev)
 // CHECK1: define weak_odr void @_ZN5test16foobarIvED2Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
 // CHECK1: define weak_odr void @_ZN5test16foobarIvED0Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
Index: test/CodeGenCXX/constructor-init.cpp
===================================================================
--- test/CodeGenCXX/constructor-init.cpp
+++ test/CodeGenCXX/constructor-init.cpp
@@ -163,7 +163,7 @@
 
 // Make sure that the instantiated constructor initializes start and
 // end properly.
-// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}}) %other) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%"struct.X<int>"* %this, %"struct.X<int>"* dereferenceable({{[0-9]+}}) %other) unnamed_addr
 // CHECK: {{store.*null}}
 // CHECK: {{store.*null}}
 // CHECK: ret
Index: test/CodeGenCXX/const-init-cxx11.cpp
===================================================================
--- test/CodeGenCXX/const-init-cxx11.cpp
+++ test/CodeGenCXX/const-init-cxx11.cpp
@@ -608,4 +608,4 @@
 
 // VirtualMembers::TemplateClass::templateMethod() must be defined in this TU,
 // not just declared.
-// CHECK: define linkonce_odr void @_ZN14VirtualMembers13TemplateClassIiE14templateMethodEv(%"struct.VirtualMembers::TemplateClass"* %this)
+// CHECK: define linkonce_odr void @_ZN14VirtualMembers13TemplateClassIiE14templateMethodEv(%"struct.VirtualMembers::TemplateClass<int>"* %this)
Index: test/CodeGenCXX/captured-statements.cpp
===================================================================
--- test/CodeGenCXX/captured-statements.cpp
+++ test/CodeGenCXX/captured-statements.cpp
@@ -145,15 +145,15 @@
 
   // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
   // CHECK-5-NOT: }
-  // CHECK-5: store %class.Val*
+  // CHECK-5: store %"class.Val<float, 202>"*
   // CHECK-5: call void @__captured_stmt
   // CHECK-5-NEXT: ret void
   Val<float, 202> Obj;
   Obj.set();
 
   // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
   // CHECK-5-NOT: }
-  // CHECK-5: store %class.Val*
+  // CHECK-5: store %"class.Val<float, 202>"*
   // CHECK-5: store double
   // CHECK-5: call void @__captured_stmt
   // CHECK-5-NEXT: ret void
Index: test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
===================================================================
--- test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
+++ test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -disable-O0-optnone -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x i8*] } { [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x i8*] } { [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%"struct.Templ<int>"*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%"struct.Templ<int>"*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%"struct.Templ<int>"*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%"struct.Templ<int>"*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
 
 struct B1 { 
   virtual ~B1(); 
@@ -42,7 +42,7 @@
   t->Templ::~Templ();
 }
 
-// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [7 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
-// CHECK: declare void @_ZN5TemplIiED0Ev(%struct.Templ*)
-// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
-// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
+// CHECK: getelementptr inbounds (void (%"struct.Templ<int>"*)*, void (%"struct.Templ<int>"*)** bitcast ({ [7 x i8*] }* @_ZTV5TemplIiE to void (%"struct.Templ<int>"*)**), i64 2)
+// CHECK: declare void @_ZN5TemplIiED0Ev(%"struct.Templ<int>"*)
+// CHECK: define internal void @_ZN5TemplIiE1fEv(%"struct.Templ<int>"* %this)
+// CHECK: define internal void @_ZN5TemplIiE1gEv(%"struct.Templ<int>"* %this)
Index: test/CodeGenCXX/apple-kext-indirect-call.cpp
===================================================================
--- test/CodeGenCXX/apple-kext-indirect-call.cpp
+++ test/CodeGenCXX/apple-kext-indirect-call.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%"struct.Templ<int>"*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%"struct.Templ<int>"*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
 
 struct Base { 
   virtual void abc(void) const; 
@@ -37,6 +37,6 @@
   t->Templ::f();
 }
 
-// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [5 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
-// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
-// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
+// CHECK: getelementptr inbounds (void (%"struct.Templ<int>"*)*, void (%"struct.Templ<int>"*)** bitcast ({ [5 x i8*] }* @_ZTV5TemplIiE to void (%"struct.Templ<int>"*)**), i64 2)
+// CHECK: define internal void @_ZN5TemplIiE1fEv(%"struct.Templ<int>"* %this)
+// CHECK: define internal void @_ZN5TemplIiE1gEv(%"struct.Templ<int>"* %this)
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -778,6 +778,19 @@
     }
   }
 
+  if (Arg *A = Args.getLastArg(OPT_ir_type_names_EQ)) {
+    StringRef Name = A->getValue();
+    auto Info = llvm::StringSwitch<CodeGenOptions::IRNameKind>(Name)
+        .Case("terse", CodeGenOptions::IRNameKind::Terse)
+        .Case("full", CodeGenOptions::IRNameKind::Full)
+        .Default(CodeGenOptions::IRNameKind::Unspecified);
+    if (Info == CodeGenOptions::IRNameKind::Unspecified) {
+      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+      Success = false;
+    } else
+      Opts.setIRTypeNames(Info);
+  }
+
   Opts.PreserveVec3Type = Args.hasArg(OPT_fpreserve_vec3_type);
   Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
   Opts.InstrumentFunctionsAfterInlining =
Index: lib/CodeGen/CodeGenTypes.cpp
===================================================================
--- lib/CodeGen/CodeGenTypes.cpp
+++ lib/CodeGen/CodeGenTypes.cpp
@@ -54,7 +54,7 @@
   SmallString<256> TypeName;
   llvm::raw_svector_ostream OS(TypeName);
   OS << RD->getKindName() << '.';
-  
+
   // Name the codegen type after the typedef name
   // if there is no tag type name available
   if (RD->getIdentifier()) {
@@ -64,6 +64,12 @@
       RD->printQualifiedName(OS);
     else
       RD->printName(OS);
+    if (getCodeGenOpts().getIRTypeNames() == CodeGenOptions::IRNameKind::Full)
+      if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
+        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+        TemplateSpecializationType::PrintTemplateArgumentList(
+            OS, TemplateArgs.asArray(), RD->getASTContext().getPrintingPolicy());
+      }
   } else if (const TypedefNameDecl *TDD = RD->getTypedefNameForAnonDecl()) {
     // FIXME: We should not have to check for a null decl context here.
     // Right now we do it because the implicit Obj-C decls don't have one.
Index: lib/CodeGen/CodeGenAction.cpp
===================================================================
--- lib/CodeGen/CodeGenAction.cpp
+++ lib/CodeGen/CodeGenAction.cpp
@@ -884,6 +884,17 @@
                                     std::unique_ptr<PPCallbacks>(CoverageInfo));
   }
 
+  // If IR representation can be used in linking, types in it must have
+  // full names.
+  if (CI.getCodeGenOpts().getIRTypeNames()
+          == CodeGenOptions::IRNameKind::Unspecified &&
+      (BA == Backend_EmitBC ||
+       BA == Backend_EmitLL ||
+       (BA == Backend_EmitObj &&
+        CI.getCodeGenOpts().getEmbedBitcode() != CodeGenOptions::Embed_Off) ||
+       !LinkModules.empty()))
+    CI.getCodeGenOpts().setIRTypeNames(CodeGenOptions::IRNameKind::Full);
+
   std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
       BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
       CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
Index: include/clang/Frontend/CodeGenOptions.h
===================================================================
--- include/clang/Frontend/CodeGenOptions.h
+++ include/clang/Frontend/CodeGenOptions.h
@@ -106,6 +106,18 @@
     Embed_Marker    // Embed a marker as a placeholder for bitcode.
   };
 
+  /// Describes what kind of names should be specified for LLVM IR objects.
+  ///
+  /// For example, LLVM structure types corresponding to template class
+  /// specializations may be assigned names with template arguments (as
+  /// "struct.Foo<int>") or name with only version suffix (as "Foo.123").
+  ///
+  enum class IRNameKind {
+    Unspecified,    ///< No special option was passed.
+    Terse,          ///< Only minimal name.
+    Full,           ///< Full names (with template parameters).
+  };
+
   /// The code model to use (-mcmodel).
   std::string CodeModel;
 
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -71,6 +71,11 @@
 CODEGENOPT(EmulatedTLS       , 1, 0) ///< Set when -femulated-tls is enabled.
 /// \brief Embed Bitcode mode (off/all/bitcode/marker).
 ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off)
+
+/// What kind of names should be specified for LLVM IR objects.
+/// \see CodeGenOptions::IRNameKind.
+ENUM_CODEGENOPT(IRTypeNames, IRNameKind, 4, IRNameKind::Unspecified)
+
 CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
                                         ///< are required.
 CODEGENOPT(FunctionSections  , 1, 0) ///< Set when -ffunction-sections is enabled.
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1661,6 +1661,10 @@
     MetaVarName<"<file>">, HelpText<"Include file before parsing">, Flags<[CC1Option]>;
 def include_pch : Separate<["-"], "include-pch">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Include precompiled header file">, MetaVarName<"<file>">;
+def ir_type_names_EQ : Joined<["--"], "ir-type-names=">,
+  Flags<[CC1Option, HelpHidden]>,
+  HelpText<"Encoding of IR type names (option: terse, full)">,
+  Values<"terse,full">;
 def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, Flags<[CC1Option]>,
   HelpText<"Whether to build a relocatable precompiled header">;
 def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>, Flags<[CC1Option]>,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D40567: A... Serge Pavlov via Phabricator via cfe-commits

Reply via email to