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
This commit is contained in:
Nico Weber
2020-02-24 16:07:16 -05:00
parent e5513336ae
commit bcda1269c4
7 changed files with 64 additions and 19 deletions

View File

@@ -156,8 +156,9 @@ def _SLASH_Qvec : CLFlag<"Qvec">,
def _SLASH_Qvec_ : CLFlag<"Qvec-">,
HelpText<"Disable the loop vectorization passes">, Alias<fno_vectorize>;
def _SLASH_showIncludes : CLFlag<"showIncludes">,
HelpText<"Print info about included files to stderr">,
Alias<show_includes>;
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-">,

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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 <command line>
// header.

View File

@@ -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

View File

@@ -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: <command line>
// 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: <command line>
// 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 <noline.h>
#include "Inputs/test.h"

View File

@@ -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