elsteveogrande updated this revision to Diff 73224.
elsteveogrande added a comment.
Updated to actually use the include token's text, not a hardcoded `#include`.
Updated unit test to expect the right word here.
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>";
@@ -154,7 +156,7 @@
}
bool MoveToLine(unsigned LineNo);
- bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
+ bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
const Token &Tok) {
return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
}
@@ -238,7 +240,7 @@
++CurLine;
return true;
}
-
+
return false;
}
@@ -252,11 +254,11 @@
// Unless we are exiting a #include, make sure to skip ahead to the line the
// #include directive was at.
SourceManager &SourceMgr = SM;
-
+
PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
if (UserLoc.isInvalid())
return;
-
+
unsigned NewLine = UserLoc.getLine();
if (Reason == PPCallbacks::EnterFile) {
@@ -271,7 +273,7 @@
// off by one. We can do better by simply incrementing NewLine here.
NewLine += 1;
}
-
+
CurLine = NewLine;
CurFilename.clear();
@@ -282,7 +284,7 @@
startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
return;
}
-
+
if (!Initialized) {
WriteLineInfo(CurLine);
Initialized = true;
@@ -311,6 +313,54 @@
}
}
+namespace {
+/**
+ * Escape chars which are bad to print inside preprocessed output; e.g. we cannot break lines
+ * if we're emitting a '#'-style directive (escape both CR and LF). Paths are quoted in some
+ * instances, so escape quotes. Escaping is with a backslash (and backslashes themselves have
+ * to be escaped); for CR or LF, we use "\r" or "\n".
+ */
+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 '\\':
+ str[len++] = '\\';
+ str[len++] = '\\';
+ break;
+ case '\r':
+ str[len++] = '\\';
+ str[len++] = 'r';
+ break;
+ case '\n':
+ str[len++] = '\\';
+ str[len++] = 'n';
+ break;
+ case '"':
+ str[len++] = '\\';
+ str[len++] = '"';
+ break;
+ default:
+ str[len++] = c;
+ }
+ }
+ return str.substr(0, len);
+}
+
+bool tryGetTokenText(std::string* InclusionKeyword, const Token &tok) {
+ if (tok.getKind() == clang::tok::identifier) {
+ const auto* idInfo = tok.getIdentifierInfo();
+ if (idInfo && idInfo->getNameStart() != nullptr) {
+ *InclusionKeyword = std::string(idInfo->getNameStart(), idInfo->getLength());
+ return true;
+ }
+ }
+ return false;
+}
+}
+
void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
StringRef FileName,
@@ -320,10 +370,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 +394,31 @@
// 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 ? '>' : '"');
+
+ OS << " /* clang -E -dI:";
+
+ auto SanitizedSearchPath = sanitizePath(SearchPath);
+ auto SanitizedRelativePath = sanitizePath(RelativePath);
+ if (SanitizedSearchPath.size() == 0 && SanitizedRelativePath.size() > 0) {
+ OS << " absolute=\"" << SanitizedRelativePath << "\"";
+ } else if (SanitizedSearchPath.size() > 0 && SanitizedRelativePath.size() > 0) {
+ OS << " path=\"" << SanitizedSearchPath << "\"";
+ }
+
+ OS << " */";
+
+ setEmittedDirectiveOnThisLine();
+ startNewLineIfNeeded();
+ }
}
}
@@ -751,7 +826,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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits