1// RUN: rm -rf %t
2// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class
3// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class | FileCheck %s
4// expected-no-diagnostics
5
6@import templates_left;
7
8void testInlineRedeclEarly() {
9  // instantiate definition now, we'll add another declaration in _right.
10  OutOfLineInline<int>().h();
11}
12
13@import templates_right;
14
15// CHECK: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8,
16// CHECK: @list_right = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 12,
17// CHECK: @_ZZ15testMixedStructvE1l = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 1,
18// CHECK: @_ZZ15testMixedStructvE1r = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 2,
19
20void testTemplateClasses() {
21  Vector<int> vec_int;
22  vec_int.push_back(0);
23
24  List<bool> list_bool;
25  list_bool.push_back(false);
26
27  N::Set<char> set_char;
28  set_char.insert('A');
29
30  List<double> list_double;
31  list_double.push_back(0.0);
32}
33
34void testPendingInstantiations() {
35  // CHECK: call {{.*pendingInstantiationEmit}}
36  // CHECK: call {{.*pendingInstantiationEmit}}
37  // CHECK: define {{.*pendingInstantiationEmit.*[(]i}}
38  // CHECK: define {{.*pendingInstantiationEmit.*[(]double}}
39  triggerPendingInstantiation();
40  triggerPendingInstantiationToo();
41}
42
43void testRedeclDefinition() {
44  // CHECK: define {{.*redeclDefinitionEmit}}
45  redeclDefinitionEmit();
46}
47
48void testInlineRedecl() {
49  outOfLineInlineUseLeftF();
50  outOfLineInlineUseRightG();
51
52  outOfLineInlineUseRightF();
53  outOfLineInlineUseLeftG();
54}
55
56// CHECK-NOT: @_ZN21ExplicitInstantiationILb0ELb0EE1fEv(
57// CHECK: declare {{.*}}@_ZN21ExplicitInstantiationILb1ELb0EE1fEv(
58// CHECK: define {{.*}}@_ZN21ExplicitInstantiationILb1ELb1EE1fEv(
59// CHECK-NOT: @_ZN21ExplicitInstantiationILb0ELb0EE1fEv(
60
61// These three are all the same type.
62typedef OuterIntInner_left OuterIntInner;
63typedef OuterIntInner_right OuterIntInner;
64typedef Outer<int>::Inner OuterIntInner;
65
66// CHECK: call {{.*pendingInstantiation}}
67// CHECK: call {{.*redeclDefinitionEmit}}
68
69static_assert(size_left == size_right, "same field both ways");
70void useListInt(List<int> &);
71
72// CHECK-LABEL: define i32 @_Z15testMixedStructv(
73unsigned testMixedStruct() {
74  // CHECK: %[[l:.*]] = alloca %[[ListInt:[^ ]*]], align 8
75  // CHECK: %[[r:.*]] = alloca %[[ListInt]], align 8
76
77  // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1l to i8*), i64 16,
78  ListInt_left l{0, 1};
79
80  // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1r to i8*), i64 16,
81  ListInt_right r{0, 2};
82
83  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* nonnull %[[l]])
84  useListInt(l);
85  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* nonnull %[[r]])
86  useListInt(r);
87
88  // CHECK: load i32* bitcast (i8* getelementptr inbounds (i8* bitcast ({{.*}}* @list_left to i8*), i64 8) to i32*)
89  // CHECK: load i32* bitcast (i8* getelementptr inbounds (i8* bitcast ({{.*}}* @list_right to i8*), i64 8) to i32*)
90  return list_left.*size_right + list_right.*size_left;
91}
92
93template<typename T> struct MergePatternDecl {
94  typedef int Type;
95  void f(Type);
96};
97template<typename T> void MergePatternDecl<T>::f(Type type) {}
98// CHECK: define {{.*}}@_ZN21ExplicitInstantiationILb0ELb1EE1fEv(
99template struct ExplicitInstantiation<false, true>;
100template struct ExplicitInstantiation<true, true>;
101
102void testDelayUpdatesImpl() { testDelayUpdates<int>(); }
103