Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -164,6 +164,7 @@ BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch") BENIGN_LANGOPT(BuildingPCHWithObjectFile, 1, 0, "building a pch which has a corresponding object file") BENIGN_LANGOPT(CacheGeneratedPCH, 1, 0, "cache generated PCH files in memory") +BENIGN_LANGOPT(PCHInstantiateTemplates, 1, 0, "instantiate templates while building a PCH") COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references") COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules") Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1457,6 +1457,13 @@ def fno_pch_validate_input_files_content: Flag <["-"], "fno_pch-validate-input-files-content">, Group, Flags<[DriverOption]>; +def fpch_instantiate_templates: + Flag <["-"], "fpch-instantiate-templates">, + Group, Flags<[CC1Option]>, + HelpText<"Instantiate templates already while building a PCH">; +def fno_pch_instantiate_templates: + Flag <["-"], "fno-pch-instantiate-templates">, + Group, Flags<[CC1Option]>; def fmodules : Flag <["-"], "fmodules">, Group, Flags<[DriverOption, CC1Option]>, Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -8782,9 +8782,17 @@ S.VTableUses.swap(SavedVTableUses); // Restore the set of pending implicit instantiations. - assert(S.PendingInstantiations.empty() && - "PendingInstantiations should be empty before it is discarded."); - S.PendingInstantiations.swap(SavedPendingInstantiations); + if (S.TUKind != TU_Prefix || !S.LangOpts.PCHInstantiateTemplates) { + assert(S.PendingInstantiations.empty() && + "PendingInstantiations should be empty before it is discarded."); + S.PendingInstantiations.swap(SavedPendingInstantiations); + } else { + // Template instantiations in the PCH may be delayed until the TU. + S.PendingInstantiations.swap(SavedPendingInstantiations); + S.PendingInstantiations.insert(S.PendingInstantiations.end(), + SavedPendingInstantiations.begin(), + SavedPendingInstantiations.end()); + } } private: Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -1232,6 +1232,7 @@ if (YcArg && JA.getKind() >= Action::PrecompileJobClass && JA.getKind() <= Action::AssembleJobClass) { CmdArgs.push_back(Args.MakeArgString("-building-pch-with-obj")); + CmdArgs.push_back(Args.MakeArgString("-fpch-instantiate-templates")); } if (YcArg || YuArg) { StringRef ThroughHeader = YcArg ? YcArg->getValue() : YuArg->getValue(); @@ -5620,6 +5621,9 @@ if (Args.hasFlag(options::OPT_fpch_validate_input_files_content, options::OPT_fno_pch_validate_input_files_content, false)) CmdArgs.push_back("-fvalidate-ast-input-files-content"); + if (Args.hasFlag(options::OPT_fpch_instantiate_templates, + options::OPT_fno_pch_instantiate_templates, false)) + CmdArgs.push_back("-fpch-instantiate-templates"); Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager, options::OPT_fno_experimental_new_pass_manager); Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3326,6 +3326,7 @@ Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers); Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj); + Opts.PCHInstantiateTemplates = Args.hasArg(OPT_fpch_instantiate_templates); Opts.MaxTokens = getLastArgIntValue(Args, OPT_fmax_tokens_EQ, 0, Diags); Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -1009,6 +1009,11 @@ LateParsedInstantiations.begin(), LateParsedInstantiations.end()); LateParsedInstantiations.clear(); + + if (LangOpts.PCHInstantiateTemplates) { + llvm::TimeTraceScope TimeScope("PerformPendingInstantiations"); + PerformPendingInstantiations(); + } } DiagnoseUnterminatedPragmaPack(); Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5920,6 +5920,7 @@ /// Performs template instantiation for all implicit template /// instantiations we have seen until this point. void Sema::PerformPendingInstantiations(bool LocalOnly) { + std::deque delayedPCHInstantiations; while (!PendingLocalImplicitInstantiations.empty() || (!LocalOnly && !PendingInstantiations.empty())) { PendingImplicitInstantiation Inst; @@ -5950,6 +5951,10 @@ if (Function->isDefined()) Function->setInstantiationIsPending(false); } + // Definition of a PCH-ed template declaration may be available only in the TU. + if (!LocalOnly && LangOpts.PCHInstantiateTemplates && + TUKind == TU_Prefix && Function->instantiationIsPending()) + delayedPCHInstantiations.push_back(Inst); continue; } @@ -5995,6 +6000,9 @@ InstantiateVariableDefinition(/*FIXME:*/ Inst.second, Var, true, DefinitionRequired, true); } + + if (!LocalOnly && LangOpts.PCHInstantiateTemplates) + PendingInstantiations.swap(delayedPCHInstantiations); } void Sema::PerformDependentDiagnostics(const DeclContext *Pattern, Index: clang/test/PCH/codegen.cpp =================================================================== --- clang/test/PCH/codegen.cpp +++ clang/test/PCH/codegen.cpp @@ -15,6 +15,18 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-cg.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-di.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s +// Test with template instantiation in the pch. + +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-debuginfo -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch + +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-cg.pch -building-pch-with-obj -fmodules-codegen | FileCheck --check-prefix=CG %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-di.pch -building-pch-with-obj -fmodules-debuginfo | FileCheck --check-prefix=DI %s + +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-cg.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-di.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s + + // CG: define weak_odr void @_Z2f1v // CG: DICompileUnit // CG-NOT: DICompositeType Index: clang/test/PCH/crash-12631281.cpp =================================================================== --- clang/test/PCH/crash-12631281.cpp +++ clang/test/PCH/crash-12631281.cpp @@ -1,5 +1,9 @@ // RUN: %clang_cc1 -std=c++11 %s -emit-pch -o %t.pch // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -include-pch %t.pch -verify + +// RUN: %clang_cc1 -std=c++11 %s -emit-pch -fpch-instantiate-templates -o %t.pch +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -include-pch %t.pch -verify + // expected-no-diagnostics // rdar://12631281 Index: clang/test/PCH/cxx-alias-decl.cpp =================================================================== --- clang/test/PCH/cxx-alias-decl.cpp +++ clang/test/PCH/cxx-alias-decl.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -o %t %S/cxx-alias-decl.h // RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -fsyntax-only -emit-llvm -o - %s +// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -fpch-instantiate-templates -o %t %S/cxx-alias-decl.h +// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -fsyntax-only -emit-llvm -o - %s + template struct T; C::A a; Index: clang/test/PCH/cxx-dependent-sized-ext-vector.cpp =================================================================== --- clang/test/PCH/cxx-dependent-sized-ext-vector.cpp +++ clang/test/PCH/cxx-dependent-sized-ext-vector.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++11 -emit-pch %s -o %t // RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s +// RUN: %clang_cc1 -std=c++11 -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED Index: clang/test/PCH/cxx-explicit-specifier.cpp =================================================================== --- clang/test/PCH/cxx-explicit-specifier.cpp +++ clang/test/PCH/cxx-explicit-specifier.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t-cxx2a // RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s +// RUN: %clang_cc1 -std=c++2a -emit-pch -fpch-instantiate-templates %s -o %t-cxx2a +// RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s + #ifndef USE_PCH namespace inheriting_constructor { struct S {}; Index: clang/test/PCH/cxx-exprs.cpp =================================================================== --- clang/test/PCH/cxx-exprs.cpp +++ clang/test/PCH/cxx-exprs.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s // RUN: %clang_cc1 -include-pch %t -verify -std=c++11 %s +// RUN: %clang_cc1 -std=c++11 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -include-pch %t -verify -std=c++11 %s + // expected-no-diagnostics #ifndef HEADER Index: clang/test/PCH/cxx-friends.cpp =================================================================== --- clang/test/PCH/cxx-friends.cpp +++ clang/test/PCH/cxx-friends.cpp @@ -5,6 +5,10 @@ // RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-friends.h // RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s -error-on-deserialized-decl doNotDeserialize +// Test with pch and template instantiation in the pch. +// RUN: %clang_cc1 -x c++-header -emit-pch -fpch-instantiate-templates -o %t %S/cxx-friends.h +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s -error-on-deserialized-decl doNotDeserialize + // Test with modules. // RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-friends.h -fmodules // RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s -error-on-deserialized-decl doNotDeserialize -fmodules Index: clang/test/PCH/cxx-member-init.cpp =================================================================== --- clang/test/PCH/cxx-member-init.cpp +++ clang/test/PCH/cxx-member-init.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -x c++ -std=c++11 -DHEADER -emit-pch -o %t %s // RUN: %clang_cc1 -x c++ -std=c++11 -DHEADER -include-pch %t -fsyntax-only -emit-llvm -o - %s +// RUN: %clang_cc1 -x c++ -std=c++11 -DHEADER -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -x c++ -std=c++11 -DHEADER -include-pch %t -fsyntax-only -emit-llvm -o - %s + #ifdef HEADER int n; struct S { Index: clang/test/PCH/cxx-ms-function-specialization-class-scope.cpp =================================================================== --- clang/test/PCH/cxx-ms-function-specialization-class-scope.cpp +++ clang/test/PCH/cxx-ms-function-specialization-class-scope.cpp @@ -1,6 +1,9 @@ // REQUIRES: x86-registered-target // RUN: %clang_cc1 -fms-extensions -triple i386-unknown-unknown -x c++-header -emit-pch -o %t %S/cxx-ms-function-specialization-class-scope.h // RUN: %clang_cc1 -fms-extensions -triple i386-unknown-unknown -include-pch %t -fsyntax-only -verify %s + +// RUN: %clang_cc1 -fms-extensions -triple i386-unknown-unknown -x c++-header -emit-pch -fpch-instantiate-templates -o %t %S/cxx-ms-function-specialization-class-scope.h +// RUN: %clang_cc1 -fms-extensions -triple i386-unknown-unknown -include-pch %t -fsyntax-only -verify %s // expected-no-diagnostics Index: clang/test/PCH/cxx-static_assert.cpp =================================================================== --- clang/test/PCH/cxx-static_assert.cpp +++ clang/test/PCH/cxx-static_assert.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s // RUN: %clang_cc1 -include-pch %t -verify -std=c++11 %s +// RUN: %clang_cc1 -std=c++11 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -include-pch %t -verify -std=c++11 %s + #ifndef HEADER #define HEADER @@ -14,7 +17,7 @@ #else -// expected-error@12 {{static_assert failed due to requirement '1 == 2' "N is not 2!"}} +// expected-error@15 {{static_assert failed due to requirement '1 == 2' "N is not 2!"}} T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}} T<2> t2; Index: clang/test/PCH/cxx-templates.cpp =================================================================== --- clang/test/PCH/cxx-templates.cpp +++ clang/test/PCH/cxx-templates.cpp @@ -17,6 +17,11 @@ // RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t -verify %s // RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s +// Test with pch and template instantiation in the pch. +// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fpch-instantiate-templates -x c++-header -emit-pch -o %t %S/cxx-templates.h +// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t -verify %s +// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s + // CHECK: define weak_odr {{.*}}void @_ZN2S4IiE1mEv // CHECK: define linkonce_odr {{.*}}void @_ZN2S3IiE1mEv Index: clang/test/PCH/cxx-variadic-templates-with-default-params.cpp =================================================================== --- clang/test/PCH/cxx-variadic-templates-with-default-params.cpp +++ clang/test/PCH/cxx-variadic-templates-with-default-params.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -std=c++11 -x c++-header -emit-pch -o %t %s // RUN: %clang_cc1 -std=c++11 -include-pch %t -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -x c++-header -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -std=c++11 -include-pch %t -fsyntax-only -verify %s + // expected-no-diagnostics // PR25271: Ensure that default template arguments prior to a parameter pack Index: clang/test/PCH/cxx-variadic-templates.cpp =================================================================== --- clang/test/PCH/cxx-variadic-templates.cpp +++ clang/test/PCH/cxx-variadic-templates.cpp @@ -7,6 +7,10 @@ // RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s -ast-dump -o - // RUN: %clang_cc1 -std=c++11 -include-pch %t %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -x c++-header -emit-pch -fpch-instantiate-templates -o %t %S/cxx-variadic-templates.h +// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s -ast-dump -o - +// RUN: %clang_cc1 -std=c++11 -include-pch %t %s -emit-llvm -o - | FileCheck %s + // expected-no-diagnostics // CHECK: allocate_shared Index: clang/test/PCH/cxx0x-default-delete.cpp =================================================================== --- clang/test/PCH/cxx0x-default-delete.cpp +++ clang/test/PCH/cxx0x-default-delete.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %s // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -include-pch %t %s +// RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -include-pch %t %s + #ifndef PASS1 #define PASS1 @@ -30,11 +33,11 @@ foo::foo() { } // expected-error{{definition of explicitly defaulted default constructor}} foo f; void fn() { - f.bar(); // expected-error{{deleted function}} expected-note@12{{deleted here}} + f.bar(); // expected-error{{deleted function}} expected-note@15{{deleted here}} } -baz bz; // expected-error{{deleted function}} expected-note@16{{deleted here}} -quux qx; // expected-error{{private destructor}} expected-note@20{{private here}} +baz bz; // expected-error{{deleted function}} expected-note@19{{deleted here}} +quux qx; // expected-error{{private destructor}} expected-note@23{{private here}} struct B { A a; }; struct C { mutable A a; }; Index: clang/test/PCH/cxx11-constexpr.cpp =================================================================== --- clang/test/PCH/cxx11-constexpr.cpp +++ clang/test/PCH/cxx11-constexpr.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED @@ -31,9 +34,9 @@ static_assert(D(4).k == 9, ""); constexpr int f(C c) { return 0; } // expected-error {{not a literal type}} -// expected-note@13 {{not an aggregate and has no constexpr constructors}} +// expected-note@16 {{not an aggregate and has no constexpr constructors}} constexpr B b; // expected-error {{constant expression}} expected-note {{non-constexpr}} - // expected-note@9 {{here}} + // expected-note@12 {{here}} static_assert(plus_seven(3) == 10, ""); Index: clang/test/PCH/cxx11-enum-template.cpp =================================================================== --- clang/test/PCH/cxx11-enum-template.cpp +++ clang/test/PCH/cxx11-enum-template.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED @@ -20,7 +23,7 @@ int k1 = (int)S::E::e; int k2 = (int)decltype(b)::e; -int k3 = (int)decltype(c)::e; // expected-error@10 {{conversion from 'double' to 'int'}} expected-note {{here}} +int k3 = (int)decltype(c)::e; // expected-error@13 {{conversion from 'double' to 'int'}} expected-note {{here}} int k4 = (int)S::E::e; #endif Index: clang/test/PCH/cxx11-exception-spec.cpp =================================================================== --- clang/test/PCH/cxx11-exception-spec.cpp +++ clang/test/PCH/cxx11-exception-spec.cpp @@ -2,6 +2,12 @@ // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.1 -emit-pch %s -o %t.2 // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.2 -verify %s // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.2 -emit-llvm-only %s + +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch -fpch-instantiate-templates %s -o %t.1 +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.1 -emit-pch -fpch-instantiate-templates %s -o %t.2 +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.2 -verify %s +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.2 -emit-llvm-only %s + // expected-no-diagnostics #ifndef PHASE1_DONE Index: clang/test/PCH/cxx11-inheriting-ctors.cpp =================================================================== --- clang/test/PCH/cxx11-inheriting-ctors.cpp +++ clang/test/PCH/cxx11-inheriting-ctors.cpp @@ -4,10 +4,17 @@ // RxN: %clang_cc1 -std=c++11 -emit-pch -o %t.12 -include %s %s // RxN: %clang_cc1 -std=c++11 -include-pch %t.12 -verify %s // +// RxN: %clang_cc1 -std=c++11 -emit-pch -fpch-instantiate-templates -o %t.12 -include %s %s +// RxN: %clang_cc1 -std=c++11 -include-pch %t.12 -verify %s +// // Emit with definitions in update records: // RxN: %clang_cc1 -std=c++11 -emit-pch -o %t.1 %s // RxN: %clang_cc1 -std=c++11 -include-pch %t.1 -emit-pch -o %t.2 -verify %s // RxN: %clang_cc1 -std=c++11 -include-pch %t.1 -include-pch %t.2 -verify %s +// +// RxN: %clang_cc1 -std=c++11 -emit-pch -fpch-instantiate-templates -o %t.1 %s +// RxN: %clang_cc1 -std=c++11 -include-pch %t.1 -emit-pch -fpch-instantiate-templates -o %t.2 -verify %s +// RxN: %clang_cc1 -std=c++11 -include-pch %t.1 -include-pch %t.2 -verify %s // expected-no-diagnostics Index: clang/test/PCH/cxx11-user-defined-literals.cpp =================================================================== --- clang/test/PCH/cxx11-user-defined-literals.cpp +++ clang/test/PCH/cxx11-user-defined-literals.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED @@ -17,6 +20,6 @@ int *l = f(&k); struct S {}; int m = f(S()); // expected-error {{no matching}} - // expected-note@11 {{substitution failure}} + // expected-note@14 {{substitution failure}} #endif Index: clang/test/PCH/cxx1y-decltype-auto.cpp =================================================================== --- clang/test/PCH/cxx1y-decltype-auto.cpp +++ clang/test/PCH/cxx1y-decltype-auto.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED @@ -18,7 +21,7 @@ int x : 5; // expected-note {{bit-field}} }; -// expected-error@12 {{non-const reference cannot bind to bit-field 'x'}} +// expected-error@15 {{non-const reference cannot bind to bit-field 'x'}} template void f(Z); // expected-note {{in instantiation of}} #endif Index: clang/test/PCH/cxx1y-deduced-return-type.cpp =================================================================== --- clang/test/PCH/cxx1y-deduced-return-type.cpp +++ clang/test/PCH/cxx1y-deduced-return-type.cpp @@ -6,6 +6,10 @@ // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch %s -o %t.b // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch -fpch-instantiate-templates %s -o %t.a +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch -fpch-instantiate-templates %s -o %t.b +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s + // expected-no-diagnostics #if !defined(HEADER1) Index: clang/test/PCH/cxx1y-default-initializer.cpp =================================================================== --- clang/test/PCH/cxx1y-default-initializer.cpp +++ clang/test/PCH/cxx1y-default-initializer.cpp @@ -3,6 +3,10 @@ // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.1 -emit-pch -o %t.2 %s // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.2 -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch -fpch-instantiate-templates -o %t.1 %s +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.1 -emit-pch -fpch-instantiate-templates -o %t.2 %s +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.2 -verify %s + #ifndef HEADER_1 #define HEADER_1 Index: clang/test/PCH/cxx1y-init-captures.cpp =================================================================== --- clang/test/PCH/cxx1y-init-captures.cpp +++ clang/test/PCH/cxx1y-init-captures.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s + #ifndef HEADER #define HEADER @@ -21,7 +24,7 @@ void g() { f(0); // ok - // expected-error@15 {{lvalue of type 'const char *const'}} + // expected-error@18 {{lvalue of type 'const char *const'}} f("foo"); // expected-note {{here}} } Index: clang/test/PCH/cxx1y-variable-templates.cpp =================================================================== --- clang/test/PCH/cxx1y-variable-templates.cpp +++ clang/test/PCH/cxx1y-variable-templates.cpp @@ -7,6 +7,10 @@ // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch %s -o %t.b -DHEADER2 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE +// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch -fpch-instantiate-templates %s -o %t.a -DHEADER1 +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch -fpch-instantiate-templates %s -o %t.b -DHEADER2 +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE + #ifndef ERROR // expected-no-diagnostics #endif @@ -89,8 +93,8 @@ namespace diff_types { #ifdef ERROR - template extern T err0; // expected-error {{redeclaration of 'err0' with a different type: 'T' vs 'float'}} // expected-note@42 {{previous declaration is here}} - template extern float err1; // expected-error {{redeclaration of 'err1' with a different type: 'float' vs 'T'}} // expected-note@43 {{previous declaration is here}} + template extern T err0; // expected-error {{redeclaration of 'err0' with a different type: 'T' vs 'float'}} // expected-note@46 {{previous declaration is here}} + template extern float err1; // expected-error {{redeclaration of 'err1' with a different type: 'float' vs 'T'}} // expected-note@47 {{previous declaration is here}} #endif template extern T def; } Index: clang/test/PCH/cxx1z-aligned-alloc.cpp =================================================================== --- clang/test/PCH/cxx1z-aligned-alloc.cpp +++ clang/test/PCH/cxx1z-aligned-alloc.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -include-pch %t -verify %s + // expected-no-diagnostics #ifndef HEADER Index: clang/test/PCH/cxx1z-decomposition.cpp =================================================================== --- clang/test/PCH/cxx1z-decomposition.cpp +++ clang/test/PCH/cxx1z-decomposition.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s + #ifndef HEADER #define HEADER @@ -26,7 +29,7 @@ static_assert(foo({1, 2}) == 12); -// expected-error@12 {{cannot decompose non-class, non-array type 'const int'}} +// expected-error@15 {{cannot decompose non-class, non-array type 'const int'}} int z = decomp(10); // expected-note {{instantiation of}} #endif Index: clang/test/PCH/cxx1z-using-declaration.cpp =================================================================== --- clang/test/PCH/cxx1z-using-declaration.cpp +++ clang/test/PCH/cxx1z-using-declaration.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch %s -o %t // RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s + #ifndef HEADER #define HEADER @@ -25,10 +28,10 @@ a.g(); a.g(0); a.g(0, 0); - // expected-error@13 {{no match}} - // expected-note@16 {{candidate}} - // expected-note@17 {{candidate}} - // expected-note@18 {{candidate}} + // expected-error@16 {{no match}} + // expected-note@19 {{candidate}} + // expected-note@20 {{candidate}} + // expected-note@21 {{candidate}} a.g(0, 0, 0); // expected-note {{instantiation of}} } Index: clang/test/PCH/cxx2a-bitfield-init.cpp =================================================================== --- clang/test/PCH/cxx2a-bitfield-init.cpp +++ clang/test/PCH/cxx2a-bitfield-init.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -std=c++2a -include %s -verify %s // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t // RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s -DPCH +// RUN: %clang_cc1 -std=c++2a -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s -DPCH #ifndef HEADER #define HEADER Index: clang/test/PCH/cxx2a-concept-specialization-expr.cpp =================================================================== --- clang/test/PCH/cxx2a-concept-specialization-expr.cpp +++ clang/test/PCH/cxx2a-concept-specialization-expr.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t // RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s +// RUN: %clang_cc1 -std=c++2a -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s + // expected-no-diagnostics #ifndef HEADER Index: clang/test/PCH/cxx2a-constraints.cpp =================================================================== --- clang/test/PCH/cxx2a-constraints.cpp +++ clang/test/PCH/cxx2a-constraints.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t // RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s +// RUN: %clang_cc1 -std=c++2a -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s + // expected-no-diagnostics #ifndef HEADER Index: clang/test/PCH/cxx2a-defaulted-comparison.cpp =================================================================== --- clang/test/PCH/cxx2a-defaulted-comparison.cpp +++ clang/test/PCH/cxx2a-defaulted-comparison.cpp @@ -2,6 +2,9 @@ // // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t.pch // RUN: %clang_cc1 -std=c++2a -include-pch %t.pch %s -verify +// +// RUN: %clang_cc1 -std=c++2a -emit-pch -fpch-instantiate-templates %s -o %t.pch +// RUN: %clang_cc1 -std=c++2a -include-pch %t.pch %s -verify // expected-no-diagnostics Index: clang/test/PCH/cxx2a-requires-expr.cpp =================================================================== --- clang/test/PCH/cxx2a-requires-expr.cpp +++ clang/test/PCH/cxx2a-requires-expr.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -emit-pch -std=c++2a -o %t %s // RUN: %clang_cc1 -std=c++2a -x ast -ast-print %t | FileCheck %s +// RUN: %clang_cc1 -emit-pch -std=c++2a -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -std=c++2a -x ast -ast-print %t | FileCheck %s + template concept C = true; Index: clang/test/PCH/cxx2a-template-lambdas.cpp =================================================================== --- clang/test/PCH/cxx2a-template-lambdas.cpp +++ clang/test/PCH/cxx2a-template-lambdas.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t // RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s +// RUN: %clang_cc1 -std=c++2a -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s + // expected-no-diagnostics #ifndef HEADER Index: clang/test/PCH/delayed-pch-instantiate.cpp =================================================================== --- /dev/null +++ clang/test/PCH/delayed-pch-instantiate.cpp @@ -0,0 +1,30 @@ +// Test this without pch. +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -DBODY %s -o - | FileCheck %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -include-pch %t -DBODY %s -o - | FileCheck %s + +// RUN: %clang_cc1 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -include-pch %t -DBODY %s -o - | FileCheck %s + +// expected-no-diagnostics + +#ifndef HEADER_H +#define HEADER_H +struct A { + void foo() { bar<0>(); } // This will trigger implicit instantiation of bar<0>() in the PCH. + template + void bar(); +}; +#endif + +#ifdef BODY +// But the definition is only in the source, so the instantiation must be delayed until the TU. +template +void A::bar() {} + +void test(A *a) { a->foo(); } +#endif + +// CHECK: define linkonce_odr void @_ZN1A3barILi0EEEvv Index: clang/test/PCH/friend-template.cpp =================================================================== --- clang/test/PCH/friend-template.cpp +++ clang/test/PCH/friend-template.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -emit-pch -o %t %s // RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s +// RUN: %clang_cc1 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s + // expected-no-diagnostics #ifndef HEADER Index: clang/test/PCH/implicitly-deleted.cpp =================================================================== --- clang/test/PCH/implicitly-deleted.cpp +++ clang/test/PCH/implicitly-deleted.cpp @@ -1,5 +1,9 @@ // RUN: %clang_cc1 -std=c++11 -x c++-header %s -emit-pch -o %t.pch // RUN: %clang_cc1 -std=c++11 -x c++ /dev/null -include-pch %t.pch + +// RUN: %clang_cc1 -std=c++11 -x c++-header %s -emit-pch -fpch-instantiate-templates -o %t.pch +// RUN: %clang_cc1 -std=c++11 -x c++ /dev/null -include-pch %t.pch + class move_only { move_only(const move_only&) = delete; move_only(move_only&&); }; struct sb { move_only il; Index: clang/test/PCH/late-parsed-instantiations.cpp =================================================================== --- clang/test/PCH/late-parsed-instantiations.cpp +++ clang/test/PCH/late-parsed-instantiations.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -emit-pch %s -o %t.pch -verify // RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -include-pch %t.pch %s -verify +// RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -emit-pch -fpch-instantiate-templates %s -o %t.pch -verify +// RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -include-pch %t.pch %s -verify + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED Index: clang/test/PCH/local_static.cpp =================================================================== --- clang/test/PCH/local_static.cpp +++ clang/test/PCH/local_static.cpp @@ -8,6 +8,10 @@ // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -include-pch %t.pch -emit-llvm -o %t.pch.ll %s // RUN: FileCheck --input-file %t.pch.ll %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -x c++-header -emit-pch -fpch-instantiate-templates -o %t.pch %S/local_static.h +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -include-pch %t.pch -emit-llvm -o %t.pch.ll %s +// RUN: FileCheck --input-file %t.pch.ll %s + void test(Bar &b) { b.f(); static int s; Index: clang/test/PCH/macro-undef.cpp =================================================================== --- clang/test/PCH/macro-undef.cpp +++ clang/test/PCH/macro-undef.cpp @@ -2,31 +2,35 @@ // RUN: %clang_cc1 -std=c++98 -fsyntax-only -include-pch %t %s -Wuninitialized -verify // RUN: %clang_cc1 -std=c++98 -fsyntax-only -include-pch %t %s -Wuninitialized -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s +// RUN: %clang_cc1 -std=c++98 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -include-pch %t %s -Wuninitialized -verify +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -include-pch %t %s -Wuninitialized -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s + #ifndef HEADER #define HEADER #define NULL 0 template void *f() { - void *p; // @11 - return p; // @12 + void *p; // @15 + return p; // @16 } #undef NULL template void *g() { - void *p; // @17 - return p; // @18 + void *p; // @21 + return p; // @22 } #else -// expected-warning@12 {{uninitialized}} -// expected-note@11 {{initialize}} -// CHECK: fix-it:"{{.*}}":{11:10-11:10}:" = NULL" +// expected-warning@16 {{uninitialized}} +// expected-note@15 {{initialize}} +// CHECK: fix-it:"{{.*}}":{15:10-15:10}:" = NULL" -// expected-warning@18 {{uninitialized}} -// expected-note@17 {{initialize}} -// CHECK: fix-it:"{{.*}}":{17:10-17:10}:" = 0" +// expected-warning@22 {{uninitialized}} +// expected-note@21 {{initialize}} +// CHECK: fix-it:"{{.*}}":{21:10-21:10}:" = 0" int main() { f(); // expected-note {{instantiation}} Index: clang/test/PCH/make-integer-seq.cpp =================================================================== --- clang/test/PCH/make-integer-seq.cpp +++ clang/test/PCH/make-integer-seq.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++14 -x c++-header %s -emit-pch -o %t.pch // RUN: %clang_cc1 -std=c++14 -x c++ /dev/null -include-pch %t.pch +// RUN: %clang_cc1 -std=c++14 -x c++-header %s -emit-pch -fpch-instantiate-templates -o %t.pch +// RUN: %clang_cc1 -std=c++14 -x c++ /dev/null -include-pch %t.pch + template struct Seq { static constexpr T PackSize = sizeof...(I); Index: clang/test/PCH/ms-if-exists.cpp =================================================================== --- clang/test/PCH/ms-if-exists.cpp +++ clang/test/PCH/ms-if-exists.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -x c++ -fms-extensions -fsyntax-only -emit-pch -o %t %s // RUN: %clang_cc1 -x c++ -fms-extensions -fsyntax-only -include-pch %t %s -verify +// RUN: %clang_cc1 -x c++ -fms-extensions -fsyntax-only -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -x c++ -fms-extensions -fsyntax-only -include-pch %t %s -verify + #ifndef HEADER #define HEADER template @@ -25,6 +28,6 @@ }; template void f(HasFoo); // expected-note{{in instantiation of function template specialization 'f' requested here}} - // expected-error@14{{no viable conversion from 'HasFoo' to 'int *'}} + // expected-error@17{{no viable conversion from 'HasFoo' to 'int *'}} template void f(HasBar); #endif Index: clang/test/PCH/pch-instantiate-templates-forward-decl.cpp =================================================================== --- /dev/null +++ clang/test/PCH/pch-instantiate-templates-forward-decl.cpp @@ -0,0 +1,30 @@ +// Test this without pch. +// RUN: %clang_cc1 -fsyntax-only %s -DBODY + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %s +// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s -DBODY + +// Test with pch with template instantiation in the pch. +// RUN: %clang_cc1 -emit-pch -fpch-instantiate-templates -o %t %s -verify + +#ifndef HEADER_H +#define HEADER_H + +template +void f(); +struct X; // @16 +void g() { f(); } // @17 instantiation not performed yet + +template +void f() { T t; }; // @20 + +#endif + +#ifdef BODY +struct X {}; +#endif + +// expected-error@20 {{variable has incomplete type}} +// expected-note@17 {{in instantiation of function template specialization}} +// expected-note@16 {{forward declaration}} Index: clang/test/PCH/pch-instantiate-templates.cpp =================================================================== --- /dev/null +++ clang/test/PCH/pch-instantiate-templates.cpp @@ -0,0 +1,28 @@ +// Test this without pch, template will be instantiated. +// RUN: %clang_cc1 -fsyntax-only %s -verify=expected + +// Test with pch, template will be instantiated in the TU. +// RUN: %clang_cc1 -emit-pch -o %t %s -verify=ok +// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s -verify=expected + +// Test with pch with template instantiation in the pch. +// RUN: %clang_cc1 -emit-pch -fpch-instantiate-templates -o %t %s -verify=expected + +// ok-no-diagnostics + +#ifndef HEADER_H +#define HEADER_H + +template +struct A { + T foo() const { return "test"; } // @18 +}; + +double bar(A *a) { + return a->foo(); // @22 +} + +#endif + +// expected-error@18 {{cannot initialize return object}} +// expected-note@22 {{in instantiation of member function}} Index: clang/test/PCH/pr18806.cpp =================================================================== --- clang/test/PCH/pr18806.cpp +++ clang/test/PCH/pr18806.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s // RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s +// RUN: %clang_cc1 -std=c++11 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s + // expected-no-diagnostics // Before the patch, this test triggered an assert violation in Index: clang/test/PCH/pragma-diag-section.cpp =================================================================== --- clang/test/PCH/pragma-diag-section.cpp +++ clang/test/PCH/pragma-diag-section.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 %s -emit-pch -o %t // RUN: %clang_cc1 %s -include-pch %t -verify -fsyntax-only -Wuninitialized +// RUN: %clang_cc1 %s -emit-pch -fpch-instantiate-templates -o %t +// RUN: %clang_cc1 %s -include-pch %t -verify -fsyntax-only -Wuninitialized + #ifndef HEADER #define HEADER @@ -27,8 +30,8 @@ void m() { T a; T b = a; // expected-warning {{variable 'a' is uninitialized}} \ - expected-note@41 {{in instantiation of member function}} \ - expected-note@28 {{initialize the variable 'a' to silence}} + expected-note@44 {{in instantiation of member function}} \ + expected-note@31 {{initialize the variable 'a' to silence}} } }; Index: clang/test/PCH/rdar10830559.cpp =================================================================== --- clang/test/PCH/rdar10830559.cpp +++ clang/test/PCH/rdar10830559.cpp @@ -6,6 +6,9 @@ // RUN: %clang_cc1 -emit-pch -o %t %s // RUN: %clang_cc1 -include-pch %t -emit-llvm-only %t.empty.cpp +// RUN: %clang_cc1 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -include-pch %t -emit-llvm-only %t.empty.cpp + // rdar://10830559 //#pragma ms_struct on Index: clang/test/PCH/specialization-after-instantiation.cpp =================================================================== --- /dev/null +++ clang/test/PCH/specialization-after-instantiation.cpp @@ -0,0 +1,32 @@ +// Test this without pch. +// RUN: %clang_cc1 -fsyntax-only -verify -DBODY %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %s +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify -DBODY %s + +// RUN: %clang_cc1 -emit-pch -fpch-instantiate-templates -o %t %s +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify -DBODY %s + +#ifndef HEADER_H +#define HEADER_H + +template +struct A { + int foo() const; +}; + +int bar(A *a) { + return a->foo(); +} + +#endif // HEADER_H + +#ifdef BODY + +template <> +int A::foo() const { // expected-error {{explicit specialization of 'foo' after instantiation}} // expected-note@20 {{implicit instantiation first required here}} + return 10; +} + +#endif // BODY Index: clang/test/PCH/type_pack_element.cpp =================================================================== --- clang/test/PCH/type_pack_element.cpp +++ clang/test/PCH/type_pack_element.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++14 -x c++-header %s -emit-pch -o %t.pch // RUN: %clang_cc1 -std=c++14 -x c++ /dev/null -include-pch %t.pch +// RUN: %clang_cc1 -std=c++14 -x c++-header %s -emit-pch -fpch-instantiate-templates -o %t.pch +// RUN: %clang_cc1 -std=c++14 -x c++ /dev/null -include-pch %t.pch + template struct X { };