elsteveogrande updated this revision to Diff 73394.
elsteveogrande updated the summary for this revision.
elsteveogrande added a comment.

Fixed escaping function; simplified that function as well as the diagnostic 
output.


https://reviews.llvm.org/D25153

Files:
  include/clang/Driver/Options.td
  include/clang/Frontend/PreprocessorOutputOptions.h
  lib/Frontend/CompilerInvocation.cpp
  lib/Frontend/PrintPreprocessedOutput.cpp
  test/Preprocessor/dump_import.h
  test/Preprocessor/dump_import.m
  test/Preprocessor/dump_include.c
  test/Preprocessor/dump_include.h

Index: test/Preprocessor/dump_include.h
===================================================================
--- /dev/null
+++ test/Preprocessor/dump_include.h
@@ -0,0 +1,2 @@
+#pragma once
+#define DUMP_INCLUDE_TESTVAL 1
Index: test/Preprocessor/dump_include.c
===================================================================
--- /dev/null
+++ test/Preprocessor/dump_include.c
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -E -dI %s -o - | grep '^#include'
+#include "dump_include.h"
Index: test/Preprocessor/dump_import.m
===================================================================
--- /dev/null
+++ test/Preprocessor/dump_import.m
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -E -dI %s -o - | grep '^#import'
+#import "dump_import.h"
Index: test/Preprocessor/dump_import.h
===================================================================
--- /dev/null
+++ test/Preprocessor/dump_import.h
@@ -0,0 +1 @@
+#define DUMP_IMPORT_TESTVAL 1
Index: lib/Frontend/PrintPreprocessedOutput.cpp
===================================================================
--- lib/Frontend/PrintPreprocessedOutput.cpp
+++ lib/Frontend/PrintPreprocessedOutput.cpp
@@ -93,13 +93,15 @@
   bool Initialized;
   bool DisableLineMarkers;
   bool DumpDefines;
+  bool DumpIncludeDirectives;
   bool UseLineDirectives;
   bool IsFirstFileEntered;
 public:
   PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, bool lineMarkers,
-                           bool defines, bool UseLineDirectives)
+                           bool defines, bool dumpIncludeDirectives, bool UseLineDirectives)
       : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
         DisableLineMarkers(lineMarkers), DumpDefines(defines),
+        DumpIncludeDirectives(dumpIncludeDirectives),
         UseLineDirectives(UseLineDirectives) {
     CurLine = 0;
     CurFilename += "<uninit>";
@@ -311,6 +313,46 @@
   }
 }
 
+namespace {
+/**
+ * Escape a pathname appropriate for use in preprocessed output, e.g. if using
+ * '-dI' to print info about inclusions.
+ */
+std::string sanitizePath(const StringRef& path) {
+  std::string str(path.size() * 2, '\0');
+  size_t len = 0;
+  for (size_t i = 0; i < path.size(); i++) {
+    const char c = path[i];
+    switch (c) {
+      case '"':  // paths are enclosed in quotes; escape them
+      case '*':  // don't allow a "*/" sequence to accidentally open the comment
+      case '\\': // escape the escape character itself.
+        str[len++] = '\\';
+        // fall through
+      default:
+        str[len++] = c;
+    }
+  }
+  return str.substr(0, len);
+}
+
+/**
+ * Try to obtain the text of the token (identifier or other kind).  Return
+ * true if successful, false otherwise.  If successful, the "text" parameter
+ * receives a copy of the token text.
+ */
+bool tryGetTokenText(std::string* text, const Token &tok) {
+  if (tok.getKind() == clang::tok::identifier) {
+    const auto* idInfo = tok.getIdentifierInfo();
+    if (idInfo && idInfo->getNameStart() != nullptr) {
+      *text = std::string(idInfo->getNameStart(), idInfo->getLength());
+      return true;
+    }
+  }
+  return false;
+}
+}
+
 void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
                                                   const Token &IncludeTok,
                                                   StringRef FileName,
