@@ -588,24 +588,76 @@ static void ReadPrologFiles(Preprocessor &PP, std::vector<char> &Buf) {
588
588
// Preprocessed output mode.
589
589
// ===----------------------------------------------------------------------===//
590
590
591
+ static unsigned EModeCurLine;
592
+ static std::string EModeCurFilename;
593
+ static Preprocessor *EModePP;
594
+ static bool EmodeEmittedTokensOnThisLine;
595
+
596
+ static void MoveToLine (unsigned LineNo) {
597
+ // If this line is "close enough" to the original line, just print newlines,
598
+ // otherwise print a #line directive.
599
+ if (LineNo-EModeCurLine < 8 ) {
600
+ for (; EModeCurLine != LineNo; ++EModeCurLine)
601
+ std::cout << " \n " ;
602
+ } else {
603
+ if (EmodeEmittedTokensOnThisLine) {
604
+ std::cout << " \n " ;
605
+ EmodeEmittedTokensOnThisLine = false ;
606
+ }
607
+
608
+ std::cout << " # " << LineNo << " " << EModeCurFilename;
609
+
610
+ // FIXME: calculate system file right.
611
+ std::cout << " 3" ;
612
+
613
+ std::cout << " \n " ;
614
+ EModeCurLine = LineNo;
615
+ }
616
+ }
617
+
618
+ // / HandleFileChange - Whenever the preprocessor enters or exits a #include file
619
+ // / it invokes this handler. Update our conception of the current
620
+ static void HandleFileChange (SourceLocation Loc, bool EnteringFile) {
621
+ SourceManager &SourceMgr = EModePP->getSourceManager ();
622
+
623
+ // If we are entering a new #include, make sure to skip ahead to the line the
624
+ // #include directive was at.
625
+ if (EnteringFile) {
626
+ SourceLocation IncludeLoc = SourceMgr.getIncludeLoc (Loc.getFileID ());
627
+ MoveToLine (SourceMgr.getLineNumber (IncludeLoc));
628
+ }
629
+
630
+ EModeCurLine = SourceMgr.getLineNumber (Loc);
631
+ // FIXME: escape filename right.
632
+ EModeCurFilename = ' "' + SourceMgr.getSourceName (Loc) + ' "' ;
633
+
634
+ if (EmodeEmittedTokensOnThisLine) {
635
+ std::cout << " \n " ;
636
+ EmodeEmittedTokensOnThisLine = false ;
637
+ }
638
+ std::cout << " # " << EModeCurLine << " " << EModeCurFilename;
639
+ if (EnteringFile)
640
+ std::cout << " 1" ;
641
+ else
642
+ std::cout << " 2" ;
643
+
644
+ // FIXME: calculate system file right.
645
+ std::cout << " 3" ;
646
+
647
+ std::cout << " \n " ;
648
+ }
649
+
650
+
591
651
// / HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
592
652
// / is called for the first token on each new line.
593
- static void HandleFirstTokOnLine (LexerToken &Tok, Preprocessor &PP,
594
- unsigned &CurLine) {
653
+ static void HandleFirstTokOnLine (LexerToken &Tok, Preprocessor &PP) {
595
654
// Figure out what line we went to and insert the appropriate number of
596
655
// newline characters.
597
656
unsigned LineNo = PP.getSourceManager ().getLineNumber (Tok.getLocation ());
598
657
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
- }
658
+ // Move to the specified line.
659
+ MoveToLine (LineNo);
660
+
609
661
610
662
// Print out space characters so that the first token on a line is
611
663
// indented for easy reading.
@@ -630,7 +682,12 @@ static void HandleFirstTokOnLine(LexerToken &Tok, Preprocessor &PP,
630
682
void DoPrintPreprocessedInput (Preprocessor &PP) {
631
683
LexerToken Tok;
632
684
char Buffer[256 ];
633
- unsigned CurLine = 1 ;
685
+ EModeCurLine = 0 ;
686
+ EModeCurFilename = " \" <uninit>\" " ;
687
+ PP.setFileChangeHandler (HandleFileChange);
688
+ EModePP = &PP;
689
+ EmodeEmittedTokensOnThisLine = false ;
690
+
634
691
do {
635
692
PP.Lex (Tok);
636
693
@@ -640,7 +697,7 @@ void DoPrintPreprocessedInput(Preprocessor &PP) {
640
697
// FIXME: For some tests, this fails just because there is no col# info from
641
698
// macro expansions!
642
699
if (Tok.isAtStartOfLine ()) {
643
- HandleFirstTokOnLine (Tok, PP, CurLine );
700
+ HandleFirstTokOnLine (Tok, PP);
644
701
} else if (Tok.hasLeadingSpace ()) {
645
702
std::cout << ' ' ;
646
703
}
@@ -652,6 +709,7 @@ void DoPrintPreprocessedInput(Preprocessor &PP) {
652
709
} else {
653
710
std::cout << PP.getSpelling (Tok);
654
711
}
712
+ EmodeEmittedTokensOnThisLine = true ;
655
713
} while (Tok.getKind () != tok::eof);
656
714
std::cout << " \n " ;
657
715
}
0 commit comments