Improve #line emission in -E mode to include file entry/exits. This is

still pretty hacky because it doesn't compute the 3/4 markers correctly.

llvm-svn: 38561
This commit is contained in:
Chris Lattner 2006-06-21 06:50:18 +00:00
parent 9a13bde643
commit 0c885f5581
3 changed files with 106 additions and 19 deletions

View File

@ -588,24 +588,76 @@ static void ReadPrologFiles(Preprocessor &PP, std::vector<char> &Buf) {
// Preprocessed output mode.
//===----------------------------------------------------------------------===//
static unsigned EModeCurLine;
static std::string EModeCurFilename;
static Preprocessor *EModePP;
static bool EmodeEmittedTokensOnThisLine;
static void MoveToLine(unsigned LineNo) {
// If this line is "close enough" to the original line, just print newlines,
// otherwise print a #line directive.
if (LineNo-EModeCurLine < 8) {
for (; EModeCurLine != LineNo; ++EModeCurLine)
std::cout << "\n";
} else {
if (EmodeEmittedTokensOnThisLine) {
std::cout << "\n";
EmodeEmittedTokensOnThisLine = false;
}
std::cout << "# " << LineNo << " " << EModeCurFilename;
// FIXME: calculate system file right.
std::cout << " 3";
std::cout << "\n";
EModeCurLine = LineNo;
}
}
/// HandleFileChange - Whenever the preprocessor enters or exits a #include file
/// it invokes this handler. Update our conception of the current
static void HandleFileChange(SourceLocation Loc, bool EnteringFile) {
SourceManager &SourceMgr = EModePP->getSourceManager();
// If we are entering a new #include, make sure to skip ahead to the line the
// #include directive was at.
if (EnteringFile) {
SourceLocation IncludeLoc = SourceMgr.getIncludeLoc(Loc.getFileID());
MoveToLine(SourceMgr.getLineNumber(IncludeLoc));
}
EModeCurLine = SourceMgr.getLineNumber(Loc);
// FIXME: escape filename right.
EModeCurFilename = '"' + SourceMgr.getSourceName(Loc) + '"';
if (EmodeEmittedTokensOnThisLine) {
std::cout << "\n";
EmodeEmittedTokensOnThisLine = false;
}
std::cout << "# " << EModeCurLine << " " << EModeCurFilename;
if (EnteringFile)
std::cout << " 1";
else
std::cout << " 2";
// FIXME: calculate system file right.
std::cout << " 3";
std::cout << "\n";
}
/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
/// is called for the first token on each new line.
static void HandleFirstTokOnLine(LexerToken &Tok, Preprocessor &PP,
unsigned &CurLine) {
static void HandleFirstTokOnLine(LexerToken &Tok, Preprocessor &PP) {
// Figure out what line we went to and insert the appropriate number of
// newline characters.
unsigned LineNo = PP.getSourceManager().getLineNumber(Tok.getLocation());
// If this line is "close enough" to the original line, just print newlines,
// otherwise print a #line directive.
if (LineNo-CurLine < 8) {
for (; CurLine != LineNo; ++CurLine)
std::cout << "\n";
} else {
// FIXME: filename too.
std::cout << "\n# " << LineNo << "\n";
CurLine = LineNo;
}
// Move to the specified line.
MoveToLine(LineNo);
// Print out space characters so that the first token on a line is
// indented for easy reading.
@ -630,7 +682,12 @@ static void HandleFirstTokOnLine(LexerToken &Tok, Preprocessor &PP,
void DoPrintPreprocessedInput(Preprocessor &PP) {
LexerToken Tok;
char Buffer[256];
unsigned CurLine = 1;
EModeCurLine = 0;
EModeCurFilename = "\"<uninit>\"";
PP.setFileChangeHandler(HandleFileChange);
EModePP = &PP;
EmodeEmittedTokensOnThisLine = false;
do {
PP.Lex(Tok);
@ -640,7 +697,7 @@ void DoPrintPreprocessedInput(Preprocessor &PP) {
// FIXME: For some tests, this fails just because there is no col# info from
// macro expansions!
if (Tok.isAtStartOfLine()) {
HandleFirstTokOnLine(Tok, PP, CurLine);
HandleFirstTokOnLine(Tok, PP);
} else if (Tok.hasLeadingSpace()) {
std::cout << ' ';
}
@ -652,6 +709,7 @@ void DoPrintPreprocessedInput(Preprocessor &PP) {
} else {
std::cout << PP.getSpelling(Tok);
}
EmodeEmittedTokensOnThisLine = true;
} while (Tok.getKind() != tok::eof);
std::cout << "\n";
}

View File

@ -55,10 +55,13 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
NumEnteredSourceFiles = NumMacroExpanded = NumFastMacroExpanded = 0;
MaxIncludeStackDepth = MaxMacroStackDepth = 0;
NumSkipped = 0;
// Macro expansion is enabled.
DisableMacroExpansion = false;
SkippingContents = false;
// There is no file-change handler yet.
FileChangeHandler = 0;
}
Preprocessor::~Preprocessor() {
@ -342,6 +345,10 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
CurLexer = new Lexer(Buffer, FileID, *this);
CurNextDirLookup = NextDir;
// Notify the client, if desired, that we are in a new source file.
if (FileChangeHandler)
FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart), true);
}
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
@ -464,7 +471,7 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) {
/// HandleEndOfFile - This callback is invoked when the lexer hits the end of
/// the current file. This either returns the EOF token or pops a level off
/// the include stack and keeps going.
void Preprocessor::HandleEndOfFile(LexerToken &Result) {
void Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
assert(!CurMacroExpander &&
"Ending a file when currently in a macro!");
@ -488,6 +495,12 @@ void Preprocessor::HandleEndOfFile(LexerToken &Result) {
CurLexer = IncludeStack.back().TheLexer;
CurNextDirLookup = IncludeStack.back().TheDirLookup;
IncludeStack.pop_back();
// Notify the client, if desired, that we are in a new source file.
if (FileChangeHandler && !isEndOfMacro)
FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferPtr),
false);
return Lex(Result);
}
@ -519,7 +532,7 @@ void Preprocessor::HandleEndOfMacro(LexerToken &Result) {
} else {
CurMacroExpander = 0;
// Handle this like a #include file being popped off the stack.
return HandleEndOfFile(Result);
return HandleEndOfFile(Result, true);
}
}

