]> granicus.if.org Git - clang/commitdiff
clang-cl: Support /showIncludes
authorHans Wennborg <hans@hanshq.net>
Fri, 9 Aug 2013 00:32:23 +0000 (00:32 +0000)
committerHans Wennborg <hans@hanshq.net>
Fri, 9 Aug 2013 00:32:23 +0000 (00:32 +0000)
This option prints information about #included files to stderr. Clang could
already do it, this patch just teaches the existing code about the /showIncludes
style and adds the flag.

Differential Revision: http://llvm-reviews.chandlerc.com/D1333

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188037 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/Driver/CLCompatOptions.td
include/clang/Driver/Options.td
include/clang/Frontend/DependencyOutputOptions.h
include/clang/Frontend/Utils.h
lib/Driver/Tools.cpp
lib/Frontend/CompilerInstance.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Frontend/HeaderIncludeGen.cpp
test/Driver/cl-options.c
test/Frontend/print-header-includes.c

index 6ac40f5d208313049ee01367a4b8e4bb55ad1a1e..2774dc69f2ea46178cac26816028f6181afe4ee0 100644 (file)
@@ -221,6 +221,8 @@ def sys_header_deps : Flag<["-"], "sys-header-deps">,
   HelpText<"Include system headers in dependency output">;
 def header_include_file : Separate<["-"], "header-include-file">,
   HelpText<"Filename (or -) to write header include output to">;
+def show_includes : Flag<["--"], "show-includes">,
+  HelpText<"Print cl.exe style /showIncludes to stderr">;
 
 //===----------------------------------------------------------------------===//
 // Diagnostic Options
index d5251f6df2f042753f702266c972d5a5ca77ed3f..0fdd6f343a00b31e6055c52100bfcbb5720fb2d6 100644 (file)
@@ -68,6 +68,9 @@ def _SLASH_Oy_ : CLFlag<"Oy-">, HelpText<"Disable frame pointer omission">,
 def _SLASH_P : CLFlag<"P">, HelpText<"Only run the preprocessor">, Alias<E>;
 def _SLASH_QUESTION : CLFlag<"?">, Alias<help>,
   HelpText<"Display available options">;
+def _SLASH_showIncludes : CLFlag<"showIncludes">,
+  HelpText<"Print info about included files to stderr">,
+  Alias<show_includes>;
 def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
   MetaVarName<"<macro>">, Alias<U>;
 def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>;
@@ -130,7 +133,6 @@ def _SLASH_Gy : CLFlag<"Gy">;
 def _SLASH_Gy_ : CLFlag<"Gy-">;
 def _SLASH_GZ : CLFlag<"GZ">;
 def _SLASH_RTC : CLJoined<"RTC">;
-def _SLASH_showIncludes : CLJoined<"showIncludes">;
 def _SLASH_w : CLJoined<"w">;
 def _SLASH_Za : CLFlag<"Za">;
 def _SLASH_Zc : CLJoined<"Zc:">;
index 4598265aeb396818d33bcb118a7c193729f6b67c..ff48369d0876264bebc91dad279ec53809c4c36a 100644 (file)
@@ -1333,6 +1333,6 @@ def Z_reserved_lib_stdcxx : Flag<["-"], "Z-reserved-lib-stdc++">,
 def Z_reserved_lib_cckext : Flag<["-"], "Z-reserved-lib-cckext">,
     Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>;
 
-include "CLCompatOptions.td"
-
 include "CC1Options.td"
+
+include "CLCompatOptions.td"
index 83976c36048ff432b932bfd8e902db620d32659a..fefb6f3eda8408d7bc262c22da6f1038157fbd50 100644 (file)
@@ -25,6 +25,7 @@ public:
                                      /// dependency, which can avoid some 'make'
                                      /// problems.
   unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
+  unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
   
   /// The file to write dependency output to.
   std::string OutputFile;
@@ -48,6 +49,7 @@ public:
     ShowHeaderIncludes = 0;
     UsePhonyTargets = 0;
     AddMissingHeaderDeps = 0;
+    PrintShowIncludes = 0;
   }
 };
 
index d6ab03783768ae3d65ef5352f3201b5e1f176987..dff56c3a8a4eb0b43e6071587c882e61beb9be5e 100644 (file)
@@ -91,9 +91,11 @@ void AttachDependencyFileGen(Preprocessor &PP,
 /// the default behavior used by -H.
 /// \param OutputPath - If non-empty, a path to write the header include
 /// 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, bool ShowAllHeaders = false,
                             StringRef OutputPath = "",
-                            bool ShowDepth = true);
+                            bool ShowDepth = true, bool MSStyle = false);
 
 /// CacheTokens - Cache tokens for use with PCH. Note that this requires
 /// a seekable stream.
index 7724a1e6814feb85f2354eb7b64d6b7915535885..1d41b94b7f17cb683613924953bece5dad98055f 100644 (file)
@@ -3727,6 +3727,9 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
   // FIXME: Make this default for the win32 triple.
   CmdArgs.push_back("-cxx-abi");
   CmdArgs.push_back("microsoft");
+
+  if (Arg *A = Args.getLastArg(options::OPT_show_includes))
+    A->render(Args, CmdArgs);
 }
 
 void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
index f06eaf87360d10431c429d61b5944d027bdd9527..d2e93685062890ed1d9c85b83644f055711d7a4e 100644 (file)
@@ -259,7 +259,7 @@ void CompilerInstance::createPreprocessor() {
     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
                              getHeaderSearchOpts().Sysroot);
 
