Skip to content

Commit d12ad77

Browse files
committed
Add really early support for emitting # line directives, and emitting the
right number of newlines between tokens when needed. This reduces the delta of the gcc -E output from 12198 differences to 6764. It still needs to emit filenames on #line directives, track filename switches, and track entry/exit of include files. llvm-svn: 38559
1 parent bb893c3 commit d12ad77

File tree

1 file changed

+40
-21
lines changed

1 file changed

+40
-21
lines changed

clang/Driver/clang.cpp

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -588,11 +588,49 @@ static void ReadPrologFiles(Preprocessor &PP, std::vector<char> &Buf) {
588588
// Preprocessed output mode.
589589
//===----------------------------------------------------------------------===//
590590

591+
/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
592+
/// is called for the first token on each new line.
593+
static void HandleFirstTokOnLine(LexerToken &Tok, Preprocessor &PP,
594+
unsigned &CurLine) {
595+
// Figure out what line we went to and insert the appropriate number of
596+
// newline characters.
597+
unsigned LineNo = PP.getSourceManager().getLineNumber(Tok.getLocation());
598+
599+
// If this line is "close enough" to the original line, just print newlines,
600+
// otherwise print a #line directive.
601+
if (LineNo-CurLine < 8) {
602+
for (; CurLine != LineNo; ++CurLine)
603+
std::cout << "\n";
604+
} else {
605+
// FIXME: filename too.
606+
std::cout << "\n# " << LineNo << "\n";
607+
CurLine = LineNo;
608+
}
609+
610+
// Print out space characters so that the first token on a line is
611+
// indented for easy reading.
612+
unsigned ColNo =
613+
PP.getSourceManager().getColumnNumber(Tok.getLocation());
614+
615+
// This hack prevents stuff like:
616+
// #define HASH #
617+
// HASH define foo bar
618+
// From having the # character end up at column 1, which makes it so it
619+
// is not handled as a #define next time through the preprocessor if in
620+
// -fpreprocessed mode.
621+
if (ColNo <= 1 && Tok.getKind() == tok::hash)
622+
std::cout << ' ';
623+
624+
// Otherwise, indent the appropriate number of spaces.
625+
for (; ColNo > 1; --ColNo)
626+
std::cout << ' ';
627+
}
628+
591629
/// DoPrintPreprocessedInput - This implements -E mode.
592630
void DoPrintPreprocessedInput(Preprocessor &PP) {
593631
LexerToken Tok;
594632
char Buffer[256];
595-
bool isFirstToken = true;
633+
unsigned CurLine = 1;
596634
do {
597635
PP.Lex(Tok);
598636

@@ -602,29 +640,10 @@ void DoPrintPreprocessedInput(Preprocessor &PP) {
602640
// FIXME: For some tests, this fails just because there is no col# info from
603641
// macro expansions!
604642
if (Tok.isAtStartOfLine()) {
605-
if (!isFirstToken)
606-
std::cout << "\n";
607-
// Print out space characters so that the first token on a line is
608-
// indented for easy reading.
609-
unsigned ColNo =
610-
PP.getSourceManager().getColumnNumber(Tok.getLocation());
611-
612-
// This hack prevents stuff like:
613-
// #define HASH #
614-
// HASH define foo bar
615-
// From having the # character end up at column 1, which makes it so it
616-
// is not handled as a #define next time through the preprocessor if in
617-
// -fpreprocessed mode.
618-
if (ColNo <= 1 && Tok.getKind() == tok::hash)
619-
std::cout << ' ';
620-
621-
for (; ColNo > 1; --ColNo)
622-
std::cout << ' ';
623-
643+
HandleFirstTokOnLine(Tok, PP, CurLine);
624644
} else if (Tok.hasLeadingSpace()) {
625645
std::cout << ' ';
626646
}
627-
isFirstToken = false;
628647

629648
if (Tok.getLength() < 256) {
630649
unsigned Len = PP.getSpelling(Tok, Buffer);

0 commit comments

Comments
 (0)