clang  3.8.0
PrintPreprocessedOutput.cpp
Go to the documentation of this file.
1 //===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This code simply runs the preprocessor on the input file and prints out the
11 // result. This is the traditional behavior of the -E option.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Frontend/Utils.h"
16 #include "clang/Basic/CharInfo.h"
17 #include "clang/Basic/Diagnostic.h"
20 #include "clang/Lex/MacroInfo.h"
21 #include "clang/Lex/PPCallbacks.h"
22 #include "clang/Lex/Pragma.h"
23 #include "clang/Lex/Preprocessor.h"
25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <cstdio>
31 using namespace clang;
32 
33 /// PrintMacroDefinition - Print a macro definition in a form that will be
34 /// properly accepted back as a definition.
35 static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
36  Preprocessor &PP, raw_ostream &OS) {
37  OS << "#define " << II.getName();
38 
39  if (MI.isFunctionLike()) {
40  OS << '(';
41  if (!MI.arg_empty()) {
42  MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
43  for (; AI+1 != E; ++AI) {
44  OS << (*AI)->getName();
45  OS << ',';
46  }
47 
48  // Last argument.
49  if ((*AI)->getName() == "__VA_ARGS__")
50  OS << "...";
51  else
52  OS << (*AI)->getName();
53  }
54 
55  if (MI.isGNUVarargs())
56  OS << "..."; // #define foo(x...)
57 
58  OS << ')';
59  }
60 
61  // GCC always emits a space, even if the macro body is empty. However, do not
62  // want to emit two spaces if the first token has a leading space.
63  if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
64  OS << ' ';
65 
66  SmallString<128> SpellingBuffer;
67  for (const auto &T : MI.tokens()) {
68  if (T.hasLeadingSpace())
69  OS << ' ';
70 
71  OS << PP.getSpelling(T, SpellingBuffer);
72  }
73 }
74 
75 //===----------------------------------------------------------------------===//
76 // Preprocessed token printer
77 //===----------------------------------------------------------------------===//
78 
79 namespace {
80 class PrintPPOutputPPCallbacks : public PPCallbacks {
81  Preprocessor &PP;
83  TokenConcatenation ConcatInfo;
84 public:
85  raw_ostream &OS;
86 private:
87  unsigned CurLine;
88 
89  bool EmittedTokensOnThisLine;
90  bool EmittedDirectiveOnThisLine;
92  SmallString<512> CurFilename;
93  bool Initialized;
94  bool DisableLineMarkers;
95  bool DumpDefines;
96  bool UseLineDirectives;
97  bool IsFirstFileEntered;
98 public:
99  PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, bool lineMarkers,
100  bool defines, bool UseLineDirectives)
101  : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
102  DisableLineMarkers(lineMarkers), DumpDefines(defines),
103  UseLineDirectives(UseLineDirectives) {
104  CurLine = 0;
105  CurFilename += "<uninit>";
106  EmittedTokensOnThisLine = false;
107  EmittedDirectiveOnThisLine = false;
108  FileType = SrcMgr::C_User;
109  Initialized = false;
110  IsFirstFileEntered = false;
111  }
112 
113  void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
114  bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
115 
116  void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; }
117  bool hasEmittedDirectiveOnThisLine() const {
118  return EmittedDirectiveOnThisLine;
119  }
120 
121  bool startNewLineIfNeeded(bool ShouldUpdateCurrentLine = true);
122 
123  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
125  FileID PrevFID) override;
126  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
127  StringRef FileName, bool IsAngled,
128  CharSourceRange FilenameRange, const FileEntry *File,
129  StringRef SearchPath, StringRef RelativePath,
130  const Module *Imported) override;
131  void Ident(SourceLocation Loc, StringRef str) override;
132  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
133  PragmaMessageKind Kind, StringRef Str) override;
134  void PragmaDebug(SourceLocation Loc, StringRef DebugType) override;
135  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override;
136  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override;
137  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
138  diag::Severity Map, StringRef Str) override;
139  void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
140  ArrayRef<int> Ids) override;
141  void PragmaWarningPush(SourceLocation Loc, int Level) override;
142  void PragmaWarningPop(SourceLocation Loc) override;
143 
144  bool HandleFirstTokOnLine(Token &Tok);
145 
146  /// Move to the line of the provided source location. This will
147  /// return true if the output stream required adjustment or if
148  /// the requested location is on the first line.
149  bool MoveToLine(SourceLocation Loc) {
150  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
151  if (PLoc.isInvalid())
152  return false;
153  return MoveToLine(PLoc.getLine()) || (PLoc.getLine() == 1);
154  }
155  bool MoveToLine(unsigned LineNo);
156 
157  bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
158  const Token &Tok) {
159  return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
160  }
161  void WriteLineInfo(unsigned LineNo, const char *Extra=nullptr,
162  unsigned ExtraLen=0);
163  bool LineMarkersAreDisabled() const { return DisableLineMarkers; }
164  void HandleNewlinesInToken(const char *TokStr, unsigned Len);
165 
166  /// MacroDefined - This hook is called whenever a macro definition is seen.
167  void MacroDefined(const Token &MacroNameTok,
168  const MacroDirective *MD) override;
169 
170  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
171  void MacroUndefined(const Token &MacroNameTok,
172  const MacroDefinition &MD) override;
173 };
174 } // end anonymous namespace
175 
176 void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
177  const char *Extra,
178  unsigned ExtraLen) {
179  startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
180 
181  // Emit #line directives or GNU line markers depending on what mode we're in.
182  if (UseLineDirectives) {
183  OS << "#line" << ' ' << LineNo << ' ' << '"';
184  OS.write_escaped(CurFilename);
185  OS << '"';
186  } else {
187  OS << '#' << ' ' << LineNo << ' ' << '"';
188  OS.write_escaped(CurFilename);
189  OS << '"';
190 
191  if (ExtraLen)
192  OS.write(Extra, ExtraLen);
193 
194  if (FileType == SrcMgr::C_System)
195  OS.write(" 3", 2);
196  else if (FileType == SrcMgr::C_ExternCSystem)
197  OS.write(" 3 4", 4);
198  }
199  OS << '\n';
200 }
201 
202 /// MoveToLine - Move the output to the source line specified by the location
203 /// object. We can do this by emitting some number of \n's, or be emitting a
204 /// #line directive. This returns false if already at the specified line, true
205 /// if some newlines were emitted.
206 bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) {
207  // If this line is "close enough" to the original line, just print newlines,
208  // otherwise print a #line directive.
209  if (LineNo-CurLine <= 8) {
210  if (LineNo-CurLine == 1)
211  OS << '\n';
212  else if (LineNo == CurLine)
213  return false; // Spelling line moved, but expansion line didn't.
214  else {
215  const char *NewLines = "\n\n\n\n\n\n\n\n";
216  OS.write(NewLines, LineNo-CurLine);
217  }
218  } else if (!DisableLineMarkers) {
219  // Emit a #line or line marker.
220  WriteLineInfo(LineNo, nullptr, 0);
221  } else {
222  // Okay, we're in -P mode, which turns off line markers. However, we still
223  // need to emit a newline between tokens on different lines.
224  startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
225  }
226 
227  CurLine = LineNo;
228  return true;
229 }
230 
231 bool
232 PrintPPOutputPPCallbacks::startNewLineIfNeeded(bool ShouldUpdateCurrentLine) {
233  if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
234  OS << '\n';
235  EmittedTokensOnThisLine = false;
236  EmittedDirectiveOnThisLine = false;
237  if (ShouldUpdateCurrentLine)
238  ++CurLine;
239  return true;
240  }
241 
242  return false;
243 }
244 
245 /// FileChanged - Whenever the preprocessor enters or exits a #include file
246 /// it invokes this handler. Update our conception of the current source
247 /// position.
248 void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
249  FileChangeReason Reason,
250  SrcMgr::CharacteristicKind NewFileType,
251  FileID PrevFID) {
252  // Unless we are exiting a #include, make sure to skip ahead to the line the
253  // #include directive was at.
255 
256  PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
257  if (UserLoc.isInvalid())
258  return;
259 
260  unsigned NewLine = UserLoc.getLine();
261 
262  if (Reason == PPCallbacks::EnterFile) {
263  SourceLocation IncludeLoc = UserLoc.getIncludeLoc();
264  if (IncludeLoc.isValid())
265  MoveToLine(IncludeLoc);
266  } else if (Reason == PPCallbacks::SystemHeaderPragma) {
267  // GCC emits the # directive for this directive on the line AFTER the
268  // directive and emits a bunch of spaces that aren't needed. This is because
269  // otherwise we will emit a line marker for THIS line, which requires an
270  // extra blank line after the directive to avoid making all following lines
271  // off by one. We can do better by simply incrementing NewLine here.
272  NewLine += 1;
273  }
274 
275  CurLine = NewLine;
276 
277  CurFilename.clear();
278  CurFilename += UserLoc.getFilename();
279  FileType = NewFileType;
280 
281  if (DisableLineMarkers) {
282  startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
283  return;
284  }
285 
286  if (!Initialized) {
287  WriteLineInfo(CurLine);
288  Initialized = true;
289  }
290 
291  // Do not emit an enter marker for the main file (which we expect is the first
292  // entered file). This matches gcc, and improves compatibility with some tools
293  // which track the # line markers as a way to determine when the preprocessed
294  // output is in the context of the main file.
295  if (Reason == PPCallbacks::EnterFile && !IsFirstFileEntered) {
296  IsFirstFileEntered = true;
297  return;
298  }
299 
300  switch (Reason) {
302  WriteLineInfo(CurLine, " 1", 2);
303  break;
305  WriteLineInfo(CurLine, " 2", 2);
306  break;
309  WriteLineInfo(CurLine);
310  break;
311  }
312 }
313 
314 void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
315  const Token &IncludeTok,
316  StringRef FileName,
317  bool IsAngled,
318  CharSourceRange FilenameRange,
319  const FileEntry *File,
320  StringRef SearchPath,
321  StringRef RelativePath,
322  const Module *Imported) {
323  // When preprocessing, turn implicit imports into @imports.
324  // FIXME: This is a stop-gap until a more comprehensive "preprocessing with
325  // modules" solution is introduced.
326  if (Imported) {
327  startNewLineIfNeeded();
328  MoveToLine(HashLoc);
329  OS << "@import " << Imported->getFullModuleName() << ";"
330  << " /* clang -E: implicit import for \"" << File->getName() << "\" */";
331  // Since we want a newline after the @import, but not a #<line>, start a new
332  // line immediately.
333  EmittedTokensOnThisLine = true;
334  startNewLineIfNeeded();
335  }
336 }
337 
338 /// Ident - Handle #ident directives when read by the preprocessor.
339 ///
340 void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
341  MoveToLine(Loc);
342 
343  OS.write("#ident ", strlen("#ident "));
344  OS.write(S.begin(), S.size());
345  EmittedTokensOnThisLine = true;
346 }
347 
348 /// MacroDefined - This hook is called whenever a macro definition is seen.
349 void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
350  const MacroDirective *MD) {
351  const MacroInfo *MI = MD->getMacroInfo();
352  // Only print out macro definitions in -dD mode.
353  if (!DumpDefines ||
354  // Ignore __FILE__ etc.
355  MI->isBuiltinMacro()) return;
356 
357  MoveToLine(MI->getDefinitionLoc());
358  PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS);
359  setEmittedDirectiveOnThisLine();
360 }
361 
362 void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
363  const MacroDefinition &MD) {
364  // Only print out macro definitions in -dD mode.
365  if (!DumpDefines) return;
366 
367  MoveToLine(MacroNameTok.getLocation());
368  OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName();
369  setEmittedDirectiveOnThisLine();
370 }
371 
372 static void outputPrintable(llvm::raw_ostream& OS,
373  const std::string &Str) {
374  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
375  unsigned char Char = Str[i];
376  if (isPrintable(Char) && Char != '\\' && Char != '"')
377  OS << (char)Char;
378  else // Output anything hard as an octal escape.
379  OS << '\\'
380  << (char)('0'+ ((Char >> 6) & 7))
381  << (char)('0'+ ((Char >> 3) & 7))
382  << (char)('0'+ ((Char >> 0) & 7));
383  }
384 }
385 
386 void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
387  StringRef Namespace,
388  PragmaMessageKind Kind,
389  StringRef Str) {
390  startNewLineIfNeeded();
391  MoveToLine(Loc);
392  OS << "#pragma ";
393  if (!Namespace.empty())
394  OS << Namespace << ' ';
395  switch (Kind) {
396  case PMK_Message:
397  OS << "message(\"";
398  break;
399  case PMK_Warning:
400  OS << "warning \"";
401  break;
402  case PMK_Error:
403  OS << "error \"";
404  break;
405  }
406 
407  outputPrintable(OS, Str);
408  OS << '"';
409  if (Kind == PMK_Message)
410  OS << ')';
411  setEmittedDirectiveOnThisLine();
412 }
413 
414 void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
415  StringRef DebugType) {
416  startNewLineIfNeeded();
417  MoveToLine(Loc);
418 
419  OS << "#pragma clang __debug ";
420  OS << DebugType;
421 
422  setEmittedDirectiveOnThisLine();
423 }
424 
425 void PrintPPOutputPPCallbacks::
426 PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
427  startNewLineIfNeeded();
428  MoveToLine(Loc);
429  OS << "#pragma " << Namespace << " diagnostic push";
430  setEmittedDirectiveOnThisLine();
431 }
432 
433 void PrintPPOutputPPCallbacks::
434 PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
435  startNewLineIfNeeded();
436  MoveToLine(Loc);
437  OS << "#pragma " << Namespace << " diagnostic pop";
438  setEmittedDirectiveOnThisLine();
439 }
440 
441 void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
442  StringRef Namespace,
444  StringRef Str) {
445  startNewLineIfNeeded();
446  MoveToLine(Loc);
447  OS << "#pragma " << Namespace << " diagnostic ";
448  switch (Map) {
450  OS << "remark";
451  break;
453  OS << "warning";
454  break;
456  OS << "error";
457  break;
459  OS << "ignored";
460  break;
462  OS << "fatal";
463  break;
464  }
465  OS << " \"" << Str << '"';
466  setEmittedDirectiveOnThisLine();
467 }
468 
469 void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc,
470  StringRef WarningSpec,
471  ArrayRef<int> Ids) {
472  startNewLineIfNeeded();
473  MoveToLine(Loc);
474  OS << "#pragma warning(" << WarningSpec << ':';
475  for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I)
476  OS << ' ' << *I;
477  OS << ')';
478  setEmittedDirectiveOnThisLine();
479 }
480 
481 void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc,
482  int Level) {
483  startNewLineIfNeeded();
484  MoveToLine(Loc);
485  OS << "#pragma warning(push";
486  if (Level >= 0)
487  OS << ", " << Level;
488  OS << ')';
489  setEmittedDirectiveOnThisLine();
490 }
491 
492 void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
493  startNewLineIfNeeded();
494  MoveToLine(Loc);
495  OS << "#pragma warning(pop)";
496  setEmittedDirectiveOnThisLine();
497 }
498 
499 /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
500 /// is called for the first token on each new line. If this really is the start
501 /// of a new logical line, handle it and return true, otherwise return false.
502 /// This may not be the start of a logical line because the "start of line"
503 /// marker is set for spelling lines, not expansion ones.
504 bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
505  // Figure out what line we went to and insert the appropriate number of
506  // newline characters.
507  if (!MoveToLine(Tok.getLocation()))
508  return false;
509 
510  // Print out space characters so that the first token on a line is
511  // indented for easy reading.
512  unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation());
513 
514  // The first token on a line can have a column number of 1, yet still expect
515  // leading white space, if a macro expansion in column 1 starts with an empty
516  // macro argument, or an empty nested macro expansion. In this case, move the
517  // token to column 2.
518  if (ColNo == 1 && Tok.hasLeadingSpace())
519  ColNo = 2;
520 
521  // This hack prevents stuff like:
522  // #define HASH #
523  // HASH define foo bar
524  // From having the # character end up at column 1, which makes it so it
525  // is not handled as a #define next time through the preprocessor if in
526  // -fpreprocessed mode.
527  if (ColNo <= 1 && Tok.is(tok::hash))
528  OS << ' ';
529 
530  // Otherwise, indent the appropriate number of spaces.
531  for (; ColNo > 1; --ColNo)
532  OS << ' ';
533 
534  return true;
535 }
536 
537 void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
538  unsigned Len) {
539  unsigned NumNewlines = 0;
540  for (; Len; --Len, ++TokStr) {
541  if (*TokStr != '\n' &&
542  *TokStr != '\r')
543  continue;
544 
545  ++NumNewlines;
546 
547  // If we have \n\r or \r\n, skip both and count as one line.
548  if (Len != 1 &&
549  (TokStr[1] == '\n' || TokStr[1] == '\r') &&
550  TokStr[0] != TokStr[1])
551  ++TokStr, --Len;
552  }
553 
554  if (NumNewlines == 0) return;
555 
556  CurLine += NumNewlines;
557 }
558 
559 
560 namespace {
561 struct UnknownPragmaHandler : public PragmaHandler {
562  const char *Prefix;
563  PrintPPOutputPPCallbacks *Callbacks;
564 
565  // Set to true if tokens should be expanded
566  bool ShouldExpandTokens;
567 
568  UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks,
569  bool RequireTokenExpansion)
570  : Prefix(prefix), Callbacks(callbacks),
571  ShouldExpandTokens(RequireTokenExpansion) {}
572  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
573  Token &PragmaTok) override {
574  // Figure out what line we went to and insert the appropriate number of
575  // newline characters.
576  Callbacks->startNewLineIfNeeded();
577  Callbacks->MoveToLine(PragmaTok.getLocation());
578  Callbacks->OS.write(Prefix, strlen(Prefix));
579 
580  Token PrevToken;
581  Token PrevPrevToken;
582  PrevToken.startToken();
583  PrevPrevToken.startToken();
584 
585  // Read and print all of the pragma tokens.
586  while (PragmaTok.isNot(tok::eod)) {
587  if (PragmaTok.hasLeadingSpace() ||
588  Callbacks->AvoidConcat(PrevPrevToken, PrevToken, PragmaTok))
589  Callbacks->OS << ' ';
590  std::string TokSpell = PP.getSpelling(PragmaTok);
591  Callbacks->OS.write(&TokSpell[0], TokSpell.size());
592 
593  PrevPrevToken = PrevToken;
594  PrevToken = PragmaTok;
595 
596  if (ShouldExpandTokens)
597  PP.Lex(PragmaTok);
598  else
599  PP.LexUnexpandedToken(PragmaTok);
600  }
601  Callbacks->setEmittedDirectiveOnThisLine();
602  }
603 };
604 } // end anonymous namespace
605 
606 
608  PrintPPOutputPPCallbacks *Callbacks,
609  raw_ostream &OS) {
610  bool DropComments = PP.getLangOpts().TraditionalCPP &&
612 
613  char Buffer[256];
614  Token PrevPrevTok, PrevTok;
615  PrevPrevTok.startToken();
616  PrevTok.startToken();
617  while (1) {
618  if (Callbacks->hasEmittedDirectiveOnThisLine()) {
619  Callbacks->startNewLineIfNeeded();
620  Callbacks->MoveToLine(Tok.getLocation());
621  }
622 
623  // If this token is at the start of a line, emit newlines if needed.
624  if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
625  // done.
626  } else if (Tok.hasLeadingSpace() ||
627  // If we haven't emitted a token on this line yet, PrevTok isn't
628  // useful to look at and no concatenation could happen anyway.
629  (Callbacks->hasEmittedTokensOnThisLine() &&
630  // Don't print "-" next to "-", it would form "--".
631  Callbacks->AvoidConcat(PrevPrevTok, PrevTok, Tok))) {
632  OS << ' ';
633  }
634 
635  if (DropComments && Tok.is(tok::comment)) {
636  // Skip comments. Normally the preprocessor does not generate
637  // tok::comment nodes at all when not keeping comments, but under
638  // -traditional-cpp the lexer keeps /all/ whitespace, including comments.
639  SourceLocation StartLoc = Tok.getLocation();
640  Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));
641  } else if (Tok.is(tok::annot_module_include) ||
642  Tok.is(tok::annot_module_begin) ||
643  Tok.is(tok::annot_module_end)) {
644  // PrintPPOutputPPCallbacks::InclusionDirective handles producing
645  // appropriate output here. Ignore this token entirely.
646  PP.Lex(Tok);
647  continue;
648  } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
649  OS << II->getName();
650  } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
651  Tok.getLiteralData()) {
652  OS.write(Tok.getLiteralData(), Tok.getLength());
653  } else if (Tok.getLength() < 256) {
654  const char *TokPtr = Buffer;
655  unsigned Len = PP.getSpelling(Tok, TokPtr);
656  OS.write(TokPtr, Len);
657 
658  // Tokens that can contain embedded newlines need to adjust our current
659  // line number.
660  if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
661  Callbacks->HandleNewlinesInToken(TokPtr, Len);
662  } else {
663  std::string S = PP.getSpelling(Tok);
664  OS.write(&S[0], S.size());
665 
666  // Tokens that can contain embedded newlines need to adjust our current
667  // line number.
668  if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
669  Callbacks->HandleNewlinesInToken(&S[0], S.size());
670  }
671  Callbacks->setEmittedTokensOnThisLine();
672 
673  if (Tok.is(tok::eof)) break;
674 
675  PrevPrevTok = PrevTok;
676  PrevTok = Tok;
677  PP.Lex(Tok);
678  }
679 }
680 
681 typedef std::pair<const IdentifierInfo *, MacroInfo *> id_macro_pair;
682 static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS) {
683  return LHS->first->getName().compare(RHS->first->getName());
684 }
685 
686 static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
687  // Ignore unknown pragmas.
688  PP.IgnorePragmas();
689 
690  // -dM mode just scans and ignores all tokens in the files, then dumps out
691  // the macro table at the end.
692  PP.EnterMainSourceFile();
693 
694  Token Tok;
695  do PP.Lex(Tok);
696  while (Tok.isNot(tok::eof));
697 
700  I != E; ++I) {
701  auto *MD = I->second.getLatest();
702  if (MD && MD->isDefined())
703  MacrosByID.push_back(id_macro_pair(I->first, MD->getMacroInfo()));
704  }
705  llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
706 
707  for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
708  MacroInfo &MI = *MacrosByID[i].second;
709  // Ignore computed macros like __LINE__ and friends.
710  if (MI.isBuiltinMacro()) continue;
711 
712  PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
713  *OS << '\n';
714  }
715 }
716 
717 /// DoPrintPreprocessedInput - This implements -E mode.
718 ///
720  const PreprocessorOutputOptions &Opts) {
721  // Show macros with no output is handled specially.
722  if (!Opts.ShowCPP) {
723  assert(Opts.ShowMacros && "Not yet implemented!");
724  DoPrintMacros(PP, OS);
725  return;
726  }
727 
728  // Inform the preprocessor whether we want it to retain comments or not, due
729  // to -C or -CC.
731 
732  PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
733  PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, Opts.UseLineDirectives);
734 
735  // Expand macros in pragmas with -fms-extensions. The assumption is that
736  // the majority of pragmas in such a file will be Microsoft pragmas.
737  PP.AddPragmaHandler(new UnknownPragmaHandler(
738  "#pragma", Callbacks,
739  /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
740  PP.AddPragmaHandler(
741  "GCC", new UnknownPragmaHandler(
742  "#pragma GCC", Callbacks,
743  /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
744  PP.AddPragmaHandler(
745  "clang", new UnknownPragmaHandler(
746  "#pragma clang", Callbacks,
747  /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
748 
749  // The tokens after pragma omp need to be expanded.
750  //
751  // OpenMP [2.1, Directive format]
752  // Preprocessing tokens following the #pragma omp are subject to macro
753  // replacement.
754  PP.AddPragmaHandler("omp",
755  new UnknownPragmaHandler("#pragma omp", Callbacks,
756  /*RequireTokenExpansion=*/true));
757 
758  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
759 
760  // After we have configured the preprocessor, enter the main file.
761  PP.EnterMainSourceFile();
762 
763  // Consume all of the tokens that come from the predefines buffer. Those
764  // should not be emitted into the output and are guaranteed to be at the
765  // start.
766  const SourceManager &SourceMgr = PP.getSourceManager();
767  Token Tok;
768  do {
769  PP.Lex(Tok);
770  if (Tok.is(tok::eof) || !Tok.getLocation().isFileID())
771  break;
772 
773  PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
774  if (PLoc.isInvalid())
775  break;
776 
777  if (strcmp(PLoc.getFilename(), "<built-in>"))
778  break;
779  } while (true);
780 
781  // Read all the preprocessed tokens, printing them out to the stream.
782  PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
783  *OS << '\n';
784 }
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Definition: Token.h:261
SourceManager & getSourceManager() const
Definition: Preprocessor.h:687
static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, Preprocessor &PP, raw_ostream &OS)
PrintMacroDefinition - Print a macro definition in a form that will be properly accepted back as a de...
std::pair< const IdentifierInfo *, MacroInfo * > id_macro_pair
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
Definition: Pragma.cpp:729
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Defines the SourceManager interface.
TokenConcatenation class, which answers the question of "Is it safe to emit two tokens without a whit...
Defines the clang::MacroInfo and clang::MacroDirective classes.
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
Definition: Token.h:265
A description of the current definition of a macro.
Definition: MacroInfo.h:563
std::unique_ptr< llvm::MemoryBuffer > Buffer
macro_iterator macro_begin(bool IncludeExternalMacros=true) const
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
Definition: Token.h:280
MacroMap::const_iterator macro_iterator
Definition: Preprocessor.h:902
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
Definition: Pragma.cpp:1488
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing)...
Definition: DiagnosticIDs.h:62
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Definition: MacroInfo.h:120
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:79
This interface provides a way to observe the actions of the preprocessor as it does its thing...
Definition: PPCallbacks.h:38
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
std::string getFullModuleName() const
Retrieve the full name of this module, including the path from its top-level module.
One of these records is kept for each identifier that is lexed.
bool isFileID() const
const LangOptions & getLangOpts() const
Definition: Preprocessor.h:683
Token - This structure provides full information about a lexed token.
Definition: Token.h:37
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments)
Control whether the preprocessor retains comments in output.
Definition: Preprocessor.h:721
bool tokens_empty() const
Definition: MacroInfo.h:241
Describes a module or submodule.
Definition: Basic/Module.h:47
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
Definition: MacroInfo.h:579
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
static void outputPrintable(llvm::raw_ostream &OS, const std::string &Str)
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
bool getCommentRetentionState() const
Definition: Preprocessor.h:726
tokens_iterator tokens_begin() const
Definition: MacroInfo.h:239
Present this diagnostic as an error.
tok::TokenKind getKind() const
Definition: Token.h:90
unsigned getLine() const
Return the presumed line number of this location.
detail::InMemoryDirectory::const_iterator I
PragmaIntroducerKind
Describes how the pragma was introduced, e.g., with #pragma, _Pragma, or __pragma.
Definition: Pragma.h:32
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
ArrayRef< Token > tokens() const
Definition: MacroInfo.h:242
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
PreprocessorOutputOptions - Options for controlling the C preprocessor output (e.g., -E).
SourceManager & SM
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
DoPrintPreprocessedInput - Implement -E mode.
IdentifierInfo *const * arg_iterator
Arguments - The list of arguments for a function-like macro.
Definition: MacroInfo.h:175
static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS)
StringRef getName() const
Return the actual identifier string.
Represents a character-granular source range.
SourceManager & SourceMgr
Definition: Format.cpp:1352
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc...
Defines the clang::Preprocessor interface.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Definition: Token.h:124
bool isNot(tok::TokenKind K) const
Definition: Token.h:96
unsigned ShowMacros
Print macro definitions.
Record the location of an inclusion directive, such as an #include or #import statement.
Represents an unpacked "presumed" location which can be presented to the user.
arg_iterator arg_end() const
Definition: MacroInfo.h:178
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
Definition: Token.h:215
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Definition: MacroInfo.h:307
Kind
static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS)
const char * getFilename() const
Return the presumed filename of this location.
const char * getName() const
Definition: FileManager.h:84
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
macro_iterator macro_end(bool IncludeExternalMacros=true) const
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:53
void Lex(Token &Result)
Lex the next token for this preprocessor.
unsigned UseLineDirectives
Use #line instead of GCC-style # N.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
Definition: Token.h:95
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
Definition: CharInfo.h:140
Present this diagnostic as a remark.
bool isGNUVarargs() const
Definition: MacroInfo.h:203
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
Definition: Pragma.h:59
const MacroInfo * getMacroInfo() const
Definition: MacroInfo.h:403
detail::InMemoryDirectory::const_iterator E
bool arg_empty() const
Definition: MacroInfo.h:176
unsigned Map[Count]
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
Definition: AddressSpaces.h:45
Defines the Diagnostic-related interfaces.
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
Definition: Token.h:113
bool isFunctionLike() const
Definition: MacroInfo.h:196
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:34
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
Definition: MacroInfo.h:212
Defines the PPCallbacks interface.
unsigned ShowMacroComments
Show comments, even in macros.
Do not present this diagnostic, ignore it.
unsigned ShowLineMarkers
Show #line markers.
unsigned ShowCPP
Print normal preprocessed output.
unsigned getLength() const
Definition: Token.h:127
Present this diagnostic as a fatal error.
arg_iterator arg_begin() const
Definition: MacroInfo.h:177
Present this diagnostic as a warning.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Definition: Preprocessor.h:778
This class handles loading and caching of source files into memory.
void startToken()
Reset all flags to cleared.
Definition: Token.h:169
static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, PrintPPOutputPPCallbacks *Callbacks, raw_ostream &OS)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:96
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:177
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.