Index: include/clang/Frontend/Utils.h =================================================================== --- include/clang/Frontend/Utils.h +++ include/clang/Frontend/Utils.h @@ -145,6 +145,19 @@ void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, StringRef SysRoot); +enum IncludeGenShowHeadersKind { + // Don't print headers from the predefines buffer (i.e. from -include flags). + IGSHK_OmitPredefines, + + // Print headers from the predefines buffer scoped under a "" + // item. + IGSHK_ScopePredefines, + + // Print headers from the predefines buffer without scoping, as if they were + // included by the main translation unit. + IGSHK_InlinePredefines, +}; + /// AttachHeaderIncludeGen - Create a header include list generator, and attach /// it to the given preprocessor. /// @@ -159,11 +172,10 @@ /// information to, instead of writing to stderr. /// \param ShowDepth - Whether to indent to show the nesting of the includes. /// \param MSStyle - Whether to print in cl.exe /showIncludes style. -void AttachHeaderIncludeGen(Preprocessor &PP, - const std::vector &ExtraHeaders, - bool ShowAllHeaders = false, - StringRef OutputPath = "", - bool ShowDepth = true, bool MSStyle = false); +void AttachHeaderIncludeGen( + Preprocessor &PP, const std::vector &ExtraHeaders, + IncludeGenShowHeadersKind ShowAllHeaders = IGSHK_OmitPredefines, + StringRef OutputPath = "", bool ShowDepth = true, bool MSStyle = false); /// Cache tokens for use with PCH. Note that this requires a seekable stream. void CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS); Index: lib/Frontend/CompilerInstance.cpp =================================================================== --- lib/Frontend/CompilerInstance.cpp +++ lib/Frontend/CompilerInstance.cpp @@ -366,13 +366,13 @@ if (OutputPath == "-") OutputPath = ""; AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps, - /*ShowAllHeaders=*/true, OutputPath, + IGSHK_ScopePredefines, OutputPath, /*ShowDepth=*/false); } if (DepOpts.PrintShowIncludes) { AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps, - /*ShowAllHeaders=*/false, /*OutputPath=*/"", + IGSHK_InlinePredefines, /*OutputPath=*/"", /*ShowDepth=*/true, /*MSStyle=*/true); } } Index: lib/Frontend/HeaderIncludeGen.cpp =================================================================== --- lib/Frontend/HeaderIncludeGen.cpp +++ lib/Frontend/HeaderIncludeGen.cpp @@ -21,22 +21,23 @@ raw_ostream *OutputFile; const std::vector &ExtraHeaders; unsigned CurrentIncludeDepth; + IncludeGenShowHeadersKind ShowAllHeaders; bool HasProcessedPredefines; bool OwnsOutputFile; - bool ShowAllHeaders; bool ShowDepth; bool MSStyle; bool PrintedExtraHeaders; public: - HeaderIncludesCallback(const Preprocessor *PP, bool ShowAllHeaders_, + HeaderIncludesCallback(const Preprocessor *PP, + IncludeGenShowHeadersKind ShowAllHeaders_, raw_ostream *OutputFile_, const std::vector &ExtraHeaders, bool OwnsOutputFile_, bool ShowDepth_, bool MSStyle_) : SM(PP->getSourceManager()), OutputFile(OutputFile_), ExtraHeaders(ExtraHeaders), CurrentIncludeDepth(0), - HasProcessedPredefines(false), OwnsOutputFile(OwnsOutputFile_), - ShowAllHeaders(ShowAllHeaders_), ShowDepth(ShowDepth_), + ShowAllHeaders(ShowAllHeaders_), HasProcessedPredefines(false), + OwnsOutputFile(OwnsOutputFile_), ShowDepth(ShowDepth_), MSStyle(MSStyle_), PrintedExtraHeaders(false) {} ~HeaderIncludesCallback() override { @@ -79,7 +80,7 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, const std::vector &ExtraHeaders, - bool ShowAllHeaders, + IncludeGenShowHeadersKind ShowAllHeaders, StringRef OutputPath, bool ShowDepth, bool MSStyle) { raw_ostream *OutputFile = MSStyle ? &llvm::outs() : &llvm::errs(); @@ -146,13 +147,25 @@ // Show the header if we are (a) past the predefines, or (b) showing all // headers and in the predefines at a depth past the initial file and command // line buffers. - bool ShowHeader = (HasProcessedPredefines || - (ShowAllHeaders && CurrentIncludeDepth > 2)); - + bool ShowHeader = false; + unsigned IncludeDepth = CurrentIncludeDepth; + if (HasProcessedPredefines) + ShowHeader = true; + else { + if (ShowAllHeaders == IGSHK_ScopePredefines && CurrentIncludeDepth > 2) + ShowHeader = true; + else if (ShowAllHeaders == IGSHK_InlinePredefines && + CurrentIncludeDepth > 3) { + ShowHeader = true; + // Ignore indent relative to and . + IncludeDepth -= 2; + } + } + // Dump the header include information we are past the predefines buffer or // are showing all headers. if (ShowHeader && Reason == PPCallbacks::EnterFile) { - PrintHeaderInfo(OutputFile, UserLoc.getFilename(), - ShowDepth, CurrentIncludeDepth, MSStyle); + PrintHeaderInfo(OutputFile, UserLoc.getFilename(), ShowDepth, IncludeDepth, + MSStyle); } } Index: test/Driver/cl-pch-showincludes.cpp =================================================================== --- test/Driver/cl-pch-showincludes.cpp +++ test/Driver/cl-pch-showincludes.cpp @@ -8,16 +8,17 @@ // When building the pch, header1.h (included by header2.h), header2.h (the pch // input itself) and header3.h (included directly, above) should be printed. -// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Ycheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-YC %s -// CHECK-YC: Note: including file: {{.+header2.h}} -// CHECK-YC: Note: including file: {{.+header1.h}} -// CHECK-YC: Note: including file: {{.+header3.h}} +// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Ycheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s \ +// RUN: | FileCheck --strict-whitespace -check-prefix=CHECK-YC %s +// CHECK-YC: Note: including file: {{[^ ]*header2.h}} +// FIXME: header1.h should be indented one more: +// CHECK-YC: Note: including file: {{[^ ]*header1.h}} +// CHECK-YC: Note: including file: {{[^ ]*header3.h}} // When using the pch, only the direct include is printed. -// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Yuheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-YU %s +// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Yuheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s \ +// RUN: | FileCheck --strict-whitespace -check-prefix=CHECK-YU %s // CHECK-YU-NOT: Note: including file: {{.*pch}} // CHECK-YU-NOT: Note: including file: {{.*header1.h}} // CHECK-YU-NOT: Note: including file: {{.*header2.h}} -// CHECK-YU: Note: including file: {{.+header3.h}} +// CHECK-YU: Note: including file: {{[^ ]*header3.h}} Index: test/Frontend/print-header-includes.c =================================================================== --- test/Frontend/print-header-includes.c +++ test/Frontend/print-header-includes.c @@ -1,24 +1,24 @@ -// RUN: cd %S -// RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.stderr +// RUN: %clang_cc1 -I%S -include Inputs/test3.h -E -H -o /dev/null %s 2> %t.stderr // RUN: FileCheck < %t.stderr %s // CHECK-NOT: test3.h // CHECK: . {{.*test.h}} // CHECK: .. {{.*test2.h}} -// RUN: %clang_cc1 -include Inputs/test3.h -E --show-includes -o %t.out %s > %t.stdout -// RUN: FileCheck --check-prefix=MS < %t.stdout %s -// MS-NOT: test3.h -// MS: Note: including file: {{.*test.h}} -// MS: Note: including file: {{.*test2.h}} +// RUN: %clang_cc1 -I%S -include Inputs/test3.h -E --show-includes -o /dev/null %s | \ +// RUN: FileCheck --strict-whitespace --check-prefix=MS %s +// MS-NOT: +// MS: Note: including file: {{[^ ]*test3.h}} +// MS: Note: including file: {{[^ ]*test.h}} +// MS: Note: including file: {{[^ ]*test2.h}} // MS-NOT: Note // RUN: echo "fun:foo" > %t.blacklist -// RUN: %clang_cc1 -fsanitize=address -fdepfile-entry=%t.blacklist -E --show-includes -o %t.out %s > %t.stdout -// RUN: FileCheck --check-prefix=MS-BLACKLIST < %t.stdout %s -// MS-BLACKLIST: Note: including file: {{.*\.blacklist}} -// MS-BLACKLIST: Note: including file: {{.*test.h}} -// MS-BLACKLIST: Note: including file: {{.*test2.h}} +// RUN: %clang_cc1 -I%S -fsanitize=address -fdepfile-entry=%t.blacklist -E --show-includes -o /dev/null %s | \ +// RUN: FileCheck --strict-whitespace --check-prefix=MS-BLACKLIST %s +// MS-BLACKLIST: Note: including file: {{[^ ]*\.blacklist}} +// MS-BLACKLIST: Note: including file: {{[^ ]*test.h}} +// MS-BLACKLIST: Note: including file: {{[^ ]*test2.h}} // MS-BLACKLIST-NOT: Note #include "Inputs/test.h"