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:
parent
9a13bde643
commit
0c885f5581
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue