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