Frontend: Add basic -H support.

- I didn't implement the GCC "multiple include guard" detection parts, because
   it doesn't seem useful or obvious.

llvm-svn: 111983
This commit is contained in:
Daniel Dunbar 2010-08-24 22:44:13 +00:00
parent 5b8967f8a2
commit d435275c59
10 changed files with 68 additions and 16 deletions

View File

@ -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">;

View File

@ -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;
}
};

View File

@ -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);

View File

@ -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) {

View File

@ -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 += "<uninit>";
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));

View File

@ -0,0 +1 @@
config.suffixes = []

View File

@ -0,0 +1 @@
#include "test2.h"

View File

@ -0,0 +1 @@
int x;

View File

@ -0,0 +1 @@
int y;

View File

@ -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"