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