1 // Build PCH without object file, then use it. 2 // RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-pch -o %t %s 3 // RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-obj -emit-llvm -include-pch %t -o - %s | FileCheck -check-prefix=PCH %s 4 5 // Build PCH with object file, then use it. 6 // RUN: %clang_cc1 -triple i686-pc-win32 -O1 -fms-extensions -emit-pch -building-pch-with-obj -o %t %s 7 // RUN: %clang_cc1 -triple i686-pc-win32 -O1 -disable-llvm-optzns -fms-extensions -emit-obj -emit-llvm -include-pch %t -building-pch-with-obj -o - %s | FileCheck -check-prefix=OBJ %s 8 // RUN: %clang_cc1 -triple i686-pc-win32 -O1 -disable-llvm-optzns -fms-extensions -emit-obj -emit-llvm -include-pch %t -o - %s | FileCheck -check-prefix=PCHWITHOBJ -check-prefix=PCHWITHOBJ-O1 %s 9 10 // Check for vars separately to avoid having to reorder the check statements. 11 // RUN: %clang_cc1 -triple i686-pc-win32 -O1 -disable-llvm-optzns -fms-extensions -emit-obj -emit-llvm -include-pch %t -o - %s | FileCheck -check-prefix=PCHWITHOBJVARS %s 12 13 // Test the PCHWITHOBJ at -O0 where available_externally definitions are not 14 // provided: 15 // RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-pch -building-pch-with-obj -o %t %s 16 // RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-obj -emit-llvm -include-pch %t -o - %s | FileCheck -check-prefix=PCHWITHOBJ -check-prefix=PCHWITHOBJ-O0 %s 17 // RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-obj -emit-llvm -include-pch %t -o - %s | FileCheck -check-prefix=PCHWITHOBJVARS %s 18 19 20 #ifndef IN_HEADER 21 #define IN_HEADER 22 23 inline void __declspec(dllexport) foo() {} 24 // OBJ: define weak_odr dso_local dllexport void @"?foo@@YAXXZ" 25 // PCH: define weak_odr dso_local dllexport void @"?foo@@YAXXZ" 26 // PCHWITHOBJ-NOT: define {{.*}}foo 27 28 29 // This function is referenced, so gets emitted as usual. 30 inline void __declspec(dllexport) baz() {} 31 // OBJ: define weak_odr dso_local dllexport void @"?baz@@YAXXZ" 32 // PCH: define weak_odr dso_local dllexport void @"?baz@@YAXXZ" 33 // PCHWITHOBJ-O1: define available_externally dso_local void @"?baz@@YAXXZ" 34 // PCHWITHOBJ-O0-NOT: define {{.*}}"?baz@@YAXXZ" 35 36 37 struct __declspec(dllexport) S { 38 void bar() {} 39 // OBJ: define weak_odr dso_local dllexport x86_thiscallcc void @"?bar@S@@QAEXXZ" 40 // PCH: define weak_odr dso_local dllexport x86_thiscallcc void @"?bar@S@@QAEXXZ" 41 // PCHWITHOBJ-NOT: define {{.*}}bar 42 }; 43 44 // This isn't dllexported, attribute((used)) or referenced, so not emitted. 45 inline void quux() {} 46 // OBJ-NOT: define {{.*}}quux 47 // PCH-NOT: define {{.*}}quux 48 // PCHWITHOBJ-NOT: define {{.*}}quux 49 50 // Referenced non-dllexport function. 51 inline void referencedNonExported() {} 52 // OBJ: define {{.*}}referencedNonExported 53 // PCH: define {{.*}}referencedNonExported 54 // PCHWITHOBJ: define {{.*}}referencedNonExported 55 56 template <typename T> void __declspec(dllexport) implicitInstantiation(T) {} 57 58 template <typename T> inline void __declspec(dllexport) explicitSpecialization(T) {} 59 60 template <typename T> void __declspec(dllexport) explicitInstantiationDef(T) {} 61 62 template <typename T> void __declspec(dllexport) explicitInstantiationDefAfterDecl(T) {} 63 extern template void explicitInstantiationDefAfterDecl<int>(int); 64 65 template <typename T> T __declspec(dllexport) variableTemplate; 66 extern template int variableTemplate<int>; 67 68 namespace pr38934 { 69 template <typename T> struct S {}; 70 extern template struct S<int>; 71 // The use here causes the S<int>::operator= decl to go into the PCH. 72 inline void use(S<int> *a, S<int> *b) { *a = *b; }; 73 } 74 75 #else 76 77 void use() { 78 baz(); 79 referencedNonExported(); 80 } 81 82 // Templates can be tricky. None of the definitions below come from the PCH. 83 84 void useTemplate() { implicitInstantiation(42); } 85 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$implicitInstantiation@H@@YAXH@Z" 86 87 template<> inline void __declspec(dllexport) explicitSpecialization<int>(int) {} 88 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$explicitSpecialization@H@@YAXH@Z" 89 90 template void __declspec(dllexport) explicitInstantiationDef<int>(int); 91 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$explicitInstantiationDef@H@@YAXH@Z" 92 93 template void __declspec(dllexport) explicitInstantiationDefAfterDecl<int>(int); 94 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$explicitInstantiationDefAfterDecl@H@@YAXH@Z"(i32 noundef %0) 95 96 template int __declspec(dllexport) variableTemplate<int>; 97 // PCHWITHOBJVARS: @"??$variableTemplate@H@@3HA" = weak_odr dso_local dllexport global 98 99 // PR38934: Make sure S<int>::operator= gets emitted. While it itself isn't a 100 // template specialization, its parent is. 101 template struct __declspec(dllexport) pr38934::S<int>; 102 // PCHWITHOBJ: define weak_odr dso_local dllexport x86_thiscallcc noundef nonnull align 1 dereferenceable(1) %"struct.pr38934::S"* @"??4?$S@H@pr38934@@QAEAAU01@ABU01@@Z" 103 104 #endif 105