View File

@ -87,6 +87,13 @@ class Preprocessor {
std::vector<DirectoryLookup> SearchDirs;
unsigned SystemDirIdx;
bool NoCurDirSearch;
/// FileChangeHandler - This callback is invoked whenever a source file is
/// entered or exited. The SourceLocation indicates the new location, and
/// EnteringFile indicates whether this is because we are entering a new
/// #include'd file (when true) or whether we're exiting one because we ran
/// off the end (when false).
void (*FileChangeHandler)(SourceLocation Loc, bool EnteringFile);
enum {
/// MaxIncludeStackDepth - Maximum depth of #includes.
@ -103,7 +110,6 @@ class Preprocessor {
/// CurLexer - This is the current top of the stack that we're lexing from if
/// not expanding a macro. One of CurLexer and CurMacroExpander must be null.
///
Lexer *CurLexer;
/// CurDirLookup - The next DirectoryLookup structure to search for a file if
@ -185,6 +191,16 @@ public:
NoCurDirSearch = noCurDirSearch;
}
/// setFileChangeHandler - Set the callback invoked whenever a source file is
/// entered or exited. The SourceLocation indicates the new location, and
/// EnteringFile indicates whether this is because we are entering a new
/// #include'd file (when true) or whether we're exiting one because we ran
/// off the end (when false).
void setFileChangeHandler(void (*Handler)(SourceLocation, bool)) {
FileChangeHandler = Handler;
}
/// getIdentifierInfo - Return information about the specified preprocessor
/// identifier token. The version of this method that takes two character
/// pointers is preferred unless the identifier is already available as a
@ -302,7 +318,7 @@ public:
/// HandleEndOfFile - This callback is invoked when the lexer hits the end of
/// the current file. This either returns the EOF token or pops a level off
/// the include stack and keeps going.
void HandleEndOfFile(LexerToken &Result);
void HandleEndOfFile(LexerToken &Result, bool isEndOfMacro = false);
/// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
/// the current macro line.