From: Daniel Dunbar Date: Tue, 24 Aug 2010 22:44:13 +0000 (+0000) Subject: Frontend: Add basic -H support. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7c16d903f11814e2d6780e2a2e189b7a7afc4ed;p=clang Frontend: Add basic -H support. - I didn't implement the GCC "multiple include guard" detection parts, because it doesn't seem useful or obvious. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111983 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 9a22c21dc1..bdb918bfae 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -556,3 +556,5 @@ def dM : Flag<"-dM">, HelpText<"Print macro definitions in -E mode instead of normal output">; def dD : Flag<"-dD">, HelpText<"Print macro definitions in -E mode in addition to normal output">; +def H : Flag<"-H">, + HelpText<"Show header includes and nesting depth">; diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h index a712a3d1bb..82517c51d1 100644 --- a/include/clang/Frontend/PreprocessorOutputOptions.h +++ b/include/clang/Frontend/PreprocessorOutputOptions.h @@ -16,19 +16,21 @@ namespace clang { /// output (e.g., -E). class PreprocessorOutputOptions { public: - unsigned ShowCPP : 1; ///< Print normal preprocessed output. - unsigned ShowMacros : 1; ///< Print macro definitions. - unsigned ShowLineMarkers : 1; ///< Show #line markers. - unsigned ShowComments : 1; ///< Show comments. - unsigned ShowMacroComments : 1; ///< Show comments, even in macros. + unsigned ShowCPP : 1; ///< Print normal preprocessed output. + unsigned ShowComments : 1; ///< Show comments. + unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H). + unsigned ShowLineMarkers : 1; ///< Show #line markers. + unsigned ShowMacroComments : 1; ///< Show comments, even in macros. + unsigned ShowMacros : 1; ///< Print macro definitions. public: PreprocessorOutputOptions() { ShowCPP = 1; - ShowMacros = 0; - ShowLineMarkers = 1; ShowComments = 0; + ShowHeaderIncludes = 0; + ShowLineMarkers = 1; ShowMacroComments = 0; + ShowMacros = 0; } }; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 4f839e9dea..9e7a061e94 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -962,6 +962,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } Args.AddAllArgs(CmdArgs, options::OPT_v); + Args.AddLastArg(CmdArgs, options::OPT_H); Args.AddLastArg(CmdArgs, options::OPT_P); Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 86ce31538f..68e2d846c5 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -689,6 +689,8 @@ static void PreprocessorOutputOptsToArgs(const PreprocessorOutputOptions &Opts, else if (!Opts.ShowCPP && Opts.ShowMacros) Res.push_back("-dM"); + if (Opts.ShowHeaderIncludes) + Res.push_back("-H"); if (!Opts.ShowLineMarkers) Res.push_back("-P"); if (Opts.ShowComments) @@ -1456,10 +1458,11 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, ArgList &Args) { using namespace cc1options; Opts.ShowCPP = !Args.hasArg(OPT_dM); - Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD); - Opts.ShowLineMarkers = !Args.hasArg(OPT_P); Opts.ShowComments = Args.hasArg(OPT_C); + Opts.ShowHeaderIncludes = Args.hasArg(OPT_H); + Opts.ShowLineMarkers = !Args.hasArg(OPT_P); Opts.ShowMacroComments = Args.hasArg(OPT_CC); + Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD); } static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index e68fd583aa..cfaf8a23b1 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -85,6 +85,10 @@ public: llvm::raw_ostream &OS; private: unsigned CurLine; + + /// The current include nesting level, used by header include dumping (-H). + unsigned CurrentIncludeDepth; + bool EmittedTokensOnThisLine; bool EmittedMacroOnThisLine; SrcMgr::CharacteristicKind FileType; @@ -92,19 +96,22 @@ private: bool Initialized; bool DisableLineMarkers; bool DumpDefines; + bool DumpHeaderIncludes; bool UseLineDirective; + bool HasProcessedPredefines; public: PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os, - bool lineMarkers, bool defines) + bool lineMarkers, bool defines, bool headers) : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers), - DumpDefines(defines) { - CurLine = 0; + DumpDefines(defines), DumpHeaderIncludes(headers) { + CurLine = CurrentIncludeDepth = 0; CurFilename += ""; EmittedTokensOnThisLine = false; EmittedMacroOnThisLine = false; FileType = SrcMgr::C_User; Initialized = false; + HasProcessedPredefines = false; // If we're in microsoft mode, use normal #line instead of line markers. UseLineDirective = PP.getLangOptions().Microsoft; @@ -219,7 +226,7 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc); unsigned NewLine = UserLoc.getLine(); - + if (Reason == PPCallbacks::EnterFile) { SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc(); if (IncludeLoc.isValid()) @@ -231,16 +238,41 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, // directive and emits a bunch of spaces that aren't needed. Emulate this // strange behavior. } + + // Adjust the current include depth. + if (Reason == PPCallbacks::EnterFile) { + ++CurrentIncludeDepth; + } else { + if (CurrentIncludeDepth) + --CurrentIncludeDepth; + + // We track when we are done with the predefines by watching for the first + // place where we drop back to a nesting depth of 0. + if (CurrentIncludeDepth == 0 && !HasProcessedPredefines) + HasProcessedPredefines = true; + } CurLine = NewLine; - if (DisableLineMarkers) return; - CurFilename.clear(); CurFilename += UserLoc.getFilename(); Lexer::Stringify(CurFilename); FileType = NewFileType; + // Dump the header include information, if enabled and we are past the + // predefines buffer. + if (DumpHeaderIncludes && HasProcessedPredefines && + Reason == PPCallbacks::EnterFile) { + llvm::SmallString<256> Msg; + llvm::raw_svector_ostream OS(Msg); + for (unsigned i = 0; i != CurrentIncludeDepth; ++i) + OS << '.'; + OS << ' ' << CurFilename << '\n'; + llvm::errs() << OS.str(); + } + + if (DisableLineMarkers) return; + if (!Initialized) { WriteLineInfo(CurLine); Initialized = true; @@ -529,7 +561,7 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS, PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers, - Opts.ShowMacros); + Opts.ShowMacros, Opts.ShowHeaderIncludes); PP.AddPragmaHandler(new UnknownPragmaHandler("#pragma", Callbacks)); PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC", Callbacks)); diff --git a/test/Frontend/Inputs/lit.local.cfg b/test/Frontend/Inputs/lit.local.cfg new file mode 100644 index 0000000000..e6f55eef7a --- /dev/null +++ b/test/Frontend/Inputs/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = [] diff --git a/test/Frontend/Inputs/test.h b/test/Frontend/Inputs/test.h new file mode 100644 index 0000000000..98cc459a24 --- /dev/null +++ b/test/Frontend/Inputs/test.h @@ -0,0 +1 @@ +#include "test2.h" diff --git a/test/Frontend/Inputs/test2.h b/test/Frontend/Inputs/test2.h new file mode 100644 index 0000000000..6d1a0d47b7 --- /dev/null +++ b/test/Frontend/Inputs/test2.h @@ -0,0 +1 @@ +int x; diff --git a/test/Frontend/Inputs/test3.h b/test/Frontend/Inputs/test3.h new file mode 100644 index 0000000000..92ff4b8fac --- /dev/null +++ b/test/Frontend/Inputs/test3.h @@ -0,0 +1 @@ +int y; diff --git a/test/Frontend/print-header-includes.c b/test/Frontend/print-header-includes.c new file mode 100644 index 0000000000..7773d2069d --- /dev/null +++ b/test/Frontend/print-header-includes.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.err +// RUN: FileCheck < %t.err %s + +// CHECK-NOT: test3.h +// CHECK: . {{.*test.h}} +// CHECK: .. {{.*test2.h}} + +#include "Inputs/test.h"