From 9483fa6dbe01ac2b7513a2bf50dcb599ebe4af46 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Thu, 17 Nov 2016 22:45:31 +0000 Subject: [PATCH] [Preprocessor] Support for '-dI' flag MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Re-introduce r285411. Implement the -dI as supported by GCC: Output ‘#include’ directives in addition to the result of preprocessing. This change aims to add this option, pass it through to the preprocessor via the options class, and when inclusions occur we output some information (+ test cases). Patch by Steve O'Brien! Differential Revision: https://reviews.llvm.org/D26089 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@287275 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Options.td | 2 ++ .../Frontend/PreprocessorOutputOptions.h | 2 ++ lib/Frontend/CompilerInvocation.cpp | 1 + lib/Frontend/PrintPreprocessedOutput.cpp | 34 ++++++++++++++----- test/Preprocessor/dump_import.h | 1 + test/Preprocessor/dump_import.m | 6 ++++ test/Preprocessor/dump_include.c | 11 ++++++ test/Preprocessor/dump_include.h | 2 ++ 8 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 test/Preprocessor/dump_import.h create mode 100644 test/Preprocessor/dump_import.m create mode 100644 test/Preprocessor/dump_include.c create mode 100644 test/Preprocessor/dump_include.h diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 701a43c598..fa2511de14 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -429,6 +429,8 @@ def fno_cuda_approx_transcendentals : Flag<["-"], "fno-cuda-approx-transcendenta def dA : Flag<["-"], "dA">, Group; def dD : Flag<["-"], "dD">, Group, Flags<[CC1Option]>, HelpText<"Print macro definitions in -E mode in addition to normal output">; +def dI : Flag<["-"], "dI">, Group, Flags<[CC1Option]>, + HelpText<"Print include directives in -E mode in addition to normal output">; def dM : Flag<["-"], "dM">, Group, Flags<[CC1Option]>, HelpText<"Print macro definitions in -E mode instead of normal output">; def dead__strip : Flag<["-"], "dead_strip">; diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h index f86c49039e..3261b66538 100644 --- a/include/clang/Frontend/PreprocessorOutputOptions.h +++ b/include/clang/Frontend/PreprocessorOutputOptions.h @@ -22,6 +22,7 @@ public: 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 @@ public: UseLineDirectives = 0; ShowMacroComments = 0; ShowMacros = 0; + ShowIncludeDirectives = 0; RewriteIncludes = 0; } }; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 2bdd40cc99..874827b7e5 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2357,6 +2357,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, 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); } diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index 77b80e612f..d48b952ef2 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -93,13 +93,16 @@ private: 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 += ""; @@ -320,10 +323,10 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc, 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) { @@ -331,9 +334,9 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc, << " /* clang -E: implicit import for \"" << File->getName() << "\" */"; } else { - // FIXME: Preseve whether this was a - // #include/#include_next/#include_macros/#import. - OS << "#include " + const std::string TokenText = PP.getSpelling(IncludeTok); + assert(!TokenText.empty()); + OS << "#" << TokenText << " " << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"') @@ -344,6 +347,20 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc, // 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) { + startNewLineIfNeeded(); + MoveToLine(HashLoc); + const std::string TokenText = PP.getSpelling(IncludeTok); + assert(!TokenText.empty()); + OS << "#" << TokenText << " " + << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"') + << " /* clang -E -dI */"; + setEmittedDirectiveOnThisLine(); + startNewLineIfNeeded(); + } } } @@ -751,7 +768,8 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, 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. diff --git a/test/Preprocessor/dump_import.h b/test/Preprocessor/dump_import.h new file mode 100644 index 0000000000..fded1e52cb --- /dev/null +++ b/test/Preprocessor/dump_import.h @@ -0,0 +1 @@ +#define DUMP_IMPORT_TESTVAL 1 diff --git a/test/Preprocessor/dump_import.m b/test/Preprocessor/dump_import.m new file mode 100644 index 0000000000..20424ad507 --- /dev/null +++ b/test/Preprocessor/dump_import.m @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -E -dI %s -o - | FileCheck %s +// CHECK: {{^}}#import "dump_ + +// See also `dump_include.c` which tests other inclusion cases with `-dI`. + +#import "dump_import.h" diff --git a/test/Preprocessor/dump_include.c b/test/Preprocessor/dump_include.c new file mode 100644 index 0000000000..4d7d857d5f --- /dev/null +++ b/test/Preprocessor/dump_include.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -w -E -dI -isystem %S -imacros %S/dump_include.h %s -o - | FileCheck %s +// CHECK: {{^}}#__include_macros "{{.*}}dump_ +// CHECK: {{^}}#include +#include "dump_include.h" +#include_next "dump_include.h" diff --git a/test/Preprocessor/dump_include.h b/test/Preprocessor/dump_include.h new file mode 100644 index 0000000000..9dafaa50b5 --- /dev/null +++ b/test/Preprocessor/dump_include.h @@ -0,0 +1,2 @@ +#pragma once +#define DUMP_INCLUDE_TESTVAL 1 -- 2.40.0