PrintPreprocessedOutput.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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. #include "clang/Frontend/Utils.h"
  15. #include "clang/Basic/Diagnostic.h"
  16. #include "clang/Basic/SourceManager.h"
  17. #include "clang/Frontend/PreprocessorOutputOptions.h"
  18. #include "clang/Lex/MacroInfo.h"
  19. #include "clang/Lex/PPCallbacks.h"
  20. #include "clang/Lex/Pragma.h"
  21. #include "clang/Lex/Preprocessor.h"
  22. #include "clang/Lex/TokenConcatenation.h"
  23. #include "llvm/ADT/SmallString.h"
  24. #include "llvm/ADT/STLExtras.h"
  25. #include "llvm/ADT/StringRef.h"
  26. #include "llvm/Support/raw_ostream.h"
  27. #include "llvm/Support/ErrorHandling.h"
  28. #include <cctype>
  29. #include <cstdio>
  30. using namespace clang;
  31. /// PrintMacroDefinition - Print a macro definition in a form that will be
  32. /// properly accepted back as a definition.
  33. static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
  34. Preprocessor &PP, raw_ostream &OS) {
  35. OS << "#define " << II.getName();
  36. if (MI.isFunctionLike()) {
  37. OS << '(';
  38. if (!MI.arg_empty()) {
  39. MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
  40. for (; AI+1 != E; ++AI) {
  41. OS << (*AI)->getName();
  42. OS << ',';
  43. }
  44. // Last argument.
  45. if ((*AI)->getName() == "__VA_ARGS__")
  46. OS << "...";
  47. else
  48. OS << (*AI)->getName();
  49. }
  50. if (MI.isGNUVarargs())
  51. OS << "..."; // #define foo(x...)
  52. OS << ')';
  53. }
  54. // GCC always emits a space, even if the macro body is empty. However, do not
  55. // want to emit two spaces if the first token has a leading space.
  56. if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
  57. OS << ' ';
  58. SmallString<128> SpellingBuffer;
  59. for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end();
  60. I != E; ++I) {
  61. if (I->hasLeadingSpace())
  62. OS << ' ';
  63. OS << PP.getSpelling(*I, SpellingBuffer);
  64. }
  65. }
  66. //===----------------------------------------------------------------------===//
  67. // Preprocessed token printer
  68. //===----------------------------------------------------------------------===//
  69. namespace {
  70. class PrintPPOutputPPCallbacks : public PPCallbacks {
  71. Preprocessor &PP;
  72. SourceManager &SM;
  73. TokenConcatenation ConcatInfo;
  74. public:
  75. raw_ostream &OS;
  76. private:
  77. unsigned CurLine;
  78. bool EmittedTokensOnThisLine;
  79. bool EmittedDirectiveOnThisLine;
  80. SrcMgr::CharacteristicKind FileType;
  81. SmallString<512> CurFilename;
  82. bool Initialized;
  83. bool DisableLineMarkers;
  84. bool DumpDefines;
  85. bool UseLineDirective;
  86. public:
  87. PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os,
  88. bool lineMarkers, bool defines)
  89. : PP(pp), SM(PP.getSourceManager()),
  90. ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
  91. DumpDefines(defines) {
  92. CurLine = 0;
  93. CurFilename += "<uninit>";
  94. EmittedTokensOnThisLine = false;
  95. EmittedDirectiveOnThisLine = false;
  96. FileType = SrcMgr::C_User;
  97. Initialized = false;
  98. // If we're in microsoft mode, use normal #line instead of line markers.
  99. UseLineDirective = PP.getLangOpts().MicrosoftExt;
  100. }
  101. void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
  102. bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
  103. void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; }
  104. bool hasEmittedDirectiveOnThisLine() const {
  105. return EmittedDirectiveOnThisLine;
  106. }
  107. bool startNewLineIfNeeded(bool ShouldUpdateCurrentLine = true);
  108. virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
  109. SrcMgr::CharacteristicKind FileType,
  110. FileID PrevFID);
  111. virtual void Ident(SourceLocation Loc, const std::string &str);
  112. virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
  113. const std::string &Str);
  114. virtual void PragmaMessage(SourceLocation Loc, StringRef Str);
  115. virtual void PragmaDiagnosticPush(SourceLocation Loc,
  116. StringRef Namespace);
  117. virtual void PragmaDiagnosticPop(SourceLocation Loc,
  118. StringRef Namespace);
  119. virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
  120. diag::Mapping Map, StringRef Str);
  121. bool HandleFirstTokOnLine(Token &Tok);
  122. bool MoveToLine(SourceLocation Loc) {
  123. PresumedLoc PLoc = SM.getPresumedLoc(Loc);
  124. if (PLoc.isInvalid())
  125. return false;
  126. return MoveToLine(PLoc.getLine());
  127. }
  128. bool MoveToLine(unsigned LineNo);
  129. bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
  130. const Token &Tok) {
  131. return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
  132. }
  133. void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
  134. bool LineMarkersAreDisabled() const { return DisableLineMarkers; }
  135. void HandleNewlinesInToken(const char *TokStr, unsigned Len);
  136. /// MacroDefined - This hook is called whenever a macro definition is seen.
  137. void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI);
  138. /// MacroUndefined - This hook is called whenever a macro #undef is seen.
  139. void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI);
  140. };
  141. } // end anonymous namespace
  142. void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
  143. const char *Extra,
  144. unsigned ExtraLen) {
  145. startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
  146. // Emit #line directives or GNU line markers depending on what mode we're in.
  147. if (UseLineDirective) {
  148. OS << "#line" << ' ' << LineNo << ' ' << '"';
  149. OS.write(CurFilename.data(), CurFilename.size());
  150. OS << '"';
  151. } else {
  152. OS << '#' << ' ' << LineNo << ' ' << '"';
  153. OS.write(CurFilename.data(), CurFilename.size());
  154. OS << '"';
  155. if (ExtraLen)
  156. OS.write(Extra, ExtraLen);
  157. if (FileType == SrcMgr::C_System)
  158. OS.write(" 3", 2);
  159. else if (FileType == SrcMgr::C_ExternCSystem)
  160. OS.write(" 3 4", 4);
  161. }
  162. OS << '\n';
  163. }
  164. /// MoveToLine - Move the output to the source line specified by the location
  165. /// object. We can do this by emitting some number of \n's, or be emitting a
  166. /// #line directive. This returns false if already at the specified line, true
  167. /// if some newlines were emitted.
  168. bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) {
  169. // If this line is "close enough" to the original line, just print newlines,
  170. // otherwise print a #line directive.
  171. if (LineNo-CurLine <= 8) {
  172. if (LineNo-CurLine == 1)
  173. OS << '\n';
  174. else if (LineNo == CurLine)
  175. return false; // Spelling line moved, but expansion line didn't.
  176. else {
  177. const char *NewLines = "\n\n\n\n\n\n\n\n";
  178. OS.write(NewLines, LineNo-CurLine);
  179. }
  180. } else if (!DisableLineMarkers) {
  181. // Emit a #line or line marker.
  182. WriteLineInfo(LineNo, 0, 0);
  183. } else {
  184. // Okay, we're in -P mode, which turns off line markers. However, we still
  185. // need to emit a newline between tokens on different lines.
  186. startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
  187. }
  188. CurLine = LineNo;
  189. return true;
  190. }
  191. bool
  192. PrintPPOutputPPCallbacks::startNewLineIfNeeded(bool ShouldUpdateCurrentLine) {
  193. if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
  194. OS << '\n';
  195. EmittedTokensOnThisLine = false;
  196. EmittedDirectiveOnThisLine = false;
  197. if (ShouldUpdateCurrentLine)
  198. ++CurLine;
  199. return true;
  200. }
  201. return false;
  202. }
  203. /// FileChanged - Whenever the preprocessor enters or exits a #include file
  204. /// it invokes this handler. Update our conception of the current source
  205. /// position.
  206. void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
  207. FileChangeReason Reason,
  208. SrcMgr::CharacteristicKind NewFileType,
  209. FileID PrevFID) {
  210. // Unless we are exiting a #include, make sure to skip ahead to the line the
  211. // #include directive was at.
  212. SourceManager &SourceMgr = SM;
  213. PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
  214. if (UserLoc.isInvalid())
  215. return;
  216. unsigned NewLine = UserLoc.getLine();
  217. if (Reason == PPCallbacks::EnterFile) {
  218. SourceLocation IncludeLoc = UserLoc.getIncludeLoc();
  219. if (IncludeLoc.isValid())
  220. MoveToLine(IncludeLoc);
  221. } else if (Reason == PPCallbacks::SystemHeaderPragma) {
  222. MoveToLine(NewLine);
  223. // TODO GCC emits the # directive for this directive on the line AFTER the
  224. // directive and emits a bunch of spaces that aren't needed. Emulate this
  225. // strange behavior.
  226. }
  227. CurLine = NewLine;
  228. CurFilename.clear();
  229. CurFilename += UserLoc.getFilename();
  230. Lexer::Stringify(CurFilename);
  231. FileType = NewFileType;
  232. if (DisableLineMarkers) return;
  233. if (!Initialized) {
  234. WriteLineInfo(CurLine);
  235. Initialized = true;
  236. }
  237. switch (Reason) {
  238. case PPCallbacks::EnterFile:
  239. WriteLineInfo(CurLine, " 1", 2);
  240. break;
  241. case PPCallbacks::ExitFile:
  242. WriteLineInfo(CurLine, " 2", 2);
  243. break;
  244. case PPCallbacks::SystemHeaderPragma:
  245. case PPCallbacks::RenameFile:
  246. WriteLineInfo(CurLine);
  247. break;
  248. }
  249. }
  250. /// Ident - Handle #ident directives when read by the preprocessor.
  251. ///
  252. void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
  253. MoveToLine(Loc);
  254. OS.write("#ident ", strlen("#ident "));
  255. OS.write(&S[0], S.size());
  256. EmittedTokensOnThisLine = true;
  257. }
  258. /// MacroDefined - This hook is called whenever a macro definition is seen.
  259. void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
  260. const MacroInfo *MI) {
  261. // Only print out macro definitions in -dD mode.
  262. if (!DumpDefines ||
  263. // Ignore __FILE__ etc.
  264. MI->isBuiltinMacro()) return;
  265. MoveToLine(MI->getDefinitionLoc());
  266. PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS);
  267. setEmittedDirectiveOnThisLine();
  268. }
  269. void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
  270. const MacroInfo *MI) {
  271. // Only print out macro definitions in -dD mode.
  272. if (!DumpDefines) return;
  273. MoveToLine(MacroNameTok.getLocation());
  274. OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName();
  275. setEmittedDirectiveOnThisLine();
  276. }
  277. void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
  278. const IdentifierInfo *Kind,
  279. const std::string &Str) {
  280. startNewLineIfNeeded();
  281. MoveToLine(Loc);
  282. OS << "#pragma comment(" << Kind->getName();
  283. if (!Str.empty()) {
  284. OS << ", \"";
  285. for (unsigned i = 0, e = Str.size(); i != e; ++i) {
  286. unsigned char Char = Str[i];
  287. if (isprint(Char) && Char != '\\' && Char != '"')
  288. OS << (char)Char;
  289. else // Output anything hard as an octal escape.
  290. OS << '\\'
  291. << (char)('0'+ ((Char >> 6) & 7))
  292. << (char)('0'+ ((Char >> 3) & 7))
  293. << (char)('0'+ ((Char >> 0) & 7));
  294. }
  295. OS << '"';
  296. }
  297. OS << ')';
  298. setEmittedDirectiveOnThisLine();
  299. }
  300. void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
  301. StringRef Str) {
  302. startNewLineIfNeeded();
  303. MoveToLine(Loc);
  304. OS << "#pragma message(";
  305. OS << '"';
  306. for (unsigned i = 0, e = Str.size(); i != e; ++i) {
  307. unsigned char Char = Str[i];
  308. if (isprint(Char) && Char != '\\' && Char != '"')
  309. OS << (char)Char;
  310. else // Output anything hard as an octal escape.
  311. OS << '\\'
  312. << (char)('0'+ ((Char >> 6) & 7))
  313. << (char)('0'+ ((Char >> 3) & 7))
  314. << (char)('0'+ ((Char >> 0) & 7));
  315. }
  316. OS << '"';
  317. OS << ')';
  318. setEmittedDirectiveOnThisLine();
  319. }
  320. void PrintPPOutputPPCallbacks::
  321. PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
  322. startNewLineIfNeeded();
  323. MoveToLine(Loc);
  324. OS << "#pragma " << Namespace << " diagnostic push";
  325. setEmittedDirectiveOnThisLine();
  326. }
  327. void PrintPPOutputPPCallbacks::
  328. PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
  329. startNewLineIfNeeded();
  330. MoveToLine(Loc);
  331. OS << "#pragma " << Namespace << " diagnostic pop";
  332. setEmittedDirectiveOnThisLine();
  333. }
  334. void PrintPPOutputPPCallbacks::
  335. PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
  336. diag::Mapping Map, StringRef Str) {
  337. startNewLineIfNeeded();
  338. MoveToLine(Loc);
  339. OS << "#pragma " << Namespace << " diagnostic ";
  340. switch (Map) {
  341. case diag::MAP_WARNING:
  342. OS << "warning";
  343. break;
  344. case diag::MAP_ERROR:
  345. OS << "error";
  346. break;
  347. case diag::MAP_IGNORE:
  348. OS << "ignored";
  349. break;
  350. case diag::MAP_FATAL:
  351. OS << "fatal";
  352. break;
  353. }
  354. OS << " \"" << Str << '"';
  355. setEmittedDirectiveOnThisLine();
  356. }
  357. /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
  358. /// is called for the first token on each new line. If this really is the start
  359. /// of a new logical line, handle it and return true, otherwise return false.
  360. /// This may not be the start of a logical line because the "start of line"
  361. /// marker is set for spelling lines, not expansion ones.
  362. bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
  363. // Figure out what line we went to and insert the appropriate number of
  364. // newline characters.
  365. if (!MoveToLine(Tok.getLocation()))
  366. return false;
  367. // Print out space characters so that the first token on a line is
  368. // indented for easy reading.
  369. unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation());
  370. // This hack prevents stuff like:
  371. // #define HASH #
  372. // HASH define foo bar
  373. // From having the # character end up at column 1, which makes it so it
  374. // is not handled as a #define next time through the preprocessor if in
  375. // -fpreprocessed mode.
  376. if (ColNo <= 1 && Tok.is(tok::hash))
  377. OS << ' ';
  378. // Otherwise, indent the appropriate number of spaces.
  379. for (; ColNo > 1; --ColNo)
  380. OS << ' ';
  381. return true;
  382. }
  383. void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
  384. unsigned Len) {
  385. unsigned NumNewlines = 0;
  386. for (; Len; --Len, ++TokStr) {
  387. if (*TokStr != '\n' &&
  388. *TokStr != '\r')
  389. continue;
  390. ++NumNewlines;
  391. // If we have \n\r or \r\n, skip both and count as one line.
  392. if (Len != 1 &&
  393. (TokStr[1] == '\n' || TokStr[1] == '\r') &&
  394. TokStr[0] != TokStr[1])
  395. ++TokStr, --Len;
  396. }
  397. if (NumNewlines == 0) return;
  398. CurLine += NumNewlines;
  399. }
  400. namespace {
  401. struct UnknownPragmaHandler : public PragmaHandler {
  402. const char *Prefix;
  403. PrintPPOutputPPCallbacks *Callbacks;
  404. UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
  405. : Prefix(prefix), Callbacks(callbacks) {}
  406. virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
  407. Token &PragmaTok) {
  408. // Figure out what line we went to and insert the appropriate number of
  409. // newline characters.
  410. Callbacks->startNewLineIfNeeded();
  411. Callbacks->MoveToLine(PragmaTok.getLocation());
  412. Callbacks->OS.write(Prefix, strlen(Prefix));
  413. // Read and print all of the pragma tokens.
  414. while (PragmaTok.isNot(tok::eod)) {
  415. if (PragmaTok.hasLeadingSpace())
  416. Callbacks->OS << ' ';
  417. std::string TokSpell = PP.getSpelling(PragmaTok);
  418. Callbacks->OS.write(&TokSpell[0], TokSpell.size());
  419. PP.LexUnexpandedToken(PragmaTok);
  420. }
  421. Callbacks->setEmittedDirectiveOnThisLine();
  422. }
  423. };
  424. } // end anonymous namespace
  425. static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
  426. PrintPPOutputPPCallbacks *Callbacks,
  427. raw_ostream &OS) {
  428. char Buffer[256];
  429. Token PrevPrevTok, PrevTok;
  430. PrevPrevTok.startToken();
  431. PrevTok.startToken();
  432. while (1) {
  433. if (Callbacks->hasEmittedDirectiveOnThisLine()) {
  434. Callbacks->startNewLineIfNeeded();
  435. Callbacks->MoveToLine(Tok.getLocation());
  436. }
  437. // If this token is at the start of a line, emit newlines if needed.
  438. if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
  439. // done.
  440. } else if (Tok.hasLeadingSpace() ||
  441. // If we haven't emitted a token on this line yet, PrevTok isn't
  442. // useful to look at and no concatenation could happen anyway.
  443. (Callbacks->hasEmittedTokensOnThisLine() &&
  444. // Don't print "-" next to "-", it would form "--".
  445. Callbacks->AvoidConcat(PrevPrevTok, PrevTok, Tok))) {
  446. OS << ' ';
  447. }
  448. if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
  449. OS << II->getName();
  450. } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
  451. Tok.getLiteralData()) {
  452. OS.write(Tok.getLiteralData(), Tok.getLength());
  453. } else if (Tok.getLength() < 256) {
  454. const char *TokPtr = Buffer;
  455. unsigned Len = PP.getSpelling(Tok, TokPtr);
  456. OS.write(TokPtr, Len);
  457. // Tokens that can contain embedded newlines need to adjust our current
  458. // line number.
  459. if (Tok.getKind() == tok::comment)
  460. Callbacks->HandleNewlinesInToken(TokPtr, Len);
  461. } else {
  462. std::string S = PP.getSpelling(Tok);
  463. OS.write(&S[0], S.size());
  464. // Tokens that can contain embedded newlines need to adjust our current
  465. // line number.
  466. if (Tok.getKind() == tok::comment)
  467. Callbacks->HandleNewlinesInToken(&S[0], S.size());
  468. }
  469. Callbacks->setEmittedTokensOnThisLine();
  470. if (Tok.is(tok::eof)) break;
  471. PrevPrevTok = PrevTok;
  472. PrevTok = Tok;
  473. PP.Lex(Tok);
  474. }
  475. }
  476. typedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair;
  477. static int MacroIDCompare(const void* a, const void* b) {
  478. const id_macro_pair *LHS = static_cast<const id_macro_pair*>(a);
  479. const id_macro_pair *RHS = static_cast<const id_macro_pair*>(b);
  480. return LHS->first->getName().compare(RHS->first->getName());
  481. }
  482. static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
  483. // Ignore unknown pragmas.
  484. PP.AddPragmaHandler(new EmptyPragmaHandler());
  485. // -dM mode just scans and ignores all tokens in the files, then dumps out
  486. // the macro table at the end.
  487. PP.EnterMainSourceFile();
  488. Token Tok;
  489. do PP.Lex(Tok);
  490. while (Tok.isNot(tok::eof));
  491. SmallVector<id_macro_pair, 128>
  492. MacrosByID(PP.macro_begin(), PP.macro_end());
  493. llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
  494. for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
  495. MacroInfo &MI = *MacrosByID[i].second;
  496. // Ignore computed macros like __LINE__ and friends.
  497. if (MI.isBuiltinMacro()) continue;
  498. PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
  499. *OS << '\n';
  500. }
  501. }
  502. /// DoPrintPreprocessedInput - This implements -E mode.
  503. ///
  504. void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
  505. const PreprocessorOutputOptions &Opts) {
  506. // Show macros with no output is handled specially.
  507. if (!Opts.ShowCPP) {
  508. assert(Opts.ShowMacros && "Not yet implemented!");
  509. DoPrintMacros(PP, OS);
  510. return;
  511. }
  512. // Inform the preprocessor whether we want it to retain comments or not, due
  513. // to -C or -CC.
  514. PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
  515. PrintPPOutputPPCallbacks *Callbacks =
  516. new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
  517. Opts.ShowMacros);
  518. PP.AddPragmaHandler(new UnknownPragmaHandler("#pragma", Callbacks));
  519. PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",Callbacks));
  520. PP.AddPragmaHandler("clang",
  521. new UnknownPragmaHandler("#pragma clang", Callbacks));
  522. PP.addPPCallbacks(Callbacks);
  523. // After we have configured the preprocessor, enter the main file.
  524. PP.EnterMainSourceFile();
  525. // Consume all of the tokens that come from the predefines buffer. Those
  526. // should not be emitted into the output and are guaranteed to be at the
  527. // start.
  528. const SourceManager &SourceMgr = PP.getSourceManager();
  529. Token Tok;
  530. do {
  531. PP.Lex(Tok);
  532. if (Tok.is(tok::eof) || !Tok.getLocation().isFileID())
  533. break;
  534. PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
  535. if (PLoc.isInvalid())
  536. break;
  537. if (strcmp(PLoc.getFilename(), "<built-in>"))
  538. break;
  539. } while (true);
  540. // Read all the preprocessed tokens, printing them out to the stream.
  541. PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
  542. *OS << '\n';
  543. }