From bcda1269c4c4d5d19d2be425c0a52d19fe09f146 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 24 Feb 2020 16:07:16 -0500 Subject: [PATCH] clang-cl: Add a `/showIncludes:user` flag. This flag is like /showIncludes, but it only includes user headers and omits system headers (similar to MD and MMD). The motivation is that projects that already track system includes though other means can use this flag to get consistent behavior on Windows and non-Windows, and it saves tools that output /showIncludes output (e.g. ninja) some work. implementation-wise, this makes `HeaderIncludesCallback` honor the existing `IncludeSystemHeaders` bit, and changes the three clients of `HeaderIncludesCallback` (`/showIncludes`, `-H`, `CC_PRINT_HEADERS=1`) to pass `-sys-header-deps` to set that bit -- except for `/showIncludes:user`, which doesn't pass it. Differential Revision: https://reviews.llvm.org/D75093 --- clang/include/clang/Driver/CLCompatOptions.td | 5 +++-- clang/lib/Driver/ToolChains/Clang.cpp | 16 ++++++++++++++-- clang/lib/Frontend/DependencyFile.cpp | 11 ++++++----- clang/lib/Frontend/HeaderIncludeGen.cpp | 7 +++++-- clang/test/Driver/cl-options.c | 10 ++++++++-- clang/test/Frontend/print-header-includes.c | 27 +++++++++++++++++++++++---- clang/test/Preprocessor/headermap-rel2.c | 7 +++++-- 7 files changed, 64 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td index 561746d..17d248a 100644 --- a/clang/include/clang/Driver/CLCompatOptions.td +++ b/clang/include/clang/Driver/CLCompatOptions.td @@ -156,8 +156,9 @@ def _SLASH_Qvec : CLFlag<"Qvec">, def _SLASH_Qvec_ : CLFlag<"Qvec-">, HelpText<"Disable the loop vectorization passes">, Alias; def _SLASH_showIncludes : CLFlag<"showIncludes">, - HelpText<"Print info about included files to stderr">, - Alias; + HelpText<"Print info about included files to stderr">; +def _SLASH_showIncludes_user : CLFlag<"showIncludes:user">, + HelpText<"Like /showIncludes but omit system headers">; def _SLASH_showFilenames : CLFlag<"showFilenames">, HelpText<"Print the name of each compiled file">; def _SLASH_showFilenames_ : CLFlag<"showFilenames-">, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4bd0b5e..19a23c9 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4758,11 +4758,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } Args.AddAllArgs(CmdArgs, options::OPT_v); - Args.AddLastArg(CmdArgs, options::OPT_H); + + if (Args.getLastArg(options::OPT_H)) { + CmdArgs.push_back("-H"); + CmdArgs.push_back("-sys-header-deps"); + } + if (D.CCPrintHeaders && !D.CCGenDiagnostics) { CmdArgs.push_back("-header-include-file"); CmdArgs.push_back(D.CCPrintHeadersFilename ? D.CCPrintHeadersFilename : "-"); + CmdArgs.push_back("-sys-header-deps"); } Args.AddLastArg(CmdArgs, options::OPT_P); Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); @@ -6433,7 +6439,13 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back("--dependent-lib=oldnames"); } - Args.AddLastArg(CmdArgs, options::OPT_show_includes); + if (Arg *ShowIncludes = + Args.getLastArg(options::OPT__SLASH_showIncludes, + options::OPT__SLASH_showIncludes_user)) { + CmdArgs.push_back("--show-includes"); + if (ShowIncludes->getOption().matches(options::OPT__SLASH_showIncludes)) + CmdArgs.push_back("-sys-header-deps"); + } // This controls whether or not we emit RTTI data for polymorphic types. if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR, diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp index f39ffd8..c9240f4 100644 --- a/clang/lib/Frontend/DependencyFile.cpp +++ b/clang/lib/Frontend/DependencyFile.cpp @@ -137,9 +137,10 @@ struct DepCollectorASTListener : public ASTReaderListener { }; } // end anonymous namespace -void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule, - bool IsSystem, bool IsModuleFile, - bool IsMissing) { +void DependencyCollector::maybeAddDependency(StringRef Filename, + bool FromModule, bool IsSystem, + bool IsModuleFile, + bool IsMissing) { if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing)) addDependency(Filename); } @@ -160,8 +161,8 @@ static bool isSpecialFilename(StringRef Filename) { } bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule, - bool IsSystem, bool IsModuleFile, - bool IsMissing) { + bool IsSystem, bool IsModuleFile, + bool IsMissing) { return !isSpecialFilename(Filename) && (needSystemDependencies() || !IsSystem); } diff --git a/clang/lib/Frontend/HeaderIncludeGen.cpp b/clang/lib/Frontend/HeaderIncludeGen.cpp index 5f91157..97fac8a 100644 --- a/clang/lib/Frontend/HeaderIncludeGen.cpp +++ b/clang/lib/Frontend/HeaderIncludeGen.cpp @@ -127,8 +127,8 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, void HeaderIncludesCallback::FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind NewFileType, - FileID PrevFID) { + SrcMgr::CharacteristicKind NewFileType, + FileID PrevFID) { // Unless we are exiting a #include, make sure to skip ahead to the line the // #include directive was at. PresumedLoc UserLoc = SM.getPresumedLoc(Loc); @@ -167,6 +167,9 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc, else if (!DepOpts.ShowIncludesPretendHeader.empty()) ++IncludeDepth; // Pretend inclusion by ShowIncludesPretendHeader. + if (!DepOpts.IncludeSystemHeaders && isSystem(NewFileType)) + ShowHeader = false; + // Dump the header include information we are past the predefines buffer or // are showing all headers and this isn't the magic implicit // header. diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index f230caa..67744d9 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -199,10 +199,16 @@ // RUN: %clang_cl /Qvec /Qvec- -### -- %s 2>&1 | FileCheck -check-prefix=Qvec_ %s // Qvec_-NOT: -vectorize-loops -// RUN: %clang_cl /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes %s -// showIncludes: --show-includes +// RUN: %clang_cl /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_ %s +// showIncludes_: --show-includes +// showIncludes_: -sys-header-deps + +// RUN: %clang_cl /showIncludes:user -### -- %s 2>&1 | FileCheck -check-prefix=showIncludesUser %s +// showIncludesUser: --show-includes +// showIncludesUser-NOT: -sys-header-deps // RUN: %clang_cl /E /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s +// RUN: %clang_cl /E /showIncludes:user -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s // RUN: %clang_cl /EP /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s // RUN: %clang_cl /E /EP /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s // RUN: %clang_cl /EP /P /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s diff --git a/clang/test/Frontend/print-header-includes.c b/clang/test/Frontend/print-header-includes.c index 7da56e2..c5b711a 100644 --- a/clang/test/Frontend/print-header-includes.c +++ b/clang/test/Frontend/print-header-includes.c @@ -1,32 +1,51 @@ -// RUN: %clang_cc1 -I%S -include Inputs/test3.h -E -H -o /dev/null %s 2> %t.stderr +// RUN: %clang_cc1 -I%S -include Inputs/test3.h -isystem %S/Inputs/SystemHeaderPrefix \ +// RUN: -E -H -o /dev/null %s 2> %t.stderr // RUN: FileCheck < %t.stderr %s // CHECK-NOT: test3.h +// CHECK-NOT: . {{.*noline.h}} // CHECK: . {{.*test.h}} // CHECK: .. {{.*test2.h}} -// RUN: %clang_cc1 -I%S -include Inputs/test3.h --show-includes -o /dev/null %s | \ +// RUN: %clang_cc1 -I%S -include Inputs/test3.h -isystem %S/Inputs/SystemHeaderPrefix \ +// RUN: -E -H -sys-header-deps -o /dev/null %s 2> %t.stderr +// RUN: FileCheck --check-prefix SYSHEADERS < %t.stderr %s + +// SYSHEADERS-NOT: test3.h +// SYSHEADERS: . {{.*noline.h}} +// SYSHEADERS: . {{.*test.h}} +// SYSHEADERS: .. {{.*test2.h}} + +// RUN: %clang_cc1 -I%S -include Inputs/test3.h -isystem %S/Inputs/SystemHeaderPrefix \ +// RUN: --show-includes -o /dev/null %s | \ // RUN: FileCheck --strict-whitespace --check-prefix=MS-STDOUT %s // MS-STDOUT-NOT: +// MS-STDOUT-NOT: Note: including file: {{[^ ]*noline.h}} // MS-STDOUT: Note: including file: {{[^ ]*test3.h}} // MS-STDOUT: Note: including file: {{[^ ]*test.h}} // MS-STDOUT: Note: including file: {{[^ ]*test2.h}} // MS-STDOUT-NOT: Note -// RUN: %clang_cc1 -I%S -include Inputs/test3.h -E --show-includes -o /dev/null %s 2> %t.stderr +// RUN: %clang_cc1 -I%S -include Inputs/test3.h -isystem %S/Inputs/SystemHeaderPrefix \ +// RUN: -E --show-includes -o /dev/null %s 2> %t.stderr // RUN: FileCheck --strict-whitespace --check-prefix=MS-STDERR < %t.stderr %s // MS-STDERR-NOT: +// MS-STDERR-NOT: Note: including file: {{[^ ]*noline.h}} // MS-STDERR: Note: including file: {{[^ ]*test3.h}} // MS-STDERR: Note: including file: {{[^ ]*test.h}} // MS-STDERR: Note: including file: {{[^ ]*test2.h}} // MS-STDERR-NOT: Note // RUN: echo "fun:foo" > %t.blacklist -// RUN: %clang_cc1 -I%S -fsanitize=address -fdepfile-entry=%t.blacklist --show-includes -o /dev/null %s | \ +// RUN: %clang_cc1 -I%S -isystem %S/Inputs/SystemHeaderPrefix \ +// RUN: -fsanitize=address -fdepfile-entry=%t.blacklist \ +// RUN: --show-includes -o /dev/null %s | \ // RUN: FileCheck --strict-whitespace --check-prefix=MS-BLACKLIST %s // MS-BLACKLIST: Note: including file: {{[^ ]*\.blacklist}} +// MS-BLACKLIST-NOT: Note: including file: {{[^ ]*noline.h}} // MS-BLACKLIST: Note: including file: {{[^ ]*test.h}} // MS-BLACKLIST: Note: including file: {{[^ ]*test2.h}} // MS-BLACKLIST-NOT: Note +#include #include "Inputs/test.h" diff --git a/clang/test/Preprocessor/headermap-rel2.c b/clang/test/Preprocessor/headermap-rel2.c index 83e89f0..611ddd8 100644 --- a/clang/test/Preprocessor/headermap-rel2.c +++ b/clang/test/Preprocessor/headermap-rel2.c @@ -1,7 +1,10 @@ // RUN: rm -f %t.hmap // RUN: %hmaptool write %S/Inputs/headermap-rel2/project-headers.hmap.json %t.hmap -// RUN: %clang_cc1 -v -fsyntax-only %s -iquote %t.hmap -isystem %S/Inputs/headermap-rel2/system/usr/include -I %S/Inputs/headermap-rel2 -H -// RUN: %clang_cc1 -fsyntax-only %s -iquote %t.hmap -isystem %S/Inputs/headermap-rel2/system/usr/include -I %S/Inputs/headermap-rel2 -H 2> %t.out + +// RUN: %clang -fsyntax-only %s -iquote %t.hmap -isystem %S/Inputs/headermap-rel2/system/usr/include -I %S/Inputs/headermap-rel2 -H 2> %t.out +// RUN: FileCheck %s -input-file %t.out + +// RUN: env CC_PRINT_HEADERS=1 %clang -fsyntax-only %s -iquote %t.hmap -isystem %S/Inputs/headermap-rel2/system/usr/include -I %S/Inputs/headermap-rel2 2> %t.out // RUN: FileCheck %s -input-file %t.out // CHECK: Product/someheader.h -- 2.7.4