rsmith created this revision.
rsmith added reviewers: rjmccall, v.g.vassilev, bruno.
Herald added subscribers: cfe-commits, javed.absar.

Previously, we expected Sema to make this ABI decision for us, resulting
in our emitting vtables in some cases where we didn't need them. With
this change, we emit vtables in precisely three cases:

1. When we emit a reference to the vtable and it has suitable linkage.
2. When we emit a key function definition.
3. When we emit an explicit instantiation of a class.

This also removes the need to mark key functions as "must be emitted",
which means that an inline key function is no longer added to the list
of eagerly deserialized declarations in an AST file.

In exchange, we do now list explicit instantiation definitions of
dynamic classes as eagerly deserialized declarations. But they should
be much rarer in header files!


Repository:
  rC Clang

https://reviews.llvm.org/D54986

Files:
  lib/AST/ASTContext.cpp
  lib/AST/RecordLayoutBuilder.cpp
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGVTables.cpp
  lib/CodeGen/CodeGenAction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  lib/CodeGen/ModuleBuilder.cpp
  lib/Serialization/ASTReaderDecl.cpp
  test/CodeGenCXX/aarch64-cxxabi.cpp
  test/CodeGenCXX/key-function-vtable.cpp
  test/CodeGenCXX/rtti-linkage.cpp
  test/CodeGenCXX/type_visibility.cpp
  test/CodeGenCXX/visibility.cpp
  test/CodeGenCXX/vtt-layout.cpp

Index: test/CodeGenCXX/vtt-layout.cpp
===================================================================
--- test/CodeGenCXX/vtt-layout.cpp
+++ test/CodeGenCXX/vtt-layout.cpp
@@ -78,12 +78,12 @@
   }
 }
 
-// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5Test11BE, i32 0, inrange i32 0, i32 3) to i8*)]
-// CHECK: @_ZTVN5Test51AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)] }
-// CHECK: @_ZTVN5Test61AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)] }
-// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*)]
-// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 0, i32 5) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*)]
-// CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr constant { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] } { [6 x i8*] [i8* inttoptr (i64 72 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 56 to i8*), i8* inttoptr (i64 40 to i8*), i8* null, i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [8 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 56 to i8*), i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::V3"*)* @_ZN5Test42V31gEv to i8*)], [3 x i8*] [i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -40 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [4 x i8*] [i8* null, i8* inttoptr (i64 -56 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::A2"*)* @_ZN5Test42A21fEv to i8*)], [4 x i8*] [i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -32 to i8*), i8* inttoptr (i64 -72 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)] }
-// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 1, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 4, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 2, i32 3) to i8*)]
+// CHECK-DAG: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5Test11BE, i32 0, inrange i32 0, i32 3) to i8*)]
+// CHECK-DAG: @_ZTVN5Test51AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)] }
+// CHECK-DAG: @_ZTVN5Test61AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)] }
+// CHECK-DAG: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*)]
+// CHECK-DAG: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 0, i32 5) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*)]
+// CHECK-DAG: @_ZTVN5Test41DE = linkonce_odr unnamed_addr constant { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] } { [6 x i8*] [i8* inttoptr (i64 72 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 56 to i8*), i8* inttoptr (i64 40 to i8*), i8* null, i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [8 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 56 to i8*), i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::V3"*)* @_ZN5Test42V31gEv to i8*)], [3 x i8*] [i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -40 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [4 x i8*] [i8* null, i8* inttoptr (i64 -56 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::A2"*)* @_ZN5Test42A21fEv to i8*)], [4 x i8*] [i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -32 to i8*), i8* inttoptr (i64 -72 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)] }
+// CHECK-DAG: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 1, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 4, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 2, i32 3) to i8*)]
 // CHECK: declare void @__cxa_pure_virtual() unnamed_addr
 // CHECK: declare void @__cxa_deleted_virtual() unnamed_addr
Index: test/CodeGenCXX/visibility.cpp
===================================================================
--- test/CodeGenCXX/visibility.cpp
+++ test/CodeGenCXX/visibility.cpp
@@ -101,6 +101,25 @@
   // CHECK-HIDDEN: _ZN6test481yE = hidden global
 }
 
+namespace test27 {
+  template<typename T>
+  class C {
+    class DEFAULT D {
+      void f();
+    };
+  };
+
+  template<>
+  class C<int>::D {
+    virtual void g();
+  };
+
+  void C<int>::D::g() {
+  }
+  // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
+  // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
+}
+
 // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
 // CHECK: @_ZN5Test71aE = hidden global
 // CHECK: @_ZN5Test71bE = global
