FrontendActions.cpp 22 KB

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