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/ASTUnit.h"
15#include "clang/Frontend/CompilerInstance.h"
16#include "clang/Frontend/FrontendDiagnostic.h"
17#include "clang/Frontend/Utils.h"
18#include "clang/Lex/HeaderSearch.h"
19#include "clang/Lex/Pragma.h"
20#include "clang/Lex/Preprocessor.h"
21#include "clang/Parse/Parser.h"
22#include "clang/Serialization/ASTReader.h"
23#include "clang/Serialization/ASTWriter.h"
24#include "llvm/Support/FileSystem.h"
25#include "llvm/Support/MemoryBuffer.h"
26#include "llvm/Support/raw_ostream.h"
27#include <memory>
28#include <system_error>
29
30using namespace clang;
31
32//===----------------------------------------------------------------------===//
33// Custom Actions
34//===----------------------------------------------------------------------===//
35
36std::unique_ptr<ASTConsumer>
37InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
38  return llvm::make_unique<ASTConsumer>();
39}
40
41void InitOnlyAction::ExecuteAction() {
42}
43
44//===----------------------------------------------------------------------===//
45// AST Consumer Actions
46//===----------------------------------------------------------------------===//
47
48std::unique_ptr<ASTConsumer>
49ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
50  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
51    return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter);
52  return nullptr;
53}
54
55std::unique_ptr<ASTConsumer>
56ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
57  return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter,
58                         CI.getFrontendOpts().ASTDumpDecls,
59                         CI.getFrontendOpts().ASTDumpLookups);
60}
61
62std::unique_ptr<ASTConsumer>
63ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
64  return CreateASTDeclNodeLister();
65}
66
67std::unique_ptr<ASTConsumer>
68ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
69  return CreateASTViewer();
70}
71
72std::unique_ptr<ASTConsumer>
73DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
74                                          StringRef InFile) {
75  return CreateDeclContextPrinter();
76}
77
78std::unique_ptr<ASTConsumer>
79GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
80  std::string Sysroot;
81  std::string OutputFile;
82  raw_ostream *OS =
83      ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
84  if (!OS)
85    return nullptr;
86
87  if (!CI.getFrontendOpts().RelocatablePCH)
88    Sysroot.clear();
89  return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile,
90                                         nullptr, Sysroot, OS);
91}
92
93raw_ostream *GeneratePCHAction::ComputeASTConsumerArguments(
94    CompilerInstance &CI, StringRef InFile, std::string &Sysroot,
95    std::string &OutputFile) {
96  Sysroot = CI.getHeaderSearchOpts().Sysroot;
97  if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
98    CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
99    return nullptr;
100  }
101
102  // We use createOutputFile here because this is exposed via libclang, and we
103  // must disable the RemoveFileOnSignal behavior.
104  // We use a temporary to avoid race conditions.
105  raw_ostream *OS =
106      CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
107                          /*RemoveFileOnSignal=*/false, InFile,
108                          /*Extension=*/"", /*useTemporary=*/true);
109  if (!OS)
110    return nullptr;
111
112  OutputFile = CI.getFrontendOpts().OutputFile;
113  return OS;
114}
115
116std::unique_ptr<ASTConsumer>
117GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
118                                        StringRef InFile) {
119  std::string Sysroot;
120  std::string OutputFile;
121  raw_ostream *OS =
122      ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
123  if (!OS)
124    return nullptr;
125
126  return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile,
127                                         Module, Sysroot, OS);
128}
129
130static SmallVectorImpl<char> &
131operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
132  Includes.append(RHS.begin(), RHS.end());
133  return Includes;
134}
135
136static std::error_code addHeaderInclude(StringRef HeaderName,
137                                        SmallVectorImpl<char> &Includes,
138                                        const LangOptions &LangOpts,
139                                        bool IsExternC) {
140  if (IsExternC && LangOpts.CPlusPlus)
141    Includes += "extern \"C\" {\n";
142  if (LangOpts.ObjC1)
143    Includes += "#import \"";
144  else
145    Includes += "#include \"";
146
147  Includes += HeaderName;
148
149  Includes += "\"\n";
150  if (IsExternC && LangOpts.CPlusPlus)
151    Includes += "}\n";
152  return std::error_code();
153}
154
155static std::error_code addHeaderInclude(const FileEntry *Header,
156                                        SmallVectorImpl<char> &Includes,
157                                        const LangOptions &LangOpts,
158                                        bool IsExternC) {
159  // Use an absolute path if we don't have a filename as written in the module
160  // map file; this ensures that we will identify the right file independent of
161  // header search paths.
162  if (llvm::sys::path::is_absolute(Header->getName()))
163    return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
164
165  SmallString<256> AbsName(Header->getName());
166  if (std::error_code Err = llvm::sys::fs::make_absolute(AbsName))
167    return Err;
168  return addHeaderInclude(AbsName, Includes, LangOpts, IsExternC);
169}
170
171/// \brief Collect the set of header includes needed to construct the given
172/// module and update the TopHeaders file set of the module.
173///
174/// \param Module The module we're collecting includes from.
175///
176/// \param Includes Will be augmented with the set of \#includes or \#imports
177/// needed to load all of the named headers.
178static std::error_code
179collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
180                            ModuleMap &ModMap, clang::Module *Module,
181                            SmallVectorImpl<char> &Includes) {
182  // Don't collect any headers for unavailable modules.
183  if (!Module->isAvailable())
184    return std::error_code();
185
186  // Add includes for each of these headers.
187  for (Module::Header &H : Module->Headers[Module::HK_Normal]) {
188    Module->addTopHeader(H.Entry);
189    // Use the path as specified in the module map file. We'll look for this
190    // file relative to the module build directory (the directory containing
191    // the module map file) so this will find the same file that we found
192    // while parsing the module map.
193    if (std::error_code Err = addHeaderInclude(H.NameAsWritten, Includes,
194                                               LangOpts, Module->IsExternC))
195      return Err;
196  }
197  // Note that Module->PrivateHeaders will not be a TopHeader.
198
199  if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
200    // FIXME: Track the name as written here.
201    Module->addTopHeader(UmbrellaHeader);
202    if (Module->Parent) {
203      // Include the umbrella header for submodules.
204      if (std::error_code Err = addHeaderInclude(UmbrellaHeader, Includes,
205                                                 LangOpts, Module->IsExternC))
206        return Err;
207    }
208  } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
209    // Add all of the headers we find in this subdirectory.
210    std::error_code EC;
211    SmallString<128> DirNative;
212    llvm::sys::path::native(UmbrellaDir->getName(), DirNative);
213    for (llvm::sys::fs::recursive_directory_iterator Dir(DirNative, EC),
214                                                     DirEnd;
215         Dir != DirEnd && !EC; Dir.increment(EC)) {
216      // Check whether this entry has an extension typically associated with
217      // headers.
218      if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
219          .Cases(".h", ".H", ".hh", ".hpp", true)
220          .Default(false))
221        continue;
222
223      const FileEntry *Header = FileMgr.getFile(Dir->path());
224      // FIXME: This shouldn't happen unless there is a file system race. Is
225      // that worth diagnosing?
226      if (!Header)
227        continue;
228
229      // If this header is marked 'unavailable' in this module, don't include
230      // it.
231      if (ModMap.isHeaderUnavailableInModule(Header, Module))
232        continue;
233
234      // Include this header as part of the umbrella directory.
235      // FIXME: Track the name as written through to here.
236      Module->addTopHeader(Header);
237      if (std::error_code Err =
238              addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC))
239        return Err;
240    }
241
242    if (EC)
243      return EC;
244  }
245
246  // Recurse into submodules.
247  for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
248                                      SubEnd = Module->submodule_end();
249       Sub != SubEnd; ++Sub)
250    if (std::error_code Err = collectModuleHeaderIncludes(
251            LangOpts, FileMgr, ModMap, *Sub, Includes))
252      return Err;
253
254  return std::error_code();
255}
256
257bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
258                                                 StringRef Filename) {
259  // Find the module map file.
260  const FileEntry *ModuleMap = CI.getFileManager().getFile(Filename);
261  if (!ModuleMap)  {
262    CI.getDiagnostics().Report(diag::err_module_map_not_found)
263      << Filename;
264    return false;
265  }
266
267  // Parse the module map file.
268  HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
269  if (HS.loadModuleMapFile(ModuleMap, IsSystem))
270    return false;
271
272  if (CI.getLangOpts().CurrentModule.empty()) {
273    CI.getDiagnostics().Report(diag::err_missing_module_name);
274
275    // FIXME: Eventually, we could consider asking whether there was just
276    // a single module described in the module map, and use that as a
277    // default. Then it would be fairly trivial to just "compile" a module
278    // map with a single module (the common case).
279    return false;
280  }
281
282  // If we're being run from the command-line, the module build stack will not
283  // have been filled in yet, so complete it now in order to allow us to detect
284  // module cycles.
285  SourceManager &SourceMgr = CI.getSourceManager();
286  if (SourceMgr.getModuleBuildStack().empty())
287    SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
288                                   FullSourceLoc(SourceLocation(), SourceMgr));
289
290  // Dig out the module definition.
291  Module = HS.lookupModule(CI.getLangOpts().CurrentModule,
292                           /*AllowSearch=*/false);
293  if (!Module) {
294    CI.getDiagnostics().Report(diag::err_missing_module)
295      << CI.getLangOpts().CurrentModule << Filename;
296
297    return false;
298  }
299
300  // Check whether we can build this module at all.
301  clang::Module::Requirement Requirement;
302  clang::Module::UnresolvedHeaderDirective MissingHeader;
303  if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement,
304                           MissingHeader)) {
305    if (MissingHeader.FileNameLoc.isValid()) {
306      CI.getDiagnostics().Report(MissingHeader.FileNameLoc,
307                                 diag::err_module_header_missing)
308        << MissingHeader.IsUmbrella << MissingHeader.FileName;
309    } else {
310      CI.getDiagnostics().Report(diag::err_module_unavailable)
311        << Module->getFullModuleName()
312        << Requirement.second << Requirement.first;
313    }
314
315    return false;
316  }
317
318  if (ModuleMapForUniquing && ModuleMapForUniquing != ModuleMap) {
319    Module->IsInferred = true;
320    HS.getModuleMap().setInferredModuleAllowedBy(Module, ModuleMapForUniquing);
321  } else {
322    ModuleMapForUniquing = ModuleMap;
323  }
324
325  FileManager &FileMgr = CI.getFileManager();
326
327  // Collect the set of #includes we need to build the module.
328  SmallString<256> HeaderContents;
329  std::error_code Err = std::error_code();
330  if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader())
331    // FIXME: Track the file name as written.
332    Err = addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(),
333                           Module->IsExternC);
334  if (!Err)
335    Err = collectModuleHeaderIncludes(
336        CI.getLangOpts(), FileMgr,
337        CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), Module,
338        HeaderContents);
339
340  if (Err) {
341    CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
342      << Module->getFullModuleName() << Err.message();
343    return false;
344  }
345
346  // Inform the preprocessor that includes from within the input buffer should
347  // be resolved relative to the build directory of the module map file.
348  CI.getPreprocessor().setMainFileDir(Module->Directory);
349
350  std::unique_ptr<llvm::MemoryBuffer> InputBuffer =
351      llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,
352                                           Module::getModuleInputBufferName());
353  // Ownership of InputBuffer will be transferred to the SourceManager.
354  setCurrentInput(FrontendInputFile(InputBuffer.release(), getCurrentFileKind(),
355                                    Module->IsSystem));
356  return true;
357}
358
359raw_ostream *GenerateModuleAction::ComputeASTConsumerArguments(
360    CompilerInstance &CI, StringRef InFile, std::string &Sysroot,
361    std::string &OutputFile) {
362  // If no output file was provided, figure out where this module would go
363  // in the module cache.
364  if (CI.getFrontendOpts().OutputFile.empty()) {
365    HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
366    CI.getFrontendOpts().OutputFile =
367        HS.getModuleFileName(CI.getLangOpts().CurrentModule,
368                             ModuleMapForUniquing->getName());
369  }
370
371  // We use createOutputFile here because this is exposed via libclang, and we
372  // must disable the RemoveFileOnSignal behavior.
373  // We use a temporary to avoid race conditions.
374  raw_ostream *OS =
375      CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
376                          /*RemoveFileOnSignal=*/false, InFile,
377                          /*Extension=*/"", /*useTemporary=*/true,
378                          /*CreateMissingDirectories=*/true);
379  if (!OS)
380    return nullptr;
381
382  OutputFile = CI.getFrontendOpts().OutputFile;
383  return OS;
384}
385
386std::unique_ptr<ASTConsumer>
387SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
388  return llvm::make_unique<ASTConsumer>();
389}
390
391std::unique_ptr<ASTConsumer>
392DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI,
393                                        StringRef InFile) {
394  return llvm::make_unique<ASTConsumer>();
395}
396
397std::unique_ptr<ASTConsumer>
398VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
399  return llvm::make_unique<ASTConsumer>();
400}
401
402void VerifyPCHAction::ExecuteAction() {
403  CompilerInstance &CI = getCompilerInstance();
404  bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
405  const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
406  std::unique_ptr<ASTReader> Reader(
407      new ASTReader(CI.getPreprocessor(), CI.getASTContext(),
408                    Sysroot.empty() ? "" : Sysroot.c_str(),
409                    /*DisableValidation*/ false,
410                    /*AllowPCHWithCompilerErrors*/ false,
411                    /*AllowConfigurationMismatch*/ true,
412                    /*ValidateSystemInputs*/ true));
413
414  Reader->ReadAST(getCurrentFile(),
415                  Preamble ? serialization::MK_Preamble
416                           : serialization::MK_PCH,
417                  SourceLocation(),
418                  ASTReader::ARR_ConfigurationMismatch);
419}
420
421namespace {
422  /// \brief AST reader listener that dumps module information for a module
423  /// file.
424  class DumpModuleInfoListener : public ASTReaderListener {
425    llvm::raw_ostream &Out;
426
427  public:
428    DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }
429
430#define DUMP_BOOLEAN(Value, Text)                       \
431    Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
432
433    bool ReadFullVersionInformation(StringRef FullVersion) override {
434      Out.indent(2)
435        << "Generated by "
436        << (FullVersion == getClangFullRepositoryVersion()? "this"
437                                                          : "a different")
438        << " Clang: " << FullVersion << "\n";
439      return ASTReaderListener::ReadFullVersionInformation(FullVersion);
440    }
441
442    void ReadModuleName(StringRef ModuleName) override {
443      Out.indent(2) << "Module name: " << ModuleName << "\n";
444    }
445    void ReadModuleMapFile(StringRef ModuleMapPath) override {
446      Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
447    }
448
449    bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
450                             bool AllowCompatibleDifferences) override {
451      Out.indent(2) << "Language options:\n";
452#define LANGOPT(Name, Bits, Default, Description) \
453      DUMP_BOOLEAN(LangOpts.Name, Description);
454#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
455      Out.indent(4) << Description << ": "                   \
456                    << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
457#define VALUE_LANGOPT(Name, Bits, Default, Description) \
458      Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
459#define BENIGN_LANGOPT(Name, Bits, Default, Description)
460#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
461#include "clang/Basic/LangOptions.def"
462      return false;
463    }
464
465    bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
466                           bool AllowCompatibleDifferences) override {
467      Out.indent(2) << "Target options:\n";
468      Out.indent(4) << "  Triple: " << TargetOpts.Triple << "\n";
469      Out.indent(4) << "  CPU: " << TargetOpts.CPU << "\n";
470      Out.indent(4) << "  ABI: " << TargetOpts.ABI << "\n";
471
472      if (!TargetOpts.FeaturesAsWritten.empty()) {
473        Out.indent(4) << "Target features:\n";
474        for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
475             I != N; ++I) {
476          Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
477        }
478      }
479
480      return false;
481    }
482
483    bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
484                               bool Complain) override {
485      Out.indent(2) << "Diagnostic options:\n";
486#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
487#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
488      Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
489#define VALUE_DIAGOPT(Name, Bits, Default) \
490      Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
491#include "clang/Basic/DiagnosticOptions.def"
492
493      Out.indent(4) << "Diagnostic flags:\n";
494      for (const std::string &Warning : DiagOpts->Warnings)
495        Out.indent(6) << "-W" << Warning << "\n";
496      for (const std::string &Remark : DiagOpts->Remarks)
497        Out.indent(6) << "-R" << Remark << "\n";
498
499      return false;
500    }
501
502    bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
503                                 StringRef SpecificModuleCachePath,
504                                 bool Complain) override {
505      Out.indent(2) << "Header search options:\n";
506      Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
507      Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
508      DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
509                   "Use builtin include directories [-nobuiltininc]");
510      DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes,
511                   "Use standard system include directories [-nostdinc]");
512      DUMP_BOOLEAN(HSOpts.UseStandardCXXIncludes,
513                   "Use standard C++ include directories [-nostdinc++]");
514      DUMP_BOOLEAN(HSOpts.UseLibcxx,
515                   "Use libc++ (rather than libstdc++) [-stdlib=]");
516      return false;
517    }
518
519    bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
520                                 bool Complain,
521                                 std::string &SuggestedPredefines) override {
522      Out.indent(2) << "Preprocessor options:\n";
523      DUMP_BOOLEAN(PPOpts.UsePredefines,
524                   "Uses compiler/target-specific predefines [-undef]");
525      DUMP_BOOLEAN(PPOpts.DetailedRecord,
526                   "Uses detailed preprocessing record (for indexing)");
527
528      if (!PPOpts.Macros.empty()) {
529        Out.indent(4) << "Predefined macros:\n";
530      }
531
532      for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
533             I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
534           I != IEnd; ++I) {
535        Out.indent(6);
536        if (I->second)
537          Out << "-U";
538        else
539          Out << "-D";
540        Out << I->first << "\n";
541      }
542      return false;
543    }
544#undef DUMP_BOOLEAN
545  };
546}
547
548void DumpModuleInfoAction::ExecuteAction() {
549  // Set up the output file.
550  std::unique_ptr<llvm::raw_fd_ostream> OutFile;
551  StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile;
552  if (!OutputFileName.empty() && OutputFileName != "-") {
553    std::error_code EC;
554    OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC,
555                                           llvm::sys::fs::F_Text));
556  }
557  llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
558
559  Out << "Information for module file '" << getCurrentFile() << "':\n";
560  DumpModuleInfoListener Listener(Out);
561  ASTReader::readASTFileControlBlock(getCurrentFile(),
562                                     getCompilerInstance().getFileManager(),
563                                     Listener);
564}
565
566//===----------------------------------------------------------------------===//
567// Preprocessor Actions
568//===----------------------------------------------------------------------===//
569
570void DumpRawTokensAction::ExecuteAction() {
571  Preprocessor &PP = getCompilerInstance().getPreprocessor();
572  SourceManager &SM = PP.getSourceManager();
573
574  // Start lexing the specified input file.
575  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
576  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
577  RawLex.SetKeepWhitespaceMode(true);
578
579  Token RawTok;
580  RawLex.LexFromRawLexer(RawTok);
581  while (RawTok.isNot(tok::eof)) {
582    PP.DumpToken(RawTok, true);
583    llvm::errs() << "\n";
584    RawLex.LexFromRawLexer(RawTok);
585  }
586}
587
588void DumpTokensAction::ExecuteAction() {
589  Preprocessor &PP = getCompilerInstance().getPreprocessor();
590  // Start preprocessing the specified input file.
591  Token Tok;
592  PP.EnterMainSourceFile();
593  do {
594    PP.Lex(Tok);
595    PP.DumpToken(Tok, true);
596    llvm::errs() << "\n";
597  } while (Tok.isNot(tok::eof));
598}
599
600void GeneratePTHAction::ExecuteAction() {
601  CompilerInstance &CI = getCompilerInstance();
602  raw_pwrite_stream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
603  if (!OS)
604    return;
605
606  CacheTokens(CI.getPreprocessor(), OS);
607}
608
609void PreprocessOnlyAction::ExecuteAction() {
610  Preprocessor &PP = getCompilerInstance().getPreprocessor();
611
612  // Ignore unknown pragmas.
613  PP.IgnorePragmas();
614
615  Token Tok;
616  // Start parsing the specified input file.
617  PP.EnterMainSourceFile();
618  do {
619    PP.Lex(Tok);
620  } while (Tok.isNot(tok::eof));
621}
622
623void PrintPreprocessedAction::ExecuteAction() {
624  CompilerInstance &CI = getCompilerInstance();
625  // Output file may need to be set to 'Binary', to avoid converting Unix style
626  // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
627  //
628  // Look to see what type of line endings the file uses. If there's a
629  // CRLF, then we won't open the file up in binary mode. If there is
630  // just an LF or CR, then we will open the file up in binary mode.
631  // In this fashion, the output format should match the input format, unless
632  // the input format has inconsistent line endings.
633  //
634  // This should be a relatively fast operation since most files won't have
635  // all of their source code on a single line. However, that is still a
636  // concern, so if we scan for too long, we'll just assume the file should
637  // be opened in binary mode.
638  bool BinaryMode = true;
639  bool InvalidFile = false;
640  const SourceManager& SM = CI.getSourceManager();
641  const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(),
642                                                     &InvalidFile);
643  if (!InvalidFile) {
644    const char *cur = Buffer->getBufferStart();
645    const char *end = Buffer->getBufferEnd();
646    const char *next = (cur != end) ? cur + 1 : end;
647
648    // Limit ourselves to only scanning 256 characters into the source
649    // file.  This is mostly a sanity check in case the file has no
650    // newlines whatsoever.
651    if (end - cur > 256) end = cur + 256;
652
653    while (next < end) {
654      if (*cur == 0x0D) {  // CR
655        if (*next == 0x0A)  // CRLF
656          BinaryMode = false;
657
658        break;
659      } else if (*cur == 0x0A)  // LF
660        break;
661
662      ++cur, ++next;
663    }
664  }
665
666  raw_ostream *OS = CI.createDefaultOutputFile(BinaryMode, getCurrentFile());
667  if (!OS) return;
668
669  DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
670                           CI.getPreprocessorOutputOpts());
671}
672
673void PrintPreambleAction::ExecuteAction() {
674  switch (getCurrentFileKind()) {
675  case IK_C:
676  case IK_CXX:
677  case IK_ObjC:
678  case IK_ObjCXX:
679  case IK_OpenCL:
680  case IK_CUDA:
681    break;
682
683  case IK_None:
684  case IK_Asm:
685  case IK_PreprocessedC:
686  case IK_PreprocessedCuda:
687  case IK_PreprocessedCXX:
688  case IK_PreprocessedObjC:
689  case IK_PreprocessedObjCXX:
690  case IK_AST:
691  case IK_LLVM_IR:
692    // We can't do anything with these.
693    return;
694  }
695
696  CompilerInstance &CI = getCompilerInstance();
697  auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
698  if (Buffer) {
699    unsigned Preamble =
700        Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).first;
701    llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
702  }
703}
704