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