@@ -119,25 +138,6 @@
 // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
 // CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
 
-namespace test27 {
-  template<typename T>
-  class C {
-    class DEFAULT D {
-      void f();
-    };
-  };
-
-  template<>
-  class C<int>::D {
-    virtual void g();
-  };
-
-  void C<int>::D::g() {
-  }
-  // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
-  // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
-}
-
 // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
 
 // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
Index: test/CodeGenCXX/type_visibility.cpp
===================================================================
--- test/CodeGenCXX/type_visibility.cpp
+++ test/CodeGenCXX/type_visibility.cpp
@@ -27,13 +27,13 @@
 
   template struct B<A>;
   // FUNS-LABEL:        define weak_odr void @_ZN5temp01BINS_1AEE3fooEv(
-  // VARS:        @_ZTVN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
-  // VARS:        @_ZTSN5temp01BINS_1AEEE = weak_odr constant
-  // VARS:        @_ZTIN5temp01BINS_1AEEE = weak_odr constant
+  // VARS-DAG:          @_ZTVN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5temp01BINS_1AEEE = weak_odr constant
+  // VARS-DAG:          @_ZTIN5temp01BINS_1AEEE = weak_odr constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp01BINS_1AEE3fooEv(
-  // VARS-HIDDEN: @_ZTVN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5temp01BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp01BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5temp01BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5temp01BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace temp1 {
@@ -44,13 +44,13 @@
 
   template struct B<A>;
   // FUNS-LABEL:        define weak_odr void @_ZN5temp11BINS_1AEE3fooEv(
