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 -fms-extensions -emit-pch -building-pch-with-obj -o %t %s 7 // RUN: %clang_cc1 -triple i686-pc-win32 -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 -fms-extensions -emit-obj -emit-llvm -include-pch %t -o - %s | FileCheck -check-prefix=PCHWITHOBJ %s 9 10 // Check for vars separately to avoid having to reorder the check statements. 11 // RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-obj -emit-llvm -include-pch %t -o - %s | FileCheck -check-prefix=PCHWITHOBJVARS %s 12 13 #ifndef IN_HEADER 14 #define IN_HEADER 15 16 inline void __declspec(dllexport) foo() {} 17 // OBJ: define weak_odr dso_local dllexport void @"?foo@@YAXXZ" 18 // PCH: define weak_odr dso_local dllexport void @"?foo@@YAXXZ" 19 // PCHWITHOBJ-NOT: define {{.*}}foo 20 21 22 // This function is referenced, so gets emitted as usual. 23 inline void __declspec(dllexport) baz() {} 24 // OBJ: define weak_odr dso_local dllexport void @"?baz@@YAXXZ" 25 // PCH: define weak_odr dso_local dllexport void @"?baz@@YAXXZ" 26 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"?baz@@YAXXZ" 27 28 29 struct __declspec(dllexport) S { 30 void bar() {} 31 // OBJ: define weak_odr dso_local dllexport x86_thiscallcc void @"?bar@S@@QAEXXZ" 32 // PCH: define weak_odr dso_local dllexport x86_thiscallcc void @"?bar@S@@QAEXXZ" 33 // PCHWITHOBJ-NOT: define {{.*}}bar 34 }; 35 36 // This isn't dllexported, attribute((used)) or referenced, so not emitted. 37 inline void quux() {} 38 // OBJ-NOT: define {{.*}}quux 39 // PCH-NOT: define {{.*}}quux 40 // PCHWITHOBJ-NOT: define {{.*}}quux 41 42 // Referenced non-dllexport function. 43 inline void referencedNonExported() {} 44 // OBJ: define {{.*}}referencedNonExported 45 // PCH: define {{.*}}referencedNonExported 46 // PCHWITHOBJ: define {{.*}}referencedNonExported 47 48 template <typename T> void __declspec(dllexport) implicitInstantiation(T) {} 49 50 template <typename T> inline void __declspec(dllexport) explicitSpecialization(T) {} 51 52 template <typename T> void __declspec(dllexport) explicitInstantiationDef(T) {} 53 54 template <typename T> void __declspec(dllexport) explicitInstantiationDefAfterDecl(T) {} 55 extern template void explicitInstantiationDefAfterDecl<int>(int); 56 57 template <typename T> T __declspec(dllexport) variableTemplate; 58 extern template int variableTemplate<int>; 59 60 #else 61 62 void use() { 63 baz(); 64 referencedNonExported(); 65 } 66 67 // Templates can be tricky. None of the definitions below come from the PCH. 68 69 void useTemplate() { implicitInstantiation(42); } 70 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$implicitInstantiation@H@@YAXH@Z" 71 72 template<> inline void __declspec(dllexport) explicitSpecialization<int>(int) {} 73 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$explicitSpecialization@H@@YAXH@Z" 74 75 template void __declspec(dllexport) explicitInstantiationDef<int>(int); 76 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$explicitInstantiationDef@H@@YAXH@Z" 77 78 template void __declspec(dllexport) explicitInstantiationDefAfterDecl<int>(int); 79 // PCHWITHOBJ: define weak_odr dso_local dllexport void @"??$explicitInstantiationDefAfterDecl@H@@YAXH@Z"(i32) 80 81 template int __declspec(dllexport) variableTemplate<int>; 82 // PCHWITHOBJVARS: @"??$variableTemplate@H@@3HA" = weak_odr dso_local dllexport global 83 84 #endif 85