FrontendAction.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //===--- FrontendAction.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/FrontendAction.h"
  10. #include "clang/AST/ASTContext.h"
  11. #include "clang/Lex/HeaderSearch.h"
  12. #include "clang/Lex/Preprocessor.h"
  13. #include "clang/Frontend/ASTUnit.h"
  14. #include "clang/Frontend/CompilerInstance.h"
  15. #include "clang/Frontend/FrontendDiagnostic.h"
  16. #include "clang/Sema/ParseAST.h"
  17. #include "llvm/Support/MemoryBuffer.h"
  18. #include "llvm/Support/Timer.h"
  19. #include "llvm/Support/ErrorHandling.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. using namespace clang;
  22. FrontendAction::FrontendAction() : Instance(0) {}
  23. FrontendAction::~FrontendAction() {}
  24. void FrontendAction::setCurrentFile(llvm::StringRef Value, InputKind Kind,
  25. ASTUnit *AST) {
  26. CurrentFile = Value;
  27. CurrentFileKind = Kind;
  28. CurrentASTUnit.reset(AST);
  29. }
  30. bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
  31. llvm::StringRef Filename,
  32. InputKind InputKind) {
  33. assert(!Instance && "Already processing a source file!");
  34. assert(!Filename.empty() && "Unexpected empty filename!");
  35. setCurrentFile(Filename, InputKind);
  36. setCompilerInstance(&CI);
  37. // AST files follow a very different path, since they share objects via the
  38. // AST unit.
  39. if (InputKind == IK_AST) {
  40. assert(!usesPreprocessorOnly() &&
  41. "Attempt to pass AST file to preprocessor only action!");
  42. assert(hasASTFileSupport() &&
  43. "This action does not have AST file support!");
  44. llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
  45. std::string Error;
  46. ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, Diags);
  47. if (!AST)
  48. goto failure;
  49. setCurrentFile(Filename, InputKind, AST);
  50. // Set the shared objects, these are reset when we finish processing the
  51. // file, otherwise the CompilerInstance will happily destroy them.
  52. CI.setFileManager(&AST->getFileManager());
  53. CI.setSourceManager(&AST->getSourceManager());
  54. CI.setPreprocessor(&AST->getPreprocessor());
  55. CI.setASTContext(&AST->getASTContext());
  56. // Initialize the action.
  57. if (!BeginSourceFileAction(CI, Filename))
  58. goto failure;
  59. /// Create the AST consumer.
  60. CI.setASTConsumer(CreateASTConsumer(CI, Filename));
  61. if (!CI.hasASTConsumer())
  62. goto failure;
  63. return true;
  64. }
  65. // Set up the file and source managers, if needed.
  66. if (!CI.hasFileManager())
  67. CI.createFileManager();
  68. if (!CI.hasSourceManager())
  69. CI.createSourceManager();
  70. // IR files bypass the rest of initialization.
  71. if (InputKind == IK_LLVM_IR) {
  72. assert(hasIRSupport() &&
  73. "This action does not have IR file support!");
  74. // Inform the diagnostic client we are processing a source file.
  75. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
  76. // Initialize the action.
  77. if (!BeginSourceFileAction(CI, Filename))
  78. goto failure;
  79. return true;
  80. }
  81. // Set up the preprocessor.
  82. CI.createPreprocessor();
  83. // Inform the diagnostic client we are processing a source file.
  84. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
  85. &CI.getPreprocessor());
  86. // Initialize the action.
  87. if (!BeginSourceFileAction(CI, Filename))
  88. goto failure;
  89. /// Create the AST context and consumer unless this is a preprocessor only
  90. /// action.
  91. if (!usesPreprocessorOnly()) {
  92. CI.createASTContext();
  93. CI.setASTConsumer(CreateASTConsumer(CI, Filename));
  94. if (!CI.hasASTConsumer())
  95. goto failure;
  96. /// Use PCH?
  97. if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
  98. assert(hasPCHSupport() && "This action does not have PCH support!");
  99. CI.createPCHExternalASTSource(
  100. CI.getPreprocessorOpts().ImplicitPCHInclude);
  101. if (!CI.getASTContext().getExternalSource())
  102. goto failure;
  103. }
  104. }
  105. // Initialize builtin info as long as we aren't using an external AST
  106. // source.
  107. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
  108. Preprocessor &PP = CI.getPreprocessor();
  109. PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
  110. PP.getLangOptions().NoBuiltin);
  111. }
  112. return true;
  113. // If we failed, reset state since the client will not end up calling the
  114. // matching EndSourceFile().
  115. failure:
  116. if (isCurrentFileAST()) {
  117. CI.takeASTContext();
  118. CI.takePreprocessor();
  119. CI.takeSourceManager();
  120. CI.takeFileManager();
  121. }
  122. CI.getDiagnosticClient().EndSourceFile();
  123. setCurrentFile("", IK_None);
  124. setCompilerInstance(0);
  125. return false;
  126. }
  127. void FrontendAction::Execute() {
  128. CompilerInstance &CI = getCompilerInstance();
  129. // Initialize the main file entry. This needs to be delayed until after PCH
  130. // has loaded.
  131. if (isCurrentFileAST()) {
  132. // Set the main file ID to an empty file.
  133. //
  134. // FIXME: We probably shouldn't need this, but for now this is the
  135. // simplest way to reuse the logic in ParseAST.
  136. const char *EmptyStr = "";
  137. llvm::MemoryBuffer *SB =
  138. llvm::MemoryBuffer::getMemBuffer(EmptyStr, "<dummy input>");
  139. CI.getSourceManager().createMainFileIDForMemBuffer(SB);
  140. } else {
  141. if (!CI.InitializeSourceManager(getCurrentFile()))
  142. return;
  143. }
  144. if (CI.hasFrontendTimer()) {
  145. llvm::TimeRegion Timer(CI.getFrontendTimer());
  146. ExecuteAction();
  147. }
  148. else ExecuteAction();
  149. }
  150. void FrontendAction::EndSourceFile() {
  151. CompilerInstance &CI = getCompilerInstance();
  152. // Finalize the action.
  153. EndSourceFileAction();
  154. // Release the consumer and the AST, in that order since the consumer may
  155. // perform actions in its destructor which require the context.
  156. //
  157. // FIXME: There is more per-file stuff we could just drop here?
  158. if (CI.getFrontendOpts().DisableFree) {
  159. CI.takeASTConsumer();
  160. if (!isCurrentFileAST())
  161. CI.takeASTContext();
  162. } else {
  163. CI.setASTConsumer(0);
  164. if (!isCurrentFileAST())
  165. CI.setASTContext(0);
  166. }
  167. // Inform the preprocessor we are done.
  168. if (CI.hasPreprocessor())
  169. CI.getPreprocessor().EndSourceFile();
  170. if (CI.getFrontendOpts().ShowStats) {
  171. llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
  172. CI.getPreprocessor().PrintStats();
  173. CI.getPreprocessor().getIdentifierTable().PrintStats();
  174. CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
  175. CI.getSourceManager().PrintStats();
  176. llvm::errs() << "\n";
  177. }
  178. // Cleanup the output streams, and erase the output files if we encountered
  179. // an error.
  180. CI.clearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().getNumErrors());
  181. // Inform the diagnostic client we are done with this source file.
  182. CI.getDiagnosticClient().EndSourceFile();
  183. if (isCurrentFileAST()) {
  184. CI.takeASTContext();
  185. CI.takePreprocessor();
  186. CI.takeSourceManager();
  187. CI.takeFileManager();
  188. }
  189. setCompilerInstance(0);
  190. setCurrentFile("", IK_None);
  191. }
  192. //===----------------------------------------------------------------------===//
  193. // Utility Actions
  194. //===----------------------------------------------------------------------===//
  195. void ASTFrontendAction::ExecuteAction() {
  196. CompilerInstance &CI = getCompilerInstance();
  197. // FIXME: Move the truncation aspect of this into Sema, we delayed this till
  198. // here so the source manager would be initialized.
  199. if (hasCodeCompletionSupport() &&
  200. !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
  201. CI.createCodeCompletionConsumer();
  202. // Use a code completion consumer?
  203. CodeCompleteConsumer *CompletionConsumer = 0;
  204. if (CI.hasCodeCompletionConsumer())
  205. CompletionConsumer = &CI.getCodeCompletionConsumer();
  206. ParseAST(CI.getPreprocessor(), &CI.getASTConsumer(), CI.getASTContext(),
  207. CI.getFrontendOpts().ShowStats,
  208. usesCompleteTranslationUnit(), CompletionConsumer);
  209. }
  210. ASTConsumer *
  211. PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
  212. llvm::StringRef InFile) {
  213. llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
  214. }