@@ -320,10 +362,10 @@
                                                   StringRef SearchPath,
                                                   StringRef RelativePath,
                                                   const Module *Imported) {
-  // When preprocessing, turn implicit imports into @imports.
-  // FIXME: This is a stop-gap until a more comprehensive "preprocessing with
-  // modules" solution is introduced.
   if (Imported) {
+    // When preprocessing, turn implicit imports into @imports.
+    // FIXME: This is a stop-gap until a more comprehensive "preprocessing with
+    // modules" solution is introduced.
     startNewLineIfNeeded();
     MoveToLine(HashLoc);
     if (PP.getLangOpts().ObjC2) {
@@ -344,6 +386,30 @@
     // line immediately.
     EmittedTokensOnThisLine = true;
     startNewLineIfNeeded();
+  } else {
+    // Not a module import; it's a more vanilla inclusion of some file using one
+    // of: #include, #import, #include_next, #include_macros.
+    if (DumpIncludeDirectives) {
+      // If we couldn't determine the actual token used in the source, just say
+      // "#include" in output.
+      std::string InclusionKeyword("include");
+      tryGetTokenText(&InclusionKeyword, IncludeTok);
+
+      OS << "#" << InclusionKeyword << " "
+         << (IsAngled ? '<' : '"')
+         << FileName
+         << (IsAngled ? '>' : '"')
+         << " /* clang -E -dI:";
+      if (SearchPath.size() == 0 && RelativePath.size() > 0) {
+        OS << " absolute";
+      } else if (SearchPath.size() > 0 && RelativePath.size() > 0) {
+        OS << " path=\"" << sanitizePath(SearchPath) << "\"";
+      }
+      OS << " */";
+
+      setEmittedDirectiveOnThisLine();
+      startNewLineIfNeeded();
+    }
   }
 }
 
@@ -751,7 +817,8 @@
   PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
 
   PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
-      PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, Opts.UseLineDirectives);
+      PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, Opts.ShowIncludeDirectives,
+      Opts.UseLineDirectives);
 
   // Expand macros in pragmas with -fms-extensions.  The assumption is that
   // the majority of pragmas in such a file will be Microsoft pragmas.
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2332,6 +2332,7 @@
   Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
   Opts.ShowMacroComments = Args.hasArg(OPT_CC);
   Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
+  Opts.ShowIncludeDirectives = Args.hasArg(OPT_dI);
   Opts.RewriteIncludes = Args.hasArg(OPT_frewrite_includes);
   Opts.UseLineDirectives = Args.hasArg(OPT_fuse_line_directives);
 }
Index: include/clang/Frontend/PreprocessorOutputOptions.h
===================================================================
--- include/clang/Frontend/PreprocessorOutputOptions.h
+++ include/clang/Frontend/PreprocessorOutputOptions.h
@@ -22,6 +22,7 @@
   unsigned UseLineDirectives : 1;   ///< Use \#line instead of GCC-style \# N.
   unsigned ShowMacroComments : 1;  ///< Show comments, even in macros.
   unsigned ShowMacros : 1;         ///< Print macro definitions.
+  unsigned ShowIncludeDirectives : 1;  ///< Print includes, imports etc. within preprocessed output.
   unsigned RewriteIncludes : 1;    ///< Preprocess include directives only.
 
 public:
@@ -32,6 +33,7 @@
     UseLineDirectives = 0;
     ShowMacroComments = 0;
     ShowMacros = 0;
+    ShowIncludeDirectives = 0;
     RewriteIncludes = 0;
   }
 };
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -429,6 +429,8 @@
 def dA : Flag<["-"], "dA">, Group<d_Group>;
 def dD : Flag<["-"], "dD">, Group<d_Group>, Flags<[CC1Option]>,
   HelpText<"Print macro definitions in -E mode in addition to normal output">;
+def dI : Flag<["-"], "dI">, Group<d_Group>, Flags<[CC1Option]>,
+  HelpText<"Print include directives in -E mode in addition to normal output">;
 def dM : Flag<["-"], "dM">, Group<d_Group>, Flags<[CC1Option]>,
   HelpText<"Print macro definitions in -E mode instead of normal output">;
 def dead__strip : Flag<["-"], "dead_strip">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to