-  // VARS:        @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
-  // VARS:        @_ZTSN5temp11BINS_1AEEE = weak_odr constant
-  // VARS:        @_ZTIN5temp11BINS_1AEEE = weak_odr constant
+  // VARS-DAG:          @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5temp11BINS_1AEEE = weak_odr constant
+  // VARS-DAG:          @_ZTIN5temp11BINS_1AEEE = weak_odr constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp11BINS_1AEE3fooEv(
-  // VARS-HIDDEN: @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5temp11BINS_1AEEE = weak_odr constant
-  // VARS-HIDDEN: @_ZTIN5temp11BINS_1AEEE = weak_odr constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5temp11BINS_1AEEE = weak_odr constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5temp11BINS_1AEEE = weak_odr constant
 }
 
 namespace temp2 {
@@ -61,13 +61,13 @@
 
   template struct B<A>;
   // FUNS-LABEL:        define weak_odr void @_ZN5temp21BINS_1AEE3fooEv(
-  // VARS:        @_ZTVN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
-  // VARS:        @_ZTSN5temp21BINS_1AEEE = weak_odr constant
-  // VARS:        @_ZTIN5temp21BINS_1AEEE = weak_odr constant
+  // VARS-DAG:          @_ZTVN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5temp21BINS_1AEEE = weak_odr constant
+  // VARS-DAG:          @_ZTIN5temp21BINS_1AEEE = weak_odr constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp21BINS_1AEE3fooEv(
-  // VARS-HIDDEN: @_ZTVN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5temp21BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp21BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5temp21BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5temp21BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace temp3 {
@@ -78,13 +78,13 @@
 
   template struct B<A>;
   // FUNS-LABEL:        define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
-  // VARS:        @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
-  // VARS:        @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
-  // VARS:        @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
+  // VARS-DAG:          @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
+  // VARS-DAG:          @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
-  // VARS-HIDDEN: @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace temp4 {
@@ -95,13 +95,13 @@
 
   template struct B<A>;
   // FUNS-LABEL:        define weak_odr void @_ZN5temp41BINS_1AEE3fooEv(
-  // VARS:        @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
-  // VARS:        @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
-  // VARS:        @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
+  // VARS-DAG:          @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
+  // VARS-DAG:          @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp41BINS_1AEE3fooEv(
-  // VARS-HIDDEN: @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace type0 {
@@ -111,13 +111,13 @@
 
   void A::foo() {}
   // FUNS-LABEL:        define void @_ZN5type01A3fooEv(
-  // VARS:        @_ZTVN5type01AE = unnamed_addr constant
-  // VARS:        @_ZTSN5type01AE = constant
-  // VARS:        @_ZTIN5type01AE = constant
+  // VARS-DAG:          @_ZTVN5type01AE = unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5type01AE = constant
+  // VARS-DAG:          @_ZTIN5type01AE = constant
   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type01A3fooEv(
-  // VARS-HIDDEN: @_ZTVN5type01AE = unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5type01AE = constant
-  // VARS-HIDDEN: @_ZTIN5type01AE = constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5type01AE = unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5type01AE = constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5type01AE = constant
 }
 
 namespace type1 {
@@ -127,13 +127,13 @@
 
   void A::foo() {}
   // FUNS-LABEL:        define hidden void @_ZN5type11A3fooEv(
-  // VARS:        @_ZTVN5type11AE = unnamed_addr constant
-  // VARS:        @_ZTSN5type11AE = constant
-  // VARS:        @_ZTIN5type11AE = constant
+  // VARS-DAG:          @_ZTVN5type11AE = unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5type11AE = constant
+  // VARS-DAG:          @_ZTIN5type11AE = constant
   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type11A3fooEv(
-  // VARS-HIDDEN: @_ZTVN5type11AE = unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5type11AE = constant
-  // VARS-HIDDEN: @_ZTIN5type11AE = constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5type11AE = unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5type11AE = constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5type11AE = constant
 }
 
 namespace type2 {
@@ -143,13 +143,13 @@
 
   void A::foo() {}
   // FUNS-LABEL:        define void @_ZN5type21A3fooEv(
-  // VARS:        @_ZTVN5type21AE = hidden unnamed_addr constant
-  // VARS:        @_ZTSN5type21AE = hidden constant
-  // VARS:        @_ZTIN5type21AE = hidden constant
+  // VARS-DAG:          @_ZTVN5type21AE = hidden unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5type21AE = hidden constant
+  // VARS-DAG:          @_ZTIN5type21AE = hidden constant
   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type21A3fooEv(
-  // VARS-HIDDEN: @_ZTVN5type21AE = hidden unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5type21AE = hidden constant
-  // VARS-HIDDEN: @_ZTIN5type21AE = hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5type21AE = hidden unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5type21AE = hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5type21AE = hidden constant
 }
 
 namespace type3 {
@@ -159,12 +159,12 @@
 
   void A::foo() {}
   // FUNS-LABEL:        define void @_ZN5type31A3fooEv(
-  // VARS:        @_ZTVN5type31AE = hidden unnamed_addr constant
-  // VARS:        @_ZTSN5type31AE = hidden constant
-  // VARS:        @_ZTIN5type31AE = hidden constant
+  // VARS-DAG:          @_ZTVN5type31AE = hidden unnamed_addr constant
+  // VARS-DAG:          @_ZTSN5type31AE = hidden constant
+  // VARS-DAG:          @_ZTIN5type31AE = hidden constant
   // FUNS-HIDDEN-LABEL: define void @_ZN5type31A3fooEv(
-  // VARS-HIDDEN: @_ZTVN5type31AE = hidden unnamed_addr constant
-  // VARS-HIDDEN: @_ZTSN5type31AE = hidden constant
-  // VARS-HIDDEN: @_ZTIN5type31AE = hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTVN5type31AE = hidden unnamed_addr constant
+  // VARS-HIDDEN-DAG:   @_ZTSN5type31AE = hidden constant
+  // VARS-HIDDEN-DAG:   @_ZTIN5type31AE = hidden constant
 }
 
Index: test/CodeGenCXX/rtti-linkage.cpp
===================================================================
--- test/CodeGenCXX/rtti-linkage.cpp
+++ test/CodeGenCXX/rtti-linkage.cpp
@@ -115,6 +115,7 @@
 };
 
 inline void F::f() { }
+void use_F_key_function(F &f) { f.F::f(); }
 const D getD();
 
 const std::type_info &t2() {
Index: test/CodeGenCXX/key-function-vtable.cpp
===================================================================
--- test/CodeGenCXX/key-function-vtable.cpp
+++ test/CodeGenCXX/key-function-vtable.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-none-linux-gnu %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple arm-apple-darwin %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-none-linux-gnu %s -emit-llvm -o - | FileCheck %s --implicit-check-not=@_ZTV5testc
+// RUN: %clang_cc1 -triple arm-apple-darwin %s -emit-llvm -o - | FileCheck %s --implicit-check-not=@_ZTV5testc
 
 // Simple key function test
 struct testa { virtual void a(); };
@@ -10,6 +10,7 @@
 testb *testbvar = new testb;
 
 // Key function with out-of-line inline definition
+// Key function is not emitted, so vtable is also not emitted.
 struct testc { virtual void a(); };
 inline void testc::a() {}
 
@@ -34,6 +35,18 @@
 void testg::a() {}
 testg *testgvar = new testg;
 
+// Key function with out-of-line inline definition
+// Key function is emitted, so vtable is emitted.
+struct testh { virtual void a(); void b(); };
+inline void testh::a() {}
+void testh::b() { testh::a(); }
+
+// Key function with out-of-line inline definition
+// VTable is used, so is emitted.
+struct testi { virtual void a(); };
+inline void testi::a() {}
+void use_i() { testi ti; }
+
 struct X0 { virtual ~X0(); };
 struct X1 : X0 {
   virtual void f();
@@ -45,7 +58,8 @@
 
 // CHECK-DAG: @_ZTV2X1 = linkonce_odr unnamed_addr constant
 // CHECK-DAG: @_ZTV5testa = unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
 // CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
 // CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
 // CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testh = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testi = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
Index: test/CodeGenCXX/aarch64-cxxabi.cpp
===================================================================
--- test/CodeGenCXX/aarch64-cxxabi.cpp
+++ test/CodeGenCXX/aarch64-cxxabi.cpp
@@ -19,13 +19,37 @@
 // CHECK: @_ZTV16CheckKeyFunction =
 struct CheckKeyFunction {
   virtual void foo();
+  void bar();
 };
 
 // This is not inline when CheckKeyFunction is completed, so
-// CheckKeyFunction::foo is the key function. VTables should be emitted.
+// CheckKeyFunction::foo is the key function. VTables should be emitted
+// if CheckKeyFunction::foo is emitted.
 inline void CheckKeyFunction::foo() {
 }
 
+void CheckKeyFunction::bar() {
+  // Explicit use triggers emission of foo, which triggers emission of vtable.
+  CheckKeyFunction::foo();
+}
+
+// CHECK-NOT: @_ZTV22CheckKeyFunctionUnused =
+struct CheckKeyFunctionUnused {
+  virtual void foo();
+};
+inline void CheckKeyFunctionUnused::foo() {
+}
+
+// CHECK: @_ZTV14CheckVTableUse =
+// Check that using the vtable is enough to trigger emission of the key
+// function and thus the vtable.
+struct CheckVTableUse {
+  virtual void foo();
+};
+inline void CheckVTableUse::foo() {
+}
+void *useVTable() { return new CheckVTableUse; }
+
 ////////////////////////////////////////////////////////////////////////////////
 
 // Guard variables only specify and use the low bit to determine status, rather
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -2771,6 +2771,10 @@
       return false;
   }
 
+  if (auto *ES = D->getASTContext().getExternalSource())
+    if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never)
+      return true;
+
   if (isa<FileScopeAsmDecl>(D) ||
       isa<ObjCProtocolDecl>(D) ||
       isa<ObjCImplDecl>(D) ||
@@ -2786,10 +2790,9 @@
             OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Var));
   if (const auto *Func = dyn_cast<FunctionDecl>(D))
     return Func->doesThisDeclarationHaveABody() || HasBody;
-
-  if (auto *ES = D->getASTContext().getExternalSource())
-    if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never)
-      return true;
+  if (const auto *RD = dyn_cast<CXXRecordDecl>(D))
+    return RD->getTemplateSpecializationKind() ==
+           TSK_ExplicitInstantiationDefinition;
 
   return false;
 }
