PrintPreprocessedOutput.cpp revision 200583
130489Sphk//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===// 230489Sphk// 330489Sphk// The LLVM Compiler Infrastructure 430489Sphk// 530489Sphk// This file is distributed under the University of Illinois Open Source 630489Sphk// License. See LICENSE.TXT for details. 730489Sphk// 830489Sphk//===----------------------------------------------------------------------===// 930489Sphk// 1030489Sphk// This code simply runs the preprocessor on the input file and prints out the 1130489Sphk// result. This is the traditional behavior of the -E option. 1230489Sphk// 1330489Sphk//===----------------------------------------------------------------------===// 1430489Sphk 1530489Sphk#include "clang/Frontend/Utils.h" 1630489Sphk#include "clang/Basic/Diagnostic.h" 1730489Sphk#include "clang/Basic/SourceManager.h" 1830489Sphk#include "clang/Frontend/PreprocessorOutputOptions.h" 1930489Sphk#include "clang/Lex/MacroInfo.h" 2030489Sphk#include "clang/Lex/PPCallbacks.h" 2130489Sphk#include "clang/Lex/Pragma.h" 2230489Sphk#include "clang/Lex/Preprocessor.h" 2330489Sphk#include "clang/Lex/TokenConcatenation.h" 2430489Sphk#include "llvm/ADT/SmallString.h" 2530489Sphk#include "llvm/ADT/StringExtras.h" 2630489Sphk#include "llvm/Config/config.h" 2730489Sphk#include "llvm/Support/raw_ostream.h" 2830489Sphk#include <cstdio> 2930489Sphkusing namespace clang; 3030489Sphk 3130489Sphk/// PrintMacroDefinition - Print a macro definition in a form that will be 3230489Sphk/// properly accepted back as a definition. 3330489Sphkstatic void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, 3430489Sphk Preprocessor &PP, llvm::raw_ostream &OS) { 3530489Sphk OS << "#define " << II.getName(); 3630489Sphk 3730489Sphk if (MI.isFunctionLike()) { 3847989Sgpalmer OS << '('; 3950477Speter if (!MI.arg_empty()) { 4030489Sphk MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end(); 4130489Sphk for (; AI+1 != E; ++AI) { 4230489Sphk OS << (*AI)->getName(); 4330489Sphk OS << ','; 4460041Sphk } 4544272Sbde 4665770Sbp // Last argument. 4730489Sphk if ((*AI)->getName() == "__VA_ARGS__") 4831561Sbde OS << "..."; 4930743Sphk else 5051068Salfred OS << (*AI)->getName(); 5167365Sjhb } 5230492Sphk 5330489Sphk if (MI.isGNUVarargs()) 5430743Sphk OS << "..."; // #define foo(x...) 5530489Sphk 5665770Sbp OS << ')'; 5765770Sbp } 5865770Sbp 5965770Sbp // GCC always emits a space, even if the macro body is empty. However, do not 6065770Sbp // want to emit two spaces if the first token has a leading space. 6165770Sbp if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace()) 6265770Sbp OS << ' '; 6365770Sbp 6465770Sbp llvm::SmallVector<char, 128> SpellingBuffer; 6565770Sbp for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end(); 6665770Sbp I != E; ++I) { 6792723Salfred if (I->hasLeadingSpace()) 6892723Salfred OS << ' '; 69108686Sphk 7030489Sphk // Make sure we have enough space in the spelling buffer. 7130489Sphk if (I->getLength() > SpellingBuffer.size()) 7230489Sphk SpellingBuffer.resize(I->getLength()); 7330489Sphk const char *Buffer = SpellingBuffer.data(); 7430489Sphk unsigned SpellingLen = PP.getSpelling(*I, Buffer); 7530489Sphk OS.write(Buffer, SpellingLen); 7630489Sphk } 7730489Sphk} 7830489Sphk 7930489Sphk//===----------------------------------------------------------------------===// 8030489Sphk// Preprocessed token printer 8130492Sphk//===----------------------------------------------------------------------===// 8230492Sphk 8376131Sphknamespace { 8430492Sphkclass PrintPPOutputPPCallbacks : public PPCallbacks { 8565770Sbp Preprocessor &PP; 8665770Sbp TokenConcatenation ConcatInfo; 8730492Sphkpublic: 8876167Sphk llvm::raw_ostream &OS; 8965770Sbpprivate: 9064819Sphk unsigned CurLine; 9130492Sphk bool EmittedTokensOnThisLine; 92100739Sjeff bool EmittedMacroOnThisLine; 9330739Sphk SrcMgr::CharacteristicKind FileType; 94100739Sjeff llvm::SmallString<512> CurFilename; 9572594Sbde bool Initialized; 9630492Sphk bool DisableLineMarkers; 9730492Sphk bool DumpDefines; 98108680Sphk bool UseLineDirective; 9976167Sphkpublic: 10030492Sphk PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os, 10130489Sphk bool lineMarkers, bool defines) 102108686Sphk : PP(pp), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers), 10330489Sphk DumpDefines(defines) { 104100739Sjeff CurLine = 0; 10530489Sphk CurFilename += "<uninit>"; 10630489Sphk EmittedTokensOnThisLine = false; 10730489Sphk EmittedMacroOnThisLine = false; 10830489Sphk FileType = SrcMgr::C_User; 10930489Sphk Initialized = false; 11030489Sphk 11130489Sphk // If we're in microsoft mode, use normal #line instead of line markers. 11230489Sphk UseLineDirective = PP.getLangOptions().Microsoft; 11391690Seivind } 11491690Seivind 11591690Seivind void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; } 11691690Seivind bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; } 11791690Seivind 11830489Sphk virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, 11930492Sphk SrcMgr::CharacteristicKind FileType); 12030489Sphk virtual void Ident(SourceLocation Loc, const std::string &str); 12130489Sphk virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 12230492Sphk const std::string &Str); 12330489Sphk 12430489Sphk 12530489Sphk bool HandleFirstTokOnLine(Token &Tok); 12630489Sphk bool MoveToLine(SourceLocation Loc); 12730489Sphk bool AvoidConcat(const Token &PrevTok, const Token &Tok) { 12830489Sphk return ConcatInfo.AvoidConcat(PrevTok, Tok); 12930492Sphk } 13030489Sphk void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0); 13130489Sphk 13230492Sphk void HandleNewlinesInToken(const char *TokStr, unsigned Len); 13330492Sphk 13430492Sphk /// MacroDefined - This hook is called whenever a macro definition is seen. 13530492Sphk void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI); 13630492Sphk 13730492Sphk}; 13830492Sphk} // end anonymous namespace 13930492Sphk 14030492Sphkvoid PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo, 14130492Sphk const char *Extra, 14230492Sphk unsigned ExtraLen) { 14330492Sphk if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) { 14430492Sphk OS << '\n'; 14530492Sphk EmittedTokensOnThisLine = false; 14630492Sphk EmittedMacroOnThisLine = false; 14730492Sphk } 14830492Sphk 14930492Sphk // Emit #line directives or GNU line markers depending on what mode we're in. 15030492Sphk if (UseLineDirective) { 15130492Sphk OS << "#line" << ' ' << LineNo << ' ' << '"'; 15230492Sphk OS.write(&CurFilename[0], CurFilename.size()); 15330492Sphk OS << '"'; 15430492Sphk } else { 15530492Sphk OS << '#' << ' ' << LineNo << ' ' << '"'; 15691690Seivind OS.write(&CurFilename[0], CurFilename.size()); 15791690Seivind OS << '"'; 15891690Seivind 15930492Sphk if (ExtraLen) 16030492Sphk OS.write(Extra, ExtraLen); 16130492Sphk 16230492Sphk if (FileType == SrcMgr::C_System) 16330489Sphk OS.write(" 3", 2); 16430489Sphk else if (FileType == SrcMgr::C_ExternCSystem) 16530489Sphk OS.write(" 3 4", 4); 16691690Seivind } 16791690Seivind OS << '\n'; 16891690Seivind} 16941056Speter 17041056Speter/// MoveToLine - Move the output to the source line specified by the location 17141056Speter/// object. We can do this by emitting some number of \n's, or be emitting a 17241056Speter/// #line directive. This returns false if already at the specified line, true 17372594Sbde/// if some newlines were emitted. 17441056Speterbool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) { 17541056Speter unsigned LineNo = PP.getSourceManager().getInstantiationLineNumber(Loc); 17691690Seivind 17791690Seivind if (DisableLineMarkers) { 17891690Seivind if (LineNo == CurLine) return false; 17991690Seivind 18091690Seivind CurLine = LineNo; 18191690Seivind 18291690Seivind if (!EmittedTokensOnThisLine && !EmittedMacroOnThisLine) 18391690Seivind return true; 18491690Seivind 18591690Seivind OS << '\n'; 18691690Seivind EmittedTokensOnThisLine = false; 18791690Seivind EmittedMacroOnThisLine = false; 18872594Sbde return true; 18972594Sbde } 19072594Sbde 19172594Sbde // If this line is "close enough" to the original line, just print newlines, 19272594Sbde // otherwise print a #line directive. 19372594Sbde if (LineNo-CurLine <= 8) { 19472594Sbde if (LineNo-CurLine == 1) 19572594Sbde OS << '\n'; 19672594Sbde else if (LineNo == CurLine) 19772594Sbde return false; // Spelling line moved, but instantiation line didn't. 19872594Sbde else { 19972594Sbde const char *NewLines = "\n\n\n\n\n\n\n\n"; 20072594Sbde OS.write(NewLines, LineNo-CurLine); 20146349Salc } 20246349Salc } else { 20346349Salc WriteLineInfo(LineNo, 0, 0); 20446349Salc } 20546349Salc 20658934Sphk CurLine = LineNo; 20758345Sphk return true; 20858345Sphk} 20958345Sphk 21058934Sphk 21146349Salc/// FileChanged - Whenever the preprocessor enters or exits a #include file 21246349Salc/// it invokes this handler. Update our conception of the current source 21330489Sphk/// position. 21430489Sphkvoid PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, 21530489Sphk FileChangeReason Reason, 21630489Sphk SrcMgr::CharacteristicKind NewFileType) { 217111842Snjl // Unless we are exiting a #include, make sure to skip ahead to the line the 218111842Snjl // #include directive was at. 21958934Sphk SourceManager &SourceMgr = PP.getSourceManager(); 22030489Sphk if (Reason == PPCallbacks::EnterFile) { 22159249Sphk SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc(); 22230489Sphk if (IncludeLoc.isValid()) 22330489Sphk MoveToLine(IncludeLoc); 22430492Sphk } else if (Reason == PPCallbacks::SystemHeaderPragma) { 22591690Seivind MoveToLine(Loc); 226108686Sphk 227108686Sphk // TODO GCC emits the # directive for this directive on the line AFTER the 228108686Sphk // directive and emits a bunch of spaces that aren't needed. Emulate this 229108686Sphk // strange behavior. 230108686Sphk } 231108686Sphk 232108686Sphk Loc = SourceMgr.getInstantiationLoc(Loc); 233108686Sphk // FIXME: Should use presumed line #! 234108686Sphk CurLine = SourceMgr.getInstantiationLineNumber(Loc); 235108686Sphk 236108686Sphk if (DisableLineMarkers) return; 237108686Sphk 238108686Sphk CurFilename.clear(); 239108686Sphk CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename(); 240108686Sphk Lexer::Stringify(CurFilename); 241111842Snjl FileType = NewFileType; 242108686Sphk 243108686Sphk if (!Initialized) { 244108686Sphk WriteLineInfo(CurLine); 245108686Sphk Initialized = true; 246108686Sphk } 247108686Sphk 248108686Sphk switch (Reason) { 24991690Seivind case PPCallbacks::EnterFile: 25091690Seivind WriteLineInfo(CurLine, " 1", 2); 25191690Seivind break; 25291690Seivind case PPCallbacks::ExitFile: 25391690Seivind WriteLineInfo(CurLine, " 2", 2); 25491690Seivind break; 25591690Seivind case PPCallbacks::SystemHeaderPragma: 25630492Sphk case PPCallbacks::RenameFile: 25730492Sphk WriteLineInfo(CurLine); 25830492Sphk break; 25930492Sphk } 26030492Sphk} 26130492Sphk 26230492Sphk/// Ident - Handle #ident directives when read by the preprocessor. 26330492Sphk/// 26430492Sphkvoid PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) { 26530492Sphk MoveToLine(Loc); 26630492Sphk 26730492Sphk OS.write("#ident ", strlen("#ident ")); 26830492Sphk OS.write(&S[0], S.size()); 26930492Sphk EmittedTokensOnThisLine = true; 27030492Sphk} 27130492Sphk 27230492Sphk/// MacroDefined - This hook is called whenever a macro definition is seen. 27330492Sphkvoid PrintPPOutputPPCallbacks::MacroDefined(const IdentifierInfo *II, 27430492Sphk const MacroInfo *MI) { 27530492Sphk // Only print out macro definitions in -dD mode. 27630492Sphk if (!DumpDefines || 27730492Sphk // Ignore __FILE__ etc. 27830492Sphk MI->isBuiltinMacro()) return; 27930492Sphk 28030492Sphk MoveToLine(MI->getDefinitionLoc()); 28130492Sphk PrintMacroDefinition(*II, *MI, PP, OS); 28230492Sphk EmittedMacroOnThisLine = true; 28330492Sphk} 28430492Sphk 28530492Sphk 28630492Sphkvoid PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc, 28730492Sphk const IdentifierInfo *Kind, 28830492Sphk const std::string &Str) { 28930513Sphk MoveToLine(Loc); 29030513Sphk OS << "#pragma comment(" << Kind->getName(); 29130513Sphk 29230513Sphk if (!Str.empty()) { 29330513Sphk OS << ", \""; 29430513Sphk 29530513Sphk for (unsigned i = 0, e = Str.size(); i != e; ++i) { 29630513Sphk unsigned char Char = Str[i]; 29730513Sphk if (isprint(Char) && Char != '\\' && Char != '"') 29883366Sjulian OS << (char)Char; 29930513Sphk else // Output anything hard as an octal escape. 30030513Sphk OS << '\\' 30166355Sbp << (char)('0'+ ((Char >> 6) & 7)) 30230513Sphk << (char)('0'+ ((Char >> 3) & 7)) 30342900Seivind << (char)('0'+ ((Char >> 0) & 7)); 304105077Smckusick } 30542900Seivind OS << '"'; 306105077Smckusick } 30783366Sjulian 30842900Seivind OS << ')'; 30930513Sphk EmittedTokensOnThisLine = true; 31030513Sphk} 31191690Seivind 31230513Sphk 31330513Sphk/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this 31430513Sphk/// is called for the first token on each new line. If this really is the start 31530513Sphk/// of a new logical line, handle it and return true, otherwise return false. 31630513Sphk/// This may not be the start of a logical line because the "start of line" 31783366Sjulian/// marker is set for spelling lines, not instantiation ones. 31830513Sphkbool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) { 31930513Sphk // Figure out what line we went to and insert the appropriate number of 32066355Sbp // newline characters. 32130513Sphk if (!MoveToLine(Tok.getLocation())) 322105077Smckusick return false; 32383366Sjulian 32430513Sphk // Print out space characters so that the first token on a line is 32530513Sphk // indented for easy reading. 32691690Seivind const SourceManager &SourceMgr = PP.getSourceManager(); 32730513Sphk unsigned ColNo = SourceMgr.getInstantiationColumnNumber(Tok.getLocation()); 32830513Sphk 32930513Sphk // This hack prevents stuff like: 33030513Sphk // #define HASH # 33183366Sjulian // HASH define foo bar 33230513Sphk // From having the # character end up at column 1, which makes it so it 33330513Sphk // is not handled as a #define next time through the preprocessor if in 33430513Sphk // -fpreprocessed mode. 335105077Smckusick if (ColNo <= 1 && Tok.is(tok::hash)) 33630513Sphk OS << ' '; 33730513Sphk 33891690Seivind // Otherwise, indent the appropriate number of spaces. 33964819Sphk for (; ColNo > 1; --ColNo) 34064819Sphk OS << ' '; 34164819Sphk 34264819Sphk return true; 34383366Sjulian} 34464819Sphk 34564819Sphkvoid PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr, 34664819Sphk unsigned Len) { 34783366Sjulian unsigned NumNewlines = 0; 34864819Sphk for (; Len; --Len, ++TokStr) { 34964819Sphk if (*TokStr != '\n' && 35064819Sphk *TokStr != '\r') 35130743Sphk continue; 35230743Sphk 35330743Sphk ++NumNewlines; 35430743Sphk 35530743Sphk // If we have \n\r or \r\n, skip both and count as one line. 35630743Sphk if (Len != 1 && 35730743Sphk (TokStr[1] == '\n' || TokStr[1] == '\r') && 35830743Sphk TokStr[0] != TokStr[1]) 35930743Sphk ++TokStr, --Len; 36083366Sjulian } 36130743Sphk 36230743Sphk if (NumNewlines == 0) return; 36330743Sphk 36431727Swollman CurLine += NumNewlines; 36531727Swollman} 36631727Swollman 36731727Swollman 36831727Swollmannamespace { 36930743Sphkstruct UnknownPragmaHandler : public PragmaHandler { 37031727Swollman const char *Prefix; 37131727Swollman PrintPPOutputPPCallbacks *Callbacks; 37231727Swollman 37330743Sphk UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks) 37430743Sphk : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {} 37530743Sphk virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) { 37631727Swollman // Figure out what line we went to and insert the appropriate number of 37731727Swollman // newline characters. 37831727Swollman Callbacks->MoveToLine(PragmaTok.getLocation()); 37930743Sphk Callbacks->OS.write(Prefix, strlen(Prefix)); 38031727Swollman 38131727Swollman // Read and print all of the pragma tokens. 38231727Swollman while (PragmaTok.isNot(tok::eom)) { 38331727Swollman if (PragmaTok.hasLeadingSpace()) 38431727Swollman Callbacks->OS << ' '; 38583366Sjulian std::string TokSpell = PP.getSpelling(PragmaTok); 38631727Swollman Callbacks->OS.write(&TokSpell[0], TokSpell.size()); 38731727Swollman PP.LexUnexpandedToken(PragmaTok); 38876578Sjlemon } 38983366Sjulian Callbacks->OS << '\n'; 39076578Sjlemon } 39131727Swollman}; 39231727Swollman} // end anonymous namespace 39330743Sphk 39430743Sphk 39530743Sphkstatic void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, 39630743Sphk PrintPPOutputPPCallbacks *Callbacks, 39730743Sphk llvm::raw_ostream &OS) { 39830743Sphk char Buffer[256]; 39930743Sphk Token PrevTok; 40030743Sphk while (1) { 40130743Sphk 40230743Sphk // If this token is at the start of a line, emit newlines if needed. 40330743Sphk if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) { 40483366Sjulian // done. 40530743Sphk } else if (Tok.hasLeadingSpace() || 40630743Sphk // If we haven't emitted a token on this line yet, PrevTok isn't 40730743Sphk // useful to look at and no concatenation could happen anyway. 40830743Sphk (Callbacks->hasEmittedTokensOnThisLine() && 40930743Sphk // Don't print "-" next to "-", it would form "--". 41030743Sphk Callbacks->AvoidConcat(PrevTok, Tok))) { 41130743Sphk OS << ' '; 41230743Sphk } 41330743Sphk 41430743Sphk if (IdentifierInfo *II = Tok.getIdentifierInfo()) { 41530743Sphk OS << II->getName(); 41630743Sphk } else if (Tok.isLiteral() && !Tok.needsCleaning() && 41730743Sphk Tok.getLiteralData()) { 41830743Sphk OS.write(Tok.getLiteralData(), Tok.getLength()); 41930743Sphk } else if (Tok.getLength() < 256) { 42030743Sphk const char *TokPtr = Buffer; 42130743Sphk unsigned Len = PP.getSpelling(Tok, TokPtr); 42230743Sphk OS.write(TokPtr, Len); 42330743Sphk 42430743Sphk // Tokens that can contain embedded newlines need to adjust our current 42530743Sphk // line number. 42630743Sphk if (Tok.getKind() == tok::comment) 42730743Sphk Callbacks->HandleNewlinesInToken(TokPtr, Len); 42830743Sphk } else { 42930743Sphk std::string S = PP.getSpelling(Tok); 43030743Sphk OS.write(&S[0], S.size()); 43130743Sphk 43230743Sphk // Tokens that can contain embedded newlines need to adjust our current 43330743Sphk // line number. 43430743Sphk if (Tok.getKind() == tok::comment) 43530743Sphk Callbacks->HandleNewlinesInToken(&S[0], S.size()); 43630743Sphk } 43730743Sphk Callbacks->SetEmittedTokensOnThisLine(); 43830743Sphk 43930743Sphk if (Tok.is(tok::eof)) break; 44030743Sphk 44130743Sphk PrevTok = Tok; 44230743Sphk PP.Lex(Tok); 44330743Sphk } 44430743Sphk} 44530743Sphk 44630743Sphknamespace { 44730743Sphk struct SortMacrosByID { 44830743Sphk typedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair; 44930743Sphk bool operator()(const id_macro_pair &LHS, const id_macro_pair &RHS) const { 45042900Seivind return LHS.first->getName() < RHS.first->getName(); 451105077Smckusick } 45242900Seivind }; 453105077Smckusick} 45442900Seivind 45542900Seivindstatic void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) { 45630743Sphk // -dM mode just scans and ignores all tokens in the files, then dumps out 45730743Sphk // the macro table at the end. 45830743Sphk PP.EnterMainSourceFile(); 45930743Sphk 46030743Sphk Token Tok; 46130743Sphk do PP.Lex(Tok); 46230743Sphk while (Tok.isNot(tok::eof)); 46330743Sphk 46430743Sphk std::vector<std::pair<IdentifierInfo*, MacroInfo*> > MacrosByID; 46530743Sphk for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); 46630743Sphk I != E; ++I) 46730743Sphk MacrosByID.push_back(*I); 46830743Sphk std::sort(MacrosByID.begin(), MacrosByID.end(), SortMacrosByID()); 46983366Sjulian 47030743Sphk for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) { 47130743Sphk MacroInfo &MI = *MacrosByID[i].second; 47230743Sphk // Ignore computed macros like __LINE__ and friends. 47330743Sphk if (MI.isBuiltinMacro()) continue; 47430743Sphk 47530743Sphk PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS); 47630743Sphk *OS << "\n"; 47730743Sphk } 47830743Sphk} 47930743Sphk 48030743Sphk/// DoPrintPreprocessedInput - This implements -E mode. 48130743Sphk/// 48230743Sphkvoid clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS, 48330743Sphk const PreprocessorOutputOptions &Opts) { 48430743Sphk // Show macros with no output is handled specially. 48530743Sphk if (!Opts.ShowCPP) { 48630743Sphk assert(Opts.ShowMacros && "Not yet implemented!"); 48730743Sphk DoPrintMacros(PP, OS); 48830743Sphk return; 48930743Sphk } 49030743Sphk 49130743Sphk // Inform the preprocessor whether we want it to retain comments or not, due 49230743Sphk // to -C or -CC. 49330743Sphk PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments); 49430743Sphk 49530743Sphk OS->SetBufferSize(64*1024); 49630743Sphk 49730743Sphk PrintPPOutputPPCallbacks *Callbacks = 49830743Sphk new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers, 49930743Sphk Opts.ShowMacros); 50030743Sphk PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks)); 50130743Sphk PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC", 50230743Sphk Callbacks)); 50330743Sphk 50430743Sphk PP.setPPCallbacks(Callbacks); 50530743Sphk 50630743Sphk // After we have configured the preprocessor, enter the main file. 50730743Sphk PP.EnterMainSourceFile(); 508105077Smckusick 50930743Sphk // Consume all of the tokens that come from the predefines buffer. Those 51030743Sphk // should not be emitted into the output and are guaranteed to be at the 51130743Sphk // start. 51230743Sphk const SourceManager &SourceMgr = PP.getSourceManager(); 51330743Sphk Token Tok; 51431263Sbde do PP.Lex(Tok); 515103927Sjeff while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() && 51630743Sphk !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(), 51730743Sphk "<built-in>")); 51830743Sphk 51930743Sphk // Read all the preprocessed tokens, printing them out to the stream. 52030743Sphk PrintPreprocessedTokens(PP, Tok, Callbacks, *OS); 52130743Sphk *OS << '\n'; 52230743Sphk} 52330743Sphk 52430743Sphk