14ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar//===--- FrontendAction.cpp -----------------------------------------------===// 24ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// 34ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// The LLVM Compiler Infrastructure 44ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// 54ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// This file is distributed under the University of Illinois Open Source 64ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// License. See LICENSE.TXT for details. 74ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// 84ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar//===----------------------------------------------------------------------===// 94ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 104ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Frontend/FrontendAction.h" 11ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl#include "clang/AST/ASTConsumer.h" 124ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/AST/ASTContext.h" 135aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber#include "clang/AST/DeclGroup.h" 144ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Frontend/ASTUnit.h" 1571088d1af241ad114294ec3fe03cd9baea39ee08Chandler Carruth#include "clang/Frontend/ChainedIncludesSource.h" 164ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Frontend/CompilerInstance.h" 174ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 185aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber#include "clang/Frontend/FrontendPluginRegistry.h" 19453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor#include "clang/Frontend/LayoutOverrideSource.h" 205aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber#include "clang/Frontend/MultiplexConsumer.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/HeaderSearch.h" 2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Preprocessor.h" 2319510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Parse/ParseAST.h" 24b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis#include "clang/Serialization/ASTDeserializationListener.h" 25e735e2deb9e57d9b62c1258ee236ccfeba8e84b2Jonathan D. Turner#include "clang/Serialization/ASTReader.h" 26a6b00fc97669aa25d89ae9f202b05dfadfd0e324Douglas Gregor#include "clang/Serialization/GlobalModuleIndex.h" 274ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "llvm/Support/ErrorHandling.h" 2827ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor#include "llvm/Support/FileSystem.h" 2927ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 3055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Timer.h" 314ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "llvm/Support/raw_ostream.h" 3227ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor#include "llvm/Support/system_error.h" 334ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarusing namespace clang; 344ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 35b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidisnamespace { 36b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 37407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidisclass DelegatingDeserializationListener : public ASTDeserializationListener { 38b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis ASTDeserializationListener *Previous; 39b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 40b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidispublic: 41407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis explicit DelegatingDeserializationListener( 42407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis ASTDeserializationListener *Previous) 43b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis : Previous(Previous) { } 44b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 45407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis virtual void ReaderInitialized(ASTReader *Reader) { 46407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis if (Previous) 47407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis Previous->ReaderInitialized(Reader); 48407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis } 49407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis virtual void IdentifierRead(serialization::IdentID ID, 50407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis IdentifierInfo *II) { 51407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis if (Previous) 52407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis Previous->IdentifierRead(ID, II); 53407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis } 54407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { 55407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis if (Previous) 56407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis Previous->TypeRead(Idx, T); 57407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis } 58407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 59407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis if (Previous) 60407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis Previous->DeclRead(ID, D); 61407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis } 62407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis virtual void SelectorRead(serialization::SelectorID ID, Selector Sel) { 63407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis if (Previous) 64407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis Previous->SelectorRead(ID, Sel); 65407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis } 66407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis virtual void MacroDefinitionRead(serialization::PreprocessedEntityID PPID, 67407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis MacroDefinition *MD) { 68407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis if (Previous) 69407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis Previous->MacroDefinitionRead(PPID, MD); 70407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis } 71407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis}; 72407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis 73407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis/// \brief Dumps deserialized declarations. 74407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidisclass DeserializedDeclsDumper : public DelegatingDeserializationListener { 75407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidispublic: 76407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous) 77407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis : DelegatingDeserializationListener(Previous) { } 78407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis 79b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 80b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis llvm::outs() << "PCH DECL: " << D->getDeclKindName(); 81b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 82a59d20b135bfde058a5a69045bab5ec4e2553f74Benjamin Kramer llvm::outs() << " - " << *ND; 83b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis llvm::outs() << "\n"; 84b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 85407ef9a9286a05bd286174471889295f6615c1b2Argyrios Kyrtzidis DelegatingDeserializationListener::DeclRead(ID, D); 86b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis } 87b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis}; 88b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 89e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie/// \brief Checks deserialized declarations and emits error if a name 90e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie/// matches one given in command-line using -error-on-deserialized-decl. 91e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikieclass DeserializedDeclsChecker : public DelegatingDeserializationListener { 92e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie ASTContext &Ctx; 93e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie std::set<std::string> NamesToCheck; 94e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie 95e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikiepublic: 96e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie DeserializedDeclsChecker(ASTContext &Ctx, 97e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie const std::set<std::string> &NamesToCheck, 98e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie ASTDeserializationListener *Previous) 99e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie : DelegatingDeserializationListener(Previous), 100e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie Ctx(Ctx), NamesToCheck(NamesToCheck) { } 101e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie 102e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 103e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 104e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { 105e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie unsigned DiagID 106e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, 107e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie "%0 was deserialized"); 108e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID) 109e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie << ND->getNameAsString(); 110e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie } 111e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie 112e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie DelegatingDeserializationListener::DeclRead(ID, D); 113e3f341152af5589f2586b6b5cfbad284afa731f2David Blaikie } 1143e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis}; 1153e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis 116b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis} // end anonymous namespace 117b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 118f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan RajaratnamFrontendAction::FrontendAction() : Instance(0) {} 1194ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1204ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel DunbarFrontendAction::~FrontendAction() {} 1214ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1221f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregorvoid FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput, 1231f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor ASTUnit *AST) { 1241f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor this->CurrentInput = CurrentInput; 1254ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CurrentASTUnit.reset(AST); 1264ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 1274ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1285aa74affa5d61d04c4b034b3722ca41aec0cba6eNico WeberASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, 1295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 1305aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber ASTConsumer* Consumer = CreateASTConsumer(CI, InFile); 1315aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber if (!Consumer) 1325aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber return 0; 1335aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1345aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber if (CI.getFrontendOpts().AddPluginActions.size() == 0) 1355aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber return Consumer; 1365aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1375aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // Make sure the non-plugin consumer is first, so that plugins can't 1385aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // modifiy the AST. 1395aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber std::vector<ASTConsumer*> Consumers(1, Consumer); 1405aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1415aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); 1425aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber i != e; ++i) { 1435aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // This is O(|plugins| * |add_plugins|), but since both numbers are 1445aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // way below 50 in practice, that's ok. 1455aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber for (FrontendPluginRegistry::iterator 1465aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber it = FrontendPluginRegistry::begin(), 1475aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber ie = FrontendPluginRegistry::end(); 1485aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber it != ie; ++it) { 1495aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { 1506f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<PluginASTAction> P(it->instantiate()); 1515aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber FrontendAction* c = P.get(); 152f25649c74397d2620e6ac61f1045261644707c80Nico Weber if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) 1535aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber Consumers.push_back(c->CreateASTConsumer(CI, InFile)); 1545aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber } 1555aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber } 1565aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber } 1575aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1585aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber return new MultiplexConsumer(Consumers); 1595aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber} 1605aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 16127ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor 1624ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarbool FrontendAction::BeginSourceFile(CompilerInstance &CI, 1631f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor const FrontendInputFile &Input) { 1644ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar assert(!Instance && "Already processing a source file!"); 1658616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(!Input.isEmpty() && "Unexpected empty filename!"); 1661f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor setCurrentInput(Input); 1674ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar setCompilerInstance(&CI); 1684ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1698616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis StringRef InputFile = Input.getFile(); 170af6cf431ead1658e13338c6ac0e571755047f7c7Jordan Rose bool HasBegunSourceFile = false; 171e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis if (!BeginInvocation(CI)) 172e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis goto failure; 173e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis 1744ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // AST files follow a very different path, since they share objects via the 1754ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // AST unit. 1768616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis if (Input.getKind() == IK_AST) { 1774ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar assert(!usesPreprocessorOnly() && 1784ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar "Attempt to pass AST file to preprocessor only action!"); 179eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbar assert(hasASTFileSupport() && 180eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbar "This action does not have AST file support!"); 1814ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 182c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); 1834ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar std::string Error; 1848616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags, 185389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis CI.getFileSystemOpts()); 1865262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar if (!AST) 1874ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 1884ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1891f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor setCurrentInput(Input, AST); 1904ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 19162ba4ba4852b3dc3a8c1c77b34b58a06077387d8Argyrios Kyrtzidis // Inform the diagnostic client we are processing a source file. 19262ba4ba4852b3dc3a8c1c77b34b58a06077387d8Argyrios Kyrtzidis CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); 19362ba4ba4852b3dc3a8c1c77b34b58a06077387d8Argyrios Kyrtzidis HasBegunSourceFile = true; 19462ba4ba4852b3dc3a8c1c77b34b58a06077387d8Argyrios Kyrtzidis 1954ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Set the shared objects, these are reset when we finish processing the 1964ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // file, otherwise the CompilerInstance will happily destroy them. 1974ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setFileManager(&AST->getFileManager()); 1984ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setSourceManager(&AST->getSourceManager()); 1994ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setPreprocessor(&AST->getPreprocessor()); 2004ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setASTContext(&AST->getASTContext()); 2014ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2024ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Initialize the action. 2038616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis if (!BeginSourceFileAction(CI, InputFile)) 2044ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 2054ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 20618f43a62134eca1cd830a5b289f4bee4e6ee42feJames Dennett // Create the AST consumer. 2078616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); 2084ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!CI.hasASTConsumer()) 2094ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 2104ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2114ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar return true; 2124ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 2134ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 214faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Set up the file and source managers, if needed. 2152056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar if (!CI.hasFileManager()) 2162056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar CI.createFileManager(); 2172056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar if (!CI.hasSourceManager()) 21839b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner CI.createSourceManager(CI.getFileManager()); 219faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 220faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // IR files bypass the rest of initialization. 2218616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis if (Input.getKind() == IK_LLVM_IR) { 222faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar assert(hasIRSupport() && 223faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar "This action does not have IR file support!"); 224faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 225faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Inform the diagnostic client we are processing a source file. 226faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); 227af6cf431ead1658e13338c6ac0e571755047f7c7Jordan Rose HasBegunSourceFile = true; 228faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 229faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Initialize the action. 2308616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis if (!BeginSourceFileAction(CI, InputFile)) 231faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar goto failure; 232faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 233faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar return true; 234faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar } 235faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 23627ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor // If the implicit PCH include is actually a directory, rather than 23727ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor // a single file, search for a suitable PCH file in that directory. 23827ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 23927ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor FileManager &FileMgr = CI.getFileManager(); 24027ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); 24127ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor StringRef PCHInclude = PPOpts.ImplicitPCHInclude; 24227ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { 24327ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor llvm::error_code EC; 24427ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor SmallString<128> DirNative; 24527ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor llvm::sys::path::native(PCHDir->getName(), DirNative); 24627ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor bool Found = false; 24727ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 24827ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 24927ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor // Check whether this is an acceptable AST file. 25027ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr, 25127ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor CI.getLangOpts(), 2524c0c7e86645dfa1719d17d70e009ab49347aba62Douglas Gregor CI.getTargetOpts(), 2534c0c7e86645dfa1719d17d70e009ab49347aba62Douglas Gregor CI.getPreprocessorOpts())) { 2543ad86fd2effccf1b9337e8cb9a317e4353cec275Argyrios Kyrtzidis PPOpts.ImplicitPCHInclude = Dir->path(); 2553ad86fd2effccf1b9337e8cb9a317e4353cec275Argyrios Kyrtzidis Found = true; 25627ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor break; 25727ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor } 25827ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor } 25927ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor 26027ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor if (!Found) { 26127ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; 26227ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor return true; 26327ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor } 26427ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor } 26527ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor } 26627ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor 267faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Set up the preprocessor. 2682056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar CI.createPreprocessor(); 2692056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar 2704ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Inform the diagnostic client we are processing a source file. 2714ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 2724ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar &CI.getPreprocessor()); 273af6cf431ead1658e13338c6ac0e571755047f7c7Jordan Rose HasBegunSourceFile = true; 2744ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2754ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Initialize the action. 2768616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis if (!BeginSourceFileAction(CI, InputFile)) 2774ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 2784ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 27918f43a62134eca1cd830a5b289f4bee4e6ee42feJames Dennett // Create the AST context and consumer unless this is a preprocessor only 28018f43a62134eca1cd830a5b289f4bee4e6ee42feJames Dennett // action. 2814ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!usesPreprocessorOnly()) { 2824ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.createASTContext(); 2834ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2846f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ASTConsumer> Consumer( 2858616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis CreateWrappedASTConsumer(CI, InputFile)); 286d305719f9b7e154a822ff6688c663cbd32bb1d7bFariborz Jahanian if (!Consumer) 287d305719f9b7e154a822ff6688c663cbd32bb1d7bFariborz Jahanian goto failure; 288ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 2897b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); 290a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor 291b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { 292b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis // Convert headers to PCH and chain them. 2936f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ExternalASTSource> source; 294b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis source.reset(ChainedIncludesSource::create(CI)); 295b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis if (!source) 296b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis goto failure; 297cbdbbd1ba105e65c5c1afa30c6c64f44adf56ad4Argyrios Kyrtzidis CI.setModuleManager(static_cast<ASTReader*>( 298cbdbbd1ba105e65c5c1afa30c6c64f44adf56ad4Argyrios Kyrtzidis &static_cast<ChainedIncludesSource*>(source.get())->getFinalReader())); 299b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis CI.getASTContext().setExternalSource(source); 300b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 301b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 302b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis // Use PCH. 3034ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar assert(hasPCHSupport() && "This action does not have PCH support!"); 304f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ASTDeserializationListener *DeserialListener = 305f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Consumer->GetASTDeserializationListener(); 306b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) 307b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis DeserialListener = new DeserializedDeclsDumper(DeserialListener); 3083e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) 3093e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(), 3103e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, 3113e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis DeserialListener); 3124ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.createPCHExternalASTSource( 313fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor CI.getPreprocessorOpts().ImplicitPCHInclude, 314ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl CI.getPreprocessorOpts().DisablePCHValidation, 315bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, 316b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis DeserialListener); 3174ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!CI.getASTContext().getExternalSource()) 3184ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 3194ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 32077f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl 321ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl CI.setASTConsumer(Consumer.take()); 32277f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl if (!CI.hasASTConsumer()) 32377f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl goto failure; 3244ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 3254ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 326e735e2deb9e57d9b62c1258ee236ccfeba8e84b2Jonathan D. Turner // Initialize built-in info as long as we aren't using an external AST 3274ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // source. 3284ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { 3294ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar Preprocessor &PP = CI.getPreprocessor(); 3304ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), 3314e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie PP.getLangOpts()); 3324ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 3334ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 334453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // If there is a layout overrides file, attach an external AST source that 335453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // provides the layouts from that file. 336453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 337453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { 3386f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ExternalASTSource> 339453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Override(new LayoutOverrideSource( 340453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor CI.getFrontendOpts().OverrideRecordLayoutsFile)); 341453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor CI.getASTContext().setExternalSource(Override); 342453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 343453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 3444ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar return true; 3454ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3464ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // If we failed, reset state since the client will not end up calling the 3474ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // matching EndSourceFile(). 3484ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar failure: 3494ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (isCurrentFileAST()) { 3504f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.setASTContext(0); 3514f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.setPreprocessor(0); 3524f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.setSourceManager(0); 3534f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.setFileManager(0); 3544ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 3554ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 356af6cf431ead1658e13338c6ac0e571755047f7c7Jordan Rose if (HasBegunSourceFile) 357af6cf431ead1658e13338c6ac0e571755047f7c7Jordan Rose CI.getDiagnosticClient().EndSourceFile(); 358ac447fce02d119fb70f0aab885d836dea43e7f26Benjamin Kramer CI.clearOutputFiles(/*EraseFiles=*/true); 3591f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor setCurrentInput(FrontendInputFile()); 3604ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar setCompilerInstance(0); 3614ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar return false; 3624ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 3634ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 364374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidisbool FrontendAction::Execute() { 3654ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompilerInstance &CI = getCompilerInstance(); 3664ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3674ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Initialize the main file entry. This needs to be delayed until after PCH 3684ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // has loaded. 369b8c879a5363f36bdae8831112b563333e3c05acbArgyrios Kyrtzidis if (!isCurrentFileAST()) { 3708e1fbbc492bc1f4833136d9b55e1aaf478565d32Argyrios Kyrtzidis if (!CI.InitializeSourceManager(getCurrentInput())) 371374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis return false; 3724ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 3734ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 374f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam if (CI.hasFrontendTimer()) { 375f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam llvm::TimeRegion Timer(CI.getFrontendTimer()); 376f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam ExecuteAction(); 377f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam } 378f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam else ExecuteAction(); 379374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis 380a6b00fc97669aa25d89ae9f202b05dfadfd0e324Douglas Gregor // If we are supposed to rebuild the global module index, do so now unless 381f575d6e7c3b887ea4c5394d2c7e322c7a929a57eDouglas Gregor // there were any module-build failures. 382f575d6e7c3b887ea4c5394d2c7e322c7a929a57eDouglas Gregor if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() && 383f575d6e7c3b887ea4c5394d2c7e322c7a929a57eDouglas Gregor CI.hasPreprocessor()) { 384a6b00fc97669aa25d89ae9f202b05dfadfd0e324Douglas Gregor GlobalModuleIndex::writeIndex( 385a6b00fc97669aa25d89ae9f202b05dfadfd0e324Douglas Gregor CI.getFileManager(), 386a6b00fc97669aa25d89ae9f202b05dfadfd0e324Douglas Gregor CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 387a6b00fc97669aa25d89ae9f202b05dfadfd0e324Douglas Gregor } 388a6b00fc97669aa25d89ae9f202b05dfadfd0e324Douglas Gregor 389374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis return true; 3904ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 3914ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3924ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarvoid FrontendAction::EndSourceFile() { 3934ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompilerInstance &CI = getCompilerInstance(); 3944ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 39592b97f2d279405751447488504816d82e1906f4fDouglas Gregor // Inform the diagnostic client we are done with this source file. 39692b97f2d279405751447488504816d82e1906f4fDouglas Gregor CI.getDiagnosticClient().EndSourceFile(); 39792b97f2d279405751447488504816d82e1906f4fDouglas Gregor 3984ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Finalize the action. 3994ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar EndSourceFileAction(); 4004ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4014ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Release the consumer and the AST, in that order since the consumer may 4024ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // perform actions in its destructor which require the context. 4034ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // 4044ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // FIXME: There is more per-file stuff we could just drop here? 4054ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (CI.getFrontendOpts().DisableFree) { 4064ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeASTConsumer(); 407f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor if (!isCurrentFileAST()) { 408f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.takeSema(); 4094f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.resetAndLeakASTContext(); 410f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor } 4114ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } else { 412f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor if (!isCurrentFileAST()) { 413f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.setSema(0); 4144ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setASTContext(0); 415f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor } 416f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.setASTConsumer(0); 4174ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 4184ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 419dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar // Inform the preprocessor we are done. 420dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar if (CI.hasPreprocessor()) 421dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar CI.getPreprocessor().EndSourceFile(); 422dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar 4234ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (CI.getFrontendOpts().ShowStats) { 4244ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; 4254ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getPreprocessor().PrintStats(); 4264ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getPreprocessor().getIdentifierTable().PrintStats(); 4274ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getPreprocessor().getHeaderSearchInfo().PrintStats(); 4284ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getSourceManager().PrintStats(); 4294ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar llvm::errs() << "\n"; 4304ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 4314ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4321f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis // Cleanup the output streams, and erase the output files if instructed by the 4331f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis // FrontendAction. 4341f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles()); 4354ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4364ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (isCurrentFileAST()) { 437f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.takeSema(); 4384f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.resetAndLeakASTContext(); 4394f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.resetAndLeakPreprocessor(); 4404f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.resetAndLeakSourceManager(); 4414f32786ac45210143654390177105eb749b614e9Ted Kremenek CI.resetAndLeakFileManager(); 4424ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 4434ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4444ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar setCompilerInstance(0); 4451f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor setCurrentInput(FrontendInputFile()); 4464ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 4474ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4481f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidisbool FrontendAction::shouldEraseOutputFiles() { 4491f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis return getCompilerInstance().getDiagnostics().hasErrorOccurred(); 4501f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis} 4511f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis 4524ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar//===----------------------------------------------------------------------===// 4534ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// Utility Actions 4544ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar//===----------------------------------------------------------------------===// 4554ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4564ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarvoid ASTFrontendAction::ExecuteAction() { 4574ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompilerInstance &CI = getCompilerInstance(); 4580046ce5aa0a0cae048ec8f277bc7098870294dd3Rafael Espindola if (!CI.hasPreprocessor()) 4590046ce5aa0a0cae048ec8f277bc7098870294dd3Rafael Espindola return; 4604ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4614ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // FIXME: Move the truncation aspect of this into Sema, we delayed this till 4624ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // here so the source manager would be initialized. 4634ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (hasCodeCompletionSupport() && 4644ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 4654ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.createCodeCompletionConsumer(); 4664ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 4674ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Use a code completion consumer? 4684ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CodeCompleteConsumer *CompletionConsumer = 0; 4694ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (CI.hasCodeCompletionConsumer()) 4704ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompletionConsumer = &CI.getCodeCompletionConsumer(); 4714ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 472f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor if (!CI.hasSema()) 473467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor CI.createSema(getTranslationUnitKind(), CompletionConsumer); 474f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor 4756a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats, 4766a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen CI.getFrontendOpts().SkipFunctionBodies); 4774ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 4784ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 47999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid PluginASTAction::anchor() { } 48099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie 4814ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel DunbarASTConsumer * 4824ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel DunbarPreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, 4835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 4849f61aa9e280adea9fbf3365f0e4f6ed568c9885aJeffrey Yasskin llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!"); 4854ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 486f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth 487f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler CarruthASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI, 4885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 489f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth return WrappedAction->CreateASTConsumer(CI, InFile); 490f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 491e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidisbool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) { 492e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis return WrappedAction->BeginInvocation(CI); 493e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis} 494f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthbool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI, 4955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename) { 4961f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor WrappedAction->setCurrentInput(getCurrentInput()); 497e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis WrappedAction->setCompilerInstance(&CI); 498f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth return WrappedAction->BeginSourceFileAction(CI, Filename); 499f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 500f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthvoid WrapperFrontendAction::ExecuteAction() { 501f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth WrappedAction->ExecuteAction(); 502f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 503f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthvoid WrapperFrontendAction::EndSourceFileAction() { 504f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth WrappedAction->EndSourceFileAction(); 505f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 506f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth 507f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthbool WrapperFrontendAction::usesPreprocessorOnly() const { 508f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth return WrappedAction->usesPreprocessorOnly(); 509f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 510467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas GregorTranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() { 511467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor return WrappedAction->getTranslationUnitKind(); 512f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 513f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthbool WrapperFrontendAction::hasPCHSupport() const { 514f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth return WrappedAction->hasPCHSupport(); 515f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 516f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthbool WrapperFrontendAction::hasASTFileSupport() const { 517f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth return WrappedAction->hasASTFileSupport(); 518f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 519f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthbool WrapperFrontendAction::hasIRSupport() const { 520f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth return WrappedAction->hasIRSupport(); 521f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 522f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruthbool WrapperFrontendAction::hasCodeCompletionSupport() const { 523f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth return WrappedAction->hasCodeCompletionSupport(); 524f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth} 525f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth 526f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler CarruthWrapperFrontendAction::WrapperFrontendAction(FrontendAction *WrappedAction) 527f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth : WrappedAction(WrappedAction) {} 528f7f8188fac71e34e09ee457ff6f039f5d14ad117Chandler Carruth 529