1 //===--- FrontendActions.cpp ----------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "clang/Frontend/FrontendActions.h" 11 #include "clang/AST/ASTConsumer.h" 12 #include "clang/Basic/FileManager.h" 13 #include "clang/Frontend/ASTConsumers.h" 14 #include "clang/Frontend/CompilerInstance.h" 15 #include "clang/Frontend/FrontendDiagnostic.h" 16 #include "clang/Frontend/MultiplexConsumer.h" 17 #include "clang/Frontend/Utils.h" 18 #include "clang/Lex/HeaderSearch.h" 19 #include "clang/Lex/Preprocessor.h" 20 #include "clang/Lex/PreprocessorOptions.h" 21 #include "clang/Serialization/ASTReader.h" 22 #include "clang/Serialization/ASTWriter.h" 23 #include "llvm/Support/FileSystem.h" 24 #include "llvm/Support/MemoryBuffer.h" 25 #include "llvm/Support/Path.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include <memory> 28 #include <system_error> 29 30 using namespace clang; 31 32 //===----------------------------------------------------------------------===// 33 // Custom Actions 34 //===----------------------------------------------------------------------===// 35 36 std::unique_ptr<ASTConsumer> 37 InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 38 return llvm::make_unique<ASTConsumer>(); 39 } 40 41 void InitOnlyAction::ExecuteAction() { 42 } 43 44 //===----------------------------------------------------------------------===// 45 // AST Consumer Actions 46 //===----------------------------------------------------------------------===// 47 48 std::unique_ptr<ASTConsumer> 49 ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 50 if (std::unique_ptr<raw_ostream> OS = 51 CI.createDefaultOutputFile(false, InFile)) 52 return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter); 53 return nullptr; 54 } 55 56 std::unique_ptr<ASTConsumer> 57 ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 58 return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter, 59 CI.getFrontendOpts().ASTDumpDecls, 60 CI.getFrontendOpts().ASTDumpAll, 61 CI.getFrontendOpts().ASTDumpLookups); 62 } 63 64 std::unique_ptr<ASTConsumer> 65 ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 66 return CreateASTDeclNodeLister(); 67 } 68 69 std::unique_ptr<ASTConsumer> 70 ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 71 return CreateASTViewer(); 72 } 73 74 std::unique_ptr<ASTConsumer> 75 DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, 76 StringRef InFile) { 77 return CreateDeclContextPrinter(); 78 } 79 80 std::unique_ptr<ASTConsumer> 81 GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 82 std::string Sysroot; 83 std::string OutputFile; 84 std::unique_ptr<raw_pwrite_stream> OS = 85 ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile); 86 if (!OS) 87 return nullptr; 88 89 if (!CI.getFrontendOpts().RelocatablePCH) 90 Sysroot.clear(); 91 92 auto Buffer = std::make_shared<PCHBuffer>(); 93 std::vector<std::unique_ptr<ASTConsumer>> Consumers; 94 Consumers.push_back(llvm::make_unique<PCHGenerator>( 95 CI.getPreprocessor(), OutputFile, Sysroot, 96 Buffer, CI.getFrontendOpts().ModuleFileExtensions, 97 /*AllowASTWithErrors*/CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, 98 /*IncludeTimestamps*/ 99 +CI.getFrontendOpts().IncludeTimestamps)); 100 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( 101 CI, InFile, OutputFile, std::move(OS), Buffer)); 102 103 return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); 104 } 105 106 std::unique_ptr<raw_pwrite_stream> 107 GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, 108 StringRef InFile, 109 std::string &Sysroot, 110 std::string &OutputFile) { 111 Sysroot = CI.getHeaderSearchOpts().Sysroot; 112 if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) { 113 CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot); 114 return nullptr; 115 } 116 117 // We use createOutputFile here because this is exposed via libclang, and we 118 // must disable the RemoveFileOnSignal behavior. 119 // We use a temporary to avoid race conditions. 120 std::unique_ptr<raw_pwrite_stream> OS = 121 CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, 122 /*RemoveFileOnSignal=*/false, InFile, 123 /*Extension=*/"", /*useTemporary=*/true); 124 if (!OS) 125 return nullptr; 126 127 OutputFile = CI.getFrontendOpts().OutputFile; 128 return OS; 129 } 130 131 bool GeneratePCHAction::shouldEraseOutputFiles() { 132 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors) 133 return false; 134 return ASTFrontendAction::shouldEraseOutputFiles(); 135 } 136 137 bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI) { 138 CI.getLangOpts().CompilingPCH = true; 139 return true; 140 } 141 142 std::unique_ptr<ASTConsumer> 143 GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, 144 StringRef InFile) { 145 std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile); 146 if (!OS) 147 return nullptr; 148 149 std::string OutputFile = CI.getFrontendOpts().OutputFile; 150 std::string Sysroot; 151 152 auto Buffer = std::make_shared<PCHBuffer>(); 153 std::vector<std::unique_ptr<ASTConsumer>> Consumers; 154 155 Consumers.push_back(llvm::make_unique<PCHGenerator>( 156 CI.getPreprocessor(), OutputFile, Sysroot, 157 Buffer, CI.getFrontendOpts().ModuleFileExtensions, 158 /*AllowASTWithErrors=*/false, 159 /*IncludeTimestamps=*/ 160 +CI.getFrontendOpts().BuildingImplicitModule)); 161 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( 162 CI, InFile, OutputFile, std::move(OS), Buffer)); 163 return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); 164 } 165 166 std::unique_ptr<raw_pwrite_stream> 167 GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI, 168 StringRef InFile) { 169 // If no output file was provided, figure out where this module would go 170 // in the module cache. 171 if (CI.getFrontendOpts().OutputFile.empty()) { 172 StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap; 173 if (ModuleMapFile.empty()) 174 ModuleMapFile = InFile; 175 176 HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo(); 177 CI.getFrontendOpts().OutputFile = 178 HS.getModuleFileName(CI.getLangOpts().CurrentModule, ModuleMapFile, 179 /*UsePrebuiltPath=*/false); 180 } 181 182 // We use createOutputFile here because this is exposed via libclang, and we 183 // must disable the RemoveFileOnSignal behavior. 184 // We use a temporary to avoid race conditions. 185 return CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, 186 /*RemoveFileOnSignal=*/false, InFile, 187 /*Extension=*/"", /*useTemporary=*/true, 188 /*CreateMissingDirectories=*/true); 189 } 190 191 bool GenerateModuleInterfaceAction::BeginSourceFileAction( 192 CompilerInstance &CI) { 193 if (!CI.getLangOpts().ModulesTS) { 194 CI.getDiagnostics().Report(diag::err_module_interface_requires_modules_ts); 195 return false; 196 } 197 198 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface); 199 200 return GenerateModuleAction::BeginSourceFileAction(CI); 201 } 202 203 std::unique_ptr<raw_pwrite_stream> 204 GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI, 205 StringRef InFile) { 206 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm"); 207 } 208 209 SyntaxOnlyAction::~SyntaxOnlyAction() { 210 } 211 212 std::unique_ptr<ASTConsumer> 213 SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 214 return llvm::make_unique<ASTConsumer>(); 215 } 216 217 std::unique_ptr<ASTConsumer> 218 DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI, 219 StringRef InFile) { 220 return llvm::make_unique<ASTConsumer>(); 221 } 222 223 std::unique_ptr<ASTConsumer> 224 VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 225 return llvm::make_unique<ASTConsumer>(); 226 } 227 228 void VerifyPCHAction::ExecuteAction() { 229 CompilerInstance &CI = getCompilerInstance(); 230 bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 231 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; 232 std::unique_ptr<ASTReader> Reader(new ASTReader( 233 CI.getPreprocessor(), &CI.getASTContext(), CI.getPCHContainerReader(), 234 CI.getFrontendOpts().ModuleFileExtensions, 235 Sysroot.empty() ? "" : Sysroot.c_str(), 236 /*DisableValidation*/ false, 237 /*AllowPCHWithCompilerErrors*/ false, 238 /*AllowConfigurationMismatch*/ true, 239 /*ValidateSystemInputs*/ true)); 240 241 Reader->ReadAST(getCurrentFile(), 242 Preamble ? serialization::MK_Preamble 243 : serialization::MK_PCH, 244 SourceLocation(), 245 ASTReader::ARR_ConfigurationMismatch); 246 } 247 248 namespace { 249 /// \brief AST reader listener that dumps module information for a module 250 /// file. 251 class DumpModuleInfoListener : public ASTReaderListener { 252 llvm::raw_ostream &Out; 253 254 public: 255 DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { } 256 257 #define DUMP_BOOLEAN(Value, Text) \ 258 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n" 259 260 bool ReadFullVersionInformation(StringRef FullVersion) override { 261 Out.indent(2) 262 << "Generated by " 263 << (FullVersion == getClangFullRepositoryVersion()? "this" 264 : "a different") 265 << " Clang: " << FullVersion << "\n"; 266 return ASTReaderListener::ReadFullVersionInformation(FullVersion); 267 } 268 269 void ReadModuleName(StringRef ModuleName) override { 270 Out.indent(2) << "Module name: " << ModuleName << "\n"; 271 } 272 void ReadModuleMapFile(StringRef ModuleMapPath) override { 273 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n"; 274 } 275 276 bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, 277 bool AllowCompatibleDifferences) override { 278 Out.indent(2) << "Language options:\n"; 279 #define LANGOPT(Name, Bits, Default, Description) \ 280 DUMP_BOOLEAN(LangOpts.Name, Description); 281 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ 282 Out.indent(4) << Description << ": " \ 283 << static_cast<unsigned>(LangOpts.get##Name()) << "\n"; 284 #define VALUE_LANGOPT(Name, Bits, Default, Description) \ 285 Out.indent(4) << Description << ": " << LangOpts.Name << "\n"; 286 #define BENIGN_LANGOPT(Name, Bits, Default, Description) 287 #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) 288 #include "clang/Basic/LangOptions.def" 289 290 if (!LangOpts.ModuleFeatures.empty()) { 291 Out.indent(4) << "Module features:\n"; 292 for (StringRef Feature : LangOpts.ModuleFeatures) 293 Out.indent(6) << Feature << "\n"; 294 } 295 296 return false; 297 } 298 299 bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, 300 bool AllowCompatibleDifferences) override { 301 Out.indent(2) << "Target options:\n"; 302 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n"; 303 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n"; 304 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n"; 305 306 if (!TargetOpts.FeaturesAsWritten.empty()) { 307 Out.indent(4) << "Target features:\n"; 308 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); 309 I != N; ++I) { 310 Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n"; 311 } 312 } 313 314 return false; 315 } 316 317 bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, 318 bool Complain) override { 319 Out.indent(2) << "Diagnostic options:\n"; 320 #define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name); 321 #define ENUM_DIAGOPT(Name, Type, Bits, Default) \ 322 Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n"; 323 #define VALUE_DIAGOPT(Name, Bits, Default) \ 324 Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n"; 325 #include "clang/Basic/DiagnosticOptions.def" 326 327 Out.indent(4) << "Diagnostic flags:\n"; 328 for (const std::string &Warning : DiagOpts->Warnings) 329 Out.indent(6) << "-W" << Warning << "\n"; 330 for (const std::string &Remark : DiagOpts->Remarks) 331 Out.indent(6) << "-R" << Remark << "\n"; 332 333 return false; 334 } 335 336 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, 337 StringRef SpecificModuleCachePath, 338 bool Complain) override { 339 Out.indent(2) << "Header search options:\n"; 340 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n"; 341 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n"; 342 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n"; 343 DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes, 344 "Use builtin include directories [-nobuiltininc]"); 345 DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes, 346 "Use standard system include directories [-nostdinc]"); 347 DUMP_BOOLEAN(HSOpts.UseStandardCXXIncludes, 348 "Use standard C++ include directories [-nostdinc++]"); 349 DUMP_BOOLEAN(HSOpts.UseLibcxx, 350 "Use libc++ (rather than libstdc++) [-stdlib=]"); 351 return false; 352 } 353 354 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, 355 bool Complain, 356 std::string &SuggestedPredefines) override { 357 Out.indent(2) << "Preprocessor options:\n"; 358 DUMP_BOOLEAN(PPOpts.UsePredefines, 359 "Uses compiler/target-specific predefines [-undef]"); 360 DUMP_BOOLEAN(PPOpts.DetailedRecord, 361 "Uses detailed preprocessing record (for indexing)"); 362 363 if (!PPOpts.Macros.empty()) { 364 Out.indent(4) << "Predefined macros:\n"; 365 } 366 367 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator 368 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end(); 369 I != IEnd; ++I) { 370 Out.indent(6); 371 if (I->second) 372 Out << "-U"; 373 else 374 Out << "-D"; 375 Out << I->first << "\n"; 376 } 377 return false; 378 } 379 380 /// Indicates that a particular module file extension has been read. 381 void readModuleFileExtension( 382 const ModuleFileExtensionMetadata &Metadata) override { 383 Out.indent(2) << "Module file extension '" 384 << Metadata.BlockName << "' " << Metadata.MajorVersion 385 << "." << Metadata.MinorVersion; 386 if (!Metadata.UserInfo.empty()) { 387 Out << ": "; 388 Out.write_escaped(Metadata.UserInfo); 389 } 390 391 Out << "\n"; 392 } 393 #undef DUMP_BOOLEAN 394 }; 395 } 396 397 bool DumpModuleInfoAction::BeginInvocation(CompilerInstance &CI) { 398 // The Object file reader also supports raw ast files and there is no point in 399 // being strict about the module file format in -module-file-info mode. 400 CI.getHeaderSearchOpts().ModuleFormat = "obj"; 401 return true; 402 } 403 404 void DumpModuleInfoAction::ExecuteAction() { 405 // Set up the output file. 406 std::unique_ptr<llvm::raw_fd_ostream> OutFile; 407 StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile; 408 if (!OutputFileName.empty() && OutputFileName != "-") { 409 std::error_code EC; 410 OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC, 411 llvm::sys::fs::F_Text)); 412 } 413 llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs(); 414 415 Out << "Information for module file '" << getCurrentFile() << "':\n"; 416 auto &FileMgr = getCompilerInstance().getFileManager(); 417 auto Buffer = FileMgr.getBufferForFile(getCurrentFile()); 418 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer(); 419 bool IsRaw = (Magic.size() >= 4 && Magic[0] == 'C' && Magic[1] == 'P' && 420 Magic[2] == 'C' && Magic[3] == 'H'); 421 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n"; 422 423 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 424 DumpModuleInfoListener Listener(Out); 425 HeaderSearchOptions &HSOpts = 426 PP.getHeaderSearchInfo().getHeaderSearchOpts(); 427 ASTReader::readASTFileControlBlock( 428 getCurrentFile(), FileMgr, getCompilerInstance().getPCHContainerReader(), 429 /*FindModuleFileExtensions=*/true, Listener, 430 HSOpts.ModulesValidateDiagnosticOptions); 431 } 432 433 //===----------------------------------------------------------------------===// 434 // Preprocessor Actions 435 //===----------------------------------------------------------------------===// 436 437 void DumpRawTokensAction::ExecuteAction() { 438 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 439 SourceManager &SM = PP.getSourceManager(); 440 441 // Start lexing the specified input file. 442 const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID()); 443 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts()); 444 RawLex.SetKeepWhitespaceMode(true); 445 446 Token RawTok; 447 RawLex.LexFromRawLexer(RawTok); 448 while (RawTok.isNot(tok::eof)) { 449 PP.DumpToken(RawTok, true); 450 llvm::errs() << "\n"; 451 RawLex.LexFromRawLexer(RawTok); 452 } 453 } 454 455 void DumpTokensAction::ExecuteAction() { 456 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 457 // Start preprocessing the specified input file. 458 Token Tok; 459 PP.EnterMainSourceFile(); 460 do { 461 PP.Lex(Tok); 462 PP.DumpToken(Tok, true); 463 llvm::errs() << "\n"; 464 } while (Tok.isNot(tok::eof)); 465 } 466 467 void GeneratePTHAction::ExecuteAction() { 468 CompilerInstance &CI = getCompilerInstance(); 469 std::unique_ptr<raw_pwrite_stream> OS = 470 CI.createDefaultOutputFile(true, getCurrentFile()); 471 if (!OS) 472 return; 473 474 CacheTokens(CI.getPreprocessor(), OS.get()); 475 } 476 477 void PreprocessOnlyAction::ExecuteAction() { 478 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 479 480 // Ignore unknown pragmas. 481 PP.IgnorePragmas(); 482 483 Token Tok; 484 // Start parsing the specified input file. 485 PP.EnterMainSourceFile(); 486 do { 487 PP.Lex(Tok); 488 } while (Tok.isNot(tok::eof)); 489 } 490 491 void PrintPreprocessedAction::ExecuteAction() { 492 CompilerInstance &CI = getCompilerInstance(); 493 // Output file may need to be set to 'Binary', to avoid converting Unix style 494 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>). 495 // 496 // Look to see what type of line endings the file uses. If there's a 497 // CRLF, then we won't open the file up in binary mode. If there is 498 // just an LF or CR, then we will open the file up in binary mode. 499 // In this fashion, the output format should match the input format, unless 500 // the input format has inconsistent line endings. 501 // 502 // This should be a relatively fast operation since most files won't have 503 // all of their source code on a single line. However, that is still a 504 // concern, so if we scan for too long, we'll just assume the file should 505 // be opened in binary mode. 506 bool BinaryMode = true; 507 bool InvalidFile = false; 508 const SourceManager& SM = CI.getSourceManager(); 509 const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(), 510 &InvalidFile); 511 if (!InvalidFile) { 512 const char *cur = Buffer->getBufferStart(); 513 const char *end = Buffer->getBufferEnd(); 514 const char *next = (cur != end) ? cur + 1 : end; 515 516 // Limit ourselves to only scanning 256 characters into the source 517 // file. This is mostly a sanity check in case the file has no 518 // newlines whatsoever. 519 if (end - cur > 256) end = cur + 256; 520 521 while (next < end) { 522 if (*cur == 0x0D) { // CR 523 if (*next == 0x0A) // CRLF 524 BinaryMode = false; 525 526 break; 527 } else if (*cur == 0x0A) // LF 528 break; 529 530 ++cur; 531 ++next; 532 } 533 } 534 535 std::unique_ptr<raw_ostream> OS = 536 CI.createDefaultOutputFile(BinaryMode, getCurrentFile()); 537 if (!OS) return; 538 539 // If we're preprocessing a module map, start by dumping the contents of the 540 // module itself before switching to the input buffer. 541 auto &Input = getCurrentInput(); 542 if (Input.getKind().getFormat() == InputKind::ModuleMap) { 543 if (Input.isFile()) { 544 (*OS) << "# 1 \""; 545 OS->write_escaped(Input.getFile()); 546 (*OS) << "\"\n"; 547 } 548 // FIXME: Include additional information here so that we don't need the 549 // original source files to exist on disk. 550 getCurrentModule()->print(*OS); 551 (*OS) << "#pragma clang module contents\n"; 552 } 553 554 DoPrintPreprocessedInput(CI.getPreprocessor(), OS.get(), 555 CI.getPreprocessorOutputOpts()); 556 } 557 558 void PrintPreambleAction::ExecuteAction() { 559 switch (getCurrentFileKind().getLanguage()) { 560 case InputKind::C: 561 case InputKind::CXX: 562 case InputKind::ObjC: 563 case InputKind::ObjCXX: 564 case InputKind::OpenCL: 565 case InputKind::CUDA: 566 break; 567 568 case InputKind::Unknown: 569 case InputKind::Asm: 570 case InputKind::LLVM_IR: 571 case InputKind::RenderScript: 572 // We can't do anything with these. 573 return; 574 } 575 576 // We don't expect to find any #include directives in a preprocessed input. 577 if (getCurrentFileKind().isPreprocessed()) 578 return; 579 580 CompilerInstance &CI = getCompilerInstance(); 581 auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile()); 582 if (Buffer) { 583 unsigned Preamble = 584 Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).first; 585 llvm::outs().write((*Buffer)->getBufferStart(), Preamble); 586 } 587 } 588