PrintPreprocessedOutput.cpp revision 353358
1139749Simp//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===// 2119853Scg// 370291Scg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 470291Scg// See https://llvm.org/LICENSE.txt for license information. 570291Scg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 670291Scg// 770291Scg//===----------------------------------------------------------------------===// 870291Scg// 970291Scg// This code simply runs the preprocessor on the input file and prints out the 1070291Scg// result. This is the traditional behavior of the -E option. 1170291Scg// 1270291Scg//===----------------------------------------------------------------------===// 1370291Scg 1470291Scg#include "clang/Frontend/Utils.h" 1570291Scg#include "clang/Basic/CharInfo.h" 1670291Scg#include "clang/Basic/Diagnostic.h" 1770291Scg#include "clang/Basic/SourceManager.h" 1870291Scg#include "clang/Frontend/PreprocessorOutputOptions.h" 1970291Scg#include "clang/Lex/MacroInfo.h" 2070291Scg#include "clang/Lex/PPCallbacks.h" 2170291Scg#include "clang/Lex/Pragma.h" 2270291Scg#include "clang/Lex/Preprocessor.h" 2370291Scg#include "clang/Lex/TokenConcatenation.h" 2470291Scg#include "llvm/ADT/STLExtras.h" 2570291Scg#include "llvm/ADT/SmallString.h" 2670291Scg#include "llvm/ADT/StringRef.h" 2770291Scg#include "llvm/Support/ErrorHandling.h" 2870291Scg#include "llvm/Support/raw_ostream.h" 2974763Scg#include <cstdio> 3074763Scgusing namespace clang; 3182180Scg 3282180Scg/// PrintMacroDefinition - Print a macro definition in a form that will be 3374763Scg/// properly accepted back as a definition. 34125136Struckmanstatic void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, 3574763Scg Preprocessor &PP, raw_ostream &OS) { 3674763Scg OS << "#define " << II.getName(); 3774763Scg 38111119Simp if (MI.isFunctionLike()) { 3974763Scg OS << '('; 4089834Scg if (!MI.param_empty()) { 41125136Struckman MacroInfo::param_iterator AI = MI.param_begin(), E = MI.param_end(); 4289834Scg for (; AI+1 != E; ++AI) { 4374763Scg OS << (*AI)->getName(); 4474763Scg OS << ','; 4574763Scg } 4674763Scg 4774763Scg // Last argument. 4874763Scg if ((*AI)->getName() == "__VA_ARGS__") 4974763Scg OS << "..."; 5074763Scg else 5174763Scg OS << (*AI)->getName(); 52111183Scognet } 53111183Scognet 54111183Scognet if (MI.isGNUVarargs()) 55111183Scognet OS << "..."; // #define foo(x...) 56111183Scognet 57111183Scognet OS << ')'; 5870291Scg } 5970291Scg 6070291Scg // GCC always emits a space, even if the macro body is empty. However, do not 6174763Scg // want to emit two spaces if the first token has a leading space. 6270291Scg if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace()) 6370291Scg OS << ' '; 64136531Syongari 65136531Syongari SmallString<128> SpellingBuffer; 66136531Syongari for (const auto &T : MI.tokens()) { 6770291Scg if (T.hasLeadingSpace()) 68136531Syongari OS << ' '; 69136531Syongari 70136531Syongari OS << PP.getSpelling(T, SpellingBuffer); 71136531Syongari } 7270291Scg} 7370291Scg 7470291Scg//===----------------------------------------------------------------------===// 7574763Scg// Preprocessed token printer 7674763Scg//===----------------------------------------------------------------------===// 7770291Scg 78111183Scognetnamespace { 7970291Scgclass PrintPPOutputPPCallbacks : public PPCallbacks { 8074763Scg Preprocessor &PP; 8170291Scg SourceManager &SM; 82136531Syongari TokenConcatenation ConcatInfo; 83136531Syongaripublic: 8470291Scg raw_ostream &OS; 8570291Scgprivate: 8670291Scg unsigned CurLine; 87136531Syongari 88136531Syongari bool EmittedTokensOnThisLine; 89136531Syongari bool EmittedDirectiveOnThisLine; 90136531Syongari SrcMgr::CharacteristicKind FileType; 91136531Syongari SmallString<512> CurFilename; 92136531Syongari bool Initialized; 93136531Syongari bool DisableLineMarkers; 94136531Syongari bool DumpDefines; 95136531Syongari bool DumpIncludeDirectives; 96136531Syongari bool UseLineDirectives; 97136531Syongari bool IsFirstFileEntered; 98136531Syongaripublic: 99136531Syongari PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, bool lineMarkers, 100136531Syongari bool defines, bool DumpIncludeDirectives, 101136531Syongari bool UseLineDirectives) 10270291Scg : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os), 10370291Scg DisableLineMarkers(lineMarkers), DumpDefines(defines), 10470291Scg DumpIncludeDirectives(DumpIncludeDirectives), 10574763Scg UseLineDirectives(UseLineDirectives) { 10670291Scg CurLine = 0; 10770291Scg CurFilename += "<uninit>"; 10870291Scg EmittedTokensOnThisLine = false; 10970291Scg EmittedDirectiveOnThisLine = false; 11070291Scg FileType = SrcMgr::C_User; 11170291Scg Initialized = false; 11270291Scg IsFirstFileEntered = false; 11370291Scg } 11474763Scg 11570291Scg void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; } 11674763Scg bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; } 11774763Scg 11874763Scg void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; } 11974763Scg bool hasEmittedDirectiveOnThisLine() const { 12074763Scg return EmittedDirectiveOnThisLine; 12174797Scg } 12274763Scg 12374763Scg bool startNewLineIfNeeded(bool ShouldUpdateCurrentLine = true); 12474797Scg 12577265Scg void FileChanged(SourceLocation Loc, FileChangeReason Reason, 12677265Scg SrcMgr::CharacteristicKind FileType, 12770291Scg FileID PrevFID) override; 12870291Scg void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 12970291Scg StringRef FileName, bool IsAngled, 13074763Scg CharSourceRange FilenameRange, const FileEntry *File, 13170291Scg StringRef SearchPath, StringRef RelativePath, 132125136Struckman const Module *Imported, 133125136Struckman SrcMgr::CharacteristicKind FileType) override; 134125136Struckman void Ident(SourceLocation Loc, StringRef str) override; 13574763Scg void PragmaMessage(SourceLocation Loc, StringRef Namespace, 136125136Struckman PragmaMessageKind Kind, StringRef Str) override; 13770291Scg void PragmaDebug(SourceLocation Loc, StringRef DebugType) override; 13870291Scg void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override; 13970291Scg void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override; 14070291Scg void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, 141125136Struckman diag::Severity Map, StringRef Str) override; 142125136Struckman void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, 14370291Scg ArrayRef<int> Ids) override; 144125136Struckman void PragmaWarningPush(SourceLocation Loc, int Level) override; 14589834Scg void PragmaWarningPop(SourceLocation Loc) override; 146125136Struckman void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override; 147125136Struckman void PragmaExecCharsetPop(SourceLocation Loc) override; 148125136Struckman void PragmaAssumeNonNullBegin(SourceLocation Loc) override; 149128730Sgreen void PragmaAssumeNonNullEnd(SourceLocation Loc) override; 150125136Struckman 151125136Struckman bool HandleFirstTokOnLine(Token &Tok); 152125136Struckman 15370291Scg /// Move to the line of the provided source location. This will 15470291Scg /// return true if the output stream required adjustment or if 15570291Scg /// the requested location is on the first line. 156125136Struckman bool MoveToLine(SourceLocation Loc) { 157113752Sorion PresumedLoc PLoc = SM.getPresumedLoc(Loc); 15870291Scg if (PLoc.isInvalid()) 159125136Struckman return false; 160125136Struckman return MoveToLine(PLoc.getLine()) || (PLoc.getLine() == 1); 16170291Scg } 162125136Struckman bool MoveToLine(unsigned LineNo); 163125136Struckman 164125136Struckman bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok, 16570291Scg const Token &Tok) { 16670291Scg return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok); 16774763Scg } 16874763Scg void WriteLineInfo(unsigned LineNo, const char *Extra=nullptr, 16974763Scg unsigned ExtraLen=0); 170107237Scg bool LineMarkersAreDisabled() const { return DisableLineMarkers; } 171107237Scg void HandleNewlinesInToken(const char *TokStr, unsigned Len); 172125136Struckman 173107237Scg /// MacroDefined - This hook is called whenever a macro definition is seen. 17474763Scg void MacroDefined(const Token &MacroNameTok, 17574763Scg const MacroDirective *MD) override; 17674763Scg 177107237Scg /// MacroUndefined - This hook is called whenever a macro #undef is seen. 17874763Scg void MacroUndefined(const Token &MacroNameTok, 179125136Struckman const MacroDefinition &MD, 180125136Struckman const MacroDirective *Undef) override; 181125136Struckman 182125136Struckman void BeginModule(const Module *M); 183125136Struckman void EndModule(const Module *M); 184125136Struckman}; 18574763Scg} // end anonymous namespace 186125136Struckman 187107237Scgvoid PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo, 188107237Scg const char *Extra, 189125136Struckman unsigned ExtraLen) { 190125136Struckman startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false); 191107237Scg 192125136Struckman // Emit #line directives or GNU line markers depending on what mode we're in. 19374763Scg if (UseLineDirectives) { 194107237Scg OS << "#line" << ' ' << LineNo << ' ' << '"'; 195107237Scg OS.write_escaped(CurFilename); 196107237Scg OS << '"'; 197107237Scg } else { 198107237Scg OS << '#' << ' ' << LineNo << ' ' << '"'; 199107237Scg OS.write_escaped(CurFilename); 200107237Scg OS << '"'; 201107237Scg 202107237Scg if (ExtraLen) 203125136Struckman OS.write(Extra, ExtraLen); 204125136Struckman 205125136Struckman if (FileType == SrcMgr::C_System) 206107237Scg OS.write(" 3", 2); 207107237Scg else if (FileType == SrcMgr::C_ExternCSystem) 208107237Scg OS.write(" 3 4", 4); 209107237Scg } 210107237Scg OS << '\n'; 211125136Struckman} 212125136Struckman 213125136Struckman/// MoveToLine - Move the output to the source line specified by the location 214125136Struckman/// object. We can do this by emitting some number of \n's, or be emitting a 21574763Scg/// #line directive. This returns false if already at the specified line, true 21674763Scg/// if some newlines were emitted. 21770291Scgbool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) { 21874763Scg // If this line is "close enough" to the original line, just print newlines, 21970291Scg // otherwise print a #line directive. 22070291Scg if (LineNo-CurLine <= 8) { 22173768Scg if (LineNo-CurLine == 1) 22270291Scg OS << '\n'; 22370291Scg else if (LineNo == CurLine) 22470291Scg return false; // Spelling line moved, but expansion line didn't. 22573768Scg else { 22673768Scg const char *NewLines = "\n\n\n\n\n\n\n\n"; 22770291Scg OS.write(NewLines, LineNo-CurLine); 22870291Scg } 22970291Scg } else if (!DisableLineMarkers) { 23070291Scg // Emit a #line or line marker. 23170291Scg WriteLineInfo(LineNo, nullptr, 0); 23270291Scg } else { 23374763Scg // Okay, we're in -P mode, which turns off line markers. However, we still 23474763Scg // need to emit a newline between tokens on different lines. 23573768Scg startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false); 23673768Scg } 23773768Scg 23873768Scg CurLine = LineNo; 23973768Scg return true; 24070291Scg} 24170291Scg 24270291Scgbool 24370291ScgPrintPPOutputPPCallbacks::startNewLineIfNeeded(bool ShouldUpdateCurrentLine) { 24470291Scg if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) { 24577265Scg OS << '\n'; 24677265Scg EmittedTokensOnThisLine = false; 24777265Scg EmittedDirectiveOnThisLine = false; 24877265Scg if (ShouldUpdateCurrentLine) 24977265Scg ++CurLine; 25077265Scg return true; 25177265Scg } 25277265Scg 25377265Scg return false; 25477265Scg} 25577265Scg 25677265Scg/// FileChanged - Whenever the preprocessor enters or exits a #include file 25777265Scg/// it invokes this handler. Update our conception of the current source 25877265Scg/// position. 25977265Scgvoid PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, 26077265Scg FileChangeReason Reason, 26177265Scg SrcMgr::CharacteristicKind NewFileType, 26277265Scg FileID PrevFID) { 26377265Scg // Unless we are exiting a #include, make sure to skip ahead to the line the 26474763Scg // #include directive was at. 26570291Scg SourceManager &SourceMgr = SM; 26674763Scg 26774763Scg PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc); 26874763Scg if (UserLoc.isInvalid()) 26974763Scg return; 27074763Scg 27174763Scg unsigned NewLine = UserLoc.getLine(); 27274763Scg 27370291Scg if (Reason == PPCallbacks::EnterFile) { 27470291Scg SourceLocation IncludeLoc = UserLoc.getIncludeLoc(); 27570291Scg if (IncludeLoc.isValid()) 27670291Scg MoveToLine(IncludeLoc); 27774763Scg } else if (Reason == PPCallbacks::SystemHeaderPragma) { 27874763Scg // GCC emits the # directive for this directive on the line AFTER the 27974763Scg // directive and emits a bunch of spaces that aren't needed. This is because 28074763Scg // otherwise we will emit a line marker for THIS line, which requires an 28174763Scg // extra blank line after the directive to avoid making all following lines 28274763Scg // off by one. We can do better by simply incrementing NewLine here. 28370291Scg NewLine += 1; 28474763Scg } 28570291Scg 28670291Scg CurLine = NewLine; 28770291Scg 28870291Scg CurFilename.clear(); 289148606Snetchild CurFilename += UserLoc.getFilename(); 290148606Snetchild FileType = NewFileType; 291148606Snetchild 292148606Snetchild if (DisableLineMarkers) { 293148606Snetchild startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false); 294148606Snetchild return; 29570291Scg } 29670291Scg 29770291Scg if (!Initialized) { 29874763Scg WriteLineInfo(CurLine); 29974763Scg Initialized = true; 30070291Scg } 30174763Scg 30274763Scg // Do not emit an enter marker for the main file (which we expect is the first 30374763Scg // entered file). This matches gcc, and improves compatibility with some tools 30474763Scg // which track the # line markers as a way to determine when the preprocessed 30574763Scg // output is in the context of the main file. 30674763Scg if (Reason == PPCallbacks::EnterFile && !IsFirstFileEntered) { 30774763Scg IsFirstFileEntered = true; 30874763Scg return; 30974763Scg } 31074763Scg 31174763Scg switch (Reason) { 31274763Scg case PPCallbacks::EnterFile: 31374763Scg WriteLineInfo(CurLine, " 1", 2); 31474763Scg break; 31574763Scg case PPCallbacks::ExitFile: 31674763Scg WriteLineInfo(CurLine, " 2", 2); 31774763Scg break; 31874763Scg case PPCallbacks::SystemHeaderPragma: 31974763Scg case PPCallbacks::RenameFile: 32074763Scg WriteLineInfo(CurLine); 32174763Scg break; 32274763Scg } 32374763Scg} 32474763Scg 32574763Scgvoid PrintPPOutputPPCallbacks::InclusionDirective( 32674763Scg SourceLocation HashLoc, 32774763Scg const Token &IncludeTok, 32874763Scg StringRef FileName, 32974763Scg bool IsAngled, 33074763Scg CharSourceRange FilenameRange, 33174763Scg const FileEntry *File, 33274763Scg StringRef SearchPath, 33374763Scg StringRef RelativePath, 33474763Scg const Module *Imported, 33574763Scg SrcMgr::CharacteristicKind FileType) { 33674763Scg // In -dI mode, dump #include directives prior to dumping their content or 33774763Scg // interpretation. 33874763Scg if (DumpIncludeDirectives) { 33974763Scg startNewLineIfNeeded(); 34074763Scg MoveToLine(HashLoc); 34174763Scg const std::string TokenText = PP.getSpelling(IncludeTok); 34274763Scg assert(!TokenText.empty()); 34374763Scg OS << "#" << TokenText << " " 34474763Scg << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"') 34570291Scg << " /* clang -E -dI */"; 34670291Scg setEmittedDirectiveOnThisLine(); 34770291Scg startNewLineIfNeeded(); 34870291Scg } 34974763Scg 35070291Scg // When preprocessing, turn implicit imports into module import pragmas. 35170291Scg if (Imported) { 35270291Scg switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) { 35370291Scg case tok::pp_include: 35474763Scg case tok::pp_import: 35574763Scg case tok::pp_include_next: 35670291Scg startNewLineIfNeeded(); 35789771Scg MoveToLine(HashLoc); 35874763Scg OS << "#pragma clang module import " << Imported->getFullModuleName(true) 35974763Scg << " /* clang -E: implicit import for " 36074763Scg << "#" << PP.getSpelling(IncludeTok) << " " 36174763Scg << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"') 36274763Scg << " */"; 36374763Scg // Since we want a newline after the pragma, but not a #<line>, start a 36474763Scg // new line immediately. 36570291Scg EmittedTokensOnThisLine = true; 36670291Scg startNewLineIfNeeded(); 36770291Scg break; 36874763Scg 36974763Scg case tok::pp___include_macros: 37070291Scg // #__include_macros has no effect on a user of a preprocessed source 37174763Scg // file; the only effect is on preprocessing. 37274763Scg // 37374763Scg // FIXME: That's not *quite* true: it causes the module in question to 37474763Scg // be loaded, which can affect downstream diagnostics. 37574763Scg break; 37674763Scg 37770291Scg default: 37870291Scg llvm_unreachable("unknown include directive kind"); 37970291Scg break; 38074763Scg } 38174763Scg } 38274763Scg} 38374763Scg 38474763Scg/// Handle entering the scope of a module during a module compilation. 38574763Scgvoid PrintPPOutputPPCallbacks::BeginModule(const Module *M) { 38674763Scg startNewLineIfNeeded(); 38774763Scg OS << "#pragma clang module begin " << M->getFullModuleName(true); 38874763Scg setEmittedDirectiveOnThisLine(); 38974763Scg} 39074763Scg 39174763Scg/// Handle leaving the scope of a module during a module compilation. 39274763Scgvoid PrintPPOutputPPCallbacks::EndModule(const Module *M) { 39374763Scg startNewLineIfNeeded(); 39474763Scg OS << "#pragma clang module end /*" << M->getFullModuleName(true) << "*/"; 39574763Scg setEmittedDirectiveOnThisLine(); 39674763Scg} 39774763Scg 39874763Scg/// Ident - Handle #ident directives when read by the preprocessor. 39974763Scg/// 40074763Scgvoid PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) { 40174763Scg MoveToLine(Loc); 402160439Snetchild 40374763Scg OS.write("#ident ", strlen("#ident ")); 40474763Scg OS.write(S.begin(), S.size()); 40574763Scg EmittedTokensOnThisLine = true; 406160439Snetchild} 40774763Scg 40874763Scg/// MacroDefined - This hook is called whenever a macro definition is seen. 40974763Scgvoid PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok, 41074763Scg const MacroDirective *MD) { 41174763Scg const MacroInfo *MI = MD->getMacroInfo(); 41274763Scg // Only print out macro definitions in -dD mode. 41374763Scg if (!DumpDefines || 41474763Scg // Ignore __FILE__ etc. 41574763Scg MI->isBuiltinMacro()) return; 41674763Scg 41774763Scg MoveToLine(MI->getDefinitionLoc()); 41874763Scg PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS); 41974763Scg setEmittedDirectiveOnThisLine(); 42074763Scg} 42174763Scg 42274763Scgvoid PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok, 42374763Scg const MacroDefinition &MD, 42474763Scg const MacroDirective *Undef) { 42574763Scg // Only print out macro definitions in -dD mode. 42674763Scg if (!DumpDefines) return; 42774763Scg 42874763Scg MoveToLine(MacroNameTok.getLocation()); 42987599Sobrien OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName(); 43074763Scg setEmittedDirectiveOnThisLine(); 43174763Scg} 43274763Scg 43374763Scgstatic void outputPrintable(raw_ostream &OS, StringRef Str) { 43474763Scg for (unsigned char Char : Str) { 43574763Scg if (isPrintable(Char) && Char != '\\' && Char != '"') 43674763Scg OS << (char)Char; 43774763Scg else // Output anything hard as an octal escape. 43887599Sobrien OS << '\\' 43974763Scg << (char)('0' + ((Char >> 6) & 7)) 44074763Scg << (char)('0' + ((Char >> 3) & 7)) 44174763Scg << (char)('0' + ((Char >> 0) & 7)); 44274763Scg } 44374763Scg} 44474763Scg 44574763Scgvoid PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc, 44674763Scg StringRef Namespace, 44787599Sobrien PragmaMessageKind Kind, 44874763Scg StringRef Str) { 44974763Scg startNewLineIfNeeded(); 45074763Scg MoveToLine(Loc); 45174763Scg OS << "#pragma "; 45274763Scg if (!Namespace.empty()) 45374763Scg OS << Namespace << ' '; 45474763Scg switch (Kind) { 45574763Scg case PMK_Message: 45687599Sobrien OS << "message(\""; 45787599Sobrien break; 45874763Scg case PMK_Warning: 45974763Scg OS << "warning \""; 46074763Scg break; 46174763Scg case PMK_Error: 46274763Scg OS << "error \""; 46374763Scg break; 46474763Scg } 46574763Scg 46674763Scg outputPrintable(OS, Str); 46774763Scg OS << '"'; 46874763Scg if (Kind == PMK_Message) 46974763Scg OS << ')'; 47074763Scg setEmittedDirectiveOnThisLine(); 47174763Scg} 47274763Scg 47374763Scgvoid PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc, 47474763Scg StringRef DebugType) { 47574763Scg startNewLineIfNeeded(); 47674763Scg MoveToLine(Loc); 47774763Scg 47874763Scg OS << "#pragma clang __debug "; 47974763Scg OS << DebugType; 48074763Scg 48174763Scg setEmittedDirectiveOnThisLine(); 48274763Scg} 48374763Scg 48474763Scgvoid PrintPPOutputPPCallbacks:: 48574763ScgPragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) { 48674763Scg startNewLineIfNeeded(); 48774763Scg MoveToLine(Loc); 48874763Scg OS << "#pragma " << Namespace << " diagnostic push"; 48974763Scg setEmittedDirectiveOnThisLine(); 49074763Scg} 49174763Scg 49274763Scgvoid PrintPPOutputPPCallbacks:: 49374763ScgPragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) { 49474763Scg startNewLineIfNeeded(); 49574763Scg MoveToLine(Loc); 49670291Scg OS << "#pragma " << Namespace << " diagnostic pop"; 49774763Scg setEmittedDirectiveOnThisLine(); 49870291Scg} 49974763Scg 50074763Scgvoid PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc, 50187599Sobrien StringRef Namespace, 50287599Sobrien diag::Severity Map, 50374763Scg StringRef Str) { 50474763Scg startNewLineIfNeeded(); 50574763Scg MoveToLine(Loc); 50674763Scg OS << "#pragma " << Namespace << " diagnostic "; 50774763Scg switch (Map) { 50874763Scg case diag::Severity::Remark: 50974763Scg OS << "remark"; 51074763Scg break; 51174763Scg case diag::Severity::Warning: 51274763Scg OS << "warning"; 51374763Scg break; 51487599Sobrien case diag::Severity::Error: 51574763Scg OS << "error"; 51674763Scg break; 51774763Scg case diag::Severity::Ignored: 51874763Scg OS << "ignored"; 51974763Scg break; 52074763Scg case diag::Severity::Fatal: 52174763Scg OS << "fatal"; 52274763Scg break; 52374763Scg } 52487599Sobrien OS << " \"" << Str << '"'; 52587599Sobrien setEmittedDirectiveOnThisLine(); 52674763Scg} 52774763Scg 52874763Scgvoid PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc, 52974763Scg StringRef WarningSpec, 53074763Scg ArrayRef<int> Ids) { 53174763Scg startNewLineIfNeeded(); 53274763Scg MoveToLine(Loc); 53374763Scg OS << "#pragma warning(" << WarningSpec << ':'; 53474763Scg for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I) 53574763Scg OS << ' ' << *I; 53674763Scg OS << ')'; 53774763Scg setEmittedDirectiveOnThisLine(); 53874763Scg} 53987599Sobrien 54074763Scgvoid PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc, 54174763Scg int Level) { 54274763Scg startNewLineIfNeeded(); 54374763Scg MoveToLine(Loc); 54474763Scg OS << "#pragma warning(push"; 54574763Scg if (Level >= 0) 54674763Scg OS << ", " << Level; 54774763Scg OS << ')'; 54877265Scg setEmittedDirectiveOnThisLine(); 54977265Scg} 55074763Scg 55174763Scgvoid PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) { 55274763Scg startNewLineIfNeeded(); 55374763Scg MoveToLine(Loc); 55475317Scg OS << "#pragma warning(pop)"; 55575317Scg setEmittedDirectiveOnThisLine(); 55674763Scg} 55774763Scg 55874763Scgvoid PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc, 55974763Scg StringRef Str) { 56074763Scg startNewLineIfNeeded(); 56174763Scg MoveToLine(Loc); 56274763Scg OS << "#pragma character_execution_set(push"; 56374763Scg if (!Str.empty()) 56474763Scg OS << ", " << Str; 56574763Scg OS << ')'; 56674763Scg setEmittedDirectiveOnThisLine(); 56774763Scg} 56874763Scg 56974763Scgvoid PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) { 57074763Scg startNewLineIfNeeded(); 57174763Scg MoveToLine(Loc); 57274763Scg OS << "#pragma character_execution_set(pop)"; 57374763Scg setEmittedDirectiveOnThisLine(); 57474763Scg} 57574763Scg 57674763Scgvoid PrintPPOutputPPCallbacks:: 57774763ScgPragmaAssumeNonNullBegin(SourceLocation Loc) { 57874763Scg startNewLineIfNeeded(); 57974763Scg MoveToLine(Loc); 58074763Scg OS << "#pragma clang assume_nonnull begin"; 58174763Scg setEmittedDirectiveOnThisLine(); 58274763Scg} 58374763Scg 58474763Scgvoid PrintPPOutputPPCallbacks:: 58574763ScgPragmaAssumeNonNullEnd(SourceLocation Loc) { 58674763Scg startNewLineIfNeeded(); 58774763Scg MoveToLine(Loc); 58874763Scg OS << "#pragma clang assume_nonnull end"; 58974763Scg setEmittedDirectiveOnThisLine(); 59074763Scg} 59174763Scg 59274763Scg/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this 59374763Scg/// is called for the first token on each new line. If this really is the start 59474763Scg/// of a new logical line, handle it and return true, otherwise return false. 595/// This may not be the start of a logical line because the "start of line" 596/// marker is set for spelling lines, not expansion ones. 597bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) { 598 // Figure out what line we went to and insert the appropriate number of 599 // newline characters. 600 if (!MoveToLine(Tok.getLocation())) 601 return false; 602 603 // Print out space characters so that the first token on a line is 604 // indented for easy reading. 605 unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation()); 606 607 // The first token on a line can have a column number of 1, yet still expect 608 // leading white space, if a macro expansion in column 1 starts with an empty 609 // macro argument, or an empty nested macro expansion. In this case, move the 610 // token to column 2. 611 if (ColNo == 1 && Tok.hasLeadingSpace()) 612 ColNo = 2; 613 614 // This hack prevents stuff like: 615 // #define HASH # 616 // HASH define foo bar 617 // From having the # character end up at column 1, which makes it so it 618 // is not handled as a #define next time through the preprocessor if in 619 // -fpreprocessed mode. 620 if (ColNo <= 1 && Tok.is(tok::hash)) 621 OS << ' '; 622 623 // Otherwise, indent the appropriate number of spaces. 624 for (; ColNo > 1; --ColNo) 625 OS << ' '; 626 627 return true; 628} 629 630void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr, 631 unsigned Len) { 632 unsigned NumNewlines = 0; 633 for (; Len; --Len, ++TokStr) { 634 if (*TokStr != '\n' && 635 *TokStr != '\r') 636 continue; 637 638 ++NumNewlines; 639 640 // If we have \n\r or \r\n, skip both and count as one line. 641 if (Len != 1 && 642 (TokStr[1] == '\n' || TokStr[1] == '\r') && 643 TokStr[0] != TokStr[1]) { 644 ++TokStr; 645 --Len; 646 } 647 } 648 649 if (NumNewlines == 0) return; 650 651 CurLine += NumNewlines; 652} 653 654 655namespace { 656struct UnknownPragmaHandler : public PragmaHandler { 657 const char *Prefix; 658 PrintPPOutputPPCallbacks *Callbacks; 659 660 // Set to true if tokens should be expanded 661 bool ShouldExpandTokens; 662 663 UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks, 664 bool RequireTokenExpansion) 665 : Prefix(prefix), Callbacks(callbacks), 666 ShouldExpandTokens(RequireTokenExpansion) {} 667 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, 668 Token &PragmaTok) override { 669 // Figure out what line we went to and insert the appropriate number of 670 // newline characters. 671 Callbacks->startNewLineIfNeeded(); 672 Callbacks->MoveToLine(PragmaTok.getLocation()); 673 Callbacks->OS.write(Prefix, strlen(Prefix)); 674 675 if (ShouldExpandTokens) { 676 // The first token does not have expanded macros. Expand them, if 677 // required. 678 auto Toks = llvm::make_unique<Token[]>(1); 679 Toks[0] = PragmaTok; 680 PP.EnterTokenStream(std::move(Toks), /*NumToks=*/1, 681 /*DisableMacroExpansion=*/false, 682 /*IsReinject=*/false); 683 PP.Lex(PragmaTok); 684 } 685 Token PrevToken; 686 Token PrevPrevToken; 687 PrevToken.startToken(); 688 PrevPrevToken.startToken(); 689 690 // Read and print all of the pragma tokens. 691 while (PragmaTok.isNot(tok::eod)) { 692 if (PragmaTok.hasLeadingSpace() || 693 Callbacks->AvoidConcat(PrevPrevToken, PrevToken, PragmaTok)) 694 Callbacks->OS << ' '; 695 std::string TokSpell = PP.getSpelling(PragmaTok); 696 Callbacks->OS.write(&TokSpell[0], TokSpell.size()); 697 698 PrevPrevToken = PrevToken; 699 PrevToken = PragmaTok; 700 701 if (ShouldExpandTokens) 702 PP.Lex(PragmaTok); 703 else 704 PP.LexUnexpandedToken(PragmaTok); 705 } 706 Callbacks->setEmittedDirectiveOnThisLine(); 707 } 708}; 709} // end anonymous namespace 710 711 712static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, 713 PrintPPOutputPPCallbacks *Callbacks, 714 raw_ostream &OS) { 715 bool DropComments = PP.getLangOpts().TraditionalCPP && 716 !PP.getCommentRetentionState(); 717 718 char Buffer[256]; 719 Token PrevPrevTok, PrevTok; 720 PrevPrevTok.startToken(); 721 PrevTok.startToken(); 722 while (1) { 723 if (Callbacks->hasEmittedDirectiveOnThisLine()) { 724 Callbacks->startNewLineIfNeeded(); 725 Callbacks->MoveToLine(Tok.getLocation()); 726 } 727 728 // If this token is at the start of a line, emit newlines if needed. 729 if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) { 730 // done. 731 } else if (Tok.hasLeadingSpace() || 732 // If we haven't emitted a token on this line yet, PrevTok isn't 733 // useful to look at and no concatenation could happen anyway. 734 (Callbacks->hasEmittedTokensOnThisLine() && 735 // Don't print "-" next to "-", it would form "--". 736 Callbacks->AvoidConcat(PrevPrevTok, PrevTok, Tok))) { 737 OS << ' '; 738 } 739 740 if (DropComments && Tok.is(tok::comment)) { 741 // Skip comments. Normally the preprocessor does not generate 742 // tok::comment nodes at all when not keeping comments, but under 743 // -traditional-cpp the lexer keeps /all/ whitespace, including comments. 744 SourceLocation StartLoc = Tok.getLocation(); 745 Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength())); 746 } else if (Tok.is(tok::eod)) { 747 // Don't print end of directive tokens, since they are typically newlines 748 // that mess up our line tracking. These come from unknown pre-processor 749 // directives or hash-prefixed comments in standalone assembly files. 750 PP.Lex(Tok); 751 continue; 752 } else if (Tok.is(tok::annot_module_include)) { 753 // PrintPPOutputPPCallbacks::InclusionDirective handles producing 754 // appropriate output here. Ignore this token entirely. 755 PP.Lex(Tok); 756 continue; 757 } else if (Tok.is(tok::annot_module_begin)) { 758 // FIXME: We retrieve this token after the FileChanged callback, and 759 // retrieve the module_end token before the FileChanged callback, so 760 // we render this within the file and render the module end outside the 761 // file, but this is backwards from the token locations: the module_begin 762 // token is at the include location (outside the file) and the module_end 763 // token is at the EOF location (within the file). 764 Callbacks->BeginModule( 765 reinterpret_cast<Module *>(Tok.getAnnotationValue())); 766 PP.Lex(Tok); 767 continue; 768 } else if (Tok.is(tok::annot_module_end)) { 769 Callbacks->EndModule( 770 reinterpret_cast<Module *>(Tok.getAnnotationValue())); 771 PP.Lex(Tok); 772 continue; 773 } else if (Tok.is(tok::annot_header_unit)) { 774 // This is a header-name that has been (effectively) converted into a 775 // module-name. 776 // FIXME: The module name could contain non-identifier module name 777 // components. We don't have a good way to round-trip those. 778 Module *M = reinterpret_cast<Module *>(Tok.getAnnotationValue()); 779 std::string Name = M->getFullModuleName(); 780 OS.write(Name.data(), Name.size()); 781 Callbacks->HandleNewlinesInToken(Name.data(), Name.size()); 782 } else if (Tok.isAnnotation()) { 783 // Ignore annotation tokens created by pragmas - the pragmas themselves 784 // will be reproduced in the preprocessed output. 785 PP.Lex(Tok); 786 continue; 787 } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) { 788 OS << II->getName(); 789 } else if (Tok.isLiteral() && !Tok.needsCleaning() && 790 Tok.getLiteralData()) { 791 OS.write(Tok.getLiteralData(), Tok.getLength()); 792 } else if (Tok.getLength() < llvm::array_lengthof(Buffer)) { 793 const char *TokPtr = Buffer; 794 unsigned Len = PP.getSpelling(Tok, TokPtr); 795 OS.write(TokPtr, Len); 796 797 // Tokens that can contain embedded newlines need to adjust our current 798 // line number. 799 if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown) 800 Callbacks->HandleNewlinesInToken(TokPtr, Len); 801 } else { 802 std::string S = PP.getSpelling(Tok); 803 OS.write(S.data(), S.size()); 804 805 // Tokens that can contain embedded newlines need to adjust our current 806 // line number. 807 if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown) 808 Callbacks->HandleNewlinesInToken(S.data(), S.size()); 809 } 810 Callbacks->setEmittedTokensOnThisLine(); 811 812 if (Tok.is(tok::eof)) break; 813 814 PrevPrevTok = PrevTok; 815 PrevTok = Tok; 816 PP.Lex(Tok); 817 } 818} 819 820typedef std::pair<const IdentifierInfo *, MacroInfo *> id_macro_pair; 821static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS) { 822 return LHS->first->getName().compare(RHS->first->getName()); 823} 824 825static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) { 826 // Ignore unknown pragmas. 827 PP.IgnorePragmas(); 828 829 // -dM mode just scans and ignores all tokens in the files, then dumps out 830 // the macro table at the end. 831 PP.EnterMainSourceFile(); 832 833 Token Tok; 834 do PP.Lex(Tok); 835 while (Tok.isNot(tok::eof)); 836 837 SmallVector<id_macro_pair, 128> MacrosByID; 838 for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); 839 I != E; ++I) { 840 auto *MD = I->second.getLatest(); 841 if (MD && MD->isDefined()) 842 MacrosByID.push_back(id_macro_pair(I->first, MD->getMacroInfo())); 843 } 844 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare); 845 846 for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) { 847 MacroInfo &MI = *MacrosByID[i].second; 848 // Ignore computed macros like __LINE__ and friends. 849 if (MI.isBuiltinMacro()) continue; 850 851 PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS); 852 *OS << '\n'; 853 } 854} 855 856/// DoPrintPreprocessedInput - This implements -E mode. 857/// 858void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, 859 const PreprocessorOutputOptions &Opts) { 860 // Show macros with no output is handled specially. 861 if (!Opts.ShowCPP) { 862 assert(Opts.ShowMacros && "Not yet implemented!"); 863 DoPrintMacros(PP, OS); 864 return; 865 } 866 867 // Inform the preprocessor whether we want it to retain comments or not, due 868 // to -C or -CC. 869 PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments); 870 871 PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks( 872 PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, 873 Opts.ShowIncludeDirectives, Opts.UseLineDirectives); 874 875 // Expand macros in pragmas with -fms-extensions. The assumption is that 876 // the majority of pragmas in such a file will be Microsoft pragmas. 877 // Remember the handlers we will add so that we can remove them later. 878 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler( 879 new UnknownPragmaHandler( 880 "#pragma", Callbacks, 881 /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); 882 883 std::unique_ptr<UnknownPragmaHandler> GCCHandler(new UnknownPragmaHandler( 884 "#pragma GCC", Callbacks, 885 /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); 886 887 std::unique_ptr<UnknownPragmaHandler> ClangHandler(new UnknownPragmaHandler( 888 "#pragma clang", Callbacks, 889 /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); 890 891 PP.AddPragmaHandler(MicrosoftExtHandler.get()); 892 PP.AddPragmaHandler("GCC", GCCHandler.get()); 893 PP.AddPragmaHandler("clang", ClangHandler.get()); 894 895 // The tokens after pragma omp need to be expanded. 896 // 897 // OpenMP [2.1, Directive format] 898 // Preprocessing tokens following the #pragma omp are subject to macro 899 // replacement. 900 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler( 901 new UnknownPragmaHandler("#pragma omp", Callbacks, 902 /*RequireTokenExpansion=*/true)); 903 PP.AddPragmaHandler("omp", OpenMPHandler.get()); 904 905 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks)); 906 907 // After we have configured the preprocessor, enter the main file. 908 PP.EnterMainSourceFile(); 909 910 // Consume all of the tokens that come from the predefines buffer. Those 911 // should not be emitted into the output and are guaranteed to be at the 912 // start. 913 const SourceManager &SourceMgr = PP.getSourceManager(); 914 Token Tok; 915 do { 916 PP.Lex(Tok); 917 if (Tok.is(tok::eof) || !Tok.getLocation().isFileID()) 918 break; 919 920 PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); 921 if (PLoc.isInvalid()) 922 break; 923 924 if (strcmp(PLoc.getFilename(), "<built-in>")) 925 break; 926 } while (true); 927 928 // Read all the preprocessed tokens, printing them out to the stream. 929 PrintPreprocessedTokens(PP, Tok, Callbacks, *OS); 930 *OS << '\n'; 931 932 // Remove the handlers we just added to leave the preprocessor in a sane state 933 // so that it can be reused (for example by a clang::Parser instance). 934 PP.RemovePragmaHandler(MicrosoftExtHandler.get()); 935 PP.RemovePragmaHandler("GCC", GCCHandler.get()); 936 PP.RemovePragmaHandler("clang", ClangHandler.get()); 937 PP.RemovePragmaHandler("omp", OpenMPHandler.get()); 938} 939