PrintPreprocessedOutput.cpp revision 3ff2a4b861082f271bb769755ea6d1da4b3e6b8d
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This code simply runs the preprocessor on the input file and prints out the
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// result.  This is the traditional behavior of the -E option.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15b09f6e15c59b89d5820db8ef40598eb1d1323c1fEli Friedman#include "clang/Frontend/Utils.h"
16775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar#include "clang/Basic/Diagnostic.h"
17775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar#include "clang/Basic/SourceManager.h"
18775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar#include "clang/Frontend/PreprocessorOutputOptions.h"
19f73903a1ded46748e1dfda151f5d037b7b3d31f9Chris Lattner#include "clang/Lex/MacroInfo.h"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/PPCallbacks.h"
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/Pragma.h"
22775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar#include "clang/Lex/Preprocessor.h"
23d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner#include "clang/Lex/TokenConcatenation.h"
24d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner#include "llvm/ADT/SmallString.h"
253ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer#include "llvm/ADT/STLExtras.h"
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Config/config.h"
27dceb6a7244b2e730d0b883512aa7fc7a331a5429Chris Lattner#include "llvm/Support/raw_ostream.h"
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <cstdio>
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
31d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner/// PrintMacroDefinition - Print a macro definition in a form that will be
32d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner/// properly accepted back as a definition.
33d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattnerstatic void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
34d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner                                 Preprocessor &PP, llvm::raw_ostream &OS) {
35d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  OS << "#define " << II.getName();
361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  if (MI.isFunctionLike()) {
38d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    OS << '(';
3913d555859cd643d657000401ebc88ca404d23bbaChris Lattner    if (!MI.arg_empty()) {
40d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
4113d555859cd643d657000401ebc88ca404d23bbaChris Lattner      for (; AI+1 != E; ++AI) {
4213d555859cd643d657000401ebc88ca404d23bbaChris Lattner        OS << (*AI)->getName();
43d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner        OS << ',';
44807b93ee6ae2806b53131abc779d2b146d853aedChris Lattner      }
4513d555859cd643d657000401ebc88ca404d23bbaChris Lattner
4613d555859cd643d657000401ebc88ca404d23bbaChris Lattner      // Last argument.
4713d555859cd643d657000401ebc88ca404d23bbaChris Lattner      if ((*AI)->getName() == "__VA_ARGS__")
4813d555859cd643d657000401ebc88ca404d23bbaChris Lattner        OS << "...";
4913d555859cd643d657000401ebc88ca404d23bbaChris Lattner      else
5013d555859cd643d657000401ebc88ca404d23bbaChris Lattner        OS << (*AI)->getName();
51d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    }
52807b93ee6ae2806b53131abc779d2b146d853aedChris Lattner
53807b93ee6ae2806b53131abc779d2b146d853aedChris Lattner    if (MI.isGNUVarargs())
54807b93ee6ae2806b53131abc779d2b146d853aedChris Lattner      OS << "...";  // #define foo(x...)
55807b93ee6ae2806b53131abc779d2b146d853aedChris Lattner
56d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    OS << ')';
57d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  }
581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  // GCC always emits a space, even if the macro body is empty.  However, do not
60d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  // want to emit two spaces if the first token has a leading space.
61d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
62d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    OS << ' ';
631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  llvm::SmallVector<char, 128> SpellingBuffer;
65d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end();
66d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner       I != E; ++I) {
67d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    if (I->hasLeadingSpace())
68d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      OS << ' ';
691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    // Make sure we have enough space in the spelling buffer.
713e27c01eb48c189723b263796d0dbe008b9c95c1Ted Kremenek    if (I->getLength() > SpellingBuffer.size())
72d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      SpellingBuffer.resize(I->getLength());
73beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad    const char *Buffer = SpellingBuffer.data();
74d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    unsigned SpellingLen = PP.getSpelling(*I, Buffer);
75d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    OS.write(Buffer, SpellingLen);
76d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  }
77d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner}
78d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Preprocessed token printer
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass PrintPPOutputPPCallbacks : public PPCallbacks {
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Preprocessor &PP;
86d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  TokenConcatenation ConcatInfo;
87e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattnerpublic:
88e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner  llvm::raw_ostream &OS;
89e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattnerprivate:
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned CurLine;
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool EmittedTokensOnThisLine;
923e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman  bool EmittedMacroOnThisLine;
939d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind FileType;
94d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner  llvm::SmallString<512> CurFilename;
95737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  bool Initialized;
9612d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  bool DisableLineMarkers;
9712d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  bool DumpDefines;
98f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner  bool UseLineDirective;
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
10012d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
10112d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman                           bool lineMarkers, bool defines)
10212d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman     : PP(pp), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
10312d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman       DumpDefines(defines) {
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CurLine = 0;
105d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner    CurFilename += "<uninit>";
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    EmittedTokensOnThisLine = false;
1073e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    EmittedMacroOnThisLine = false;
1080b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    FileType = SrcMgr::C_User;
109737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    Initialized = false;
110f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner
111f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    // If we're in microsoft mode, use normal #line instead of line markers.
112f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    UseLineDirective = PP.getLangOptions().Microsoft;
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
116f0f2b295437efecc0b52220b3f4a469fbb9aeac8Chris Lattner  bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
1199d72851fec9e9c62570a027d42701562bbf29751Chris Lattner                           SrcMgr::CharacteristicKind FileType);
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void Ident(SourceLocation Loc, const std::string &str);
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
122c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner                             const std::string &Str);
123c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1255f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  bool HandleFirstTokOnLine(Token &Tok);
1265f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  bool MoveToLine(SourceLocation Loc);
127d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  bool AvoidConcat(const Token &PrevTok, const Token &Tok) {
128d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    return ConcatInfo.AvoidConcat(PrevTok, Tok);
129d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  }
130737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1323ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  void HandleNewlinesInToken(const char *TokStr, unsigned Len);
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
134d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  /// MacroDefined - This hook is called whenever a macro definition is seen.
135d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1385db17c9b5edb43e12196e565389b73e91a4fcb65Chris Lattner}  // end anonymous namespace
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
140737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbarvoid PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
141737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar                                             const char *Extra,
142737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar                                             unsigned ExtraLen) {
1433e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman  if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
144737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    OS << '\n';
145737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    EmittedTokensOnThisLine = false;
1463e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    EmittedMacroOnThisLine = false;
147737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  }
148737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
149f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner  // Emit #line directives or GNU line markers depending on what mode we're in.
150f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner  if (UseLineDirective) {
151f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    OS << "#line" << ' ' << LineNo << ' ' << '"';
152f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    OS.write(&CurFilename[0], CurFilename.size());
153f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    OS << '"';
154f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner  } else {
155f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    OS << '#' << ' ' << LineNo << ' ' << '"';
156f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    OS.write(&CurFilename[0], CurFilename.size());
157f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner    OS << '"';
158f7449346006d6b94b14a303eb82cad52c8e75413Chris Lattner
159d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff    if (ExtraLen)
160d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff      OS.write(Extra, ExtraLen);
161737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
162d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff    if (FileType == SrcMgr::C_System)
163d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff      OS.write(" 3", 2);
164d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff    else if (FileType == SrcMgr::C_ExternCSystem)
165d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff      OS.write(" 3 4", 4);
166d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff  }
167737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  OS << '\n';
168737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar}
169737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// MoveToLine - Move the output to the source line specified by the location
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// object.  We can do this by emitting some number of \n's, or be emitting a
1725f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// #line directive.  This returns false if already at the specified line, true
1735f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// if some newlines were emitted.
1745f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattnerbool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) {
175f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner  unsigned LineNo = PP.getSourceManager().getInstantiationLineNumber(Loc);
176737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (DisableLineMarkers) {
1785f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    if (LineNo == CurLine) return false;
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1805f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    CurLine = LineNo;
1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1823e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    if (!EmittedTokensOnThisLine && !EmittedMacroOnThisLine)
1835f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner      return true;
1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
185e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    OS << '\n';
1865f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    EmittedTokensOnThisLine = false;
1873e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    EmittedMacroOnThisLine = false;
1885f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    return true;
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
190737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this line is "close enough" to the original line, just print newlines,
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // otherwise print a #line directive.
193fd96684034c29c59a134dfec20d61c132e60ef30Daniel Dunbar  if (LineNo-CurLine <= 8) {
194822f9406477554b7290a73a78d5d89308c157e05Chris Lattner    if (LineNo-CurLine == 1)
195e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner      OS << '\n';
1965f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    else if (LineNo == CurLine)
197f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner      return false;    // Spelling line moved, but instantiation line didn't.
198822f9406477554b7290a73a78d5d89308c157e05Chris Lattner    else {
199822f9406477554b7290a73a78d5d89308c157e05Chris Lattner      const char *NewLines = "\n\n\n\n\n\n\n\n";
200e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner      OS.write(NewLines, LineNo-CurLine);
201822f9406477554b7290a73a78d5d89308c157e05Chris Lattner    }
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
203737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(LineNo, 0, 0);
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
205737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CurLine = LineNo;
2075f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  return true;
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FileChanged - Whenever the preprocessor enters or exits a #include file
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// it invokes this handler.  Update our conception of the current source
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// position.
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                           FileChangeReason Reason,
2169d72851fec9e9c62570a027d42701562bbf29751Chris Lattner                                       SrcMgr::CharacteristicKind NewFileType) {
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Unless we are exiting a #include, make sure to skip ahead to the line the
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // #include directive was at.
2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceManager &SourceMgr = PP.getSourceManager();
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (Reason == PPCallbacks::EnterFile) {
22171d8bfb560735e8d47105cf434409ed347267830Chris Lattner    SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
22271d8bfb560735e8d47105cf434409ed347267830Chris Lattner    if (IncludeLoc.isValid())
22371d8bfb560735e8d47105cf434409ed347267830Chris Lattner      MoveToLine(IncludeLoc);
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else if (Reason == PPCallbacks::SystemHeaderPragma) {
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    MoveToLine(Loc);
2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // TODO GCC emits the # directive for this directive on the line AFTER the
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // directive and emits a bunch of spaces that aren't needed.  Emulate this
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // strange behavior.
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
232f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner  Loc = SourceMgr.getInstantiationLoc(Loc);
23316629386f1326608dc1ff9f4ff785fb3fae0bfb3Chris Lattner  // FIXME: Should use presumed line #!
23430fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner  CurLine = SourceMgr.getInstantiationLineNumber(Loc);
235737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
2365f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  if (DisableLineMarkers) return;
2375f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner
238d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner  CurFilename.clear();
239b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner  CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename();
240d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner  Lexer::Stringify(CurFilename);
241737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  FileType = NewFileType;
242737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
243737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  if (!Initialized) {
244737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine);
245737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    Initialized = true;
2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
247737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (Reason) {
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case PPCallbacks::EnterFile:
250737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine, " 1", 2);
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case PPCallbacks::ExitFile:
253737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine, " 2", 2);
254737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    break;
2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case PPCallbacks::SystemHeaderPragma:
2561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case PPCallbacks::RenameFile:
257737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine);
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
262c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner/// Ident - Handle #ident directives when read by the preprocessor.
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  MoveToLine(Loc);
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
267e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner  OS.write("#ident ", strlen("#ident "));
268e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner  OS.write(&S[0], S.size());
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  EmittedTokensOnThisLine = true;
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
272d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner/// MacroDefined - This hook is called whenever a macro definition is seen.
273d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattnervoid PrintPPOutputPPCallbacks::MacroDefined(const IdentifierInfo *II,
274d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner                                            const MacroInfo *MI) {
275d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  // Only print out macro definitions in -dD mode.
276d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  if (!DumpDefines ||
277d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      // Ignore __FILE__ etc.
278d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      MI->isBuiltinMacro()) return;
2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
280d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  MoveToLine(MI->getDefinitionLoc());
281d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  PrintMacroDefinition(*II, *MI, PP, OS);
2823e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman  EmittedMacroOnThisLine = true;
283d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner}
284d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
285d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
286c7d945d053f122eba704ef14c518db2ae595c562Chris Lattnervoid PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
2871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             const IdentifierInfo *Kind,
288c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner                                             const std::string &Str) {
289c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  MoveToLine(Loc);
290c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  OS << "#pragma comment(" << Kind->getName();
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
292c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  if (!Str.empty()) {
293c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    OS << ", \"";
2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
295c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    for (unsigned i = 0, e = Str.size(); i != e; ++i) {
296c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner      unsigned char Char = Str[i];
29752a3e9ed658859606544bbdf5f5d1c3b89471820Chris Lattner      if (isprint(Char) && Char != '\\' && Char != '"')
298c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner        OS << (char)Char;
299c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner      else  // Output anything hard as an octal escape.
300c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner        OS << '\\'
301c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner           << (char)('0'+ ((Char >> 6) & 7))
302c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner           << (char)('0'+ ((Char >> 3) & 7))
303c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner           << (char)('0'+ ((Char >> 0) & 7));
304c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    }
305c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    OS << '"';
306c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  }
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
308c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  OS << ')';
309c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  EmittedTokensOnThisLine = true;
310c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner}
311c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner
312c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
3145f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// is called for the first token on each new line.  If this really is the start
3155f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// of a new logical line, handle it and return true, otherwise return false.
3165f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// This may not be the start of a logical line because the "start of line"
317f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// marker is set for spelling lines, not instantiation ones.
3185f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattnerbool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Figure out what line we went to and insert the appropriate number of
3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // newline characters.
3215f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  if (!MoveToLine(Tok.getLocation()))
3225f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    return false;
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Print out space characters so that the first token on a line is
3255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // indented for easy reading.
3269dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner  const SourceManager &SourceMgr = PP.getSourceManager();
327f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner  unsigned ColNo = SourceMgr.getInstantiationColumnNumber(Tok.getLocation());
3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // This hack prevents stuff like:
3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // #define HASH #
3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // HASH define foo bar
3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // From having the # character end up at column 1, which makes it so it
3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // is not handled as a #define next time through the preprocessor if in
3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // -fpreprocessed mode.
335057aaf6304a5f59bcafa7b46c19625bb779af1d1Chris Lattner  if (ColNo <= 1 && Tok.is(tok::hash))
336e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    OS << ' ';
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Otherwise, indent the appropriate number of spaces.
3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (; ColNo > 1; --ColNo)
340e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    OS << ' ';
3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3425f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  return true;
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3453ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattnervoid PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
3463ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner                                                     unsigned Len) {
3473ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  unsigned NumNewlines = 0;
3483ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  for (; Len; --Len, ++TokStr) {
3493ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    if (*TokStr != '\n' &&
3503ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        *TokStr != '\r')
3513ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      continue;
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3533ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    ++NumNewlines;
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3553ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    // If we have \n\r or \r\n, skip both and count as one line.
3563ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    if (Len != 1 &&
3573ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        (TokStr[1] == '\n' || TokStr[1] == '\r') &&
3583ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        TokStr[0] != TokStr[1])
3593ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      ++TokStr, --Len;
3603ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  }
3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3623ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  if (NumNewlines == 0) return;
3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
364ed2d7c4ffd4112ddf10cb95e48428bae0b36377aChris Lattner  CurLine += NumNewlines;
3653ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner}
3663ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner
3673ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner
3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct UnknownPragmaHandler : public PragmaHandler {
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *Prefix;
3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PrintPPOutputPPCallbacks *Callbacks;
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {}
375d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) {
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Figure out what line we went to and insert the appropriate number of
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // newline characters.
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Callbacks->MoveToLine(PragmaTok.getLocation());
379e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    Callbacks->OS.write(Prefix, strlen(Prefix));
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read and print all of the pragma tokens.
382057aaf6304a5f59bcafa7b46c19625bb779af1d1Chris Lattner    while (PragmaTok.isNot(tok::eom)) {
3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (PragmaTok.hasLeadingSpace())
384e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner        Callbacks->OS << ' ';
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      std::string TokSpell = PP.getSpelling(PragmaTok);
386e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner      Callbacks->OS.write(&TokSpell[0], TokSpell.size());
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PP.LexUnexpandedToken(PragmaTok);
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
389e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    Callbacks->OS << '\n';
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end anonymous namespace
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
394f0f2b295437efecc0b52220b3f4a469fbb9aeac8Chris Lattner
39559076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattnerstatic void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
39659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                                    PrintPPOutputPPCallbacks *Callbacks,
39759076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                                    llvm::raw_ostream &OS) {
39859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  char Buffer[256];
39959076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  Token PrevTok;
40059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  while (1) {
4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    // If this token is at the start of a line, emit newlines if needed.
40359076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
40459076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      // done.
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    } else if (Tok.hasLeadingSpace() ||
40659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               // If we haven't emitted a token on this line yet, PrevTok isn't
40759076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               // useful to look at and no concatenation could happen anyway.
40859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               (Callbacks->hasEmittedTokensOnThisLine() &&
40959076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                // Don't print "-" next to "-", it would form "--".
41059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                Callbacks->AvoidConcat(PrevTok, Tok))) {
41159076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS << ' ';
41259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    }
4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41459076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
41501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      OS << II->getName();
41659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
41759076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               Tok.getLiteralData()) {
41859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS.write(Tok.getLiteralData(), Tok.getLength());
41959076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    } else if (Tok.getLength() < 256) {
42059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      const char *TokPtr = Buffer;
42159076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      unsigned Len = PP.getSpelling(Tok, TokPtr);
42259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS.write(TokPtr, Len);
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4243ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      // Tokens that can contain embedded newlines need to adjust our current
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // line number.
4263ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      if (Tok.getKind() == tok::comment)
4273ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        Callbacks->HandleNewlinesInToken(TokPtr, Len);
42859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    } else {
42959076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      std::string S = PP.getSpelling(Tok);
43059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS.write(&S[0], S.size());
4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4323ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      // Tokens that can contain embedded newlines need to adjust our current
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // line number.
4343ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      if (Tok.getKind() == tok::comment)
4353ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        Callbacks->HandleNewlinesInToken(&S[0], S.size());
43659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    }
43759076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    Callbacks->SetEmittedTokensOnThisLine();
4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43959076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    if (Tok.is(tok::eof)) break;
4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44159076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    PrevTok = Tok;
44259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    PP.Lex(Tok);
44359076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  }
44459076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner}
44559076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner
4463ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramertypedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair;
4473ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramerstatic int MacroIDCompare(const void* a, const void* b) {
4483ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer  const id_macro_pair *LHS = static_cast<const id_macro_pair*>(a);
4493ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer  const id_macro_pair *RHS = static_cast<const id_macro_pair*>(b);
4503ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer  return LHS->first->getName().compare(RHS->first->getName());
4512a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattner}
45259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner
453775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbarstatic void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
454f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // -dM mode just scans and ignores all tokens in the files, then dumps out
455f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // the macro table at the end.
456f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.EnterMainSourceFile();
457f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
458f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  Token Tok;
459f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  do PP.Lex(Tok);
460f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  while (Tok.isNot(tok::eof));
461f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
4623ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer  llvm::SmallVector<id_macro_pair, 128>
4633ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer    MacrosByID(PP.macro_begin(), PP.macro_end());
4643ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer  llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
465f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
466f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
467f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    MacroInfo &MI = *MacrosByID[i].second;
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Ignore computed macros like __LINE__ and friends.
469f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    if (MI.isBuiltinMacro()) continue;
470f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
471f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
4723ff2a4b861082f271bb769755ea6d1da4b3e6b8dBenjamin Kramer    *OS << '\n';
473f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  }
474f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman}
475f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
4765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// DoPrintPreprocessedInput - This implements -E mode.
4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
47812d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedmanvoid clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
47929cf746aef63b1984c013448e843a290b2badf7bDaniel Dunbar                                     const PreprocessorOutputOptions &Opts) {
480775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  // Show macros with no output is handled specially.
481775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  if (!Opts.ShowCPP) {
482775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar    assert(Opts.ShowMacros && "Not yet implemented!");
483775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar    DoPrintMacros(PP, OS);
484775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar    return;
485775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  }
486775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar
4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Inform the preprocessor whether we want it to retain comments or not, due
4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // to -C or -CC.
489775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
490f54fce8ff8818cde6b421265f709319f5fea0844Eli Friedman
491f54fce8ff8818cde6b421265f709319f5fea0844Eli Friedman  OS->SetBufferSize(64*1024);
492d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
49312d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  PrintPPOutputPPCallbacks *Callbacks =
494775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar      new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
495775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar                                   Opts.ShowMacros);
496f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks));
497f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
498f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman                                                      Callbacks));
499f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
500f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.setPPCallbacks(Callbacks);
501f54fce8ff8818cde6b421265f709319f5fea0844Eli Friedman
502f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // After we have configured the preprocessor, enter the main file.
503f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.EnterMainSourceFile();
504f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
505f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // Consume all of the tokens that come from the predefines buffer.  Those
506f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // should not be emitted into the output and are guaranteed to be at the
507f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // start.
508f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  const SourceManager &SourceMgr = PP.getSourceManager();
509f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  Token Tok;
510f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  do PP.Lex(Tok);
511f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
512f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman         !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
513f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman                 "<built-in>"));
514f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
515f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // Read all the preprocessed tokens, printing them out to the stream.
516f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
517f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  *OS << '\n';
5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
520