PrintPreprocessedOutput.cpp 22 KB

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