PrintPreprocessedOutput.cpp revision 204962
1168404Spjd//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
2168404Spjd//
3168404Spjd//                     The LLVM Compiler Infrastructure
4168404Spjd//
5168404Spjd// This file is distributed under the University of Illinois Open Source
6168404Spjd// License. See LICENSE.TXT for details.
7168404Spjd//
8168404Spjd//===----------------------------------------------------------------------===//
9168404Spjd//
10168404Spjd// This code simply runs the preprocessor on the input file and prints out the
11168404Spjd// result.  This is the traditional behavior of the -E option.
12168404Spjd//
13168404Spjd//===----------------------------------------------------------------------===//
14168404Spjd
15168404Spjd#include "clang/Frontend/Utils.h"
16168404Spjd#include "clang/Basic/Diagnostic.h"
17168404Spjd#include "clang/Basic/SourceManager.h"
18168404Spjd#include "clang/Frontend/PreprocessorOutputOptions.h"
19168404Spjd#include "clang/Lex/MacroInfo.h"
20168404Spjd#include "clang/Lex/PPCallbacks.h"
21168404Spjd#include "clang/Lex/Pragma.h"
22185029Spjd#include "clang/Lex/Preprocessor.h"
23168404Spjd#include "clang/Lex/TokenConcatenation.h"
24168404Spjd#include "llvm/ADT/SmallString.h"
25168404Spjd#include "llvm/ADT/STLExtras.h"
26168404Spjd#include "llvm/Config/config.h"
27168404Spjd#include "llvm/Support/raw_ostream.h"
28168404Spjd#include <cstdio>
29168404Spjdusing namespace clang;
30168404Spjd
31168404Spjd/// PrintMacroDefinition - Print a macro definition in a form that will be
32168404Spjd/// properly accepted back as a definition.
33168404Spjdstatic void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
34168404Spjd                                 Preprocessor &PP, llvm::raw_ostream &OS) {
35168404Spjd  OS << "#define " << II.getName();
36168404Spjd
37168404Spjd  if (MI.isFunctionLike()) {
38168404Spjd    OS << '(';
39168404Spjd    if (!MI.arg_empty()) {
40168404Spjd      MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
41168404Spjd      for (; AI+1 != E; ++AI) {
42168404Spjd        OS << (*AI)->getName();
43168404Spjd        OS << ',';
44168404Spjd      }
45168404Spjd
46168404Spjd      // Last argument.
47168404Spjd      if ((*AI)->getName() == "__VA_ARGS__")
48168404Spjd        OS << "...";
49168404Spjd      else
50168404Spjd        OS << (*AI)->getName();
51168404Spjd    }
52168404Spjd
53168404Spjd    if (MI.isGNUVarargs())
54168404Spjd      OS << "...";  // #define foo(x...)
55168404Spjd
56168404Spjd    OS << ')';
57168404Spjd  }
58168404Spjd
59168404Spjd  // GCC always emits a space, even if the macro body is empty.  However, do not
60168404Spjd  // want to emit two spaces if the first token has a leading space.
61168404Spjd  if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
62168404Spjd    OS << ' ';
63168404Spjd
64168404Spjd  llvm::SmallVector<char, 128> SpellingBuffer;
65168404Spjd  for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end();
66168404Spjd       I != E; ++I) {
67168404Spjd    if (I->hasLeadingSpace())
68168404Spjd      OS << ' ';
69168404Spjd
70168404Spjd    OS << PP.getSpelling(*I, SpellingBuffer);
71169028Spjd  }
72168404Spjd}
73168404Spjd
74168404Spjd//===----------------------------------------------------------------------===//
75168404Spjd// Preprocessed token printer
76168404Spjd//===----------------------------------------------------------------------===//
77168404Spjd
78168404Spjdnamespace {
79168404Spjdclass PrintPPOutputPPCallbacks : public PPCallbacks {
80168404Spjd  Preprocessor &PP;
81168404Spjd  TokenConcatenation ConcatInfo;
82168404Spjdpublic:
83168404Spjd  llvm::raw_ostream &OS;
84168404Spjdprivate:
85168404Spjd  unsigned CurLine;
86168404Spjd  bool EmittedTokensOnThisLine;
87168404Spjd  bool EmittedMacroOnThisLine;
88168404Spjd  SrcMgr::CharacteristicKind FileType;
89168404Spjd  llvm::SmallString<512> CurFilename;
90168404Spjd  bool Initialized;
91168404Spjd  bool DisableLineMarkers;
92168404Spjd  bool DumpDefines;
93168404Spjd  bool UseLineDirective;
94168404Spjdpublic:
95168404Spjd  PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
96168404Spjd                           bool lineMarkers, bool defines)
97168404Spjd     : PP(pp), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
98168404Spjd       DumpDefines(defines) {
99168404Spjd    CurLine = 0;
100168404Spjd    CurFilename += "<uninit>";
101168404Spjd    EmittedTokensOnThisLine = false;
102168404Spjd    EmittedMacroOnThisLine = false;
103168404Spjd    FileType = SrcMgr::C_User;
104168404Spjd    Initialized = false;
105168404Spjd
106168404Spjd    // If we're in microsoft mode, use normal #line instead of line markers.
107168404Spjd    UseLineDirective = PP.getLangOptions().Microsoft;
108168404Spjd  }
109168404Spjd
110168404Spjd  void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
111168404Spjd  bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
112168404Spjd
113168404Spjd  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
114168404Spjd                           SrcMgr::CharacteristicKind FileType);
115168404Spjd  virtual void Ident(SourceLocation Loc, const std::string &str);
116168404Spjd  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
117168404Spjd                             const std::string &Str);
118168404Spjd
119168404Spjd
120168404Spjd  bool HandleFirstTokOnLine(Token &Tok);
121168404Spjd  bool MoveToLine(SourceLocation Loc);
122168404Spjd  bool AvoidConcat(const Token &PrevTok, const Token &Tok) {
123168404Spjd    return ConcatInfo.AvoidConcat(PrevTok, Tok);
124168404Spjd  }
125168404Spjd  void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
126168404Spjd
127168404Spjd  void HandleNewlinesInToken(const char *TokStr, unsigned Len);
128168404Spjd
129168404Spjd  /// MacroDefined - This hook is called whenever a macro definition is seen.
130168404Spjd  void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
131168404Spjd
132168404Spjd};
133168404Spjd}  // end anonymous namespace
134168404Spjd
135168404Spjdvoid PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
136168404Spjd                                             const char *Extra,
137168404Spjd                                             unsigned ExtraLen) {
138168404Spjd  if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
139168404Spjd    OS << '\n';
140168404Spjd    EmittedTokensOnThisLine = false;
141168404Spjd    EmittedMacroOnThisLine = false;
142168404Spjd  }
143168404Spjd
144168404Spjd  // Emit #line directives or GNU line markers depending on what mode we're in.
145168404Spjd  if (UseLineDirective) {
146168404Spjd    OS << "#line" << ' ' << LineNo << ' ' << '"';
147168404Spjd    OS.write(&CurFilename[0], CurFilename.size());
148168404Spjd    OS << '"';
149168404Spjd  } else {
150168404Spjd    OS << '#' << ' ' << LineNo << ' ' << '"';
151168404Spjd    OS.write(&CurFilename[0], CurFilename.size());
152168404Spjd    OS << '"';
153168404Spjd
154168404Spjd    if (ExtraLen)
155168404Spjd      OS.write(Extra, ExtraLen);
156168404Spjd
157168404Spjd    if (FileType == SrcMgr::C_System)
158168404Spjd      OS.write(" 3", 2);
159168404Spjd    else if (FileType == SrcMgr::C_ExternCSystem)
160168404Spjd      OS.write(" 3 4", 4);
161168404Spjd  }
162168404Spjd  OS << '\n';
163168404Spjd}
164168404Spjd
165168404Spjd/// MoveToLine - Move the output to the source line specified by the location
166168404Spjd/// object.  We can do this by emitting some number of \n's, or be emitting a
167168404Spjd/// #line directive.  This returns false if already at the specified line, true
168168404Spjd/// if some newlines were emitted.
169168404Spjdbool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) {
170168404Spjd  unsigned LineNo = PP.getSourceManager().getInstantiationLineNumber(Loc);
171168404Spjd
172168404Spjd  if (DisableLineMarkers) {
173168404Spjd    if (LineNo == CurLine) return false;
174168404Spjd
175185029Spjd    CurLine = LineNo;
176185029Spjd
177185029Spjd    if (!EmittedTokensOnThisLine && !EmittedMacroOnThisLine)
178185029Spjd      return true;
179185029Spjd
180168404Spjd    OS << '\n';
181168404Spjd    EmittedTokensOnThisLine = false;
182168404Spjd    EmittedMacroOnThisLine = false;
183168404Spjd    return true;
184168404Spjd  }
185168404Spjd
186168404Spjd  // If this line is "close enough" to the original line, just print newlines,
187168404Spjd  // otherwise print a #line directive.
188168404Spjd  if (LineNo-CurLine <= 8) {
189168404Spjd    if (LineNo-CurLine == 1)
190185029Spjd      OS << '\n';
191185029Spjd    else if (LineNo == CurLine)
192168404Spjd      return false;    // Spelling line moved, but instantiation line didn't.
193168404Spjd    else {
194185029Spjd      const char *NewLines = "\n\n\n\n\n\n\n\n";
195185029Spjd      OS.write(NewLines, LineNo-CurLine);
196168404Spjd    }
197168404Spjd  } else {
198168404Spjd    WriteLineInfo(LineNo, 0, 0);
199185029Spjd  }
200185029Spjd
201185029Spjd  CurLine = LineNo;
202185029Spjd  return true;
203185029Spjd}
204168404Spjd
205168404Spjd
206168404Spjd/// FileChanged - Whenever the preprocessor enters or exits a #include file
207168404Spjd/// it invokes this handler.  Update our conception of the current source
208168404Spjd/// position.
209168404Spjdvoid PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
210168404Spjd                                           FileChangeReason Reason,
211168404Spjd                                       SrcMgr::CharacteristicKind NewFileType) {
212168404Spjd  // Unless we are exiting a #include, make sure to skip ahead to the line the
213168404Spjd  // #include directive was at.
214168404Spjd  SourceManager &SourceMgr = PP.getSourceManager();
215168404Spjd  if (Reason == PPCallbacks::EnterFile) {
216168404Spjd    SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
217168404Spjd    if (IncludeLoc.isValid())
218168404Spjd      MoveToLine(IncludeLoc);
219168404Spjd  } else if (Reason == PPCallbacks::SystemHeaderPragma) {
220168404Spjd    MoveToLine(Loc);
221168404Spjd
222168404Spjd    // TODO GCC emits the # directive for this directive on the line AFTER the
223168404Spjd    // directive and emits a bunch of spaces that aren't needed.  Emulate this
224168404Spjd    // strange behavior.
225168404Spjd  }
226168404Spjd
227168404Spjd  Loc = SourceMgr.getInstantiationLoc(Loc);
228168404Spjd  // FIXME: Should use presumed line #!
229168404Spjd  CurLine = SourceMgr.getInstantiationLineNumber(Loc);
230168404Spjd
231168404Spjd  if (DisableLineMarkers) return;
232168404Spjd
233168404Spjd  CurFilename.clear();
234168404Spjd  CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename();
235168404Spjd  Lexer::Stringify(CurFilename);
236168404Spjd  FileType = NewFileType;
237168404Spjd
238168404Spjd  if (!Initialized) {
239168404Spjd    WriteLineInfo(CurLine);
240168404Spjd    Initialized = true;
241168404Spjd  }
242168404Spjd
243168404Spjd  switch (Reason) {
244168404Spjd  case PPCallbacks::EnterFile:
245168404Spjd    WriteLineInfo(CurLine, " 1", 2);
246168404Spjd    break;
247168404Spjd  case PPCallbacks::ExitFile:
248168404Spjd    WriteLineInfo(CurLine, " 2", 2);
249168404Spjd    break;
250168404Spjd  case PPCallbacks::SystemHeaderPragma:
251168404Spjd  case PPCallbacks::RenameFile:
252168404Spjd    WriteLineInfo(CurLine);
253168404Spjd    break;
254168404Spjd  }
255168404Spjd}
256168404Spjd
257168404Spjd/// Ident - Handle #ident directives when read by the preprocessor.
258168404Spjd///
259168404Spjdvoid PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
260168404Spjd  MoveToLine(Loc);
261168404Spjd
262168404Spjd  OS.write("#ident ", strlen("#ident "));
263168404Spjd  OS.write(&S[0], S.size());
264168404Spjd  EmittedTokensOnThisLine = true;
265168404Spjd}
266168404Spjd
267168404Spjd/// MacroDefined - This hook is called whenever a macro definition is seen.
268168404Spjdvoid PrintPPOutputPPCallbacks::MacroDefined(const IdentifierInfo *II,
269168404Spjd                                            const MacroInfo *MI) {
270168404Spjd  // Only print out macro definitions in -dD mode.
271168404Spjd  if (!DumpDefines ||
272168404Spjd      // Ignore __FILE__ etc.
273168404Spjd      MI->isBuiltinMacro()) return;
274168404Spjd
275168404Spjd  MoveToLine(MI->getDefinitionLoc());
276168404Spjd  PrintMacroDefinition(*II, *MI, PP, OS);
277168404Spjd  EmittedMacroOnThisLine = true;
278168404Spjd}
279168404Spjd
280168404Spjd
281168404Spjdvoid PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
282168404Spjd                                             const IdentifierInfo *Kind,
283168404Spjd                                             const std::string &Str) {
284168404Spjd  MoveToLine(Loc);
285168404Spjd  OS << "#pragma comment(" << Kind->getName();
286168404Spjd
287168404Spjd  if (!Str.empty()) {
288168404Spjd    OS << ", \"";
289168404Spjd
290168404Spjd    for (unsigned i = 0, e = Str.size(); i != e; ++i) {
291168404Spjd      unsigned char Char = Str[i];
292168404Spjd      if (isprint(Char) && Char != '\\' && Char != '"')
293168404Spjd        OS << (char)Char;
294168404Spjd      else  // Output anything hard as an octal escape.
295168404Spjd        OS << '\\'
296168404Spjd           << (char)('0'+ ((Char >> 6) & 7))
297168404Spjd           << (char)('0'+ ((Char >> 3) & 7))
298185029Spjd           << (char)('0'+ ((Char >> 0) & 7));
299185029Spjd    }
300168404Spjd    OS << '"';
301168404Spjd  }
302168404Spjd
303168404Spjd  OS << ')';
304168404Spjd  EmittedTokensOnThisLine = true;
305168404Spjd}
306168404Spjd
307168404Spjd
308168404Spjd/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
309168404Spjd/// is called for the first token on each new line.  If this really is the start
310168404Spjd/// of a new logical line, handle it and return true, otherwise return false.
311168404Spjd/// This may not be the start of a logical line because the "start of line"
312168404Spjd/// marker is set for spelling lines, not instantiation ones.
313168404Spjdbool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
314168404Spjd  // Figure out what line we went to and insert the appropriate number of
315168404Spjd  // newline characters.
316168404Spjd  if (!MoveToLine(Tok.getLocation()))
317168404Spjd    return false;
318168404Spjd
319168404Spjd  // Print out space characters so that the first token on a line is
320168404Spjd  // indented for easy reading.
321168404Spjd  const SourceManager &SourceMgr = PP.getSourceManager();
322168404Spjd  unsigned ColNo = SourceMgr.getInstantiationColumnNumber(Tok.getLocation());
323168404Spjd
324168404Spjd  // This hack prevents stuff like:
325168404Spjd  // #define HASH #
326168404Spjd  // HASH define foo bar
327168404Spjd  // From having the # character end up at column 1, which makes it so it
328168404Spjd  // is not handled as a #define next time through the preprocessor if in
329168404Spjd  // -fpreprocessed mode.
330168404Spjd  if (ColNo <= 1 && Tok.is(tok::hash))
331168404Spjd    OS << ' ';
332168404Spjd
333168404Spjd  // Otherwise, indent the appropriate number of spaces.
334168404Spjd  for (; ColNo > 1; --ColNo)
335168404Spjd    OS << ' ';
336168404Spjd
337168404Spjd  return true;
338168404Spjd}
339168404Spjd
340168404Spjdvoid PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
341168404Spjd                                                     unsigned Len) {
342168404Spjd  unsigned NumNewlines = 0;
343168404Spjd  for (; Len; --Len, ++TokStr) {
344168404Spjd    if (*TokStr != '\n' &&
345168404Spjd        *TokStr != '\r')
346168404Spjd      continue;
347168404Spjd
348168404Spjd    ++NumNewlines;
349168404Spjd
350168404Spjd    // If we have \n\r or \r\n, skip both and count as one line.
351168404Spjd    if (Len != 1 &&
352168404Spjd        (TokStr[1] == '\n' || TokStr[1] == '\r') &&
353168404Spjd        TokStr[0] != TokStr[1])
354168404Spjd      ++TokStr, --Len;
355168404Spjd  }
356168404Spjd
357168404Spjd  if (NumNewlines == 0) return;
358168404Spjd
359168404Spjd  CurLine += NumNewlines;
360168404Spjd}
361168404Spjd
362168404Spjd
363168404Spjdnamespace {
364168404Spjdstruct UnknownPragmaHandler : public PragmaHandler {
365168404Spjd  const char *Prefix;
366168404Spjd  PrintPPOutputPPCallbacks *Callbacks;
367168404Spjd
368168404Spjd  UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
369168404Spjd    : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {}
370168404Spjd  virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) {
371168404Spjd    // Figure out what line we went to and insert the appropriate number of
372168404Spjd    // newline characters.
373168404Spjd    Callbacks->MoveToLine(PragmaTok.getLocation());
374168404Spjd    Callbacks->OS.write(Prefix, strlen(Prefix));
375168404Spjd
376168404Spjd    // Read and print all of the pragma tokens.
377168404Spjd    while (PragmaTok.isNot(tok::eom)) {
378168404Spjd      if (PragmaTok.hasLeadingSpace())
379168404Spjd        Callbacks->OS << ' ';
380168404Spjd      std::string TokSpell = PP.getSpelling(PragmaTok);
381168404Spjd      Callbacks->OS.write(&TokSpell[0], TokSpell.size());
382168404Spjd      PP.LexUnexpandedToken(PragmaTok);
383168404Spjd    }
384168404Spjd    Callbacks->OS << '\n';
385168404Spjd  }
386168404Spjd};
387168404Spjd} // end anonymous namespace
388168404Spjd
389168404Spjd
390168404Spjdstatic void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
391168404Spjd                                    PrintPPOutputPPCallbacks *Callbacks,
392168404Spjd                                    llvm::raw_ostream &OS) {
393168404Spjd  char Buffer[256];
394168404Spjd  Token PrevTok;
395168404Spjd  while (1) {
396168404Spjd
397168404Spjd    // If this token is at the start of a line, emit newlines if needed.
398168404Spjd    if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
399168404Spjd      // done.
400168404Spjd    } else if (Tok.hasLeadingSpace() ||
401168404Spjd               // If we haven't emitted a token on this line yet, PrevTok isn't
402168404Spjd               // useful to look at and no concatenation could happen anyway.
403168404Spjd               (Callbacks->hasEmittedTokensOnThisLine() &&
404168404Spjd                // Don't print "-" next to "-", it would form "--".
405168404Spjd                Callbacks->AvoidConcat(PrevTok, Tok))) {
406168404Spjd      OS << ' ';
407168404Spjd    }
408168404Spjd
409168404Spjd    if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
410168404Spjd      OS << II->getName();
411168404Spjd    } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
412168404Spjd               Tok.getLiteralData()) {
413168404Spjd      OS.write(Tok.getLiteralData(), Tok.getLength());
414168404Spjd    } else if (Tok.getLength() < 256) {
415168404Spjd      const char *TokPtr = Buffer;
416168404Spjd      unsigned Len = PP.getSpelling(Tok, TokPtr);
417168404Spjd      OS.write(TokPtr, Len);
418168404Spjd
419168404Spjd      // Tokens that can contain embedded newlines need to adjust our current
420168404Spjd      // line number.
421168404Spjd      if (Tok.getKind() == tok::comment)
422168404Spjd        Callbacks->HandleNewlinesInToken(TokPtr, Len);
423168404Spjd    } else {
424168404Spjd      std::string S = PP.getSpelling(Tok);
425168404Spjd      OS.write(&S[0], S.size());
426168404Spjd
427168404Spjd      // Tokens that can contain embedded newlines need to adjust our current
428168404Spjd      // line number.
429168404Spjd      if (Tok.getKind() == tok::comment)
430168404Spjd        Callbacks->HandleNewlinesInToken(&S[0], S.size());
431168404Spjd    }
432168404Spjd    Callbacks->SetEmittedTokensOnThisLine();
433168404Spjd
434168404Spjd    if (Tok.is(tok::eof)) break;
435168404Spjd
436168404Spjd    PrevTok = Tok;
437168404Spjd    PP.Lex(Tok);
438168404Spjd  }
439185029Spjd}
440185029Spjd
441185029Spjdtypedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair;
442185029Spjdstatic int MacroIDCompare(const void* a, const void* b) {
443185029Spjd  const id_macro_pair *LHS = static_cast<const id_macro_pair*>(a);
444185029Spjd  const id_macro_pair *RHS = static_cast<const id_macro_pair*>(b);
445185029Spjd  return LHS->first->getName().compare(RHS->first->getName());
446185029Spjd}
447185029Spjd
448185029Spjdstatic void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
449168404Spjd  // -dM mode just scans and ignores all tokens in the files, then dumps out
450168404Spjd  // the macro table at the end.
451168404Spjd  PP.EnterMainSourceFile();
452168404Spjd
453168404Spjd  Token Tok;
454168404Spjd  do PP.Lex(Tok);
455168404Spjd  while (Tok.isNot(tok::eof));
456168404Spjd
457168404Spjd  llvm::SmallVector<id_macro_pair, 128>
458168404Spjd    MacrosByID(PP.macro_begin(), PP.macro_end());
459168404Spjd  llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
460168404Spjd
461168404Spjd  for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
462168404Spjd    MacroInfo &MI = *MacrosByID[i].second;
463168404Spjd    // Ignore computed macros like __LINE__ and friends.
464168404Spjd    if (MI.isBuiltinMacro()) continue;
465168404Spjd
466168404Spjd    PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
467168404Spjd    *OS << '\n';
468168404Spjd  }
469168404Spjd}
470168404Spjd
471168404Spjd/// DoPrintPreprocessedInput - This implements -E mode.
472185029Spjd///
473168404Spjdvoid clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
474185029Spjd                                     const PreprocessorOutputOptions &Opts) {
475185029Spjd  // Show macros with no output is handled specially.
476185029Spjd  if (!Opts.ShowCPP) {
477185029Spjd    assert(Opts.ShowMacros && "Not yet implemented!");
478185029Spjd    DoPrintMacros(PP, OS);
479185029Spjd    return;
480185029Spjd  }
481185029Spjd
482185029Spjd  // Inform the preprocessor whether we want it to retain comments or not, due
483185029Spjd  // to -C or -CC.
484185029Spjd  PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
485185029Spjd
486185029Spjd  OS->SetBufferSize(64*1024);
487185029Spjd
488168404Spjd  PrintPPOutputPPCallbacks *Callbacks =
489168404Spjd      new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
490185029Spjd                                   Opts.ShowMacros);
491185029Spjd  PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks));
492185029Spjd  PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
493185029Spjd                                                      Callbacks));
494185029Spjd
495185029Spjd  PP.addPPCallbacks(Callbacks);
496185029Spjd
497185029Spjd  // After we have configured the preprocessor, enter the main file.
498185029Spjd  PP.EnterMainSourceFile();
499185029Spjd
500185029Spjd  // Consume all of the tokens that come from the predefines buffer.  Those
501185029Spjd  // should not be emitted into the output and are guaranteed to be at the
502185029Spjd  // start.
503168404Spjd  const SourceManager &SourceMgr = PP.getSourceManager();
504168404Spjd  Token Tok;
505168404Spjd  do PP.Lex(Tok);
506168404Spjd  while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
507168404Spjd         !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
508168404Spjd                 "<built-in>"));
509168404Spjd
510168404Spjd  // Read all the preprocessed tokens, printing them out to the stream.
511168404Spjd  PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
512168404Spjd  *OS << '\n';
513168404Spjd}
514168404Spjd
515185029Spjd