-  
+
   // Handle generating header include information, if requested.
   if (DepOpts.ShowHeaderIncludes)
     AttachHeaderIncludeGen(*PP);
@@ -270,6 +270,11 @@ void CompilerInstance::createPreprocessor() {
     AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath,
                            /*ShowDepth=*/false);
   }
+
+  if (DepOpts.PrintShowIncludes) {
+    AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"",
+                           /*ShowDepth=*/true, /*MSStyle=*/true);
+  }
 }
 
 // ASTContext
index f88c124f08cb65ab0f3165a4a5ab8e767a3b0862..a4a84127c059befe5081aee1b90dd4657673b113 100644 (file)
@@ -518,6 +518,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
   Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
   Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
   Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
+  Opts.PrintShowIncludes = Args.hasArg(OPT_show_includes);
   Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);
 }
 
index 4d8a05cfbc15b01c2af70a6d4262c5272559caca..237e5b1ac0c6087ed89611fe2acc8d5d74d461d8 100644 (file)
@@ -24,15 +24,16 @@ class HeaderIncludesCallback : public PPCallbacks {
   bool OwnsOutputFile;
   bool ShowAllHeaders;
   bool ShowDepth;
+  bool MSStyle;
 
 public:
   HeaderIncludesCallback(const Preprocessor *PP, bool ShowAllHeaders_,
                          raw_ostream *OutputFile_, bool OwnsOutputFile_,
-                         bool ShowDepth_)
+                         bool ShowDepth_, bool MSStyle_)
     : SM(PP->getSourceManager()), OutputFile(OutputFile_),
       CurrentIncludeDepth(0), HasProcessedPredefines(false),
       OwnsOutputFile(OwnsOutputFile_), ShowAllHeaders(ShowAllHeaders_),
-      ShowDepth(ShowDepth_) {}
+      ShowDepth(ShowDepth_), MSStyle(MSStyle_) {}
 
   ~HeaderIncludesCallback() {
     if (OwnsOutputFile)
@@ -46,7 +47,8 @@ public:
 }
 
 void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
-                                   StringRef OutputPath, bool ShowDepth) {
+                                   StringRef OutputPath, bool ShowDepth,
+                                   bool MSStyle) {
   raw_ostream *OutputFile = &llvm::errs();
   bool OwnsOutputFile = false;
 
@@ -69,7 +71,7 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
 
   PP.addPPCallbacks(new HeaderIncludesCallback(&PP, ShowAllHeaders,
                                                OutputFile, OwnsOutputFile,
-                                               ShowDepth));
+                                               ShowDepth, MSStyle));
 }
 
 void HeaderIncludesCallback::FileChanged(SourceLocation Loc,
@@ -109,14 +111,20 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc,
   if (ShowHeader && Reason == PPCallbacks::EnterFile) {
     // Write to a temporary string to avoid unnecessary flushing on errs().
     SmallString<512> Filename(UserLoc.getFilename());
-    Lexer::Stringify(Filename);
+    if (!MSStyle)
+      Lexer::Stringify(Filename);
 
     SmallString<256> Msg;
+    if (MSStyle)
+      Msg += "Note: including file:";
+
     if (ShowDepth) {
       // The main source file is at depth 1, so skip one dot.
       for (unsigned i = 1; i != CurrentIncludeDepth; ++i)
-        Msg += '.';
-      Msg += ' ';
+        Msg += MSStyle ? ' ' : '.';
+
+      if (!MSStyle)
+        Msg += ' ';
     }
     Msg += Filename;
     Msg += '\n';
index f9f5c37136424b54f94eadbec81c61cd8db640c3..f10141b82445ec602ec74eddc270ae1142d08775 100644 (file)
@@ -59,6 +59,9 @@
 // RUN: %clang_cl /P -### -- %s 2>&1 | FileCheck -check-prefix=P %s
 // P: -E
 
+// RUN: %clang_cl /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes %s
+// showIncludes: --show-includes
+
 // RUN: %clang_cl /Umymacro -### -- %s 2>&1 | FileCheck -check-prefix=U %s
 // RUN: %clang_cl /U mymacro -### -- %s 2>&1 | FileCheck -check-prefix=U %s
 // U: "-U" "mymacro"
 // RUN: %clang_cl /Zs /EHsc /Fdfoo /fp:precise /Gd /GL /GL- -- %s 2>&1
 // RUN: %clang_cl /Zs /Gm /Gm- /GS /Gy /Gy- /GZ -- %s 2>&1
 // RUN: %clang_cl /Zs /RTC1 /wfoo /Zc:wchar_t- -- %s 2>&1
-// RUN: %clang_cl /Zs /ZI /Zi /showIncludes -- %s 2>&1
+// RUN: %clang_cl /Zs /ZI /Zi -- %s 2>&1
index 7773d2069d9883befb10349b17dbcf56b766dab5..aa3e3971fd1b7c6d51cf2cfc90ad4455692b2e22 100644 (file)
@@ -5,4 +5,11 @@
 // CHECK: . {{.*test.h}}
 // CHECK: .. {{.*test2.h}}
 
+// RUN: %clang_cc1 -include Inputs/test3.h -E --show-includes -o %t.out %s 2> %t.err
+// RUN: FileCheck --check-prefix=MS < %t.err %s
+// MS-NOT: test3.h
+// MS: Note: including file: {{.*test.h}}
+// MS: Note: including file:  {{.*test2.h}}
+// MS-NOT: Note
+
 #include "Inputs/test.h"