FrontendActions.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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/Lex/Pragma.h"
  12. #include "clang/Lex/Preprocessor.h"
  13. #include "clang/Parse/Parser.h"
  14. #include "clang/Basic/FileManager.h"
  15. #include "clang/Frontend/ASTConsumers.h"
  16. #include "clang/Frontend/ASTUnit.h"
  17. #include "clang/Frontend/CompilerInstance.h"
  18. #include "clang/Frontend/FrontendDiagnostic.h"
  19. #include "clang/Frontend/Utils.h"
  20. #include "clang/Serialization/ASTWriter.h"
  21. #include "llvm/ADT/OwningPtr.h"
  22. #include "llvm/Support/MemoryBuffer.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. using namespace clang;
  25. //===----------------------------------------------------------------------===//
  26. // Custom Actions
  27. //===----------------------------------------------------------------------===//
  28. ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
  29. llvm::StringRef InFile) {
  30. return new ASTConsumer();
  31. }
  32. void InitOnlyAction::ExecuteAction() {
  33. }
  34. //===----------------------------------------------------------------------===//
  35. // AST Consumer Actions
  36. //===----------------------------------------------------------------------===//
  37. ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
  38. llvm::StringRef InFile) {
  39. if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
  40. return CreateASTPrinter(OS);
  41. return 0;
  42. }
  43. ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI,
  44. llvm::StringRef InFile) {
  45. if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml"))
  46. return CreateASTPrinterXML(OS);
  47. return 0;
  48. }
  49. ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
  50. llvm::StringRef InFile) {
  51. return CreateASTDumper();
  52. }
  53. ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
  54. llvm::StringRef InFile) {
  55. return CreateASTViewer();
  56. }
  57. ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
  58. llvm::StringRef InFile) {
  59. return CreateDeclContextPrinter();
  60. }
  61. ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
  62. llvm::StringRef InFile) {
  63. std::string Sysroot;
  64. llvm::raw_ostream *OS = 0;
  65. bool Chaining;
  66. if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OS, Chaining))
  67. return 0;
  68. const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
  69. Sysroot.c_str() : 0;
  70. return new PCHGenerator(CI.getPreprocessor(), Chaining, isysroot, OS);
  71. }
  72. bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
  73. llvm::StringRef InFile,
  74. std::string &Sysroot,
  75. llvm::raw_ostream *&OS,
  76. bool &Chaining) {
  77. Sysroot = CI.getHeaderSearchOpts().Sysroot;
  78. if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
  79. CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
  80. return true;
  81. }
  82. OS = CI.createDefaultOutputFile(true, InFile);
  83. if (!OS)
  84. return true;
  85. Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
  86. !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
  87. return false;
  88. }
  89. ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
  90. llvm::StringRef InFile) {
  91. return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance);
  92. }
  93. ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
  94. llvm::StringRef InFile) {
  95. return new ASTConsumer();
  96. }
  97. //===----------------------------------------------------------------------===//
  98. // Preprocessor Actions
  99. //===----------------------------------------------------------------------===//
  100. void DumpRawTokensAction::ExecuteAction() {
  101. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  102. SourceManager &SM = PP.getSourceManager();
  103. // Start lexing the specified input file.
  104. const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
  105. Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
  106. RawLex.SetKeepWhitespaceMode(true);
  107. Token RawTok;
  108. RawLex.LexFromRawLexer(RawTok);
  109. while (RawTok.isNot(tok::eof)) {
  110. PP.DumpToken(RawTok, true);
  111. llvm::errs() << "\n";
  112. RawLex.LexFromRawLexer(RawTok);
  113. }
  114. }
  115. void DumpTokensAction::ExecuteAction() {
  116. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  117. // Start preprocessing the specified input file.
  118. Token Tok;
  119. PP.EnterMainSourceFile();
  120. do {
  121. PP.Lex(Tok);
  122. PP.DumpToken(Tok, true);
  123. llvm::errs() << "\n";
  124. } while (Tok.isNot(tok::eof));
  125. }
  126. void GeneratePTHAction::ExecuteAction() {
  127. CompilerInstance &CI = getCompilerInstance();
  128. if (CI.getFrontendOpts().OutputFile.empty() ||
  129. CI.getFrontendOpts().OutputFile == "-") {
  130. // FIXME: Don't fail this way.
  131. // FIXME: Verify that we can actually seek in the given file.
  132. llvm::report_fatal_error("PTH requires a seekable file for output!");
  133. }
  134. llvm::raw_fd_ostream *OS =
  135. CI.createDefaultOutputFile(true, getCurrentFile());
  136. if (!OS) return;
  137. CacheTokens(CI.getPreprocessor(), OS);
  138. }
  139. void PreprocessOnlyAction::ExecuteAction() {
  140. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  141. // Ignore unknown pragmas.
  142. PP.AddPragmaHandler(new EmptyPragmaHandler());
  143. Token Tok;
  144. // Start parsing the specified input file.
  145. PP.EnterMainSourceFile();
  146. do {
  147. PP.Lex(Tok);
  148. } while (Tok.isNot(tok::eof));
  149. }
  150. void PrintPreprocessedAction::ExecuteAction() {
  151. CompilerInstance &CI = getCompilerInstance();
  152. // Output file needs to be set to 'Binary', to avoid converting Unix style
  153. // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
  154. llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
  155. if (!OS) return;
  156. DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
  157. CI.getPreprocessorOutputOpts());
  158. }
  159. void PrintPreambleAction::ExecuteAction() {
  160. switch (getCurrentFileKind()) {
  161. case IK_C:
  162. case IK_CXX:
  163. case IK_ObjC:
  164. case IK_ObjCXX:
  165. case IK_OpenCL:
  166. break;
  167. case IK_None:
  168. case IK_Asm:
  169. case IK_PreprocessedC:
  170. case IK_PreprocessedCXX:
  171. case IK_PreprocessedObjC:
  172. case IK_PreprocessedObjCXX:
  173. case IK_AST:
  174. case IK_LLVM_IR:
  175. // We can't do anything with these.
  176. return;
  177. }
  178. CompilerInstance &CI = getCompilerInstance();
  179. llvm::MemoryBuffer *Buffer
  180. = CI.getFileManager().getBufferForFile(getCurrentFile(),
  181. CI.getFileSystemOpts());
  182. if (Buffer) {
  183. unsigned Preamble = Lexer::ComputePreamble(Buffer).first;
  184. llvm::outs().write(Buffer->getBufferStart(), Preamble);
  185. delete Buffer;
  186. }
  187. }