Index: lib/CodeGen/ModuleBuilder.cpp
===================================================================
--- lib/CodeGen/ModuleBuilder.cpp
+++ lib/CodeGen/ModuleBuilder.cpp
@@ -276,13 +276,6 @@
 
       Builder->EmitTentativeDefinition(D);
     }
-
-    void HandleVTable(CXXRecordDecl *RD) override {
-      if (Diags.hasErrorOccurred())
-        return;
-
-      Builder->EmitVTable(RD);
-    }
   };
 }
 
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -292,6 +292,8 @@
   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
                                         CharUnits VPtrOffset) override;
 
+  void emitVTables(const CXXRecordDecl *RD) override;
+
   CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
                                      Address This, llvm::Type *Ty,
                                      SourceLocation Loc) override;
@@ -1710,23 +1712,7 @@
   MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
   const VPtrInfoVector &VFPtrs = VTContext.getVFPtrOffsets(RD);
 
-  if (DeferredVFTables.insert(RD).second) {
-    // We haven't processed this record type before.
-    // Queue up this vtable for possible deferred emission.
-    CGM.addDeferredVTable(RD);
-
-#ifndef NDEBUG
-    // Create all the vftables at once in order to make sure each vftable has
-    // a unique mangled name.
-    llvm::StringSet<> ObservedMangledNames;
-    for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
-      SmallString<256> Name;
-      mangleVFTableName(getMangleContext(), RD, *VFPtrs[J], Name);
-      if (!ObservedMangledNames.insert(Name.str()).second)
-        llvm_unreachable("Already saw this mangling before?");
-    }
-#endif
-  }
+  emitVTables(RD);
 
   const std::unique_ptr<VPtrInfo> *VFPtrI = std::find_if(
       VFPtrs.begin(), VFPtrs.end(), [&](const std::unique_ptr<VPtrInfo>& VPI) {
@@ -1829,6 +1815,29 @@
   return VTable;
 }
 
+void MicrosoftCXXABI::emitVTables(const CXXRecordDecl *RD) {
+  if (DeferredVFTables.insert(RD).second) {
+    // We haven't processed this record type before.
+    // Queue up this vtable for possible deferred emission.
+    CGM.addDeferredVTable(RD);
+
+#ifndef NDEBUG
+    MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
+    const VPtrInfoVector &VFPtrs = VTContext.getVFPtrOffsets(RD);
+
+    // Create all the vftables at once in order to make sure each vftable has
+    // a unique mangled name.
+    llvm::StringSet<> ObservedMangledNames;
+    for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
+      SmallString<256> Name;
+      mangleVFTableName(getMangleContext(), RD, *VFPtrs[J], Name);
+      assert(ObservedMangledNames.insert(Name.str()).second &&
+             "Already saw this mangling before?");
+    }
+#endif
+  }
+}
+
 CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
                                                     GlobalDecl GD,
                                                     Address This,
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -274,6 +274,10 @@
   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
                                         CharUnits VPtrOffset) override;
 
