1 // If the linkage of the class is internal, then the stubs and proxies should
2 // also be internally linked.
3 
4 // RUN: %clang_cc1 %s -triple=x86_64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
5 
6 // External linkage.
7 // CHECK: @_ZTI8External.rtti_proxy = hidden unnamed_addr constant { i8*, i8* }* @_ZTI8External, comdat
8 
9 class External {
10 public:
11   virtual void func();
12 };
13 
func()14 void External::func() {}
15 
16 // Internal linkage.
17 // CHECK: @_ZTIN12_GLOBAL__N_18InternalE.rtti_proxy = internal unnamed_addr constant { i8*, i8* }* @_ZTIN12_GLOBAL__N_18InternalE
18 namespace {
19 
20 class Internal {
21 public:
22   virtual void func();
23 };
24 
func()25 void Internal::func() {}
26 
27 } // namespace
28 
29 // This gets the same treatment as an externally available vtable.
30 // CHECK: @_ZTI11LinkOnceODR.rtti_proxy = hidden unnamed_addr constant { i8*, i8* }* @_ZTI11LinkOnceODR, comdat
31 class LinkOnceODR {
32 public:
func()33   virtual void func() {} // A method defined in the class definition results in this linkage for the vtable.
34 };
35 
36 // Force an emission of a vtable for Internal by using it here.
manifest_internal()37 void manifest_internal() {
38   Internal internal;
39   (void)internal;
40   LinkOnceODR linkonceodr;
41   (void)linkonceodr;
42 }
43 
44 // Aliases are typically emitted after the vtable definitions but before the
45 // function definitions.
46 // CHECK: @_ZTV8External = unnamed_addr alias { [3 x i32] }, { [3 x i32] }* @_ZTV8External.local
47 // CHECK: @_ZTV11LinkOnceODR = linkonce_odr unnamed_addr alias { [3 x i32] }, { [3 x i32] }* @_ZTV11LinkOnceODR.local
48 
49 // CHECK: define void @_ZN8External4funcEv
50 // CHECK: define internal void @_ZN12_GLOBAL__N_18Internal4funcEv.stub
51 // CHECK: define hidden void @_ZN11LinkOnceODR4funcEv.stub
52