diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -329,6 +329,8 @@ InGroup; def warn_drv_pch_not_first_include : Warning< "precompiled header '%0' was ignored because '%1' is not first '-include'">; +def warn_drv_multiple_include_pch : Warning< + "-include-pch passed multiple times but only the last '%0' is being used">; def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">, InGroup>; def warn_incompatible_sysroot : Warning<"using sysroot for '%0' but targeting '%1'">, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3576,7 +3576,13 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action) { - Opts.ImplicitPCHInclude = std::string(Args.getLastArgValue(OPT_include_pch)); + auto allPchFiles = Args.getAllArgValues(OPT_include_pch); + if (!allPchFiles.empty()) { + Opts.ImplicitPCHInclude = std::string(allPchFiles.back()); + if (allPchFiles.size() > 1) + Diags.Report(diag::warn_drv_multiple_include_pch) + << Opts.ImplicitPCHInclude; + } Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) || Args.hasArg(OPT_pch_through_hdrstop_use); Opts.PCHWithHdrStopCreate = Args.hasArg(OPT_pch_through_hdrstop_create); diff --git a/clang/test/PCH/multiple-include-pch-warning.c b/clang/test/PCH/multiple-include-pch-warning.c new file mode 100644 --- /dev/null +++ b/clang/test/PCH/multiple-include-pch-warning.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-pch -o %t1.pch %s +// RUN: %clang_cc1 -emit-pch -o %t2.pch %s +// RUN: %clang_cc1 %s -include-pch %t1.pch -include-pch %t2.pch 2>&1 | FileCheck %s + +// CHECK: warning: -include-pch passed multiple times but only the last '{{.*\.pch}}' is being used