FrontendAction.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  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/ASTConsumer.h"
  11. #include "clang/AST/ASTContext.h"
  12. #include "clang/AST/DeclGroup.h"
  13. #include "clang/Lex/HeaderSearch.h"
  14. #include "clang/Lex/Preprocessor.h"
  15. #include "clang/Frontend/ASTUnit.h"
  16. #include "clang/Frontend/CompilerInstance.h"
  17. #include "clang/Frontend/FrontendDiagnostic.h"
  18. #include "clang/Frontend/FrontendPluginRegistry.h"
  19. #include "clang/Frontend/MultiplexConsumer.h"
  20. #include "clang/Parse/ParseAST.h"
  21. #include "clang/Serialization/ASTDeserializationListener.h"
  22. #include "llvm/Support/MemoryBuffer.h"
  23. #include "llvm/Support/Timer.h"
  24. #include "llvm/Support/ErrorHandling.h"
  25. #include "llvm/Support/raw_ostream.h"
  26. using namespace clang;
  27. namespace {
  28. /// \brief Dumps deserialized declarations.
  29. class DeserializedDeclsDumper : public ASTDeserializationListener {
  30. ASTDeserializationListener *Previous;
  31. public:
  32. DeserializedDeclsDumper(ASTDeserializationListener *Previous)
  33. : Previous(Previous) { }
  34. virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
  35. llvm::outs() << "PCH DECL: " << D->getDeclKindName();
  36. if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
  37. llvm::outs() << " - " << ND->getNameAsString();
  38. llvm::outs() << "\n";
  39. if (Previous)
  40. Previous->DeclRead(ID, D);
  41. }
  42. };
  43. /// \brief Checks deserialized declarations and emits error if a name
  44. /// matches one given in command-line using -error-on-deserialized-decl.
  45. class DeserializedDeclsChecker : public ASTDeserializationListener {
  46. ASTContext &Ctx;
  47. std::set<std::string> NamesToCheck;
  48. ASTDeserializationListener *Previous;
  49. public:
  50. DeserializedDeclsChecker(ASTContext &Ctx,
  51. const std::set<std::string> &NamesToCheck,
  52. ASTDeserializationListener *Previous)
  53. : Ctx(Ctx), NamesToCheck(NamesToCheck), Previous(Previous) { }
  54. virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
  55. if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
  56. if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
  57. unsigned DiagID
  58. = Ctx.getDiagnostics().getCustomDiagID(Diagnostic::Error,
  59. "%0 was deserialized");
  60. Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
  61. << ND->getNameAsString();
  62. }
  63. if (Previous)
  64. Previous->DeclRead(ID, D);
  65. }
  66. };
  67. } // end anonymous namespace
  68. FrontendAction::FrontendAction() : Instance(0) {}
  69. FrontendAction::~FrontendAction() {}
  70. void FrontendAction::setCurrentFile(llvm::StringRef Value, InputKind Kind,
  71. ASTUnit *AST) {
  72. CurrentFile = Value;
  73. CurrentFileKind = Kind;
  74. CurrentASTUnit.reset(AST);
  75. }
  76. ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
  77. llvm::StringRef InFile) {
  78. ASTConsumer* Consumer = CreateASTConsumer(CI, InFile);
  79. if (!Consumer)
  80. return 0;
  81. if (CI.getFrontendOpts().AddPluginActions.size() == 0)
  82. return Consumer;
  83. // Make sure the non-plugin consumer is first, so that plugins can't
  84. // modifiy the AST.
  85. std::vector<ASTConsumer*> Consumers(1, Consumer);
  86. for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size();
  87. i != e; ++i) {
  88. // This is O(|plugins| * |add_plugins|), but since both numbers are
  89. // way below 50 in practice, that's ok.
  90. for (FrontendPluginRegistry::iterator
  91. it = FrontendPluginRegistry::begin(),
  92. ie = FrontendPluginRegistry::end();
  93. it != ie; ++it) {
  94. if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) {
  95. llvm::OwningPtr<PluginASTAction> P(it->instantiate());
  96. FrontendAction* c = P.get();
  97. if (P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
  98. Consumers.push_back(c->CreateASTConsumer(CI, InFile));
  99. }
  100. }
  101. }
  102. return new MultiplexConsumer(Consumers);
  103. }
  104. bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
  105. llvm::StringRef Filename,
  106. InputKind InputKind) {
  107. assert(!Instance && "Already processing a source file!");
  108. assert(!Filename.empty() && "Unexpected empty filename!");
  109. setCurrentFile(Filename, InputKind);
  110. setCompilerInstance(&CI);
  111. // AST files follow a very different path, since they share objects via the
  112. // AST unit.
  113. if (InputKind == IK_AST) {
  114. assert(!usesPreprocessorOnly() &&
  115. "Attempt to pass AST file to preprocessor only action!");
  116. assert(hasASTFileSupport() &&
  117. "This action does not have AST file support!");
  118. llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
  119. std::string Error;
  120. ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags,
  121. CI.getFileSystemOpts());
  122. if (!AST)
  123. goto failure;
  124. setCurrentFile(Filename, InputKind, AST);
  125. // Set the shared objects, these are reset when we finish processing the
  126. // file, otherwise the CompilerInstance will happily destroy them.
  127. CI.setFileManager(&AST->getFileManager());
  128. CI.setSourceManager(&AST->getSourceManager());
  129. CI.setPreprocessor(&AST->getPreprocessor());
  130. CI.setASTContext(&AST->getASTContext());
  131. // Initialize the action.
  132. if (!BeginSourceFileAction(CI, Filename))
  133. goto failure;
  134. /// Create the AST consumer.
  135. CI.setASTConsumer(CreateWrappedASTConsumer(CI, Filename));
  136. if (!CI.hasASTConsumer())
  137. goto failure;
  138. return true;
  139. }
  140. // Set up the file and source managers, if needed.
  141. if (!CI.hasFileManager())
  142. CI.createFileManager();
  143. if (!CI.hasSourceManager())
  144. CI.createSourceManager(CI.getFileManager());
  145. // IR files bypass the rest of initialization.
  146. if (InputKind == IK_LLVM_IR) {
  147. assert(hasIRSupport() &&
  148. "This action does not have IR file support!");
  149. // Inform the diagnostic client we are processing a source file.
  150. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
  151. // Initialize the action.
  152. if (!BeginSourceFileAction(CI, Filename))
  153. goto failure;
  154. return true;
  155. }
  156. // Set up the preprocessor.
  157. CI.createPreprocessor();
  158. // Inform the diagnostic client we are processing a source file.
  159. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
  160. &CI.getPreprocessor());
  161. // Initialize the action.
  162. if (!BeginSourceFileAction(CI, Filename))
  163. goto failure;
  164. /// Create the AST context and consumer unless this is a preprocessor only
  165. /// action.
  166. if (!usesPreprocessorOnly()) {
  167. CI.createASTContext();
  168. llvm::OwningPtr<ASTConsumer> Consumer(
  169. CreateWrappedASTConsumer(CI, Filename));
  170. if (!Consumer)
  171. goto failure;
  172. CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
  173. /// Use PCH?
  174. if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
  175. assert(hasPCHSupport() && "This action does not have PCH support!");
  176. ASTDeserializationListener *DeserialListener
  177. = CI.getInvocation().getFrontendOpts().ChainedPCH ?
  178. Consumer->GetASTDeserializationListener() : 0;
  179. if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
  180. DeserialListener = new DeserializedDeclsDumper(DeserialListener);
  181. if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
  182. DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
  183. CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
  184. DeserialListener);
  185. CI.createPCHExternalASTSource(
  186. CI.getPreprocessorOpts().ImplicitPCHInclude,
  187. CI.getPreprocessorOpts().DisablePCHValidation,
  188. DeserialListener);
  189. if (!CI.getASTContext().getExternalSource())
  190. goto failure;
  191. }
  192. CI.setASTConsumer(Consumer.take());
  193. if (!CI.hasASTConsumer())
  194. goto failure;
  195. }
  196. // Initialize builtin info as long as we aren't using an external AST
  197. // source.
  198. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
  199. Preprocessor &PP = CI.getPreprocessor();
  200. PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
  201. PP.getLangOptions());
  202. }
  203. return true;
  204. // If we failed, reset state since the client will not end up calling the
  205. // matching EndSourceFile().
  206. failure:
  207. if (isCurrentFileAST()) {
  208. CI.takeASTContext();
  209. CI.takePreprocessor();
  210. CI.takeSourceManager();
  211. CI.takeFileManager();
  212. }
  213. CI.getDiagnosticClient().EndSourceFile();
  214. setCurrentFile("", IK_None);
  215. setCompilerInstance(0);
  216. return false;
  217. }
  218. void FrontendAction::Execute() {
  219. CompilerInstance &CI = getCompilerInstance();
  220. // Initialize the main file entry. This needs to be delayed until after PCH
  221. // has loaded.
  222. if (isCurrentFileAST()) {
  223. // Set the main file ID to an empty file.
  224. //
  225. // FIXME: We probably shouldn't need this, but for now this is the
  226. // simplest way to reuse the logic in ParseAST.
  227. const char *EmptyStr = "";
  228. llvm::MemoryBuffer *SB =
  229. llvm::MemoryBuffer::getMemBuffer(EmptyStr, "<dummy input>");
  230. CI.getSourceManager().createMainFileIDForMemBuffer(SB);
  231. } else {
  232. if (!CI.InitializeSourceManager(getCurrentFile()))
  233. return;
  234. }
  235. if (CI.hasFrontendTimer()) {
  236. llvm::TimeRegion Timer(CI.getFrontendTimer());
  237. ExecuteAction();
  238. }
  239. else ExecuteAction();
  240. }
  241. void FrontendAction::EndSourceFile() {
  242. CompilerInstance &CI = getCompilerInstance();
  243. // Finalize the action.
  244. EndSourceFileAction();
  245. // Release the consumer and the AST, in that order since the consumer may
  246. // perform actions in its destructor which require the context.
  247. //
  248. // FIXME: There is more per-file stuff we could just drop here?
  249. if (CI.getFrontendOpts().DisableFree) {
  250. CI.takeASTConsumer();
  251. if (!isCurrentFileAST()) {
  252. CI.takeSema();
  253. CI.takeASTContext();
  254. }
  255. } else {
  256. if (!isCurrentFileAST()) {
  257. CI.setSema(0);
  258. CI.setASTContext(0);
  259. }
  260. CI.setASTConsumer(0);
  261. }
  262. // Inform the preprocessor we are done.
  263. if (CI.hasPreprocessor())
  264. CI.getPreprocessor().EndSourceFile();
  265. if (CI.getFrontendOpts().ShowStats) {
  266. llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
  267. CI.getPreprocessor().PrintStats();
  268. CI.getPreprocessor().getIdentifierTable().PrintStats();
  269. CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
  270. CI.getSourceManager().PrintStats();
  271. llvm::errs() << "\n";
  272. }
  273. // Cleanup the output streams, and erase the output files if we encountered
  274. // an error.
  275. CI.clearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().hasErrorOccurred());
  276. // Inform the diagnostic client we are done with this source file.
  277. CI.getDiagnosticClient().EndSourceFile();
  278. if (isCurrentFileAST()) {
  279. CI.takeSema();
  280. CI.takeASTContext();
  281. CI.takePreprocessor();
  282. CI.takeSourceManager();
  283. CI.takeFileManager();
  284. }
  285. setCompilerInstance(0);
  286. setCurrentFile("", IK_None);
  287. }
  288. //===----------------------------------------------------------------------===//
  289. // Utility Actions
  290. //===----------------------------------------------------------------------===//
  291. void ASTFrontendAction::ExecuteAction() {
  292. CompilerInstance &CI = getCompilerInstance();
  293. // FIXME: Move the truncation aspect of this into Sema, we delayed this till
  294. // here so the source manager would be initialized.
  295. if (hasCodeCompletionSupport() &&
  296. !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
  297. CI.createCodeCompletionConsumer();
  298. // Use a code completion consumer?
  299. CodeCompleteConsumer *CompletionConsumer = 0;
  300. if (CI.hasCodeCompletionConsumer())
  301. CompletionConsumer = &CI.getCodeCompletionConsumer();
  302. if (!CI.hasSema())
  303. CI.createSema(usesCompleteTranslationUnit(), CompletionConsumer);
  304. ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats);
  305. }
  306. ASTConsumer *
  307. PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
  308. llvm::StringRef InFile) {
  309. llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
  310. }