+  void emitVTables(const CXXRecordDecl *RD) override {
+    (void) getAddrOfVTable(RD, CharUnits());
+  }
+
   CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
                                      Address This, llvm::Type *Ty,
                                      SourceLocation Loc) override;
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1110,7 +1110,7 @@
 
   void EmitTentativeDefinition(const VarDecl *D);
 
-  void EmitVTable(CXXRecordDecl *Class);
+  void EmitVTable(const CXXRecordDecl *Class);
 
   void RefreshTypeCacheForClass(const CXXRecordDecl *Class);
 
@@ -1312,7 +1312,8 @@
 
   void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr);
 
-  void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
+  llvm::GlobalValue *
+  EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV = nullptr);
   void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
 
   void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false);
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -2455,7 +2455,8 @@
 
     if (FD->isMultiVersion())
       return EmitMultiVersionFunctionDefinition(GD, GV);
-    return EmitGlobalFunctionDefinition(GD, GV);
+    EmitGlobalFunctionDefinition(GD, GV);
+    return;
   }
 
   if (const auto *VD = dyn_cast<VarDecl>(D))
@@ -3940,7 +3941,7 @@
   EmitTopLevelDecl(VD);
 }
 
-void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
+llvm::GlobalValue *CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
                                                  llvm::GlobalValue *GV) {
   const auto *D = cast<FunctionDecl>(GD.getDecl());
 
@@ -3956,7 +3957,7 @@
 
   // Already emitted.
   if (!GV->isDeclaration())
-    return;
+    return GV;
 
   // We need to set linkage and visibility on the function before
   // generating code for it because various parts of IR generation
@@ -3973,7 +3974,7 @@
 
   maybeSetTrivialComdat(*D, *Fn);
 
-  CodeGenFunction(*this).GenerateCode(D, Fn, FI);
+  CodeGenFunction(*this).GenerateCode(GD, Fn, FI);
 
   setNonAliasAttributes(GD, Fn);
   SetLLVMFunctionAttributesForDefinition(D, Fn);
@@ -3984,6 +3985,16 @@
     AddGlobalDtor(Fn, DA->getPriority());
   if (D->hasAttr<AnnotateAttr>())
     AddGlobalAnnotations(D, Fn);
+
+  // If we emit a key function, also emit the vtable.
+  if (auto *MD = dyn_cast<CXXMethodDecl>(D)) {
+    // FIXME: There's no reason to do this if the key function is inline.
+    // Formally, the ABI requires it, but the difference is not observable.
+    if (declaresSameEntity(Context.getCurrentKeyFunction(MD->getParent()), MD))
+      EmitVTable(MD->getParent());
+  }
+
+  return Fn;
 }
 
 void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
