PrintPreprocessedOutput.cpp revision d76fbda5da19c34752aa582e690a4dbd1cae39cd
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"
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringExtras.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 << '(';
39d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    if (MI.arg_empty())
40d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      ;
411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    else if (MI.getNumArgs() == 1)
42d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      OS << (*MI.arg_begin())->getName();
43d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    else {
44d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
45d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      OS << (*AI++)->getName();
46d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      while (AI != E)
47d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner        OS << ',' << (*AI++)->getName();
48d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    }
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
50d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    if (MI.isVariadic()) {
51d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      if (!MI.arg_empty())
52d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner        OS << ',';
53d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      OS << "...";
54d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    }
55d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    OS << ')';
56d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  }
571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
58d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  // GCC always emits a space, even if the macro body is empty.  However, do not
59d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  // want to emit two spaces if the first token has a leading space.
60d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
61d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    OS << ' ';
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  llvm::SmallVector<char, 128> SpellingBuffer;
64d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end();
65d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner       I != E; ++I) {
66d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    if (I->hasLeadingSpace())
67d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      OS << ' ';
681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    // Make sure we have enough space in the spelling buffer.
703e27c01eb48c189723b263796d0dbe008b9c95c1Ted Kremenek    if (I->getLength() > SpellingBuffer.size())
71d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      SpellingBuffer.resize(I->getLength());
72beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad    const char *Buffer = SpellingBuffer.data();
73d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    unsigned SpellingLen = PP.getSpelling(*I, Buffer);
74d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner    OS.write(Buffer, SpellingLen);
75d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  }
76d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner}
77d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Preprocessed token printer
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass PrintPPOutputPPCallbacks : public PPCallbacks {
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Preprocessor &PP;
85d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  TokenConcatenation ConcatInfo;
86e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattnerpublic:
87e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner  llvm::raw_ostream &OS;
88e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattnerprivate:
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned CurLine;
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool EmittedTokensOnThisLine;
913e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman  bool EmittedMacroOnThisLine;
929d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind FileType;
93d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner  llvm::SmallString<512> CurFilename;
94737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  bool Initialized;
9512d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  bool DisableLineMarkers;
9612d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  bool DumpDefines;
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
9812d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
9912d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman                           bool lineMarkers, bool defines)
10012d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman     : PP(pp), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
10112d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman       DumpDefines(defines) {
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CurLine = 0;
103d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner    CurFilename += "<uninit>";
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    EmittedTokensOnThisLine = false;
1053e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    EmittedMacroOnThisLine = false;
1060b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    FileType = SrcMgr::C_User;
107737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    Initialized = false;
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
111f0f2b295437efecc0b52220b3f4a469fbb9aeac8Chris Lattner  bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
1149d72851fec9e9c62570a027d42701562bbf29751Chris Lattner                           SrcMgr::CharacteristicKind FileType);
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void Ident(SourceLocation Loc, const std::string &str);
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
117c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner                             const std::string &Str);
118c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1205f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  bool HandleFirstTokOnLine(Token &Tok);
1215f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  bool MoveToLine(SourceLocation Loc);
122d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  bool AvoidConcat(const Token &PrevTok, const Token &Tok) {
123d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    return ConcatInfo.AvoidConcat(PrevTok, Tok);
124d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  }
125737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1273ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  void HandleNewlinesInToken(const char *TokStr, unsigned Len);
1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
129d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  /// MacroDefined - This hook is called whenever a macro definition is seen.
130d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1335db17c9b5edb43e12196e565389b73e91a4fcb65Chris Lattner}  // end anonymous namespace
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
135737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbarvoid PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
136737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar                                             const char *Extra,
137737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar                                             unsigned ExtraLen) {
1383e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman  if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
139737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    OS << '\n';
140737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    EmittedTokensOnThisLine = false;
1413e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    EmittedMacroOnThisLine = false;
142737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  }
143737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
144d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff  OS << '#';
145d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff  if (PP.getLangOptions().Microsoft)
146d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff    OS << "line";
147d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff  OS << ' ' << LineNo << ' ' << '"';
148d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff
149737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  OS.write(&CurFilename[0], CurFilename.size());
150737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  OS << '"';
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
152d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff  if (!PP.getLangOptions().Microsoft) {
153d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff    if (ExtraLen)
154d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff      OS.write(Extra, ExtraLen);
155737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
156d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff    if (FileType == SrcMgr::C_System)
157d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff      OS.write(" 3", 2);
158d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff    else if (FileType == SrcMgr::C_ExternCSystem)
159d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff      OS.write(" 3 4", 4);
160d76fbda5da19c34752aa582e690a4dbd1cae39cdSteve Naroff  }
161737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  OS << '\n';
162737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar}
163737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// MoveToLine - Move the output to the source line specified by the location
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// object.  We can do this by emitting some number of \n's, or be emitting a
1665f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// #line directive.  This returns false if already at the specified line, true
1675f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// if some newlines were emitted.
1685f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattnerbool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) {
169f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner  unsigned LineNo = PP.getSourceManager().getInstantiationLineNumber(Loc);
170737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (DisableLineMarkers) {
1725f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    if (LineNo == CurLine) return false;
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1745f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    CurLine = LineNo;
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1763e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    if (!EmittedTokensOnThisLine && !EmittedMacroOnThisLine)
1775f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner      return true;
1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
179e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    OS << '\n';
1805f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    EmittedTokensOnThisLine = false;
1813e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman    EmittedMacroOnThisLine = false;
1825f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    return true;
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
184737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this line is "close enough" to the original line, just print newlines,
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // otherwise print a #line directive.
187fd96684034c29c59a134dfec20d61c132e60ef30Daniel Dunbar  if (LineNo-CurLine <= 8) {
188822f9406477554b7290a73a78d5d89308c157e05Chris Lattner    if (LineNo-CurLine == 1)
189e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner      OS << '\n';
1905f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    else if (LineNo == CurLine)
191f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner      return false;    // Spelling line moved, but instantiation line didn't.
192822f9406477554b7290a73a78d5d89308c157e05Chris Lattner    else {
193822f9406477554b7290a73a78d5d89308c157e05Chris Lattner      const char *NewLines = "\n\n\n\n\n\n\n\n";
194e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner      OS.write(NewLines, LineNo-CurLine);
195822f9406477554b7290a73a78d5d89308c157e05Chris Lattner    }
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
197737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(LineNo, 0, 0);
1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
199737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CurLine = LineNo;
2015f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  return true;
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FileChanged - Whenever the preprocessor enters or exits a #include file
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// it invokes this handler.  Update our conception of the current source
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// position.
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                           FileChangeReason Reason,
2109d72851fec9e9c62570a027d42701562bbf29751Chris Lattner                                       SrcMgr::CharacteristicKind NewFileType) {
2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Unless we are exiting a #include, make sure to skip ahead to the line the
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // #include directive was at.
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceManager &SourceMgr = PP.getSourceManager();
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (Reason == PPCallbacks::EnterFile) {
21571d8bfb560735e8d47105cf434409ed347267830Chris Lattner    SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
21671d8bfb560735e8d47105cf434409ed347267830Chris Lattner    if (IncludeLoc.isValid())
21771d8bfb560735e8d47105cf434409ed347267830Chris Lattner      MoveToLine(IncludeLoc);
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else if (Reason == PPCallbacks::SystemHeaderPragma) {
2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    MoveToLine(Loc);
2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // TODO GCC emits the # directive for this directive on the line AFTER the
2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // directive and emits a bunch of spaces that aren't needed.  Emulate this
2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // strange behavior.
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
226f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner  Loc = SourceMgr.getInstantiationLoc(Loc);
22716629386f1326608dc1ff9f4ff785fb3fae0bfb3Chris Lattner  // FIXME: Should use presumed line #!
22830fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner  CurLine = SourceMgr.getInstantiationLineNumber(Loc);
229737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
2305f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  if (DisableLineMarkers) return;
2315f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner
232d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner  CurFilename.clear();
233b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner  CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename();
234d8e3083840fef752d11ca183f42786470ed061e3Chris Lattner  Lexer::Stringify(CurFilename);
235737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  FileType = NewFileType;
236737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
237737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar  if (!Initialized) {
238737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine);
239737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    Initialized = true;
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
241737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar
2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (Reason) {
2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case PPCallbacks::EnterFile:
244737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine, " 1", 2);
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case PPCallbacks::ExitFile:
247737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine, " 2", 2);
248737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    break;
2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case PPCallbacks::SystemHeaderPragma:
2501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case PPCallbacks::RenameFile:
251737bdb418c8283d53cb16dbf660de29bcd077b6cDaniel Dunbar    WriteLineInfo(CurLine);
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
256c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner/// Ident - Handle #ident directives when read by the preprocessor.
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  MoveToLine(Loc);
2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
261e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner  OS.write("#ident ", strlen("#ident "));
262e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner  OS.write(&S[0], S.size());
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  EmittedTokensOnThisLine = true;
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
266d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner/// MacroDefined - This hook is called whenever a macro definition is seen.
267d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattnervoid PrintPPOutputPPCallbacks::MacroDefined(const IdentifierInfo *II,
268d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner                                            const MacroInfo *MI) {
269d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  // Only print out macro definitions in -dD mode.
270d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  if (!DumpDefines ||
271d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      // Ignore __FILE__ etc.
272d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner      MI->isBuiltinMacro()) return;
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
274d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  MoveToLine(MI->getDefinitionLoc());
275d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner  PrintMacroDefinition(*II, *MI, PP, OS);
2763e753e279d2457cf16b45be88032c4a117f9adb3Eli Friedman  EmittedMacroOnThisLine = true;
277d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner}
278d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
279d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
280c7d945d053f122eba704ef14c518db2ae595c562Chris Lattnervoid PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
2811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             const IdentifierInfo *Kind,
282c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner                                             const std::string &Str) {
283c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  MoveToLine(Loc);
284c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  OS << "#pragma comment(" << Kind->getName();
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
286c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  if (!Str.empty()) {
287c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    OS << ", \"";
2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
289c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    for (unsigned i = 0, e = Str.size(); i != e; ++i) {
290c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner      unsigned char Char = Str[i];
29152a3e9ed658859606544bbdf5f5d1c3b89471820Chris Lattner      if (isprint(Char) && Char != '\\' && Char != '"')
292c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner        OS << (char)Char;
293c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner      else  // Output anything hard as an octal escape.
294c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner        OS << '\\'
295c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner           << (char)('0'+ ((Char >> 6) & 7))
296c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner           << (char)('0'+ ((Char >> 3) & 7))
297c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner           << (char)('0'+ ((Char >> 0) & 7));
298c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    }
299c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner    OS << '"';
300c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  }
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
302c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  OS << ')';
303c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner  EmittedTokensOnThisLine = true;
304c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner}
305c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner
306c7d945d053f122eba704ef14c518db2ae595c562Chris Lattner
3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
3085f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// is called for the first token on each new line.  If this really is the start
3095f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// of a new logical line, handle it and return true, otherwise return false.
3105f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner/// This may not be the start of a logical line because the "start of line"
311f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// marker is set for spelling lines, not instantiation ones.
3125f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattnerbool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Figure out what line we went to and insert the appropriate number of
3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // newline characters.
3155f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  if (!MoveToLine(Tok.getLocation()))
3165f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner    return false;
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Print out space characters so that the first token on a line is
3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // indented for easy reading.
3209dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner  const SourceManager &SourceMgr = PP.getSourceManager();
321f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner  unsigned ColNo = SourceMgr.getInstantiationColumnNumber(Tok.getLocation());
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // This hack prevents stuff like:
3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // #define HASH #
3255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // HASH define foo bar
3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // From having the # character end up at column 1, which makes it so it
3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // is not handled as a #define next time through the preprocessor if in
3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // -fpreprocessed mode.
329057aaf6304a5f59bcafa7b46c19625bb779af1d1Chris Lattner  if (ColNo <= 1 && Tok.is(tok::hash))
330e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    OS << ' ';
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Otherwise, indent the appropriate number of spaces.
3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (; ColNo > 1; --ColNo)
334e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    OS << ' ';
3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3365f1803210b24b79c1a20f88aa8b0c62191e9d1cbChris Lattner  return true;
3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3393ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattnervoid PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
3403ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner                                                     unsigned Len) {
3413ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  unsigned NumNewlines = 0;
3423ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  for (; Len; --Len, ++TokStr) {
3433ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    if (*TokStr != '\n' &&
3443ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        *TokStr != '\r')
3453ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      continue;
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3473ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    ++NumNewlines;
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3493ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    // If we have \n\r or \r\n, skip both and count as one line.
3503ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner    if (Len != 1 &&
3513ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        (TokStr[1] == '\n' || TokStr[1] == '\r') &&
3523ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        TokStr[0] != TokStr[1])
3533ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      ++TokStr, --Len;
3543ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  }
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3563ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner  if (NumNewlines == 0) return;
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
358ed2d7c4ffd4112ddf10cb95e48428bae0b36377aChris Lattner  CurLine += NumNewlines;
3593ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner}
3603ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner
3613ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct UnknownPragmaHandler : public PragmaHandler {
3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *Prefix;
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PrintPPOutputPPCallbacks *Callbacks;
3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {}
369d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) {
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Figure out what line we went to and insert the appropriate number of
3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // newline characters.
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Callbacks->MoveToLine(PragmaTok.getLocation());
373e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    Callbacks->OS.write(Prefix, strlen(Prefix));
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read and print all of the pragma tokens.
376057aaf6304a5f59bcafa7b46c19625bb779af1d1Chris Lattner    while (PragmaTok.isNot(tok::eom)) {
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (PragmaTok.hasLeadingSpace())
378e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner        Callbacks->OS << ' ';
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      std::string TokSpell = PP.getSpelling(PragmaTok);
380e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner      Callbacks->OS.write(&TokSpell[0], TokSpell.size());
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PP.LexUnexpandedToken(PragmaTok);
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
383e96de3e9134bee666f5cb1f5127b95e1c48c5bc2Chris Lattner    Callbacks->OS << '\n';
3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end anonymous namespace
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
388f0f2b295437efecc0b52220b3f4a469fbb9aeac8Chris Lattner
38959076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattnerstatic void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
39059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                                    PrintPPOutputPPCallbacks *Callbacks,
39159076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                                    llvm::raw_ostream &OS) {
39259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  char Buffer[256];
39359076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  Token PrevTok;
39459076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  while (1) {
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    // If this token is at the start of a line, emit newlines if needed.
39759076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
39859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      // done.
3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    } else if (Tok.hasLeadingSpace() ||
40059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               // If we haven't emitted a token on this line yet, PrevTok isn't
40159076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               // useful to look at and no concatenation could happen anyway.
40259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               (Callbacks->hasEmittedTokensOnThisLine() &&
40359076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                // Don't print "-" next to "-", it would form "--".
40459076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner                Callbacks->AvoidConcat(PrevTok, Tok))) {
40559076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS << ' ';
40659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    }
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
40901eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      OS << II->getName();
41059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
41159076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner               Tok.getLiteralData()) {
41259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS.write(Tok.getLiteralData(), Tok.getLength());
41359076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    } else if (Tok.getLength() < 256) {
41459076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      const char *TokPtr = Buffer;
41559076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      unsigned Len = PP.getSpelling(Tok, TokPtr);
41659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS.write(TokPtr, Len);
4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4183ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      // Tokens that can contain embedded newlines need to adjust our current
4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // line number.
4203ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      if (Tok.getKind() == tok::comment)
4213ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        Callbacks->HandleNewlinesInToken(TokPtr, Len);
42259076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    } else {
42359076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      std::string S = PP.getSpelling(Tok);
42459076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner      OS.write(&S[0], S.size());
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4263ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      // Tokens that can contain embedded newlines need to adjust our current
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // line number.
4283ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner      if (Tok.getKind() == tok::comment)
4293ee211fd15dfeeb51bb69681084cdfcea427f314Chris Lattner        Callbacks->HandleNewlinesInToken(&S[0], S.size());
43059076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    }
43159076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    Callbacks->SetEmittedTokensOnThisLine();
4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43359076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    if (Tok.is(tok::eof)) break;
4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43559076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    PrevTok = Tok;
43659076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner    PP.Lex(Tok);
43759076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner  }
43859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner}
43959076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner
4402a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattnernamespace {
4412a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattner  struct SortMacrosByID {
4422a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattner    typedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair;
4432a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattner    bool operator()(const id_macro_pair &LHS, const id_macro_pair &RHS) const {
44401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      return LHS.first->getName() < RHS.first->getName();
4452a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattner    }
4462a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattner  };
4472a2bb1855a23b5415d3f6d0e1699c3c37c12ad28Chris Lattner}
44859076ab80b67774ee9e90d9d906c7877cb99f07bChris Lattner
449775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbarstatic void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
450f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // -dM mode just scans and ignores all tokens in the files, then dumps out
451f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // the macro table at the end.
452f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.EnterMainSourceFile();
453f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
454f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  Token Tok;
455f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  do PP.Lex(Tok);
456f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  while (Tok.isNot(tok::eof));
457f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
458f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  std::vector<std::pair<IdentifierInfo*, MacroInfo*> > MacrosByID;
459f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
460f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman       I != E; ++I)
461f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    MacrosByID.push_back(*I);
462f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  std::sort(MacrosByID.begin(), MacrosByID.end(), SortMacrosByID());
463f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
464f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
465f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    MacroInfo &MI = *MacrosByID[i].second;
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Ignore computed macros like __LINE__ and friends.
467f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    if (MI.isBuiltinMacro()) continue;
468f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
469f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
470f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman    *OS << "\n";
471f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  }
472f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman}
473f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
4745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// DoPrintPreprocessedInput - This implements -E mode.
4755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
47612d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedmanvoid clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
47729cf746aef63b1984c013448e843a290b2badf7bDaniel Dunbar                                     const PreprocessorOutputOptions &Opts) {
478775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  // Show macros with no output is handled specially.
479775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  if (!Opts.ShowCPP) {
480775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar    assert(Opts.ShowMacros && "Not yet implemented!");
481775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar    DoPrintMacros(PP, OS);
482775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar    return;
483775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  }
484775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Inform the preprocessor whether we want it to retain comments or not, due
4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // to -C or -CC.
487775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar  PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
488f54fce8ff8818cde6b421265f709319f5fea0844Eli Friedman
489f54fce8ff8818cde6b421265f709319f5fea0844Eli Friedman  OS->SetBufferSize(64*1024);
490d82df3ad430397d7f9ef511e7c5157f997c41f53Chris Lattner
49112d3b1d98ec4463b733348e9fb8eadd19b365b0bEli Friedman  PrintPPOutputPPCallbacks *Callbacks =
492775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar      new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
493775bee71ad21c84bc130af22ac47c1c8e0f9e72fDaniel Dunbar                                   Opts.ShowMacros);
494f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks));
495f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
496f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman                                                      Callbacks));
497f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
498f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.setPPCallbacks(Callbacks);
499f54fce8ff8818cde6b421265f709319f5fea0844Eli Friedman
500f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // After we have configured the preprocessor, enter the main file.
501f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PP.EnterMainSourceFile();
502f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
503f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // Consume all of the tokens that come from the predefines buffer.  Those
504f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // should not be emitted into the output and are guaranteed to be at the
505f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // start.
506f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  const SourceManager &SourceMgr = PP.getSourceManager();
507f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  Token Tok;
508f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  do PP.Lex(Tok);
509f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
510f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman         !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
511f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman                 "<built-in>"));
512f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman
513f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  // Read all the preprocessed tokens, printing them out to the stream.
514f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
515f1db58547a7004eefeca08b44f3e7da71ba578a2Eli Friedman  *OS << '\n';
5165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
518