1// RUN: rm -rf %t
2// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -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 -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class | FileCheck %s
4// expected-no-diagnostics
5// REQUIRES: x86-registered-target
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-DAG: @list_left ={{.*}} global %[[LIST:.*]] { %[[LISTNODE:.*]]* null, i32 8 }, align 8
16// CHECK-DAG: @list_right ={{.*}} global %[[LIST]] { %[[LISTNODE]]* null, i32 12 }, align 8
17// CHECK-DAG: @__const._Z15testMixedStructv.l = {{.*}} constant %[[LIST]] { %{{.*}}* null, i32 1 }, align 8
18// CHECK-DAG: @__const._Z15testMixedStructv.r = {{.*}} constant %[[LIST]] { %{{.*}}* null, i32 2 }, align 8
19// CHECK-DAG: @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE = external global
20
21void testTemplateClasses() {
22  Vector<int> vec_int;
23  vec_int.push_back(0);
24
25  List<bool> list_bool;
26  list_bool.push_back(false);
27
28  N::Set<char> set_char;
29  set_char.insert('A');
30
31  static_assert(sizeof(List<long>) == sizeof(List<short>), "");
32
33  List<double> list_double;
34  list_double.push_back(0.0);
35}
36
37void testPendingInstantiations() {
38  // CHECK: call {{.*pendingInstantiationEmit}}
39  // CHECK: call {{.*pendingInstantiationEmit}}
40  // CHECK: define {{.*pendingInstantiationEmit.*[(]i}}
41  // CHECK: define {{.*pendingInstantiationEmit.*[(]double}}
42  triggerPendingInstantiation();
43  triggerPendingInstantiationToo();
44}
45
46void testRedeclDefinition() {
47  // CHECK: define {{.*redeclDefinitionEmit}}
48  redeclDefinitionEmit();
49}
50
51void testInlineRedecl() {
52  outOfLineInlineUseLeftF();
53  outOfLineInlineUseRightG();
54
55  outOfLineInlineUseRightF();
56  outOfLineInlineUseLeftG();
57}
58
59// CHECK-NOT: @_ZN21ExplicitInstantiationILb0ELb0EE1fEv(
60// CHECK: declare {{.*}}@_ZN21ExplicitInstantiationILb1ELb0EE1fEv(
61// CHECK: define {{.*}}@_ZN21ExplicitInstantiationILb1ELb1EE1fEv(
62// CHECK-NOT: @_ZN21ExplicitInstantiationILb0ELb0EE1fEv(
63
64// These three are all the same type.
65typedef OuterIntInner_left OuterIntInner;
66typedef OuterIntInner_right OuterIntInner;
67typedef Outer<int>::Inner OuterIntInner;
68
69// CHECK: call {{.*pendingInstantiation}}
70// CHECK: call {{.*redeclDefinitionEmit}}
71
72static_assert(size_left == size_right, "same field both ways");
73void useListInt(List<int> &);
74
75// CHECK-LABEL: define{{.*}} i32 @_Z15testMixedStructv(
76unsigned testMixedStruct() {
77  // CHECK: %[[l:.*]] = alloca %[[ListInt:[^ ]*]], align 8
78  // CHECK: %[[r:.*]] = alloca %[[ListInt]], align 8
79
80  // CHECK: call {{.*}}memcpy{{.*}}(i8* align {{[0-9]+}} %{{.*}}, i8* align {{[0-9]+}} bitcast ({{.*}}* @__const._Z15testMixedStructv.l to i8*), i64 16,
81  ListInt_left l{0, 1};
82
83  // CHECK: call {{.*}}memcpy{{.*}}(i8* align {{[0-9]+}} %{{.*}}, i8* align {{[0-9]+}} bitcast ({{.*}}* @__const._Z15testMixedStructv.r to i8*), i64 16,
84  ListInt_right r{0, 2};
85
86  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %[[l]])
87  useListInt(l);
88  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %[[r]])
89  useListInt(r);
90
91  // CHECK: load i32, i32* bitcast (i8* getelementptr inbounds (i8, i8* bitcast ({{.*}}* @list_left to i8*), i64 8) to i32*)
92  // CHECK: load i32, i32* bitcast (i8* getelementptr inbounds (i8, i8* bitcast ({{.*}}* @list_right to i8*), i64 8) to i32*)
93  return list_left.*size_right + list_right.*size_left;
94}
95
96template<typename T> struct MergePatternDecl {
97  typedef int Type;
98  void f(Type);
99};
100template<typename T> void MergePatternDecl<T>::f(Type type) {}
101// CHECK: define {{.*}}@_ZN21ExplicitInstantiationILb0ELb1EE1fEv(
102template struct ExplicitInstantiation<false, true>;
103template struct ExplicitInstantiation<true, true>;
104
105void testDelayUpdatesImpl() { testDelayUpdates<int>(); }
106
107void testStaticDataMember() {
108  WithUndefinedStaticDataMember<int[]> load_it;
109
110  // CHECK-LABEL: define linkonce_odr i32* @_Z23getStaticDataMemberLeftv(
111  // CHECK: ret i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i64 0, i64 0)
112  (void) getStaticDataMemberLeft();
113
114  // CHECK-LABEL: define linkonce_odr i32* @_Z24getStaticDataMemberRightv(
115  // CHECK: ret i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i64 0, i64 0)
116  (void) getStaticDataMemberRight();
117}
118
119void testWithAttributes() {
120  auto a = make_with_attributes_left();
121  auto b = make_with_attributes_right();
122  static_assert(alignof(decltype(a)) == 2, "");
123  static_assert(alignof(decltype(b)) == 2, "");
124}
125
126// Check that returnNonTrivial doesn't return Class0<S0> directly in registers.
127
128// CHECK: declare void @_Z16returnNonTrivialv(%struct.Class0* sret(%struct.Class0) align 8)
129
130@import template_nontrivial0;
131@import template_nontrivial1;
132
133S1::S1() : a(returnNonTrivial()) {
134}
135