@@ -4797,14 +4808,22 @@
   case Decl::Namespace:
     EmitDeclContext(cast<NamespaceDecl>(D));
     break;
-  case Decl::ClassTemplateSpecialization: {
-    const auto *Spec = cast<ClassTemplateSpecializationDecl>(D);
-    if (DebugInfo &&
-        Spec->getSpecializationKind() == TSK_ExplicitInstantiationDefinition &&
-        Spec->hasDefinition())
-      DebugInfo->completeTemplateDefinition(*Spec);
-  } LLVM_FALLTHROUGH;
-  case Decl::CXXRecord:
+  case Decl::ClassTemplateSpecialization:
+  case Decl::CXXRecord: {
+    auto *RD = cast<CXXRecordDecl>(D);
+    // If this class was explicitly instantiated, emit the accompanying data.
+    if (RD->getTemplateSpecializationKind() ==
+            TSK_ExplicitInstantiationDefinition &&
+        RD->hasDefinition()) {
+      if (DebugInfo) {
+        // FIXME: This should almost certainly apply to explicitly instantiated
+        // member classes of class templates too.
+        if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
+          DebugInfo->completeTemplateDefinition(*CTSD);
+      }
+      if (RD->isDynamicClass())
+        EmitVTable(RD);
+    }
     if (DebugInfo) {
       if (auto *ES = D->getASTContext().getExternalSource())
         if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never)
@@ -4815,6 +4834,7 @@
       if (isa<VarDecl>(I) || isa<CXXRecordDecl>(I))
         EmitTopLevelDecl(I);
     break;
+  }
     // No code generation needed.
   case Decl::UsingShadow:
   case Decl::ClassTemplate:
Index: lib/CodeGen/CodeGenAction.cpp
===================================================================
--- lib/CodeGen/CodeGenAction.cpp
+++ lib/CodeGen/CodeGenAction.cpp
@@ -321,10 +321,6 @@
       Gen->AssignInheritanceModel(RD);
     }
 
-    void HandleVTable(CXXRecordDecl *RD) override {
-      Gen->HandleVTable(RD);
-    }
-
     static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
                                      unsigned LocCookie) {
       SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp
+++ lib/CodeGen/CGVTables.cpp
@@ -876,14 +876,14 @@
   llvm_unreachable("Invalid TemplateSpecializationKind!");
 }
 
-/// This is a callback from Sema to tell us that a particular vtable is
-/// required to be emitted in this translation unit.
+/// This is called when a particular vtable is required to be emitted in this
+/// translation unit.
 ///
 /// This is only called for vtables that _must_ be emitted (mainly due to key
 /// functions).  For weak vtables, CodeGen tracks when they are needed and
 /// emits them as-needed.
-void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) {
-  VTables.GenerateClassData(theClass);
+void CodeGenModule::EmitVTable(const CXXRecordDecl *theClass) {
+  getCXXABI().emitVTables(theClass);
 }
 
 void
@@ -955,21 +955,15 @@
 /// vtables, and that we are now at the end of the translation unit,
 /// decide whether we should emit them.
 void CodeGenModule::EmitDeferredVTables() {
-#ifndef NDEBUG
-  // Remember the size of DeferredVTables, because we're going to assume
-  // that this entire operation doesn't modify it.
-  size_t savedSize = DeferredVTables.size();
-#endif
-
-  for (const CXXRecordDecl *RD : DeferredVTables)
-    if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD))
-      VTables.GenerateClassData(RD);
-    else if (shouldOpportunisticallyEmitVTables())
-      OpportunisticVTables.push_back(RD);
-
-  assert(savedSize == DeferredVTables.size() &&
-         "deferred extra vtables during vtable emission?");
-  DeferredVTables.clear();
+  while (!DeferredVTables.empty()) {
+    auto WorkList = std::move(DeferredVTables);
+    DeferredVTables.clear();
+    for (const CXXRecordDecl *RD : WorkList)
+      if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD))
+        VTables.GenerateClassData(RD);
+      else if (shouldOpportunisticallyEmitVTables())
+        OpportunisticVTables.push_back(RD);
+  }
 }
 
 bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
