1 1.1 joerg //===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg // 9 1.1 joerg // This code simply runs the preprocessor on the input file and prints out the 10 1.1 joerg // result. This is the traditional behavior of the -E option. 11 1.1 joerg // 12 1.1 joerg //===----------------------------------------------------------------------===// 13 1.1 joerg 14 1.1 joerg #include "clang/Frontend/Utils.h" 15 1.1 joerg #include "clang/Basic/CharInfo.h" 16 1.1 joerg #include "clang/Basic/Diagnostic.h" 17 1.1 joerg #include "clang/Basic/SourceManager.h" 18 1.1 joerg #include "clang/Frontend/PreprocessorOutputOptions.h" 19 1.1 joerg #include "clang/Lex/MacroInfo.h" 20 1.1 joerg #include "clang/Lex/PPCallbacks.h" 21 1.1 joerg #include "clang/Lex/Pragma.h" 22 1.1 joerg #include "clang/Lex/Preprocessor.h" 23 1.1 joerg #include "clang/Lex/TokenConcatenation.h" 24 1.1 joerg #include "llvm/ADT/STLExtras.h" 25 1.1 joerg #include "llvm/ADT/SmallString.h" 26 1.1 joerg #include "llvm/ADT/StringRef.h" 27 1.1 joerg #include "llvm/Support/ErrorHandling.h" 28 1.1 joerg #include "llvm/Support/raw_ostream.h" 29 1.1 joerg #include <cstdio> 30 1.1 joerg using namespace clang; 31 1.1 joerg 32 1.1 joerg /// PrintMacroDefinition - Print a macro definition in a form that will be 33 1.1 joerg /// properly accepted back as a definition. 34 1.1 joerg static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, 35 1.1 joerg Preprocessor &PP, raw_ostream &OS) { 36 1.1 joerg OS << "#define " << II.getName(); 37 1.1 joerg 38 1.1 joerg if (MI.isFunctionLike()) { 39 1.1 joerg OS << '('; 40 1.1 joerg if (!MI.param_empty()) { 41 1.1 joerg MacroInfo::param_iterator AI = MI.param_begin(), E = MI.param_end(); 42 1.1 joerg for (; AI+1 != E; ++AI) { 43 1.1 joerg OS << (*AI)->getName(); 44 1.1 joerg OS << ','; 45 1.1 joerg } 46 1.1 joerg 47 1.1 joerg // Last argument. 48 1.1 joerg if ((*AI)->getName() == "__VA_ARGS__") 49 1.1 joerg OS << "..."; 50 1.1 joerg else 51 1.1 joerg OS << (*AI)->getName(); 52 1.1 joerg } 53 1.1 joerg 54 1.1 joerg if (MI.isGNUVarargs()) 55 1.1 joerg OS << "..."; // #define foo(x...) 56 1.1 joerg 57 1.1 joerg OS << ')'; 58 1.1 joerg } 59 1.1 joerg 60 1.1 joerg // GCC always emits a space, even if the macro body is empty. However, do not 61 1.1 joerg // want to emit two spaces if the first token has a leading space. 62 1.1 joerg if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace()) 63 1.1 joerg OS << ' '; 64 1.1 joerg 65 1.1 joerg SmallString<128> SpellingBuffer; 66 1.1 joerg for (const auto &T : MI.tokens()) { 67 1.1 joerg if (T.hasLeadingSpace()) 68 1.1 joerg OS << ' '; 69 1.1 joerg 70 1.1 joerg OS << PP.getSpelling(T, SpellingBuffer); 71 1.1 joerg } 72 1.1 joerg } 73 1.1 joerg 74 1.1 joerg //===----------------------------------------------------------------------===// 75 1.1 joerg // Preprocessed token printer 76 1.1 joerg //===----------------------------------------------------------------------===// 77 1.1 joerg 78 1.1 joerg namespace { 79 1.1 joerg class PrintPPOutputPPCallbacks : public PPCallbacks { 80 1.1 joerg Preprocessor &PP; 81 1.1 joerg SourceManager &SM; 82 1.1 joerg TokenConcatenation ConcatInfo; 83 1.1 joerg public: 84 1.1 joerg raw_ostream &OS; 85 1.1 joerg private: 86 1.1 joerg unsigned CurLine; 87 1.1 joerg 88 1.1 joerg bool EmittedTokensOnThisLine; 89 1.1 joerg bool EmittedDirectiveOnThisLine; 90 1.1 joerg SrcMgr::CharacteristicKind FileType; 91 1.1 joerg SmallString<512> CurFilename; 92 1.1 joerg bool Initialized; 93 1.1 joerg bool DisableLineMarkers; 94 1.1 joerg bool DumpDefines; 95 1.1 joerg bool DumpIncludeDirectives; 96 1.1 joerg bool UseLineDirectives; 97 1.1 joerg bool IsFirstFileEntered; 98 1.1 joerg public: 99 1.1 joerg PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, bool lineMarkers, 100 1.1 joerg bool defines, bool DumpIncludeDirectives, 101 1.1 joerg bool UseLineDirectives) 102 1.1 joerg : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os), 103 1.1 joerg DisableLineMarkers(lineMarkers), DumpDefines(defines), 104 1.1 joerg DumpIncludeDirectives(DumpIncludeDirectives), 105 1.1 joerg UseLineDirectives(UseLineDirectives) { 106 1.1 joerg CurLine = 0; 107 1.1 joerg CurFilename += "<uninit>"; 108 1.1 joerg EmittedTokensOnThisLine = false; 109 1.1 joerg EmittedDirectiveOnThisLine = false; 110 1.1 joerg FileType = SrcMgr::C_User; 111 1.1 joerg Initialized = false; 112 1.1 joerg IsFirstFileEntered = false; 113 1.1 joerg } 114 1.1 joerg 115 1.1 joerg void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; } 116 1.1 joerg bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; } 117 1.1 joerg 118 1.1 joerg void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; } 119 1.1 joerg bool hasEmittedDirectiveOnThisLine() const { 120 1.1 joerg return EmittedDirectiveOnThisLine; 121 1.1 joerg } 122 1.1 joerg 123 1.1 joerg bool startNewLineIfNeeded(bool ShouldUpdateCurrentLine = true); 124 1.1 joerg 125 1.1 joerg void FileChanged(SourceLocation Loc, FileChangeReason Reason, 126 1.1 joerg SrcMgr::CharacteristicKind FileType, 127 1.1 joerg FileID PrevFID) override; 128 1.1 joerg void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 129 1.1 joerg StringRef FileName, bool IsAngled, 130 1.1 joerg CharSourceRange FilenameRange, const FileEntry *File, 131 1.1 joerg StringRef SearchPath, StringRef RelativePath, 132 1.1 joerg const Module *Imported, 133 1.1 joerg SrcMgr::CharacteristicKind FileType) override; 134 1.1 joerg void Ident(SourceLocation Loc, StringRef str) override; 135 1.1 joerg void PragmaMessage(SourceLocation Loc, StringRef Namespace, 136 1.1 joerg PragmaMessageKind Kind, StringRef Str) override; 137 1.1 joerg void PragmaDebug(SourceLocation Loc, StringRef DebugType) override; 138 1.1 joerg void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override; 139 1.1 joerg void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override; 140 1.1 joerg void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, 141 1.1 joerg diag::Severity Map, StringRef Str) override; 142 1.1 joerg void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, 143 1.1 joerg ArrayRef<int> Ids) override; 144 1.1 joerg void PragmaWarningPush(SourceLocation Loc, int Level) override; 145 1.1 joerg void PragmaWarningPop(SourceLocation Loc) override; 146 1.1 joerg void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override; 147 1.1 joerg void PragmaExecCharsetPop(SourceLocation Loc) override; 148 1.1 joerg void PragmaAssumeNonNullBegin(SourceLocation Loc) override; 149 1.1 joerg void PragmaAssumeNonNullEnd(SourceLocation Loc) override; 150 1.1 joerg 151 1.1 joerg bool HandleFirstTokOnLine(Token &Tok); 152 1.1 joerg 153 1.1 joerg /// Move to the line of the provided source location. This will 154 1.1 joerg /// return true if the output stream required adjustment or if 155 1.1 joerg /// the requested location is on the first line. 156 1.1 joerg bool MoveToLine(SourceLocation Loc) { 157 1.1 joerg PresumedLoc PLoc = SM.getPresumedLoc(Loc); 158 1.1 joerg if (PLoc.isInvalid()) 159 1.1 joerg return false; 160 1.1 joerg return MoveToLine(PLoc.getLine()) || (PLoc.getLine() == 1); 161 1.1 joerg } 162 1.1 joerg bool MoveToLine(unsigned LineNo); 163 1.1 joerg 164 1.1 joerg bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok, 165 1.1 joerg const Token &Tok) { 166 1.1 joerg return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok); 167 1.1 joerg } 168 1.1 joerg void WriteLineInfo(unsigned LineNo, const char *Extra=nullptr, 169 1.1 joerg unsigned ExtraLen=0); 170 1.1 joerg bool LineMarkersAreDisabled() const { return DisableLineMarkers; } 171 1.1 joerg void HandleNewlinesInToken(const char *TokStr, unsigned Len); 172 1.1 joerg 173 1.1 joerg /// MacroDefined - This hook is called whenever a macro definition is seen. 174 1.1 joerg void MacroDefined(const Token &MacroNameTok, 175 1.1 joerg const MacroDirective *MD) override; 176 1.1 joerg 177 1.1 joerg /// MacroUndefined - This hook is called whenever a macro #undef is seen. 178 1.1 joerg void MacroUndefined(const Token &MacroNameTok, 179 1.1 joerg const MacroDefinition &MD, 180 1.1 joerg const MacroDirective *Undef) override; 181 1.1 joerg 182 1.1 joerg void BeginModule(const Module *M); 183 1.1 joerg void EndModule(const Module *M); 184 1.1 joerg }; 185 1.1 joerg } // end anonymous namespace 186 1.1 joerg 187 1.1 joerg void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo, 188 1.1 joerg const char *Extra, 189 1.1 joerg unsigned ExtraLen) { 190 1.1 joerg startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false); 191 1.1 joerg 192 1.1 joerg // Emit #line directives or GNU line markers depending on what mode we're in. 193 1.1 joerg if (UseLineDirectives) { 194 1.1 joerg OS << "#line" << ' ' << LineNo << ' ' << '"'; 195 1.1 joerg OS.write_escaped(CurFilename); 196 1.1 joerg OS << '"'; 197 1.1 joerg } else { 198 1.1 joerg OS << '#' << ' ' << LineNo << ' ' << '"'; 199 1.1 joerg OS.write_escaped(CurFilename); 200 1.1 joerg OS << '"'; 201 1.1 joerg 202 1.1 joerg if (ExtraLen) 203 1.1 joerg OS.write(Extra, ExtraLen); 204 1.1 joerg 205 1.1 joerg if (FileType == SrcMgr::C_System) 206 1.1 joerg OS.write(" 3", 2); 207 1.1 joerg else if (FileType == SrcMgr::C_ExternCSystem) 208 1.1 joerg OS.write(" 3 4", 4); 209 1.1 joerg } 210 1.1 joerg OS << '\n'; 211 1.1 joerg } 212 1.1 joerg 213 1.1 joerg /// MoveToLine - Move the output to the source line specified by the location 214 1.1 joerg /// object. We can do this by emitting some number of \n's, or be emitting a 215 1.1 joerg /// #line directive. This returns false if already at the specified line, true 216 1.1 joerg /// if some newlines were emitted. 217 1.1 joerg bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) { 218 1.1 joerg // If this line is "close enough" to the original line, just print newlines, 219 1.1 joerg // otherwise print a #line directive. 220 1.1 joerg if (LineNo-CurLine <= 8) { 221 1.1 joerg if (LineNo-CurLine == 1) 222 1.1 joerg OS << '\n'; 223 1.1 joerg else if (LineNo == CurLine) 224 1.1 joerg return false; // Spelling line moved, but expansion line didn't. 225 1.1 joerg else { 226 1.1 joerg const char *NewLines = "\n\n\n\n\n\n\n\n"; 227 1.1 joerg OS.write(NewLines, LineNo-CurLine); 228 1.1 joerg } 229 1.1 joerg } else if (!DisableLineMarkers) { 230 1.1 joerg // Emit a #line or line marker. 231 1.1 joerg WriteLineInfo(LineNo, nullptr, 0); 232 1.1 joerg } else { 233 1.1 joerg // Okay, we're in -P mode, which turns off line markers. However, we still 234 1.1 joerg // need to emit a newline between tokens on different lines. 235 1.1 joerg startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false); 236 1.1 joerg } 237 1.1 joerg 238 1.1 joerg CurLine = LineNo; 239 1.1 joerg return true; 240 1.1 joerg } 241 1.1 joerg 242 1.1 joerg bool 243 1.1 joerg PrintPPOutputPPCallbacks::startNewLineIfNeeded(bool ShouldUpdateCurrentLine) { 244 1.1 joerg if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) { 245 1.1 joerg OS << '\n'; 246 1.1 joerg EmittedTokensOnThisLine = false; 247 1.1 joerg EmittedDirectiveOnThisLine = false; 248 1.1 joerg if (ShouldUpdateCurrentLine) 249 1.1 joerg ++CurLine; 250 1.1 joerg return true; 251 1.1 joerg } 252 1.1 joerg 253 1.1 joerg return false; 254 1.1 joerg } 255 1.1 joerg 256 1.1 joerg /// FileChanged - Whenever the preprocessor enters or exits a #include file 257 1.1 joerg /// it invokes this handler. Update our conception of the current source 258 1.1 joerg /// position. 259 1.1 joerg void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, 260 1.1 joerg FileChangeReason Reason, 261 1.1 joerg SrcMgr::CharacteristicKind NewFileType, 262 1.1 joerg FileID PrevFID) { 263 1.1 joerg // Unless we are exiting a #include, make sure to skip ahead to the line the 264 1.1 joerg // #include directive was at. 265 1.1 joerg SourceManager &SourceMgr = SM; 266 1.1 joerg 267 1.1 joerg PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc); 268 1.1 joerg if (UserLoc.isInvalid()) 269 1.1 joerg return; 270 1.1 joerg 271 1.1 joerg unsigned NewLine = UserLoc.getLine(); 272 1.1 joerg 273 1.1 joerg if (Reason == PPCallbacks::EnterFile) { 274 1.1 joerg SourceLocation IncludeLoc = UserLoc.getIncludeLoc(); 275 1.1 joerg if (IncludeLoc.isValid()) 276 1.1 joerg MoveToLine(IncludeLoc); 277 1.1 joerg } else if (Reason == PPCallbacks::SystemHeaderPragma) { 278 1.1 joerg // GCC emits the # directive for this directive on the line AFTER the 279 1.1 joerg // directive and emits a bunch of spaces that aren't needed. This is because 280 1.1 joerg // otherwise we will emit a line marker for THIS line, which requires an 281 1.1 joerg // extra blank line after the directive to avoid making all following lines 282 1.1 joerg // off by one. We can do better by simply incrementing NewLine here. 283 1.1 joerg NewLine += 1; 284 1.1 joerg } 285 1.1 joerg 286 1.1 joerg CurLine = NewLine; 287 1.1 joerg 288 1.1 joerg CurFilename.clear(); 289 1.1 joerg CurFilename += UserLoc.getFilename(); 290 1.1 joerg FileType = NewFileType; 291 1.1 joerg 292 1.1 joerg if (DisableLineMarkers) { 293 1.1 joerg startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false); 294 1.1 joerg return; 295 1.1 joerg } 296 1.1 joerg 297 1.1 joerg if (!Initialized) { 298 1.1 joerg WriteLineInfo(CurLine); 299 1.1 joerg Initialized = true; 300 1.1 joerg } 301 1.1 joerg 302 1.1 joerg // Do not emit an enter marker for the main file (which we expect is the first 303 1.1 joerg // entered file). This matches gcc, and improves compatibility with some tools 304 1.1 joerg // which track the # line markers as a way to determine when the preprocessed 305 1.1 joerg // output is in the context of the main file. 306 1.1 joerg if (Reason == PPCallbacks::EnterFile && !IsFirstFileEntered) { 307 1.1 joerg IsFirstFileEntered = true; 308 1.1 joerg return; 309 1.1 joerg } 310 1.1 joerg 311 1.1 joerg switch (Reason) { 312 1.1 joerg case PPCallbacks::EnterFile: 313 1.1 joerg WriteLineInfo(CurLine, " 1", 2); 314 1.1 joerg break; 315 1.1 joerg case PPCallbacks::ExitFile: 316 1.1 joerg WriteLineInfo(CurLine, " 2", 2); 317 1.1 joerg break; 318 1.1 joerg case PPCallbacks::SystemHeaderPragma: 319 1.1 joerg case PPCallbacks::RenameFile: 320 1.1 joerg WriteLineInfo(CurLine); 321 1.1 joerg break; 322 1.1 joerg } 323 1.1 joerg } 324 1.1 joerg 325 1.1 joerg void PrintPPOutputPPCallbacks::InclusionDirective( 326 1.1 joerg SourceLocation HashLoc, 327 1.1 joerg const Token &IncludeTok, 328 1.1 joerg StringRef FileName, 329 1.1 joerg bool IsAngled, 330 1.1 joerg CharSourceRange FilenameRange, 331 1.1 joerg const FileEntry *File, 332 1.1 joerg StringRef SearchPath, 333 1.1 joerg StringRef RelativePath, 334 1.1 joerg const Module *Imported, 335 1.1 joerg SrcMgr::CharacteristicKind FileType) { 336 1.1 joerg // In -dI mode, dump #include directives prior to dumping their content or 337 1.1 joerg // interpretation. 338 1.1 joerg if (DumpIncludeDirectives) { 339 1.1 joerg startNewLineIfNeeded(); 340 1.1 joerg MoveToLine(HashLoc); 341 1.1 joerg const std::string TokenText = PP.getSpelling(IncludeTok); 342 1.1 joerg assert(!TokenText.empty()); 343 1.1 joerg OS << "#" << TokenText << " " 344 1.1 joerg << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"') 345 1.1 joerg << " /* clang -E -dI */"; 346 1.1 joerg setEmittedDirectiveOnThisLine(); 347 1.1 joerg startNewLineIfNeeded(); 348 1.1 joerg } 349 1.1 joerg 350 1.1 joerg // When preprocessing, turn implicit imports into module import pragmas. 351 1.1 joerg if (Imported) { 352 1.1 joerg switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) { 353 1.1 joerg case tok::pp_include: 354 1.1 joerg case tok::pp_import: 355 1.1 joerg case tok::pp_include_next: 356 1.1 joerg startNewLineIfNeeded(); 357 1.1 joerg MoveToLine(HashLoc); 358 1.1 joerg OS << "#pragma clang module import " << Imported->getFullModuleName(true) 359 1.1 joerg << " /* clang -E: implicit import for " 360 1.1 joerg << "#" << PP.getSpelling(IncludeTok) << " " 361 1.1 joerg << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"') 362 1.1 joerg << " */"; 363 1.1 joerg // Since we want a newline after the pragma, but not a #<line>, start a 364 1.1 joerg // new line immediately. 365 1.1 joerg EmittedTokensOnThisLine = true; 366 1.1 joerg startNewLineIfNeeded(); 367 1.1 joerg break; 368 1.1 joerg 369 1.1 joerg case tok::pp___include_macros: 370 1.1 joerg // #__include_macros has no effect on a user of a preprocessed source 371 1.1 joerg // file; the only effect is on preprocessing. 372 1.1 joerg // 373 1.1 joerg // FIXME: That's not *quite* true: it causes the module in question to 374 1.1 joerg // be loaded, which can affect downstream diagnostics. 375 1.1 joerg break; 376 1.1 joerg 377 1.1 joerg default: 378 1.1 joerg llvm_unreachable("unknown include directive kind"); 379 1.1 joerg break; 380 1.1 joerg } 381 1.1 joerg } 382 1.1 joerg } 383 1.1 joerg 384 1.1 joerg /// Handle entering the scope of a module during a module compilation. 385 1.1 joerg void PrintPPOutputPPCallbacks::BeginModule(const Module *M) { 386 1.1 joerg startNewLineIfNeeded(); 387 1.1 joerg OS << "#pragma clang module begin " << M->getFullModuleName(true); 388 1.1 joerg setEmittedDirectiveOnThisLine(); 389 1.1 joerg } 390 1.1 joerg 391 1.1 joerg /// Handle leaving the scope of a module during a module compilation. 392 1.1 joerg void PrintPPOutputPPCallbacks::EndModule(const Module *M) { 393 1.1 joerg startNewLineIfNeeded(); 394 1.1 joerg OS << "#pragma clang module end /*" << M->getFullModuleName(true) << "*/"; 395 1.1 joerg setEmittedDirectiveOnThisLine(); 396 1.1 joerg } 397 1.1 joerg 398 1.1 joerg /// Ident - Handle #ident directives when read by the preprocessor. 399 1.1 joerg /// 400 1.1 joerg void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) { 401 1.1 joerg MoveToLine(Loc); 402 1.1 joerg 403 1.1 joerg OS.write("#ident ", strlen("#ident ")); 404 1.1 joerg OS.write(S.begin(), S.size()); 405 1.1 joerg EmittedTokensOnThisLine = true; 406 1.1 joerg } 407 1.1 joerg 408 1.1 joerg /// MacroDefined - This hook is called whenever a macro definition is seen. 409 1.1 joerg void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok, 410 1.1 joerg const MacroDirective *MD) { 411 1.1 joerg const MacroInfo *MI = MD->getMacroInfo(); 412 1.1 joerg // Only print out macro definitions in -dD mode. 413 1.1 joerg if (!DumpDefines || 414 1.1 joerg // Ignore __FILE__ etc. 415 1.1 joerg MI->isBuiltinMacro()) return; 416 1.1 joerg 417 1.1 joerg MoveToLine(MI->getDefinitionLoc()); 418 1.1 joerg PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS); 419 1.1 joerg setEmittedDirectiveOnThisLine(); 420 1.1 joerg } 421 1.1 joerg 422 1.1 joerg void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok, 423 1.1 joerg const MacroDefinition &MD, 424 1.1 joerg const MacroDirective *Undef) { 425 1.1 joerg // Only print out macro definitions in -dD mode. 426 1.1 joerg if (!DumpDefines) return; 427 1.1 joerg 428 1.1 joerg MoveToLine(MacroNameTok.getLocation()); 429 1.1 joerg OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName(); 430 1.1 joerg setEmittedDirectiveOnThisLine(); 431 1.1 joerg } 432 1.1 joerg 433 1.1 joerg static void outputPrintable(raw_ostream &OS, StringRef Str) { 434 1.1 joerg for (unsigned char Char : Str) { 435 1.1 joerg if (isPrintable(Char) && Char != '\\' && Char != '"') 436 1.1 joerg OS << (char)Char; 437 1.1 joerg else // Output anything hard as an octal escape. 438 1.1 joerg OS << '\\' 439 1.1 joerg << (char)('0' + ((Char >> 6) & 7)) 440 1.1 joerg << (char)('0' + ((Char >> 3) & 7)) 441 1.1 joerg << (char)('0' + ((Char >> 0) & 7)); 442 1.1 joerg } 443 1.1 joerg } 444 1.1 joerg 445 1.1 joerg void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc, 446 1.1 joerg StringRef Namespace, 447 1.1 joerg PragmaMessageKind Kind, 448 1.1 joerg StringRef Str) { 449 1.1 joerg startNewLineIfNeeded(); 450 1.1 joerg MoveToLine(Loc); 451 1.1 joerg OS << "#pragma "; 452 1.1 joerg if (!Namespace.empty()) 453 1.1 joerg OS << Namespace << ' '; 454 1.1 joerg switch (Kind) { 455 1.1 joerg case PMK_Message: 456 1.1 joerg OS << "message(\""; 457 1.1 joerg break; 458 1.1 joerg case PMK_Warning: 459 1.1 joerg OS << "warning \""; 460 1.1 joerg break; 461 1.1 joerg case PMK_Error: 462 1.1 joerg OS << "error \""; 463 1.1 joerg break; 464 1.1 joerg } 465 1.1 joerg 466 1.1 joerg outputPrintable(OS, Str); 467 1.1 joerg OS << '"'; 468 1.1 joerg if (Kind == PMK_Message) 469 1.1 joerg OS << ')'; 470 1.1 joerg setEmittedDirectiveOnThisLine(); 471 1.1 joerg } 472 1.1 joerg 473 1.1 joerg void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc, 474 1.1 joerg StringRef DebugType) { 475 1.1 joerg startNewLineIfNeeded(); 476 1.1 joerg MoveToLine(Loc); 477 1.1 joerg 478 1.1 joerg OS << "#pragma clang __debug "; 479 1.1 joerg OS << DebugType; 480 1.1 joerg 481 1.1 joerg setEmittedDirectiveOnThisLine(); 482 1.1 joerg } 483 1.1 joerg 484 1.1 joerg void PrintPPOutputPPCallbacks:: 485 1.1 joerg PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) { 486 1.1 joerg startNewLineIfNeeded(); 487 1.1 joerg MoveToLine(Loc); 488 1.1 joerg OS << "#pragma " << Namespace << " diagnostic push"; 489 1.1 joerg setEmittedDirectiveOnThisLine(); 490 1.1 joerg } 491 1.1 joerg 492 1.1 joerg void PrintPPOutputPPCallbacks:: 493 1.1 joerg PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) { 494 1.1 joerg startNewLineIfNeeded(); 495 1.1 joerg MoveToLine(Loc); 496 1.1 joerg OS << "#pragma " << Namespace << " diagnostic pop"; 497 1.1 joerg setEmittedDirectiveOnThisLine(); 498 1.1 joerg } 499 1.1 joerg 500 1.1 joerg void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc, 501 1.1 joerg StringRef Namespace, 502 1.1 joerg diag::Severity Map, 503 1.1 joerg StringRef Str) { 504 1.1 joerg startNewLineIfNeeded(); 505 1.1 joerg MoveToLine(Loc); 506 1.1 joerg OS << "#pragma " << Namespace << " diagnostic "; 507 1.1 joerg switch (Map) { 508 1.1 joerg case diag::Severity::Remark: 509 1.1 joerg OS << "remark"; 510 1.1 joerg break; 511 1.1 joerg case diag::Severity::Warning: 512 1.1 joerg OS << "warning"; 513 1.1 joerg break; 514 1.1 joerg case diag::Severity::Error: 515 1.1 joerg OS << "error"; 516 1.1 joerg break; 517 1.1 joerg case diag::Severity::Ignored: 518 1.1 joerg OS << "ignored"; 519 1.1 joerg break; 520 1.1 joerg case diag::Severity::Fatal: 521 1.1 joerg OS << "fatal"; 522 1.1 joerg break; 523 1.1 joerg } 524 1.1 joerg OS << " \"" << Str << '"'; 525 1.1 joerg setEmittedDirectiveOnThisLine(); 526 1.1 joerg } 527 1.1 joerg 528 1.1 joerg void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc, 529 1.1 joerg StringRef WarningSpec, 530 1.1 joerg ArrayRef<int> Ids) { 531 1.1 joerg startNewLineIfNeeded(); 532 1.1 joerg MoveToLine(Loc); 533 1.1 joerg OS << "#pragma warning(" << WarningSpec << ':'; 534 1.1 joerg for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I) 535 1.1 joerg OS << ' ' << *I; 536 1.1 joerg OS << ')'; 537 1.1 joerg setEmittedDirectiveOnThisLine(); 538 1.1 joerg } 539 1.1 joerg 540 1.1 joerg void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc, 541 1.1 joerg int Level) { 542 1.1 joerg startNewLineIfNeeded(); 543 1.1 joerg MoveToLine(Loc); 544 1.1 joerg OS << "#pragma warning(push"; 545 1.1 joerg if (Level >= 0) 546 1.1 joerg OS << ", " << Level; 547 1.1 joerg OS << ')'; 548 1.1 joerg setEmittedDirectiveOnThisLine(); 549 1.1 joerg } 550 1.1 joerg 551 1.1 joerg void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) { 552 1.1 joerg startNewLineIfNeeded(); 553 1.1 joerg MoveToLine(Loc); 554 1.1 joerg OS << "#pragma warning(pop)"; 555 1.1 joerg setEmittedDirectiveOnThisLine(); 556 1.1 joerg } 557 1.1 joerg 558 1.1 joerg void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc, 559 1.1 joerg StringRef Str) { 560 1.1 joerg startNewLineIfNeeded(); 561 1.1 joerg MoveToLine(Loc); 562 1.1 joerg OS << "#pragma character_execution_set(push"; 563 1.1 joerg if (!Str.empty()) 564 1.1 joerg OS << ", " << Str; 565 1.1 joerg OS << ')'; 566 1.1 joerg setEmittedDirectiveOnThisLine(); 567 1.1 joerg } 568 1.1 joerg 569 1.1 joerg void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) { 570 1.1 joerg startNewLineIfNeeded(); 571 1.1 joerg MoveToLine(Loc); 572 1.1 joerg OS << "#pragma character_execution_set(pop)"; 573 1.1 joerg setEmittedDirectiveOnThisLine(); 574 1.1 joerg } 575 1.1 joerg 576 1.1 joerg void PrintPPOutputPPCallbacks:: 577 1.1 joerg PragmaAssumeNonNullBegin(SourceLocation Loc) { 578 1.1 joerg startNewLineIfNeeded(); 579 1.1 joerg MoveToLine(Loc); 580 1.1 joerg OS << "#pragma clang assume_nonnull begin"; 581 1.1 joerg setEmittedDirectiveOnThisLine(); 582 1.1 joerg } 583 1.1 joerg 584 1.1 joerg void PrintPPOutputPPCallbacks:: 585 1.1 joerg PragmaAssumeNonNullEnd(SourceLocation Loc) { 586 1.1 joerg startNewLineIfNeeded(); 587 1.1 joerg MoveToLine(Loc); 588 1.1 joerg OS << "#pragma clang assume_nonnull end"; 589 1.1 joerg setEmittedDirectiveOnThisLine(); 590 1.1 joerg } 591 1.1 joerg 592 1.1 joerg /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this 593 1.1 joerg /// is called for the first token on each new line. If this really is the start 594 1.1 joerg /// of a new logical line, handle it and return true, otherwise return false. 595 1.1 joerg /// This may not be the start of a logical line because the "start of line" 596 1.1 joerg /// marker is set for spelling lines, not expansion ones. 597 1.1 joerg bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) { 598 1.1 joerg // Figure out what line we went to and insert the appropriate number of 599 1.1 joerg // newline characters. 600 1.1 joerg if (!MoveToLine(Tok.getLocation())) 601 1.1 joerg return false; 602 1.1 joerg 603 1.1 joerg // Print out space characters so that the first token on a line is 604 1.1 joerg // indented for easy reading. 605 1.1 joerg unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation()); 606 1.1 joerg 607 1.1 joerg // The first token on a line can have a column number of 1, yet still expect 608 1.1 joerg // leading white space, if a macro expansion in column 1 starts with an empty 609 1.1 joerg // macro argument, or an empty nested macro expansion. In this case, move the 610 1.1 joerg // token to column 2. 611 1.1 joerg if (ColNo == 1 && Tok.hasLeadingSpace()) 612 1.1 joerg ColNo = 2; 613 1.1 joerg 614 1.1 joerg // This hack prevents stuff like: 615 1.1 joerg // #define HASH # 616 1.1 joerg // HASH define foo bar 617 1.1 joerg // From having the # character end up at column 1, which makes it so it 618 1.1 joerg // is not handled as a #define next time through the preprocessor if in 619 1.1 joerg // -fpreprocessed mode. 620 1.1 joerg if (ColNo <= 1 && Tok.is(tok::hash)) 621 1.1 joerg OS << ' '; 622 1.1 joerg 623 1.1 joerg // Otherwise, indent the appropriate number of spaces. 624 1.1 joerg for (; ColNo > 1; --ColNo) 625 1.1 joerg OS << ' '; 626 1.1 joerg 627 1.1 joerg return true; 628 1.1 joerg } 629 1.1 joerg 630 1.1 joerg void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr, 631 1.1 joerg unsigned Len) { 632 1.1 joerg unsigned NumNewlines = 0; 633 1.1 joerg for (; Len; --Len, ++TokStr) { 634 1.1 joerg if (*TokStr != '\n' && 635 1.1 joerg *TokStr != '\r') 636 1.1 joerg continue; 637 1.1 joerg 638 1.1 joerg ++NumNewlines; 639 1.1 joerg 640 1.1 joerg // If we have \n\r or \r\n, skip both and count as one line. 641 1.1 joerg if (Len != 1 && 642 1.1 joerg (TokStr[1] == '\n' || TokStr[1] == '\r') && 643 1.1 joerg TokStr[0] != TokStr[1]) { 644 1.1 joerg ++TokStr; 645 1.1 joerg --Len; 646 1.1 joerg } 647 1.1 joerg } 648 1.1 joerg 649 1.1 joerg if (NumNewlines == 0) return; 650 1.1 joerg 651 1.1 joerg CurLine += NumNewlines; 652 1.1 joerg } 653 1.1 joerg 654 1.1 joerg 655 1.1 joerg namespace { 656 1.1 joerg struct UnknownPragmaHandler : public PragmaHandler { 657 1.1 joerg const char *Prefix; 658 1.1 joerg PrintPPOutputPPCallbacks *Callbacks; 659 1.1 joerg 660 1.1 joerg // Set to true if tokens should be expanded 661 1.1 joerg bool ShouldExpandTokens; 662 1.1 joerg 663 1.1 joerg UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks, 664 1.1 joerg bool RequireTokenExpansion) 665 1.1 joerg : Prefix(prefix), Callbacks(callbacks), 666 1.1 joerg ShouldExpandTokens(RequireTokenExpansion) {} 667 1.1 joerg void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, 668 1.1 joerg Token &PragmaTok) override { 669 1.1 joerg // Figure out what line we went to and insert the appropriate number of 670 1.1 joerg // newline characters. 671 1.1 joerg Callbacks->startNewLineIfNeeded(); 672 1.1 joerg Callbacks->MoveToLine(PragmaTok.getLocation()); 673 1.1 joerg Callbacks->OS.write(Prefix, strlen(Prefix)); 674 1.1 joerg 675 1.1 joerg if (ShouldExpandTokens) { 676 1.1 joerg // The first token does not have expanded macros. Expand them, if 677 1.1 joerg // required. 678 1.1 joerg auto Toks = std::make_unique<Token[]>(1); 679 1.1 joerg Toks[0] = PragmaTok; 680 1.1 joerg PP.EnterTokenStream(std::move(Toks), /*NumToks=*/1, 681 1.1 joerg /*DisableMacroExpansion=*/false, 682 1.1 joerg /*IsReinject=*/false); 683 1.1 joerg PP.Lex(PragmaTok); 684 1.1 joerg } 685 1.1 joerg Token PrevToken; 686 1.1 joerg Token PrevPrevToken; 687 1.1 joerg PrevToken.startToken(); 688 1.1 joerg PrevPrevToken.startToken(); 689 1.1 joerg 690 1.1 joerg // Read and print all of the pragma tokens. 691 1.1 joerg while (PragmaTok.isNot(tok::eod)) { 692 1.1 joerg if (PragmaTok.hasLeadingSpace() || 693 1.1 joerg Callbacks->AvoidConcat(PrevPrevToken, PrevToken, PragmaTok)) 694 1.1 joerg Callbacks->OS << ' '; 695 1.1 joerg std::string TokSpell = PP.getSpelling(PragmaTok); 696 1.1 joerg Callbacks->OS.write(&TokSpell[0], TokSpell.size()); 697 1.1 joerg 698 1.1 joerg PrevPrevToken = PrevToken; 699 1.1 joerg PrevToken = PragmaTok; 700 1.1 joerg 701 1.1 joerg if (ShouldExpandTokens) 702 1.1 joerg PP.Lex(PragmaTok); 703 1.1 joerg else 704 1.1 joerg PP.LexUnexpandedToken(PragmaTok); 705 1.1 joerg } 706 1.1 joerg Callbacks->setEmittedDirectiveOnThisLine(); 707 1.1 joerg } 708 1.1 joerg }; 709 1.1 joerg } // end anonymous namespace 710 1.1 joerg 711 1.1 joerg 712 1.1 joerg static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, 713 1.1 joerg PrintPPOutputPPCallbacks *Callbacks, 714 1.1 joerg raw_ostream &OS) { 715 1.1 joerg bool DropComments = PP.getLangOpts().TraditionalCPP && 716 1.1 joerg !PP.getCommentRetentionState(); 717 1.1 joerg 718 1.1 joerg char Buffer[256]; 719 1.1 joerg Token PrevPrevTok, PrevTok; 720 1.1 joerg PrevPrevTok.startToken(); 721 1.1 joerg PrevTok.startToken(); 722 1.1 joerg while (1) { 723 1.1 joerg if (Callbacks->hasEmittedDirectiveOnThisLine()) { 724 1.1 joerg Callbacks->startNewLineIfNeeded(); 725 1.1 joerg Callbacks->MoveToLine(Tok.getLocation()); 726 1.1 joerg } 727 1.1 joerg 728 1.1 joerg // If this token is at the start of a line, emit newlines if needed. 729 1.1 joerg if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) { 730 1.1 joerg // done. 731 1.1 joerg } else if (Tok.hasLeadingSpace() || 732 1.1 joerg // If we haven't emitted a token on this line yet, PrevTok isn't 733 1.1 joerg // useful to look at and no concatenation could happen anyway. 734 1.1 joerg (Callbacks->hasEmittedTokensOnThisLine() && 735 1.1 joerg // Don't print "-" next to "-", it would form "--". 736 1.1 joerg Callbacks->AvoidConcat(PrevPrevTok, PrevTok, Tok))) { 737 1.1 joerg OS << ' '; 738 1.1 joerg } 739 1.1 joerg 740 1.1 joerg if (DropComments && Tok.is(tok::comment)) { 741 1.1 joerg // Skip comments. Normally the preprocessor does not generate 742 1.1 joerg // tok::comment nodes at all when not keeping comments, but under 743 1.1 joerg // -traditional-cpp the lexer keeps /all/ whitespace, including comments. 744 1.1 joerg SourceLocation StartLoc = Tok.getLocation(); 745 1.1 joerg Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength())); 746 1.1 joerg } else if (Tok.is(tok::eod)) { 747 1.1 joerg // Don't print end of directive tokens, since they are typically newlines 748 1.1 joerg // that mess up our line tracking. These come from unknown pre-processor 749 1.1 joerg // directives or hash-prefixed comments in standalone assembly files. 750 1.1 joerg PP.Lex(Tok); 751 1.1 joerg continue; 752 1.1 joerg } else if (Tok.is(tok::annot_module_include)) { 753 1.1 joerg // PrintPPOutputPPCallbacks::InclusionDirective handles producing 754 1.1 joerg // appropriate output here. Ignore this token entirely. 755 1.1 joerg PP.Lex(Tok); 756 1.1 joerg continue; 757 1.1 joerg } else if (Tok.is(tok::annot_module_begin)) { 758 1.1 joerg // FIXME: We retrieve this token after the FileChanged callback, and 759 1.1 joerg // retrieve the module_end token before the FileChanged callback, so 760 1.1 joerg // we render this within the file and render the module end outside the 761 1.1 joerg // file, but this is backwards from the token locations: the module_begin 762 1.1 joerg // token is at the include location (outside the file) and the module_end 763 1.1 joerg // token is at the EOF location (within the file). 764 1.1 joerg Callbacks->BeginModule( 765 1.1 joerg reinterpret_cast<Module *>(Tok.getAnnotationValue())); 766 1.1 joerg PP.Lex(Tok); 767 1.1 joerg continue; 768 1.1 joerg } else if (Tok.is(tok::annot_module_end)) { 769 1.1 joerg Callbacks->EndModule( 770 1.1 joerg reinterpret_cast<Module *>(Tok.getAnnotationValue())); 771 1.1 joerg PP.Lex(Tok); 772 1.1 joerg continue; 773 1.1 joerg } else if (Tok.is(tok::annot_header_unit)) { 774 1.1 joerg // This is a header-name that has been (effectively) converted into a 775 1.1 joerg // module-name. 776 1.1 joerg // FIXME: The module name could contain non-identifier module name 777 1.1 joerg // components. We don't have a good way to round-trip those. 778 1.1 joerg Module *M = reinterpret_cast<Module *>(Tok.getAnnotationValue()); 779 1.1 joerg std::string Name = M->getFullModuleName(); 780 1.1 joerg OS.write(Name.data(), Name.size()); 781 1.1 joerg Callbacks->HandleNewlinesInToken(Name.data(), Name.size()); 782 1.1 joerg } else if (Tok.isAnnotation()) { 783 1.1 joerg // Ignore annotation tokens created by pragmas - the pragmas themselves 784 1.1 joerg // will be reproduced in the preprocessed output. 785 1.1 joerg PP.Lex(Tok); 786 1.1 joerg continue; 787 1.1 joerg } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) { 788 1.1 joerg OS << II->getName(); 789 1.1 joerg } else if (Tok.isLiteral() && !Tok.needsCleaning() && 790 1.1 joerg Tok.getLiteralData()) { 791 1.1 joerg OS.write(Tok.getLiteralData(), Tok.getLength()); 792 1.1 joerg } else if (Tok.getLength() < llvm::array_lengthof(Buffer)) { 793 1.1 joerg const char *TokPtr = Buffer; 794 1.1 joerg unsigned Len = PP.getSpelling(Tok, TokPtr); 795 1.1 joerg OS.write(TokPtr, Len); 796 1.1 joerg 797 1.1 joerg // Tokens that can contain embedded newlines need to adjust our current 798 1.1 joerg // line number. 799 1.1 joerg if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown) 800 1.1 joerg Callbacks->HandleNewlinesInToken(TokPtr, Len); 801 1.1 joerg } else { 802 1.1 joerg std::string S = PP.getSpelling(Tok); 803 1.1 joerg OS.write(S.data(), S.size()); 804 1.1 joerg 805 1.1 joerg // Tokens that can contain embedded newlines need to adjust our current 806 1.1 joerg // line number. 807 1.1 joerg if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown) 808 1.1 joerg Callbacks->HandleNewlinesInToken(S.data(), S.size()); 809 1.1 joerg } 810 1.1 joerg Callbacks->setEmittedTokensOnThisLine(); 811 1.1 joerg 812 1.1 joerg if (Tok.is(tok::eof)) break; 813 1.1 joerg 814 1.1 joerg PrevPrevTok = PrevTok; 815 1.1 joerg PrevTok = Tok; 816 1.1 joerg PP.Lex(Tok); 817 1.1 joerg } 818 1.1 joerg } 819 1.1 joerg 820 1.1 joerg typedef std::pair<const IdentifierInfo *, MacroInfo *> id_macro_pair; 821 1.1 joerg static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS) { 822 1.1 joerg return LHS->first->getName().compare(RHS->first->getName()); 823 1.1 joerg } 824 1.1 joerg 825 1.1 joerg static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) { 826 1.1 joerg // Ignore unknown pragmas. 827 1.1 joerg PP.IgnorePragmas(); 828 1.1 joerg 829 1.1 joerg // -dM mode just scans and ignores all tokens in the files, then dumps out 830 1.1 joerg // the macro table at the end. 831 1.1 joerg PP.EnterMainSourceFile(); 832 1.1 joerg 833 1.1 joerg Token Tok; 834 1.1 joerg do PP.Lex(Tok); 835 1.1 joerg while (Tok.isNot(tok::eof)); 836 1.1 joerg 837 1.1 joerg SmallVector<id_macro_pair, 128> MacrosByID; 838 1.1 joerg for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); 839 1.1 joerg I != E; ++I) { 840 1.1 joerg auto *MD = I->second.getLatest(); 841 1.1 joerg if (MD && MD->isDefined()) 842 1.1 joerg MacrosByID.push_back(id_macro_pair(I->first, MD->getMacroInfo())); 843 1.1 joerg } 844 1.1 joerg llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare); 845 1.1 joerg 846 1.1 joerg for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) { 847 1.1 joerg MacroInfo &MI = *MacrosByID[i].second; 848 1.1 joerg // Ignore computed macros like __LINE__ and friends. 849 1.1 joerg if (MI.isBuiltinMacro()) continue; 850 1.1 joerg 851 1.1 joerg PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS); 852 1.1 joerg *OS << '\n'; 853 1.1 joerg } 854 1.1 joerg } 855 1.1 joerg 856 1.1 joerg /// DoPrintPreprocessedInput - This implements -E mode. 857 1.1 joerg /// 858 1.1 joerg void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, 859 1.1 joerg const PreprocessorOutputOptions &Opts) { 860 1.1 joerg // Show macros with no output is handled specially. 861 1.1 joerg if (!Opts.ShowCPP) { 862 1.1 joerg assert(Opts.ShowMacros && "Not yet implemented!"); 863 1.1 joerg DoPrintMacros(PP, OS); 864 1.1 joerg return; 865 1.1 joerg } 866 1.1 joerg 867 1.1 joerg // Inform the preprocessor whether we want it to retain comments or not, due 868 1.1 joerg // to -C or -CC. 869 1.1 joerg PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments); 870 1.1 joerg 871 1.1 joerg PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks( 872 1.1 joerg PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, 873 1.1 joerg Opts.ShowIncludeDirectives, Opts.UseLineDirectives); 874 1.1 joerg 875 1.1 joerg // Expand macros in pragmas with -fms-extensions. The assumption is that 876 1.1 joerg // the majority of pragmas in such a file will be Microsoft pragmas. 877 1.1 joerg // Remember the handlers we will add so that we can remove them later. 878 1.1 joerg std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler( 879 1.1 joerg new UnknownPragmaHandler( 880 1.1 joerg "#pragma", Callbacks, 881 1.1 joerg /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); 882 1.1 joerg 883 1.1 joerg std::unique_ptr<UnknownPragmaHandler> GCCHandler(new UnknownPragmaHandler( 884 1.1 joerg "#pragma GCC", Callbacks, 885 1.1 joerg /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); 886 1.1 joerg 887 1.1 joerg std::unique_ptr<UnknownPragmaHandler> ClangHandler(new UnknownPragmaHandler( 888 1.1 joerg "#pragma clang", Callbacks, 889 1.1 joerg /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); 890 1.1 joerg 891 1.1 joerg PP.AddPragmaHandler(MicrosoftExtHandler.get()); 892 1.1 joerg PP.AddPragmaHandler("GCC", GCCHandler.get()); 893 1.1 joerg PP.AddPragmaHandler("clang", ClangHandler.get()); 894 1.1 joerg 895 1.1 joerg // The tokens after pragma omp need to be expanded. 896 1.1 joerg // 897 1.1 joerg // OpenMP [2.1, Directive format] 898 1.1 joerg // Preprocessing tokens following the #pragma omp are subject to macro 899 1.1 joerg // replacement. 900 1.1 joerg std::unique_ptr<UnknownPragmaHandler> OpenMPHandler( 901 1.1 joerg new UnknownPragmaHandler("#pragma omp", Callbacks, 902 1.1 joerg /*RequireTokenExpansion=*/true)); 903 1.1 joerg PP.AddPragmaHandler("omp", OpenMPHandler.get()); 904 1.1 joerg 905 1.1 joerg PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks)); 906 1.1 joerg 907 1.1 joerg // After we have configured the preprocessor, enter the main file. 908 1.1 joerg PP.EnterMainSourceFile(); 909 1.1 joerg 910 1.1 joerg // Consume all of the tokens that come from the predefines buffer. Those 911 1.1 joerg // should not be emitted into the output and are guaranteed to be at the 912 1.1 joerg // start. 913 1.1 joerg const SourceManager &SourceMgr = PP.getSourceManager(); 914 1.1 joerg Token Tok; 915 1.1 joerg do { 916 1.1 joerg PP.Lex(Tok); 917 1.1 joerg if (Tok.is(tok::eof) || !Tok.getLocation().isFileID()) 918 1.1 joerg break; 919 1.1 joerg 920 1.1 joerg PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); 921 1.1 joerg if (PLoc.isInvalid()) 922 1.1 joerg break; 923 1.1 joerg 924 1.1 joerg if (strcmp(PLoc.getFilename(), "<built-in>")) 925 1.1 joerg break; 926 1.1 joerg } while (true); 927 1.1 joerg 928 1.1 joerg // Read all the preprocessed tokens, printing them out to the stream. 929 1.1 joerg PrintPreprocessedTokens(PP, Tok, Callbacks, *OS); 930 1.1 joerg *OS << '\n'; 931 1.1 joerg 932 1.1 joerg // Remove the handlers we just added to leave the preprocessor in a sane state 933 1.1 joerg // so that it can be reused (for example by a clang::Parser instance). 934 1.1 joerg PP.RemovePragmaHandler(MicrosoftExtHandler.get()); 935 1.1 joerg PP.RemovePragmaHandler("GCC", GCCHandler.get()); 936 1.1 joerg PP.RemovePragmaHandler("clang", ClangHandler.get()); 937 1.1 joerg PP.RemovePragmaHandler("omp", OpenMPHandler.get()); 938 1.1 joerg } 939