Index: lib/CodeGen/CGCXXABI.h
===================================================================
--- lib/CodeGen/CGCXXABI.h
+++ lib/CodeGen/CGCXXABI.h
@@ -420,6 +420,9 @@
   virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
                                                 CharUnits VPtrOffset) = 0;
 
+  /// Ensure that all vtables for the given class are emitted.
+  virtual void emitVTables(const CXXRecordDecl *RD) = 0;
+
   /// Build a virtual function pointer in the ABI-specific way.
   virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF,
                                              GlobalDecl GD, Address This,
Index: lib/CodeGen/CGCXX.cpp
===================================================================
--- lib/CodeGen/CGCXX.cpp
+++ lib/CodeGen/CGCXX.cpp
@@ -206,12 +206,6 @@
 
 llvm::Function *CodeGenModule::codegenCXXStructor(const CXXMethodDecl *MD,
                                                   StructorType Type) {
-  const CGFunctionInfo &FnInfo =
-      getTypes().arrangeCXXStructorDeclaration(MD, Type);
-  auto *Fn = cast<llvm::Function>(
-      getAddrOfCXXStructor(MD, Type, &FnInfo, /*FnType=*/nullptr,
-                           /*DontDefer=*/true, ForDefinition));
-
   GlobalDecl GD;
   if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
     GD = GlobalDecl(DD, toCXXDtorType(Type));
@@ -220,12 +214,7 @@
     GD = GlobalDecl(CD, toCXXCtorType(Type));
   }
 
-  setFunctionLinkage(GD, Fn);
-
-  CodeGenFunction(*this).GenerateCode(GD, Fn, FnInfo);
-  setNonAliasAttributes(GD, Fn);
-  SetLLVMFunctionAttributesForDefinition(MD, Fn);
-  return Fn;
+  return cast<llvm::Function>(EmitGlobalFunctionDefinition(GD));
 }
 
 llvm::Constant *CodeGenModule::getAddrOfCXXStructor(
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -3053,7 +3053,7 @@
 }
 
 const CXXMethodDecl *ASTContext::getCurrentKeyFunction(const CXXRecordDecl *RD) {
-  if (!getTargetInfo().getCXXABI().hasKeyFunctions())
+  if (!getTargetInfo().getCXXABI().hasKeyFunctions() || !RD->isDynamicClass())
     return nullptr;
 
   assert(RD->getDefinition() && "Cannot get key function for forward decl!");
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -9793,6 +9793,12 @@
     return !D->getDeclContext()->isDependentContext();
   else if (isa<ImportDecl>(D))
     return true;
+  else if (auto *RD = dyn_cast<CXXRecordDecl>(D))
+    // An explicit instantiation of a dynamic class emits the vtable and
+    // type_info objects, so must be emitted.
+    return RD->hasDefinition() && RD->isDynamicClass() &&
+           RD->getTemplateSpecializationKind() ==
+               TSK_ExplicitInstantiationDefinition;
   else
     return false;
 
@@ -9842,8 +9848,11 @@
   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
     // Multiversioned functions always have to be emitted, because they are used
     // by the resolver.
+    // FIXME: This doesn't appear to be correct. Multiversioned functions should
+    // only be emitted if the resolver is emitted.
     if (FD->isMultiVersion())
       return true;
+
     // Forward declarations aren't required.
     if (!FD->doesThisDeclarationHaveABody())
       return FD->doesDeclarationForceExternallyVisibleDefinition();
@@ -9852,19 +9861,6 @@
     if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
       return true;
 
-    // The key function for a class is required.  This rule only comes
-    // into play when inline functions can be key functions, though.
-    if (getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {
-      if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
-        const CXXRecordDecl *RD = MD->getParent();
-        if (MD->isOutOfLine() && RD->isDynamicClass()) {
-          const CXXMethodDecl *KeyFunc = getCurrentKeyFunction(RD);
-          if (KeyFunc && KeyFunc->getCanonicalDecl() == MD->getCanonicalDecl())
-            return true;
-        }
-      }
-    }
-
     GVALinkage Linkage = GetGVALinkageForFunction(FD);
 
     // static, static inline, always_inline, and extern inline functions can
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to